@cushin/api-codegen 1.1.0 → 2.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 DELETED
@@ -1,435 +0,0 @@
1
- # @cushin/api-codegen
2
-
3
- Type-safe API client generator for React/Next.js applications with automatic hooks and server actions generation.
4
-
5
- ## Features
6
-
7
- - 🎯 **Type-Safe**: Full TypeScript support with Zod schema validation
8
- - 🔄 **Auto-Generated**: Generate React Query hooks, Server Actions, and Server Queries
9
- - 🚀 **Framework Agnostic**: Works with Vite, Next.js, and more
10
- - 🔐 **Auth Built-in**: Token refresh, automatic retry with customizable callbacks
11
- - 📦 **Zero Config**: Simple configuration with sensible defaults
12
- - 🎨 **Customizable**: Custom templates and generation options
13
-
14
- ## Installation
15
-
16
- ```bash
17
- npm install @cushin/api-codegen ky zod
18
- # or
19
- pnpm add @cushin/api-codegen ky zod
20
- # or
21
- yarn add @cushin/api-codegen ky zod
22
- ```
23
-
24
- For React Query support (client-side):
25
- ```bash
26
- npm install @tanstack/react-query
27
- ```
28
-
29
- ## Quick Start
30
-
31
- ### 1. Initialize Configuration
32
-
33
- ```bash
34
- npx @cushin/api-codegen init --provider vite
35
- # or for Next.js
36
- npx @cushin/api-codegen init --provider nextjs
37
- ```
38
-
39
- This creates `api-codegen.config.js`:
40
-
41
- ```js
42
- /** @type {import('@cushin/api-codegen').UserConfig} */
43
- export default {
44
- provider: 'vite',
45
- endpoints: './lib/api/config/endpoints.ts',
46
- output: './lib/api/generated',
47
- baseUrl: process.env.VITE_API_URL,
48
- generateHooks: true,
49
- generateClient: true,
50
- };
51
- ```
52
-
53
- ### 2. Define Your API Endpoints
54
-
55
- Create your endpoints configuration file:
56
-
57
- ```typescript
58
- // lib/api/config/endpoints.ts
59
- import { z } from 'zod';
60
- import { defineConfig, defineEndpoint } from '@cushin/api-codegen';
61
-
62
- // Define your schemas
63
- const UserSchema = z.object({
64
- id: z.string(),
65
- name: z.string(),
66
- email: z.string().email(),
67
- });
68
-
69
- const CreateUserSchema = z.object({
70
- name: z.string(),
71
- email: z.string().email(),
72
- });
73
-
74
- // Define your endpoints
75
- export const apiConfig = defineConfig({
76
- baseUrl: 'https://api.example.com',
77
- endpoints: {
78
- // GET request
79
- getUser: defineEndpoint({
80
- path: '/users/:id',
81
- method: 'GET',
82
- params: z.object({ id: z.string() }),
83
- response: UserSchema,
84
- tags: ['users', 'query'],
85
- description: 'Get user by ID',
86
- }),
87
-
88
- // GET with query params
89
- listUsers: defineEndpoint({
90
- path: '/users',
91
- method: 'GET',
92
- query: z.object({
93
- page: z.number().optional(),
94
- limit: z.number().optional(),
95
- }),
96
- response: z.array(UserSchema),
97
- tags: ['users', 'query'],
98
- }),
99
-
100
- // POST request
101
- createUser: defineEndpoint({
102
- path: '/users',
103
- method: 'POST',
104
- body: CreateUserSchema,
105
- response: UserSchema,
106
- tags: ['users', 'mutation'],
107
- }),
108
-
109
- // PUT request with params
110
- updateUser: defineEndpoint({
111
- path: '/users/:id',
112
- method: 'PUT',
113
- params: z.object({ id: z.string() }),
114
- body: CreateUserSchema,
115
- response: UserSchema,
116
- tags: ['users', 'mutation'],
117
- }),
118
-
119
- // DELETE request
120
- deleteUser: defineEndpoint({
121
- path: '/users/:id',
122
- method: 'DELETE',
123
- params: z.object({ id: z.string() }),
124
- response: z.object({ success: z.boolean() }),
125
- tags: ['users', 'mutation'],
126
- }),
127
- },
128
- });
129
- ```
130
-
131
- ### 3. Generate Code
132
-
133
- ```bash
134
- npx @cushin/api-codegen generate
135
- ```
136
-
137
- This generates:
138
- - `generated/types.ts` - Type definitions
139
- - `generated/client.ts` - API client
140
- - `generated/hooks.ts` - React Query hooks
141
- - `generated/actions.ts` - Server Actions (Next.js only)
142
- - `generated/queries.ts` - Server Queries (Next.js only)
143
-
144
- ### 4. Initialize Client (Vite)
145
-
146
- ```typescript
147
- // lib/auth/provider.tsx
148
- import { initializeAPIClient } from '@/lib/api/generated/client';
149
-
150
- export function AuthProvider({ children }) {
151
- useEffect(() => {
152
- initializeAPIClient({
153
- getTokens: () => {
154
- const token = localStorage.getItem('access_token');
155
- return token ? { accessToken: token } : null;
156
- },
157
- setTokens: (tokens) => {
158
- localStorage.setItem('access_token', tokens.accessToken);
159
- },
160
- clearTokens: () => {
161
- localStorage.removeItem('access_token');
162
- },
163
- onAuthError: () => {
164
- router.push('/login');
165
- },
166
- onRefreshToken: async () => {
167
- const response = await fetch('/api/auth/refresh', {
168
- method: 'POST',
169
- credentials: 'include',
170
- });
171
- const data = await response.json();
172
- return data.accessToken;
173
- },
174
- });
175
- }, []);
176
-
177
- return <>{children}</>;
178
- }
179
- ```
180
-
181
- ### 5. Use Generated Hooks
182
-
183
- ```typescript
184
- // components/UserList.tsx
185
- import { useListUsers, useCreateUser, useDeleteUser } from '@/lib/api/generated/hooks';
186
-
187
- export function UserList() {
188
- // Query hook
189
- const { data: users, isLoading } = useListUsers({
190
- page: 1,
191
- limit: 10,
192
- });
193
-
194
- // Mutation hooks
195
- const createUser = useCreateUser({
196
- onSuccess: () => {
197
- console.log('User created!');
198
- },
199
- });
200
-
201
- const deleteUser = useDeleteUser();
202
-
203
- const handleCreate = () => {
204
- createUser.mutate({
205
- name: 'John Doe',
206
- email: 'john@example.com',
207
- });
208
- };
209
-
210
- const handleDelete = (id: string) => {
211
- deleteUser.mutate({ id });
212
- };
213
-
214
- if (isLoading) return <div>Loading...</div>;
215
-
216
- return (
217
- <div>
218
- <button onClick={handleCreate}>Create User</button>
219
- {users?.map((user) => (
220
- <div key={user.id}>
221
- {user.name}
222
- <button onClick={() => handleDelete(user.id)}>Delete</button>
223
- </div>
224
- ))}
225
- </div>
226
- );
227
- }
228
- ```
229
-
230
- ## Next.js Usage
231
-
232
- ### Server Components
233
-
234
- ```typescript
235
- // app/users/page.tsx
236
- import { listUsersQuery } from '@/lib/api/generated/queries';
237
-
238
- export default async function UsersPage() {
239
- const users = await listUsersQuery({ page: 1, limit: 10 });
240
-
241
- return (
242
- <div>
243
- {users.map((user) => (
244
- <div key={user.id}>{user.name}</div>
245
- ))}
246
- </div>
247
- );
248
- }
249
- ```
250
-
251
- ### Server Actions
252
-
253
- ```typescript
254
- // app/users/actions.ts
255
- 'use client';
256
-
257
- import { createUserAction, deleteUserAction } from '@/lib/api/generated/actions';
258
- import { useTransition } from 'react';
259
-
260
- export function UserForm() {
261
- const [isPending, startTransition] = useTransition();
262
-
263
- const handleSubmit = async (formData: FormData) => {
264
- startTransition(async () => {
265
- const result = await createUserAction({
266
- name: formData.get('name') as string,
267
- email: formData.get('email') as string,
268
- });
269
-
270
- if (result.success) {
271
- console.log('User created:', result.data);
272
- } else {
273
- console.error('Error:', result.error);
274
- }
275
- });
276
- };
277
-
278
- return <form action={handleSubmit}>...</form>;
279
- }
280
- ```
281
-
282
- ## Configuration
283
-
284
- ### Full Configuration Options
285
-
286
- ```typescript
287
- /** @type {import('@cushin/api-codegen').UserConfig} */
288
- export default {
289
- // Required: Provider type
290
- provider: 'vite' | 'nextjs',
291
-
292
- // Required: Path to endpoints configuration
293
- endpoints: './lib/api/config/endpoints.ts',
294
-
295
- // Required: Output directory
296
- output: './lib/api/generated',
297
-
298
- // Optional: Base URL (can also be set at runtime)
299
- baseUrl: process.env.VITE_API_URL,
300
-
301
- // Optional: Generation flags
302
- generateHooks: true, // Generate React Query hooks
303
- generateClient: true, // Generate API client
304
- generateServerActions: true, // Next.js only
305
- generateServerQueries: true, // Next.js only
306
-
307
- // Optional: Advanced options
308
- options: {
309
- useClientDirective: true, // Add 'use client' to generated files
310
- hookPrefix: 'use', // Prefix for hook names (e.g., useGetUser)
311
- actionSuffix: 'Action', // Suffix for action names (e.g., createUserAction)
312
- customImports: {
313
- // Add custom imports to generated files
314
- hooks: ['import { customHook } from "./custom"'],
315
- },
316
- },
317
- };
318
- ```
319
-
320
- ## CLI Commands
321
-
322
- ```bash
323
- # Generate code from config
324
- npx @cushin/api-codegen generate
325
-
326
- # Generate with specific config file
327
- npx @cushin/api-codegen generate --config ./custom.config.js
328
-
329
- # Initialize new config
330
- npx @cushin/api-codegen init --provider nextjs
331
-
332
- # Validate configuration
333
- npx @cushin/api-codegen validate
334
- ```
335
-
336
- ## Advanced Usage
337
-
338
- ### Custom Base URL per Endpoint
339
-
340
- ```typescript
341
- defineEndpoint({
342
- path: '/auth/login',
343
- method: 'POST',
344
- baseUrl: 'https://auth.example.com', // Override base URL
345
- body: LoginSchema,
346
- response: TokenSchema,
347
- });
348
- ```
349
-
350
- ### Multiple Endpoints Files
351
-
352
- ```typescript
353
- // lib/api/config/modules/users.ts
354
- export const userEndpoints = {
355
- getUser: defineEndpoint({ ... }),
356
- createUser: defineEndpoint({ ... }),
357
- };
358
-
359
- // lib/api/config/endpoints.ts
360
- import { userEndpoints } from './modules/users';
361
- import { productEndpoints } from './modules/products';
362
-
363
- export const apiConfig = defineConfig({
364
- baseUrl: 'https://api.example.com',
365
- endpoints: {
366
- ...userEndpoints,
367
- ...productEndpoints,
368
- },
369
- });
370
- ```
371
-
372
- ### Custom Auth Logic
373
-
374
- ```typescript
375
- initializeAPIClient({
376
- getTokens: () => {
377
- // Custom token retrieval
378
- return yourAuthStore.getTokens();
379
- },
380
- setTokens: (tokens) => {
381
- // Custom token storage
382
- yourAuthStore.setTokens(tokens);
383
- },
384
- clearTokens: () => {
385
- // Custom cleanup
386
- yourAuthStore.clearTokens();
387
- },
388
- onRefreshToken: async () => {
389
- // Custom refresh logic
390
- const newToken = await yourRefreshFunction();
391
- return newToken;
392
- },
393
- onAuthError: () => {
394
- // Custom error handling
395
- yourRouter.push('/login');
396
- },
397
- });
398
- ```
399
-
400
- ## Type Safety
401
-
402
- All generated code is fully typed:
403
-
404
- ```typescript
405
- // IntelliSense knows the exact shape
406
- const { data } = useGetUser({ id: '123' });
407
- // ^? { id: string; name: string; email: string; }
408
-
409
- // TypeScript will error on invalid params
410
- const { data } = useGetUser({ id: 123 }); // ❌ Type error
411
- const { data } = useGetUser({ wrongParam: '123' }); // ❌ Type error
412
-
413
- // Mutation inputs are also typed
414
- createUser.mutate({
415
- name: 'John',
416
- email: 'invalid', // ❌ Type error: invalid email format
417
- });
418
- ```
419
-
420
- ## Best Practices
421
-
422
- 1. **Organize endpoints by feature/module**
423
- 2. **Use descriptive endpoint names**
424
- 3. **Add descriptions to endpoints for better documentation**
425
- 4. **Use tags for query invalidation**
426
- 5. **Define reusable schemas**
427
- 6. **Keep baseUrl in environment variables**
428
-
429
- ## Contributing
430
-
431
- Contributions are welcome! Please read our contributing guide.
432
-
433
- ## License
434
-
435
- MIT © Le Viet Hoang
package/dist/cli.d.ts DELETED
@@ -1 +0,0 @@
1
- #!/usr/bin/env node
@@ -1,84 +0,0 @@
1
- import { APIConfig } from './schema.js';
2
- import 'zod';
3
-
4
- interface UserConfig {
5
- /**
6
- * Base URL for API requests
7
- */
8
- baseUrl?: string;
9
- /**
10
- * Path to the endpoints configuration file
11
- */
12
- endpoints: string;
13
- /**
14
- * Provider type: 'vite' | 'nextjs'
15
- */
16
- provider: "vite" | "nextjs";
17
- /**
18
- * Output directory for generated files
19
- */
20
- output: string;
21
- /**
22
- * Whether to generate React Query hooks (for client-side)
23
- * @default true for vite, nextjs
24
- */
25
- generateHooks?: boolean;
26
- /**
27
- * Whether to generate server actions (Next.js only)
28
- * @default true for nextjs, false for vite
29
- */
30
- generateServerActions?: boolean;
31
- /**
32
- * Whether to generate server queries (Next.js only)
33
- * @default true for nextjs, false for vite
34
- */
35
- generateServerQueries?: boolean;
36
- /**
37
- * Whether to generate API client
38
- * @default true
39
- */
40
- generateClient?: boolean;
41
- /**
42
- * Whether to generate prefetch utilities
43
- * @default true
44
- */
45
- generatePrefetch?: boolean;
46
- /**
47
- * Custom templates directory
48
- */
49
- templatesDir?: string;
50
- /**
51
- * Additional options
52
- */
53
- options?: {
54
- /**
55
- * Use 'use client' directive
56
- */
57
- useClientDirective?: boolean;
58
- /**
59
- * Custom imports to add to generated files
60
- */
61
- customImports?: Record<string, string[]>;
62
- /**
63
- * Prefix for generated hook names
64
- */
65
- hookPrefix?: string;
66
- /**
67
- * Suffix for generated action names
68
- */
69
- actionSuffix?: string;
70
- };
71
- }
72
- interface ResolvedConfig extends UserConfig {
73
- rootDir: string;
74
- endpointsPath: string;
75
- outputDir: string;
76
- apiConfig?: APIConfig;
77
- }
78
- declare function loadConfig(configPath?: string): Promise<ResolvedConfig | null>;
79
- /**
80
- * Validate user config
81
- */
82
- declare function validateConfig(config: UserConfig): void;
83
-
84
- export { type ResolvedConfig, type UserConfig, loadConfig, validateConfig };
@@ -1,69 +0,0 @@
1
- import { cosmiconfig } from 'cosmiconfig';
2
- import path from 'path';
3
-
4
- // src/config/index.ts
5
- var explorer = cosmiconfig("api-codegen", {
6
- searchPlaces: [
7
- "api-codegen.config.js",
8
- "api-codegen.config.mjs",
9
- "api-codegen.config.ts",
10
- "api-codegen.config.json",
11
- ".api-codegenrc",
12
- ".api-codegenrc.json",
13
- ".api-codegenrc.js"
14
- ]
15
- });
16
- async function loadConfig(configPath) {
17
- try {
18
- const result = configPath ? await explorer.load(configPath) : await explorer.search();
19
- if (!result || !result.config) {
20
- return null;
21
- }
22
- const userConfig = result.config;
23
- const rootDir = path.dirname(result.filepath);
24
- const endpointsPath = path.resolve(rootDir, userConfig.endpoints);
25
- const outputDir = path.resolve(rootDir, userConfig.output);
26
- const generateHooks = userConfig.generateHooks ?? true;
27
- const generateServerActions = userConfig.generateServerActions ?? userConfig.provider === "nextjs";
28
- const generateServerQueries = userConfig.generateServerQueries ?? userConfig.provider === "nextjs";
29
- const generateClient = userConfig.generateClient ?? true;
30
- const generatePrefetch = userConfig.generatePrefetch ?? true;
31
- return {
32
- ...userConfig,
33
- rootDir,
34
- endpointsPath,
35
- outputDir,
36
- generateHooks,
37
- generateServerActions,
38
- generateServerQueries,
39
- generateClient,
40
- generatePrefetch
41
- };
42
- } catch (error) {
43
- throw new Error(
44
- `Failed to load config: ${error instanceof Error ? error.message : String(error)}`
45
- );
46
- }
47
- }
48
- function validateConfig(config) {
49
- if (!config.endpoints) {
50
- throw new Error('Config error: "endpoints" path is required');
51
- }
52
- if (!config.provider) {
53
- throw new Error(
54
- 'Config error: "provider" must be specified (vite or nextjs)'
55
- );
56
- }
57
- if (!["vite", "nextjs"].includes(config.provider)) {
58
- throw new Error(
59
- 'Config error: "provider" must be either "vite" or "nextjs"'
60
- );
61
- }
62
- if (!config.output) {
63
- throw new Error('Config error: "output" directory is required');
64
- }
65
- }
66
-
67
- export { loadConfig, validateConfig };
68
- //# sourceMappingURL=index.js.map
69
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/config/index.ts"],"names":[],"mappings":";;;;AA6FA,IAAM,QAAA,GAAW,YAAY,aAAA,EAAe;AAAA,EAC1C,YAAA,EAAc;AAAA,IACZ,uBAAA;AAAA,IACA,wBAAA;AAAA,IACA,uBAAA;AAAA,IACA,yBAAA;AAAA,IACA,gBAAA;AAAA,IACA,qBAAA;AAAA,IACA;AAAA;AAEJ,CAAC,CAAA;AAED,eAAsB,WACpB,UAAA,EACgC;AAChC,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,aACX,MAAM,QAAA,CAAS,KAAK,UAAU,CAAA,GAC9B,MAAM,QAAA,CAAS,MAAA,EAAO;AAE1B,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,CAAO,MAAA,EAAQ;AAC7B,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,aAAa,MAAA,CAAO,MAAA;AAC1B,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,QAAQ,CAAA;AAG5C,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,WAAW,SAAS,CAAA;AAChE,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,WAAW,MAAM,CAAA;AAGzD,IAAA,MAAM,aAAA,GAAgB,WAAW,aAAA,IAAiB,IAAA;AAClD,IAAA,MAAM,qBAAA,GACJ,UAAA,CAAW,qBAAA,IAAyB,UAAA,CAAW,QAAA,KAAa,QAAA;AAC9D,IAAA,MAAM,qBAAA,GACJ,UAAA,CAAW,qBAAA,IAAyB,UAAA,CAAW,QAAA,KAAa,QAAA;AAC9D,IAAA,MAAM,cAAA,GAAiB,WAAW,cAAA,IAAkB,IAAA;AACpD,IAAA,MAAM,gBAAA,GAAmB,WAAW,gBAAA,IAAoB,IAAA;AAExD,IAAA,OAAO;AAAA,MACL,GAAG,UAAA;AAAA,MACH,OAAA;AAAA,MACA,aAAA;AAAA,MACA,SAAA;AAAA,MACA,aAAA;AAAA,MACA,qBAAA;AAAA,MACA,qBAAA;AAAA,MACA,cAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,0BAA0B,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,KAClF;AAAA,EACF;AACF;AAKO,SAAS,eAAe,MAAA,EAA0B;AACvD,EAAA,IAAI,CAAC,OAAO,SAAA,EAAW;AACrB,IAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,EAC9D;AAEA,EAAA,IAAI,CAAC,OAAO,QAAA,EAAU;AACpB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,CAAC,MAAA,EAAQ,QAAQ,EAAE,QAAA,CAAS,MAAA,CAAO,QAAQ,CAAA,EAAG;AACjD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,OAAO,MAAA,EAAQ;AAClB,IAAA,MAAM,IAAI,MAAM,8CAA8C,CAAA;AAAA,EAChE;AACF","file":"index.js","sourcesContent":["import { cosmiconfig } from \"cosmiconfig\";\nimport path from \"path\";\nimport type { APIConfig } from \"./schema.js\";\n\nexport interface UserConfig {\n /**\n * Base URL for API requests\n */\n baseUrl?: string;\n\n /**\n * Path to the endpoints configuration file\n */\n endpoints: string;\n\n /**\n * Provider type: 'vite' | 'nextjs'\n */\n provider: \"vite\" | \"nextjs\";\n\n /**\n * Output directory for generated files\n */\n output: string;\n\n /**\n * Whether to generate React Query hooks (for client-side)\n * @default true for vite, nextjs\n */\n generateHooks?: boolean;\n\n /**\n * Whether to generate server actions (Next.js only)\n * @default true for nextjs, false for vite\n */\n generateServerActions?: boolean;\n\n /**\n * Whether to generate server queries (Next.js only)\n * @default true for nextjs, false for vite\n */\n generateServerQueries?: boolean;\n\n /**\n * Whether to generate API client\n * @default true\n */\n generateClient?: boolean;\n\n /**\n * Whether to generate prefetch utilities\n * @default true\n */\n generatePrefetch?: boolean;\n\n /**\n * Custom templates directory\n */\n templatesDir?: string;\n\n /**\n * Additional options\n */\n options?: {\n /**\n * Use 'use client' directive\n */\n useClientDirective?: boolean;\n\n /**\n * Custom imports to add to generated files\n */\n customImports?: Record<string, string[]>;\n\n /**\n * Prefix for generated hook names\n */\n hookPrefix?: string;\n\n /**\n * Suffix for generated action names\n */\n actionSuffix?: string;\n };\n}\n\nexport interface ResolvedConfig extends UserConfig {\n rootDir: string;\n endpointsPath: string;\n outputDir: string;\n apiConfig?: APIConfig;\n}\n\nconst explorer = cosmiconfig(\"api-codegen\", {\n searchPlaces: [\n \"api-codegen.config.js\",\n \"api-codegen.config.mjs\",\n \"api-codegen.config.ts\",\n \"api-codegen.config.json\",\n \".api-codegenrc\",\n \".api-codegenrc.json\",\n \".api-codegenrc.js\",\n ],\n});\n\nexport async function loadConfig(\n configPath?: string,\n): Promise<ResolvedConfig | null> {\n try {\n const result = configPath\n ? await explorer.load(configPath)\n : await explorer.search();\n\n if (!result || !result.config) {\n return null;\n }\n\n const userConfig = result.config as UserConfig;\n const rootDir = path.dirname(result.filepath);\n\n // Resolve paths\n const endpointsPath = path.resolve(rootDir, userConfig.endpoints);\n const outputDir = path.resolve(rootDir, userConfig.output);\n\n // Set defaults based on provider\n const generateHooks = userConfig.generateHooks ?? true;\n const generateServerActions =\n userConfig.generateServerActions ?? userConfig.provider === \"nextjs\";\n const generateServerQueries =\n userConfig.generateServerQueries ?? userConfig.provider === \"nextjs\";\n const generateClient = userConfig.generateClient ?? true;\n const generatePrefetch = userConfig.generatePrefetch ?? true;\n\n return {\n ...userConfig,\n rootDir,\n endpointsPath,\n outputDir,\n generateHooks,\n generateServerActions,\n generateServerQueries,\n generateClient,\n generatePrefetch,\n };\n } catch (error) {\n throw new Error(\n `Failed to load config: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\n/**\n * Validate user config\n */\nexport function validateConfig(config: UserConfig): void {\n if (!config.endpoints) {\n throw new Error('Config error: \"endpoints\" path is required');\n }\n\n if (!config.provider) {\n throw new Error(\n 'Config error: \"provider\" must be specified (vite or nextjs)',\n );\n }\n\n if (![\"vite\", \"nextjs\"].includes(config.provider)) {\n throw new Error(\n 'Config error: \"provider\" must be either \"vite\" or \"nextjs\"',\n );\n }\n\n if (!config.output) {\n throw new Error('Config error: \"output\" directory is required');\n }\n}\n"]}
@@ -1,43 +0,0 @@
1
- import { z } from 'zod';
2
-
3
- type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
4
- interface APIEndpoint {
5
- path: string;
6
- method: HTTPMethod;
7
- baseUrl?: string;
8
- params?: z.ZodType<any>;
9
- query?: z.ZodType<any>;
10
- body?: z.ZodType<any>;
11
- response: z.ZodType<any>;
12
- tags?: string[];
13
- description?: string;
14
- }
15
- interface APIConfig {
16
- baseUrl?: string;
17
- endpoints: Record<string, APIEndpoint>;
18
- }
19
- type EndpointConfig<TPath extends string = string, TMethod extends HTTPMethod = HTTPMethod, TParams = undefined, TQuery = undefined, TBody = undefined, TResponse = any> = {
20
- path: TPath;
21
- method: TMethod;
22
- baseUrl?: string;
23
- params?: z.ZodType<TParams>;
24
- query?: z.ZodType<TQuery>;
25
- body?: z.ZodType<TBody>;
26
- response: z.ZodType<TResponse>;
27
- tags?: string[];
28
- description?: string;
29
- };
30
- /**
31
- * Helper function to define API configuration with type safety
32
- */
33
- declare function defineConfig<T extends APIConfig>(config: T): T;
34
- /**
35
- * Helper function to define a single endpoint with type inference
36
- */
37
- declare function defineEndpoint<TPath extends string, TMethod extends HTTPMethod, TParams = undefined, TQuery = undefined, TBody = undefined, TResponse = any>(config: EndpointConfig<TPath, TMethod, TParams, TQuery, TBody, TResponse>): EndpointConfig<TPath, TMethod, TParams, TQuery, TBody, TResponse>;
38
- /**
39
- * Helper to define multiple endpoints
40
- */
41
- declare function defineEndpoints<T extends Record<string, APIEndpoint>>(endpoints: T): T;
42
-
43
- export { type APIConfig, type APIEndpoint, type EndpointConfig, type HTTPMethod, defineConfig, defineEndpoint, defineEndpoints };
@@ -1,14 +0,0 @@
1
- // src/config/schema.ts
2
- function defineConfig(config) {
3
- return config;
4
- }
5
- function defineEndpoint(config) {
6
- return config;
7
- }
8
- function defineEndpoints(endpoints) {
9
- return endpoints;
10
- }
11
-
12
- export { defineConfig, defineEndpoint, defineEndpoints };
13
- //# sourceMappingURL=schema.js.map
14
- //# sourceMappingURL=schema.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/config/schema.ts"],"names":[],"mappings":";AA2CO,SAAS,aAAkC,MAAA,EAAc;AAC9D,EAAA,OAAO,MAAA;AACT;AAKO,SAAS,eAQd,MAAA,EACmE;AACnE,EAAA,OAAO,MAAA;AACT;AAKO,SAAS,gBAEd,SAAA,EAAiB;AACjB,EAAA,OAAO,SAAA;AACT","file":"schema.js","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}\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};\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<\n T extends Record<string, APIEndpoint>,\n>(endpoints: T): T {\n return endpoints;\n}\n"]}