nuxt-openapi-hyperfetch 0.1.0-alpha.1
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/.editorconfig +26 -0
- package/.prettierignore +17 -0
- package/.prettierrc.json +12 -0
- package/CONTRIBUTING.md +292 -0
- package/INSTRUCTIONS.md +327 -0
- package/LICENSE +202 -0
- package/README.md +202 -0
- package/dist/cli/config.d.ts +57 -0
- package/dist/cli/config.js +85 -0
- package/dist/cli/logger.d.ts +44 -0
- package/dist/cli/logger.js +58 -0
- package/dist/cli/logo.d.ts +6 -0
- package/dist/cli/logo.js +21 -0
- package/dist/cli/messages.d.ts +65 -0
- package/dist/cli/messages.js +86 -0
- package/dist/cli/prompts.d.ts +30 -0
- package/dist/cli/prompts.js +118 -0
- package/dist/cli/types.d.ts +43 -0
- package/dist/cli/types.js +4 -0
- package/dist/cli/utils.d.ts +26 -0
- package/dist/cli/utils.js +45 -0
- package/dist/generate.d.ts +6 -0
- package/dist/generate.js +48 -0
- package/dist/generators/nuxt-server/bff-templates.d.ts +25 -0
- package/dist/generators/nuxt-server/bff-templates.js +737 -0
- package/dist/generators/nuxt-server/generator.d.ts +7 -0
- package/dist/generators/nuxt-server/generator.js +206 -0
- package/dist/generators/nuxt-server/parser.d.ts +5 -0
- package/dist/generators/nuxt-server/parser.js +5 -0
- package/dist/generators/nuxt-server/templates.d.ts +35 -0
- package/dist/generators/nuxt-server/templates.js +412 -0
- package/dist/generators/nuxt-server/types.d.ts +5 -0
- package/dist/generators/nuxt-server/types.js +5 -0
- package/dist/generators/shared/parsers/heyapi-parser.d.ts +11 -0
- package/dist/generators/shared/parsers/heyapi-parser.js +248 -0
- package/dist/generators/shared/parsers/official-parser.d.ts +5 -0
- package/dist/generators/shared/parsers/official-parser.js +5 -0
- package/dist/generators/shared/runtime/apiHelpers.d.ts +183 -0
- package/dist/generators/shared/runtime/apiHelpers.js +268 -0
- package/dist/generators/shared/templates/api-callbacks-plugin.d.ts +178 -0
- package/dist/generators/shared/templates/api-callbacks-plugin.js +338 -0
- package/dist/generators/shared/types.d.ts +25 -0
- package/dist/generators/shared/types.js +4 -0
- package/dist/generators/tanstack-query/generator.d.ts +5 -0
- package/dist/generators/tanstack-query/generator.js +11 -0
- package/dist/generators/use-async-data/generator.d.ts +5 -0
- package/dist/generators/use-async-data/generator.js +156 -0
- package/dist/generators/use-async-data/parser.d.ts +5 -0
- package/dist/generators/use-async-data/parser.js +5 -0
- package/dist/generators/use-async-data/runtime/useApiAsyncData.d.ts +38 -0
- package/dist/generators/use-async-data/runtime/useApiAsyncData.js +122 -0
- package/dist/generators/use-async-data/runtime/useApiAsyncDataRaw.d.ts +54 -0
- package/dist/generators/use-async-data/runtime/useApiAsyncDataRaw.js +126 -0
- package/dist/generators/use-async-data/templates.d.ts +20 -0
- package/dist/generators/use-async-data/templates.js +191 -0
- package/dist/generators/use-async-data/types.d.ts +4 -0
- package/dist/generators/use-async-data/types.js +4 -0
- package/dist/generators/use-fetch/generator.d.ts +5 -0
- package/dist/generators/use-fetch/generator.js +131 -0
- package/dist/generators/use-fetch/parser.d.ts +9 -0
- package/dist/generators/use-fetch/parser.js +282 -0
- package/dist/generators/use-fetch/runtime/useApiRequest.d.ts +46 -0
- package/dist/generators/use-fetch/runtime/useApiRequest.js +158 -0
- package/dist/generators/use-fetch/templates.d.ts +16 -0
- package/dist/generators/use-fetch/templates.js +169 -0
- package/dist/generators/use-fetch/types.d.ts +5 -0
- package/dist/generators/use-fetch/types.js +5 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +213 -0
- package/docs/API-REFERENCE.md +887 -0
- package/docs/ARCHITECTURE.md +649 -0
- package/docs/DEVELOPMENT.md +918 -0
- package/docs/QUICK-START.md +323 -0
- package/docs/README.md +155 -0
- package/docs/TROUBLESHOOTING.md +881 -0
- package/eslint.config.js +72 -0
- package/package.json +65 -0
- package/src/cli/config.ts +140 -0
- package/src/cli/logger.ts +66 -0
- package/src/cli/logo.ts +25 -0
- package/src/cli/messages.ts +97 -0
- package/src/cli/prompts.ts +143 -0
- package/src/cli/types.ts +50 -0
- package/src/cli/utils.ts +49 -0
- package/src/generate.ts +57 -0
- package/src/generators/nuxt-server/bff-templates.ts +754 -0
- package/src/generators/nuxt-server/generator.ts +270 -0
- package/src/generators/nuxt-server/parser.ts +5 -0
- package/src/generators/nuxt-server/templates.ts +483 -0
- package/src/generators/nuxt-server/types.ts +5 -0
- package/src/generators/shared/parsers/heyapi-parser.ts +307 -0
- package/src/generators/shared/parsers/official-parser.ts +5 -0
- package/src/generators/shared/runtime/apiHelpers.ts +466 -0
- package/src/generators/shared/templates/api-callbacks-plugin.ts +352 -0
- package/src/generators/shared/types.ts +27 -0
- package/src/generators/tanstack-query/generator.ts +11 -0
- package/src/generators/use-async-data/generator.ts +204 -0
- package/src/generators/use-async-data/parser.ts +5 -0
- package/src/generators/use-async-data/runtime/useApiAsyncData.ts +220 -0
- package/src/generators/use-async-data/runtime/useApiAsyncDataRaw.ts +236 -0
- package/src/generators/use-async-data/templates.ts +250 -0
- package/src/generators/use-async-data/types.ts +4 -0
- package/src/generators/use-fetch/generator.ts +169 -0
- package/src/generators/use-fetch/parser.ts +341 -0
- package/src/generators/use-fetch/runtime/useApiRequest.ts +223 -0
- package/src/generators/use-fetch/templates.ts +214 -0
- package/src/generators/use-fetch/types.ts +5 -0
- package/src/index.ts +265 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,881 @@
|
|
|
1
|
+
# 🐛 Troubleshooting Guide
|
|
2
|
+
|
|
3
|
+
> **Purpose**: Solutions for common problems encountered when using or developing the generator.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Installation Issues](#installation-issues)
|
|
8
|
+
- [Generation Errors](#generation-errors)
|
|
9
|
+
- [Runtime Errors](#runtime-errors)
|
|
10
|
+
- [Type Errors](#type-errors)
|
|
11
|
+
- [Callback Issues](#callback-issues)
|
|
12
|
+
- [Performance Issues](#performance-issues)
|
|
13
|
+
- [OpenAPI Spec Issues](#openapi-spec-issues)
|
|
14
|
+
|
|
15
|
+
## Installation Issues
|
|
16
|
+
|
|
17
|
+
### Error: `Cannot find module 'commander'`
|
|
18
|
+
|
|
19
|
+
**Symptom:**
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
Error: Cannot find module 'commander'
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Cause**: Dependencies not installed
|
|
26
|
+
|
|
27
|
+
**Solution:**
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
### Error: `Permission denied` (Unix/Mac)
|
|
36
|
+
|
|
37
|
+
**Symptom:**
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
Error: EACCES: permission denied
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Cause**: Need sudo for global install
|
|
44
|
+
|
|
45
|
+
**Solution:**
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Use npx instead
|
|
49
|
+
nxh generate
|
|
50
|
+
|
|
51
|
+
# Or fix npm permissions
|
|
52
|
+
npm config set prefix ~/.npm-global
|
|
53
|
+
export PATH=~/.npm-global/bin:$PATH
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
### Build Fails with TypeScript Errors
|
|
59
|
+
|
|
60
|
+
**Symptom:**
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
error TS2307: Cannot find module 'ts-morph'
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Cause**: Missing or corrupted node_modules
|
|
67
|
+
|
|
68
|
+
**Solution:**
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Clean install
|
|
72
|
+
rm -rf node_modules package-lock.json
|
|
73
|
+
npm install
|
|
74
|
+
npm run build
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Generation Errors
|
|
78
|
+
|
|
79
|
+
### Error: `APIs directory not found`
|
|
80
|
+
|
|
81
|
+
**Symptom:**
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
Error: APIs directory not found: ./swagger/apis
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Cause**: Output directory doesn't contain OpenAPI-generated files
|
|
88
|
+
|
|
89
|
+
**Solution:**
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Generate OpenAPI files first
|
|
93
|
+
npx @openapitools/openapi-generator-cli generate \
|
|
94
|
+
-i swagger.yaml \
|
|
95
|
+
-g typescript-fetch \
|
|
96
|
+
-o ./swagger
|
|
97
|
+
|
|
98
|
+
# Then generate composables
|
|
99
|
+
node dist/index.js generate -i ./swagger -o ./output
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Note**: The tool expects **TWO** directories:
|
|
103
|
+
|
|
104
|
+
- **Input**: OpenAPI Generator output (e.g., `./swagger`)
|
|
105
|
+
- **Output**: Where composables will be written (e.g., `./output`)
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
### Error: `Found 0 methods in API file`
|
|
110
|
+
|
|
111
|
+
**Symptom:**
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
✓ Parsed PetApi
|
|
115
|
+
Found 0 methods in PetApi
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Cause**: Parser can't find `xxxRequestOpts()` methods
|
|
119
|
+
|
|
120
|
+
**Debug Steps:**
|
|
121
|
+
|
|
122
|
+
1. **Check Generated API File**:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
cat swagger/apis/PetApi.ts | grep RequestOpts
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Should see methods like:
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
async addPetRequestOpts(params: AddPetRequest): Promise<RequestOpts> { ... }
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
2. **Verify OpenAPI Generator Version**:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
npx @openapitools/openapi-generator-cli version
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Recommended: `7.14.0`
|
|
141
|
+
|
|
142
|
+
3. **Check TypeScript Syntax**:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# Install ts-morph globally
|
|
146
|
+
npm install -g ts-morph
|
|
147
|
+
|
|
148
|
+
# Parse file
|
|
149
|
+
ts-morph parse swagger/apis/PetApi.ts
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Solution**: Regenerate with correct OpenAPI Generator version:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
npx @openapitools/openapi-generator-cli generate \
|
|
156
|
+
-i swagger.yaml \
|
|
157
|
+
-g typescript-fetch \
|
|
158
|
+
-o ./swagger \
|
|
159
|
+
--additional-properties=supportsES6=true
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
### Error: `Could not parse method X`
|
|
165
|
+
|
|
166
|
+
**Symptom:**
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
Warning: Could not parse method addPet: Cannot read property 'getText' of undefined
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Cause**: Unexpected method signature or return type
|
|
173
|
+
|
|
174
|
+
**Debug**:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
// Add to parser.ts temporarily
|
|
178
|
+
try {
|
|
179
|
+
const method = extractMethodInfo(methodNode, sourceFile);
|
|
180
|
+
console.log('Extracted method:', JSON.stringify(method, null, 2));
|
|
181
|
+
} catch (error) {
|
|
182
|
+
console.error('Error:', error);
|
|
183
|
+
console.error('Method text:', methodNode.getText());
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Common Causes**:
|
|
188
|
+
|
|
189
|
+
- No parameters → `requestType` is `undefined`
|
|
190
|
+
- No return type → `responseType` extraction fails
|
|
191
|
+
- Complex generics → Type text extraction fails
|
|
192
|
+
|
|
193
|
+
**Solution**: Update parser to handle edge cases:
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
const requestType =
|
|
197
|
+
params.length > 0
|
|
198
|
+
? params[0]
|
|
199
|
+
.getType()
|
|
200
|
+
.getText()
|
|
201
|
+
.replace(/^import\(.*?\)\./, '')
|
|
202
|
+
: undefined; // Handle no params gracefully
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
### Error: `ENOENT: no such file or directory`
|
|
208
|
+
|
|
209
|
+
**Symptom:**
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
Error: ENOENT: no such file or directory, scandir './swagger/apis'
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Cause**: Wrong input directory path
|
|
216
|
+
|
|
217
|
+
**Solution**:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
# Check directory exists
|
|
221
|
+
ls ./swagger/apis
|
|
222
|
+
|
|
223
|
+
# If not, check OpenAPI output location
|
|
224
|
+
ls ./swagger
|
|
225
|
+
|
|
226
|
+
# Use absolute path
|
|
227
|
+
node dist/index.js generate -i $(pwd)/swagger -o ./output
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
### Warning: `Could not copy plugin template`
|
|
233
|
+
|
|
234
|
+
**Symptom:**
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
Warning: Could not copy plugin template: ...
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Cause**: Plugins directory doesn't exist or permissions issue
|
|
241
|
+
|
|
242
|
+
**Impact**: Non-critical - global callbacks won't work but composables will
|
|
243
|
+
|
|
244
|
+
**Solution**:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
# Create plugins directory manually
|
|
248
|
+
mkdir -p plugins
|
|
249
|
+
|
|
250
|
+
# Copy template manually
|
|
251
|
+
cp src/generators/shared/templates/api-callbacks-plugin.ts plugins/api-callbacks.ts
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Runtime Errors
|
|
255
|
+
|
|
256
|
+
### Error: `Cannot find module '../apis/PetApi'`
|
|
257
|
+
|
|
258
|
+
**Symptom** (in Nuxt project):
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
Error: Cannot find module '../apis/PetApi'
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
**Cause**: Generated imports are incorrect (wrong relative path)
|
|
265
|
+
|
|
266
|
+
**Debug**:
|
|
267
|
+
|
|
268
|
+
Check generated file:
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
// In use-fetch-add-pet.ts
|
|
272
|
+
import type { Pet, AddPetRequest } from '../apis/PetApi'; // ← Check this path
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Verify actual location:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
# From composable file location:
|
|
279
|
+
ls ../apis/PetApi.ts
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**Solution**: Fix import path calculation in templates:
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
// In templates.ts
|
|
286
|
+
let relativePath = path.relative(composablesDir, apisDir);
|
|
287
|
+
relativePath = relativePath.replace(/\\/g, '/'); // Windows compatibility
|
|
288
|
+
if (!relativePath.startsWith('.')) {
|
|
289
|
+
relativePath = './' + relativePath;
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
### Error: `useFetch is not defined` (SSR)
|
|
296
|
+
|
|
297
|
+
**Symptom**:
|
|
298
|
+
|
|
299
|
+
```
|
|
300
|
+
ReferenceError: useFetch is not defined
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Cause**: Runtime wrapper expects Nuxt environment
|
|
304
|
+
|
|
305
|
+
**Solution**: Ensure files are in Nuxt project's `composables/` directory:
|
|
306
|
+
|
|
307
|
+
```
|
|
308
|
+
my-nuxt-app/
|
|
309
|
+
composables/
|
|
310
|
+
use-fetch/
|
|
311
|
+
use-fetch-add-pet.ts # Generated composables
|
|
312
|
+
runtime/
|
|
313
|
+
useApiRequest.ts # Wrapper
|
|
314
|
+
shared/
|
|
315
|
+
runtime/
|
|
316
|
+
apiHelpers.ts # Helpers
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Nuxt auto-imports composables from `composables/` directory.
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
### Error: `$fetch is not defined`
|
|
324
|
+
|
|
325
|
+
**Symptom**:
|
|
326
|
+
|
|
327
|
+
```
|
|
328
|
+
ReferenceError: $fetch is not defined
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**Cause**: Missing Nuxt app context (useAsyncData composables)
|
|
332
|
+
|
|
333
|
+
**Solution**: Ensure using composables in proper context:
|
|
334
|
+
|
|
335
|
+
```vue
|
|
336
|
+
<!-- ✅ Good: In component setup -->
|
|
337
|
+
<script setup>
|
|
338
|
+
const { data } = useAsyncDataGetPet({ petId: 123 });
|
|
339
|
+
</script>
|
|
340
|
+
|
|
341
|
+
<!-- ❌ Bad: Outside component -->
|
|
342
|
+
<script>
|
|
343
|
+
const { data } = useAsyncDataGetPet({ petId: 123 }); // No Nuxt context
|
|
344
|
+
</script>
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
### Error: `Cannot watch reactive object`
|
|
350
|
+
|
|
351
|
+
**Symptom**:
|
|
352
|
+
|
|
353
|
+
```
|
|
354
|
+
Error: Cannot watch reactive object
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**Cause**: Watching refs incorrectly in wrapper
|
|
358
|
+
|
|
359
|
+
**Solution**: Use getter function:
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
// ✅ Good
|
|
363
|
+
watch(() => result.data.value, (data) => { ... });
|
|
364
|
+
|
|
365
|
+
// ❌ Bad
|
|
366
|
+
watch(result.data, (data) => { ... });
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## Type Errors
|
|
370
|
+
|
|
371
|
+
### Error: `Type 'Pet' is not assignable`
|
|
372
|
+
|
|
373
|
+
**Symptom**:
|
|
374
|
+
|
|
375
|
+
```
|
|
376
|
+
Type 'Pet | null' is not assignable to type 'Pet'
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
**Cause**: Nuxt composables return `Ref<T | null>`, not `Ref<T>`
|
|
380
|
+
|
|
381
|
+
**Solution**: Handle null case:
|
|
382
|
+
|
|
383
|
+
```typescript
|
|
384
|
+
const { data } = useFetchGetPet({ petId: 123 });
|
|
385
|
+
|
|
386
|
+
// ✅ Good: Check for null
|
|
387
|
+
if (data.value) {
|
|
388
|
+
console.log(data.value.name);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// ❌ Bad: Assume non-null
|
|
392
|
+
console.log(data.value.name); // Error if null
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
### Error: `Cannot find name 'ApiRequestOptions'`
|
|
398
|
+
|
|
399
|
+
**Symptom**:
|
|
400
|
+
|
|
401
|
+
```
|
|
402
|
+
Cannot find name 'ApiRequestOptions'
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
**Cause**: TypeScript can't find runtime types
|
|
406
|
+
|
|
407
|
+
**Solution**: Check import path in generated file:
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
// Generated file should have:
|
|
411
|
+
import { useApiRequest, type ApiRequestOptions } from '../runtime/useApiRequest';
|
|
412
|
+
|
|
413
|
+
// Verify file exists:
|
|
414
|
+
// ls composables/use-fetch/runtime/useApiRequest.ts
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
**If missing**: Regenerate with correct output structure.
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
### Error: `Property 'pet' does not exist on type`
|
|
422
|
+
|
|
423
|
+
**Symptom**:
|
|
424
|
+
|
|
425
|
+
```
|
|
426
|
+
Property 'pet' does not exist on type 'AddPetRequest'
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
**Cause**: Parser extracted wrong body field
|
|
430
|
+
|
|
431
|
+
**Debug**: Check generated composable:
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
// Should be:
|
|
435
|
+
body: computed(() => p.value.pet);
|
|
436
|
+
|
|
437
|
+
// Not:
|
|
438
|
+
body: params; // Wrong
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
**Solution**: Check parser's bodyField extraction:
|
|
442
|
+
|
|
443
|
+
```typescript
|
|
444
|
+
// In parser.ts
|
|
445
|
+
const bodyProperty = returnObj.getProperty('body');
|
|
446
|
+
const bodyText = bodyProperty?.getInitializer()?.getText();
|
|
447
|
+
|
|
448
|
+
console.log('Body text:', bodyText); // Should be: PetToJSON(params.pet)
|
|
449
|
+
|
|
450
|
+
// Extract field name (actual parser pattern)
|
|
451
|
+
const bodyField = bodyText?.match(/requestParameters(?:\['(\w+)'\]|\.(\w+))/)?.[1];
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
## Callback Issues
|
|
455
|
+
|
|
456
|
+
### Callback Not Firing
|
|
457
|
+
|
|
458
|
+
**Symptom**: `onSuccess` defined but never called
|
|
459
|
+
|
|
460
|
+
**Debug**:
|
|
461
|
+
|
|
462
|
+
```typescript
|
|
463
|
+
useFetchAddPet(
|
|
464
|
+
{ pet: { name: 'Fluffy' } },
|
|
465
|
+
{
|
|
466
|
+
onRequest: (ctx) => {
|
|
467
|
+
console.log('onRequest called');
|
|
468
|
+
},
|
|
469
|
+
onSuccess: (data) => {
|
|
470
|
+
console.log('onSuccess called:', data);
|
|
471
|
+
},
|
|
472
|
+
onError: (error) => {
|
|
473
|
+
console.log('onError called:', error);
|
|
474
|
+
},
|
|
475
|
+
}
|
|
476
|
+
);
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
**Common Causes**:
|
|
480
|
+
|
|
481
|
+
1. **Request Failed**: Check `onError` instead
|
|
482
|
+
2. **Global Callback Returned false**: Check global plugin
|
|
483
|
+
3. **Watch Not Triggering**: Data might be same reference
|
|
484
|
+
4. **Async Issue**: Callback execution is async
|
|
485
|
+
|
|
486
|
+
**Solution**: Check wrapper implementation:
|
|
487
|
+
|
|
488
|
+
```typescript
|
|
489
|
+
// In useApiRequest.ts
|
|
490
|
+
watch(
|
|
491
|
+
() => [result.data.value, result.error.value, result.pending.value] as const,
|
|
492
|
+
async ([data, error, pending], [prevData, prevError, prevPending]) => {
|
|
493
|
+
console.log('Watch triggered:', { data, error, pending }); // Add this
|
|
494
|
+
|
|
495
|
+
if (data && data !== prevData) {
|
|
496
|
+
console.log('Calling onSuccess'); // Add this
|
|
497
|
+
await mergedCallbacks.onSuccess?.(data);
|
|
498
|
+
}
|
|
499
|
+
},
|
|
500
|
+
{ immediate: true }
|
|
501
|
+
);
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
### Global Callbacks Not Working
|
|
507
|
+
|
|
508
|
+
**Symptom**: Plugin defined but global callbacks don't execute
|
|
509
|
+
|
|
510
|
+
**Debug**:
|
|
511
|
+
|
|
512
|
+
1. **Check Plugin Exists**:
|
|
513
|
+
|
|
514
|
+
```bash
|
|
515
|
+
ls plugins/api-callbacks.ts
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
2. **Check Plugin Registration**:
|
|
519
|
+
|
|
520
|
+
```typescript
|
|
521
|
+
// In plugins/api-callbacks.ts
|
|
522
|
+
export default defineNuxtPlugin(() => {
|
|
523
|
+
console.log('Plugin loaded'); // Add this
|
|
524
|
+
|
|
525
|
+
return {
|
|
526
|
+
provide: {
|
|
527
|
+
getGlobalApiCallbacks: () => {
|
|
528
|
+
console.log('getGlobalApiCallbacks called'); // Add this
|
|
529
|
+
return {
|
|
530
|
+
/* ... */
|
|
531
|
+
};
|
|
532
|
+
},
|
|
533
|
+
},
|
|
534
|
+
};
|
|
535
|
+
});
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
3. **Check Helper Function**:
|
|
539
|
+
|
|
540
|
+
```typescript
|
|
541
|
+
// In apiHelpers.ts
|
|
542
|
+
export function getGlobalCallbacks() {
|
|
543
|
+
try {
|
|
544
|
+
const nuxtApp = useNuxtApp();
|
|
545
|
+
console.log('nuxtApp:', nuxtApp); // Add this
|
|
546
|
+
console.log('getGlobalApiCallbacks:', nuxtApp.$getGlobalApiCallbacks); // Add this
|
|
547
|
+
|
|
548
|
+
if (nuxtApp.$getGlobalApiCallbacks) {
|
|
549
|
+
return nuxtApp.$getGlobalApiCallbacks();
|
|
550
|
+
}
|
|
551
|
+
} catch (error) {
|
|
552
|
+
console.error('Error getting global callbacks:', error);
|
|
553
|
+
}
|
|
554
|
+
return null;
|
|
555
|
+
}
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
**Common Causes**:
|
|
559
|
+
|
|
560
|
+
- Plugin file not in `plugins/` directory
|
|
561
|
+
- Plugin not registered in Nuxt config
|
|
562
|
+
- `skipGlobalCallbacks: true` in options
|
|
563
|
+
- Pattern doesn't match URL
|
|
564
|
+
|
|
565
|
+
**Solution**: Verify plugin location and content:
|
|
566
|
+
|
|
567
|
+
```bash
|
|
568
|
+
# Should be here:
|
|
569
|
+
ls plugins/api-callbacks.ts
|
|
570
|
+
|
|
571
|
+
# Check Nuxt detects it:
|
|
572
|
+
npm run dev
|
|
573
|
+
# Look for: "Registered plugins: ... api-callbacks"
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
---
|
|
577
|
+
|
|
578
|
+
### `return false` Not Cancelling Local Callback
|
|
579
|
+
|
|
580
|
+
**Symptom**: Global returns `false` but local still executes
|
|
581
|
+
|
|
582
|
+
**Cause**: Logic error in `mergeCallbacks()`
|
|
583
|
+
|
|
584
|
+
**Check**:
|
|
585
|
+
|
|
586
|
+
```typescript
|
|
587
|
+
// In apiHelpers.ts
|
|
588
|
+
const merged = {
|
|
589
|
+
onSuccess: (data, ctx) => {
|
|
590
|
+
if (global.onSuccess && shouldApply('onSuccess')) {
|
|
591
|
+
const result = global.onSuccess(data, ctx);
|
|
592
|
+
if (result === false) {
|
|
593
|
+
console.log('Global returned false, skipping local'); // Add this
|
|
594
|
+
return; // ← This should prevent local from running
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
if (local.onSuccess) {
|
|
598
|
+
console.log('Running local onSuccess'); // Add this
|
|
599
|
+
local.onSuccess(data, ctx);
|
|
600
|
+
}
|
|
601
|
+
},
|
|
602
|
+
};
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
**Solution**: Ensure early return after `result === false`.
|
|
606
|
+
|
|
607
|
+
## Performance Issues
|
|
608
|
+
|
|
609
|
+
### Generation is Slow
|
|
610
|
+
|
|
611
|
+
**Symptom**: Takes >10 seconds to generate composables
|
|
612
|
+
|
|
613
|
+
**Causes**:
|
|
614
|
+
|
|
615
|
+
- Large OpenAPI spec (100+ endpoints)
|
|
616
|
+
- Prettier formatting each file individually
|
|
617
|
+
- Disk I/O bottleneck
|
|
618
|
+
|
|
619
|
+
**Solutions**:
|
|
620
|
+
|
|
621
|
+
1. **Batch Prettier Formatting**:
|
|
622
|
+
|
|
623
|
+
```typescript
|
|
624
|
+
// Instead of:
|
|
625
|
+
for (const method of methods) {
|
|
626
|
+
const content = generateComposableFile(method);
|
|
627
|
+
const formatted = await prettier.format(content); // Slow: One at a time
|
|
628
|
+
await fs.writeFile(path, formatted);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
// Do:
|
|
632
|
+
const tasks = methods.map(async (method) => {
|
|
633
|
+
const content = generateComposableFile(method);
|
|
634
|
+
const formatted = await prettier.format(content);
|
|
635
|
+
return { path: method.fileName, content: formatted };
|
|
636
|
+
});
|
|
637
|
+
|
|
638
|
+
const results = await Promise.all(tasks); // Fast: Parallel
|
|
639
|
+
for (const { path, content } of results) {
|
|
640
|
+
await fs.writeFile(path, content);
|
|
641
|
+
}
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
2. **Skip Formatting in Development**:
|
|
645
|
+
|
|
646
|
+
```bash
|
|
647
|
+
node dist/index.js generate -i swagger.yaml -o ./output --skip-formatting
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
3. **Reduce OpenAPI Spec Size**: Split into multiple specs
|
|
651
|
+
|
|
652
|
+
---
|
|
653
|
+
|
|
654
|
+
### Runtime is Slow (Request Delays)
|
|
655
|
+
|
|
656
|
+
**Symptom**: API requests take longer than expected
|
|
657
|
+
|
|
658
|
+
**Causes**:
|
|
659
|
+
|
|
660
|
+
- Synchronous callbacks blocking request
|
|
661
|
+
- Heavy computation in `onRequest`
|
|
662
|
+
- Inefficient `pick` or `transform`
|
|
663
|
+
|
|
664
|
+
**Solutions**:
|
|
665
|
+
|
|
666
|
+
1. **Make Callbacks Async**:
|
|
667
|
+
|
|
668
|
+
```typescript
|
|
669
|
+
onRequest: async (ctx) => {
|
|
670
|
+
// ❌ Bad: Blocks request
|
|
671
|
+
const token = expensiveComputationSync();
|
|
672
|
+
|
|
673
|
+
// ✅ Good: Non-blocking
|
|
674
|
+
const token = await expensiveComputationAsync();
|
|
675
|
+
|
|
676
|
+
return { headers: { Authorization: token } };
|
|
677
|
+
};
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
2. **Optimize `pick`**:
|
|
681
|
+
|
|
682
|
+
```typescript
|
|
683
|
+
// ❌ Bad: Pick deeply nested field
|
|
684
|
+
pick: ['users.0.profile.avatar.url.thumbnail'];
|
|
685
|
+
|
|
686
|
+
// ✅ Good: Pick at shallower level
|
|
687
|
+
pick: ['users'];
|
|
688
|
+
// Then access in component:
|
|
689
|
+
const thumbnail = data.value.users[0]?.profile?.avatar?.url?.thumbnail;
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
3. **Debounce Rapid Calls**:
|
|
693
|
+
|
|
694
|
+
```typescript
|
|
695
|
+
import { useDebounceFn } from '@vueuse/core';
|
|
696
|
+
|
|
697
|
+
const debouncedFetch = useDebounceFn(() => {
|
|
698
|
+
useFetchGetData(params);
|
|
699
|
+
}, 300);
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
## OpenAPI Spec Issues
|
|
703
|
+
|
|
704
|
+
### Generated Types Have `any`
|
|
705
|
+
|
|
706
|
+
**Symptom**:
|
|
707
|
+
|
|
708
|
+
```typescript
|
|
709
|
+
export interface Pet {
|
|
710
|
+
name: any; // Should be string
|
|
711
|
+
}
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
**Cause**: OpenAPI spec missing type definitions
|
|
715
|
+
|
|
716
|
+
**Solution**: Add types to OpenAPI spec:
|
|
717
|
+
|
|
718
|
+
```yaml
|
|
719
|
+
# ❌ Bad
|
|
720
|
+
Pet:
|
|
721
|
+
properties:
|
|
722
|
+
name: {}
|
|
723
|
+
|
|
724
|
+
# ✅ Good
|
|
725
|
+
Pet:
|
|
726
|
+
properties:
|
|
727
|
+
name:
|
|
728
|
+
type: string
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
---
|
|
732
|
+
|
|
733
|
+
### Missing Request/Response Types
|
|
734
|
+
|
|
735
|
+
**Symptom**:
|
|
736
|
+
|
|
737
|
+
```
|
|
738
|
+
Cannot find name 'AddPetRequest'
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
**Cause**: OpenAPI spec missing `requestBody` or doesn't use schemas
|
|
742
|
+
|
|
743
|
+
**Solution**: Define schemas in OpenAPI:
|
|
744
|
+
|
|
745
|
+
```yaml
|
|
746
|
+
paths:
|
|
747
|
+
/pet:
|
|
748
|
+
post:
|
|
749
|
+
requestBody:
|
|
750
|
+
required: true
|
|
751
|
+
content:
|
|
752
|
+
application/json:
|
|
753
|
+
schema:
|
|
754
|
+
$ref: '#/components/schemas/Pet'
|
|
755
|
+
responses:
|
|
756
|
+
'200':
|
|
757
|
+
content:
|
|
758
|
+
application/json:
|
|
759
|
+
schema:
|
|
760
|
+
$ref: '#/components/schemas/Pet'
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
---
|
|
764
|
+
|
|
765
|
+
### Path Parameters Not Replaced
|
|
766
|
+
|
|
767
|
+
**Symptom**: Generated URL is `/pet/{petId}` instead of `` `/pet/${params.petId}` ``
|
|
768
|
+
|
|
769
|
+
**Cause**: Parser not detecting path parameters
|
|
770
|
+
|
|
771
|
+
**Debug**: Check parser output:
|
|
772
|
+
|
|
773
|
+
```typescript
|
|
774
|
+
// Add to parser.ts
|
|
775
|
+
console.log('Path params:', method.pathParams);
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
**Solution**: Ensure OpenAPI spec defines path params:
|
|
779
|
+
|
|
780
|
+
```yaml
|
|
781
|
+
paths:
|
|
782
|
+
/pet/{petId}:
|
|
783
|
+
get:
|
|
784
|
+
parameters:
|
|
785
|
+
- name: petId
|
|
786
|
+
in: path
|
|
787
|
+
required: true
|
|
788
|
+
schema:
|
|
789
|
+
type: integer
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
## Getting Help
|
|
793
|
+
|
|
794
|
+
### Before Opening an Issue
|
|
795
|
+
|
|
796
|
+
1. ✅ Check this troubleshooting guide
|
|
797
|
+
2. ✅ Read relevant documentation:
|
|
798
|
+
- [Quick Start](./QUICK-START.md)
|
|
799
|
+
- [Architecture](./ARCHITECTURE.md)
|
|
800
|
+
- [API Reference](./API-REFERENCE.md)
|
|
801
|
+
3. ✅ Search existing issues on GitHub
|
|
802
|
+
4. ✅ Test with example `swagger.yaml` from repository
|
|
803
|
+
5. ✅ Try with latest version: `npm install -g nuxt-openapi-hyperfetch@latest`
|
|
804
|
+
|
|
805
|
+
### What to Include in Bug Reports
|
|
806
|
+
|
|
807
|
+
````markdown
|
|
808
|
+
**Environment:**
|
|
809
|
+
|
|
810
|
+
- Node version: 18.16.0
|
|
811
|
+
- npm version: 9.5.1
|
|
812
|
+
- OS: Windows 11
|
|
813
|
+
- Nuxt Generator version: 1.5.0
|
|
814
|
+
|
|
815
|
+
**Steps to Reproduce:**
|
|
816
|
+
|
|
817
|
+
1. Run: `node dist/index.js generate -i swagger.yaml -o ./output`
|
|
818
|
+
2. Check output file: `output/composables/use-fetch/use-fetch-get-pet.ts`
|
|
819
|
+
3. See error: ...
|
|
820
|
+
|
|
821
|
+
**Expected Behavior:**
|
|
822
|
+
Should generate valid TypeScript file with correct imports.
|
|
823
|
+
|
|
824
|
+
**Actual Behavior:**
|
|
825
|
+
Error: Cannot find module '../apis/PetApi'
|
|
826
|
+
|
|
827
|
+
**OpenAPI Spec (simplified):**
|
|
828
|
+
|
|
829
|
+
```yaml
|
|
830
|
+
openapi: 3.0.0
|
|
831
|
+
paths:
|
|
832
|
+
/pet:
|
|
833
|
+
get:
|
|
834
|
+
responses:
|
|
835
|
+
'200':
|
|
836
|
+
content:
|
|
837
|
+
application/json:
|
|
838
|
+
schema:
|
|
839
|
+
$ref: '#/components/schemas/Pet'
|
|
840
|
+
```
|
|
841
|
+
````
|
|
842
|
+
|
|
843
|
+
**Generated File:**
|
|
844
|
+
|
|
845
|
+
```typescript
|
|
846
|
+
import type { Pet } from '../apis/PetApi'; // ← Wrong path
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
**Additional Context:**
|
|
850
|
+
Works fine on Mac, only fails on Windows.
|
|
851
|
+
|
|
852
|
+
````
|
|
853
|
+
|
|
854
|
+
### Useful Debug Commands
|
|
855
|
+
|
|
856
|
+
```bash
|
|
857
|
+
# Check versions
|
|
858
|
+
node --version
|
|
859
|
+
npm --version
|
|
860
|
+
npx nuxt-openapi-hyperfetch --version
|
|
861
|
+
|
|
862
|
+
# Verbose build
|
|
863
|
+
npm run build -- --verbose
|
|
864
|
+
|
|
865
|
+
# Check generated files
|
|
866
|
+
ls -R swagger/
|
|
867
|
+
ls -R output/composables/
|
|
868
|
+
|
|
869
|
+
# Validate OpenAPI spec
|
|
870
|
+
npx @openapitools/openapi-generator-cli validate -i swagger.yaml
|
|
871
|
+
|
|
872
|
+
# Check TypeScript compilation
|
|
873
|
+
npx tsc --noEmit
|
|
874
|
+
|
|
875
|
+
# Check linting
|
|
876
|
+
npm run lint
|
|
877
|
+
````
|
|
878
|
+
|
|
879
|
+
---
|
|
880
|
+
|
|
881
|
+
**Need more help?** See [CONTRIBUTING.md](../CONTRIBUTING.md) or open an issue on GitHub.
|