@cushin/api-runtime 4.1.3 → 4.1.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/dist/{chunk-GJ4UWJYQ.js → chunk-3FFXWCVP.js} +1 -1
- package/dist/chunk-3FFXWCVP.js.map +1 -0
- package/dist/{chunk-3NZPNRHX.js → chunk-4X4KIDBQ.js} +16 -24
- package/dist/chunk-4X4KIDBQ.js.map +1 -0
- package/dist/client.js +1 -1
- package/dist/index.js +2 -2
- package/dist/schema.d.ts +2 -2
- package/dist/schema.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-3NZPNRHX.js.map +0 -1
- package/dist/chunk-GJ4UWJYQ.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schema.ts"],"sourcesContent":["import type { z } from \"zod\";\n\nexport type HTTPMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n\nexport interface APIEndpoint {\n path: string;\n method: HTTPMethod;\n baseUrl?: string;\n params?: z.ZodType<any>;\n query?: z.ZodType<any>;\n body?: z.ZodType<any>;\n response: z.ZodType<any>;\n tags?: string[];\n description?: string;\n headers?: Record<string, string | undefined | null>;\n}\n\nexport interface APIConfig {\n baseUrl?: string;\n endpoints: Record<string, APIEndpoint>;\n}\n\nexport type EndpointConfig<\n TPath extends string = string,\n TMethod extends HTTPMethod = HTTPMethod,\n TParams = undefined,\n TQuery = undefined,\n TBody = undefined,\n TResponse = any,\n> = {\n path: TPath;\n method: TMethod;\n baseUrl?: string;\n params?: z.ZodType<TParams>;\n query?: z.ZodType<TQuery>;\n body?: z.ZodType<TBody>;\n response: z.ZodType<TResponse>;\n tags?: string[];\n description?: string;\n headers?: Record<string, string | undefined | null>;\n};\n\n/**\n * Helper function to define API configuration with type safety\n */\nexport function defineConfig<T extends APIConfig>(config: T): T {\n return config;\n}\n\n/**\n * Helper function to define a single endpoint with type inference\n */\nexport function defineEndpoint<\n TPath extends string,\n TMethod extends HTTPMethod,\n TParams = undefined,\n TQuery = undefined,\n TBody = undefined,\n TResponse = any,\n>(\n config: EndpointConfig<TPath, TMethod, TParams, TQuery, TBody, TResponse>,\n): EndpointConfig<TPath, TMethod, TParams, TQuery, TBody, TResponse> {\n return config;\n}\n\n/**\n * Helper to define multiple endpoints\n */\nexport function defineEndpoints<T extends Record<string, APIEndpoint>>(\n endpoints: T,\n): T {\n return endpoints;\n}\n"],"mappings":";AA6CO,SAAS,aAAkC,QAAc;AAC9D,SAAO;AACT;AAKO,SAAS,eAQd,QACmE;AACnE,SAAO;AACT;AAKO,SAAS,gBACd,WACG;AACH,SAAO;AACT;","names":[]}
|
|
@@ -70,9 +70,6 @@ var APIClient = class {
|
|
|
70
70
|
};
|
|
71
71
|
this.client = ky.create({
|
|
72
72
|
prefixUrl: this.config.baseUrl,
|
|
73
|
-
headers: {
|
|
74
|
-
"Content-Type": "application/json"
|
|
75
|
-
},
|
|
76
73
|
retry: {
|
|
77
74
|
limit: 2,
|
|
78
75
|
methods: ["get", "post", "put", "delete", "patch"],
|
|
@@ -130,9 +127,6 @@ var APIClient = class {
|
|
|
130
127
|
}
|
|
131
128
|
return ky.create({
|
|
132
129
|
prefixUrl: endpointBaseUrl,
|
|
133
|
-
headers: {
|
|
134
|
-
"Content-Type": "application/json"
|
|
135
|
-
},
|
|
136
130
|
retry: {
|
|
137
131
|
limit: 2,
|
|
138
132
|
methods: ["get", "post", "put", "delete", "patch"],
|
|
@@ -146,11 +140,9 @@ var APIClient = class {
|
|
|
146
140
|
const path = this.buildPath(endpoint.path, params);
|
|
147
141
|
const client = this.getClientForEndpoint(endpoint);
|
|
148
142
|
const options = {
|
|
149
|
-
method: endpoint.method
|
|
143
|
+
method: endpoint.method,
|
|
144
|
+
headers: {}
|
|
150
145
|
};
|
|
151
|
-
if (endpoint.headers) {
|
|
152
|
-
options.headers = { ...endpoint.headers };
|
|
153
|
-
}
|
|
154
146
|
if (query && Object.keys(query).length > 0) {
|
|
155
147
|
const searchParams = new URLSearchParams();
|
|
156
148
|
Object.entries(query).forEach(([key, value]) => {
|
|
@@ -165,15 +157,23 @@ var APIClient = class {
|
|
|
165
157
|
if (body && endpoint.method !== "GET") {
|
|
166
158
|
if (body instanceof FormData) {
|
|
167
159
|
options.body = body;
|
|
168
|
-
if (options.headers && options.headers["Content-Type"]) {
|
|
169
|
-
delete options.headers["Content-Type"];
|
|
170
|
-
}
|
|
171
160
|
} else if (endpoint.body) {
|
|
172
161
|
const validatedBody = endpoint.body.parse(body);
|
|
173
162
|
options.json = validatedBody;
|
|
174
163
|
} else {
|
|
175
164
|
options.json = body;
|
|
176
165
|
}
|
|
166
|
+
} else {
|
|
167
|
+
options.headers["Content-Type"] = "application/json";
|
|
168
|
+
}
|
|
169
|
+
if (endpoint.headers) {
|
|
170
|
+
Object.entries(endpoint.headers).forEach(([key, value]) => {
|
|
171
|
+
if (value !== void 0 && value !== null) {
|
|
172
|
+
options.headers[key] = value;
|
|
173
|
+
} else if (value === void 0 || value === null) {
|
|
174
|
+
delete options.headers[key];
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
177
|
}
|
|
178
178
|
const response = await client(path, options);
|
|
179
179
|
const data = await response.json();
|
|
@@ -230,22 +230,14 @@ var APIClient = class {
|
|
|
230
230
|
};
|
|
231
231
|
}
|
|
232
232
|
} else {
|
|
233
|
-
if (endpoint.params
|
|
233
|
+
if (endpoint.params) {
|
|
234
234
|
methods[name] = (params, body) => {
|
|
235
235
|
return this.request(endpoint, params, void 0, body);
|
|
236
236
|
};
|
|
237
|
-
} else
|
|
238
|
-
methods[name] = (params) => {
|
|
239
|
-
return this.request(endpoint, params);
|
|
240
|
-
};
|
|
241
|
-
} else if (endpoint.body) {
|
|
237
|
+
} else {
|
|
242
238
|
methods[name] = (body) => {
|
|
243
239
|
return this.request(endpoint, void 0, void 0, body);
|
|
244
240
|
};
|
|
245
|
-
} else {
|
|
246
|
-
methods[name] = () => {
|
|
247
|
-
return this.request(endpoint);
|
|
248
|
-
};
|
|
249
241
|
}
|
|
250
242
|
}
|
|
251
243
|
});
|
|
@@ -268,4 +260,4 @@ export {
|
|
|
268
260
|
APIClient,
|
|
269
261
|
createAPIClient
|
|
270
262
|
};
|
|
271
|
-
//# sourceMappingURL=chunk-
|
|
263
|
+
//# sourceMappingURL=chunk-4X4KIDBQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"sourcesContent":["import ky, { HTTPError } from \"ky\";\nimport type { APIConfig, APIEndpoint } from \"./schema.js\";\n\nexport interface AuthTokens {\n accessToken: string;\n refreshToken?: string;\n}\n\nexport interface AuthCallbacks {\n getTokens: () => Promise<AuthTokens | null>;\n onAuthError?: () => void;\n onRefreshToken?: () => Promise<void>;\n}\n\nexport class APIError extends Error {\n constructor(\n message: string,\n public status: number,\n public response?: any,\n ) {\n super(message);\n this.name = \"APIError\";\n }\n}\n\nexport class AuthError extends APIError {\n constructor(message: string = \"Authentication failed\") {\n super(message, 401);\n this.name = \"AuthError\";\n }\n}\n\nexport class APIClient {\n private client: typeof ky;\n private isRefreshing = false;\n private refreshPromise: Promise<void> | null = null;\n private hooks: any;\n\n constructor(\n private config: APIConfig,\n private authCallbacks?: AuthCallbacks,\n ) {\n this.hooks = {\n beforeRequest: [\n async (request: Request) => {\n const tokens = await this.authCallbacks?.getTokens();\n if (tokens?.accessToken) {\n request.headers.set(\n \"Authorization\",\n `Bearer ${tokens.accessToken}`,\n );\n }\n },\n ],\n beforeRetry: [\n async ({ request, error, retryCount }: any) => {\n if (error instanceof HTTPError && error.response.status === 401) {\n if (retryCount === 1 && this.authCallbacks) {\n try {\n await this.refreshTokens();\n const tokens = await this.authCallbacks.getTokens();\n if (tokens?.accessToken) {\n request.headers.set(\n \"Authorization\",\n `Bearer ${tokens.accessToken}`,\n );\n }\n } catch (refreshError) {\n this.authCallbacks.onAuthError?.();\n throw new AuthError();\n }\n } else {\n this.authCallbacks?.onAuthError?.();\n throw new AuthError();\n }\n }\n },\n ],\n beforeError: [\n async (error: any) => {\n const { response } = error;\n if (response?.body) {\n try {\n const body = await response.json();\n error.message =\n (body as Error).message || `HTTP ${response.status}`;\n } catch {\n // Keep original message\n }\n }\n return error;\n },\n ],\n };\n\n this.client = ky.create({\n prefixUrl: this.config.baseUrl,\n retry: {\n limit: 2,\n methods: [\"get\", \"post\", \"put\", \"delete\", \"patch\"],\n statusCodes: [401],\n },\n hooks: this.hooks,\n });\n }\n\n private async refreshTokens(): Promise<void> {\n if (!this.authCallbacks) {\n throw new AuthError(\"No auth callbacks provided\");\n }\n\n if (this.isRefreshing && this.refreshPromise) {\n return this.refreshPromise;\n }\n\n this.isRefreshing = true;\n\n this.refreshPromise = (async () => {\n try {\n if (this.authCallbacks?.onRefreshToken) {\n await this.authCallbacks.onRefreshToken();\n } else {\n throw new AuthError(\"No refresh token handler provided\");\n }\n } catch (error) {\n throw error;\n } finally {\n this.isRefreshing = false;\n this.refreshPromise = null;\n }\n })();\n\n return this.refreshPromise;\n }\n\n private buildPath(path: string, params?: Record<string, any>): string {\n if (!params) return path;\n\n let finalPath = path;\n Object.entries(params).forEach(([key, value]) => {\n finalPath = finalPath.replace(\n `:${key}`,\n encodeURIComponent(String(value)),\n );\n });\n\n return finalPath;\n }\n\n private getEndpointBaseUrl(endpoint: APIEndpoint): string {\n return endpoint.baseUrl || this.config.baseUrl!;\n }\n\n private getClientForEndpoint(endpoint: APIEndpoint): typeof ky {\n const endpointBaseUrl = this.getEndpointBaseUrl(endpoint);\n\n if (endpointBaseUrl === this.config.baseUrl) {\n return this.client;\n }\n\n return ky.create({\n prefixUrl: endpointBaseUrl,\n retry: {\n limit: 2,\n methods: [\"get\", \"post\", \"put\", \"delete\", \"patch\"],\n statusCodes: [401],\n },\n hooks: this.hooks,\n });\n }\n\n async request<T>(\n endpoint: APIEndpoint,\n params?: Record<string, any>,\n query?: Record<string, any>,\n body?: any,\n ): Promise<T> {\n try {\n const path = this.buildPath(endpoint.path, params);\n const client = this.getClientForEndpoint(endpoint);\n\n const options: Record<string, any> = {\n method: endpoint.method,\n headers: {},\n };\n\n if (query && Object.keys(query).length > 0) {\n const searchParams = new URLSearchParams();\n Object.entries(query).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n searchParams.append(key, String(value));\n }\n });\n if (searchParams.toString()) {\n options.searchParams = searchParams;\n }\n }\n\n // Handle body and set appropriate Content-Type\n if (body && endpoint.method !== \"GET\") {\n // Check if body is FormData\n if (body instanceof FormData) {\n options.body = body;\n // DO NOT set Content-Type for FormData\n // Browser will automatically set multipart/form-data with boundary\n } else if (endpoint.body) {\n const validatedBody = endpoint.body.parse(body);\n options.json = validatedBody;\n // ky automatically sets Content-Type: application/json when using options.json\n } else {\n options.json = body;\n // ky automatically sets Content-Type: application/json when using options.json\n }\n } else {\n // For GET requests or requests without body, default to JSON\n options.headers[\"Content-Type\"] = \"application/json\";\n }\n\n // Apply custom headers AFTER body processing\n // This allows endpoint headers to override Content-Type if needed\n if (endpoint.headers) {\n Object.entries(endpoint.headers).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n options.headers[key] = value;\n } else if (value === undefined || value === null) {\n // Allow explicitly unsetting headers\n delete options.headers[key];\n }\n });\n }\n\n const response = await client(path, options);\n const data = await response.json();\n\n if (endpoint.response) {\n return endpoint.response.parse(data);\n }\n\n return data as T;\n } catch (error) {\n if (error instanceof HTTPError) {\n const errorData = await error.response.json().catch(() => ({}));\n throw new APIError(\n errorData.message || error.message,\n error.response.status,\n errorData,\n );\n }\n\n if (error instanceof AuthError) {\n throw error;\n }\n\n throw new APIError(\n error instanceof Error ? error.message : \"Network error\",\n 0,\n );\n }\n }\n\n updateAuthCallbacks(authCallbacks: AuthCallbacks) {\n this.authCallbacks = authCallbacks;\n }\n\n async refreshAuth(): Promise<void> {\n if (!this.authCallbacks) {\n throw new AuthError(\"No auth callbacks provided\");\n }\n await this.refreshTokens();\n }\n\n generateMethods() {\n const methods: any = {};\n\n Object.entries(this.config.endpoints).forEach(([name, endpoint]) => {\n if (endpoint.method === \"GET\") {\n if (endpoint.params && endpoint.query) {\n methods[name] = (params: any, query?: any): Promise<any> => {\n return this.request(endpoint, params, query);\n };\n } else if (endpoint.params) {\n methods[name] = (params: any): Promise<any> => {\n return this.request(endpoint, params);\n };\n } else if (endpoint.query) {\n methods[name] = (query?: any): Promise<any> => {\n return this.request(endpoint, undefined, query);\n };\n } else {\n methods[name] = (): Promise<any> => {\n return this.request(endpoint);\n };\n }\n } else {\n // For non-GET methods (POST, PUT, PATCH, DELETE)\n // Always support body parameter to allow FormData and other dynamic bodies\n if (endpoint.params) {\n methods[name] = (params: any, body?: any): Promise<any> => {\n return this.request(endpoint, params, undefined, body);\n };\n } else {\n // Always allow optional body parameter for non-GET methods\n methods[name] = (body?: any): Promise<any> => {\n return this.request(endpoint, undefined, undefined, body);\n };\n }\n }\n });\n\n return methods;\n }\n}\n\nexport function createAPIClient(\n config: APIConfig,\n authCallbacks?: AuthCallbacks,\n) {\n const instance = new APIClient(config, authCallbacks);\n const methods = instance.generateMethods();\n\n return {\n ...methods,\n refreshAuth: () => instance.refreshAuth(),\n updateAuthCallbacks: (newCallbacks: AuthCallbacks) =>\n instance.updateAuthCallbacks(newCallbacks),\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/client.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -3,12 +3,12 @@ import {
|
|
|
3
3
|
APIError,
|
|
4
4
|
AuthError,
|
|
5
5
|
createAPIClient
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-4X4KIDBQ.js";
|
|
7
7
|
import {
|
|
8
8
|
defineConfig,
|
|
9
9
|
defineEndpoint,
|
|
10
10
|
defineEndpoints
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-3FFXWCVP.js";
|
|
12
12
|
export {
|
|
13
13
|
APIClient,
|
|
14
14
|
APIError,
|
package/dist/schema.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ interface APIEndpoint {
|
|
|
11
11
|
response: z.ZodType<any>;
|
|
12
12
|
tags?: string[];
|
|
13
13
|
description?: string;
|
|
14
|
-
headers?: Record<string, string>;
|
|
14
|
+
headers?: Record<string, string | undefined | null>;
|
|
15
15
|
}
|
|
16
16
|
interface APIConfig {
|
|
17
17
|
baseUrl?: string;
|
|
@@ -27,7 +27,7 @@ type EndpointConfig<TPath extends string = string, TMethod extends HTTPMethod =
|
|
|
27
27
|
response: z.ZodType<TResponse>;
|
|
28
28
|
tags?: string[];
|
|
29
29
|
description?: string;
|
|
30
|
-
headers?: Record<string, string>;
|
|
30
|
+
headers?: Record<string, string | undefined | null>;
|
|
31
31
|
};
|
|
32
32
|
/**
|
|
33
33
|
* Helper function to define API configuration with type safety
|
package/dist/schema.js
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts"],"sourcesContent":["import ky, { HTTPError } from \"ky\";\nimport type { APIConfig, APIEndpoint } from \"./schema.js\";\n\nexport interface AuthTokens {\n accessToken: string;\n refreshToken?: string;\n}\n\nexport interface AuthCallbacks {\n getTokens: () => Promise<AuthTokens | null>;\n onAuthError?: () => void;\n onRefreshToken?: () => Promise<void>;\n}\n\nexport class APIError extends Error {\n constructor(\n message: string,\n public status: number,\n public response?: any,\n ) {\n super(message);\n this.name = \"APIError\";\n }\n}\n\nexport class AuthError extends APIError {\n constructor(message: string = \"Authentication failed\") {\n super(message, 401);\n this.name = \"AuthError\";\n }\n}\n\nexport class APIClient {\n private client: typeof ky;\n private isRefreshing = false;\n private refreshPromise: Promise<void> | null = null;\n private hooks: any;\n\n constructor(\n private config: APIConfig,\n private authCallbacks?: AuthCallbacks,\n ) {\n this.hooks = {\n beforeRequest: [\n async (request: Request) => {\n const tokens = await this.authCallbacks?.getTokens();\n if (tokens?.accessToken) {\n request.headers.set(\n \"Authorization\",\n `Bearer ${tokens.accessToken}`,\n );\n }\n },\n ],\n beforeRetry: [\n async ({ request, error, retryCount }: any) => {\n if (error instanceof HTTPError && error.response.status === 401) {\n if (retryCount === 1 && this.authCallbacks) {\n try {\n await this.refreshTokens();\n const tokens = await this.authCallbacks.getTokens();\n if (tokens?.accessToken) {\n request.headers.set(\n \"Authorization\",\n `Bearer ${tokens.accessToken}`,\n );\n }\n } catch (refreshError) {\n this.authCallbacks.onAuthError?.();\n throw new AuthError();\n }\n } else {\n this.authCallbacks?.onAuthError?.();\n throw new AuthError();\n }\n }\n },\n ],\n beforeError: [\n async (error: any) => {\n const { response } = error;\n if (response?.body) {\n try {\n const body = await response.json();\n error.message =\n (body as Error).message || `HTTP ${response.status}`;\n } catch {\n // Keep original message\n }\n }\n return error;\n },\n ],\n };\n\n this.client = ky.create({\n prefixUrl: this.config.baseUrl,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n retry: {\n limit: 2,\n methods: [\"get\", \"post\", \"put\", \"delete\", \"patch\"],\n statusCodes: [401],\n },\n hooks: this.hooks,\n });\n }\n\n private async refreshTokens(): Promise<void> {\n if (!this.authCallbacks) {\n throw new AuthError(\"No auth callbacks provided\");\n }\n\n if (this.isRefreshing && this.refreshPromise) {\n return this.refreshPromise;\n }\n\n this.isRefreshing = true;\n\n this.refreshPromise = (async () => {\n try {\n if (this.authCallbacks?.onRefreshToken) {\n await this.authCallbacks.onRefreshToken();\n } else {\n throw new AuthError(\"No refresh token handler provided\");\n }\n } catch (error) {\n throw error;\n } finally {\n this.isRefreshing = false;\n this.refreshPromise = null;\n }\n })();\n\n return this.refreshPromise;\n }\n\n private buildPath(path: string, params?: Record<string, any>): string {\n if (!params) return path;\n\n let finalPath = path;\n Object.entries(params).forEach(([key, value]) => {\n finalPath = finalPath.replace(\n `:${key}`,\n encodeURIComponent(String(value)),\n );\n });\n\n return finalPath;\n }\n\n private getEndpointBaseUrl(endpoint: APIEndpoint): string {\n return endpoint.baseUrl || this.config.baseUrl!;\n }\n\n private getClientForEndpoint(endpoint: APIEndpoint): typeof ky {\n const endpointBaseUrl = this.getEndpointBaseUrl(endpoint);\n\n if (endpointBaseUrl === this.config.baseUrl) {\n return this.client;\n }\n\n return ky.create({\n prefixUrl: endpointBaseUrl,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n retry: {\n limit: 2,\n methods: [\"get\", \"post\", \"put\", \"delete\", \"patch\"],\n statusCodes: [401],\n },\n hooks: this.hooks,\n });\n }\n\n async request<T>(\n endpoint: APIEndpoint,\n params?: Record<string, any>,\n query?: Record<string, any>,\n body?: any,\n ): Promise<T> {\n try {\n const path = this.buildPath(endpoint.path, params);\n const client = this.getClientForEndpoint(endpoint);\n\n const options: Record<string, any> = {\n method: endpoint.method,\n };\n\n // Apply custom headers if provided\n if (endpoint.headers) {\n options.headers = { ...endpoint.headers };\n }\n\n if (query && Object.keys(query).length > 0) {\n const searchParams = new URLSearchParams();\n Object.entries(query).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n searchParams.append(key, String(value));\n }\n });\n if (searchParams.toString()) {\n options.searchParams = searchParams;\n }\n }\n\n if (body && endpoint.method !== \"GET\") {\n // Check if body is FormData\n if (body instanceof FormData) {\n options.body = body;\n // Remove Content-Type header to let the browser set it with the correct boundary\n if (options.headers && options.headers[\"Content-Type\"]) {\n delete options.headers[\"Content-Type\"];\n }\n } else if (endpoint.body) {\n const validatedBody = endpoint.body.parse(body);\n options.json = validatedBody;\n } else {\n options.json = body;\n }\n }\n\n const response = await client(path, options);\n const data = await response.json();\n\n if (endpoint.response) {\n return endpoint.response.parse(data);\n }\n\n return data as T;\n } catch (error) {\n if (error instanceof HTTPError) {\n const errorData = await error.response.json().catch(() => ({}));\n throw new APIError(\n errorData.message || error.message,\n error.response.status,\n errorData,\n );\n }\n\n if (error instanceof AuthError) {\n throw error;\n }\n\n throw new APIError(\n error instanceof Error ? error.message : \"Network error\",\n 0,\n );\n }\n }\n\n updateAuthCallbacks(authCallbacks: AuthCallbacks) {\n this.authCallbacks = authCallbacks;\n }\n\n async refreshAuth(): Promise<void> {\n if (!this.authCallbacks) {\n throw new AuthError(\"No auth callbacks provided\");\n }\n await this.refreshTokens();\n }\n\n generateMethods() {\n const methods: any = {};\n\n Object.entries(this.config.endpoints).forEach(([name, endpoint]) => {\n if (endpoint.method === \"GET\") {\n if (endpoint.params && endpoint.query) {\n methods[name] = (params: any, query?: any): Promise<any> => {\n return this.request(endpoint, params, query);\n };\n } else if (endpoint.params) {\n methods[name] = (params: any): Promise<any> => {\n return this.request(endpoint, params);\n };\n } else if (endpoint.query) {\n methods[name] = (query?: any): Promise<any> => {\n return this.request(endpoint, undefined, query);\n };\n } else {\n methods[name] = (): Promise<any> => {\n return this.request(endpoint);\n };\n }\n } else {\n if (endpoint.params && endpoint.body) {\n methods[name] = (params: any, body: any): Promise<any> => {\n return this.request(endpoint, params, undefined, body);\n };\n } else if (endpoint.params) {\n methods[name] = (params: any): Promise<any> => {\n return this.request(endpoint, params);\n };\n } else if (endpoint.body) {\n methods[name] = (body: any): Promise<any> => {\n return this.request(endpoint, undefined, undefined, body);\n };\n } else {\n methods[name] = (): Promise<any> => {\n return this.request(endpoint);\n };\n }\n }\n });\n\n return methods;\n }\n}\n\nexport function createAPIClient(\n config: APIConfig,\n authCallbacks?: AuthCallbacks,\n) {\n const instance = new APIClient(config, authCallbacks);\n const methods = instance.generateMethods();\n\n return {\n ...methods,\n refreshAuth: () => instance.refreshAuth(),\n updateAuthCallbacks: (newCallbacks: AuthCallbacks) =>\n instance.updateAuthCallbacks(newCallbacks),\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schema.ts"],"sourcesContent":["import type { z } from \"zod\";\n\nexport type HTTPMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n\nexport interface APIEndpoint {\n path: string;\n method: HTTPMethod;\n baseUrl?: string;\n params?: z.ZodType<any>;\n query?: z.ZodType<any>;\n body?: z.ZodType<any>;\n response: z.ZodType<any>;\n tags?: string[];\n description?: string;\n headers?: Record<string, string>;\n}\n\nexport interface APIConfig {\n baseUrl?: string;\n endpoints: Record<string, APIEndpoint>;\n}\n\nexport type EndpointConfig<\n TPath extends string = string,\n TMethod extends HTTPMethod = HTTPMethod,\n TParams = undefined,\n TQuery = undefined,\n TBody = undefined,\n TResponse = any,\n> = {\n path: TPath;\n method: TMethod;\n baseUrl?: string;\n params?: z.ZodType<TParams>;\n query?: z.ZodType<TQuery>;\n body?: z.ZodType<TBody>;\n response: z.ZodType<TResponse>;\n tags?: string[];\n description?: string;\n headers?: Record<string, string>;\n};\n\n/**\n * Helper function to define API configuration with type safety\n */\nexport function defineConfig<T extends APIConfig>(config: T): T {\n return config;\n}\n\n/**\n * Helper function to define a single endpoint with type inference\n */\nexport function defineEndpoint<\n TPath extends string,\n TMethod extends HTTPMethod,\n TParams = undefined,\n TQuery = undefined,\n TBody = undefined,\n TResponse = any,\n>(\n config: EndpointConfig<TPath, TMethod, TParams, TQuery, TBody, TResponse>,\n): EndpointConfig<TPath, TMethod, TParams, TQuery, TBody, TResponse> {\n return config;\n}\n\n/**\n * Helper to define multiple endpoints\n */\nexport function defineEndpoints<T extends Record<string, APIEndpoint>>(\n endpoints: T,\n): T {\n return endpoints;\n}\n"],"mappings":";AA6CO,SAAS,aAAkC,QAAc;AAC9D,SAAO;AACT;AAKO,SAAS,eAQd,QACmE;AACnE,SAAO;AACT;AAKO,SAAS,gBACd,WACG;AACH,SAAO;AACT;","names":[]}
|