tapi-rs 3.0.0

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 ADDED
@@ -0,0 +1,281 @@
1
+ # Tapi
2
+
3
+ A type-safe REST API client builder for TypeScript with React hooks integration.
4
+
5
+ ## Features
6
+
7
+ - **Type Safety** - Full TypeScript support with compile-time type checking
8
+ - **Error as Value** - No thrown errors, all errors returned as discriminated unions
9
+ - **React Hooks** - Built-in React integration with loading states
10
+ - **Zero Runtime Validation** - Pure TypeScript types, no runtime overhead
11
+ - **Lightweight** - No external validation library dependencies
12
+ - **Auto-completion** - Full IDE support with IntelliSense
13
+ - **Internationalization** - Multi-language support for error messages
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install tapi
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ```typescript
24
+ import Tapi from "tapi";
25
+
26
+ // 1. Define your types
27
+ type User = {
28
+ id: number;
29
+ name: string;
30
+ email: string;
31
+ };
32
+
33
+ // 2. Build your API client
34
+ const api = Tapi.builder()
35
+ .withHost("https://api.example.com")
36
+ .withApiError(async (res) => ({ code: res.status, message: res.statusText }))
37
+ .withRoutes({
38
+ users: {
39
+ getAll: Tapi.get<{ response: User[] }>()({
40
+ endpoint: "/users",
41
+ response: Tapi.response<User[]>()
42
+ }),
43
+ getById: Tapi.get<{ path: { id: string }; response: User }>()({
44
+ endpoint: "/users/:id",
45
+ response: Tapi.response<User>()
46
+ }),
47
+ create: Tapi.post<{ body: { name: string; email: string }; response: User }>()({
48
+ endpoint: "/users",
49
+ response: Tapi.response<User>()
50
+ })
51
+ }
52
+ })
53
+ .build();
54
+
55
+ // 3. Use it
56
+ const result = await api.users.getAll({});
57
+ if (result.ok) {
58
+ console.log(result.data); // Fully typed User[]
59
+ }
60
+ ```
61
+
62
+ ## Type Parameters
63
+
64
+ Tapi uses object-based type parameters - only specify what you need:
65
+
66
+ ```typescript
67
+ // Simple - just response type
68
+ Tapi.get<{ response: User[] }>();
69
+
70
+ // With path params
71
+ Tapi.get<{ path: { id: string }; response: User }>();
72
+
73
+ // With query params
74
+ Tapi.get<{ query: { limit?: number }; response: Post[] }>();
75
+
76
+ // With body (for POST/PUT/PATCH)
77
+ Tapi.post<{ body: CreateUser; response: User }>();
78
+
79
+ // With headers
80
+ Tapi.get<{ headers: { Authorization: string }; response: User }>();
81
+
82
+ // With formData
83
+ Tapi.post<{ formData: { file: File }; response: UploadResult }>();
84
+ ```
85
+
86
+ ## Error Handling
87
+
88
+ All API calls return a discriminated union with an `ok` boolean:
89
+
90
+ ```typescript
91
+ const result = await api.users.getById({ path: { id: "123" } });
92
+
93
+ if (result.ok) {
94
+ console.log("User:", result.data);
95
+ } else {
96
+ switch (result.status) {
97
+ case "network_error":
98
+ console.error("Network failed:", result.error);
99
+ break;
100
+ case "api_error":
101
+ console.error(`API error [${result.code}]:`, result.data);
102
+ break;
103
+ case "mapper_error":
104
+ console.error("Mapper failed:", result.error);
105
+ break;
106
+ }
107
+ }
108
+ ```
109
+
110
+ ## React Integration
111
+
112
+ Use the built-in React hooks for automatic loading states:
113
+
114
+ ```typescript
115
+ function UserProfile({ userId }: { userId: string }) {
116
+ const [user, error, loading, refresh, setUser] = api.users.getById.useHook({
117
+ path: { id: userId }
118
+ });
119
+
120
+ if (loading) return <div>Loading...</div>;
121
+ if (error) return <div>Error: {error.message}</div>;
122
+
123
+ return (
124
+ <div>
125
+ <h1>{user.name}</h1>
126
+ <p>{user.email}</p>
127
+ <button onClick={() => refresh()}>Refresh</button>
128
+ </div>
129
+ );
130
+ }
131
+ ```
132
+
133
+ ### Hook Return Value
134
+
135
+ ```typescript
136
+ const [data, error, loading, refresh, setter] = api.endpoint.useHook(params);
137
+
138
+ // data - The response data (null if loading or error)
139
+ // error - The error object (null if success or loading)
140
+ // loading - Boolean loading state
141
+ // refresh - Function to refetch (pass true to reset state)
142
+ // setter - Function to update data locally
143
+ ```
144
+
145
+ ### Lazy Loading
146
+
147
+ ```typescript
148
+ const [user, error, loading, refresh] = api.users.getById.useHook({
149
+ path: { id: userId },
150
+ lazy: true // Don't fetch on mount
151
+ });
152
+
153
+ // Trigger fetch manually
154
+ <button onClick={() => refresh(true)}>Load User</button>
155
+ ```
156
+
157
+ ## Response Mappers
158
+
159
+ Transform API responses with type-safe mappers:
160
+
161
+ ```typescript
162
+ type ApiUser = { id: number; full_name: string };
163
+ type User = { id: number; name: string };
164
+
165
+ const api = Tapi.builder()
166
+ .withHost("https://api.example.com")
167
+ .withApiError(async (res) => ({ code: res.status }))
168
+ .withRoutes({
169
+ users: {
170
+ getById: Tapi.get<{
171
+ path: { id: string };
172
+ response: ApiUser;
173
+ mapped: User;
174
+ }>()({
175
+ endpoint: "/users/:id",
176
+ response: Tapi.response<ApiUser, User>((data) => () => ({
177
+ id: data.id,
178
+ name: data.full_name
179
+ }))
180
+ })
181
+ }
182
+ })
183
+ .build();
184
+
185
+ // result.data is typed as User (mapped type)
186
+ const result = await api.users.getById({ path: { id: "123" } });
187
+ ```
188
+
189
+ ### Mappers with Arguments
190
+
191
+ ```typescript
192
+ const api = Tapi.builder()
193
+ .withHost("https://api.example.com")
194
+ .withApiError(async (res) => ({ code: res.status }))
195
+ .withRoutes({
196
+ posts: {
197
+ getAll: Tapi.get<{
198
+ response: Post[];
199
+ mapped: Post[];
200
+ mapArg: { limit: number };
201
+ }>()({
202
+ endpoint: "/posts",
203
+ response: Tapi.response<Post[], Post[], { limit: number }>((posts) => (args) => posts.slice(0, args.limit))
204
+ })
205
+ }
206
+ })
207
+ .build();
208
+
209
+ // Pass mapper arguments at call time
210
+ const result = await api.posts.getAll({ map: { limit: 5 } });
211
+ ```
212
+
213
+ ## Advanced Configuration
214
+
215
+ ```typescript
216
+ const api = Tapi.builder()
217
+ .withHost("https://api.example.com")
218
+ .withApiError(async (response) => {
219
+ const error = await response.json();
220
+ return {
221
+ message: error.message || "Unknown error",
222
+ code: response.status,
223
+ details: error
224
+ };
225
+ })
226
+ .withDefaultHeaders({
227
+ Authorization: "Bearer <token>",
228
+ "Content-Type": "application/json"
229
+ })
230
+ .withPrefetch((request) => {
231
+ console.log(`[${request.method}] ${request.url}`);
232
+ })
233
+ .withPostfetch((response) => {
234
+ if (!response.ok) {
235
+ console.error("Request failed:", response.status);
236
+ }
237
+ })
238
+ .withLanguage("en") // "en" | "br"
239
+ .withRoutes(routes)
240
+ .build();
241
+ ```
242
+
243
+ ### Dynamic Headers
244
+
245
+ Update headers at runtime using `setHeaders`:
246
+
247
+ ```typescript
248
+ // Update auth token
249
+ api.setHeaders({
250
+ Authorization: `Bearer ${newToken}`
251
+ });
252
+
253
+ // Also works on nested routes
254
+ api.users.setHeaders({ ... });
255
+ ```
256
+
257
+ ## Internationalization
258
+
259
+ Tapi supports multiple languages for error messages:
260
+
261
+ - `"en"` - English (default)
262
+ - `"br"` - Portuguese (Brazil)
263
+
264
+ ```typescript
265
+ const api = Tapi.builder()
266
+ .withHost("https://api.example.com")
267
+ .withLanguage("br") // Portuguese error messages
268
+ .withApiError(async (res) => res.statusText)
269
+ .withRoutes(routes)
270
+ .build();
271
+ ```
272
+
273
+ ## Examples
274
+
275
+ Check the `examples/` folder for comprehensive examples:
276
+
277
+ - **`tapi-example.ts`** - Complete API client with all features
278
+
279
+ ## License
280
+
281
+ MIT
package/dist/core.d.ts ADDED
@@ -0,0 +1,65 @@
1
+ import * as Hook from "./hook";
2
+ import { Language } from "./translations";
3
+ import * as Types from "./types";
4
+ type RouteFunction<T extends Types.RequestConfig<any, any, any, any, any, any, any, any, any>, TError = string> = Types.RequesterFunction<T, TError> & {
5
+ useHook: (params: Types.CallSignature<T>) => Hook.HookResponse<T, TError>;
6
+ };
7
+ export type GenerateApiMethods<T extends Types.RouteDefinitions, TError = string> = {
8
+ [K in keyof T]: T[K] extends Types.RequestConfig<any, any, any, any, any, any, any, any, any> ? RouteFunction<T[K], TError> : T[K] extends Types.RouteDefinitions ? GenerateApiMethods<T[K], TError> : never;
9
+ } & {
10
+ /**
11
+ * Update default headers for all requests in this API instance
12
+ */
13
+ setHeaders: (headers: Record<string, string>) => void;
14
+ };
15
+ /**
16
+ * Builder class for creating API methods with proper type inference and compile-time validation
17
+ */
18
+ export declare class TapiBuilder<TRoutes extends Types.RouteDefinitions = {}, TError = string, THasHost extends boolean = false, THasRoutes extends boolean = false, THasErrorHandler extends boolean = false> {
19
+ private host?;
20
+ private routes?;
21
+ private prefetchCallback?;
22
+ private postfetchCallback?;
23
+ private defaultHeaders?;
24
+ private errorHandler?;
25
+ private language;
26
+ /**
27
+ * Set the host URL for API requests
28
+ */
29
+ withHost(host: string): TapiBuilder<TRoutes, TError, true, THasRoutes, THasErrorHandler>;
30
+ /**
31
+ * Set the route definitions with proper type inference
32
+ */
33
+ withRoutes<T extends Types.RouteDefinitions>(routes: T): TapiBuilder<T, TError, THasHost, true, THasErrorHandler>;
34
+ /**
35
+ * Set the error handler with proper type inference
36
+ */
37
+ withApiError<T>(errorHandler: (response: Response) => Promise<T>): TapiBuilder<TRoutes, T, THasHost, THasRoutes, true>;
38
+ /**
39
+ * Set the prefetch callback that runs before each request
40
+ */
41
+ withPrefetch(callback: Types.PrefetchCallback): TapiBuilder<TRoutes, TError, THasHost, THasRoutes, THasErrorHandler>;
42
+ /**
43
+ * Set the postfetch callback that runs after each request
44
+ */
45
+ withPostfetch(callback: Types.PostfetchCallback<any, TError>): TapiBuilder<TRoutes, TError, THasHost, THasRoutes, THasErrorHandler>;
46
+ /**
47
+ * Set default headers for all requests
48
+ */
49
+ withDefaultHeaders(headers: Record<string, string>): TapiBuilder<TRoutes, TError, THasHost, THasRoutes, THasErrorHandler>;
50
+ /**
51
+ * Set the language for error messages
52
+ */
53
+ withLanguage(language: Language): TapiBuilder<TRoutes, TError, THasHost, THasRoutes, THasErrorHandler>;
54
+ /**
55
+ * Build the API client with compile-time validation
56
+ *
57
+ * This method enforces that all required configurations are set:
58
+ * - Host URL
59
+ * - Route definitions
60
+ * - Error handler
61
+ */
62
+ build(...args: THasHost extends false ? ["Host is required - use .withHost() first"] : THasRoutes extends false ? ["Routes are required - use .withRoutes() first"] : THasErrorHandler extends false ? ["Error handler is required - use .withApiError() first"] : []): THasHost extends true ? (THasRoutes extends true ? (THasErrorHandler extends true ? GenerateApiMethods<TRoutes, TError> : never) : never) : never;
63
+ }
64
+ export {};
65
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
package/dist/core.js ADDED
@@ -0,0 +1,169 @@
1
+ import * as Hook from "./hook";
2
+ import * as RequestCreator from "./request";
3
+ /**
4
+ * Check if a value is a RequestConfig by duck-typing
5
+ */
6
+ function isRequestConfig(value) {
7
+ if (typeof value !== "object" || value === null)
8
+ return false;
9
+ const v = value;
10
+ return typeof v.method === "string" && typeof v.endpoint === "string" && typeof v.response === "object" && v.response !== null;
11
+ }
12
+ /**
13
+ * Recursively creates nested API methods based on route definitions
14
+ */
15
+ function createNestedMethods(host, routes, target, prefetchCallback, postfetchCallback, defaultHeaders, errorHandler, language = "en") {
16
+ // Store headers and update function references for use by setHeaders method
17
+ let currentHeaders = defaultHeaders;
18
+ const updateTargets = [];
19
+ for (const [routeName, routeValue] of Object.entries(routes)) {
20
+ if (isRequestConfig(routeValue)) {
21
+ const requester = RequestCreator.create(host, routeValue, prefetchCallback, postfetchCallback, currentHeaders, errorHandler, language);
22
+ const hook = (params) => Hook.useHook(requester, params);
23
+ requester.useHook = hook;
24
+ target[routeName] = requester;
25
+ updateTargets.push({ target: routeName, config: routeValue });
26
+ }
27
+ else if (typeof routeValue === "object" && routeValue !== null) {
28
+ target[routeName] = {};
29
+ createNestedMethods(host, routeValue, target[routeName], prefetchCallback, postfetchCallback, currentHeaders, errorHandler, language);
30
+ }
31
+ }
32
+ // Add setHeaders method to update headers for all nested routes
33
+ target.setHeaders = (headers) => {
34
+ currentHeaders = headers;
35
+ // Update existing routes with new headers
36
+ for (const item of updateTargets) {
37
+ const requester = RequestCreator.create(host, item.config, prefetchCallback, postfetchCallback, headers, errorHandler, language);
38
+ const hook = (params) => Hook.useHook(requester, params);
39
+ requester.useHook = hook;
40
+ target[item.target] = requester;
41
+ }
42
+ // Update headers for nested objects
43
+ for (const key in target) {
44
+ if (target.hasOwnProperty(key) && typeof target[key] === "object" && target[key] !== null && typeof target[key].setHeaders === "function" && key !== "setHeaders") {
45
+ target[key].setHeaders(headers);
46
+ }
47
+ }
48
+ };
49
+ }
50
+ /**
51
+ * Builder class for creating API methods with proper type inference and compile-time validation
52
+ */
53
+ export class TapiBuilder {
54
+ constructor() {
55
+ this.language = "en";
56
+ }
57
+ /**
58
+ * Set the host URL for API requests
59
+ */
60
+ withHost(host) {
61
+ const builder = new TapiBuilder();
62
+ builder.host = host;
63
+ builder.routes = this.routes;
64
+ builder.prefetchCallback = this.prefetchCallback;
65
+ builder.postfetchCallback = this.postfetchCallback;
66
+ builder.defaultHeaders = this.defaultHeaders;
67
+ builder.errorHandler = this.errorHandler;
68
+ builder.language = this.language;
69
+ return builder;
70
+ }
71
+ /**
72
+ * Set the route definitions with proper type inference
73
+ */
74
+ withRoutes(routes) {
75
+ const builder = new TapiBuilder();
76
+ builder.host = this.host;
77
+ builder.routes = routes;
78
+ builder.prefetchCallback = this.prefetchCallback;
79
+ builder.postfetchCallback = this.postfetchCallback;
80
+ builder.defaultHeaders = this.defaultHeaders;
81
+ builder.errorHandler = this.errorHandler;
82
+ builder.language = this.language;
83
+ return builder;
84
+ }
85
+ /**
86
+ * Set the error handler with proper type inference
87
+ */
88
+ withApiError(errorHandler) {
89
+ const builder = new TapiBuilder();
90
+ builder.host = this.host;
91
+ builder.routes = this.routes;
92
+ builder.prefetchCallback = this.prefetchCallback;
93
+ builder.postfetchCallback = undefined; // Reset postfetch as error type changed
94
+ builder.defaultHeaders = this.defaultHeaders;
95
+ builder.errorHandler = errorHandler;
96
+ builder.language = this.language;
97
+ return builder;
98
+ }
99
+ /**
100
+ * Set the prefetch callback that runs before each request
101
+ */
102
+ withPrefetch(callback) {
103
+ const builder = new TapiBuilder();
104
+ builder.host = this.host;
105
+ builder.routes = this.routes;
106
+ builder.prefetchCallback = callback;
107
+ builder.postfetchCallback = this.postfetchCallback;
108
+ builder.defaultHeaders = this.defaultHeaders;
109
+ builder.errorHandler = this.errorHandler;
110
+ builder.language = this.language;
111
+ return builder;
112
+ }
113
+ /**
114
+ * Set the postfetch callback that runs after each request
115
+ */
116
+ withPostfetch(callback) {
117
+ const builder = new TapiBuilder();
118
+ builder.host = this.host;
119
+ builder.routes = this.routes;
120
+ builder.prefetchCallback = this.prefetchCallback;
121
+ builder.postfetchCallback = callback;
122
+ builder.defaultHeaders = this.defaultHeaders;
123
+ builder.errorHandler = this.errorHandler;
124
+ builder.language = this.language;
125
+ return builder;
126
+ }
127
+ /**
128
+ * Set default headers for all requests
129
+ */
130
+ withDefaultHeaders(headers) {
131
+ const builder = new TapiBuilder();
132
+ builder.host = this.host;
133
+ builder.routes = this.routes;
134
+ builder.prefetchCallback = this.prefetchCallback;
135
+ builder.postfetchCallback = this.postfetchCallback;
136
+ builder.defaultHeaders = headers;
137
+ builder.errorHandler = this.errorHandler;
138
+ builder.language = this.language;
139
+ return builder;
140
+ }
141
+ /**
142
+ * Set the language for error messages
143
+ */
144
+ withLanguage(language) {
145
+ const builder = new TapiBuilder();
146
+ builder.host = this.host;
147
+ builder.routes = this.routes;
148
+ builder.prefetchCallback = this.prefetchCallback;
149
+ builder.postfetchCallback = this.postfetchCallback;
150
+ builder.defaultHeaders = this.defaultHeaders;
151
+ builder.errorHandler = this.errorHandler;
152
+ builder.language = language;
153
+ return builder;
154
+ }
155
+ /**
156
+ * Build the API client with compile-time validation
157
+ *
158
+ * This method enforces that all required configurations are set:
159
+ * - Host URL
160
+ * - Route definitions
161
+ * - Error handler
162
+ */
163
+ build(...args) {
164
+ const apiMethods = {};
165
+ createNestedMethods(this.host, this.routes, apiMethods, this.prefetchCallback, this.postfetchCallback, this.defaultHeaders, this.errorHandler, this.language);
166
+ return apiMethods;
167
+ }
168
+ }
169
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import type { RequestConfig } from "./types";
2
+ import type { ResponseConfig } from "./response";
3
+ /**
4
+ * Configuration object for endpoint factories
5
+ */
6
+ type EndpointOptions<TResponse, TMapped, TMapArg> = {
7
+ endpoint: string;
8
+ response: ResponseConfig<TResponse, TMapped, TMapArg>;
9
+ };
10
+ /**
11
+ * Type parameters object - only specify what you need
12
+ */
13
+ type EndpointTypes<TPath = undefined, TBody = undefined, TFormData = undefined, TQuery = undefined, THeaders = undefined, TResponse = unknown, TMapped = TResponse, TMapArg = undefined> = {
14
+ path?: TPath;
15
+ body?: TBody;
16
+ formData?: TFormData;
17
+ query?: TQuery;
18
+ headers?: THeaders;
19
+ response?: TResponse;
20
+ mapped?: TMapped;
21
+ mapArg?: TMapArg;
22
+ };
23
+ /**
24
+ * Extract types from the config object with defaults
25
+ */
26
+ type ExtractPath<T> = T extends {
27
+ path: infer P;
28
+ } ? P : undefined;
29
+ type ExtractBody<T> = T extends {
30
+ body: infer B;
31
+ } ? B : undefined;
32
+ type ExtractFormData<T> = T extends {
33
+ formData: infer F;
34
+ } ? F : undefined;
35
+ type ExtractQuery<T> = T extends {
36
+ query: infer Q;
37
+ } ? Q : undefined;
38
+ type ExtractHeaders<T> = T extends {
39
+ headers: infer H;
40
+ } ? H : undefined;
41
+ type ExtractResponse<T> = T extends {
42
+ response: infer R;
43
+ } ? R : unknown;
44
+ type ExtractMapped<T> = T extends {
45
+ mapped: infer M;
46
+ } ? M : ExtractResponse<T>;
47
+ type ExtractMapArg<T> = T extends {
48
+ mapArg: infer A;
49
+ } ? A : undefined;
50
+ export declare const get: <T extends EndpointTypes<any, any, any, any, any, any, any, any> = {}>() => (config: EndpointOptions<ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>) => RequestConfig<"GET", ExtractPath<T>, ExtractBody<T>, ExtractFormData<T>, ExtractQuery<T>, ExtractHeaders<T>, ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>;
51
+ export declare const post: <T extends EndpointTypes<any, any, any, any, any, any, any, any> = {}>() => (config: EndpointOptions<ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>) => RequestConfig<"POST", ExtractPath<T>, ExtractBody<T>, ExtractFormData<T>, ExtractQuery<T>, ExtractHeaders<T>, ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>;
52
+ export declare const put: <T extends EndpointTypes<any, any, any, any, any, any, any, any> = {}>() => (config: EndpointOptions<ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>) => RequestConfig<"PUT", ExtractPath<T>, ExtractBody<T>, ExtractFormData<T>, ExtractQuery<T>, ExtractHeaders<T>, ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>;
53
+ export declare const del: <T extends EndpointTypes<any, any, any, any, any, any, any, any> = {}>() => (config: EndpointOptions<ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>) => RequestConfig<"DELETE", ExtractPath<T>, ExtractBody<T>, ExtractFormData<T>, ExtractQuery<T>, ExtractHeaders<T>, ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>;
54
+ export declare const patch: <T extends EndpointTypes<any, any, any, any, any, any, any, any> = {}>() => (config: EndpointOptions<ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>) => RequestConfig<"PATCH", ExtractPath<T>, ExtractBody<T>, ExtractFormData<T>, ExtractQuery<T>, ExtractHeaders<T>, ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>;
55
+ export declare const Endpoints: {
56
+ readonly get: <T extends EndpointTypes<any, any, any, any, any, any, any, any> = {}>() => (config: EndpointOptions<ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>) => RequestConfig<"GET", ExtractPath<T>, ExtractBody<T>, ExtractFormData<T>, ExtractQuery<T>, ExtractHeaders<T>, ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>;
57
+ readonly post: <T extends EndpointTypes<any, any, any, any, any, any, any, any> = {}>() => (config: EndpointOptions<ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>) => RequestConfig<"POST", ExtractPath<T>, ExtractBody<T>, ExtractFormData<T>, ExtractQuery<T>, ExtractHeaders<T>, ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>;
58
+ readonly put: <T extends EndpointTypes<any, any, any, any, any, any, any, any> = {}>() => (config: EndpointOptions<ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>) => RequestConfig<"PUT", ExtractPath<T>, ExtractBody<T>, ExtractFormData<T>, ExtractQuery<T>, ExtractHeaders<T>, ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>;
59
+ readonly delete: <T extends EndpointTypes<any, any, any, any, any, any, any, any> = {}>() => (config: EndpointOptions<ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>) => RequestConfig<"DELETE", ExtractPath<T>, ExtractBody<T>, ExtractFormData<T>, ExtractQuery<T>, ExtractHeaders<T>, ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>;
60
+ readonly patch: <T extends EndpointTypes<any, any, any, any, any, any, any, any> = {}>() => (config: EndpointOptions<ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>) => RequestConfig<"PATCH", ExtractPath<T>, ExtractBody<T>, ExtractFormData<T>, ExtractQuery<T>, ExtractHeaders<T>, ExtractResponse<T>, ExtractMapped<T>, ExtractMapArg<T>>;
61
+ };
62
+ export {};
63
+ //# sourceMappingURL=endpoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../src/endpoints.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Curried endpoint factory using object-based type parameters
3
+ *
4
+ * Usage:
5
+ * // Simple - just response type
6
+ * Tapi.get<{ response: User[] }>()({ endpoint: "/users", response: Tapi.response<User[]>() })
7
+ *
8
+ * // With path params
9
+ * Tapi.get<{ path: { id: string }, response: User }>()({ endpoint: "/users/:id", response: Tapi.response<User>() })
10
+ *
11
+ * // With query params
12
+ * Tapi.get<{ query: { limit?: number }, response: Post[] }>()({ endpoint: "/posts", response: Tapi.response<Post[]>() })
13
+ *
14
+ * // With body (for POST/PUT)
15
+ * Tapi.post<{ body: CreateUser, response: User }>()({ endpoint: "/users", response: Tapi.response<User>() })
16
+ *
17
+ * // With mapper
18
+ * Tapi.get<{ path: { id: string }, response: User, mapped: UserDTO }>()({
19
+ * endpoint: "/users/:id",
20
+ * response: Tapi.response<User, UserDTO>((u) => () => ({ ...u, fullName: u.name }))
21
+ * })
22
+ */
23
+ function createEndpointFactory(method) {
24
+ return () => (config) => ({
25
+ method,
26
+ endpoint: config.endpoint,
27
+ response: config.response
28
+ });
29
+ }
30
+ // Individual endpoint factories
31
+ export const get = createEndpointFactory("GET");
32
+ export const post = createEndpointFactory("POST");
33
+ export const put = createEndpointFactory("PUT");
34
+ export const del = createEndpointFactory("DELETE");
35
+ export const patch = createEndpointFactory("PATCH");
36
+ // Namespace export
37
+ export const Endpoints = {
38
+ get,
39
+ post,
40
+ put,
41
+ delete: del,
42
+ patch
43
+ };
44
+ //# sourceMappingURL=endpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../src/endpoints.ts"],"names":[],"mappings":"AA8CA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAS,qBAAqB,CAA6B,MAAe;IACxE,OAAO,GAAyE,EAAE,CAChF,CACE,MAA+E,EAW/E,EAAE,CAAC,CAAC;QACJ,MAAM;QACN,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC,CAAC;AACP,CAAC;AAED,gCAAgC;AAChC,MAAM,CAAC,MAAM,GAAG,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;AAChD,MAAM,CAAC,MAAM,IAAI,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAClD,MAAM,CAAC,MAAM,GAAG,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;AAChD,MAAM,CAAC,MAAM,GAAG,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AACnD,MAAM,CAAC,MAAM,KAAK,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAEpD,mBAAmB;AACnB,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,GAAG;IACH,IAAI;IACJ,GAAG;IACH,MAAM,EAAE,GAAG;IACX,KAAK;CACG,CAAC"}