@cushin/api-codegen 1.1.1 → 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/dist/cli.js +100 -612
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +141 -7
- package/dist/index.js +101 -469
- package/dist/index.js.map +1 -1
- package/package.json +14 -19
- package/README.md +0 -435
- package/dist/cli.d.ts +0 -1
- package/dist/config/index.d.ts +0 -84
- package/dist/config/index.js +0 -69
- package/dist/config/index.js.map +0 -1
- package/dist/config/schema.d.ts +0 -43
- package/dist/config/schema.js +0 -14
- package/dist/config/schema.js.map +0 -1
- package/dist/runtime/client.d.ts +0 -40
- package/dist/runtime/client.js +0 -260
- package/dist/runtime/client.js.map +0 -1
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
|
package/dist/config/index.d.ts
DELETED
|
@@ -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 };
|
package/dist/config/index.js
DELETED
|
@@ -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
|
package/dist/config/index.js.map
DELETED
|
@@ -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"]}
|
package/dist/config/schema.d.ts
DELETED
|
@@ -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 };
|
package/dist/config/schema.js
DELETED
|
@@ -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"]}
|