nuxt-openapi-hyperfetch 0.1.7-alpha.1 → 0.2.7-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.
Files changed (97) hide show
  1. package/CONTRIBUTING.md +291 -292
  2. package/INSTRUCTIONS.md +327 -327
  3. package/LICENSE +202 -202
  4. package/README.md +231 -227
  5. package/dist/cli/logger.d.ts +26 -0
  6. package/dist/cli/logger.js +36 -0
  7. package/dist/cli/logo.js +5 -5
  8. package/dist/generators/components/connector-generator/generator.d.ts +12 -0
  9. package/dist/generators/components/connector-generator/generator.js +116 -0
  10. package/dist/generators/components/connector-generator/templates.d.ts +18 -0
  11. package/dist/generators/components/connector-generator/templates.js +222 -0
  12. package/dist/generators/components/connector-generator/types.d.ts +32 -0
  13. package/dist/generators/components/connector-generator/types.js +7 -0
  14. package/dist/generators/components/schema-analyzer/index.d.ts +17 -0
  15. package/dist/generators/components/schema-analyzer/index.js +20 -0
  16. package/dist/generators/components/schema-analyzer/intent-detector.d.ts +17 -0
  17. package/dist/generators/components/schema-analyzer/intent-detector.js +143 -0
  18. package/dist/generators/components/schema-analyzer/openapi-reader.d.ts +11 -0
  19. package/dist/generators/components/schema-analyzer/openapi-reader.js +76 -0
  20. package/dist/generators/components/schema-analyzer/resource-grouper.d.ts +6 -0
  21. package/dist/generators/components/schema-analyzer/resource-grouper.js +132 -0
  22. package/dist/generators/components/schema-analyzer/schema-field-mapper.d.ts +35 -0
  23. package/dist/generators/components/schema-analyzer/schema-field-mapper.js +220 -0
  24. package/dist/generators/components/schema-analyzer/types.d.ts +156 -0
  25. package/dist/generators/components/schema-analyzer/types.js +7 -0
  26. package/dist/generators/nuxt-server/generator.d.ts +2 -1
  27. package/dist/generators/nuxt-server/generator.js +21 -21
  28. package/dist/generators/shared/runtime/apiHelpers.d.ts +81 -41
  29. package/dist/generators/shared/runtime/apiHelpers.js +97 -104
  30. package/dist/generators/shared/runtime/pagination.d.ts +168 -0
  31. package/dist/generators/shared/runtime/pagination.js +179 -0
  32. package/dist/generators/shared/runtime/useDeleteConnector.d.ts +16 -0
  33. package/dist/generators/shared/runtime/useDeleteConnector.js +93 -0
  34. package/dist/generators/shared/runtime/useDetailConnector.d.ts +14 -0
  35. package/dist/generators/shared/runtime/useDetailConnector.js +50 -0
  36. package/dist/generators/shared/runtime/useFormConnector.d.ts +19 -0
  37. package/dist/generators/shared/runtime/useFormConnector.js +113 -0
  38. package/dist/generators/shared/runtime/useListConnector.d.ts +25 -0
  39. package/dist/generators/shared/runtime/useListConnector.js +125 -0
  40. package/dist/generators/shared/runtime/zod-error-merger.d.ts +23 -0
  41. package/dist/generators/shared/runtime/zod-error-merger.js +106 -0
  42. package/dist/generators/shared/templates/api-callbacks-plugin.js +54 -11
  43. package/dist/generators/shared/templates/api-pagination-plugin.d.ts +51 -0
  44. package/dist/generators/shared/templates/api-pagination-plugin.js +152 -0
  45. package/dist/generators/use-async-data/generator.d.ts +2 -1
  46. package/dist/generators/use-async-data/generator.js +14 -14
  47. package/dist/generators/use-async-data/runtime/useApiAsyncData.js +114 -13
  48. package/dist/generators/use-async-data/runtime/useApiAsyncDataRaw.js +88 -10
  49. package/dist/generators/use-async-data/templates.js +17 -17
  50. package/dist/generators/use-fetch/generator.d.ts +2 -1
  51. package/dist/generators/use-fetch/generator.js +12 -12
  52. package/dist/generators/use-fetch/runtime/useApiRequest.js +149 -40
  53. package/dist/generators/use-fetch/templates.js +14 -14
  54. package/dist/index.js +25 -0
  55. package/dist/module/index.d.ts +4 -0
  56. package/dist/module/index.js +93 -0
  57. package/dist/module/types.d.ts +27 -0
  58. package/dist/module/types.js +1 -0
  59. package/docs/API-REFERENCE.md +886 -887
  60. package/docs/generated-components.md +615 -0
  61. package/docs/headless-composables-ui.md +569 -0
  62. package/eslint.config.js +13 -0
  63. package/package.json +29 -2
  64. package/src/cli/config.ts +140 -140
  65. package/src/cli/logger.ts +124 -66
  66. package/src/cli/logo.ts +25 -25
  67. package/src/cli/types.ts +50 -50
  68. package/src/generators/components/connector-generator/generator.ts +138 -0
  69. package/src/generators/components/connector-generator/templates.ts +254 -0
  70. package/src/generators/components/connector-generator/types.ts +34 -0
  71. package/src/generators/components/schema-analyzer/index.ts +44 -0
  72. package/src/generators/components/schema-analyzer/intent-detector.ts +187 -0
  73. package/src/generators/components/schema-analyzer/openapi-reader.ts +96 -0
  74. package/src/generators/components/schema-analyzer/resource-grouper.ts +166 -0
  75. package/src/generators/components/schema-analyzer/schema-field-mapper.ts +268 -0
  76. package/src/generators/components/schema-analyzer/types.ts +177 -0
  77. package/src/generators/nuxt-server/generator.ts +272 -270
  78. package/src/generators/shared/runtime/apiHelpers.ts +535 -507
  79. package/src/generators/shared/runtime/pagination.ts +323 -0
  80. package/src/generators/shared/runtime/useDeleteConnector.ts +109 -0
  81. package/src/generators/shared/runtime/useDetailConnector.ts +64 -0
  82. package/src/generators/shared/runtime/useFormConnector.ts +139 -0
  83. package/src/generators/shared/runtime/useListConnector.ts +148 -0
  84. package/src/generators/shared/runtime/zod-error-merger.ts +119 -0
  85. package/src/generators/shared/templates/api-callbacks-plugin.ts +399 -352
  86. package/src/generators/shared/templates/api-pagination-plugin.ts +158 -0
  87. package/src/generators/use-async-data/generator.ts +205 -204
  88. package/src/generators/use-async-data/runtime/useApiAsyncData.ts +329 -229
  89. package/src/generators/use-async-data/runtime/useApiAsyncDataRaw.ts +324 -245
  90. package/src/generators/use-async-data/templates.ts +257 -257
  91. package/src/generators/use-fetch/generator.ts +170 -169
  92. package/src/generators/use-fetch/runtime/useApiRequest.ts +354 -234
  93. package/src/generators/use-fetch/templates.ts +214 -214
  94. package/src/index.ts +303 -265
  95. package/src/module/index.ts +133 -0
  96. package/src/module/types.ts +31 -0
  97. package/src/generators/tanstack-query/generator.ts +0 -11
@@ -1,352 +1,399 @@
1
- // @ts-nocheck
2
- /**
3
- * Global API Callbacks Plugin
4
- *
5
- * ⚠️ IMPORTANT: This file is NEVER regenerated - your changes are safe!
6
- *
7
- * This plugin allows you to configure global callbacks for all API requests
8
- * made with useFetch* and useAsyncData* composables.
9
- *
10
- * 📚 Three ways to control global callbacks:
11
- *
12
- * 1️⃣ OPTION 1: skipGlobalCallbacks (disable from the call)
13
- * Skip global callbacks for specific requests
14
- * Example:
15
- * useFetchGetPets({ skipGlobalCallbacks: true })
16
- * useFetchGetPets({ skipGlobalCallbacks: ['onSuccess'] })
17
- *
18
- * 2️⃣ OPTION 2: return false (disable from the plugin)
19
- * Global callbacks can return false to prevent local callback execution
20
- * Example:
21
- * onError: (error) => {
22
- * if (error.statusCode === 401) {
23
- * navigateTo('/login');
24
- * return false; // Don't execute local onError
25
- * }
26
- * }
27
- *
28
- * 3️⃣ OPTION 3: patterns (URL matching)
29
- * Only apply callbacks to URLs matching specific patterns
30
- * Example:
31
- * patterns: ['/api/**', '/api/v2/*']
32
- */
33
-
34
- export default defineNuxtPlugin(() => {
35
- // Uncomment and customize the callbacks you need
36
- const globalCallbacks = {
37
- // ========================================================================
38
- // OPTION 3: URL Pattern Matching (OPTIONAL)
39
- // ========================================================================
40
- // Only apply global callbacks to URLs matching these patterns
41
- // Use ** to match any path (including nested), * to match single segment
42
- // If omitted or empty, callbacks apply to ALL requests
43
- // patterns: ['/api/**'], // Only internal APIs
44
- // patterns: ['/api/v1/**', '/api/v2/**'], // Multiple API versions
45
- // patterns: ['**/public/**'], // All public endpoints
46
- // ========================================================================
47
- // onRequest: Called before every request
48
- // ========================================================================
49
- // Use cases:
50
- // - Add authentication headers globally
51
- // - Log all API calls
52
- // - Add request timestamps
53
- // - Modify request body/headers/params
54
- // onRequest: (context) => {
55
- // console.log(`[API] ${context.method} ${context.url}`);
56
- //
57
- // // Example 1: Add auth token to all requests
58
- // // const token = useCookie('auth-token').value;
59
- // // if (token) {
60
- // // return {
61
- // // headers: { 'Authorization': `Bearer ${token}` }
62
- // // };
63
- // // }
64
- //
65
- // // Example 2: Add request timestamp
66
- // // return {
67
- // // headers: { 'X-Request-Time': new Date().toISOString() }
68
- // // };
69
- //
70
- // // Example 3: Block local onRequest (OPTION 2)
71
- // // return false;
72
- // },
73
- // ========================================================================
74
- // onSuccess: Called when request succeeds
75
- // ========================================================================
76
- // Use cases:
77
- // - Show success notifications/toasts
78
- // - Track successful operations
79
- // - Update analytics
80
- // - Cache responses
81
- // onSuccess: (data, context) => {
82
- // // Example 1: Success notification
83
- // // const { $toast } = useNuxtApp();
84
- // // $toast?.success('✅ Operation successful');
85
- //
86
- // // Example 2: Track analytics
87
- // // trackEvent('api_success', { url: context?.url });
88
- //
89
- // // Example 3: Log response data (development only)
90
- // // if (process.dev) {
91
- // // console.log('API Response:', data);
92
- // // }
93
- //
94
- // // Example 4: Cache specific responses
95
- // // if (context?.url.includes('/api/config')) {
96
- // // localStorage.setItem('app-config', JSON.stringify(data));
97
- // // }
98
- //
99
- // // Example 5: Block local onSuccess for certain cases (OPTION 2)
100
- // // if (data.status === 'pending_approval') {
101
- // // $toast?.info('⏳ Awaiting approval');
102
- // // return false; // Don't execute local onSuccess
103
- // // }
104
- // },
105
- // ========================================================================
106
- // onError: Called when request fails
107
- // ========================================================================
108
- // Use cases:
109
- // - Handle authentication errors globally (401, 403)
110
- // - Show error notifications
111
- // - Log errors to monitoring service
112
- // - Handle network errors
113
- // - Retry logic
114
- // onError: (error, context) => {
115
- // console.error('[API Error]', error);
116
- // const { $toast } = useNuxtApp();
117
- //
118
- // // Example 1: Handle authentication errors (OPTION 2)
119
- // if (error.statusCode === 401) {
120
- // $toast?.warning('⚠️ Session expired - redirecting to login...');
121
- // navigateTo('/login');
122
- // return false; // Don't execute local onError (avoiding duplicate messages)
123
- // }
124
- //
125
- // // Example 2: Handle forbidden errors
126
- // // if (error.statusCode === 403) {
127
- // // $toast?.error('❌ Access denied');
128
- // // navigateTo('/');
129
- // // return false;
130
- // // }
131
- //
132
- // // Example 3: Handle server errors
133
- // // if (error.statusCode >= 500) {
134
- // // $toast?.error('❌ Server error - please try again later');
135
- // // // Log to monitoring service
136
- // // // logErrorToSentry(error);
137
- // // }
138
- //
139
- // // Example 4: Handle rate limiting
140
- // // if (error.statusCode === 429) {
141
- // // const retryAfter = error.data?.retryAfter || 60;
142
- // // $toast?.warning(`⏳ Too many requests - retry in ${retryAfter}s`);
143
- // // return false; // Don't show duplicate error in component
144
- // // }
145
- //
146
- // // Example 5: Handle network errors
147
- // // if (error.message === 'Network request failed') {
148
- // // $toast?.error('❌ Network error - check your connection');
149
- // // }
150
- //
151
- // // Example 6: Generic error notification
152
- // // $toast?.error(`❌ ${error.message || 'An error occurred'}`);
153
- //
154
- // // Allow local onError to execute (return true or don't return)
155
- // },
156
- // ========================================================================
157
- // onFinish: Called when request completes (success or error)
158
- // ========================================================================
159
- // Use cases:
160
- // - Hide loading indicators
161
- // - Track request completion
162
- // - Clean up resources
163
- // - Update request counters
164
- // onFinish: (context) => {
165
- // // Example 1: Track API call completion
166
- // // const duration = Date.now() - context.startTime;
167
- // // trackMetric('api_call_duration', duration, { url: context.url });
168
- //
169
- // // Example 2: Log request completion
170
- // // console.log(
171
- // // `[API] ${context.url} - ${context.success ? '✅ Success' : '❌ Failed'}`
172
- // // );
173
- //
174
- // // Example 3: Update request counter
175
- // // const store = useRequestStore();
176
- // // store.decrementPendingRequests();
177
- //
178
- // // Example 4: Clean up global loading state
179
- // // const { $loading } = useNuxtApp();
180
- // // $loading?.hide();
181
- // },
182
- };
183
-
184
- return {
185
- provide: {
186
- getGlobalApiCallbacks: () => globalCallbacks,
187
- },
188
- };
189
- });
190
-
191
- // ============================================================================
192
- // USAGE EXAMPLES
193
- // ============================================================================
194
-
195
- /**
196
- * Example 1: Use global callbacks (default behavior)
197
- *
198
- * const { data, error } = useFetchGetPets();
199
- * // All global callbacks execute automatically
200
- */
201
-
202
- /**
203
- * Example 2: Skip ALL global callbacks (OPTION 1)
204
- *
205
- * const { data, error } = useFetchGetPets({
206
- * skipGlobalCallbacks: true,
207
- * });
208
- * // No global callbacks execute
209
- */
210
-
211
- /**
212
- * Example 3: Skip SPECIFIC global callbacks (OPTION 1)
213
- *
214
- * const { data, error } = useFetchUpdatePet(id, pet, {
215
- * skipGlobalCallbacks: ['onSuccess'], // Skip global onSuccess only
216
- * onSuccess: (data) => {
217
- * // Only this local callback executes
218
- * console.log('Pet updated:', data);
219
- * }
220
- * });
221
- * // ✅ Global onError still executes
222
- * // Global onSuccess skipped
223
- * // Local onSuccess executes
224
- */
225
-
226
- /**
227
- * Example 4: Global callback prevents local execution (OPTION 2)
228
- *
229
- * // In plugin:
230
- * onError: (error) => {
231
- * if (error.statusCode === 401) {
232
- * navigateTo('/login');
233
- * return false; // Don't execute local onError
234
- * }
235
- * }
236
- *
237
- * // In component:
238
- * const { data, error } = useFetchGetPets({
239
- * onError: (error) => {
240
- * // ❌ This won't execute for 401 errors (global returned false)
241
- * // ✅ This executes for other errors (404, 500, etc.)
242
- * console.error('Failed to load pets:', error);
243
- * }
244
- * });
245
- */
246
-
247
- /**
248
- * Example 5: URL pattern matching (OPTION 3)
249
- *
250
- * // In plugin:
251
- * patterns: ['/api/public/**']
252
- *
253
- * // In components:
254
- * useFetchGetPets(); // URL: /api/public/pets ✅ Global callbacks execute
255
- * useFetchGetUser(); // URL: /api/users/me Global callbacks skipped
256
- * useFetchGetPublicConfig(); // URL: /api/public/config ✅ Global callbacks execute
257
- */
258
-
259
- /**
260
- * Example 6: Combine all options
261
- *
262
- * // In plugin:
263
- * patterns: ['/api/**'],
264
- * onError: (error) => {
265
- * if (error.statusCode === 401) return false;
266
- * }
267
- *
268
- * // In component:
269
- * const { data } = useFetchCreatePet(pet, {
270
- * skipGlobalCallbacks: ['onSuccess'], // Skip global success toast
271
- * onSuccess: (pet) => {
272
- * // Show custom success message
273
- * toast.success(`🐕 ${pet.name} added successfully!`);
274
- * },
275
- * onError: (error) => {
276
- * // This won't execute for 401 (global returns false)
277
- * // This executes for other errors
278
- * console.error('Failed to create pet:', error);
279
- * }
280
- * });
281
- */
282
-
283
- // ============================================================================
284
- // COMMON PATTERNS
285
- // ============================================================================
286
-
287
- /**
288
- * Pattern 1: Toast notifications for all operations
289
- *
290
- * const globalCallbacks = {
291
- * onSuccess: () => {
292
- * useNuxtApp().$toast?.success('✅ Success');
293
- * },
294
- * onError: (error) => {
295
- * if (error.statusCode === 401) {
296
- * navigateTo('/login');
297
- * return false;
298
- * }
299
- * useNuxtApp().$toast?.error(`❌ ${error.message}`);
300
- * }
301
- * };
302
- */
303
-
304
- /**
305
- * Pattern 2: Authentication + logging
306
- *
307
- * const globalCallbacks = {
308
- * onRequest: (context) => {
309
- * console.log(`[API] ${context.method} ${context.url}`);
310
- * const token = useCookie('auth-token').value;
311
- * if (token) {
312
- * return { headers: { 'Authorization': `Bearer ${token}` } };
313
- * }
314
- * },
315
- * onError: (error) => {
316
- * if (error.statusCode === 401) {
317
- * useCookie('auth-token').value = null;
318
- * navigateTo('/login');
319
- * return false;
320
- * }
321
- * }
322
- * };
323
- */
324
-
325
- /**
326
- * Pattern 3: Analytics tracking
327
- *
328
- * const globalCallbacks = {
329
- * onSuccess: (data, context) => {
330
- * trackEvent('api_success', { endpoint: context?.url });
331
- * },
332
- * onError: (error, context) => {
333
- * trackEvent('api_error', {
334
- * endpoint: context?.url,
335
- * statusCode: error.statusCode
336
- * });
337
- * }
338
- * };
339
- */
340
-
341
- /**
342
- * Pattern 4: Loading states
343
- *
344
- * const globalCallbacks = {
345
- * onRequest: () => {
346
- * useLoadingStore().increment();
347
- * },
348
- * onFinish: () => {
349
- * useLoadingStore().decrement();
350
- * }
351
- * };
352
- */
1
+ // @ts-nocheck
2
+ /**
3
+ * Global API Callbacks Plugin
4
+ *
5
+ * ⚠️ IMPORTANT: This file is NEVER regenerated - your changes are safe!
6
+ *
7
+ * This plugin allows you to configure global callbacks for all API requests
8
+ * made with useFetch* and useAsyncData* composables.
9
+ *
10
+ * 📚 Three ways to control global callbacks:
11
+ *
12
+ * 1️⃣ OPTION 1: skipGlobalCallbacks (disable from the call)
13
+ * Skip global callbacks for specific requests
14
+ * Example:
15
+ * useFetchGetPets({ skipGlobalCallbacks: true })
16
+ * useFetchGetPets({ skipGlobalCallbacks: ['onSuccess'] })
17
+ *
18
+ * 2️⃣ OPTION 2: return false (disable from the plugin)
19
+ * Global callbacks can return false to prevent local callback execution
20
+ * Example:
21
+ * onError: (error) => {
22
+ * if (error.statusCode === 401) {
23
+ * navigateTo('/login');
24
+ * return false; // Don't execute local onError
25
+ * }
26
+ * }
27
+ *
28
+ * 3️⃣ OPTION 3: patterns (URL matching)
29
+ * Only apply callbacks to URLs matching specific patterns
30
+ * Example:
31
+ * patterns: ['/api/**', '/api/v2/*']
32
+ */
33
+
34
+ export default defineNuxtPlugin(() => {
35
+ // Define your global callback rules.
36
+ // Each rule can optionally target specific URL patterns and/or HTTP methods.
37
+ // Rules are executed in order; backward-compatible with a single object.
38
+ const globalCallbacks = [
39
+ // ========================================================================
40
+ // RULE 1 applies to ALL requests (no patterns/methods filter)
41
+ // ========================================================================
42
+ // {
43
+ // onRequest: (context) => {
44
+ // console.log(`[API] ${context.method} ${context.url}`);
45
+ // },
46
+ // onError: (error) => {
47
+ // // Handle 401 globally return false to suppress local onError
48
+ // if (error.statusCode === 401) {
49
+ // navigateTo('/login');
50
+ // return false;
51
+ // }
52
+ // },
53
+ // },
54
+
55
+ // ========================================================================
56
+ // RULE 2 — only for DELETE / POST / PUT (method targeting)
57
+ // ========================================================================
58
+ // {
59
+ // methods: ['DELETE', 'POST', 'PUT'],
60
+ // onSuccess: (data, context) => {
61
+ // const { $toast } = useNuxtApp();
62
+ // $toast?.success('✅ Operation completed');
63
+ // },
64
+ // onError: (error) => {
65
+ // const { $toast } = useNuxtApp();
66
+ // $toast?.error(`❌ ${error.message || 'An error occurred'}`);
67
+ // },
68
+ // },
69
+
70
+ // ========================================================================
71
+ // RULE 3 — only for private API routes (URL pattern targeting)
72
+ // ========================================================================
73
+ // {
74
+ // patterns: ['/api/private/**'],
75
+ // onRequest: () => {
76
+ // const token = useCookie('auth-token').value;
77
+ // if (token) return { headers: { Authorization: `Bearer ${token}` } };
78
+ // },
79
+ // },
80
+
81
+ // ========================================================================
82
+ // RULE 4 DELETE on a specific resource (method + pattern combined)
83
+ // ========================================================================
84
+ // {
85
+ // methods: ['DELETE'],
86
+ // patterns: ['/api/users/**'],
87
+ // onSuccess: () => console.log('User deleted'),
88
+ // onError: (error) => console.error('Delete failed', error),
89
+ // },
90
+
91
+ // ---- Legacy single-object format is still supported ----
92
+ // You can also pass a single object instead of an array:
93
+ // getGlobalApiCallbacks: () => ({ onError: (e) => console.error(e) })
94
+ // ========================================================================
95
+ // onRequest: Called before every request
96
+ // ========================================================================
97
+ // Use cases:
98
+ // - Add authentication headers globally
99
+ // - Log all API calls
100
+ // - Add request timestamps
101
+ // - Modify request body/headers/params
102
+ // onRequest: (context) => {
103
+ // console.log(`[API] ${context.method} ${context.url}`);
104
+ //
105
+ // // Example 1: Add auth token to all requests
106
+ // // const token = useCookie('auth-token').value;
107
+ // // if (token) {
108
+ // // return {
109
+ // // headers: { 'Authorization': `Bearer ${token}` }
110
+ // // };
111
+ // // }
112
+ //
113
+ // // Example 2: Add request timestamp
114
+ // // return {
115
+ // // headers: { 'X-Request-Time': new Date().toISOString() }
116
+ // // };
117
+ //
118
+ // // Example 3: Block local onRequest (OPTION 2)
119
+ // // return false;
120
+ // },
121
+ // ========================================================================
122
+ // onSuccess: Called when request succeeds
123
+ // ========================================================================
124
+ // Use cases:
125
+ // - Show success notifications/toasts
126
+ // - Track successful operations
127
+ // - Update analytics
128
+ // - Cache responses
129
+ // onSuccess: (data, context) => {
130
+ // // Example 1: Success notification
131
+ // // const { $toast } = useNuxtApp();
132
+ // // $toast?.success('✅ Operation successful');
133
+ //
134
+ // // Example 2: Track analytics
135
+ // // trackEvent('api_success', { url: context?.url });
136
+ //
137
+ // // Example 3: Log response data (development only)
138
+ // // if (process.dev) {
139
+ // // console.log('API Response:', data);
140
+ // // }
141
+ //
142
+ // // Example 4: Cache specific responses
143
+ // // if (context?.url.includes('/api/config')) {
144
+ // // localStorage.setItem('app-config', JSON.stringify(data));
145
+ // // }
146
+ //
147
+ // // Example 5: Block local onSuccess for certain cases (OPTION 2)
148
+ // // if (data.status === 'pending_approval') {
149
+ // // $toast?.info('⏳ Awaiting approval');
150
+ // // return false; // Don't execute local onSuccess
151
+ // // }
152
+ // },
153
+ // ========================================================================
154
+ // onError: Called when request fails
155
+ // ========================================================================
156
+ // Use cases:
157
+ // - Handle authentication errors globally (401, 403)
158
+ // - Show error notifications
159
+ // - Log errors to monitoring service
160
+ // - Handle network errors
161
+ // - Retry logic
162
+ // onError: (error, context) => {
163
+ // console.error('[API Error]', error);
164
+ // const { $toast } = useNuxtApp();
165
+ //
166
+ // // Example 1: Handle authentication errors (OPTION 2)
167
+ // if (error.statusCode === 401) {
168
+ // $toast?.warning('⚠️ Session expired - redirecting to login...');
169
+ // navigateTo('/login');
170
+ // return false; // Don't execute local onError (avoiding duplicate messages)
171
+ // }
172
+ //
173
+ // // Example 2: Handle forbidden errors
174
+ // // if (error.statusCode === 403) {
175
+ // // $toast?.error('❌ Access denied');
176
+ // // navigateTo('/');
177
+ // // return false;
178
+ // // }
179
+ //
180
+ // // Example 3: Handle server errors
181
+ // // if (error.statusCode >= 500) {
182
+ // // $toast?.error('❌ Server error - please try again later');
183
+ // // // Log to monitoring service
184
+ // // // logErrorToSentry(error);
185
+ // // }
186
+ //
187
+ // // Example 4: Handle rate limiting
188
+ // // if (error.statusCode === 429) {
189
+ // // const retryAfter = error.data?.retryAfter || 60;
190
+ // // $toast?.warning(`⏳ Too many requests - retry in ${retryAfter}s`);
191
+ // // return false; // Don't show duplicate error in component
192
+ // // }
193
+ //
194
+ // // Example 5: Handle network errors
195
+ // // if (error.message === 'Network request failed') {
196
+ // // $toast?.error('❌ Network error - check your connection');
197
+ // // }
198
+ //
199
+ // // Example 6: Generic error notification
200
+ // // $toast?.error(`❌ ${error.message || 'An error occurred'}`);
201
+ //
202
+ // // Allow local onError to execute (return true or don't return)
203
+ // },
204
+ // ========================================================================
205
+ // onFinish: Called when request completes (success or error)
206
+ // ========================================================================
207
+ // Use cases:
208
+ // - Hide loading indicators
209
+ // - Track request completion
210
+ // - Clean up resources
211
+ // - Update request counters
212
+ // onFinish: (context) => {
213
+ // // Example 1: Track API call completion
214
+ // // const duration = Date.now() - context.startTime;
215
+ // // trackMetric('api_call_duration', duration, { url: context.url });
216
+ //
217
+ // // Example 2: Log request completion
218
+ // // console.log(
219
+ // // `[API] ${context.url} - ${context.success ? '✅ Success' : '❌ Failed'}`
220
+ // // );
221
+ //
222
+ // // Example 3: Update request counter
223
+ // // const store = useRequestStore();
224
+ // // store.decrementPendingRequests();
225
+ //
226
+ // // Example 4: Clean up global loading state
227
+ // // const { $loading } = useNuxtApp();
228
+ // // $loading?.hide();
229
+ ];
230
+
231
+ return {
232
+ provide: {
233
+ getGlobalApiCallbacks: () => globalCallbacks,
234
+ },
235
+ };
236
+ });
237
+
238
+ // ============================================================================
239
+ // USAGE EXAMPLES
240
+ // ============================================================================
241
+
242
+ /**
243
+ * Example 1: Use global callbacks (default behavior)
244
+ *
245
+ * const { data, error } = useFetchGetPets();
246
+ * // ✅ All global callbacks execute automatically
247
+ */
248
+
249
+ /**
250
+ * Example 2: Skip ALL global callbacks (OPTION 1)
251
+ *
252
+ * const { data, error } = useFetchGetPets({
253
+ * skipGlobalCallbacks: true,
254
+ * });
255
+ * // ❌ No global callbacks execute
256
+ */
257
+
258
+ /**
259
+ * Example 3: Skip SPECIFIC global callbacks (OPTION 1)
260
+ *
261
+ * const { data, error } = useFetchUpdatePet(id, pet, {
262
+ * skipGlobalCallbacks: ['onSuccess'], // Skip global onSuccess only
263
+ * onSuccess: (data) => {
264
+ * // Only this local callback executes
265
+ * console.log('Pet updated:', data);
266
+ * }
267
+ * });
268
+ * // Global onError still executes
269
+ * // Global onSuccess skipped
270
+ * // Local onSuccess executes
271
+ */
272
+
273
+ /**
274
+ * Example 4: Global callback prevents local execution (OPTION 2)
275
+ *
276
+ * // In plugin:
277
+ * onError: (error) => {
278
+ * if (error.statusCode === 401) {
279
+ * navigateTo('/login');
280
+ * return false; // Don't execute local onError
281
+ * }
282
+ * }
283
+ *
284
+ * // In component:
285
+ * const { data, error } = useFetchGetPets({
286
+ * onError: (error) => {
287
+ * // ❌ This won't execute for 401 errors (global returned false)
288
+ * // This executes for other errors (404, 500, etc.)
289
+ * console.error('Failed to load pets:', error);
290
+ * }
291
+ * });
292
+ */
293
+
294
+ /**
295
+ * Example 5: URL pattern matching (OPTION 3)
296
+ *
297
+ * // In plugin:
298
+ * patterns: ['/api/public/**']
299
+ *
300
+ * // In components:
301
+ * useFetchGetPets(); // URL: /api/public/pets ✅ Global callbacks execute
302
+ * useFetchGetUser(); // URL: /api/users/me ❌ Global callbacks skipped
303
+ * useFetchGetPublicConfig(); // URL: /api/public/config ✅ Global callbacks execute
304
+ */
305
+
306
+ /**
307
+ * Example 6: Combine all options
308
+ *
309
+ * // In plugin:
310
+ * patterns: ['/api/**'],
311
+ * onError: (error) => {
312
+ * if (error.statusCode === 401) return false;
313
+ * }
314
+ *
315
+ * // In component:
316
+ * const { data } = useFetchCreatePet(pet, {
317
+ * skipGlobalCallbacks: ['onSuccess'], // Skip global success toast
318
+ * onSuccess: (pet) => {
319
+ * // Show custom success message
320
+ * toast.success(`🐕 ${pet.name} added successfully!`);
321
+ * },
322
+ * onError: (error) => {
323
+ * // This won't execute for 401 (global returns false)
324
+ * // This executes for other errors
325
+ * console.error('Failed to create pet:', error);
326
+ * }
327
+ * });
328
+ */
329
+
330
+ // ============================================================================
331
+ // COMMON PATTERNS
332
+ // ============================================================================
333
+
334
+ /**
335
+ * Pattern 1: Toast notifications for all operations
336
+ *
337
+ * const globalCallbacks = {
338
+ * onSuccess: () => {
339
+ * useNuxtApp().$toast?.success('✅ Success');
340
+ * },
341
+ * onError: (error) => {
342
+ * if (error.statusCode === 401) {
343
+ * navigateTo('/login');
344
+ * return false;
345
+ * }
346
+ * useNuxtApp().$toast?.error(`❌ ${error.message}`);
347
+ * }
348
+ * };
349
+ */
350
+
351
+ /**
352
+ * Pattern 2: Authentication + logging
353
+ *
354
+ * const globalCallbacks = {
355
+ * onRequest: (context) => {
356
+ * console.log(`[API] ${context.method} ${context.url}`);
357
+ * const token = useCookie('auth-token').value;
358
+ * if (token) {
359
+ * return { headers: { 'Authorization': `Bearer ${token}` } };
360
+ * }
361
+ * },
362
+ * onError: (error) => {
363
+ * if (error.statusCode === 401) {
364
+ * useCookie('auth-token').value = null;
365
+ * navigateTo('/login');
366
+ * return false;
367
+ * }
368
+ * }
369
+ * };
370
+ */
371
+
372
+ /**
373
+ * Pattern 3: Analytics tracking
374
+ *
375
+ * const globalCallbacks = {
376
+ * onSuccess: (data, context) => {
377
+ * trackEvent('api_success', { endpoint: context?.url });
378
+ * },
379
+ * onError: (error, context) => {
380
+ * trackEvent('api_error', {
381
+ * endpoint: context?.url,
382
+ * statusCode: error.statusCode
383
+ * });
384
+ * }
385
+ * };
386
+ */
387
+
388
+ /**
389
+ * Pattern 4: Loading states
390
+ *
391
+ * const globalCallbacks = {
392
+ * onRequest: () => {
393
+ * useLoadingStore().increment();
394
+ * },
395
+ * onFinish: () => {
396
+ * useLoadingStore().decrement();
397
+ * }
398
+ * };
399
+ */