@tahanabavi/typefetch 1.4.1 → 1.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1026 -139
- package/dist/index.d.mts +104 -85
- package/dist/index.d.ts +104 -85
- package/dist/index.js +439 -4140
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +427 -4146
- package/dist/index.mjs.map +1 -1
- package/package.json +49 -15
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
1
|
+
import z$1, { z } from 'zod';
|
|
2
2
|
|
|
3
|
+
type EncryptionMethod = "AES" | "DES" | "RSA" | "Base64" | "Custom";
|
|
4
|
+
type Method = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
5
|
+
/**
|
|
6
|
+
* DeepEncryptionMap<T>
|
|
7
|
+
* --------------------
|
|
8
|
+
* Recursively describes which fields should be encrypted/decrypted.
|
|
9
|
+
* Supports:
|
|
10
|
+
* - Primitive fields → boolean | method
|
|
11
|
+
* - Objects → recursively typed maps
|
|
12
|
+
* - Arrays → mapping applies to element type (U)
|
|
13
|
+
* - Array-map override (optional but supported)
|
|
14
|
+
*/
|
|
15
|
+
type DeepEncryptionMap = boolean | EncryptionMethod | {
|
|
16
|
+
[key: string]: DeepEncryptionMap;
|
|
17
|
+
} | DeepEncryptionMap[];
|
|
18
|
+
/**
|
|
19
|
+
* EncryptionConfig
|
|
20
|
+
* ================
|
|
21
|
+
* Defines the encryption/decryption strategy for an endpoint.
|
|
22
|
+
* Both request and response maps are strictly typed based on their respective Zod schemas.
|
|
23
|
+
*/
|
|
24
|
+
type EncryptionConfig<TReq, TRes> = {
|
|
25
|
+
method: EncryptionMethod | {
|
|
26
|
+
request?: EncryptionMethod;
|
|
27
|
+
response?: EncryptionMethod;
|
|
28
|
+
};
|
|
29
|
+
/** Map of request fields to encrypt before sending to the server */
|
|
30
|
+
request?: DeepEncryptionMap;
|
|
31
|
+
/** Map of response fields to decrypt after receiving from the server */
|
|
32
|
+
response?: DeepEncryptionMap;
|
|
33
|
+
};
|
|
3
34
|
/**
|
|
4
35
|
* Base types for Zod schemas representing request and response structures.
|
|
5
36
|
* These are abstract—each concrete endpoint will define its own Zod object for these.
|
|
@@ -18,7 +49,7 @@ type ResponseSchema = z.ZodTypeAny;
|
|
|
18
49
|
*/
|
|
19
50
|
type EndpointDef<TReq extends RequestSchema, TRes extends ResponseSchema> = {
|
|
20
51
|
/** HTTP method used by this endpoint */
|
|
21
|
-
method:
|
|
52
|
+
method: Method;
|
|
22
53
|
/** URL path for this endpoint, e.g. "/users/:id" */
|
|
23
54
|
path: string;
|
|
24
55
|
/** Whether this endpoint requires an Authorization token */
|
|
@@ -33,6 +64,11 @@ type EndpointDef<TReq extends RequestSchema, TRes extends ResponseSchema> = {
|
|
|
33
64
|
* - Or a static mock response object
|
|
34
65
|
*/
|
|
35
66
|
mockData?: (() => z.infer<TRes>) | z.infer<TRes>;
|
|
67
|
+
/**
|
|
68
|
+
* Field-level encryption configuration.
|
|
69
|
+
* Allows selecting specific fields in request/response to be encrypted/decrypted.
|
|
70
|
+
*/
|
|
71
|
+
encryption?: EncryptionConfig<z.infer<TReq>, z.infer<TRes>>;
|
|
36
72
|
/**
|
|
37
73
|
* Optional custom headers. Can be:
|
|
38
74
|
* - A fixed record of header key/values
|
|
@@ -69,14 +105,29 @@ type Contracts = {
|
|
|
69
105
|
[EndpointName: string]: EndpointDef<RequestSchema, ResponseSchema>;
|
|
70
106
|
};
|
|
71
107
|
};
|
|
108
|
+
/**
|
|
109
|
+
* Convenience alias that pins both generic types
|
|
110
|
+
* to `z.ZodTypeAny`, simplifying the contract declarations.
|
|
111
|
+
*/
|
|
112
|
+
type EndpointDefZ = EndpointDef<RequestSchema, ResponseSchema>;
|
|
72
113
|
/**
|
|
73
114
|
* Context passed to all middleware functions.
|
|
74
|
-
* Contains the current request URL
|
|
75
|
-
*
|
|
115
|
+
* Contains the current request URL, initialization object,
|
|
116
|
+
* and the specific endpoint definition for metadata access.
|
|
76
117
|
*/
|
|
77
|
-
|
|
118
|
+
type RequestParts = {
|
|
119
|
+
path?: Record<string, unknown>;
|
|
120
|
+
query?: Record<string, unknown>;
|
|
121
|
+
body?: unknown;
|
|
122
|
+
headers: Record<string, string>;
|
|
123
|
+
isStructured: boolean;
|
|
124
|
+
rawInput?: unknown;
|
|
125
|
+
};
|
|
126
|
+
interface MiddlewareContext<TReq extends RequestSchema = RequestSchema, TRes extends ResponseSchema = ResponseSchema> {
|
|
78
127
|
url: string;
|
|
79
128
|
init: RequestInit;
|
|
129
|
+
endpoint: EndpointDef<TReq, TRes>;
|
|
130
|
+
request?: RequestParts;
|
|
80
131
|
}
|
|
81
132
|
/**
|
|
82
133
|
* The `next()` function type signature used inside middleware.
|
|
@@ -98,7 +149,7 @@ type MiddlewareNext = () => Promise<Response>;
|
|
|
98
149
|
* return res;
|
|
99
150
|
* };
|
|
100
151
|
*/
|
|
101
|
-
type Middleware<Options = any> = (ctx: MiddlewareContext, next: MiddlewareNext, options?: Options) => Promise<Response>;
|
|
152
|
+
type Middleware<TReq extends RequestSchema = RequestSchema, TRes extends ResponseSchema = ResponseSchema, Options = any> = (ctx: MiddlewareContext<TReq, TRes>, next: MiddlewareNext, options?: Options) => Promise<Response>;
|
|
102
153
|
/**
|
|
103
154
|
* ErrorLike
|
|
104
155
|
* =========
|
|
@@ -111,11 +162,6 @@ type ErrorLike = {
|
|
|
111
162
|
code?: string;
|
|
112
163
|
[key: string]: any;
|
|
113
164
|
};
|
|
114
|
-
/**
|
|
115
|
-
* Convenience alias that pins both generic types
|
|
116
|
-
* to `z.ZodTypeAny`, simplifying the contract declarations.
|
|
117
|
-
*/
|
|
118
|
-
type EndpointDefZ = EndpointDef<RequestSchema, ResponseSchema>;
|
|
119
165
|
/**
|
|
120
166
|
* RequestOptions
|
|
121
167
|
* ==============
|
|
@@ -149,10 +195,6 @@ type EndpointMethods<M extends Record<string, EndpointDefZ>> = {
|
|
|
149
195
|
*/
|
|
150
196
|
type TokenProvider = () => string | Promise<string>;
|
|
151
197
|
|
|
152
|
-
/**
|
|
153
|
-
* A richer extension of the native Error class that captures
|
|
154
|
-
* additional API error details such as HTTP status, code, and field errors.
|
|
155
|
-
*/
|
|
156
198
|
declare class RichError extends Error implements ErrorLike {
|
|
157
199
|
status?: number;
|
|
158
200
|
code?: string;
|
|
@@ -163,17 +205,6 @@ declare class RichError extends Error implements ErrorLike {
|
|
|
163
205
|
message: string;
|
|
164
206
|
});
|
|
165
207
|
}
|
|
166
|
-
/**
|
|
167
|
-
* ApiClient
|
|
168
|
-
* =========
|
|
169
|
-
* A robust, strongly-typed HTTP client that automatically builds API endpoint
|
|
170
|
-
* methods from Zod-based contracts, providing:
|
|
171
|
-
* - Input and response validation via Zod
|
|
172
|
-
* - Middleware support
|
|
173
|
-
* - Token-based authentication
|
|
174
|
-
* - Error normalization (RichError)
|
|
175
|
-
* - Optional caching, retries, and mock data
|
|
176
|
-
*/
|
|
177
208
|
declare class ApiClient<C extends Contracts, E extends ErrorLike = RichError> {
|
|
178
209
|
private config;
|
|
179
210
|
private contracts;
|
|
@@ -196,64 +227,34 @@ declare class ApiClient<C extends Contracts, E extends ErrorLike = RichError> {
|
|
|
196
227
|
max: number;
|
|
197
228
|
};
|
|
198
229
|
}, contracts: C);
|
|
199
|
-
/**
|
|
200
|
-
* Builds all API methods (`modules`) dynamically from the Zod contract definition.
|
|
201
|
-
* After `init()` is called, each endpoint can be invoked through `client.modules.moduleName.endpointName()`.
|
|
202
|
-
*/
|
|
203
230
|
init(): void;
|
|
204
|
-
/** Provides access to initialized modules after calling `init()`. */
|
|
205
231
|
get modules(): { [M in keyof C]: EndpointMethods<C[M]>; };
|
|
206
|
-
|
|
207
|
-
use<T>(middleware: Middleware<T>, options?: T): void;
|
|
208
|
-
/** Sets a global error handler function to unify error behavior. */
|
|
232
|
+
use<T>(middleware: Middleware<any, any, T>, options?: T): void;
|
|
209
233
|
onError(handler: (error: E) => void): void;
|
|
210
|
-
/** Defines a global transform function applied to all validated responses. */
|
|
211
234
|
useResponseTransform(fn: (data: any) => any): void;
|
|
212
|
-
/** Configures the retry logic (max attempts, backoff mode, etc.). */
|
|
213
235
|
setRetryConfig(config: ApiClient<C>["retryConfig"]): void;
|
|
214
|
-
/** Provides a custom token provider that returns tokens dynamically. */
|
|
215
236
|
setTokenProvider(provider: TokenProvider): void;
|
|
216
|
-
/** Enables mock responses instead of network requests. */
|
|
217
237
|
setMockMode(enabled: boolean, delay?: {
|
|
218
238
|
min: number;
|
|
219
239
|
max: number;
|
|
220
240
|
}): void;
|
|
221
|
-
/** Registers a wrapper schema for APIs that nest response data (e.g. `{ data, success, message }`). */
|
|
222
241
|
setResponseWrapper(wrapper: (successResponse: z.ZodTypeAny) => z.ZodTypeAny): void;
|
|
223
|
-
/** Retrieves the current auth token, using a provider if available. */
|
|
224
242
|
getCurrentToken(): Promise<string | undefined>;
|
|
225
|
-
/**
|
|
226
|
-
* Core request entry point used by auto-generated endpoint methods.
|
|
227
|
-
* Handles caching, deduplication, and mock mode routing.
|
|
228
|
-
*/
|
|
229
243
|
private request;
|
|
230
|
-
/**
|
|
231
|
-
* Full HTTP request workflow:
|
|
232
|
-
* - Token injection
|
|
233
|
-
* - Timeout support
|
|
234
|
-
* - Middleware pipeline
|
|
235
|
-
* - Fetch + response handling
|
|
236
|
-
* - Zod parsing + transformation
|
|
237
|
-
* - Caching
|
|
238
|
-
*/
|
|
239
244
|
private performRequestLogic;
|
|
240
|
-
/** Executes a function with retry logic and configurable backoff strategy. */
|
|
241
245
|
private executeWithRetry;
|
|
242
|
-
/** Calculates retry delay intervals for various backoff strategies. */
|
|
243
246
|
private getBackoffDelay;
|
|
244
|
-
/** Builds the final URL and request body from the endpoint definition and input payload. */
|
|
245
247
|
private buildUrlAndBody;
|
|
246
|
-
|
|
248
|
+
private extractRequestParts;
|
|
249
|
+
private isStructuredRequestInput;
|
|
250
|
+
private isObjectRecord;
|
|
251
|
+
private applyPathParams;
|
|
252
|
+
private appendQueryParams;
|
|
253
|
+
private appendQueryValue;
|
|
254
|
+
private appendFormValue;
|
|
255
|
+
private normalizeHeaders;
|
|
247
256
|
private createError;
|
|
248
|
-
/**
|
|
249
|
-
* Converts any thrown error to a standardized RichError instance.
|
|
250
|
-
* Also flattens Zod validation errors into readable messages.
|
|
251
|
-
*/
|
|
252
257
|
private normalizeError;
|
|
253
|
-
/**
|
|
254
|
-
* Handles mock-mode requests by simulating a delayed network call
|
|
255
|
-
* and returning validated mock data.
|
|
256
|
-
*/
|
|
257
258
|
private handleMockRequest;
|
|
258
259
|
}
|
|
259
260
|
|
|
@@ -262,7 +263,7 @@ type LoggingOptions = {
|
|
|
262
263
|
logResponse?: boolean;
|
|
263
264
|
debug?: boolean;
|
|
264
265
|
};
|
|
265
|
-
declare const loggingMiddleware: Middleware<LoggingOptions>;
|
|
266
|
+
declare const loggingMiddleware: Middleware<z$1.ZodTypeAny, z$1.ZodTypeAny, LoggingOptions>;
|
|
266
267
|
|
|
267
268
|
type RetryOptions = {
|
|
268
269
|
maxRetries?: number;
|
|
@@ -317,7 +318,7 @@ type AuthOptions = {
|
|
|
317
318
|
* authMiddleware({ refreshToken: tokenSupplier })
|
|
318
319
|
* );
|
|
319
320
|
*/
|
|
320
|
-
declare const authMiddleware: Middleware<AuthOptions>;
|
|
321
|
+
declare const authMiddleware: Middleware<z$1.ZodTypeAny, z$1.ZodTypeAny, AuthOptions>;
|
|
321
322
|
|
|
322
323
|
/**
|
|
323
324
|
* CacheOptions
|
|
@@ -365,26 +366,44 @@ type CacheOptions = {
|
|
|
365
366
|
*/
|
|
366
367
|
declare const cacheMiddleware: (options?: CacheOptions) => (ctx: MiddlewareContext, next: MiddlewareNext) => Promise<Response>;
|
|
367
368
|
|
|
368
|
-
|
|
369
|
+
type SymmetricKeyMaterial = {
|
|
370
|
+
type: "symmetric";
|
|
371
|
+
key: string;
|
|
372
|
+
};
|
|
373
|
+
type RSAKeyMaterial = {
|
|
374
|
+
type: "rsa";
|
|
375
|
+
publicKey: string;
|
|
376
|
+
privateKey: string;
|
|
377
|
+
};
|
|
378
|
+
type KeyMaterial = SymmetricKeyMaterial | RSAKeyMaterial;
|
|
379
|
+
type CustomHandlers = {
|
|
380
|
+
encrypt: (value: string, key: KeyMaterial) => string | Promise<string>;
|
|
381
|
+
decrypt: (value: string, key: KeyMaterial) => string | Promise<string>;
|
|
382
|
+
};
|
|
383
|
+
interface EncryptionOptions {
|
|
384
|
+
keyProvider: () => KeyMaterial | Promise<KeyMaterial>;
|
|
385
|
+
customHandlers?: CustomHandlers;
|
|
386
|
+
/**
|
|
387
|
+
* true = throw when encryption/decryption fails, which avoids leaking plaintext.
|
|
388
|
+
* false = log and continue/fallback to the original response.
|
|
389
|
+
* Default: true
|
|
390
|
+
*/
|
|
391
|
+
failClosed?: boolean;
|
|
392
|
+
}
|
|
393
|
+
declare function processDeep<T = unknown>(data: unknown, map: DeepEncryptionMap | null | undefined, defaultMethod: EncryptionMethod, transform: (value: unknown, method: EncryptionMethod) => Promise<unknown>): Promise<T>;
|
|
394
|
+
declare const encryptionMiddleware: Middleware<z.ZodTypeAny, z.ZodTypeAny, EncryptionOptions>;
|
|
395
|
+
|
|
396
|
+
type OptionalUndefinedBody<T extends z.ZodTypeAny> = T extends z.ZodUndefined ? z.ZodOptional<T> : T;
|
|
397
|
+
declare const makeRequestSchema: <TPath extends z.ZodRawShape = {}, TQuery extends z.ZodRawShape = {}, TBody extends z.ZodTypeAny = z.ZodUndefined, THeaders extends z.ZodTypeAny = z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>() => (defs?: {
|
|
369
398
|
path?: z.ZodObject<TPath>;
|
|
370
399
|
query?: z.ZodObject<TQuery>;
|
|
371
400
|
body?: TBody;
|
|
372
|
-
headers?:
|
|
401
|
+
headers?: THeaders;
|
|
373
402
|
}) => z.ZodObject<{
|
|
374
|
-
path: z.ZodOptional<z.ZodObject<
|
|
375
|
-
query: z.ZodOptional<z.ZodObject<
|
|
376
|
-
body: TBody
|
|
377
|
-
headers:
|
|
378
|
-
},
|
|
379
|
-
path: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>> | z.ZodOptional<z.ZodObject<TPath, z.UnknownKeysParam, z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<TPath>, any> extends infer T_5 ? { [k in keyof T_5]: T_5[k]; } : never, z.baseObjectInputType<TPath> extends infer T_6 ? { [k_1 in keyof T_6]: T_6[k_1]; } : never>>;
|
|
380
|
-
query: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>> | z.ZodOptional<z.ZodObject<TQuery, z.UnknownKeysParam, z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<TQuery>, any> extends infer T_7 ? { [k_2 in keyof T_7]: T_7[k_2]; } : never, z.baseObjectInputType<TQuery> extends infer T_8 ? { [k_3 in keyof T_8]: T_8[k_3]; } : never>>;
|
|
381
|
-
body: TBody | z.ZodUndefined;
|
|
382
|
-
headers: any;
|
|
383
|
-
}>, any> extends infer T_4 ? { [k_4 in keyof T_4]: T_4[k_4]; } : never, z.baseObjectInputType<{
|
|
384
|
-
path: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>> | z.ZodOptional<z.ZodObject<TPath, z.UnknownKeysParam, z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<TPath>, any> extends infer T_10 ? { [k in keyof T_10]: T_10[k]; } : never, z.baseObjectInputType<TPath> extends infer T_11 ? { [k_1 in keyof T_11]: T_11[k_1]; } : never>>;
|
|
385
|
-
query: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>> | z.ZodOptional<z.ZodObject<TQuery, z.UnknownKeysParam, z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<TQuery>, any> extends infer T_12 ? { [k_2 in keyof T_12]: T_12[k_2]; } : never, z.baseObjectInputType<TQuery> extends infer T_13 ? { [k_3 in keyof T_13]: T_13[k_3]; } : never>>;
|
|
386
|
-
body: TBody | z.ZodUndefined;
|
|
387
|
-
headers: any;
|
|
388
|
-
}> extends infer T_9 ? { [k_5 in keyof T_9]: T_9[k_5]; } : never>;
|
|
403
|
+
path: z.ZodOptional<z.ZodObject<TPath, z.core.$strip>>;
|
|
404
|
+
query: z.ZodOptional<z.ZodObject<TQuery, z.core.$strip>>;
|
|
405
|
+
body: OptionalUndefinedBody<TBody>;
|
|
406
|
+
headers: THeaders;
|
|
407
|
+
}, z.core.$strip>;
|
|
389
408
|
|
|
390
|
-
export { ApiClient, type AuthOptions, type CacheOptions, type Contracts, type EndpointDef, type EndpointDefZ, type EndpointMethods, type ErrorLike, type LoggingOptions, type Middleware, type MiddlewareContext, type MiddlewareNext, type RequestOptions, type RequestSchema, type ResponseSchema, type RetryOptions, RichError, type TokenProvider, authMiddleware, cacheMiddleware, loggingMiddleware, makeRequestSchema, retryMiddleware };
|
|
409
|
+
export { ApiClient, type AuthOptions, type CacheOptions, type Contracts, type DeepEncryptionMap, type EncryptionConfig, type EncryptionMethod, type EncryptionOptions, type EndpointDef, type EndpointDefZ, type EndpointMethods, type ErrorLike, type LoggingOptions, type Method, type Middleware, type MiddlewareContext, type MiddlewareNext, type RequestOptions, type RequestParts, type RequestSchema, type ResponseSchema, type RetryOptions, RichError, type TokenProvider, authMiddleware, cacheMiddleware, encryptionMiddleware, loggingMiddleware, makeRequestSchema, processDeep, retryMiddleware };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
1
|
+
import z$1, { z } from 'zod';
|
|
2
2
|
|
|
3
|
+
type EncryptionMethod = "AES" | "DES" | "RSA" | "Base64" | "Custom";
|
|
4
|
+
type Method = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
5
|
+
/**
|
|
6
|
+
* DeepEncryptionMap<T>
|
|
7
|
+
* --------------------
|
|
8
|
+
* Recursively describes which fields should be encrypted/decrypted.
|
|
9
|
+
* Supports:
|
|
10
|
+
* - Primitive fields → boolean | method
|
|
11
|
+
* - Objects → recursively typed maps
|
|
12
|
+
* - Arrays → mapping applies to element type (U)
|
|
13
|
+
* - Array-map override (optional but supported)
|
|
14
|
+
*/
|
|
15
|
+
type DeepEncryptionMap = boolean | EncryptionMethod | {
|
|
16
|
+
[key: string]: DeepEncryptionMap;
|
|
17
|
+
} | DeepEncryptionMap[];
|
|
18
|
+
/**
|
|
19
|
+
* EncryptionConfig
|
|
20
|
+
* ================
|
|
21
|
+
* Defines the encryption/decryption strategy for an endpoint.
|
|
22
|
+
* Both request and response maps are strictly typed based on their respective Zod schemas.
|
|
23
|
+
*/
|
|
24
|
+
type EncryptionConfig<TReq, TRes> = {
|
|
25
|
+
method: EncryptionMethod | {
|
|
26
|
+
request?: EncryptionMethod;
|
|
27
|
+
response?: EncryptionMethod;
|
|
28
|
+
};
|
|
29
|
+
/** Map of request fields to encrypt before sending to the server */
|
|
30
|
+
request?: DeepEncryptionMap;
|
|
31
|
+
/** Map of response fields to decrypt after receiving from the server */
|
|
32
|
+
response?: DeepEncryptionMap;
|
|
33
|
+
};
|
|
3
34
|
/**
|
|
4
35
|
* Base types for Zod schemas representing request and response structures.
|
|
5
36
|
* These are abstract—each concrete endpoint will define its own Zod object for these.
|
|
@@ -18,7 +49,7 @@ type ResponseSchema = z.ZodTypeAny;
|
|
|
18
49
|
*/
|
|
19
50
|
type EndpointDef<TReq extends RequestSchema, TRes extends ResponseSchema> = {
|
|
20
51
|
/** HTTP method used by this endpoint */
|
|
21
|
-
method:
|
|
52
|
+
method: Method;
|
|
22
53
|
/** URL path for this endpoint, e.g. "/users/:id" */
|
|
23
54
|
path: string;
|
|
24
55
|
/** Whether this endpoint requires an Authorization token */
|
|
@@ -33,6 +64,11 @@ type EndpointDef<TReq extends RequestSchema, TRes extends ResponseSchema> = {
|
|
|
33
64
|
* - Or a static mock response object
|
|
34
65
|
*/
|
|
35
66
|
mockData?: (() => z.infer<TRes>) | z.infer<TRes>;
|
|
67
|
+
/**
|
|
68
|
+
* Field-level encryption configuration.
|
|
69
|
+
* Allows selecting specific fields in request/response to be encrypted/decrypted.
|
|
70
|
+
*/
|
|
71
|
+
encryption?: EncryptionConfig<z.infer<TReq>, z.infer<TRes>>;
|
|
36
72
|
/**
|
|
37
73
|
* Optional custom headers. Can be:
|
|
38
74
|
* - A fixed record of header key/values
|
|
@@ -69,14 +105,29 @@ type Contracts = {
|
|
|
69
105
|
[EndpointName: string]: EndpointDef<RequestSchema, ResponseSchema>;
|
|
70
106
|
};
|
|
71
107
|
};
|
|
108
|
+
/**
|
|
109
|
+
* Convenience alias that pins both generic types
|
|
110
|
+
* to `z.ZodTypeAny`, simplifying the contract declarations.
|
|
111
|
+
*/
|
|
112
|
+
type EndpointDefZ = EndpointDef<RequestSchema, ResponseSchema>;
|
|
72
113
|
/**
|
|
73
114
|
* Context passed to all middleware functions.
|
|
74
|
-
* Contains the current request URL
|
|
75
|
-
*
|
|
115
|
+
* Contains the current request URL, initialization object,
|
|
116
|
+
* and the specific endpoint definition for metadata access.
|
|
76
117
|
*/
|
|
77
|
-
|
|
118
|
+
type RequestParts = {
|
|
119
|
+
path?: Record<string, unknown>;
|
|
120
|
+
query?: Record<string, unknown>;
|
|
121
|
+
body?: unknown;
|
|
122
|
+
headers: Record<string, string>;
|
|
123
|
+
isStructured: boolean;
|
|
124
|
+
rawInput?: unknown;
|
|
125
|
+
};
|
|
126
|
+
interface MiddlewareContext<TReq extends RequestSchema = RequestSchema, TRes extends ResponseSchema = ResponseSchema> {
|
|
78
127
|
url: string;
|
|
79
128
|
init: RequestInit;
|
|
129
|
+
endpoint: EndpointDef<TReq, TRes>;
|
|
130
|
+
request?: RequestParts;
|
|
80
131
|
}
|
|
81
132
|
/**
|
|
82
133
|
* The `next()` function type signature used inside middleware.
|
|
@@ -98,7 +149,7 @@ type MiddlewareNext = () => Promise<Response>;
|
|
|
98
149
|
* return res;
|
|
99
150
|
* };
|
|
100
151
|
*/
|
|
101
|
-
type Middleware<Options = any> = (ctx: MiddlewareContext, next: MiddlewareNext, options?: Options) => Promise<Response>;
|
|
152
|
+
type Middleware<TReq extends RequestSchema = RequestSchema, TRes extends ResponseSchema = ResponseSchema, Options = any> = (ctx: MiddlewareContext<TReq, TRes>, next: MiddlewareNext, options?: Options) => Promise<Response>;
|
|
102
153
|
/**
|
|
103
154
|
* ErrorLike
|
|
104
155
|
* =========
|
|
@@ -111,11 +162,6 @@ type ErrorLike = {
|
|
|
111
162
|
code?: string;
|
|
112
163
|
[key: string]: any;
|
|
113
164
|
};
|
|
114
|
-
/**
|
|
115
|
-
* Convenience alias that pins both generic types
|
|
116
|
-
* to `z.ZodTypeAny`, simplifying the contract declarations.
|
|
117
|
-
*/
|
|
118
|
-
type EndpointDefZ = EndpointDef<RequestSchema, ResponseSchema>;
|
|
119
165
|
/**
|
|
120
166
|
* RequestOptions
|
|
121
167
|
* ==============
|
|
@@ -149,10 +195,6 @@ type EndpointMethods<M extends Record<string, EndpointDefZ>> = {
|
|
|
149
195
|
*/
|
|
150
196
|
type TokenProvider = () => string | Promise<string>;
|
|
151
197
|
|
|
152
|
-
/**
|
|
153
|
-
* A richer extension of the native Error class that captures
|
|
154
|
-
* additional API error details such as HTTP status, code, and field errors.
|
|
155
|
-
*/
|
|
156
198
|
declare class RichError extends Error implements ErrorLike {
|
|
157
199
|
status?: number;
|
|
158
200
|
code?: string;
|
|
@@ -163,17 +205,6 @@ declare class RichError extends Error implements ErrorLike {
|
|
|
163
205
|
message: string;
|
|
164
206
|
});
|
|
165
207
|
}
|
|
166
|
-
/**
|
|
167
|
-
* ApiClient
|
|
168
|
-
* =========
|
|
169
|
-
* A robust, strongly-typed HTTP client that automatically builds API endpoint
|
|
170
|
-
* methods from Zod-based contracts, providing:
|
|
171
|
-
* - Input and response validation via Zod
|
|
172
|
-
* - Middleware support
|
|
173
|
-
* - Token-based authentication
|
|
174
|
-
* - Error normalization (RichError)
|
|
175
|
-
* - Optional caching, retries, and mock data
|
|
176
|
-
*/
|
|
177
208
|
declare class ApiClient<C extends Contracts, E extends ErrorLike = RichError> {
|
|
178
209
|
private config;
|
|
179
210
|
private contracts;
|
|
@@ -196,64 +227,34 @@ declare class ApiClient<C extends Contracts, E extends ErrorLike = RichError> {
|
|
|
196
227
|
max: number;
|
|
197
228
|
};
|
|
198
229
|
}, contracts: C);
|
|
199
|
-
/**
|
|
200
|
-
* Builds all API methods (`modules`) dynamically from the Zod contract definition.
|
|
201
|
-
* After `init()` is called, each endpoint can be invoked through `client.modules.moduleName.endpointName()`.
|
|
202
|
-
*/
|
|
203
230
|
init(): void;
|
|
204
|
-
/** Provides access to initialized modules after calling `init()`. */
|
|
205
231
|
get modules(): { [M in keyof C]: EndpointMethods<C[M]>; };
|
|
206
|
-
|
|
207
|
-
use<T>(middleware: Middleware<T>, options?: T): void;
|
|
208
|
-
/** Sets a global error handler function to unify error behavior. */
|
|
232
|
+
use<T>(middleware: Middleware<any, any, T>, options?: T): void;
|
|
209
233
|
onError(handler: (error: E) => void): void;
|
|
210
|
-
/** Defines a global transform function applied to all validated responses. */
|
|
211
234
|
useResponseTransform(fn: (data: any) => any): void;
|
|
212
|
-
/** Configures the retry logic (max attempts, backoff mode, etc.). */
|
|
213
235
|
setRetryConfig(config: ApiClient<C>["retryConfig"]): void;
|
|
214
|
-
/** Provides a custom token provider that returns tokens dynamically. */
|
|
215
236
|
setTokenProvider(provider: TokenProvider): void;
|
|
216
|
-
/** Enables mock responses instead of network requests. */
|
|
217
237
|
setMockMode(enabled: boolean, delay?: {
|
|
218
238
|
min: number;
|
|
219
239
|
max: number;
|
|
220
240
|
}): void;
|
|
221
|
-
/** Registers a wrapper schema for APIs that nest response data (e.g. `{ data, success, message }`). */
|
|
222
241
|
setResponseWrapper(wrapper: (successResponse: z.ZodTypeAny) => z.ZodTypeAny): void;
|
|
223
|
-
/** Retrieves the current auth token, using a provider if available. */
|
|
224
242
|
getCurrentToken(): Promise<string | undefined>;
|
|
225
|
-
/**
|
|
226
|
-
* Core request entry point used by auto-generated endpoint methods.
|
|
227
|
-
* Handles caching, deduplication, and mock mode routing.
|
|
228
|
-
*/
|
|
229
243
|
private request;
|
|
230
|
-
/**
|
|
231
|
-
* Full HTTP request workflow:
|
|
232
|
-
* - Token injection
|
|
233
|
-
* - Timeout support
|
|
234
|
-
* - Middleware pipeline
|
|
235
|
-
* - Fetch + response handling
|
|
236
|
-
* - Zod parsing + transformation
|
|
237
|
-
* - Caching
|
|
238
|
-
*/
|
|
239
244
|
private performRequestLogic;
|
|
240
|
-
/** Executes a function with retry logic and configurable backoff strategy. */
|
|
241
245
|
private executeWithRetry;
|
|
242
|
-
/** Calculates retry delay intervals for various backoff strategies. */
|
|
243
246
|
private getBackoffDelay;
|
|
244
|
-
/** Builds the final URL and request body from the endpoint definition and input payload. */
|
|
245
247
|
private buildUrlAndBody;
|
|
246
|
-
|
|
248
|
+
private extractRequestParts;
|
|
249
|
+
private isStructuredRequestInput;
|
|
250
|
+
private isObjectRecord;
|
|
251
|
+
private applyPathParams;
|
|
252
|
+
private appendQueryParams;
|
|
253
|
+
private appendQueryValue;
|
|
254
|
+
private appendFormValue;
|
|
255
|
+
private normalizeHeaders;
|
|
247
256
|
private createError;
|
|
248
|
-
/**
|
|
249
|
-
* Converts any thrown error to a standardized RichError instance.
|
|
250
|
-
* Also flattens Zod validation errors into readable messages.
|
|
251
|
-
*/
|
|
252
257
|
private normalizeError;
|
|
253
|
-
/**
|
|
254
|
-
* Handles mock-mode requests by simulating a delayed network call
|
|
255
|
-
* and returning validated mock data.
|
|
256
|
-
*/
|
|
257
258
|
private handleMockRequest;
|
|
258
259
|
}
|
|
259
260
|
|
|
@@ -262,7 +263,7 @@ type LoggingOptions = {
|
|
|
262
263
|
logResponse?: boolean;
|
|
263
264
|
debug?: boolean;
|
|
264
265
|
};
|
|
265
|
-
declare const loggingMiddleware: Middleware<LoggingOptions>;
|
|
266
|
+
declare const loggingMiddleware: Middleware<z$1.ZodTypeAny, z$1.ZodTypeAny, LoggingOptions>;
|
|
266
267
|
|
|
267
268
|
type RetryOptions = {
|
|
268
269
|
maxRetries?: number;
|
|
@@ -317,7 +318,7 @@ type AuthOptions = {
|
|
|
317
318
|
* authMiddleware({ refreshToken: tokenSupplier })
|
|
318
319
|
* );
|
|
319
320
|
*/
|
|
320
|
-
declare const authMiddleware: Middleware<AuthOptions>;
|
|
321
|
+
declare const authMiddleware: Middleware<z$1.ZodTypeAny, z$1.ZodTypeAny, AuthOptions>;
|
|
321
322
|
|
|
322
323
|
/**
|
|
323
324
|
* CacheOptions
|
|
@@ -365,26 +366,44 @@ type CacheOptions = {
|
|
|
365
366
|
*/
|
|
366
367
|
declare const cacheMiddleware: (options?: CacheOptions) => (ctx: MiddlewareContext, next: MiddlewareNext) => Promise<Response>;
|
|
367
368
|
|
|
368
|
-
|
|
369
|
+
type SymmetricKeyMaterial = {
|
|
370
|
+
type: "symmetric";
|
|
371
|
+
key: string;
|
|
372
|
+
};
|
|
373
|
+
type RSAKeyMaterial = {
|
|
374
|
+
type: "rsa";
|
|
375
|
+
publicKey: string;
|
|
376
|
+
privateKey: string;
|
|
377
|
+
};
|
|
378
|
+
type KeyMaterial = SymmetricKeyMaterial | RSAKeyMaterial;
|
|
379
|
+
type CustomHandlers = {
|
|
380
|
+
encrypt: (value: string, key: KeyMaterial) => string | Promise<string>;
|
|
381
|
+
decrypt: (value: string, key: KeyMaterial) => string | Promise<string>;
|
|
382
|
+
};
|
|
383
|
+
interface EncryptionOptions {
|
|
384
|
+
keyProvider: () => KeyMaterial | Promise<KeyMaterial>;
|
|
385
|
+
customHandlers?: CustomHandlers;
|
|
386
|
+
/**
|
|
387
|
+
* true = throw when encryption/decryption fails, which avoids leaking plaintext.
|
|
388
|
+
* false = log and continue/fallback to the original response.
|
|
389
|
+
* Default: true
|
|
390
|
+
*/
|
|
391
|
+
failClosed?: boolean;
|
|
392
|
+
}
|
|
393
|
+
declare function processDeep<T = unknown>(data: unknown, map: DeepEncryptionMap | null | undefined, defaultMethod: EncryptionMethod, transform: (value: unknown, method: EncryptionMethod) => Promise<unknown>): Promise<T>;
|
|
394
|
+
declare const encryptionMiddleware: Middleware<z.ZodTypeAny, z.ZodTypeAny, EncryptionOptions>;
|
|
395
|
+
|
|
396
|
+
type OptionalUndefinedBody<T extends z.ZodTypeAny> = T extends z.ZodUndefined ? z.ZodOptional<T> : T;
|
|
397
|
+
declare const makeRequestSchema: <TPath extends z.ZodRawShape = {}, TQuery extends z.ZodRawShape = {}, TBody extends z.ZodTypeAny = z.ZodUndefined, THeaders extends z.ZodTypeAny = z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>() => (defs?: {
|
|
369
398
|
path?: z.ZodObject<TPath>;
|
|
370
399
|
query?: z.ZodObject<TQuery>;
|
|
371
400
|
body?: TBody;
|
|
372
|
-
headers?:
|
|
401
|
+
headers?: THeaders;
|
|
373
402
|
}) => z.ZodObject<{
|
|
374
|
-
path: z.ZodOptional<z.ZodObject<
|
|
375
|
-
query: z.ZodOptional<z.ZodObject<
|
|
376
|
-
body: TBody
|
|
377
|
-
headers:
|
|
378
|
-
},
|
|
379
|
-
path: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>> | z.ZodOptional<z.ZodObject<TPath, z.UnknownKeysParam, z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<TPath>, any> extends infer T_5 ? { [k in keyof T_5]: T_5[k]; } : never, z.baseObjectInputType<TPath> extends infer T_6 ? { [k_1 in keyof T_6]: T_6[k_1]; } : never>>;
|
|
380
|
-
query: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>> | z.ZodOptional<z.ZodObject<TQuery, z.UnknownKeysParam, z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<TQuery>, any> extends infer T_7 ? { [k_2 in keyof T_7]: T_7[k_2]; } : never, z.baseObjectInputType<TQuery> extends infer T_8 ? { [k_3 in keyof T_8]: T_8[k_3]; } : never>>;
|
|
381
|
-
body: TBody | z.ZodUndefined;
|
|
382
|
-
headers: any;
|
|
383
|
-
}>, any> extends infer T_4 ? { [k_4 in keyof T_4]: T_4[k_4]; } : never, z.baseObjectInputType<{
|
|
384
|
-
path: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>> | z.ZodOptional<z.ZodObject<TPath, z.UnknownKeysParam, z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<TPath>, any> extends infer T_10 ? { [k in keyof T_10]: T_10[k]; } : never, z.baseObjectInputType<TPath> extends infer T_11 ? { [k_1 in keyof T_11]: T_11[k_1]; } : never>>;
|
|
385
|
-
query: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>> | z.ZodOptional<z.ZodObject<TQuery, z.UnknownKeysParam, z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<TQuery>, any> extends infer T_12 ? { [k_2 in keyof T_12]: T_12[k_2]; } : never, z.baseObjectInputType<TQuery> extends infer T_13 ? { [k_3 in keyof T_13]: T_13[k_3]; } : never>>;
|
|
386
|
-
body: TBody | z.ZodUndefined;
|
|
387
|
-
headers: any;
|
|
388
|
-
}> extends infer T_9 ? { [k_5 in keyof T_9]: T_9[k_5]; } : never>;
|
|
403
|
+
path: z.ZodOptional<z.ZodObject<TPath, z.core.$strip>>;
|
|
404
|
+
query: z.ZodOptional<z.ZodObject<TQuery, z.core.$strip>>;
|
|
405
|
+
body: OptionalUndefinedBody<TBody>;
|
|
406
|
+
headers: THeaders;
|
|
407
|
+
}, z.core.$strip>;
|
|
389
408
|
|
|
390
|
-
export { ApiClient, type AuthOptions, type CacheOptions, type Contracts, type EndpointDef, type EndpointDefZ, type EndpointMethods, type ErrorLike, type LoggingOptions, type Middleware, type MiddlewareContext, type MiddlewareNext, type RequestOptions, type RequestSchema, type ResponseSchema, type RetryOptions, RichError, type TokenProvider, authMiddleware, cacheMiddleware, loggingMiddleware, makeRequestSchema, retryMiddleware };
|
|
409
|
+
export { ApiClient, type AuthOptions, type CacheOptions, type Contracts, type DeepEncryptionMap, type EncryptionConfig, type EncryptionMethod, type EncryptionOptions, type EndpointDef, type EndpointDefZ, type EndpointMethods, type ErrorLike, type LoggingOptions, type Method, type Middleware, type MiddlewareContext, type MiddlewareNext, type RequestOptions, type RequestParts, type RequestSchema, type ResponseSchema, type RetryOptions, RichError, type TokenProvider, authMiddleware, cacheMiddleware, encryptionMiddleware, loggingMiddleware, makeRequestSchema, processDeep, retryMiddleware };
|