@tahanabavi/typefetch 1.1.0 → 1.2.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
@@ -1,6 +1,17 @@
1
1
  import { z } from 'zod';
2
2
 
3
- type EndpointDef<TReq extends z.ZodTypeAny, TRes extends z.ZodTypeAny> = {
3
+ /**
4
+ * Generic request schema:
5
+ *
6
+ * request: z.object({
7
+ * path: z.object({ ... }).optional(),
8
+ * query: z.object({ ... }).optional(),
9
+ * body: z.object({ ... }).optional(),
10
+ * })
11
+ */
12
+ type RequestSchema = z.ZodTypeAny;
13
+ type ResponseSchema = z.ZodTypeAny;
14
+ type EndpointDef<TReq extends RequestSchema, TRes extends ResponseSchema> = {
4
15
  method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
5
16
  path: string;
6
17
  auth?: boolean;
@@ -10,7 +21,7 @@ type EndpointDef<TReq extends z.ZodTypeAny, TRes extends z.ZodTypeAny> = {
10
21
  };
11
22
  type Contracts = {
12
23
  [ModuleName: string]: {
13
- [EndpointName: string]: EndpointDef<z.ZodTypeAny, z.ZodTypeAny>;
24
+ [EndpointName: string]: EndpointDef<RequestSchema, ResponseSchema>;
14
25
  };
15
26
  };
16
27
  interface MiddlewareContext {
@@ -25,10 +36,18 @@ type ErrorLike = {
25
36
  code?: string;
26
37
  [key: string]: any;
27
38
  };
28
- type EndpointDefZ = EndpointDef<z.ZodTypeAny, z.ZodTypeAny>;
39
+ type EndpointDefZ = EndpointDef<RequestSchema, ResponseSchema>;
40
+ /**
41
+ * For each endpoint we expose a method:
42
+ * (input: z.infer<Endpoint["request"]>) => Promise<z.infer<Endpoint["response"]>>
43
+ *
44
+ * So VSCode will show you:
45
+ * { path?: { ... }, query?: { ... }, body?: { ... } }
46
+ */
29
47
  type EndpointMethods<M extends Record<string, EndpointDefZ>> = {
30
48
  [K in keyof M]: (input: z.infer<M[K]["request"]>) => Promise<z.infer<M[K]["response"]>>;
31
49
  };
50
+ type TokenProvider = () => string | Promise<string>;
32
51
 
33
52
  declare class RichError extends Error implements ErrorLike {
34
53
  status?: number;
@@ -40,6 +59,18 @@ declare class RichError extends Error implements ErrorLike {
40
59
  message: string;
41
60
  });
42
61
  }
62
+ /**
63
+ * Strongly-typed HTTP client built from Zod contracts.
64
+ *
65
+ * Features:
66
+ * - Type-safe request & response based on Zod schemas
67
+ * - Path/query/body support via { path?, query?, body? } shape
68
+ * - Backwards compatible with flat request bodies
69
+ * - Pluggable middleware pipeline
70
+ * - Token and tokenProvider support
71
+ * - Mock mode with configurable delay
72
+ * - Optional response wrapper for APIs that nest data
73
+ */
43
74
  declare class ApiClient<C extends Contracts, E extends ErrorLike = RichError> {
44
75
  private config;
45
76
  private contracts;
@@ -49,30 +80,107 @@ declare class ApiClient<C extends Contracts, E extends ErrorLike = RichError> {
49
80
  private useMockData;
50
81
  private mockDelay;
51
82
  private responseWrapper?;
83
+ private tokenProvider?;
52
84
  private _modules;
53
85
  constructor(config: {
54
86
  baseUrl: string;
55
87
  token?: string;
88
+ tokenProvider?: TokenProvider;
56
89
  useMockData?: boolean;
57
90
  mockDelay?: {
58
91
  min: number;
59
92
  max: number;
60
93
  };
61
94
  }, contracts: C);
95
+ /**
96
+ * Builds the strongly-typed `modules` API from the provided contracts.
97
+ * Must be called once after constructing the client.
98
+ */
62
99
  init(): void;
100
+ /**
101
+ * Type-safe entrypoint for calling API endpoints.
102
+ * Populated by `init()` based on the `contracts` passed to the constructor.
103
+ */
63
104
  get modules(): { [M in keyof C]: EndpointMethods<C[M]>; };
105
+ /**
106
+ * Registers a middleware in the pipeline.
107
+ * Middlewares are executed in reverse order of registration.
108
+ */
64
109
  use<T>(middleware: Middleware<T>, options?: T): void;
110
+ /**
111
+ * Registers a global error handler.
112
+ * The handler is invoked for normalized errors before they are re-thrown.
113
+ */
65
114
  onError(handler: (error: E) => void): void;
115
+ /**
116
+ * Registers a transformation function applied to all successful responses
117
+ * after Zod parsing.
118
+ */
66
119
  useResponseTransform(fn: (data: any) => any): void;
120
+ /**
121
+ * Enables or disables mock mode. When enabled, endpoints with `mockData`
122
+ * return mocked responses instead of performing network requests.
123
+ */
67
124
  setMockMode(enabled: boolean, delay?: {
68
125
  min: number;
69
126
  max: number;
70
127
  }): void;
128
+ /**
129
+ * Registers a schema wrapper for APIs that wrap data in an envelope.
130
+ * Example: { success, data, message, code, ... }.
131
+ */
71
132
  setResponseWrapper(wrapper: (successResponse: z.ZodTypeAny) => z.ZodTypeAny): void;
133
+ /**
134
+ * Sets or updates the token provider used for authenticated endpoints.
135
+ * Overrides any static token provided in the constructor.
136
+ */
137
+ setTokenProvider(provider: TokenProvider): void;
138
+ /**
139
+ * Returns the current token, preferring the tokenProvider if present,
140
+ * otherwise falling back to the static token from the constructor.
141
+ */
142
+ getCurrentToken(): Promise<string | undefined>;
143
+ /**
144
+ * Executes a single endpoint request.
145
+ *
146
+ * Expected request shape (new style):
147
+ * z.object({
148
+ * path: z.object({...}).optional(),
149
+ * query: z.object({...}).optional(),
150
+ * body: z.any().optional(),
151
+ * })
152
+ *
153
+ * If the parsed request does not contain `path`, `query` or `body`,
154
+ * the entire input is treated as the legacy flat request body.
155
+ */
72
156
  private request;
157
+ /**
158
+ * Builds the effective URL and request body for an endpoint.
159
+ *
160
+ * - Legacy mode: if the input does not contain `path`, `query` or `body`,
161
+ * the entire input is used as the JSON request body for non-GET methods.
162
+ *
163
+ * - New mode: uses `path` to interpolate `:param` segments, `query` to
164
+ * construct the query string, and `body` as the JSON payload.
165
+ */
166
+ private buildUrlAndBody;
167
+ /**
168
+ * Returns a mocked response based on `endpoint.mockData`,
169
+ * respecting the configured mock delay and response wrapper.
170
+ */
73
171
  private handleMockRequest;
172
+ /**
173
+ * Returns a random delay in milliseconds within the current mock delay range.
174
+ */
74
175
  private getRandomDelay;
176
+ /**
177
+ * Creates a RichError instance from a partial error description.
178
+ */
75
179
  private createError;
180
+ /**
181
+ * Normalizes unknown errors into a RichError instance.
182
+ * Zod validation errors are converted into a standardized validation error.
183
+ */
76
184
  private normalizeError;
77
185
  }
78
186
 
@@ -99,4 +207,4 @@ type CacheOptions = {
99
207
  };
100
208
  declare const cacheMiddleware: (options?: CacheOptions) => (ctx: MiddlewareContext, next: MiddlewareNext) => Promise<Response>;
101
209
 
102
- 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 RetryOptions, RichError, authMiddleware, cacheMiddleware, loggingMiddleware, retryMiddleware };
210
+ 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 RequestSchema, type ResponseSchema, type RetryOptions, RichError, type TokenProvider, authMiddleware, cacheMiddleware, loggingMiddleware, retryMiddleware };