zlient 1.0.11 → 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/README.md CHANGED
@@ -1,430 +1,139 @@
1
1
  # zlient
2
2
 
3
- A type-safe HTTP client framework with Zod validation for building robust API clients.
3
+ **The Type-Safe HTTP Client for Perfectionists.**
4
+
5
+ ![NPM Version](https://img.shields.io/npm/v/zlient?style=flat-square)
6
+ ![License](https://img.shields.io/npm/l/zlient?style=flat-square)
7
+ ![Downloads](https://img.shields.io/npm/dm/zlient?style=flat-square)
8
+
9
+ Build robust, type-safe API clients with automatic Zod validation, retry logic, and zero boilerplate.
4
10
 
5
11
  ## Features
6
12
 
7
- - 🔒 **Type-safe**: Full TypeScript support with automatic type inference
8
- - **Runtime validation**: Zod schemas for request/response validation
9
- - 🔄 **Retry logic**: Built-in configurable retry strategies with exponential backoff
10
- - 🎯 **Authentication**: Multiple auth providers (API Key, Bearer Token, Custom)
11
- - 🪝 **Interceptors**: Before request and after response hooks
12
- - ⏱️ **Timeouts**: Configurable request timeouts
13
- - 📦 **Multiple endpoints**: Easy service separation with base URL mapping
14
- - 📊 **Observability**: Built-in logging and metrics collection
15
- - 🎨 **Developer Experience**: Comprehensive JSDoc, helper methods, great error messages
16
- - 🏢 **Enterprise-ready**: Production-grade logging, metrics, and monitoring support
13
+ - **Functional API**: Define endpoints with pure functions and automatic type inference.
14
+ - **Type-Safe**: Full TypeScript support. Arguments and responses are strictly typed.
15
+ - **Zod Validation**: Runtime validation for requests, responses, query params, and path params.
16
+ - **Resilience**: Built-in exponential backoff retries and timeouts.
17
+ - **Auth**: Logic-safe authentication providers (Bearer, API Key, Custom) that handle edge cases.
18
+ - **Observability**: Hooks for structured logging and metrics.
19
+
20
+ ---
17
21
 
18
22
  ## Installation
19
23
 
20
24
  ```bash
21
25
  npm install zlient zod
22
26
  # or
23
- yarn add zlient zod
24
- # or
25
- pnpm add zlient zod
26
- # or
27
27
  bun add zlient zod
28
28
  ```
29
29
 
30
- ## Quick Start
31
-
32
- ```typescript
33
- import { AuthProvider, BaseEndpoint, ClientOptions, HttpClient, HTTPMethod, RequestOptions } from "zlient";
34
- import z from "zod";
35
-
36
- /**
37
- * Schemas
38
- */
39
- const todoItem = z.object({
40
- userId: z.number(),
41
- id: z.number(),
42
- title: z.string(),
43
- completed: z.boolean(),
44
- });
45
-
46
- const ListTodosRequest = z.object({});
47
- const ListTodosResponse = z.array(todoItem);
30
+ > **Note**: `zod` is a peer dependency. You must install it alongside `zlient`.
48
31
 
49
- const GetTodoRequest = z.object({
50
- id: z.number(),
51
- });
52
- const GetTodoResponse = todoItem;
53
-
54
-
55
- /**
56
- * Endpoints
57
- */
58
- class ListTodos extends BaseEndpoint<typeof ListTodosRequest, typeof ListTodosResponse> {
59
- protected readonly method = HTTPMethod.GET;
60
- protected readonly path = "/todos";
61
- constructor(client: HttpClient) { super(client, { requestSchema: ListTodosRequest, responseSchema: ListTodosResponse }); }
62
- }
63
-
64
- class GetTodo extends BaseEndpoint<typeof GetTodoRequest, typeof GetTodoResponse> {
65
- protected readonly method = HTTPMethod.GET;
66
- protected readonly path = (args: z.infer<typeof GetTodoRequest>) => `/todos/${args.id}`;
67
- constructor(client: HttpClient) { super(client, { requestSchema: GetTodoRequest, responseSchema: GetTodoResponse }); }
68
- }
69
-
70
- /**
71
- * Service
72
- */
73
- class TodosService {
74
- constructor(private client: HttpClient) { }
75
- list(args: z.infer<typeof ListTodosRequest>, options?: RequestOptions) { return new ListTodos(this.client).call(args, options); }
76
- get(args: z.infer<typeof GetTodoRequest>, options?: RequestOptions) { return new GetTodo(this.client).call(args, options); }
77
- }
78
-
79
- /**
80
- * SDK class for initialization
81
- */
82
- export class SDK {
83
- readonly http: HttpClient;
84
- readonly todos: TodosService;
85
-
86
- constructor(opts: ClientOptions & { auth?: AuthProvider }) {
87
- this.http = new HttpClient(opts);
88
- if (opts.auth) this.http.setAuth(opts.auth);
89
-
90
- // Initialize services
91
- this.todos = new TodosService(this.http);
92
- }
93
- }
94
-
95
-
96
- /**
97
- * Usage example
98
- */
99
- const sdk = new SDK({
100
- baseUrls: {
101
- default: "https://jsonplaceholder.typicode.com",
102
- },
103
- headers: {
104
- "X-SDK-Name": "example-sdk",
105
- "X-SDK-Version": "1.0.0",
106
- },
107
- retry: { maxRetries: 2, baseDelayMs: 100, jitter: 0.2, retryMethods: ["GET"] },
108
- timeout: { requestTimeoutMs: 5000 },
109
- });
32
+ ---
110
33
 
111
- async function demo() {
112
- const todos = await sdk.todos.list({});
113
- console.log(todos);
114
-
115
- const todo = await sdk.todos.get({ id: 1 });
116
- console.log(todo);
117
- }
118
-
119
- demo().catch(console.error);
120
- ```
121
-
122
- ## Core Concepts
123
-
124
- ### HttpClient
34
+ ## Quick Start
125
35
 
126
- The main HTTP client that handles requests, retries, authentication, and interceptors.
36
+ ### 1. Initialize Client
127
37
 
128
38
  ```typescript
129
- import { HttpClient, NoAuth } from 'zlient';
39
+ import { HttpClient } from 'zlient';
130
40
 
131
41
  const client = new HttpClient({
132
42
  baseUrls: {
133
43
  default: 'https://api.example.com',
134
- v2: 'https://api-v2.example.com',
135
44
  },
136
- headers: {
137
- 'Content-Type': 'application/json',
138
- },
139
- retry: {
140
- maxRetries: 3,
141
- baseDelayMs: 1000,
142
- jitter: 0.2,
143
- },
144
- timeout: {
145
- requestTimeoutMs: 30000,
146
- },
147
- auth: new NoAuth(),
45
+ retry: { maxRetries: 3 },
148
46
  });
149
47
  ```
150
48
 
151
- ### Authentication
49
+ ### 2. Define Endpoint
152
50
 
153
- #### Bearer Token
51
+ Use `createEndpoint` to build a type-safe definition. No classes required.
154
52
 
155
53
  ```typescript
156
- import { BearerTokenAuth } from 'zlient';
157
-
158
- const auth = new BearerTokenAuth(async () => {
159
- // Fetch token from your auth service
160
- return await getAccessToken();
161
- });
162
-
163
- client.setAuth(auth);
164
- ```
165
-
166
- #### API Key
167
-
168
- ```typescript
169
- import { ApiKeyAuth } from 'zlient';
170
-
171
- // Header-based
172
- const auth = new ApiKeyAuth({
173
- header: 'X-API-Key',
174
- value: 'your-api-key',
175
- });
54
+ import { z } from 'zod';
176
55
 
177
- // Query parameter-based
178
- const auth = new ApiKeyAuth({
179
- query: 'apiKey',
180
- value: 'your-api-key',
56
+ const getUser = client.createEndpoint({
57
+ method: 'GET',
58
+ path: (params) => `/users/${params.id}`,
59
+ // Strict schemas for all inputs
60
+ pathParams: z.object({ id: z.string() }),
61
+ response: z.object({
62
+ id: z.string(),
63
+ name: z.string(),
64
+ email: z.string().email(),
65
+ }),
181
66
  });
182
67
  ```
183
68
 
184
- #### Custom Auth
185
-
186
- ```typescript
187
- import { AuthProvider } from 'zlient';
188
-
189
- class CustomAuth implements AuthProvider {
190
- async apply({ init }) {
191
- init.headers = {
192
- ...init.headers,
193
- 'X-Custom-Auth': 'custom-value',
194
- };
195
- }
196
- }
197
- ```
198
-
199
- ### BaseEndpoint
69
+ ### 3. Call It
200
70
 
201
- Create type-safe endpoints with automatic validation:
71
+ TypeScript will enforce inputs and infer the response type automatically.
202
72
 
203
73
  ```typescript
204
- import { BaseEndpoint, HttpClient } from 'zlient';
205
- import { z } from 'zod';
206
-
207
- const CreateUserSchema = z.object({
208
- name: z.string(),
209
- email: z.string().email(),
210
- });
211
-
212
- const UserResponseSchema = z.object({
213
- id: z.number(),
214
- name: z.string(),
215
- email: z.string().email(),
216
- createdAt: z.string().datetime(),
74
+ const user = await getUser.call({
75
+ pathParams: { id: '123' },
217
76
  });
218
77
 
219
- class CreateUserEndpoint extends BaseEndpoint<
220
- typeof CreateUserSchema,
221
- typeof UserResponseSchema
222
- > {
223
- protected method = 'POST' as const;
224
- protected path = '/users';
225
-
226
- constructor(client: HttpClient) {
227
- super(client, {
228
- requestSchema: CreateUserSchema,
229
- responseSchema: UserResponseSchema,
230
- });
231
- }
232
- }
233
-
234
- // Usage
235
- const endpoint = new CreateUserEndpoint(client);
236
- const user = await endpoint.call({
237
- name: 'John Doe',
238
- email: 'john@example.com',
239
- });
78
+ // `user` is typed as { id: string; name: string; email: string }
79
+ console.log(user.name);
240
80
  ```
241
81
 
242
- ### Interceptors
243
-
244
- Add hooks to inspect or modify requests and responses:
82
+ ---
245
83
 
246
- ```typescript
247
- const client = new HttpClient({
248
- baseUrls: { default: 'https://api.example.com' },
249
- interceptors: {
250
- beforeRequest: [
251
- async ({ url, init }) => {
252
- console.log('Making request to:', url);
253
- },
254
- ],
255
- afterResponse: [
256
- async ({ request, response, parsed }) => {
257
- console.log('Response received:', response.status);
258
- },
259
- ],
260
- },
261
- });
262
- ```
84
+ ## Advanced Usage
263
85
 
264
- ### Common Schemas
86
+ ### Authentication
265
87
 
266
- The package includes common reusable schemas:
88
+ Zlient provides built-in auth providers that safely handle headers.
267
89
 
268
90
  ```typescript
269
- import { Id, Timestamps, Meta, ApiErrorSchema, Envelope } from 'zlient';
91
+ import { BearerTokenAuth, ApiKeyAuth } from 'zlient';
270
92
 
271
- // Use in your schemas
272
- const MyEntitySchema = z.object({
273
- id: Id,
274
- name: z.string(),
275
- ...Timestamps.shape,
276
- });
93
+ // Bearer Token (Dynamic)
94
+ client.setAuth(new BearerTokenAuth(async () => {
95
+ return await getLatestToken(); // Auto-refresh logic supported
96
+ }));
277
97
 
278
- // Wrap responses in an envelope
279
- const MyResponseSchema = Envelope(MyEntitySchema);
98
+ // API Key (Header or Query)
99
+ client.setAuth(new ApiKeyAuth({ header: 'X-API-KEY', value: 'secret' }));
280
100
  ```
281
101
 
282
- ## Advanced Usage
102
+ ### Multiple Status Codes
283
103
 
284
- ### Multiple Base URLs
104
+ Handle different responses for different status codes.
285
105
 
286
106
  ```typescript
287
- const client = new HttpClient({
288
- baseUrls: {
289
- default: 'https://api.example.com',
290
- auth: 'https://auth.example.com',
291
- cdn: 'https://cdn.example.com',
107
+ const createPost = client.createEndpoint({
108
+ method: 'POST',
109
+ path: '/posts',
110
+ request: z.object({ title: z.string() }),
111
+ response: {
112
+ 201: z.object({ id: z.string(), status: z.literal('created') }),
113
+ 400: z.object({ error: z.string(), code: z.literal('validation_error') }),
292
114
  },
293
115
  });
294
116
 
295
- // Use specific base URL for a request
296
- await endpoint.call(data, { baseUrlKey: 'auth' });
117
+ const result = await createPost.call({ data: { title: 'Hello' } });
118
+ // `result` type is the union of the 201 and 400 schemas
297
119
  ```
298
120
 
299
- ### Request Options
121
+ ### Metrics & Logging
300
122
 
301
- ```typescript
302
- await endpoint.call(data, {
303
- headers: { 'X-Custom-Header': 'value' },
304
- baseUrlKey: 'v2',
305
- signal: abortController.signal,
306
- query: { filter: 'active', page: 1 },
307
- });
308
- ```
309
-
310
- ### Logging and Metrics
311
-
312
- #### Structured Logging
123
+ Integrate with any monitoring stack (Datadog, Prometheus, etc.).
313
124
 
314
125
  ```typescript
315
- import { HttpClient, ConsoleLogger, LogLevel } from 'zlient';
126
+ import { InMemoryMetricsCollector, ConsoleLogger } from 'zlient';
316
127
 
317
128
  const client = new HttpClient({
318
- baseUrls: { default: 'https://api.example.com' },
319
- logger: new ConsoleLogger(LogLevel.INFO),
129
+ baseUrls: { default: '...' },
130
+ logger: new ConsoleLogger(),
131
+ metrics: new InMemoryMetricsCollector(),
320
132
  });
321
-
322
- // All requests are automatically logged with duration, status, etc.
323
- ```
324
-
325
- #### Metrics Collection
326
-
327
- ```typescript
328
- import { HttpClient, InMemoryMetricsCollector } from 'zlient';
329
-
330
- const metrics = new InMemoryMetricsCollector();
331
- const client = new HttpClient({
332
- baseUrls: { default: 'https://api.example.com' },
333
- metrics,
334
- });
335
-
336
- // View metrics summary
337
- const summary = metrics.getSummary();
338
- console.log(`Success rate: ${(summary.successful / summary.total * 100).toFixed(2)}%`);
339
- console.log(`Avg duration: ${summary.avgDurationMs}ms`);
340
133
  ```
341
134
 
342
- #### Custom Logger/Metrics Integration
343
-
344
- ```typescript
345
- import { Logger, LogEntry, MetricsCollector, RequestMetrics } from 'zlient';
346
-
347
- // Integrate with your logging service (e.g., DataDog, CloudWatch)
348
- class CustomLogger implements Logger {
349
- log(entry: LogEntry) {
350
- // Send to your logging service
351
- myLoggingService.log(entry);
352
- }
353
- }
354
-
355
- class CustomMetrics implements MetricsCollector {
356
- collect(metrics: RequestMetrics) {
357
- // Send to your metrics service (e.g., Prometheus, DataDog)
358
- dogstatsd.histogram('http.request.duration', metrics.durationMs);
359
- }
360
- }
361
-
362
- const client = new HttpClient({
363
- baseUrls: { default: 'https://api.example.com' },
364
- logger: new CustomLogger(),
365
- metrics: new CustomMetrics(),
366
- });
367
- ```
368
-
369
- ### Convenience Methods
370
-
371
- ```typescript
372
- // Use shortcuts instead of full request() method
373
- const { data: users } = await client.get('/users', { query: { page: 1 } });
374
- const { data: user } = await client.post('/users', { name: 'John' });
375
- const { data: updated } = await client.put('/users/1', { name: 'Jane' });
376
- const { data: patched } = await client.patch('/users/1', { email: 'new@email.com' });
377
- await client.delete('/users/1');
378
- ```
379
-
380
- ### Error Handling
381
-
382
- ```typescript
383
- import { ApiError } from 'zlient';
384
-
385
- try {
386
- await endpoint.call(data);
387
- } catch (error) {
388
- if (error instanceof ApiError) {
389
- console.error('API Error:', error.message);
390
- console.error('Status:', error.status);
391
- console.error('Details:', error.details);
392
-
393
- // Check error type
394
- if (error.isValidationError()) {
395
- console.error('Validation errors:', error.zodError?.issues);
396
- }
397
- if (error.isClientError()) {
398
- console.error('Client error (4xx)');
399
- }
400
- if (error.isServerError()) {
401
- console.error('Server error (5xx)');
402
- }
403
-
404
- // Get full error details
405
- console.error(JSON.stringify(error.toJSON(), null, 2));
406
- }
407
- }
408
- ```
409
-
410
- ## Building from Source
411
-
412
- ```bash
413
- # Clone the repository
414
- git clone <your-repo-url>
415
- cd zlient
416
-
417
- # Install dependencies
418
- bun install
419
-
420
- # Build the package
421
- bun run build
422
- ```
135
+ ---
423
136
 
424
137
  ## License
425
138
 
426
- MIT
427
-
428
- ## Contributing
429
-
430
- Contributions are welcome! Please open an issue or submit a pull request.
139
+ MIT © [Emirhan Gumus](https://github.com/emirhangumus)
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,WAAW,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,KAAK,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC/C;AAED;;;GAGG;AACH,qBAAa,MAAO,YAAW,YAAY;IACnC,KAAK;CAGZ;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,UAAW,YAAW,YAAY;IACjC,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAQ5E,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,WAAW;CASjC;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,eAAgB,YAAW,YAAY;IACtC,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM;IACtD,KAAK,CAAC,EAAE,IAAI,EAAE,EAAE,WAAW;CAOlC"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,WAAW,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,KAAK,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC/C;AAED;;;GAGG;AACH,qBAAa,MAAO,YAAW,YAAY;IACnC,KAAK;CAGZ;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,UAAW,YAAW,YAAY;IACjC,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAQ5E,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,WAAW;CAgBjC;AACD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,eAAgB,YAAW,YAAY;IACtC,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM;IACtD,KAAK,CAAC,EAAE,IAAI,EAAE,EAAE,WAAW;CAclC"}
@@ -1,117 +1,29 @@
1
1
  import { z } from 'zod';
2
2
  import { HttpClient } from '../http/http-client';
3
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 */
4
+ export type EndpointConfig<ResSchema extends z.ZodType | Record<number, z.ZodType>, ReqSchema extends z.ZodType | undefined = undefined, QuerySchema extends z.ZodType | undefined = undefined, PathSchema extends z.ZodType | undefined = undefined> = {
5
+ method: keyof typeof HTTPMethod;
6
+ path: string | ((params: z.infer<Exclude<PathSchema, undefined>>) => string);
7
+ response: ResSchema;
8
+ request?: ReqSchema;
9
+ query?: QuerySchema;
10
+ pathParams?: PathSchema;
22
11
  baseUrlKey?: string;
23
- /** Abort controller signal for cancellation */
12
+ description?: string;
13
+ };
14
+ export type EndpointCallParams<ReqSchema extends z.ZodType | undefined, QuerySchema extends z.ZodType | undefined, PathSchema extends z.ZodType | undefined> = {
15
+ data?: ReqSchema extends z.ZodType ? z.infer<ReqSchema> : never;
16
+ query?: QuerySchema extends z.ZodType ? z.infer<QuerySchema> : never;
17
+ pathParams?: PathSchema extends z.ZodType ? z.infer<PathSchema> : never;
18
+ headers?: Record<string, string>;
24
19
  signal?: globalThis.AbortSignal;
25
20
  };
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>>;
21
+ type InferResponse<S> = S extends z.ZodType ? z.infer<S> : S extends Record<number, z.ZodType> ? z.infer<S[keyof S]> : never;
22
+ export declare class Endpoint<ResSchema extends z.ZodType | Record<number, z.ZodType>, ReqSchema extends z.ZodType | undefined, QuerySchema extends z.ZodType | undefined, PathSchema extends z.ZodType | undefined> {
23
+ private client;
24
+ private config;
25
+ constructor(client: HttpClient, config: EndpointConfig<ResSchema, ReqSchema, QuerySchema, PathSchema>);
26
+ call(params: EndpointCallParams<ReqSchema, QuerySchema, PathSchema>): Promise<InferResponse<ResSchema>>;
116
27
  }
28
+ export {};
117
29
  //# sourceMappingURL=base-endpoint.d.ts.map
@@ -1 +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"}
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,EAAyB,MAAM,UAAU,CAAC;AAG7D,MAAM,MAAM,cAAc,CACxB,SAAS,SAAS,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EACvD,SAAS,SAAS,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,SAAS,EACnD,WAAW,SAAS,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,SAAS,EACrD,UAAU,SAAS,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,SAAS,IAClD;IACF,MAAM,EAAE,MAAM,OAAO,UAAU,CAAC;IAChC,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;IAC7E,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,CAC5B,SAAS,SAAS,CAAC,CAAC,OAAO,GAAG,SAAS,EACvC,WAAW,SAAS,CAAC,CAAC,OAAO,GAAG,SAAS,EACzC,UAAU,SAAS,CAAC,CAAC,OAAO,GAAG,SAAS,IACtC;IACF,IAAI,CAAC,EAAE,SAAS,SAAS,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC;IAChE,KAAK,CAAC,EAAE,WAAW,SAAS,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC;IACrE,UAAU,CAAC,EAAE,UAAU,SAAS,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC;CACjC,CAAC;AAGF,KAAK,aAAa,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,GACvC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GACV,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,GACnC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GACnB,KAAK,CAAC;AAEV,qBAAa,QAAQ,CACnB,SAAS,SAAS,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EACvD,SAAS,SAAS,CAAC,CAAC,OAAO,GAAG,SAAS,EACvC,WAAW,SAAS,CAAC,CAAC,OAAO,GAAG,SAAS,EACzC,UAAU,SAAS,CAAC,CAAC,OAAO,GAAG,SAAS;IAGtC,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;gBADN,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,cAAc,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,CAAC;IAGzE,IAAI,CACR,MAAM,EAAE,kBAAkB,CAAC,SAAS,EAAE,WAAW,EAAE,UAAU,CAAC,GAC7D,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;CAoErC"}