zlient 1.0.8 → 1.0.10
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/endpoint/base-endpoint.d.ts +117 -0
- package/dist/endpoint/base-endpoint.d.ts.map +1 -0
- package/dist/http/{HttpClient.d.ts → http-client.d.ts} +1 -1
- package/dist/http/http-client.d.ts.map +1 -0
- package/dist/index.cjs +83 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +83 -57
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/metrics.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/endpoint/BaseEndpoint.d.ts +0 -65
- package/dist/endpoint/BaseEndpoint.d.ts.map +0 -1
- package/dist/http/HttpClient.d.ts.map +0 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { HttpClient } from '../http/http-client';
|
|
3
|
+
import { HTTPMethod } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Request configuration for endpoint calls.
|
|
6
|
+
* Wrapper object containing all request parameters.
|
|
7
|
+
*
|
|
8
|
+
* @template ReqSchema - Zod schema for request validation
|
|
9
|
+
* @template PathParams - Type for path parameters
|
|
10
|
+
* @template QueryParams - Type for query parameters
|
|
11
|
+
*/
|
|
12
|
+
export type EndpointCallConfig<ReqSchema extends z.ZodType, PathParams = never, QueryParams = never> = {
|
|
13
|
+
/** Request body data (for POST, PUT, PATCH, etc.) or request args */
|
|
14
|
+
data?: z.infer<ReqSchema>;
|
|
15
|
+
/** Path parameters for dynamic path construction */
|
|
16
|
+
pathParams?: PathParams;
|
|
17
|
+
/** Query string parameters */
|
|
18
|
+
query?: QueryParams;
|
|
19
|
+
/** Request headers */
|
|
20
|
+
headers?: Record<string, string>;
|
|
21
|
+
/** Override base URL for this call */
|
|
22
|
+
baseUrlKey?: string;
|
|
23
|
+
/** Abort controller signal for cancellation */
|
|
24
|
+
signal?: globalThis.AbortSignal;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Generic, strongly-typed endpoint with Zod schemas for request and response validation.
|
|
28
|
+
* Extend this class to create type-safe API endpoints.
|
|
29
|
+
*
|
|
30
|
+
* @template ReqSchema - Zod schema for request validation
|
|
31
|
+
* @template ResSchema - Zod schema for response validation
|
|
32
|
+
* @template PathParams - Type for path parameters (optional)
|
|
33
|
+
* @template QueryParams - Type for query parameters (optional)
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* const UserSchema = z.object({ id: z.number(), name: z.string() });
|
|
38
|
+
* const CreateUserSchema = z.object({ name: z.string() });
|
|
39
|
+
*
|
|
40
|
+
* type UserPathParams = { id: string };
|
|
41
|
+
* type UserQueryParams = { include?: string; limit?: number };
|
|
42
|
+
*
|
|
43
|
+
* class GetUser extends BaseEndpoint<
|
|
44
|
+
* typeof CreateUserSchema,
|
|
45
|
+
* typeof UserSchema,
|
|
46
|
+
* UserPathParams,
|
|
47
|
+
* UserQueryParams
|
|
48
|
+
* > {
|
|
49
|
+
* protected method = 'GET' as const;
|
|
50
|
+
* protected path = (params: UserPathParams) => `/users/${params.id}`;
|
|
51
|
+
*
|
|
52
|
+
* constructor(client: HttpClient) {
|
|
53
|
+
* super(client, {
|
|
54
|
+
* requestSchema: CreateUserSchema,
|
|
55
|
+
* responseSchema: UserSchema
|
|
56
|
+
* });
|
|
57
|
+
* }
|
|
58
|
+
* }
|
|
59
|
+
*
|
|
60
|
+
* // Usage:
|
|
61
|
+
* const user = await endpoint.call({
|
|
62
|
+
* pathParams: { id: '123' },
|
|
63
|
+
* query: { include: 'posts', limit: 10 }
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare abstract class BaseEndpoint<ReqSchema extends z.ZodType, ResSchema extends z.ZodType, PathParams = never, QueryParams = never> {
|
|
68
|
+
protected client: HttpClient;
|
|
69
|
+
/** HTTP method for this endpoint */
|
|
70
|
+
protected abstract readonly method: keyof typeof HTTPMethod;
|
|
71
|
+
/** URL path (can be a function for dynamic paths) */
|
|
72
|
+
protected abstract readonly path: string | ((params: PathParams) => string);
|
|
73
|
+
/** Additional options for the request */
|
|
74
|
+
protected readonly options?: {
|
|
75
|
+
/** Override base URL for this call */
|
|
76
|
+
baseUrlKey?: string;
|
|
77
|
+
};
|
|
78
|
+
/** Optional request schema for validation */
|
|
79
|
+
protected readonly requestSchema?: ReqSchema;
|
|
80
|
+
/** Response schema for validation */
|
|
81
|
+
protected readonly responseSchema: ResSchema;
|
|
82
|
+
/**
|
|
83
|
+
* @param client - HttpClient instance
|
|
84
|
+
* @param cfg - Configuration with request and response schemas
|
|
85
|
+
*/
|
|
86
|
+
constructor(client: HttpClient, cfg: {
|
|
87
|
+
requestSchema?: ReqSchema;
|
|
88
|
+
responseSchema: ResSchema;
|
|
89
|
+
});
|
|
90
|
+
/**
|
|
91
|
+
* Call the endpoint with strong typing derived from schemas.
|
|
92
|
+
* Validates request data before sending and response data after receiving.
|
|
93
|
+
*
|
|
94
|
+
* @param config - Request configuration object containing all parameters
|
|
95
|
+
* @returns Promise resolving to validated response data (typed by ResSchema)
|
|
96
|
+
* @throws {ZodError} If request validation fails
|
|
97
|
+
* @throws {ApiError} If response validation fails or request fails
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* const endpoint = new GetUser(client);
|
|
102
|
+
* const user = await endpoint.call({
|
|
103
|
+
* pathParams: { id: '123' },
|
|
104
|
+
* query: { include: 'posts' }
|
|
105
|
+
* });
|
|
106
|
+
* // With additional options:
|
|
107
|
+
* const user = await endpoint.call({
|
|
108
|
+
* data: { name: 'John' },
|
|
109
|
+
* pathParams: { id: '123' },
|
|
110
|
+
* headers: { 'X-Custom': 'value' },
|
|
111
|
+
* query: { include: 'posts' }
|
|
112
|
+
* });
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
call(config?: EndpointCallConfig<ReqSchema, PathParams, QueryParams>): Promise<z.infer<ResSchema>>;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=base-endpoint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-endpoint.d.ts","sourceRoot":"","sources":["../../lib/endpoint/base-endpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,CAC5B,SAAS,SAAS,CAAC,CAAC,OAAO,EAC3B,UAAU,GAAG,KAAK,EAClB,WAAW,GAAG,KAAK,IACjB;IACF,qEAAqE;IACrE,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC1B,oDAAoD;IACpD,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,sBAAsB;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC;CACjC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,8BAAsB,YAAY,CAChC,SAAS,SAAS,CAAC,CAAC,OAAO,EAC3B,SAAS,SAAS,CAAC,CAAC,OAAO,EAC3B,UAAU,GAAG,KAAK,EAClB,WAAW,GAAG,KAAK;IAqBjB,SAAS,CAAC,MAAM,EAAE,UAAU;IAnB9B,oCAAoC;IACpC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,UAAU,CAAC;IAC5D,qDAAqD;IACrD,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,UAAU,KAAK,MAAM,CAAC,CAAC;IAC5E,yCAAyC;IACzC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;QAC3B,sCAAsC;QACtC,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,6CAA6C;IAC7C,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IAC7C,qCAAqC;IACrC,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,SAAS,CAAC;IAE7C;;;OAGG;gBAES,MAAM,EAAE,UAAU,EAC5B,GAAG,EAAE;QACH,aAAa,CAAC,EAAE,SAAS,CAAC;QAC1B,cAAc,EAAE,SAAS,CAAC;KAC3B;IAMH;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACG,IAAI,CACR,MAAM,GAAE,kBAAkB,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,CAI5D,GACA,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;CAgC/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../lib/http/http-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI5C,OAAO,EAEL,aAAa,EAEb,UAAU,EAEV,cAAc,EAGf,MAAM,UAAU,CAAC;AAElB;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,OAAO,CAAmB;IAElC;;;;;OAKG;gBACS,IAAI,EAAE,aAAa;IA4C/B;;;;;;;;OAQG;IACH,OAAO,CAAC,IAAI,EAAE,YAAY;IAI1B,OAAO,CAAC,cAAc;IAUtB;;;OAGG;IACH,OAAO,CAAC,KAAK;IAIb;;;OAGG;YACW,SAAS;IAmBvB;;;OAGG;YACW,cAAc;IAM5B;;;OAGG;YACW,aAAa;IAM3B;;;;;;;;;;;;;;;;;OAiBG;IACG,OAAO,CAAC,CAAC,GAAG,OAAO,EACvB,MAAM,EAAE,MAAM,OAAO,UAAU,EAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE,CAAC;IAmI3C;;;;;;;OAOG;IACG,GAAG,CAAC,CAAC,GAAG,OAAO,EACnB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE,CAAC;IAI3C;;;;;;;OAOG;IACG,IAAI,CAAC,CAAC,GAAG,OAAO,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE,CAAC;IAI3C;;;;;;;OAOG;IACG,GAAG,CAAC,CAAC,GAAG,OAAO,EACnB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE,CAAC;IAI3C;;;;;;;OAOG;IACG,KAAK,CAAC,CAAC,GAAG,OAAO,EACrB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE,CAAC;IAI3C;;;;;;;OAOG;IACG,MAAM,CAAC,CAAC,GAAG,OAAO,EACtB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE,CAAC;CAG5C"}
|
package/dist/index.cjs
CHANGED
|
@@ -37,7 +37,7 @@ const HTTPMethod = {
|
|
|
37
37
|
/**
|
|
38
38
|
* Custom error class for API-related errors.
|
|
39
39
|
* Includes HTTP status codes, response details, and validation errors.
|
|
40
|
-
*
|
|
40
|
+
*
|
|
41
41
|
* @example
|
|
42
42
|
* ```ts
|
|
43
43
|
* throw new ApiError('Invalid request', {
|
|
@@ -103,10 +103,10 @@ const PaginationSchema = zod.z.object({
|
|
|
103
103
|
/**
|
|
104
104
|
* Converts query parameters to a URL query string.
|
|
105
105
|
* Filters out undefined values automatically.
|
|
106
|
-
*
|
|
106
|
+
*
|
|
107
107
|
* @param q - Query parameters as URLSearchParams or object
|
|
108
108
|
* @returns Query string with leading '?' or empty string
|
|
109
|
-
*
|
|
109
|
+
*
|
|
110
110
|
* @example
|
|
111
111
|
* ```ts
|
|
112
112
|
* toQueryString({ page: 1, filter: 'active' }) // "?page=1&filter=active"
|
|
@@ -139,12 +139,12 @@ var NoAuth = class {
|
|
|
139
139
|
/**
|
|
140
140
|
* API Key authentication provider.
|
|
141
141
|
* Supports both header-based and query parameter-based authentication.
|
|
142
|
-
*
|
|
142
|
+
*
|
|
143
143
|
* @example
|
|
144
144
|
* ```ts
|
|
145
145
|
* // Header-based
|
|
146
146
|
* const auth = new ApiKeyAuth({ header: 'X-API-Key', value: 'secret' });
|
|
147
|
-
*
|
|
147
|
+
*
|
|
148
148
|
* // Query parameter-based
|
|
149
149
|
* const auth = new ApiKeyAuth({ query: 'apiKey', value: 'secret' });
|
|
150
150
|
* ```
|
|
@@ -170,12 +170,12 @@ var ApiKeyAuth = class {
|
|
|
170
170
|
/**
|
|
171
171
|
* Bearer token authentication provider.
|
|
172
172
|
* Supports both static tokens and dynamic token fetching (e.g., for OAuth2 refresh).
|
|
173
|
-
*
|
|
173
|
+
*
|
|
174
174
|
* @example
|
|
175
175
|
* ```ts
|
|
176
176
|
* // Static token
|
|
177
177
|
* const auth = new BearerTokenAuth(() => 'my-token');
|
|
178
|
-
*
|
|
178
|
+
*
|
|
179
179
|
* // Dynamic token with refresh
|
|
180
180
|
* const auth = new BearerTokenAuth(async () => {
|
|
181
181
|
* return await refreshAccessToken();
|
|
@@ -201,11 +201,11 @@ var BearerTokenAuth = class {
|
|
|
201
201
|
/**
|
|
202
202
|
* Safely parse data with a Zod schema without throwing.
|
|
203
203
|
* Returns a result object with success status and data or error.
|
|
204
|
-
*
|
|
204
|
+
*
|
|
205
205
|
* @param schema - Zod schema to validate against
|
|
206
206
|
* @param data - Data to validate
|
|
207
207
|
* @returns Result object with success flag and data/error
|
|
208
|
-
*
|
|
208
|
+
*
|
|
209
209
|
* @example
|
|
210
210
|
* ```ts
|
|
211
211
|
* const result = safeParse(UserSchema, userData);
|
|
@@ -230,12 +230,12 @@ function safeParse(schema, data) {
|
|
|
230
230
|
/**
|
|
231
231
|
* Parse data with a Zod schema, throwing an ApiError on validation failure.
|
|
232
232
|
* Use this when you want to fail fast on invalid data.
|
|
233
|
-
*
|
|
233
|
+
*
|
|
234
234
|
* @param schema - Zod schema to validate against
|
|
235
235
|
* @param data - Data to validate
|
|
236
236
|
* @returns Validated and typed data
|
|
237
237
|
* @throws {ApiError} If validation fails
|
|
238
|
-
*
|
|
238
|
+
*
|
|
239
239
|
* @example
|
|
240
240
|
* ```ts
|
|
241
241
|
* try {
|
|
@@ -424,11 +424,11 @@ var ConsoleMetricsCollector = class {
|
|
|
424
424
|
};
|
|
425
425
|
|
|
426
426
|
//#endregion
|
|
427
|
-
//#region lib/http/
|
|
427
|
+
//#region lib/http/http-client.ts
|
|
428
428
|
/**
|
|
429
429
|
* HTTP client with built-in retry logic, authentication, and interceptors.
|
|
430
430
|
* Supports multiple base URLs, type-safe requests, and comprehensive error handling.
|
|
431
|
-
*
|
|
431
|
+
*
|
|
432
432
|
* @example
|
|
433
433
|
* ```ts
|
|
434
434
|
* const client = new HttpClient({
|
|
@@ -437,7 +437,7 @@ var ConsoleMetricsCollector = class {
|
|
|
437
437
|
* retry: { maxRetries: 3, baseDelayMs: 1000 },
|
|
438
438
|
* timeout: { requestTimeoutMs: 30000 }
|
|
439
439
|
* });
|
|
440
|
-
*
|
|
440
|
+
*
|
|
441
441
|
* const { data } = await client.request('GET', '/users', undefined, { query: { page: 1 } });
|
|
442
442
|
* ```
|
|
443
443
|
*/
|
|
@@ -453,7 +453,7 @@ var HttpClient = class {
|
|
|
453
453
|
metrics;
|
|
454
454
|
/**
|
|
455
455
|
* Creates a new HTTP client instance.
|
|
456
|
-
*
|
|
456
|
+
*
|
|
457
457
|
* @param opts - Client configuration options
|
|
458
458
|
* @throws {Error} If no fetch implementation is available
|
|
459
459
|
*/
|
|
@@ -482,7 +482,7 @@ var HttpClient = class {
|
|
|
482
482
|
}
|
|
483
483
|
/**
|
|
484
484
|
* Set or update the authentication provider.
|
|
485
|
-
*
|
|
485
|
+
*
|
|
486
486
|
* @param auth - Authentication provider instance
|
|
487
487
|
* @example
|
|
488
488
|
* ```ts
|
|
@@ -551,14 +551,14 @@ var HttpClient = class {
|
|
|
551
551
|
}
|
|
552
552
|
/**
|
|
553
553
|
* Make an HTTP request with automatic retry, authentication, and validation.
|
|
554
|
-
*
|
|
554
|
+
*
|
|
555
555
|
* @param method - HTTP method (GET, POST, PUT, etc.)
|
|
556
556
|
* @param path - Request path (will be appended to base URL)
|
|
557
557
|
* @param body - Request body (will be JSON.stringify'd if Content-Type is json)
|
|
558
558
|
* @param options - Additional request options (headers, query params, etc.)
|
|
559
559
|
* @returns Promise resolving to response data and Response object
|
|
560
560
|
* @throws {ApiError} If request fails or response validation fails
|
|
561
|
-
*
|
|
561
|
+
*
|
|
562
562
|
* @example
|
|
563
563
|
* ```ts
|
|
564
564
|
* const { data, response } = await client.request('GET', '/users', undefined, {
|
|
@@ -673,7 +673,7 @@ var HttpClient = class {
|
|
|
673
673
|
}
|
|
674
674
|
/**
|
|
675
675
|
* Convenience method for GET requests.
|
|
676
|
-
*
|
|
676
|
+
*
|
|
677
677
|
* @example
|
|
678
678
|
* ```ts
|
|
679
679
|
* const { data } = await client.get('/users', { query: { page: 1 } });
|
|
@@ -684,7 +684,7 @@ var HttpClient = class {
|
|
|
684
684
|
}
|
|
685
685
|
/**
|
|
686
686
|
* Convenience method for POST requests.
|
|
687
|
-
*
|
|
687
|
+
*
|
|
688
688
|
* @example
|
|
689
689
|
* ```ts
|
|
690
690
|
* const { data } = await client.post('/users', { name: 'John' });
|
|
@@ -695,7 +695,7 @@ var HttpClient = class {
|
|
|
695
695
|
}
|
|
696
696
|
/**
|
|
697
697
|
* Convenience method for PUT requests.
|
|
698
|
-
*
|
|
698
|
+
*
|
|
699
699
|
* @example
|
|
700
700
|
* ```ts
|
|
701
701
|
* const { data } = await client.put('/users/1', { name: 'John Updated' });
|
|
@@ -706,7 +706,7 @@ var HttpClient = class {
|
|
|
706
706
|
}
|
|
707
707
|
/**
|
|
708
708
|
* Convenience method for PATCH requests.
|
|
709
|
-
*
|
|
709
|
+
*
|
|
710
710
|
* @example
|
|
711
711
|
* ```ts
|
|
712
712
|
* const { data } = await client.patch('/users/1', { name: 'John' });
|
|
@@ -717,7 +717,7 @@ var HttpClient = class {
|
|
|
717
717
|
}
|
|
718
718
|
/**
|
|
719
719
|
* Convenience method for DELETE requests.
|
|
720
|
-
*
|
|
720
|
+
*
|
|
721
721
|
* @example
|
|
722
722
|
* ```ts
|
|
723
723
|
* const { data } = await client.delete('/users/1');
|
|
@@ -729,33 +729,51 @@ var HttpClient = class {
|
|
|
729
729
|
};
|
|
730
730
|
|
|
731
731
|
//#endregion
|
|
732
|
-
//#region lib/endpoint/
|
|
732
|
+
//#region lib/endpoint/base-endpoint.ts
|
|
733
733
|
/**
|
|
734
734
|
* Generic, strongly-typed endpoint with Zod schemas for request and response validation.
|
|
735
735
|
* Extend this class to create type-safe API endpoints.
|
|
736
|
-
*
|
|
736
|
+
*
|
|
737
737
|
* @template ReqSchema - Zod schema for request validation
|
|
738
738
|
* @template ResSchema - Zod schema for response validation
|
|
739
|
-
*
|
|
739
|
+
* @template PathParams - Type for path parameters (optional)
|
|
740
|
+
* @template QueryParams - Type for query parameters (optional)
|
|
741
|
+
*
|
|
740
742
|
* @example
|
|
741
743
|
* ```ts
|
|
742
744
|
* const UserSchema = z.object({ id: z.number(), name: z.string() });
|
|
743
745
|
* const CreateUserSchema = z.object({ name: z.string() });
|
|
744
|
-
*
|
|
745
|
-
*
|
|
746
|
+
*
|
|
747
|
+
* type UserPathParams = { id: string };
|
|
748
|
+
* type UserQueryParams = { include?: string; limit?: number };
|
|
749
|
+
*
|
|
750
|
+
* class GetUser extends BaseEndpoint<
|
|
751
|
+
* typeof CreateUserSchema,
|
|
752
|
+
* typeof UserSchema,
|
|
753
|
+
* UserPathParams,
|
|
754
|
+
* UserQueryParams
|
|
755
|
+
* > {
|
|
746
756
|
* protected method = 'GET' as const;
|
|
747
|
-
* protected path = (
|
|
748
|
-
*
|
|
757
|
+
* protected path = (params: UserPathParams) => `/users/${params.id}`;
|
|
758
|
+
*
|
|
749
759
|
* constructor(client: HttpClient) {
|
|
750
|
-
* super(client, {
|
|
760
|
+
* super(client, {
|
|
751
761
|
* requestSchema: CreateUserSchema,
|
|
752
|
-
* responseSchema: UserSchema
|
|
762
|
+
* responseSchema: UserSchema
|
|
753
763
|
* });
|
|
754
764
|
* }
|
|
755
765
|
* }
|
|
766
|
+
*
|
|
767
|
+
* // Usage:
|
|
768
|
+
* const user = await endpoint.call({
|
|
769
|
+
* pathParams: { id: '123' },
|
|
770
|
+
* query: { include: 'posts', limit: 10 }
|
|
771
|
+
* });
|
|
756
772
|
* ```
|
|
757
773
|
*/
|
|
758
774
|
var BaseEndpoint = class {
|
|
775
|
+
/** Additional options for the request */
|
|
776
|
+
options;
|
|
759
777
|
/** Optional request schema for validation */
|
|
760
778
|
requestSchema;
|
|
761
779
|
/** Response schema for validation */
|
|
@@ -772,37 +790,45 @@ var BaseEndpoint = class {
|
|
|
772
790
|
/**
|
|
773
791
|
* Call the endpoint with strong typing derived from schemas.
|
|
774
792
|
* Validates request data before sending and response data after receiving.
|
|
775
|
-
*
|
|
776
|
-
* @param
|
|
777
|
-
* @param options - Additional request options
|
|
793
|
+
*
|
|
794
|
+
* @param config - Request configuration object containing all parameters
|
|
778
795
|
* @returns Promise resolving to validated response data (typed by ResSchema)
|
|
779
796
|
* @throws {ZodError} If request validation fails
|
|
780
797
|
* @throws {ApiError} If response validation fails or request fails
|
|
781
|
-
*
|
|
798
|
+
*
|
|
782
799
|
* @example
|
|
783
800
|
* ```ts
|
|
784
801
|
* const endpoint = new GetUser(client);
|
|
785
|
-
* const user = await endpoint.call({
|
|
802
|
+
* const user = await endpoint.call({
|
|
803
|
+
* pathParams: { id: '123' },
|
|
804
|
+
* query: { include: 'posts' }
|
|
805
|
+
* });
|
|
806
|
+
* // With additional options:
|
|
807
|
+
* const user = await endpoint.call({
|
|
808
|
+
* data: { name: 'John' },
|
|
809
|
+
* pathParams: { id: '123' },
|
|
810
|
+
* headers: { 'X-Custom': 'value' },
|
|
811
|
+
* query: { include: 'posts' }
|
|
812
|
+
* });
|
|
786
813
|
* ```
|
|
787
814
|
*/
|
|
788
|
-
async call(
|
|
789
|
-
|
|
790
|
-
|
|
815
|
+
async call(config = {}) {
|
|
816
|
+
const { data, query, headers, baseUrlKey, signal, pathParams } = config;
|
|
817
|
+
if (this.requestSchema && data !== void 0) {
|
|
818
|
+
const parsed = this.requestSchema.safeParse(data);
|
|
791
819
|
if (!parsed.success) throw parsed.error;
|
|
792
820
|
}
|
|
793
|
-
const
|
|
794
|
-
const
|
|
795
|
-
const
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
...options,
|
|
803
|
-
query: mergedQuery && Object.keys(mergedQuery).length > 0 ? mergedQuery : options?.query
|
|
821
|
+
const pathArgs = pathParams ?? data;
|
|
822
|
+
const path = typeof this.path === "function" ? this.path(pathArgs) : this.path;
|
|
823
|
+
const body = this.method !== "GET" && this.method !== "HEAD" ? data : void 0;
|
|
824
|
+
const queryForRequest = query;
|
|
825
|
+
const { data: responseData } = await this.client.request(this.method, path, body, {
|
|
826
|
+
query: queryForRequest,
|
|
827
|
+
headers,
|
|
828
|
+
baseUrlKey: baseUrlKey ?? this.options?.baseUrlKey,
|
|
829
|
+
signal
|
|
804
830
|
});
|
|
805
|
-
return parseOrThrow(this.responseSchema,
|
|
831
|
+
return parseOrThrow(this.responseSchema, responseData);
|
|
806
832
|
}
|
|
807
833
|
};
|
|
808
834
|
|
|
@@ -811,7 +837,7 @@ var BaseEndpoint = class {
|
|
|
811
837
|
/**
|
|
812
838
|
* Common ID type that supports strings, numbers, or UUIDs.
|
|
813
839
|
* Use this for entity identifiers in your schemas.
|
|
814
|
-
*
|
|
840
|
+
*
|
|
815
841
|
* @example
|
|
816
842
|
* ```ts
|
|
817
843
|
* const UserSchema = z.object({ id: Id, name: z.string() });
|
|
@@ -825,7 +851,7 @@ const Id = zod.z.union([
|
|
|
825
851
|
/**
|
|
826
852
|
* Common timestamp fields for entities.
|
|
827
853
|
* Use this for database models with creation/update tracking.
|
|
828
|
-
*
|
|
854
|
+
*
|
|
829
855
|
* @example
|
|
830
856
|
* ```ts
|
|
831
857
|
* const UserSchema = z.object({
|
|
@@ -867,14 +893,14 @@ const ApiErrorSchema = zod.z.object({
|
|
|
867
893
|
/**
|
|
868
894
|
* Generic envelope wrapper for API responses.
|
|
869
895
|
* Provides consistent structure with success flag, data, error, and metadata.
|
|
870
|
-
*
|
|
896
|
+
*
|
|
871
897
|
* @param inner - Zod schema for the response data
|
|
872
898
|
* @returns Envelope schema wrapping the inner schema
|
|
873
|
-
*
|
|
899
|
+
*
|
|
874
900
|
* @example
|
|
875
901
|
* ```ts
|
|
876
902
|
* const UserResponseSchema = Envelope(z.object({ id: Id, name: z.string() }));
|
|
877
|
-
*
|
|
903
|
+
*
|
|
878
904
|
* // Response structure:
|
|
879
905
|
* // {
|
|
880
906
|
* // success: true,
|