jszy-swagger-doc-generator 1.4.0 → 1.5.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 +327 -113
- package/dist/cli.js +34 -1
- package/dist/cli.js.map +1 -1
- package/dist/generators/swagger.generator.d.ts +90 -0
- package/dist/generators/swagger.generator.js +626 -0
- package/dist/generators/swagger.generator.js.map +1 -0
- package/dist/helpers/handlebars.helpers.d.ts +4 -0
- package/dist/helpers/handlebars.helpers.js +92 -0
- package/dist/helpers/handlebars.helpers.js.map +1 -0
- package/dist/helpers/string.helpers.d.ts +8 -0
- package/dist/helpers/string.helpers.js +25 -0
- package/dist/helpers/string.helpers.js.map +1 -0
- package/dist/helpers/template.helpers.d.ts +4 -0
- package/dist/helpers/template.helpers.js +105 -0
- package/dist/helpers/template.helpers.js.map +1 -0
- package/dist/helpers/type.helpers.d.ts +18 -0
- package/dist/helpers/type.helpers.js +229 -0
- package/dist/helpers/type.helpers.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +432 -159
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +97 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +1 -1
- package/src/cli.ts +35 -1
- package/src/generators/swagger.generator.ts +664 -0
- package/src/helpers/template.helpers.ts +72 -0
- package/src/helpers/type.helpers.ts +232 -0
- package/src/index.ts +465 -162
- package/src/types.ts +98 -0
- package/templates/hooks/individual-hook.hbs +55 -0
- package/templates/hooks/react-hook.hbs +14 -0
- package/templates/types/type-definition.hbs +5 -0
- package/test-openapi-swagger.json +454 -0
package/README.md
CHANGED
|
@@ -1,180 +1,394 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Swagger API SDK Generator
|
|
2
2
|
|
|
3
|
-
A tool to generate
|
|
4
|
-
|
|
5
|
-
Available command aliases: `api-sdk`, `jszy-swagger-doc-generator`, `swagger-doc-generator`
|
|
3
|
+
A powerful tool to generate TypeScript React SDK from OpenAPI/Swagger specifications using Handlebars templates. This tool creates organized hooks and types organized by API tags to provide a structured way to consume APIs in frontend applications.
|
|
6
4
|
|
|
7
5
|
## Features
|
|
8
6
|
|
|
9
|
-
-
|
|
10
|
-
- Generates
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
- ✨ **Handlebars-powered Templates**: Fully customizable using Handlebars template engine
|
|
8
|
+
- 🏷️ **Tag-based Organization**: Generates separate files organized by OpenAPI tags
|
|
9
|
+
- 🔗 **React Query Integration**: Creates ready-to-use React Query hooks with axios
|
|
10
|
+
- 📝 **TypeSafe**: Generates TypeScript types from OpenAPI schemas
|
|
11
|
+
- 🛠️ **Modular**: Clean separation between hooks and types per tag
|
|
12
|
+
- 📦 **Tree-shakable**: Import only the hooks and types you need
|
|
13
|
+
- 🎨 **Customizable**: Use your own Handlebars templates
|
|
14
|
+
- 🚀 **Modern**: Built for React 18+ ecosystem
|
|
15
|
+
|
|
16
|
+
## Prerequisites
|
|
17
|
+
|
|
18
|
+
This tool is designed to work with projects that use:
|
|
19
|
+
|
|
20
|
+
- **React** (v16.8+) - For React hooks functionality
|
|
21
|
+
- **React Query** (React Query v3 or TanStack Query v4+) - For data fetching and caching
|
|
22
|
+
- **Axios** - For HTTP requests
|
|
23
|
+
- **TypeScript** - For type safety
|
|
24
|
+
- **OpenAPI/Swagger** - Specification format for your API documentation
|
|
19
25
|
|
|
20
26
|
## Installation
|
|
21
27
|
|
|
22
|
-
|
|
28
|
+
As a development dependency:
|
|
23
29
|
|
|
24
30
|
```bash
|
|
25
|
-
npm install -
|
|
31
|
+
npm install --save-dev jszy-swagger-doc-generator
|
|
32
|
+
# or
|
|
33
|
+
yarn add -D jszy-swagger-doc-generator
|
|
34
|
+
# or
|
|
35
|
+
pnpm add -D jszy-swagger-doc-generator
|
|
26
36
|
```
|
|
27
37
|
|
|
28
|
-
Or
|
|
38
|
+
Or use without installing:
|
|
29
39
|
|
|
30
40
|
```bash
|
|
31
|
-
npx jszy-swagger-doc-generator
|
|
41
|
+
npx jszy-swagger-doc-generator [options]
|
|
32
42
|
```
|
|
33
43
|
|
|
34
|
-
|
|
44
|
+
You can also define script commands in your `package.json`:
|
|
35
45
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
api-sdk --input ./swagger.json
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"scripts": {
|
|
49
|
+
"generate:auto": "api-sdk --url https://api.example.com/swagger.json",
|
|
50
|
+
"generate:sdk": "api-sdk --url https://api.example.com/swagger.json --generate-hooks --generate-types --hooks-output ./src/api --types-output ./src/types",
|
|
51
|
+
"generate:sdk:local": "api-sdk --input ./swagger.json --generate-hooks --generate-types --hooks-output ./src/api --types-output ./src/types",
|
|
52
|
+
}
|
|
53
|
+
}
|
|
42
54
|
```
|
|
43
|
-
|
|
55
|
+
|
|
56
|
+
Then run:
|
|
44
57
|
```bash
|
|
45
|
-
|
|
58
|
+
npm run generate:sdk
|
|
59
|
+
# or
|
|
60
|
+
npm run generate:sdk:local
|
|
61
|
+
# or
|
|
62
|
+
npm run generate:auto
|
|
46
63
|
```
|
|
47
|
-
3. Check the generated documentation in `./generated/docs/api-documentation.md`
|
|
48
64
|
|
|
49
|
-
|
|
65
|
+
## Quick Start
|
|
66
|
+
|
|
67
|
+
### 1. Generate SDK from API Documentation
|
|
68
|
+
|
|
69
|
+
The simplest way is to use the auto-generate command that automatically creates all content from your API specification:
|
|
50
70
|
|
|
51
|
-
1. If your API is running and exposes Swagger JSON at `http://localhost:3000/api-docs-json`:
|
|
52
71
|
```bash
|
|
53
|
-
|
|
72
|
+
# Auto-generate everything from a local OpenAPI JSON file
|
|
73
|
+
npx jszy-swagger-doc-generator --input path/to/swagger.json
|
|
74
|
+
|
|
75
|
+
# Or auto-generate everything from a URL
|
|
76
|
+
npx jszy-swagger-doc-generator --url https://api.example.com/swagger.json
|
|
54
77
|
```
|
|
55
|
-
2. All content will be generated in the `./generated` directory by default
|
|
56
78
|
|
|
57
|
-
|
|
79
|
+
This will automatically:
|
|
80
|
+
- Generate TypeScript types for all schemas
|
|
81
|
+
- Generate React Query hooks for all API endpoints
|
|
82
|
+
- Organize everything by API tags in separate folders
|
|
83
|
+
- Place generated content in `./generated/hooks` and `./generated/types`
|
|
84
|
+
|
|
85
|
+
### 2. Advanced Generation
|
|
86
|
+
|
|
87
|
+
If you want more control, you can specify individual generation options:
|
|
58
88
|
|
|
59
|
-
1. To generate TypeScript types and React hooks from your Swagger file:
|
|
60
89
|
```bash
|
|
61
|
-
|
|
90
|
+
# Generate only hooks from a local OpenAPI JSON file
|
|
91
|
+
npx jszy-swagger-doc-generator --input path/to/swagger.json --generate-hooks --hooks-output ./src/api/generated
|
|
92
|
+
|
|
93
|
+
# Generate only types from a local OpenAPI JSON file
|
|
94
|
+
npx jszy-swagger-doc-generator --input path/to/swagger.json --generate-types --types-output ./src/types/generated
|
|
95
|
+
|
|
96
|
+
# Generate both hooks and types from a URL
|
|
97
|
+
npx jszy-swagger-doc-generator --url https://api.example.com/swagger.json --generate-hooks --generate-types --hooks-output ./src/api/generated --types-output ./src/types/generated
|
|
62
98
|
```
|
|
63
|
-
2. Generated files will be in:
|
|
64
|
-
- TypeScript types: `./generated/types/`
|
|
65
|
-
- React hooks: `./generated/hooks/`
|
|
66
99
|
|
|
67
|
-
###
|
|
100
|
+
### 2. Generated Structure
|
|
101
|
+
|
|
102
|
+
The tool generates a clean structure organized by tags:
|
|
68
103
|
|
|
69
|
-
1. Generate all documentation, types, and hooks from a live API:
|
|
70
|
-
```bash
|
|
71
|
-
api-sdk --url http://localhost:3000/api-docs-json --generate-types --generate-hooks
|
|
72
104
|
```
|
|
73
|
-
|
|
105
|
+
src/api/generated/
|
|
106
|
+
├── user/
|
|
107
|
+
│ ├── user.hooks.ts
|
|
108
|
+
│ └── user.types.ts
|
|
109
|
+
├── product/
|
|
110
|
+
│ ├── product.hooks.ts
|
|
111
|
+
│ └── product.types.ts
|
|
112
|
+
└── order/
|
|
113
|
+
├── order.hooks.ts
|
|
114
|
+
└── order.types.ts
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 3. Using Generated Hooks
|
|
74
118
|
|
|
75
|
-
|
|
119
|
+
Import and use the generated hooks in your React components:
|
|
76
120
|
|
|
77
|
-
|
|
78
|
-
|
|
121
|
+
```react
|
|
122
|
+
import { useGetUsers, useCreateUser } from '@/api/generated/user/user.hooks';
|
|
123
|
+
import { User, UserCreate } from '@/api/generated/user/user.types';
|
|
79
124
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
- `--types-output`: Output directory for TypeScript types (default: ./generated/types)
|
|
86
|
-
- `--hooks-output`: Output directory for React hooks (default: ./generated/hooks)
|
|
87
|
-
- `--help`: Show help information
|
|
125
|
+
const UserList: React.FC = () => {
|
|
126
|
+
const { data: users, isLoading, error } = useGetUsers({
|
|
127
|
+
page: 1,
|
|
128
|
+
limit: 10
|
|
129
|
+
});
|
|
88
130
|
|
|
89
|
-
|
|
131
|
+
const { mutate: createUser, isLoading: isCreating } = useCreateUser();
|
|
90
132
|
|
|
91
|
-
|
|
133
|
+
if (isLoading) return <div>Loading...</div>;
|
|
134
|
+
if (error) return <div>Error: {(error as Error).message}</div>;
|
|
92
135
|
|
|
136
|
+
return (
|
|
137
|
+
<div>
|
|
138
|
+
{users?.map(user => (
|
|
139
|
+
<div key={user.id}>{user.name}</div>
|
|
140
|
+
))}
|
|
141
|
+
|
|
142
|
+
<button
|
|
143
|
+
onClick={() => createUser({ name: 'New User', email: 'new@example.com' })}
|
|
144
|
+
disabled={isCreating}
|
|
145
|
+
>
|
|
146
|
+
{isCreating ? 'Creating...' : 'Create User'}
|
|
147
|
+
</button>
|
|
148
|
+
</div>
|
|
149
|
+
);
|
|
150
|
+
};
|
|
93
151
|
```
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
152
|
+
|
|
153
|
+
## Configuration Options
|
|
154
|
+
|
|
155
|
+
### CLI Options
|
|
156
|
+
|
|
157
|
+
| Option | Description | Default |
|
|
158
|
+
|--------|-------------|---------|
|
|
159
|
+
| `--url, -u <url>` | URL to the OpenAPI JSON file | - |
|
|
160
|
+
| `--input, -i <path>` | Path to the local OpenAPI JSON file | - |
|
|
161
|
+
| `--generate-hooks` | Generate React hooks | `false` |
|
|
162
|
+
| `--generate-types` | Generate TypeScript types | `false` |
|
|
163
|
+
| `--handlebars-templates` | Use Handlebars templates for generation | `false` |
|
|
164
|
+
| `--hooks-output` | Output directory for hooks | `./generated/hooks` |
|
|
165
|
+
| `--types-output` | Output directory for types | `./generated/types` |
|
|
166
|
+
| `--help` | Show help information | - |
|
|
167
|
+
|
|
168
|
+
### Supported OpenAPI Features
|
|
169
|
+
|
|
170
|
+
The generator supports:
|
|
171
|
+
- All OpenAPI 3.0/3.1 features
|
|
172
|
+
- `allOf`, `anyOf`, `oneOf` compositions
|
|
173
|
+
- Complex nested objects
|
|
174
|
+
- Enums and unions
|
|
175
|
+
- Array types
|
|
176
|
+
- Parameter and response schemas
|
|
177
|
+
- Tag-based organization
|
|
178
|
+
- Operation IDs for hook names
|
|
179
|
+
|
|
180
|
+
## Template Customization
|
|
181
|
+
|
|
182
|
+
You can customize the generated code by modifying the Handlebars templates located in:
|
|
183
|
+
- `templates/hooks/individual-hook.hbs` - Individual hook templates
|
|
184
|
+
- `templates/hooks/react-hook.hbs` - Main hooks file template
|
|
185
|
+
- `templates/types/type-definition.hbs` - Type definitions template
|
|
186
|
+
|
|
187
|
+
Example hook template:
|
|
188
|
+
```handlebars
|
|
189
|
+
{{#if isGetRequest}}
|
|
190
|
+
{{#if hasParams}}
|
|
191
|
+
export const {{hookName}} = (params: {{paramInterfaceName}}) => {
|
|
192
|
+
return useQuery({
|
|
193
|
+
queryKey: ['{{operationId}}', params],
|
|
194
|
+
queryFn: async () => {
|
|
195
|
+
const response = await axios.get<{{responseType}}>(`{{{formattedPath}}}`, { params });
|
|
196
|
+
return response.data;
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
{{else}}
|
|
201
|
+
export const {{hookName}} = () => {
|
|
202
|
+
return useQuery({
|
|
203
|
+
queryKey: ['{{operationId}}'],
|
|
204
|
+
queryFn: async () => {
|
|
205
|
+
const response = await axios.get<{{responseType}}>(`{{{formattedPath}}}`);
|
|
206
|
+
return response.data;
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
};
|
|
210
|
+
{{/if}}
|
|
211
|
+
{{else}}
|
|
212
|
+
{{#if hasPathParams}}
|
|
213
|
+
export const {{hookName}} = (params: {{paramInterfaceName}}) => {
|
|
214
|
+
const queryClient = useQueryClient();
|
|
215
|
+
|
|
216
|
+
return useMutation({
|
|
217
|
+
mutationFn: async (data: {{requestBodyType}}) => {
|
|
218
|
+
const response = await axios.{{method}}<{{responseType}}>(`{{{formattedPath}}}`, data);
|
|
219
|
+
return response.data;
|
|
220
|
+
},
|
|
221
|
+
onSuccess: () => {
|
|
222
|
+
// Invalidate and refetch related queries
|
|
223
|
+
queryClient.invalidateQueries({ queryKey: ['{{operationId}}'] });
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
};
|
|
227
|
+
{{else}}
|
|
228
|
+
export const {{hookName}} = (data: {{requestBodyType}}) => {
|
|
229
|
+
const queryClient = useQueryClient();
|
|
230
|
+
|
|
231
|
+
return useMutation({
|
|
232
|
+
mutationFn: async (data: {{requestBodyType}}) => {
|
|
233
|
+
const response = await axios.{{method}}<{{responseType}}>(`{{{formattedPath}}}`, data);
|
|
234
|
+
return response.data;
|
|
235
|
+
},
|
|
236
|
+
onSuccess: () => {
|
|
237
|
+
// Invalidate and refetch related queries
|
|
238
|
+
queryClient.invalidateQueries({ queryKey: ['{{operationId}}'] });
|
|
239
|
+
},
|
|
240
|
+
});
|
|
241
|
+
};
|
|
242
|
+
{{/if}}
|
|
243
|
+
{{/if}}
|
|
103
244
|
```
|
|
104
245
|
|
|
105
|
-
##
|
|
246
|
+
## Technology Stack Integration Guide
|
|
247
|
+
|
|
248
|
+
### React + React Query + Axios Setup
|
|
106
249
|
|
|
107
|
-
|
|
250
|
+
Make sure your project has these dependencies:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
npm install react-query axios
|
|
254
|
+
# For TanStack Query V4
|
|
255
|
+
npm install @tanstack/react-query
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Configure React Query in your app:
|
|
108
259
|
|
|
109
260
|
```typescript
|
|
110
|
-
|
|
261
|
+
// App.tsx
|
|
262
|
+
import { QueryClient, QueryClientProvider } from 'react-query'; // or @tanstack/react-query
|
|
111
263
|
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
264
|
+
const queryClient = new QueryClient();
|
|
265
|
+
|
|
266
|
+
function App() {
|
|
267
|
+
return (
|
|
268
|
+
<QueryClientProvider client={queryClient}>
|
|
269
|
+
{/* Your app components */}
|
|
270
|
+
</QueryClientProvider>
|
|
271
|
+
);
|
|
272
|
+
}
|
|
117
273
|
```
|
|
118
274
|
|
|
119
|
-
|
|
275
|
+
### Working with Generated Types
|
|
120
276
|
|
|
121
|
-
The generated
|
|
277
|
+
The generated types are fully typed with JSDoc comments and support nested objects:
|
|
122
278
|
|
|
123
279
|
```typescript
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
280
|
+
// user.types.ts
|
|
281
|
+
export interface User {
|
|
282
|
+
/** 用户ID */
|
|
283
|
+
id: number;
|
|
284
|
+
/** 用户名 */
|
|
285
|
+
name: string;
|
|
286
|
+
/** 邮箱地址 */
|
|
287
|
+
email?: string | null;
|
|
288
|
+
profile?: null | UserProfile;
|
|
289
|
+
tags?: string[];
|
|
290
|
+
status?: UserStatus;
|
|
135
291
|
}
|
|
292
|
+
|
|
293
|
+
export type UserStatus = 'active' | 'inactive' | 'suspended';
|
|
136
294
|
```
|
|
137
295
|
|
|
138
|
-
|
|
296
|
+
### Advanced Usage
|
|
139
297
|
|
|
140
|
-
You can also
|
|
298
|
+
You can also programmatically generate the SDK using the API:
|
|
141
299
|
|
|
142
|
-
```
|
|
143
|
-
|
|
300
|
+
```typescript
|
|
301
|
+
import { SwaggerDocGenerator } from 'jszy-swagger-doc-generator';
|
|
144
302
|
|
|
145
|
-
|
|
146
|
-
const generator = new SwaggerDocGenerator();
|
|
303
|
+
const generator = new SwaggerDocGenerator();
|
|
147
304
|
|
|
148
|
-
|
|
149
|
-
|
|
305
|
+
// From URL
|
|
306
|
+
const swaggerDoc = await generator.fetchSwaggerJSON('https://api.example.com/swagger.json');
|
|
150
307
|
|
|
151
|
-
|
|
152
|
-
|
|
308
|
+
// Or from local file
|
|
309
|
+
const swaggerDoc = generator.loadSwaggerFromFile('./swagger.json');
|
|
153
310
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
311
|
+
// Generate with Handlebars templates
|
|
312
|
+
const hooksByTag = generator.generateHandlebarsResources(swaggerDoc, {
|
|
313
|
+
hooks: './templates/hooks/react-hook.hbs',
|
|
314
|
+
types: './templates/types/type-definition.hbs'
|
|
315
|
+
});
|
|
157
316
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
317
|
+
// Save to files
|
|
318
|
+
generator.saveHooksByTag(hooksByTag, './src/api/generated');
|
|
319
|
+
```
|
|
161
320
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
321
|
+
## Best Practices
|
|
322
|
+
|
|
323
|
+
### 1. Organize by API Tags
|
|
324
|
+
Use meaningful tags in your OpenAPI specification to organize endpoints logically:
|
|
325
|
+
```yaml
|
|
326
|
+
paths:
|
|
327
|
+
/users/{id}:
|
|
328
|
+
get:
|
|
329
|
+
tags:
|
|
330
|
+
- User
|
|
331
|
+
# ...
|
|
332
|
+
/products/{id}:
|
|
333
|
+
get:
|
|
334
|
+
tags:
|
|
335
|
+
- Product
|
|
336
|
+
# ...
|
|
337
|
+
```
|
|
166
338
|
|
|
167
|
-
|
|
339
|
+
### 2. Leverage React Query Caching
|
|
340
|
+
The generated hooks use React Query which provides automatic caching, deduplication, and cache invalidation:
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
// Two components using the same hook will share cached data
|
|
344
|
+
const UsersList = () => {
|
|
345
|
+
const { data } = useGetUsers(); // Cache key: ['getUsers']
|
|
346
|
+
return <>{/* ... */}</>;
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
const Stats = () => {
|
|
350
|
+
const { data } = useGetUsers(); // Same cache key: ['getUsers'] - shared data!
|
|
351
|
+
return <>{/* ... */}</>;
|
|
352
|
+
};
|
|
168
353
|
```
|
|
169
354
|
|
|
170
|
-
|
|
355
|
+
### 3. Use TypeScript Strictly
|
|
356
|
+
Leverage the generated types for complete type safety:
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
// Fully typed parameters and return values
|
|
360
|
+
const { mutate } = useUpdateUser();
|
|
361
|
+
mutate({
|
|
362
|
+
id: 123,
|
|
363
|
+
name: 'John',
|
|
364
|
+
email: 'john@example.com'
|
|
365
|
+
} as UserUpdate); // Ensures correct type
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
## Troubleshooting
|
|
369
|
+
|
|
370
|
+
### Common Issues
|
|
371
|
+
|
|
372
|
+
1. **Template not found errors**: Make sure template files exist at the expected paths
|
|
373
|
+
2. **Missing types**: Ensure your OpenAPI spec defines all referenced schemas
|
|
374
|
+
3. **Parameter mapping**: Check path parameter names match between URL and parameters
|
|
375
|
+
|
|
376
|
+
### Error Handling
|
|
377
|
+
|
|
378
|
+
The generated hooks follow React Query patterns for error handling:
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
const { data, isLoading, error, isError } = useGetUsers();
|
|
382
|
+
|
|
383
|
+
if (isLoading) return <Spinner />;
|
|
384
|
+
if (isError) return <ErrorMessage error={error} />;
|
|
385
|
+
|
|
386
|
+
return <UserList users={data} />;
|
|
387
|
+
```
|
|
171
388
|
|
|
172
|
-
|
|
389
|
+
## Contributing
|
|
173
390
|
|
|
174
|
-
|
|
175
|
-
2. Run `pnpm install` to install dependencies
|
|
176
|
-
3. Run `pnpm run build` to compile TypeScript
|
|
177
|
-
4. Run `pnpm run test` to run tests
|
|
391
|
+
Feel free to submit issues or pull requests on the GitHub repository.
|
|
178
392
|
|
|
179
393
|
## License
|
|
180
394
|
|
package/dist/cli.js
CHANGED
|
@@ -78,6 +78,21 @@ const argv = (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
|
|
|
78
78
|
describe: 'Output directory for React hooks (default: ./generated/hooks)',
|
|
79
79
|
type: 'string',
|
|
80
80
|
default: './generated/hooks'
|
|
81
|
+
})
|
|
82
|
+
.option('handlebars-templates', {
|
|
83
|
+
describe: 'Use Handlebars templates for generation',
|
|
84
|
+
type: 'boolean',
|
|
85
|
+
default: false
|
|
86
|
+
})
|
|
87
|
+
.option('hooks-template', {
|
|
88
|
+
describe: 'Path to custom hooks template (default: templates/hooks/react-hook.hbs)',
|
|
89
|
+
type: 'string',
|
|
90
|
+
default: './templates/hooks/react-hook.hbs'
|
|
91
|
+
})
|
|
92
|
+
.option('types-template', {
|
|
93
|
+
describe: 'Path to custom types template (default: templates/types/type-definition.hbs)',
|
|
94
|
+
type: 'string',
|
|
95
|
+
default: './templates/types/type-definition.hbs'
|
|
81
96
|
})
|
|
82
97
|
.check((argv) => {
|
|
83
98
|
if (!argv.url && !argv.input) {
|
|
@@ -86,6 +101,14 @@ const argv = (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
|
|
|
86
101
|
if (argv.url && argv.input) {
|
|
87
102
|
throw new Error('Only one of --url or --input can be provided');
|
|
88
103
|
}
|
|
104
|
+
// Only set defaults if user hasn't explicitly specified either flag
|
|
105
|
+
// We'll use the fact that if user explicitly sets a flag, yargs will have it as not the default
|
|
106
|
+
// By default, both --generate-types and --generate-hooks are false
|
|
107
|
+
if (!argv.generateHooks && !argv.generateTypes) {
|
|
108
|
+
// Both are false (their default), so we'll generate both as a convenience
|
|
109
|
+
argv.generateHooks = true;
|
|
110
|
+
argv.generateTypes = true;
|
|
111
|
+
}
|
|
89
112
|
return true;
|
|
90
113
|
})
|
|
91
114
|
.help()
|
|
@@ -135,7 +158,17 @@ async function run() {
|
|
|
135
158
|
fs.mkdirSync(generatedDir, { recursive: true });
|
|
136
159
|
}
|
|
137
160
|
console.log('Generating React hooks...');
|
|
138
|
-
|
|
161
|
+
let hooksByTag;
|
|
162
|
+
if (argv.handlebarsTemplates) {
|
|
163
|
+
console.log('Using Handlebars templates for generation...');
|
|
164
|
+
hooksByTag = generator.generateHandlebarsResources(swaggerDoc, {
|
|
165
|
+
hooks: argv.hooksTemplate,
|
|
166
|
+
types: argv.typesTemplate
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
hooksByTag = generator.generateReactHooks(swaggerDoc);
|
|
171
|
+
}
|
|
139
172
|
generator.saveHooksByTag(hooksByTag, argv.hooksOutput);
|
|
140
173
|
console.log(`React hooks and types generated successfully in: ${argv.hooksOutput}/`);
|
|
141
174
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,mCAA0D;AAC1D,kDAA0B;AAC1B,2CAAwC;AACxC,uCAAyB;AAGzB,MAAM,IAAI,GAAG,IAAA,eAAK,EAAC,IAAA,iBAAO,EAAC,OAAO,CAAC,IAAI,CAAC,CAAC;KACtC,KAAK,CAAC,qBAAqB,CAAC;KAC5B,MAAM,CAAC,KAAK,EAAE;IACb,KAAK,EAAE,GAAG;IACV,QAAQ,EAAE,8BAA8B;IACxC,IAAI,EAAE,QAAQ;CACf,CAAC;KACD,MAAM,CAAC,OAAO,EAAE;IACf,KAAK,EAAE,GAAG;IACV,QAAQ,EAAE,qCAAqC;IAC/C,IAAI,EAAE,QAAQ;CACf,CAAC;KACD,MAAM,CAAC,QAAQ,EAAE;IAChB,KAAK,EAAE,GAAG;IACV,QAAQ,EAAE,8FAA8F;IACxG,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,uCAAuC;CACjD,CAAC;KACD,MAAM,CAAC,gBAAgB,EAAE;IACxB,QAAQ,EAAE,sCAAsC;IAChD,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;CACf,CAAC;KACD,MAAM,CAAC,gBAAgB,EAAE;IACxB,QAAQ,EAAE,sBAAsB;IAChC,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;CACf,CAAC;KACD,MAAM,CAAC,cAAc,EAAE;IACtB,QAAQ,EAAE,oEAAoE;IAC9E,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,mBAAmB;CAC7B,CAAC;KACD,MAAM,CAAC,cAAc,EAAE;IACtB,QAAQ,EAAE,+DAA+D;IACzE,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,mBAAmB;CAC7B,CAAC;KACD,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE;IACd,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,mCAA0D;AAC1D,kDAA0B;AAC1B,2CAAwC;AACxC,uCAAyB;AAGzB,MAAM,IAAI,GAAG,IAAA,eAAK,EAAC,IAAA,iBAAO,EAAC,OAAO,CAAC,IAAI,CAAC,CAAC;KACtC,KAAK,CAAC,qBAAqB,CAAC;KAC5B,MAAM,CAAC,KAAK,EAAE;IACb,KAAK,EAAE,GAAG;IACV,QAAQ,EAAE,8BAA8B;IACxC,IAAI,EAAE,QAAQ;CACf,CAAC;KACD,MAAM,CAAC,OAAO,EAAE;IACf,KAAK,EAAE,GAAG;IACV,QAAQ,EAAE,qCAAqC;IAC/C,IAAI,EAAE,QAAQ;CACf,CAAC;KACD,MAAM,CAAC,QAAQ,EAAE;IAChB,KAAK,EAAE,GAAG;IACV,QAAQ,EAAE,8FAA8F;IACxG,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,uCAAuC;CACjD,CAAC;KACD,MAAM,CAAC,gBAAgB,EAAE;IACxB,QAAQ,EAAE,sCAAsC;IAChD,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;CACf,CAAC;KACD,MAAM,CAAC,gBAAgB,EAAE;IACxB,QAAQ,EAAE,sBAAsB;IAChC,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;CACf,CAAC;KACD,MAAM,CAAC,cAAc,EAAE;IACtB,QAAQ,EAAE,oEAAoE;IAC9E,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,mBAAmB;CAC7B,CAAC;KACD,MAAM,CAAC,cAAc,EAAE;IACtB,QAAQ,EAAE,+DAA+D;IACzE,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,mBAAmB;CAC7B,CAAC;KACD,MAAM,CAAC,sBAAsB,EAAE;IAC9B,QAAQ,EAAE,yCAAyC;IACnD,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;CACf,CAAC;KACD,MAAM,CAAC,gBAAgB,EAAE;IACxB,QAAQ,EAAE,yEAAyE;IACnF,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,kCAAkC;CAC5C,CAAC;KACD,MAAM,CAAC,gBAAgB,EAAE;IACxB,QAAQ,EAAE,8EAA8E;IACxF,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,uCAAuC;CACjD,CAAC;KACD,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE;IACd,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,oEAAoE;IACpE,gGAAgG;IAChG,mEAAmE;IACnE,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAC/C,0EAA0E;QAC1E,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;KACD,IAAI,EAAE;KACN,SAAS,EAAE,CAAC;AAEf,KAAK,UAAU,GAAG;IAChB,IAAI,CAAC;QACH,6DAA6D;QAC7D,MAAM,YAAY,GAAG,aAAa,CAAC;QACnC,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAChC,EAAE,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1D,OAAO,CAAC,GAAG,CAAC,gCAAgC,YAAY,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,2BAAmB,EAAE,CAAC;QAC5C,IAAI,UAAkC,CAAC;QAEvC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,+BAA+B,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACvD,UAAU,GAAG,MAAM,SAAS,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1D,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,8BAA8B,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACxD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAC9D,CAAC;YACD,UAAU,GAAG,SAAS,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzD,CAAC;QAED,sFAAsF;QACtF,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QAED,qCAAqC;QACrC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,qDAAqD;YACrD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBACjC,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;YACzD,MAAM,KAAK,GAAG,SAAS,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;YAC5D,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACrD,GAAG,IAAI,CAAC,WAAW,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC;YACrG,SAAS,CAAC,eAAe,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,+CAA+C,eAAe,EAAE,CAAC,CAAC;QAChF,CAAC;QAED,qCAAqC;QACrC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,qDAAqD;YACrD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBACjC,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YACzC,IAAI,UAAU,CAAC;YACf,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC7B,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;gBAC5D,UAAU,GAAG,SAAS,CAAC,2BAA2B,CAAC,UAAU,EAAE;oBAC7D,KAAK,EAAE,IAAI,CAAC,aAAa;oBACzB,KAAK,EAAE,IAAI,CAAC,aAAa;iBAC1B,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,UAAU,GAAG,SAAS,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;YACxD,CAAC;YACD,SAAS,CAAC,cAAc,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,oDAAoD,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACvF,CAAC;QAED,uFAAuF;QACvF,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YAC/C,qDAAqD;YACrD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBACjC,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;YAC3C,MAAM,aAAa,GAAG,SAAS,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC;YAClE,SAAS,CAAC,uBAAuB,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9D,OAAO,CAAC,GAAG,CAAC,4CAA4C,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,cAAc;AACd,GAAG,EAAE,CAAC"}
|