aspi 1.3.0 → 2.0.1

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/dist/index.d.ts CHANGED
@@ -67,36 +67,176 @@ declare const getHttpErrorStatus: (status: HttpErrorCodes) => HttpErrorStatus;
67
67
  */
68
68
  type HttpMethods = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'TRACE' | 'CONNECT';
69
69
 
70
+ /**
71
+ * Utility type to simplify and prettify a given type.
72
+ *
73
+ * @template Type - The type to be prettified.
74
+ */
70
75
  type Prettify<Type> = Type extends Function ? Type : Extract<{
71
76
  [Key in keyof Type]: Type[Key];
72
77
  }, Type>;
78
+ /**
79
+ * Merge two object types, with properties from `Object2` overriding those in `Object1`.
80
+ *
81
+ * @template Object1 - The base object type.
82
+ * @template Object2 - The object type whose properties will take precedence.
83
+ */
73
84
  type Merge<Object1, Object2> = Prettify<Omit<Object1, keyof Object2> & Object2>;
85
+ /**
86
+ * Represents the base URL used by Aspi.
87
+ *
88
+ * Accepts either a string representation of the URL or a native {@link URL} object.
89
+ */
90
+ type BaseURL = string | URL;
91
+ /**
92
+ * Base configuration for Aspi.
93
+ *
94
+ * This configuration is merged with native `RequestInit` properties and
95
+ * is intended to be passed alongside a `RequestInit` object when initializing
96
+ * an Aspi instance.
97
+ */
74
98
  type AspiConfigBase = {
75
- baseUrl: string;
99
+ /**
100
+ * The base URL for all Aspi requests.
101
+ */
102
+ baseUrl: BaseURL;
103
+ /**
104
+ * Optional retry configuration applied to all requests.
105
+ */
76
106
  retryConfig?: AspiRetryConfig<AspiRequestInit>;
77
107
  };
108
+ /**
109
+ * Configuration for an Aspi instance (without request body).
110
+ *
111
+ * This type includes all standard `RequestInit` properties
112
+ * (`headers`, `mode`, `credentials`, `cache`, `redirect`,
113
+ * `referrer`, `referrerPolicy`, `integrity`, `keepalive`, `signal`)
114
+ * merged with the base Aspi configuration defined in {@link AspiConfigBase}.
115
+ *
116
+ * @extends Merge<Pick<RequestInit,
117
+ * | 'headers'
118
+ * | 'mode'
119
+ * | 'credentials'
120
+ * | 'cache'
121
+ * | 'redirect'
122
+ * | 'referrer'
123
+ * | 'referrerPolicy'
124
+ * | 'integrity'
125
+ * | 'keepalive'
126
+ * | 'signal'>,
127
+ * AspiConfigBase>
128
+ */
129
+ interface AspiRequestInitWithoutBodyAndMethod extends Merge<Pick<RequestInit, 'headers' | 'mode' | 'credentials' | 'cache' | 'redirect' | 'referrer' | 'referrerPolicy' | 'integrity' | 'keepalive' | 'signal'>, AspiConfigBase> {
130
+ }
131
+ /**
132
+ * Configuration for an Aspi request that may include a request body.
133
+ *
134
+ * Extends {@link AspiRequestInitWithoutBody} with the optional `body`
135
+ * property from the native {@link RequestInit} type.
136
+ *
137
+ * @template TBody - The type of the request body (defaults to `any`).
138
+ * @extends Merge<Pick<RequestInit, 'body'>, AspiRequestInitWithoutBody>
139
+ */
140
+ interface AspiRequestInit<TBody = any> extends Merge<Pick<RequestInit, 'body' | 'method'>, Omit<AspiRequestInitWithoutBodyAndMethod, 'retryConfig'>> {
141
+ }
142
+ /**
143
+ * Configuration options for retrying an Aspi request.
144
+ *
145
+ * @template TRequest - The request type extending {@link AspiRequestInit}.
146
+ */
78
147
  type AspiRetryConfig<TRequest extends AspiRequestInit> = {
148
+ /**
149
+ * Maximum number of retry attempts. If omitted, no retries are performed.
150
+ */
79
151
  retries?: number;
152
+ /**
153
+ * Delay before the next retry attempt.
154
+ *
155
+ * Can be a static number (milliseconds) or a function that dynamically
156
+ * determines the delay based on the retry state and the request/response.
157
+ *
158
+ * @param remainingRetries - Number of retries left after the current attempt.
159
+ * @param totalRetries - The total number of retries configured.
160
+ * @param request - The original {@link AspiRequest} being retried.
161
+ * @param response - The {@link AspiResponse} received from the failed attempt.
162
+ * @returns A delay in milliseconds or a promise that resolves to one.
163
+ */
80
164
  retryDelay?: number | ((remainingRetries: number, totalRetries: number, request: AspiRequest<TRequest>, response: AspiResponse) => number | Promise<number>);
165
+ /**
166
+ * Array of HTTP status codes that should trigger a retry.
167
+ */
81
168
  retryOn?: Array<HttpErrorCodes>;
169
+ /**
170
+ * Predicate function that determines whether a retry should occur based on the
171
+ * request and response. Returning `true` triggers a retry.
172
+ *
173
+ * @param request - The {@link AspiRequest} that was sent.
174
+ * @param response - The {@link AspiResponse} received.
175
+ * @returns A boolean or a promise that resolves to a boolean.
176
+ */
82
177
  retryWhile?: (request: AspiRequest<TRequest>, response: AspiResponse) => boolean | Promise<boolean>;
178
+ /**
179
+ * Callback invoked after each retry attempt.
180
+ *
181
+ * @param request - The {@link AspiRequest} that was retried.
182
+ * @param response - The {@link AspiResponse} from the failed attempt.
183
+ */
83
184
  onRetry?: (request: AspiRequest<TRequest>, response: AspiResponse) => void;
84
185
  };
85
- type AspiConfig = Pick<RequestInit, 'headers' | 'mode'> & AspiConfigBase;
186
+ /**
187
+ * Callback type for handling custom errors.
188
+ *
189
+ * @template T - The request type extending {@link AspiRequestInit}.
190
+ * @template A - The shape of the error object returned by the callback.
191
+ * @param input - Object containing the request and response that triggered the error.
192
+ * @param input.request - The {@link AspiRequest} associated with the failed request.
193
+ * @param input.response - The {@link AspiResponse} received from the server.
194
+ * @returns The error data of type `A`.
195
+ */
86
196
  type CustomErrorCb<T extends AspiRequestInit, A extends {}> = (input: {
87
197
  request: AspiRequest<T>;
88
198
  response: AspiResponse;
89
199
  }) => A;
90
- type Middleware<T extends RequestInit, U extends RequestInit> = (request: T) => U;
91
- interface AspiRequestInit extends RequestInit, AspiConfigBase {
92
- }
200
+ /**
201
+ * Transforms a request before it is sent.
202
+ *
203
+ * @template T - The original request type extending {@link AspiRequestInit}.
204
+ * @template U - The resulting request type extending {@link AspiRequestInit}.
205
+ * @param request - The request instance to be transformed.
206
+ * @returns The transformed request of type `U`.
207
+ */
208
+ type RequestTransformer<T extends AspiRequestInit, U extends AspiRequestInit> = (request: T) => U;
209
+ /**
210
+ * Options for configuring an Aspi request.
211
+ *
212
+ * @template TRequest - The request initialization type extending {@link AspiRequestInit}.
213
+ * @property {TRequest} requestConfig - The request configuration object.
214
+ * @property {AspiRetryConfig<TRequest>} [retryConfig] - Optional retry configuration applied to the request.
215
+ * @property {RequestTransformer<TRequest, TRequest>[]} [middlewares] - Optional list of request transformers that act as middleware.
216
+ * @property {ErrorCallbacks} [errorCbs] - Optional collection of custom error callbacks keyed by HTTP status code.
217
+ * @property {boolean} [throwOnError] - When `true`, the request will throw on error instead of returning an error result.
218
+ * @property {boolean} [shouldBeResult] - When `true`, the request returns an {@link AspiResultOk} instead of a raw response.
219
+ */
93
220
  type RequestOptions<TRequest extends AspiRequestInit> = {
94
221
  requestConfig: TRequest;
95
222
  retryConfig?: AspiRetryConfig<TRequest>;
96
- middlewares?: Middleware<TRequest, TRequest>[];
223
+ middlewares?: RequestTransformer<TRequest, TRequest>[];
97
224
  errorCbs?: ErrorCallbacks;
98
225
  throwOnError?: boolean;
226
+ shouldBeResult?: boolean;
99
227
  };
228
+ /**
229
+ * Record of custom error callbacks keyed by HTTP status code.
230
+ *
231
+ * It keeps track of the custom error callbacks (`cb`) provided for specific
232
+ * response codes. Each entry includes:
233
+ *
234
+ * - `cb`: a function receiving the request and response objects that generated the error.
235
+ * - `tag`: an optional identifier or metadata associated with the callback.
236
+ *
237
+ * This type is used in {@link RequestOptions.errorCbs} to map status codes to
238
+ * their corresponding handlers.
239
+ */
100
240
  type ErrorCallbacks = Record<number, {
101
241
  cb: (input: {
102
242
  request: any;
@@ -104,44 +244,65 @@ type ErrorCallbacks = Record<number, {
104
244
  }) => any;
105
245
  tag: unknown;
106
246
  }>;
247
+ /**
248
+ * Represents a successful Aspi request result.
249
+ *
250
+ * @template TRequest - The request initialization options type extending {@link AspiRequestInit}.
251
+ * @template TData - The type of the response data.
252
+ * @property {TData} data - The parsed response payload.
253
+ * @property {AspiRequest<TRequest>} request - The request that was sent.
254
+ * @property {AspiResponse} response - The response wrapper containing status, status text, and the native {@link Response} object.
255
+ */
107
256
  type AspiResultOk<TRequest extends AspiRequestInit, TData> = {
108
257
  data: TData;
109
258
  request: AspiRequest<TRequest>;
110
259
  response: AspiResponse;
111
260
  };
112
- type AspiPlainResponse<TRequest extends AspiRequestInit, TData> = AspiResultOk<TRequest, TData>;
113
-
114
261
  /**
115
- * Response interface used in error handling
116
- * @interface AspiResponse
117
- * @property {HttpErrorCodes} status - The HTTP status code of the response
118
- * @property {HttpErrorStatus} statusText - The HTTP status text of the response
119
- * @property {Response} [response] - Optional raw Response object
120
- * @property {any} [responseData] - Optional response data content
262
+ * Represents a successful Aspi request result without any additional metadata.
263
+ *
264
+ * This type is an alias for {@link AspiResultOk} and is provided for semantic
265
+ * clarity when a plain response shape is desired.
266
+ *
267
+ * @template TRequest - The request initialization options type extending {@link AspiRequestInit}.
268
+ * @template TData - The type of the response payload.
121
269
  */
122
- interface AspiResponse {
123
- status: HttpErrorCodes;
124
- statusText: HttpErrorStatus;
125
- response?: Response;
126
- responseData?: any;
127
- }
270
+ type AspiPlainResponse<TRequest extends AspiRequestInit, TData> = AspiResultOk<TRequest, TData>;
128
271
  /**
129
- * Interface representing an API request configuration
272
+ * Interface representing an API request configuration.
273
+ *
130
274
  * @interface AspiRequest
131
- * @template T - Request initialization options type extending AspiRequestInit
132
- * @property {string} baseUrl - Base URL for the API request
133
- * @property {string} path - Request path to append to baseUrl
134
- * @property {T} requestInit - Request initialization options
135
- * @property {URLSearchParams | null} queryParams - URL query parameters, if any
136
- * @property {AspiRetryConfig<T>} retryConfig - Retry configuration for failed requests
275
+ * @template T - Request initialization options type extending {@link AspiRequestInit}
276
+ * @property {string} path - Request path to append to the base URL.
277
+ * @property {T} requestInit - Request initialization options.
278
+ * @property {URLSearchParams | null} queryParams - URL query parameters, if any.
137
279
  */
138
280
  interface AspiRequest<T extends AspiRequestInit> {
139
- baseUrl: string;
140
281
  path: string;
141
282
  requestInit: T;
142
283
  queryParams: URLSearchParams | null;
143
- retryConfig: AspiRetryConfig<T>;
144
284
  }
285
+ /**
286
+ * Represents the response returned by an Aspi request.
287
+ *
288
+ * @template TData - The type of the response payload when the request succeeds.
289
+ * @template IsError - `true` if the response represents an error condition; `false` otherwise.
290
+ *
291
+ * @property {HttpErrorCodes} status - HTTP status code of the response.
292
+ * @property {HttpErrorStatus} statusText - HTTP status text associated with the status code.
293
+ * @property {Response} response - The native {@link Response} object.
294
+ * @property {TData} [responseData] - The parsed response body. When `IsError` is `true` this property is required; otherwise it is optional.
295
+ */
296
+ type AspiResponse<TData = any, IsError extends boolean = false> = Merge<{
297
+ status: HttpErrorCodes;
298
+ statusText: HttpErrorStatus;
299
+ response: Response;
300
+ }, IsError extends true ? {
301
+ responseData: TData;
302
+ } : {
303
+ responseData?: any;
304
+ }>;
305
+
145
306
  /**
146
307
  * Custom error class for API errors
147
308
  * @class AspiError
@@ -150,17 +311,17 @@ interface AspiRequest<T extends AspiRequestInit> {
150
311
  * @property {AspiRe} request - The original request configuration
151
312
  * @property {AspiResponse} response - The error response details
152
313
  */
153
- declare class AspiError<TReq extends AspiRequestInit> extends Error {
314
+ declare class AspiError<TRequest extends AspiRequestInit> extends Error {
154
315
  tag: "aspiError";
155
- request: AspiRequest<TReq>;
156
- response: AspiResponse;
316
+ request: AspiRequest<TRequest>;
317
+ response: AspiResponse<any, false>;
157
318
  /**
158
319
  * Creates an instance of AspiError
159
320
  * @param {string} message - The error message
160
321
  * @param {AspiRe} request - The request configuration
161
322
  * @param {AspiResponse} response - The error response
162
323
  */
163
- constructor(message: string, request: AspiRequest<TReq>, response: AspiResponse);
324
+ constructor(message: string, request: AspiRequest<TRequest>, response: AspiResponse);
164
325
  /**
165
326
  * Conditionally executes callback if status matches
166
327
  * @template T
@@ -169,8 +330,8 @@ declare class AspiError<TReq extends AspiRequestInit> extends Error {
169
330
  * @returns {T | undefined} Result of callback if status matches, undefined otherwise
170
331
  */
171
332
  ifMatch<T>(status: HttpErrorStatus, cb: (args: {
172
- request: AspiRequest<TReq>;
173
- response: AspiResponse;
333
+ request: AspiRequest<TRequest>;
334
+ response: AspiResponse<any, false>;
174
335
  }) => T): T | undefined;
175
336
  }
176
337
  /**
@@ -606,7 +767,7 @@ declare class Request<Method extends HttpMethods, TRequest extends AspiRequestIn
606
767
  error: {};
607
768
  }> {
608
769
  #private;
609
- constructor(method: HttpMethods, path: string, { requestConfig, retryConfig, middlewares, errorCbs, throwOnError, }: RequestOptions<TRequest>);
770
+ constructor(method: HttpMethods, path: string, requestOptions: RequestOptions<TRequest>);
610
771
  /**
611
772
  * Sets the base URL for the request.
612
773
  * @param url The base URL to set
@@ -615,7 +776,7 @@ declare class Request<Method extends HttpMethods, TRequest extends AspiRequestIn
615
776
  * const request = new Request('/users', config);
616
777
  * request.setBaseUrl('https://api.example.com');
617
778
  */
618
- setBaseUrl(url: string): this;
779
+ setBaseUrl(url: BaseURL): this;
619
780
  /**
620
781
  * Sets the retry configuration for the request.
621
782
  * @param retry The retry configuration object
@@ -631,17 +792,21 @@ declare class Request<Method extends HttpMethods, TRequest extends AspiRequestIn
631
792
  */
632
793
  setRetry(retry: AspiRetryConfig<TRequest>): this;
633
794
  /**
634
- * Sets multiple headers for the request.
635
- * @param headers An object containing header key-value pairs
636
- * @returns The request instance for chaining
795
+ * Merges the provided headers into the request configuration.
796
+ *
797
+ * @param {HeadersInit} headers - An object or iterable containing header name/value pairs.
798
+ * Existing headers are retained unless a key in this object overwrites them.
799
+ * @returns {this} The current {@link Request} instance for method chaining.
800
+ *
637
801
  * @example
802
+ * // Set common JSON headers
638
803
  * const request = new Request('/users', config);
639
804
  * request.setHeaders({
640
805
  * 'Content-Type': 'application/json',
641
- * 'Accept': 'application/json'
806
+ * 'Accept': 'application/json',
642
807
  * });
643
808
  */
644
- setHeaders(headers: Record<string, string>): this;
809
+ setHeaders(headers: HeadersInit): this;
645
810
  /**
646
811
  * Sets a single header for the request.
647
812
  * @param key The header key
@@ -831,70 +996,126 @@ declare class Request<Method extends HttpMethods, TRequest extends AspiRequestIn
831
996
  error: { [K in keyof Opts["error"] | "internalServerError"]: K extends "internalServerError" ? CustomError<"internalServerError", A> : Opts["error"][K]; };
832
997
  }>>;
833
998
  /**
834
- * Sets a custom error handler for a specific HTTP status code.
835
- * @param tag A string identifier for the error type
836
- * @param status The HTTP error status to handle
837
- * @param cb The callback function to handle the error
838
- * @returns The request instance for chaining
999
+ * Register a custom error handler for a specific HTTP status code.
1000
+ *
1001
+ * When the response matches the provided `status`, the supplied callback `cb`
1002
+ * is invoked and its return value is wrapped in a {@link CustomError} with the
1003
+ * given `tag`. The method also augments the request's generic `Opts['error']`
1004
+ * type so that the custom error is reflected in the resulting `Result`
1005
+ * union.
1006
+ *
1007
+ * @template Tag - A string literal used as the error tag.
1008
+ * @template A - The shape of the data returned by the callback.
1009
+ *
1010
+ * @param {Tag} tag
1011
+ * A unique identifier for the custom error. This value becomes the `tag`
1012
+ * property of the {@link CustomError} produced by the handler.
1013
+ *
1014
+ * @param {HttpErrorStatus} status
1015
+ * The HTTP status code (e.g. `'BAD_REQUEST'`, `'NOT_FOUND'`) that should
1016
+ * trigger the custom handler.
1017
+ *
1018
+ * @param {CustomErrorCb<TRequest, A>} cb
1019
+ * A callback that receives the failing request and response objects and
1020
+ * returns an object describing the error payload.
1021
+ *
1022
+ * @returns {Request<Method, TRequest, Merge<Omit<Opts, 'error'>, { error: { [K in Tag | keyof Opts['error']]: K extends Tag ? CustomError<Tag, A> : Opts['error'][K]; } }>>}
1023
+ * The same {@link Request} instance, now typed with the newly added error
1024
+ * variant, allowing method‑chaining.
1025
+ *
839
1026
  * @example
1027
+ * ```ts
840
1028
  * const request = new Request('/users', config);
1029
+ *
1030
+ * // Attach a custom handler for a 400 Bad Request response
841
1031
  * request
842
- .withResult()
843
- .error('customError', 'BAD_REQUEST', (error) => {
844
- * console.log('Bad request error:', error);
845
- * return {
846
- * message: 'Invalid input',
847
- * details: error.response.responseData
848
- * };
849
- * });
1032
+ * withResult()
1033
+ * .error('customError', 'BAD_REQUEST', (ctx) => {
1034
+ * console.log('Bad request error:', ctx);
1035
+ * return {
1036
+ * message: 'Invalid input',
1037
+ * details: ctx.response.responseData,
1038
+ * };
1039
+ * });
850
1040
  *
851
- * // Later when making the request:
1041
+ * // Later, when executing the request:
852
1042
  * const result = await request.json();
853
- * if (Result.isErr(result)) {
854
- * if(result.tag === 'customError') {
1043
+ * if (Result.isErr(result) && result.tag === 'customError') {
855
1044
  * console.log(result.error.data.message); // 'Invalid input'
856
1045
  * }
1046
+ * ```
857
1047
  */
858
1048
  error<Tag extends string, A extends {}>(tag: Tag, status: HttpErrorStatus, cb: CustomErrorCb<TRequest, A>): Request<Method, TRequest, Merge<Omit<Opts, "error">, {
859
1049
  error: { [K in Tag | keyof Opts["error"]]: K extends Tag ? CustomError<Tag, A> : Opts["error"][K]; };
860
1050
  }>>;
861
1051
  /**
862
- * Sets query parameters for the request URL.
863
- * @param params An object containing query parameter key-value pairs
864
- * @returns The request instance for chaining
1052
+ * Sets the query parameters for the request URL.
1053
+ *
1054
+ * Accepts any value that can be passed to the `URLSearchParams` constructor:
1055
+ * - an object mapping keys to string values,
1056
+ * - an iterable of `[key, value]` tuples,
1057
+ * - a raw query string, or
1058
+ * - an existing {@link URLSearchParams} instance.
1059
+ *
1060
+ * The supplied parameters replace any previously defined query parameters.
1061
+ *
1062
+ * @template T - The concrete type of the supplied parameters.
1063
+ * @param {T} params - The query parameters to apply.
1064
+ * @returns {this} The request instance for method‑chaining.
1065
+ *
865
1066
  * @example
866
1067
  * const request = new Request('/users', config);
867
1068
  * request.setQueryParams({
868
1069
  * page: '1',
869
1070
  * limit: '10',
870
- * sort: 'desc'
1071
+ * sort: 'desc',
871
1072
  * });
1073
+ *
1074
+ * // Using a raw query string
1075
+ * request.setQueryParams('page=1&limit=10');
1076
+ *
1077
+ * // Using an array of entries
1078
+ * request.setQueryParams([['page', '1'], ['limit', '10']]);
1079
+ *
1080
+ * // Using an existing URLSearchParams instance
1081
+ * const qp = new URLSearchParams({ page: '1' });
1082
+ * request.setQueryParams(qp);
872
1083
  */
873
1084
  setQueryParams<T extends Record<string, string> | string[][] | string | URLSearchParams>(params: T): Request<Method, TRequest, Merge<Omit<Opts, "queryParams">, {
874
1085
  queryParams: T;
875
1086
  }>>;
876
1087
  /**
877
- * Sets the output schema for validating the response data using Zod.
878
- * @param schema The Zod schema to validate the response
879
- * @returns The request instance for chaining
1088
+ * Sets a validation schema for the response data.
1089
+ *
1090
+ * The provided {@link StandardSchemaV1} schema will be used to validate the
1091
+ * response payload when the request is executed. If validation fails, a
1092
+ * `parseError` is added to the request's error type.
1093
+ *
1094
+ * @template TSchema - A type extending {@link StandardSchemaV1}
1095
+ * @param schema - The schema used to validate the response data
1096
+ * @returns The request instance for chaining with an updated generic type that
1097
+ * includes the schema and a possible `parseError` in the error union
1098
+ *
880
1099
  * @example
1100
+ * ```ts
881
1101
  * import { z } from 'zod';
882
1102
  *
883
1103
  * const userSchema = z.object({
884
1104
  * id: z.number(),
885
1105
  * name: z.string(),
886
- * email: z.string().email()
1106
+ * email: z.string().email(),
887
1107
  * });
888
1108
  *
889
1109
  * const request = new Request('/users', config);
890
1110
  * const result = await request
891
1111
  * .withResult()
892
- * .output(userSchema)
1112
+ * .schema(userSchema)
893
1113
  * .json();
894
1114
  *
895
1115
  * if (Result.isOk(result)) {
896
1116
  * const user = result.value; // Typed and validated user data
897
1117
  * }
1118
+ * ```
898
1119
  */
899
1120
  schema<TSchema extends StandardSchemaV1>(schema: TSchema): Request<Method, TRequest, Merge<Omit<Opts, "schema">, {
900
1121
  schema: TSchema;
@@ -903,36 +1124,77 @@ declare class Request<Method extends HttpMethods, TRequest extends AspiRequestIn
903
1124
  }>;
904
1125
  }>>;
905
1126
  /**
906
- * Sets the request to throw an error if the response status is not successful.
907
- * @returns The request instance for chaining
1127
+ * Configures the request to **throw** an exception when the response status
1128
+ * indicates a failure (i.e., `!response.ok`). This disables the “Result”
1129
+ * mode (`withResult`) and enables “throwable” mode, causing
1130
+ * `await request.json()` (or other response helpers) to either resolve with
1131
+ * the successful payload **or** reject with an `AspiError`/`CustomError`.
1132
+ *
1133
+ * Use this when you prefer traditional `try / catch` error handling over
1134
+ * the explicit `Result` type returned by {@link withResult}.
1135
+ *
1136
+ * @returns This {@link Request} instance, now typed with `throwable: true` and
1137
+ * `withResult: false` for proper chaining.
1138
+ *
908
1139
  * @example
1140
+ * ```ts
909
1141
  * const request = new Request('/users', config);
910
- * const result = await request
911
- * .withResult()
912
- * .throwable()
913
- * .json();
914
1142
  *
1143
+ * try {
1144
+ * const user = await request
1145
+ * .throwable() // Enable throwing on HTTP errors
1146
+ * .json<User>(); // Will throw if the response is not ok
1147
+ * console.log(user);
1148
+ * } catch (err) {
1149
+ * // err is either AspiError or a CustomError returned by a custom handler
1150
+ * console.error('Request failed:', err);
1151
+ * }
1152
+ * ```
915
1153
  */
916
1154
  throwable(): Request<Method, TRequest, Merge<Omit<Opts, "withResult" | "throwable">, {
917
1155
  withResult: false;
918
1156
  throwable: true;
919
1157
  }>>;
920
1158
  /**
921
- * Executes the request and returns the JSON response.
922
- * @returns A Promise containing the Result type with either successful data or error information
1159
+ * Sends the request and parses the response body as JSON.
1160
+ *
1161
+ * The resolved value of the returned promise varies based on the request mode:
1162
+ *
1163
+ * - **Result mode** (`withResult()`): resolves to a {@link Result.Result} that
1164
+ * contains either an {@link AspiResultOk} with the parsed payload or a union
1165
+ * of possible error types (HTTP errors, custom errors, JSON‑parse errors,
1166
+ * schema‑validation errors, etc.).
1167
+ *
1168
+ * - **Throwable mode** (`throwable()`): resolves directly to the successful
1169
+ * payload (`AspiPlainResponse`) and throws a {@link AspiError} or
1170
+ * {@link CustomError} on failure.
1171
+ *
1172
+ * - **Default mode** (no explicit mode): resolves to a tuple
1173
+ * `[value, error]` where exactly one element is non‑null.
1174
+ *
1175
+ * @template T - The inferred output type of the response schema (if a schema
1176
+ * was supplied via {@link schema}). When no schema is provided `T` defaults
1177
+ * to `any`.
1178
+ *
1179
+ * @returns A promise whose shape depends on the selected mode (see description).
1180
+ * In Result mode it is `Result<ResultOk<…>, …>`, in throwable mode it is
1181
+ * `AspiPlainResponse<…>`, and otherwise a tuple
1182
+ * `[AspiResultOk<…> | null, Error | null]`.
1183
+ *
923
1184
  * @example
1185
+ * // Using the Result API
924
1186
  * const request = new Request('/users', config);
925
1187
  * const result = await request
926
1188
  * .setQueryParams({ id: '123' })
927
- * .
928
- withResult()
929
- * .notFound((error) => ({ message: 'User not found' }))
1189
+ * .withResult()
1190
+ * .notFound(() => ({ message: 'User not found' }))
930
1191
  * .json<User>();
931
1192
  *
932
1193
  * if (Result.isOk(result)) {
933
- * const user = result.value; // User data
1194
+ * // `result.value` has type `User`
1195
+ * console.log(result.value);
934
1196
  * } else {
935
- * console.error(result.error); // Error handling
1197
+ * console.error(result.error);
936
1198
  * }
937
1199
  */
938
1200
  json<T extends StandardSchemaV1.InferOutput<Opts['schema']>>(): Promise<Opts['withResult'] extends true ? Result<AspiResultOk<TRequest, T>, AspiError<TRequest> | (Opts extends {
@@ -944,14 +1206,45 @@ declare class Request<Method extends HttpMethods, TRequest extends AspiRequestIn
944
1206
  } ? Opts['error'][keyof Opts['error']] : never) | JSONParseError) | null)
945
1207
  ]>;
946
1208
  /**
947
- * Executes the request and returns the response as plain text.
948
- * @returns A Promise containing the Result type with either successful text data or error information
1209
+ * Executes the request and returns the response body as plain text.
1210
+ *
1211
+ * The method respects the request mode:
1212
+ *
1213
+ * - **Result mode** (`withResult()`): resolves to a {@link Result.Result}
1214
+ * containing either an {@link AspiResultOk} with the text payload or an
1215
+ * error variant.
1216
+ * - **Throwable mode** (`throwable()`): resolves directly to the text string
1217
+ * and throws on error.
1218
+ * - **Default mode**: resolves to a tuple `[value, error]` where exactly one
1219
+ * element is `null`.
1220
+ *
1221
+ * @returns {Promise<
1222
+ * Opts['withResult'] extends true
1223
+ * ? Result.Result<
1224
+ * AspiResultOk<TRequest, string>,
1225
+ * AspiError<TRequest> |
1226
+ * (Opts extends { error: any } ? Opts['error'][keyof Opts['error']] : never)
1227
+ * >
1228
+ * : Opts['throwable'] extends true
1229
+ * ? AspiPlainResponse<TRequest, string>
1230
+ * : [
1231
+ * AspiResultOk<TRequest, string> | null,
1232
+ * (
1233
+ * | AspiError<TRequest>
1234
+ * | (Opts extends { error: any } ? Opts['error'][keyof Opts['error']] : never)
1235
+ * | null
1236
+ * )
1237
+ * ]
1238
+ * }>
1239
+ * A promise that resolves according to the selected request mode.
1240
+ *
949
1241
  * @example
1242
+ * ```ts
950
1243
  * const request = new Request('/data.txt', config);
951
1244
  * const result = await request
952
1245
  * .setQueryParams({ version: '1' })
953
1246
  * .withResult()
954
- * .notFound((error) => ({ message: 'Text file not found' }))
1247
+ * .notFound(() => ({ message: 'Text file not found' }))
955
1248
  * .text();
956
1249
  *
957
1250
  * if (Result.isOk(result)) {
@@ -959,6 +1252,7 @@ declare class Request<Method extends HttpMethods, TRequest extends AspiRequestIn
959
1252
  * } else {
960
1253
  * console.error(result.error); // Error handling
961
1254
  * }
1255
+ * ```
962
1256
  */
963
1257
  text(): Promise<Opts['withResult'] extends true ? Result<AspiResultOk<TRequest, string>, AspiError<TRequest> | (Opts extends {
964
1258
  error: any;
@@ -969,14 +1263,49 @@ declare class Request<Method extends HttpMethods, TRequest extends AspiRequestIn
969
1263
  } ? Opts['error'][keyof Opts['error']] : never)) | null)
970
1264
  ]>;
971
1265
  /**
972
- * Executes the request and returns the response as a Blob.
973
- * @returns A Promise containing the Result type with either successful Blob data or error information
1266
+ * Executes the request and returns the response body as a {@link Blob}.
1267
+ *
1268
+ * The shape of the returned {@link Promise} depends on the request mode:
1269
+ *
1270
+ * - **Result mode** (`withResult()`): resolves to a {@link Result.Result} containing
1271
+ * either an {@link AspiResultOk} with `Blob` data or an error variant.
1272
+ * - **Throwable mode** (`throwable()`): resolves directly to a {@link Blob}
1273
+ * (wrapped in {@link AspiPlainResponse}) and throws on failure.
1274
+ * - **Default mode**: resolves to a tuple `[value, error]` where exactly one element
1275
+ * is `null`.
1276
+ *
1277
+ * @returns {Promise<
1278
+ * Opts['withResult'] extends true
1279
+ * ? Result.Result<
1280
+ * AspiResultOk<TRequest, Blob>,
1281
+ * | AspiError<TRequest>
1282
+ * | (Opts extends { error: any }
1283
+ * ? Opts['error'][keyof Opts['error']]
1284
+ * : never)
1285
+ * >
1286
+ * : Opts['throwable'] extends true
1287
+ * ? AspiPlainResponse<TRequest, Blob>
1288
+ * : [
1289
+ * AspiResultOk<TRequest, Blob> | null,
1290
+ * (
1291
+ * | (
1292
+ * | AspiError<TRequest>
1293
+ * | (Opts extends { error: any }
1294
+ * ? Opts['error'][keyof Opts['error']]
1295
+ * : never)
1296
+ * )
1297
+ * | null
1298
+ * ),
1299
+ * ]
1300
+ * }>
1301
+ *
974
1302
  * @example
1303
+ * ```ts
975
1304
  * const request = new Request('/image.jpg', config);
976
1305
  * const result = await request
977
1306
  * .setQueryParams({ size: 'large' })
978
1307
  * .withResult()
979
- * .notFound((error) => ({ message: 'Image not found' }))
1308
+ * .notFound(() => ({ message: 'Image not found' }))
980
1309
  * .blob();
981
1310
  *
982
1311
  * if (Result.isOk(result)) {
@@ -984,6 +1313,7 @@ declare class Request<Method extends HttpMethods, TRequest extends AspiRequestIn
984
1313
  * } else {
985
1314
  * console.error(result.error); // Error handling
986
1315
  * }
1316
+ * ```
987
1317
  */
988
1318
  blob(): Promise<Opts['withResult'] extends true ? Result<AspiResultOk<TRequest, Blob>, AspiError<TRequest> | (Opts extends {
989
1319
  error: any;
@@ -994,33 +1324,122 @@ declare class Request<Method extends HttpMethods, TRequest extends AspiRequestIn
994
1324
  } ? Opts['error'][keyof Opts['error']] : never)) | null)
995
1325
  ]>;
996
1326
  /**
997
- * Returns the complete URL for the request including base URL, path, and query parameters.
998
- * @returns The complete URL string
1327
+ * Returns the fully‑qualified URL that will be used for the request.
1328
+ *
1329
+ * The URL is constructed from the configured base URL, the request path,
1330
+ * and any query parameters added via {@link setQueryParams}.
1331
+ *
1332
+ * @returns {string} The complete request URL.
1333
+ *
999
1334
  * @example
1335
+ * ```ts
1000
1336
  * const request = new Request('/users', config);
1001
1337
  * request.setBaseUrl('https://api.example.com');
1002
1338
  * request.setQueryParams({ id: '123' });
1003
- * console.log(request.url()); // 'https://api.example.com/users?id=123'
1339
+ *
1340
+ * console.log(request.url());
1341
+ * // => 'https://api.example.com/users?id=123'
1342
+ * ```
1004
1343
  */
1005
1344
  url(): string;
1006
1345
  /**
1007
- * Configures the request to return a Result type instead of a tuple.
1008
- * @returns The request instance for chaining with Result type return value
1346
+ * Switches the request into **Result** mode.
1347
+ *
1348
+ * In Result mode the response helpers (`json`, `text`, `blob`, …) resolve to a
1349
+ * {@link Result.Result} instance instead of the default tuple
1350
+ * `[value, error]`. This allows callers to use pattern matching
1351
+ * (`Result.isOk`, `Result.isErr`) to handle success and failure.
1352
+ *
1353
+ * Calling `withResult` disables the “throwable” behaviour (see {@link throwable}).
1354
+ *
1355
+ * @returns {Request<
1356
+ * Method,
1357
+ * TRequest,
1358
+ * Merge<
1359
+ * Omit<Opts, 'withResult' | 'throwable'>,
1360
+ * {
1361
+ * withResult: true;
1362
+ * throwable: false;
1363
+ * }
1364
+ * >
1365
+ * >} The same {@link Request} instance, now typed with `withResult: true` and
1366
+ * `throwable: false` for fluent chaining.
1367
+ *
1009
1368
  * @example
1369
+ * ```ts
1010
1370
  * const request = new Request('/users', config);
1371
+ *
1011
1372
  * const result = await request
1012
- * .withResult()
1373
+ * .withResult() // enable Result mode
1013
1374
  * .json<User>();
1014
1375
  *
1015
- * // Returns Result type instead of tuple
1016
1376
  * if (Result.isOk(result)) {
1017
- * const user = result.value;
1377
+ * // `result.value` is of type `User`
1378
+ * console.log(result.value);
1018
1379
  * }
1380
+ * ```
1019
1381
  */
1020
1382
  withResult(): Request<Method, TRequest, Merge<Omit<Opts, "withResult" | "throwable">, {
1021
1383
  withResult: true;
1022
1384
  throwable: false;
1023
1385
  }>>;
1386
+ /**
1387
+ * Returns the underlying {@link AspiRequest} object that will be used for the fetch call.
1388
+ *
1389
+ * This method does not perform any network activity; it simply builds and returns the
1390
+ * request configuration, including any applied middlewares, query parameters, etc.
1391
+ *
1392
+ * @returns {AspiRequest<TRequest>} The constructed request object.
1393
+ */
1394
+ getRequest(): AspiRequest<TRequest>;
1395
+ /**
1396
+ * Retrieves the registry of custom error callbacks that have been
1397
+ * registered via {@link error}. The returned object maps HTTP status
1398
+ * codes to their corresponding callback functions and tags.
1399
+ *
1400
+ * @returns {ErrorCallbacks} A shallow copy of the internal error callback registry.
1401
+ */
1402
+ getErrorCallbackRegistry(): ErrorCallbacks;
1403
+ /**
1404
+ * Returns whether the request is configured to return a {@link Result.Result}
1405
+ * instead of the default tuple or throwing.
1406
+ *
1407
+ * @returns {boolean} `true` when {@link withResult} has been called.
1408
+ */
1409
+ isResult(): boolean;
1410
+ /**
1411
+ * Returns whether the request is configured to throw on HTTP errors.
1412
+ *
1413
+ * @returns {boolean} `true` when {@link throwable} has been called.
1414
+ */
1415
+ isThrowable(): boolean;
1416
+ /**
1417
+ * Returns the effective retry configuration for this request, including defaulted values.
1418
+ *
1419
+ * The returned object contains:
1420
+ * - `retries` – number of retry attempts (default 1)
1421
+ * - `retryDelay` – delay between attempts in milliseconds or a function that returns a delay
1422
+ * - `retryOn` – array of HTTP status codes that should trigger a retry
1423
+ * - `retryWhile` – optional custom predicate executed after each response
1424
+ * - `onRetry` – optional callback invoked after a retry attempt
1425
+ *
1426
+ * A shallow copy is returned to avoid accidental mutation of the internal state.
1427
+ *
1428
+ * @returns {{
1429
+ * retries: number;
1430
+ * retryDelay: number | ((attempt: number, maxAttempts: number, request: AspiRequest<TRequest>, response: AspiResponse<any, true>) => number);
1431
+ * retryOn: number[];
1432
+ * retryWhile?: (request: AspiRequest<TRequest>, response: AspiResponse<any, true>) => boolean | Promise<boolean>;
1433
+ * onRetry?: (request: AspiRequest<TRequest>, response: AspiResponse<any, true>) => void;
1434
+ * }}
1435
+ */
1436
+ getRetryConfig(): {
1437
+ retries: number;
1438
+ retryDelay: number | ((remainingRetries: number, totalRetries: number, request: AspiRequest<TRequest>, response: AspiResponse) => number | Promise<number>);
1439
+ retryOn: HttpErrorCodes[];
1440
+ retryWhile: ((request: AspiRequest<TRequest>, response: AspiResponse) => boolean | Promise<boolean>) | undefined;
1441
+ onRetry: ((request: AspiRequest<TRequest>, response: AspiResponse) => void) | undefined;
1442
+ };
1024
1443
  }
1025
1444
 
1026
1445
  /**
@@ -1040,16 +1459,20 @@ declare class Request<Method extends HttpMethods, TRequest extends AspiRequestIn
1040
1459
  */
1041
1460
  declare class Aspi<TRequest extends AspiRequestInit = AspiRequestInit, Opts extends Record<any, any> = {}> {
1042
1461
  #private;
1043
- constructor(config: AspiConfig);
1462
+ constructor(config: AspiRequestInitWithoutBodyAndMethod);
1044
1463
  /**
1045
- * Sets the base URL for all API requests
1046
- * @param {string} url - The base URL to be set
1047
- * @returns {Aspi} The Aspi instance for chaining
1464
+ * Sets or overrides the base URL used for all subsequent API requests.
1465
+ *
1466
+ * Accepts either a string or a `URL` instance. If a `URL` object is provided,
1467
+ * it is converted to its string representation.
1468
+ *
1469
+ * @param url - The new base URL.
1470
+ * @returns The current {@link Aspi} instance for chaining.
1048
1471
  * @example
1049
1472
  * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1050
1473
  * api.setBaseUrl('https://api.newdomain.com');
1051
1474
  */
1052
- setBaseUrl(url: string): this;
1475
+ setBaseUrl(url: string | URL): this;
1053
1476
  /**
1054
1477
  * Sets the retry configuration for failed requests
1055
1478
  * @param {AspiRetryConfig<TRequest>} retry - The retry configuration object
@@ -1074,35 +1497,34 @@ declare class Aspi<TRequest extends AspiRequestInit = AspiRequestInit, Opts exte
1074
1497
  */
1075
1498
  get(path: string): Request<"GET", TRequest, Opts>;
1076
1499
  /**
1077
- * Makes a POST request to the specified path with an optional body
1078
- * @param {string} path - The path to make the request to
1079
- * @param {BodyInit} [body] - The body of the request
1080
- * @returns {Request} A Request instance for chaining
1500
+ * Makes a POST request to the specified path.
1501
+ *
1502
+ * @param {string} path - The path to make the request to.
1503
+ * @returns {Request} A Request instance for chaining.
1504
+ *
1081
1505
  * @example
1082
1506
  * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1083
- * const response = await api.post('/users', { name: 'John' }).json();
1507
+ * const response = await api.post('/users').json();
1084
1508
  */
1085
- post(path: string, body?: BodyInit): Request<"POST", TRequest, Opts>;
1509
+ post(path: string): Request<"POST", TRequest, Opts>;
1086
1510
  /**
1087
- * Makes a PUT request to the specified path with an optional body
1088
- * @param {string} path - The path to make the request to
1089
- * @param {BodyInit} [body] - The body of the request
1090
- * @returns {Request} A Request instance for chaining
1511
+ * Makes a PUT request to the specified path.
1512
+ * @param {string} path - The path to make the request to.
1513
+ * @returns {Request} A Request instance for chaining.
1091
1514
  * @example
1092
1515
  * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1093
- * const response = await api.put('/users/1', { name: 'John' }).json();
1516
+ * const response = await api.put('/users/1').json();
1094
1517
  */
1095
- put(path: string, body?: BodyInit): Request<"PUT", TRequest, Opts>;
1518
+ put(path: string): Request<"PUT", TRequest, Opts>;
1096
1519
  /**
1097
- * Makes a PATCH request to the specified path with an optional body
1098
- * @param {string} path - The path to make the request to
1099
- * @param {BodyInit} [body] - The body of the request
1100
- * @returns {Request} A Request instance for chaining
1520
+ * Makes a PATCH request to the specified path.
1521
+ * @param {string} path - The path to make the request to.
1522
+ * @returns {Request} A Request instance for chaining.
1101
1523
  * @example
1102
1524
  * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1103
- * const response = await api.patch('/users/1', { name: 'John' }).json();
1525
+ * const response = await api.patch('/users/1').json();
1104
1526
  */
1105
- patch(path: string, body?: BodyInit): Request<"PATCH", TRequest, Opts>;
1527
+ patch(path: string): Request<"PATCH", TRequest, Opts>;
1106
1528
  /**
1107
1529
  * Makes a DELETE request to the specified path
1108
1530
  * @param {string} path - The path to make the request to
@@ -1131,8 +1553,9 @@ declare class Aspi<TRequest extends AspiRequestInit = AspiRequestInit, Opts exte
1131
1553
  */
1132
1554
  options(path: string): Request<"OPTIONS", TRequest, Opts>;
1133
1555
  /**
1134
- * Sets multiple headers for all API requests
1135
- * @param {Record<string, string>} headers - An object containing header key-value pairs
1556
+ * Sets multiple headers for all API requests. Existing headers are preserved
1557
+ * and new ones are merged, overriding any duplicate keys.
1558
+ * @param {HeadersInit} headers - An object containing header key-value pairs
1136
1559
  * @returns {Aspi} The Aspi instance for chaining
1137
1560
  * @example
1138
1561
  * const api = new Aspi({ baseUrl: 'https://api.example.com' });
@@ -1141,12 +1564,14 @@ declare class Aspi<TRequest extends AspiRequestInit = AspiRequestInit, Opts exte
1141
1564
  * 'Accept': 'application/json'
1142
1565
  * });
1143
1566
  */
1144
- setHeaders(headers: Record<string, string>): this;
1567
+ setHeaders(headers: HeadersInit): this;
1145
1568
  /**
1146
- * Sets a single header for all API requests
1147
- * @param {string} key - The header key
1148
- * @param {string} value - The header value
1149
- * @returns {Aspi} The Aspi instance for chaining
1569
+ * Sets a single header for all API requests.
1570
+ *
1571
+ * @param key - The header name.
1572
+ * @param value - The header value.
1573
+ * @returns This {@link Aspi} instance for chaining.
1574
+ *
1150
1575
  * @example
1151
1576
  * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1152
1577
  * api.setHeader('Content-Type', 'application/json');
@@ -1162,21 +1587,31 @@ declare class Aspi<TRequest extends AspiRequestInit = AspiRequestInit, Opts exte
1162
1587
  */
1163
1588
  setBearer(token: string): this;
1164
1589
  /**
1165
- * Use a middleware function to transform requests
1166
- * @param {Middleware<T, U>} fn - The middleware function to apply
1167
- * @returns {Aspi<U>} A new Aspi instance with the applied middleware
1590
+ * Register a request‑transformer middleware.
1591
+ *
1592
+ * The supplied function receives the current request initialization object
1593
+ * (`T`) and must return a request initialization of type `U`. The middleware
1594
+ * is added to the internal middleware chain and will be applied to every
1595
+ * request created by this {@link Aspi} instance.
1596
+ *
1597
+ * @template T - The input request type, extending the current {@link Aspi} request init type.
1598
+ * @template U - The output request type after transformation.
1599
+ * @param {RequestTransformer<T, U>} fn - The middleware function that transforms a request configuration.
1600
+ * @returns {Aspi<U>} A new {@link Aspi} instance typed with the transformed request configuration.
1168
1601
  * @example
1169
1602
  * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1170
- * api.use((req) => {
1171
- * // Add custom headers
1172
- * req.headers = {
1173
- * ...req.headers,
1174
- * 'x-custom-header': 'custom-value'
1603
+ * const apiWithHeaders = api.use((req) => {
1604
+ * // Add custom headers to every request
1605
+ * return {
1606
+ * ...req,
1607
+ * headers: {
1608
+ * ...req.headers,
1609
+ * 'x-custom-header': 'custom-value',
1610
+ * },
1175
1611
  * };
1176
- * return req;
1177
1612
  * });
1178
1613
  */
1179
- use<T extends TRequest, U extends TRequest>(fn: Middleware<T, U>): Aspi<U>;
1614
+ use<T extends TRequest, U extends TRequest>(fn: RequestTransformer<T, U>): Aspi<U>;
1180
1615
  /**
1181
1616
  * Registers a custom error handler for a specific HTTP status
1182
1617
  * @param {string} tag - The error tag identifier
@@ -1296,9 +1731,18 @@ declare class Aspi<TRequest extends AspiRequestInit = AspiRequestInit, Opts exte
1296
1731
  * .json();
1297
1732
  *
1298
1733
  */
1299
- throwable(): Aspi<TRequest, Prettify<Opts & {
1734
+ throwable(): Aspi<TRequest, Merge<Omit<Opts, "withResult" | "throwable">, {
1735
+ withResult: false;
1300
1736
  throwable: true;
1301
1737
  }>>;
1738
+ /**
1739
+ * Configures the request to return a Result object instead of just the response body.
1740
+ * @returns The Aspi instance with result handling enabled.
1741
+ */
1742
+ withResult(): Aspi<TRequest, Merge<Omit<Opts, "withResult" | "throwable">, {
1743
+ withResult: true;
1744
+ throwable: false;
1745
+ }>>;
1302
1746
  }
1303
1747
 
1304
- export { Aspi, type AspiConfig, type AspiConfigBase, AspiError, type AspiPlainResponse, type AspiRequest, type AspiRequestInit, type AspiResponse, type AspiResultOk, type AspiRetryConfig, CustomError, type CustomErrorCb, type ErrorCallbacks, type HttpErrorCodes, type HttpErrorStatus, type HttpMethods, type JSONParseError, type Merge, type Middleware, type Prettify, Request, type RequestOptions, result as Result, getHttpErrorStatus, httpErrors, isAspiError, isCustomError };
1748
+ export { Aspi, type AspiConfigBase, AspiError, type AspiPlainResponse, type AspiRequest, type AspiRequestInit, type AspiRequestInitWithoutBodyAndMethod, type AspiResponse, type AspiResultOk, type AspiRetryConfig, type BaseURL, CustomError, type CustomErrorCb, type ErrorCallbacks, type HttpErrorCodes, type HttpErrorStatus, type HttpMethods, type JSONParseError, type Merge, type Prettify, Request, type RequestOptions, type RequestTransformer, result as Result, getHttpErrorStatus, httpErrors, isAspiError, isCustomError };