@enfyra/sdk-nuxt 0.2.0 → 0.2.2
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 +84 -53
- package/dist/composables/useEnfyraApi.d.ts +12 -2
- package/dist/composables/useEnfyraApi.mjs +43 -36
- package/dist/composables.d.ts +13 -3
- package/dist/index.d.ts +32 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -2
- package/dist/module.json +1 -1
- package/package.json +9 -1
- package/src/composables/useEnfyraApi.ts +86 -54
- package/src/types/index.ts +39 -10
- package/dist/composables.d.ts.map +0 -1
- package/dist/composables.js +0 -1
- package/src/types/composables.ts +0 -15
package/README.md
CHANGED
|
@@ -24,17 +24,10 @@ Add the module to your `nuxt.config.ts`:
|
|
|
24
24
|
|
|
25
25
|
```typescript
|
|
26
26
|
export default defineNuxtConfig({
|
|
27
|
-
modules: [
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
public: {
|
|
32
|
-
enfyraSDK: {
|
|
33
|
-
apiUrl: process.env.ENFYRA_API_URL || 'https://api.enfyra.com',
|
|
34
|
-
apiPrefix: '/api/v1', // Optional: API prefix
|
|
35
|
-
appUrl: process.env.ENFYRA_APP_URL || 'https://app.enfyra.com'
|
|
36
|
-
},
|
|
37
|
-
},
|
|
27
|
+
modules: ["@enfyra/sdk-nuxt"],
|
|
28
|
+
enfyraSDK: {
|
|
29
|
+
apiUrl: "http://localhost:1105",
|
|
30
|
+
appUrl: "http://localhost:3001",
|
|
38
31
|
},
|
|
39
32
|
})
|
|
40
33
|
```
|
|
@@ -46,10 +39,10 @@ export default defineNuxtConfig({
|
|
|
46
39
|
```typescript
|
|
47
40
|
// pages/users.vue
|
|
48
41
|
<script setup>
|
|
49
|
-
// ✅ Automatic server-side
|
|
42
|
+
// ✅ Automatic execution on server-side with caching (runs immediately, no execute() needed)
|
|
50
43
|
const { data: users, pending, error, refresh } = useEnfyraApi('/users', {
|
|
51
44
|
ssr: true,
|
|
52
|
-
key: 'users-list'
|
|
45
|
+
key: 'users-list' // Optional cache key
|
|
53
46
|
});
|
|
54
47
|
</script>
|
|
55
48
|
|
|
@@ -121,19 +114,21 @@ await logout();
|
|
|
121
114
|
Main composable for API requests with both SSR and client-side support.
|
|
122
115
|
|
|
123
116
|
```typescript
|
|
124
|
-
// SSR Mode -
|
|
117
|
+
// SSR Mode - Runs immediately (like useFetch)
|
|
125
118
|
const { data, pending, error, refresh } = useEnfyraApi('/endpoint', {
|
|
126
119
|
ssr: true,
|
|
127
|
-
key: 'cache-key',
|
|
120
|
+
key: 'cache-key', // Optional
|
|
128
121
|
method: 'get',
|
|
129
122
|
query: { page: 1 }
|
|
130
123
|
});
|
|
124
|
+
// ⚠️ Returns useFetch result: { data, pending, error, refresh }
|
|
131
125
|
|
|
132
126
|
// Client Mode - Manual execution
|
|
133
127
|
const { data, pending, error, execute } = useEnfyraApi('/endpoint', {
|
|
134
128
|
method: 'post',
|
|
135
129
|
errorContext: 'Create Resource'
|
|
136
130
|
});
|
|
131
|
+
// ⚠️ Returns custom result: { data, pending, error, execute }
|
|
137
132
|
|
|
138
133
|
await execute({
|
|
139
134
|
body: { name: 'New Item' },
|
|
@@ -142,20 +137,29 @@ await execute({
|
|
|
142
137
|
```
|
|
143
138
|
|
|
144
139
|
**Options:**
|
|
145
|
-
- `ssr?: boolean` - Enable server-side rendering mode
|
|
140
|
+
- `ssr?: boolean` - Enable server-side rendering mode (executes immediately like useFetch)
|
|
146
141
|
- `method?: 'get' | 'post' | 'patch' | 'delete'` - HTTP method
|
|
147
142
|
- `body?: any` - Request body (POST/PATCH)
|
|
148
143
|
- `query?: Record<string, any>` - URL query parameters
|
|
149
144
|
- `headers?: Record<string, string>` - Custom headers
|
|
150
145
|
- `errorContext?: string` - Error context for logging
|
|
151
|
-
- `
|
|
146
|
+
- `onError?: (error: ApiError, context?: string) => void` - Custom error handler
|
|
147
|
+
- `batchSize?: number` - Batch size for chunking large operations (default: no limit)
|
|
148
|
+
- `concurrent?: number` - Maximum concurrent requests (default: no limit)
|
|
149
|
+
- `key?: string` - Cache key (SSR mode, optional)
|
|
152
150
|
- `default?: () => T` - Default value (SSR mode only)
|
|
153
151
|
|
|
152
|
+
**⚠️ Important: Return Types Differ**
|
|
153
|
+
- **SSR Mode**: Returns `useFetch` result `{ data, pending, error, refresh }`
|
|
154
|
+
- **Client Mode**: Returns custom result `{ data, pending, error, execute }`
|
|
155
|
+
|
|
154
156
|
**Execute Options (Client mode only):**
|
|
155
157
|
- `id?: string | number` - Single resource ID
|
|
156
158
|
- `ids?: (string | number)[]` - Batch operation IDs (PATCH/DELETE)
|
|
157
|
-
- `files?: FormData[]` -
|
|
159
|
+
- `files?: FormData[]` - Array of FormData objects for batch upload (POST)
|
|
158
160
|
- `body?: any` - Override request body
|
|
161
|
+
- `batchSize?: number` - Override batch size for this execution
|
|
162
|
+
- `concurrent?: number` - Override concurrent limit for this execution
|
|
159
163
|
|
|
160
164
|
### `useEnfyraAuth()`
|
|
161
165
|
|
|
@@ -179,7 +183,7 @@ await fetchUser() // Refresh user data
|
|
|
179
183
|
### Batch Operations
|
|
180
184
|
|
|
181
185
|
```typescript
|
|
182
|
-
//
|
|
186
|
+
// Basic batch delete - unlimited parallel requests
|
|
183
187
|
const { execute: deleteItems } = useEnfyraApi('/items', {
|
|
184
188
|
method: 'delete',
|
|
185
189
|
errorContext: 'Delete Items'
|
|
@@ -187,14 +191,50 @@ const { execute: deleteItems } = useEnfyraApi('/items', {
|
|
|
187
191
|
|
|
188
192
|
await deleteItems({ ids: ['1', '2', '3'] });
|
|
189
193
|
|
|
190
|
-
//
|
|
191
|
-
const { execute:
|
|
192
|
-
method: '
|
|
194
|
+
// Advanced batch operations with concurrency control
|
|
195
|
+
const { execute: deleteMany } = useEnfyraApi('/users', {
|
|
196
|
+
method: 'delete',
|
|
197
|
+
batchSize: 10, // Process 10 items at a time
|
|
198
|
+
concurrent: 3, // Max 3 requests simultaneously
|
|
199
|
+
onError: (error, context) => toast.error(`${context}: ${error.message}`)
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// Delete 100 users in controlled batches
|
|
203
|
+
await deleteMany({ ids: Array.from({length: 100}, (_, i) => `user-${i}`) });
|
|
204
|
+
|
|
205
|
+
// Override batch settings per execution
|
|
206
|
+
const { execute: updateUsers } = useEnfyraApi('/users', {
|
|
207
|
+
method: 'patch',
|
|
208
|
+
batchSize: 20, // Default: 20 per batch
|
|
209
|
+
concurrent: 5 // Default: 5 concurrent
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// This execution uses different settings
|
|
213
|
+
await updateUsers({
|
|
214
|
+
ids: largeUserList,
|
|
215
|
+
body: { status: 'active' },
|
|
216
|
+
batchSize: 50, // Override: 50 per batch for this call
|
|
217
|
+
concurrent: 10 // Override: 10 concurrent for this call
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Batch file upload with progress control
|
|
221
|
+
const { execute: uploadFiles } = useEnfyraApi('/file_definition', {
|
|
222
|
+
method: 'post',
|
|
223
|
+
batchSize: 5, // Upload 5 files at a time
|
|
224
|
+
concurrent: 2, // Max 2 uploads simultaneously
|
|
193
225
|
errorContext: 'Upload Files'
|
|
194
226
|
});
|
|
195
227
|
|
|
228
|
+
// Convert files to FormData array (matches enfyra_app pattern)
|
|
229
|
+
const formDataArray = selectedFiles.map(file => {
|
|
230
|
+
const formData = new FormData();
|
|
231
|
+
formData.append('file', file);
|
|
232
|
+
formData.append('folder', folderId || 'null');
|
|
233
|
+
return formData;
|
|
234
|
+
});
|
|
235
|
+
|
|
196
236
|
await uploadFiles({
|
|
197
|
-
files:
|
|
237
|
+
files: formDataArray // Array of FormData objects
|
|
198
238
|
});
|
|
199
239
|
```
|
|
200
240
|
|
|
@@ -228,10 +268,10 @@ const users = computed(() => data.value?.data || []);
|
|
|
228
268
|
const searchQuery = ref('');
|
|
229
269
|
const page = ref(1);
|
|
230
270
|
|
|
231
|
-
// SSR mode with reactive query
|
|
271
|
+
// SSR mode with reactive query (executes immediately)
|
|
232
272
|
const { data, refresh } = useEnfyraApi('/users', {
|
|
233
273
|
ssr: true,
|
|
234
|
-
key: () => `users-${page.value}-${searchQuery.value}`,
|
|
274
|
+
key: () => `users-${page.value}-${searchQuery.value}`, // Optional
|
|
235
275
|
query: computed(() => ({
|
|
236
276
|
search: searchQuery.value,
|
|
237
277
|
page: page.value,
|
|
@@ -247,7 +287,7 @@ watch([searchQuery, page], () => refresh());
|
|
|
247
287
|
|
|
248
288
|
For comprehensive guides and examples:
|
|
249
289
|
|
|
250
|
-
📚 **[useEnfyraApi Complete Guide](
|
|
290
|
+
📚 **[useEnfyraApi Complete Guide](https://github.com/dothinh115/enfyra-sdk-nuxt/blob/main/docs/useEnfyraApi.md)** - Detailed documentation with examples, best practices, and troubleshooting
|
|
251
291
|
|
|
252
292
|
Key topics covered:
|
|
253
293
|
- SSR vs Client Mode comparison
|
|
@@ -260,30 +300,21 @@ Key topics covered:
|
|
|
260
300
|
|
|
261
301
|
## Configuration
|
|
262
302
|
|
|
263
|
-
###
|
|
303
|
+
### Module Options
|
|
264
304
|
|
|
265
305
|
```typescript
|
|
266
306
|
// nuxt.config.ts
|
|
267
307
|
export default defineNuxtConfig({
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
appUrl: process.env.ENFYRA_APP_URL,
|
|
279
|
-
|
|
280
|
-
// Optional: Default headers for all requests
|
|
281
|
-
defaultHeaders: {
|
|
282
|
-
'Accept': 'application/json',
|
|
283
|
-
'Content-Type': 'application/json'
|
|
284
|
-
}
|
|
285
|
-
},
|
|
286
|
-
},
|
|
308
|
+
modules: ["@enfyra/sdk-nuxt"],
|
|
309
|
+
enfyraSDK: {
|
|
310
|
+
// Required: Main API URL
|
|
311
|
+
apiUrl: process.env.ENFYRA_API_URL || "http://localhost:1105",
|
|
312
|
+
|
|
313
|
+
// Optional: API path prefix (default: '')
|
|
314
|
+
apiPrefix: '/api/v1',
|
|
315
|
+
|
|
316
|
+
// Required: App URL for SSR requests
|
|
317
|
+
appUrl: process.env.ENFYRA_APP_URL || "http://localhost:3001",
|
|
287
318
|
},
|
|
288
319
|
})
|
|
289
320
|
```
|
|
@@ -301,13 +332,13 @@ ENFYRA_APP_URL=https://app.enfyra.com
|
|
|
301
332
|
### 1. Choose the Right Mode
|
|
302
333
|
|
|
303
334
|
```typescript
|
|
304
|
-
// ✅ Use SSR for initial page data
|
|
335
|
+
// ✅ Use SSR for initial page data (runs immediately)
|
|
305
336
|
const { data } = useEnfyraApi('/dashboard', {
|
|
306
337
|
ssr: true,
|
|
307
|
-
key: 'dashboard'
|
|
338
|
+
key: 'dashboard' // Optional
|
|
308
339
|
});
|
|
309
340
|
|
|
310
|
-
// ✅ Use Client mode for user interactions
|
|
341
|
+
// ✅ Use Client mode for user interactions (manual execution)
|
|
311
342
|
const { execute: saveData } = useEnfyraApi('/settings', {
|
|
312
343
|
method: 'patch',
|
|
313
344
|
errorContext: 'Save Settings'
|
|
@@ -370,11 +401,11 @@ Pull requests are welcome! Please read our contributing guidelines and ensure te
|
|
|
370
401
|
|
|
371
402
|
## Changelog
|
|
372
403
|
|
|
373
|
-
See [CHANGELOG.md](
|
|
404
|
+
See [CHANGELOG.md](https://github.com/dothinh115/enfyra-sdk-nuxt/blob/main/CHANGELOG.md) for a detailed history of changes and migration guides.
|
|
374
405
|
|
|
375
406
|
## Support
|
|
376
407
|
|
|
377
408
|
For issues and questions:
|
|
378
|
-
- 📖 Check the [detailed documentation](
|
|
379
|
-
- 🐛 [Report bugs](https://github.com/enfyra
|
|
380
|
-
- 💬 [
|
|
409
|
+
- 📖 Check the [detailed documentation](https://github.com/dothinh115/enfyra-sdk-nuxt/blob/main/docs/useEnfyraApi.md)
|
|
410
|
+
- 🐛 [Report bugs](https://github.com/dothinh115/enfyra-sdk-nuxt/issues)
|
|
411
|
+
- 💬 [GitHub Discussions](https://github.com/dothinh115/enfyra-sdk-nuxt/discussions)
|
|
@@ -1,2 +1,12 @@
|
|
|
1
|
-
import type { ApiOptions,
|
|
2
|
-
|
|
1
|
+
import type { ApiOptions, UseEnfyraApiSSRReturn, UseEnfyraApiClientReturn } from "../types";
|
|
2
|
+
|
|
3
|
+
// Function overloads for proper TypeScript support
|
|
4
|
+
export declare function useEnfyraApi<T = any>(
|
|
5
|
+
path: (() => string) | string,
|
|
6
|
+
opts: ApiOptions<T> & { ssr: true }
|
|
7
|
+
): UseEnfyraApiSSRReturn<T>;
|
|
8
|
+
|
|
9
|
+
export declare function useEnfyraApi<T = any>(
|
|
10
|
+
path: (() => string) | string,
|
|
11
|
+
opts?: ApiOptions<T> & { ssr?: false | undefined }
|
|
12
|
+
): UseEnfyraApiClientReturn<T>;
|
|
@@ -1,39 +1,22 @@
|
|
|
1
1
|
import { ref, unref, toRaw } from "vue";
|
|
2
2
|
import { $fetch } from "../utils/http";
|
|
3
3
|
import { useRuntimeConfig, useFetch, useRequestHeaders } from "#imports";
|
|
4
|
-
function
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
message = responseData.message || "Request failed";
|
|
16
|
-
}
|
|
17
|
-
} else if (error?.data) {
|
|
18
|
-
const errorData = error.data;
|
|
19
|
-
if (errorData.error) {
|
|
20
|
-
message = errorData.error.message || errorData.message || "Request failed";
|
|
21
|
-
errorCode = errorData.error.code;
|
|
22
|
-
correlationId = errorData.error.correlationId;
|
|
23
|
-
} else {
|
|
24
|
-
message = errorData.message || "Request failed";
|
|
25
|
-
}
|
|
26
|
-
} else if (error?.message) {
|
|
27
|
-
message = error.message;
|
|
4
|
+
function handleError(error, context, customHandler) {
|
|
5
|
+
const apiError = {
|
|
6
|
+
message: error?.message || error?.data?.message || "Request failed",
|
|
7
|
+
status: error?.status || error?.response?.status,
|
|
8
|
+
data: error?.data || error?.response?.data,
|
|
9
|
+
response: error?.response || error
|
|
10
|
+
};
|
|
11
|
+
if (customHandler) {
|
|
12
|
+
customHandler(apiError, context);
|
|
13
|
+
} else {
|
|
14
|
+
console.error(`[Enfyra API Error]`, { error: apiError, context });
|
|
28
15
|
}
|
|
29
|
-
|
|
30
|
-
context,
|
|
31
|
-
correlationId,
|
|
32
|
-
error
|
|
33
|
-
});
|
|
16
|
+
return apiError;
|
|
34
17
|
}
|
|
35
18
|
export function useEnfyraApi(path, opts = {}) {
|
|
36
|
-
const { method = "get", body, query, errorContext, ssr, key } = opts;
|
|
19
|
+
const { method = "get", body, query, errorContext, onError, ssr, key, batchSize, concurrent } = opts;
|
|
37
20
|
if (ssr) {
|
|
38
21
|
const config = useRuntimeConfig().public.enfyraSDK;
|
|
39
22
|
const basePath = (typeof path === "function" ? path() : path).replace(/^\/?api\/?/, "").replace(/^\/+/, "");
|
|
@@ -82,12 +65,38 @@ export function useEnfyraApi(path, opts = {}) {
|
|
|
82
65
|
const basePath = (typeof path === "function" ? path() : path).replace(/^\/?api\/?/, "").replace(/^\/+/, "");
|
|
83
66
|
const finalBody = executeOpts?.body || unref(body);
|
|
84
67
|
const finalQuery = unref(query);
|
|
68
|
+
const effectiveBatchSize = executeOpts?.batchSize ?? batchSize;
|
|
69
|
+
const effectiveConcurrent = executeOpts?.concurrent ?? concurrent;
|
|
85
70
|
const buildPath = (...segments) => {
|
|
86
71
|
return segments.filter(Boolean).join("/");
|
|
87
72
|
};
|
|
88
73
|
const fullBaseURL = apiUrl + (apiPrefix || "");
|
|
74
|
+
async function processBatch(items, processor) {
|
|
75
|
+
const results = [];
|
|
76
|
+
if (!effectiveBatchSize && !effectiveConcurrent) {
|
|
77
|
+
const promises = items.map(processor);
|
|
78
|
+
return await Promise.all(promises);
|
|
79
|
+
}
|
|
80
|
+
const chunks = effectiveBatchSize ? Array.from(
|
|
81
|
+
{ length: Math.ceil(items.length / effectiveBatchSize) },
|
|
82
|
+
(_, i) => items.slice(i * effectiveBatchSize, i * effectiveBatchSize + effectiveBatchSize)
|
|
83
|
+
) : [items];
|
|
84
|
+
for (const chunk of chunks) {
|
|
85
|
+
if (effectiveConcurrent && chunk.length > effectiveConcurrent) {
|
|
86
|
+
for (let i = 0; i < chunk.length; i += effectiveConcurrent) {
|
|
87
|
+
const batch = chunk.slice(i, i + effectiveConcurrent);
|
|
88
|
+
const batchResults = await Promise.all(batch.map(processor));
|
|
89
|
+
results.push(...batchResults);
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
const chunkResults = await Promise.all(chunk.map(processor));
|
|
93
|
+
results.push(...chunkResults);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return results;
|
|
97
|
+
}
|
|
89
98
|
if (!opts.disableBatch && executeOpts?.ids && executeOpts.ids.length > 0 && (method.toLowerCase() === "patch" || method.toLowerCase() === "delete")) {
|
|
90
|
-
const
|
|
99
|
+
const responses = await processBatch(executeOpts.ids, async (id) => {
|
|
91
100
|
const finalPath2 = buildPath(basePath, id);
|
|
92
101
|
return $fetch(finalPath2, {
|
|
93
102
|
baseURL: fullBaseURL,
|
|
@@ -97,12 +106,11 @@ export function useEnfyraApi(path, opts = {}) {
|
|
|
97
106
|
query: finalQuery
|
|
98
107
|
});
|
|
99
108
|
});
|
|
100
|
-
const responses = await Promise.all(promises);
|
|
101
109
|
data.value = responses;
|
|
102
110
|
return responses;
|
|
103
111
|
}
|
|
104
112
|
if (!opts.disableBatch && method.toLowerCase() === "post" && executeOpts?.files && Array.isArray(executeOpts.files) && executeOpts.files.length > 0) {
|
|
105
|
-
const
|
|
113
|
+
const responses = await processBatch(executeOpts.files, async (fileObj) => {
|
|
106
114
|
return $fetch(basePath, {
|
|
107
115
|
baseURL: fullBaseURL,
|
|
108
116
|
method,
|
|
@@ -112,7 +120,6 @@ export function useEnfyraApi(path, opts = {}) {
|
|
|
112
120
|
query: finalQuery
|
|
113
121
|
});
|
|
114
122
|
});
|
|
115
|
-
const responses = await Promise.all(promises);
|
|
116
123
|
data.value = responses;
|
|
117
124
|
return responses;
|
|
118
125
|
}
|
|
@@ -127,8 +134,8 @@ export function useEnfyraApi(path, opts = {}) {
|
|
|
127
134
|
data.value = response;
|
|
128
135
|
return response;
|
|
129
136
|
} catch (err) {
|
|
130
|
-
|
|
131
|
-
|
|
137
|
+
const apiError = handleError(err, errorContext, onError);
|
|
138
|
+
error.value = apiError;
|
|
132
139
|
return null;
|
|
133
140
|
} finally {
|
|
134
141
|
pending.value = false;
|
package/dist/composables.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Ref, ComputedRef } from 'vue';
|
|
2
|
-
import type { LoginPayload, User, ApiOptions,
|
|
2
|
+
import type { LoginPayload, User, ApiOptions, UseEnfyraApiSSRReturn, UseEnfyraApiClientReturn } from './index';
|
|
3
|
+
|
|
3
4
|
export declare function useEnfyraAuth(): {
|
|
4
5
|
me: Ref<User | null>;
|
|
5
6
|
login: (payload: LoginPayload) => Promise<any>;
|
|
@@ -7,5 +8,14 @@ export declare function useEnfyraAuth(): {
|
|
|
7
8
|
fetchUser: () => Promise<void>;
|
|
8
9
|
isLoggedIn: ComputedRef<boolean>;
|
|
9
10
|
};
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
// Function overloads for proper TypeScript support
|
|
13
|
+
export declare function useEnfyraApi<T = any>(
|
|
14
|
+
path: (() => string) | string,
|
|
15
|
+
opts: ApiOptions<T> & { ssr: true }
|
|
16
|
+
): UseEnfyraApiSSRReturn<T>;
|
|
17
|
+
|
|
18
|
+
export declare function useEnfyraApi<T = any>(
|
|
19
|
+
path: (() => string) | string,
|
|
20
|
+
opts?: ApiOptions<T> & { ssr?: false | undefined }
|
|
21
|
+
): UseEnfyraApiClientReturn<T>;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,13 +3,24 @@ export interface EnfyraConfig {
|
|
|
3
3
|
apiPrefix?: string;
|
|
4
4
|
defaultHeaders?: Record<string, string>;
|
|
5
5
|
}
|
|
6
|
+
export interface ApiError {
|
|
7
|
+
message: string;
|
|
8
|
+
status?: number;
|
|
9
|
+
data?: any;
|
|
10
|
+
response?: any;
|
|
11
|
+
}
|
|
6
12
|
export interface ApiOptions<T> {
|
|
7
13
|
method?: 'get' | 'post' | 'put' | 'patch' | 'delete' | 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
8
14
|
body?: any;
|
|
9
15
|
query?: Record<string, any>;
|
|
10
16
|
headers?: Record<string, string>;
|
|
11
17
|
errorContext?: string;
|
|
18
|
+
onError?: (error: ApiError, context?: string) => void;
|
|
12
19
|
disableBatch?: boolean;
|
|
20
|
+
/** Batch size for chunking large operations (default: no limit) */
|
|
21
|
+
batchSize?: number;
|
|
22
|
+
/** Maximum concurrent requests (default: no limit) */
|
|
23
|
+
concurrent?: number;
|
|
13
24
|
default?: () => T;
|
|
14
25
|
/** Enable SSR with useFetch instead of $fetch */
|
|
15
26
|
ssr?: boolean;
|
|
@@ -32,17 +43,29 @@ export interface BackendErrorExtended extends BackendError {
|
|
|
32
43
|
};
|
|
33
44
|
}
|
|
34
45
|
import type { Ref } from 'vue';
|
|
35
|
-
|
|
46
|
+
import type { AsyncData } from 'nuxt/app';
|
|
47
|
+
export interface UseEnfyraApiSSRReturn<T> extends AsyncData<T | null, ApiError> {
|
|
48
|
+
data: Ref<T | null>;
|
|
49
|
+
pending: Ref<boolean>;
|
|
50
|
+
error: Ref<ApiError | null>;
|
|
51
|
+
refresh: () => Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
export interface ExecuteOptions {
|
|
54
|
+
body?: any;
|
|
55
|
+
id?: string | number;
|
|
56
|
+
ids?: (string | number)[];
|
|
57
|
+
/** Array of FormData objects for batch upload */
|
|
58
|
+
files?: FormData[];
|
|
59
|
+
/** Override batch size for this specific execution */
|
|
60
|
+
batchSize?: number;
|
|
61
|
+
/** Override concurrent limit for this specific execution */
|
|
62
|
+
concurrent?: number;
|
|
63
|
+
}
|
|
64
|
+
export interface UseEnfyraApiClientReturn<T> {
|
|
36
65
|
data: Ref<T | null>;
|
|
37
|
-
error: Ref<
|
|
66
|
+
error: Ref<ApiError | null>;
|
|
38
67
|
pending: Ref<boolean>;
|
|
39
|
-
execute: (executeOpts?:
|
|
40
|
-
body?: any;
|
|
41
|
-
id?: string | number;
|
|
42
|
-
ids?: (string | number)[];
|
|
43
|
-
files?: any[];
|
|
44
|
-
}) => Promise<T | T[] | null>;
|
|
68
|
+
execute: (executeOpts?: ExecuteOptions) => Promise<T | T[] | null>;
|
|
45
69
|
}
|
|
46
70
|
export * from './auth';
|
|
47
|
-
export * from './composables';
|
|
48
71
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACnG,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;IAClB,iDAAiD;IACjD,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,KAAK,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,GAAG,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB;AAED,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACnG,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACtD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;IAClB,iDAAiD;IACjD,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,KAAK,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,GAAG,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG1C,MAAM,WAAW,qBAAqB,CAAC,CAAC,CAAE,SAAQ,SAAS,CAAC,CAAC,GAAG,IAAI,EAAE,QAAQ,CAAC;IAC7E,IAAI,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACpB,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACtB,KAAK,EAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC5B,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAGD,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC1B,iDAAiD;IACjD,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAGD,MAAM,WAAW,wBAAwB,CAAC,CAAC;IACzC,IAAI,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACpB,KAAK,EAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC5B,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACtB,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;CACpE;AAID,cAAc,QAAQ,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/module.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enfyra/sdk-nuxt",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Nuxt SDK for Enfyra CMS",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/dothinh115/enfyra-sdk-nuxt.git"
|
|
8
|
+
},
|
|
9
|
+
"bugs": {
|
|
10
|
+
"url": "https://github.com/dothinh115/enfyra-sdk-nuxt/issues"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/dothinh115/enfyra-sdk-nuxt#readme",
|
|
5
13
|
"main": "./dist/module.mjs",
|
|
6
14
|
"types": "./dist/index.d.ts",
|
|
7
15
|
"exports": {
|
|
@@ -1,56 +1,53 @@
|
|
|
1
1
|
import { ref, unref, toRaw } from "vue";
|
|
2
2
|
import type {
|
|
3
3
|
ApiOptions,
|
|
4
|
+
ApiError,
|
|
4
5
|
BackendErrorExtended,
|
|
5
|
-
|
|
6
|
+
ExecuteOptions,
|
|
7
|
+
UseEnfyraApiSSRReturn,
|
|
8
|
+
UseEnfyraApiClientReturn,
|
|
6
9
|
} from "../types";
|
|
7
10
|
import { $fetch } from "../utils/http";
|
|
8
11
|
import { useRuntimeConfig, useFetch, useRequestHeaders } from "#imports";
|
|
9
12
|
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const errorData = error.data as BackendErrorExtended;
|
|
28
|
-
if (errorData.error) {
|
|
29
|
-
message =
|
|
30
|
-
errorData.error.message || errorData.message || "Request failed";
|
|
31
|
-
errorCode = errorData.error.code;
|
|
32
|
-
correlationId = errorData.error.correlationId;
|
|
33
|
-
} else {
|
|
34
|
-
message = errorData.message || "Request failed";
|
|
35
|
-
}
|
|
36
|
-
} else if (error?.message) {
|
|
37
|
-
message = error.message;
|
|
13
|
+
function handleError(
|
|
14
|
+
error: any,
|
|
15
|
+
context?: string,
|
|
16
|
+
customHandler?: (error: ApiError, context?: string) => void
|
|
17
|
+
) {
|
|
18
|
+
// Transform error to ApiError format
|
|
19
|
+
const apiError: ApiError = {
|
|
20
|
+
message: error?.message || error?.data?.message || "Request failed",
|
|
21
|
+
status: error?.status || error?.response?.status,
|
|
22
|
+
data: error?.data || error?.response?.data,
|
|
23
|
+
response: error?.response || error
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
if (customHandler) {
|
|
27
|
+
customHandler(apiError, context);
|
|
28
|
+
} else {
|
|
29
|
+
console.error(`[Enfyra API Error]`, { error: apiError, context });
|
|
38
30
|
}
|
|
39
31
|
|
|
40
|
-
|
|
41
|
-
// For now, just log the error
|
|
42
|
-
console.error(`[Enfyra API Error] ${errorCode}: ${message}`, {
|
|
43
|
-
context,
|
|
44
|
-
correlationId,
|
|
45
|
-
error,
|
|
46
|
-
});
|
|
32
|
+
return apiError;
|
|
47
33
|
}
|
|
48
34
|
|
|
35
|
+
// Function overloads for proper TypeScript support
|
|
36
|
+
export function useEnfyraApi<T = any>(
|
|
37
|
+
path: (() => string) | string,
|
|
38
|
+
opts: ApiOptions<T> & { ssr: true }
|
|
39
|
+
): UseEnfyraApiSSRReturn<T>;
|
|
40
|
+
|
|
41
|
+
export function useEnfyraApi<T = any>(
|
|
42
|
+
path: (() => string) | string,
|
|
43
|
+
opts?: ApiOptions<T> & { ssr?: false | undefined }
|
|
44
|
+
): UseEnfyraApiClientReturn<T>;
|
|
45
|
+
|
|
49
46
|
export function useEnfyraApi<T = any>(
|
|
50
47
|
path: (() => string) | string,
|
|
51
48
|
opts: ApiOptions<T> = {}
|
|
52
|
-
):
|
|
53
|
-
const { method = "get", body, query, errorContext, ssr, key } = opts;
|
|
49
|
+
): UseEnfyraApiSSRReturn<T> | UseEnfyraApiClientReturn<T> {
|
|
50
|
+
const { method = "get", body, query, errorContext, onError, ssr, key, batchSize, concurrent } = opts;
|
|
54
51
|
|
|
55
52
|
// SSR mode - use useFetch
|
|
56
53
|
if (ssr) {
|
|
@@ -99,18 +96,13 @@ export function useEnfyraApi<T = any>(
|
|
|
99
96
|
fetchOptions.default = opts.default;
|
|
100
97
|
}
|
|
101
98
|
|
|
102
|
-
return useFetch<T>(finalUrl, fetchOptions) as
|
|
99
|
+
return useFetch<T>(finalUrl, fetchOptions) as UseEnfyraApiSSRReturn<T>;
|
|
103
100
|
}
|
|
104
101
|
const data = ref<T | null>(null);
|
|
105
|
-
const error = ref<
|
|
102
|
+
const error = ref<ApiError | null>(null);
|
|
106
103
|
const pending = ref(false);
|
|
107
104
|
|
|
108
|
-
const execute = async (executeOpts?: {
|
|
109
|
-
body?: any;
|
|
110
|
-
id?: string | number;
|
|
111
|
-
ids?: (string | number)[];
|
|
112
|
-
files?: any[];
|
|
113
|
-
}) => {
|
|
105
|
+
const execute = async (executeOpts?: ExecuteOptions) => {
|
|
114
106
|
pending.value = true;
|
|
115
107
|
error.value = null;
|
|
116
108
|
|
|
@@ -124,6 +116,10 @@ export function useEnfyraApi<T = any>(
|
|
|
124
116
|
.replace(/^\/+/, ""); // Remove leading slashes
|
|
125
117
|
const finalBody = executeOpts?.body || unref(body);
|
|
126
118
|
const finalQuery = unref(query);
|
|
119
|
+
|
|
120
|
+
// Use executeOpts overrides if provided, otherwise fall back to options
|
|
121
|
+
const effectiveBatchSize = executeOpts?.batchSize ?? batchSize;
|
|
122
|
+
const effectiveConcurrent = executeOpts?.concurrent ?? concurrent;
|
|
127
123
|
|
|
128
124
|
// Helper function to build clean path
|
|
129
125
|
const buildPath = (...segments: (string | number)[]): string => {
|
|
@@ -133,6 +129,44 @@ export function useEnfyraApi<T = any>(
|
|
|
133
129
|
// Build full base URL with prefix
|
|
134
130
|
const fullBaseURL = apiUrl + (apiPrefix || "");
|
|
135
131
|
|
|
132
|
+
// Helper function for batch processing with chunking and concurrency control
|
|
133
|
+
async function processBatch<T>(
|
|
134
|
+
items: any[],
|
|
135
|
+
processor: (item: any) => Promise<T>
|
|
136
|
+
): Promise<T[]> {
|
|
137
|
+
const results: T[] = [];
|
|
138
|
+
|
|
139
|
+
// If no limits, process all at once (current behavior)
|
|
140
|
+
if (!effectiveBatchSize && !effectiveConcurrent) {
|
|
141
|
+
const promises = items.map(processor);
|
|
142
|
+
return await Promise.all(promises);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Chunk items by batchSize
|
|
146
|
+
const chunks = effectiveBatchSize ?
|
|
147
|
+
Array.from({ length: Math.ceil(items.length / effectiveBatchSize) }, (_, i) =>
|
|
148
|
+
items.slice(i * effectiveBatchSize, i * effectiveBatchSize + effectiveBatchSize)
|
|
149
|
+
) : [items];
|
|
150
|
+
|
|
151
|
+
// Process each chunk
|
|
152
|
+
for (const chunk of chunks) {
|
|
153
|
+
if (effectiveConcurrent && chunk.length > effectiveConcurrent) {
|
|
154
|
+
// Process chunk with concurrency limit
|
|
155
|
+
for (let i = 0; i < chunk.length; i += effectiveConcurrent) {
|
|
156
|
+
const batch = chunk.slice(i, i + effectiveConcurrent);
|
|
157
|
+
const batchResults = await Promise.all(batch.map(processor));
|
|
158
|
+
results.push(...batchResults);
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
// Process entire chunk at once
|
|
162
|
+
const chunkResults = await Promise.all(chunk.map(processor));
|
|
163
|
+
results.push(...chunkResults);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return results;
|
|
168
|
+
}
|
|
169
|
+
|
|
136
170
|
// Batch operation with multiple IDs (only for patch and delete)
|
|
137
171
|
if (
|
|
138
172
|
!opts.disableBatch &&
|
|
@@ -140,7 +174,7 @@ export function useEnfyraApi<T = any>(
|
|
|
140
174
|
executeOpts.ids.length > 0 &&
|
|
141
175
|
(method.toLowerCase() === "patch" || method.toLowerCase() === "delete")
|
|
142
176
|
) {
|
|
143
|
-
const
|
|
177
|
+
const responses = await processBatch(executeOpts.ids, async (id) => {
|
|
144
178
|
const finalPath = buildPath(basePath, id);
|
|
145
179
|
return $fetch<T>(finalPath, {
|
|
146
180
|
baseURL: fullBaseURL,
|
|
@@ -151,7 +185,6 @@ export function useEnfyraApi<T = any>(
|
|
|
151
185
|
});
|
|
152
186
|
});
|
|
153
187
|
|
|
154
|
-
const responses = await Promise.all(promises);
|
|
155
188
|
data.value = responses as T;
|
|
156
189
|
return responses;
|
|
157
190
|
}
|
|
@@ -164,7 +197,7 @@ export function useEnfyraApi<T = any>(
|
|
|
164
197
|
Array.isArray(executeOpts.files) &&
|
|
165
198
|
executeOpts.files.length > 0
|
|
166
199
|
) {
|
|
167
|
-
const
|
|
200
|
+
const responses = await processBatch(executeOpts.files, async (fileObj: any) => {
|
|
168
201
|
return $fetch<T>(basePath, {
|
|
169
202
|
baseURL: fullBaseURL,
|
|
170
203
|
method: method as any,
|
|
@@ -174,7 +207,6 @@ export function useEnfyraApi<T = any>(
|
|
|
174
207
|
});
|
|
175
208
|
});
|
|
176
209
|
|
|
177
|
-
const responses = await Promise.all(promises);
|
|
178
210
|
data.value = responses as T;
|
|
179
211
|
return responses;
|
|
180
212
|
}
|
|
@@ -195,8 +227,8 @@ export function useEnfyraApi<T = any>(
|
|
|
195
227
|
data.value = response;
|
|
196
228
|
return response;
|
|
197
229
|
} catch (err) {
|
|
198
|
-
|
|
199
|
-
|
|
230
|
+
const apiError = handleError(err, errorContext, onError);
|
|
231
|
+
error.value = apiError;
|
|
200
232
|
return null;
|
|
201
233
|
} finally {
|
|
202
234
|
pending.value = false;
|
|
@@ -204,9 +236,9 @@ export function useEnfyraApi<T = any>(
|
|
|
204
236
|
};
|
|
205
237
|
|
|
206
238
|
return {
|
|
207
|
-
data
|
|
239
|
+
data,
|
|
208
240
|
error,
|
|
209
241
|
pending,
|
|
210
242
|
execute,
|
|
211
|
-
}
|
|
243
|
+
} as UseEnfyraApiClientReturn<T>;
|
|
212
244
|
}
|
package/src/types/index.ts
CHANGED
|
@@ -4,13 +4,25 @@ export interface EnfyraConfig {
|
|
|
4
4
|
defaultHeaders?: Record<string, string>;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
export interface ApiError {
|
|
8
|
+
message: string;
|
|
9
|
+
status?: number;
|
|
10
|
+
data?: any;
|
|
11
|
+
response?: any;
|
|
12
|
+
}
|
|
13
|
+
|
|
7
14
|
export interface ApiOptions<T> {
|
|
8
15
|
method?: 'get' | 'post' | 'put' | 'patch' | 'delete' | 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
9
16
|
body?: any;
|
|
10
17
|
query?: Record<string, any>;
|
|
11
18
|
headers?: Record<string, string>;
|
|
12
19
|
errorContext?: string;
|
|
20
|
+
onError?: (error: ApiError, context?: string) => void;
|
|
13
21
|
disableBatch?: boolean;
|
|
22
|
+
/** Batch size for chunking large operations (default: no limit) */
|
|
23
|
+
batchSize?: number;
|
|
24
|
+
/** Maximum concurrent requests (default: no limit) */
|
|
25
|
+
concurrent?: number;
|
|
14
26
|
default?: () => T;
|
|
15
27
|
/** Enable SSR with useFetch instead of $fetch */
|
|
16
28
|
ssr?: boolean;
|
|
@@ -36,21 +48,38 @@ export interface BackendErrorExtended extends BackendError {
|
|
|
36
48
|
}
|
|
37
49
|
|
|
38
50
|
import type { Ref } from 'vue';
|
|
51
|
+
import type { AsyncData } from 'nuxt/app';
|
|
39
52
|
|
|
40
|
-
|
|
53
|
+
// SSR Mode return type (same as useFetch)
|
|
54
|
+
export interface UseEnfyraApiSSRReturn<T> extends AsyncData<T | null, ApiError> {
|
|
41
55
|
data: Ref<T | null>;
|
|
42
|
-
error: Ref<any>;
|
|
43
56
|
pending: Ref<boolean>;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
57
|
+
error: Ref<ApiError | null>;
|
|
58
|
+
refresh: () => Promise<void>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Execute options interface
|
|
62
|
+
export interface ExecuteOptions {
|
|
63
|
+
body?: any;
|
|
64
|
+
id?: string | number;
|
|
65
|
+
ids?: (string | number)[];
|
|
66
|
+
/** Array of FormData objects for batch upload */
|
|
67
|
+
files?: FormData[];
|
|
68
|
+
/** Override batch size for this specific execution */
|
|
69
|
+
batchSize?: number;
|
|
70
|
+
/** Override concurrent limit for this specific execution */
|
|
71
|
+
concurrent?: number;
|
|
50
72
|
}
|
|
51
73
|
|
|
74
|
+
// Client Mode return type
|
|
75
|
+
export interface UseEnfyraApiClientReturn<T> {
|
|
76
|
+
data: Ref<T | null>;
|
|
77
|
+
error: Ref<ApiError | null>;
|
|
78
|
+
pending: Ref<boolean>;
|
|
79
|
+
execute: (executeOpts?: ExecuteOptions) => Promise<T | T[] | null>;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
52
83
|
// Re-export auth types
|
|
53
84
|
export * from './auth';
|
|
54
85
|
|
|
55
|
-
// Re-export composables types
|
|
56
|
-
export * from './composables';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"composables.d.ts","sourceRoot":"","sources":["../src/types/composables.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAEjF,MAAM,CAAC,OAAO,UAAU,aAAa,IAAI;IACvC,EAAE,EAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;IACpB,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IAC9C,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3B,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9B,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;CACjC,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,CAAC,GAAG,GAAG,EAC1C,IAAI,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,MAAM,EAC7B,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,GACnB,kBAAkB,CAAC,CAAC,CAAC,CAAA"}
|
package/dist/composables.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/src/types/composables.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Ref, ComputedRef } from 'vue'
|
|
2
|
-
import type { LoginPayload, User, ApiOptions, UseEnfyraApiReturn } from './index'
|
|
3
|
-
|
|
4
|
-
export declare function useEnfyraAuth(): {
|
|
5
|
-
me: Ref<User | null>
|
|
6
|
-
login: (payload: LoginPayload) => Promise<any>
|
|
7
|
-
logout: () => Promise<void>
|
|
8
|
-
fetchUser: () => Promise<void>
|
|
9
|
-
isLoggedIn: ComputedRef<boolean>
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export declare function useEnfyraApi<T = any>(
|
|
13
|
-
path: (() => string) | string,
|
|
14
|
-
opts?: ApiOptions<T>
|
|
15
|
-
): UseEnfyraApiReturn<T>
|