@enfyra/sdk-nuxt 0.3.23 → 0.3.25
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 +155 -328
- package/dist/module.cjs +7 -12
- package/dist/module.d.ts.map +1 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +7 -12
- package/dist/runtime/composables/useEnfyra.d.ts +6 -0
- package/dist/runtime/composables/useEnfyra.d.ts.map +1 -0
- package/dist/runtime/composables/useEnfyra.js +13 -0
- package/dist/runtime/composables/useEnfyraAuth.d.ts +2 -88
- package/dist/runtime/composables/useEnfyraAuth.d.ts.map +1 -1
- package/dist/runtime/composables/useEnfyraAuth.js +38 -45
- package/package.json +1 -1
- package/src/module.ts +7 -12
- package/src/runtime/composables/useEnfyra.ts +21 -0
- package/src/runtime/composables/useEnfyraAuth.ts +42 -52
- package/dist/runtime/composables/useEnfyraApi.d.ts +0 -8
- package/dist/runtime/composables/useEnfyraApi.d.ts.map +0 -1
- package/dist/runtime/composables/useEnfyraApi.js +0 -351
- package/dist/runtime/utils/http.d.ts +0 -8
- package/dist/runtime/utils/http.d.ts.map +0 -1
- package/dist/runtime/utils/http.js +0 -61
- package/src/runtime/composables/useEnfyraApi.ts +0 -483
- package/src/runtime/utils/http.ts +0 -78
package/README.md
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
# @enfyra/sdk-nuxt
|
|
2
2
|
|
|
3
|
-
Nuxt SDK for Enfyra CMS - A
|
|
3
|
+
Nuxt SDK for Enfyra CMS - A lightweight composable-based API client with full TypeScript integration.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
✅ **
|
|
7
|
+
✅ **Simple & Flexible** - Get base URL and build your own composables
|
|
8
8
|
✅ **Authentication Integration** - Built-in auth composables with automatic header forwarding
|
|
9
9
|
✅ **Asset Proxy** - Automatic `/assets/**` proxy to backend with no configuration needed
|
|
10
10
|
✅ **TypeScript Support** - Full type safety with auto-generated declarations
|
|
11
|
-
✅ **
|
|
12
|
-
✅ **Error Handling** - Automatic error management with console logging
|
|
13
|
-
✅ **Reactive State** - Built-in loading, error, and data states
|
|
14
|
-
✅ **Caching Support** - Optional cache keys for SSR mode optimization
|
|
11
|
+
✅ **SSR Ready** - Works seamlessly with Nuxt's `useFetch` and `$fetch`
|
|
15
12
|
|
|
16
13
|
## Installation
|
|
17
14
|
|
|
@@ -42,14 +39,25 @@ The SDK automatically detects your application URL:
|
|
|
42
39
|
|
|
43
40
|
## Quick Start
|
|
44
41
|
|
|
45
|
-
###
|
|
42
|
+
### Get Base URL
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// Get the base URL for your API requests
|
|
46
|
+
const { baseUrl, apiPrefix } = useEnfyra();
|
|
47
|
+
|
|
48
|
+
// baseUrl: "http://localhost:3001/enfyra/api"
|
|
49
|
+
// apiPrefix: "/enfyra/api"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Using with `useFetch` (SSR)
|
|
46
53
|
|
|
47
54
|
```typescript
|
|
48
55
|
// pages/users.vue
|
|
49
56
|
<script setup>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
57
|
+
const { baseUrl } = useEnfyra();
|
|
58
|
+
|
|
59
|
+
// Use with Nuxt's useFetch for SSR support
|
|
60
|
+
const { data: users, pending, error, refresh } = await useFetch(`${baseUrl}/users`, {
|
|
53
61
|
key: 'users-list' // Optional cache key
|
|
54
62
|
});
|
|
55
63
|
</script>
|
|
@@ -67,16 +75,14 @@ const { data: users, pending, error, refresh } = useEnfyraApi('/users', {
|
|
|
67
75
|
</template>
|
|
68
76
|
```
|
|
69
77
|
|
|
70
|
-
###
|
|
78
|
+
### Using with `$fetch` (Client)
|
|
71
79
|
|
|
72
80
|
```typescript
|
|
73
81
|
// components/CreateUserForm.vue
|
|
74
82
|
<script setup>
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
errorContext: 'Create User'
|
|
79
|
-
});
|
|
83
|
+
const { baseUrl } = useEnfyra();
|
|
84
|
+
const pending = ref(false);
|
|
85
|
+
const error = ref(null);
|
|
80
86
|
|
|
81
87
|
const formData = reactive({
|
|
82
88
|
name: '',
|
|
@@ -84,11 +90,22 @@ const formData = reactive({
|
|
|
84
90
|
});
|
|
85
91
|
|
|
86
92
|
async function handleSubmit() {
|
|
87
|
-
|
|
93
|
+
pending.value = true;
|
|
94
|
+
error.value = null;
|
|
88
95
|
|
|
89
|
-
|
|
96
|
+
try {
|
|
97
|
+
const response = await $fetch(`${baseUrl}/users`, {
|
|
98
|
+
method: 'POST',
|
|
99
|
+
body: formData
|
|
100
|
+
});
|
|
101
|
+
|
|
90
102
|
toast.success('User created successfully!');
|
|
91
103
|
await navigateTo('/users');
|
|
104
|
+
} catch (err) {
|
|
105
|
+
error.value = err;
|
|
106
|
+
toast.error('Failed to create user');
|
|
107
|
+
} finally {
|
|
108
|
+
pending.value = false;
|
|
92
109
|
}
|
|
93
110
|
}
|
|
94
111
|
</script>
|
|
@@ -98,7 +115,7 @@ async function handleSubmit() {
|
|
|
98
115
|
|
|
99
116
|
```typescript
|
|
100
117
|
<script setup>
|
|
101
|
-
const { me, login, logout, isLoggedIn } = useEnfyraAuth();
|
|
118
|
+
const { me, login, logout, fetchUser, isLoggedIn } = useEnfyraAuth();
|
|
102
119
|
|
|
103
120
|
// Login
|
|
104
121
|
await login({
|
|
@@ -110,6 +127,9 @@ await login({
|
|
|
110
127
|
console.log('Logged in:', isLoggedIn.value);
|
|
111
128
|
console.log('Current user:', me.value);
|
|
112
129
|
|
|
130
|
+
// Fetch user with optional fields
|
|
131
|
+
await fetchUser({ fields: ['id', 'email', 'role'] });
|
|
132
|
+
|
|
113
133
|
// Logout
|
|
114
134
|
await logout();
|
|
115
135
|
</script>
|
|
@@ -139,69 +159,20 @@ The SDK automatically proxies all asset requests to your backend. Simply use `/a
|
|
|
139
159
|
|
|
140
160
|
## Core Composables
|
|
141
161
|
|
|
142
|
-
### `
|
|
162
|
+
### `useEnfyra()`
|
|
143
163
|
|
|
144
|
-
|
|
164
|
+
Get the base URL and API prefix for building your own API requests.
|
|
145
165
|
|
|
146
166
|
```typescript
|
|
147
|
-
|
|
148
|
-
const { data, pending, error, refresh } = useEnfyraApi('/endpoint', {
|
|
149
|
-
ssr: true,
|
|
150
|
-
key: 'cache-key', // Optional
|
|
151
|
-
method: 'get',
|
|
152
|
-
query: { page: 1 }
|
|
153
|
-
});
|
|
154
|
-
// ⚠️ Returns useFetch result: { data, pending, error, refresh }
|
|
167
|
+
const { baseUrl, apiPrefix } = useEnfyra();
|
|
155
168
|
|
|
156
|
-
//
|
|
157
|
-
|
|
158
|
-
method: 'post',
|
|
159
|
-
errorContext: 'Create Resource'
|
|
160
|
-
});
|
|
161
|
-
// ⚠️ Returns custom result: { data, pending, error, execute }
|
|
162
|
-
|
|
163
|
-
await execute({
|
|
164
|
-
body: { name: 'New Item' },
|
|
165
|
-
id: '123' // For /endpoint/123
|
|
166
|
-
});
|
|
169
|
+
// baseUrl: "http://localhost:3001/enfyra/api"
|
|
170
|
+
// apiPrefix: "/enfyra/api"
|
|
167
171
|
```
|
|
168
172
|
|
|
169
|
-
**
|
|
170
|
-
- `
|
|
171
|
-
- `
|
|
172
|
-
- `body?: any` - Request body (POST/PATCH)
|
|
173
|
-
- `query?: Record<string, any>` - URL query parameters
|
|
174
|
-
- `headers?: Record<string, string>` - Custom headers
|
|
175
|
-
- `errorContext?: string` - Error context for logging
|
|
176
|
-
- `onError?: (error: ApiError, context?: string) => void` - Custom error handler
|
|
177
|
-
- `key?: string` - Cache key (SSR mode, optional)
|
|
178
|
-
- `default?: () => T` - Default value (SSR mode only)
|
|
179
|
-
|
|
180
|
-
**Batch Options (only available for PATCH, DELETE, and POST methods):**
|
|
181
|
-
- `batchSize?: number` - Batch size for chunking large operations (default: no limit)
|
|
182
|
-
- `concurrent?: number` - Maximum concurrent requests (default: no limit)
|
|
183
|
-
- `onProgress?: (progress: BatchProgress) => void` - Real-time progress callback for batch operations
|
|
184
|
-
|
|
185
|
-
> 🎯 **TypeScript Smart:** Batch options (`batchSize`, `concurrent`, `onProgress`) are only available in TypeScript IntelliSense when using methods that support batch operations (PATCH, DELETE, POST). For GET and PUT methods, these options won't appear in autocomplete.
|
|
186
|
-
|
|
187
|
-
**⚠️ Important: Return Types Differ**
|
|
188
|
-
- **SSR Mode**: Returns `useFetch` result `{ data, pending, error, refresh }`
|
|
189
|
-
- **Client Mode**: Returns custom result `{ data, pending, error, execute }`
|
|
190
|
-
|
|
191
|
-
**Execute Options (Client mode only):**
|
|
192
|
-
|
|
193
|
-
**Basic Options:**
|
|
194
|
-
- `id?: string | number` - Single resource ID
|
|
195
|
-
- `body?: any` - Override request body
|
|
196
|
-
|
|
197
|
-
**Batch Options (only when using `ids` or `files`):**
|
|
198
|
-
- `ids?: (string | number)[]` - Batch operation IDs (PATCH/DELETE)
|
|
199
|
-
- `files?: FormData[]` - Array of FormData objects for batch upload (POST)
|
|
200
|
-
- `batchSize?: number` - Override batch size for this execution
|
|
201
|
-
- `concurrent?: number` - Override concurrent limit for this execution
|
|
202
|
-
- `onProgress?: (progress: BatchProgress) => void` - Override progress callback for this execution
|
|
203
|
-
|
|
204
|
-
> 🎯 **TypeScript Smart:** Batch execute options (`batchSize`, `concurrent`, `onProgress`) are only available when you provide `ids` or `files` parameters, ensuring type safety.
|
|
173
|
+
**Returns:**
|
|
174
|
+
- `baseUrl: string` - Full base URL including app URL and API prefix
|
|
175
|
+
- `apiPrefix: string` - API prefix path (e.g., "/enfyra/api")
|
|
205
176
|
|
|
206
177
|
### `useEnfyraAuth()`
|
|
207
178
|
|
|
@@ -215,174 +186,78 @@ me.value // Current user data (reactive)
|
|
|
215
186
|
isLoggedIn.value // Auth status (computed)
|
|
216
187
|
|
|
217
188
|
// Methods
|
|
218
|
-
await login({ email, password })
|
|
219
|
-
await logout()
|
|
220
|
-
await fetchUser()
|
|
189
|
+
await login({ email, password }) // Login user
|
|
190
|
+
await logout() // Logout user
|
|
191
|
+
await fetchUser({ fields?: string[] }) // Refresh user data with optional fields
|
|
221
192
|
```
|
|
222
193
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
### Batch Operations
|
|
226
|
-
|
|
194
|
+
**Login:**
|
|
227
195
|
```typescript
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
errorContext: 'Delete Items'
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
await deleteItems({ ids: ['1', '2', '3'] });
|
|
236
|
-
|
|
237
|
-
// Advanced batch operations with concurrency control
|
|
238
|
-
// 🎯 TypeScript shows batch options (batchSize, concurrent, onProgress) for DELETE method
|
|
239
|
-
const { execute: deleteMany } = useEnfyraApi('/users', {
|
|
240
|
-
method: 'delete',
|
|
241
|
-
batchSize: 10, // ✅ Available: DELETE method supports batching
|
|
242
|
-
concurrent: 3, // ✅ Available: DELETE method supports batching
|
|
243
|
-
onProgress: (progress) => { // ✅ Available: DELETE method supports batching
|
|
244
|
-
console.log(`Deleting: ${progress.completed}/${progress.total}`);
|
|
245
|
-
},
|
|
246
|
-
onError: (error, context) => toast.error(`${context}: ${error.message}`)
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
// GET method example - batch options NOT available
|
|
250
|
-
// 🎯 TypeScript won't show batch options for GET method
|
|
251
|
-
const { execute: getUsers } = useEnfyraApi('/users', {
|
|
252
|
-
method: 'get',
|
|
253
|
-
// batchSize: 10, // ❌ Not available: GET doesn't support batching
|
|
254
|
-
// concurrent: 3, // ❌ Not available: GET doesn't support batching
|
|
255
|
-
// onProgress: () => {} // ❌ Not available: GET doesn't support batching
|
|
256
|
-
errorContext: 'Fetch Users'
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
// Delete 100 users in controlled batches
|
|
260
|
-
await deleteMany({ ids: Array.from({length: 100}, (_, i) => `user-${i}`) });
|
|
261
|
-
|
|
262
|
-
// Override batch settings per execution
|
|
263
|
-
// 🎯 TypeScript shows batch options for PATCH method
|
|
264
|
-
const { execute: updateUsers } = useEnfyraApi('/users', {
|
|
265
|
-
method: 'patch',
|
|
266
|
-
batchSize: 20, // ✅ Available: PATCH method supports batching
|
|
267
|
-
concurrent: 5 // ✅ Available: PATCH method supports batching
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
// This execution uses different settings
|
|
271
|
-
// 🎯 Batch options in execute() only available when using `ids` or `files`
|
|
272
|
-
await updateUsers({
|
|
273
|
-
ids: largeUserList, // ✅ Triggers batch mode
|
|
274
|
-
body: { status: 'active' },
|
|
275
|
-
batchSize: 50, // ✅ Available: Using `ids` parameter
|
|
276
|
-
concurrent: 10, // ✅ Available: Using `ids` parameter
|
|
277
|
-
onProgress: (progress) => { // ✅ Available: Using `ids` parameter
|
|
278
|
-
console.log(`Updating: ${progress.completed}/${progress.total}`);
|
|
279
|
-
}
|
|
196
|
+
const response = await login({
|
|
197
|
+
email: 'user@example.com',
|
|
198
|
+
password: 'password123',
|
|
199
|
+
remember: true // Optional
|
|
280
200
|
});
|
|
201
|
+
```
|
|
281
202
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
// batchSize: 50, // ❌ Not available: Not using `ids` or `files`
|
|
287
|
-
// concurrent: 10, // ❌ Not available: Not using `ids` or `files`
|
|
288
|
-
// onProgress: () => {} // ❌ Not available: Not using `ids` or `files`
|
|
289
|
-
});
|
|
203
|
+
**Fetch User:**
|
|
204
|
+
```typescript
|
|
205
|
+
// Fetch all user fields
|
|
206
|
+
await fetchUser();
|
|
290
207
|
|
|
291
|
-
//
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
completed: 0,
|
|
295
|
-
total: 0,
|
|
296
|
-
failed: 0,
|
|
297
|
-
estimatedTimeRemaining: 0,
|
|
298
|
-
operationsPerSecond: 0
|
|
208
|
+
// Fetch specific fields only
|
|
209
|
+
await fetchUser({
|
|
210
|
+
fields: ['id', 'email', 'role', 'allowedRoutePermissions']
|
|
299
211
|
});
|
|
212
|
+
```
|
|
300
213
|
|
|
301
|
-
|
|
302
|
-
const { execute: uploadFiles } = useEnfyraApi('/file_definition', {
|
|
303
|
-
method: 'post',
|
|
304
|
-
batchSize: 5, // ✅ Available: POST method supports batching for files
|
|
305
|
-
concurrent: 2, // ✅ Available: POST method supports batching for files
|
|
306
|
-
errorContext: 'Upload Files',
|
|
307
|
-
onProgress: (progress) => { // ✅ Available: POST method supports batching
|
|
308
|
-
progressState.value = progress;
|
|
309
|
-
console.log(`Progress: ${progress.progress}% (${progress.completed}/${progress.total})`);
|
|
310
|
-
console.log(`ETA: ${Math.round((progress.estimatedTimeRemaining || 0) / 1000)}s`);
|
|
311
|
-
console.log(`Speed: ${progress.operationsPerSecond?.toFixed(1)} ops/sec`);
|
|
312
|
-
}
|
|
313
|
-
});
|
|
214
|
+
## Advanced Usage
|
|
314
215
|
|
|
315
|
-
|
|
316
|
-
const formDataArray = selectedFiles.map(file => {
|
|
317
|
-
const formData = new FormData();
|
|
318
|
-
formData.append('file', file);
|
|
319
|
-
formData.append('folder', folderId || 'null');
|
|
320
|
-
return formData;
|
|
321
|
-
});
|
|
216
|
+
### Building Custom Composables
|
|
322
217
|
|
|
323
|
-
|
|
324
|
-
files: formDataArray // Array of FormData objects
|
|
325
|
-
});
|
|
218
|
+
Since you have access to `baseUrl`, you can build your own composables using Nuxt's built-in utilities:
|
|
326
219
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
console.log('Batch Progress:', {
|
|
338
|
-
percentage: progress.progress,
|
|
339
|
-
completed: progress.completed,
|
|
340
|
-
total: progress.total,
|
|
341
|
-
failed: progress.failed,
|
|
342
|
-
currentBatch: progress.currentBatch,
|
|
343
|
-
totalBatches: progress.totalBatches,
|
|
344
|
-
averageTime: progress.averageTime,
|
|
345
|
-
estimatedTimeRemaining: progress.estimatedTimeRemaining,
|
|
346
|
-
operationsPerSecond: progress.operationsPerSecond
|
|
220
|
+
```typescript
|
|
221
|
+
// composables/useUsers.ts
|
|
222
|
+
export const useUsers = () => {
|
|
223
|
+
const { baseUrl } = useEnfyra();
|
|
224
|
+
|
|
225
|
+
// SSR mode with useFetch
|
|
226
|
+
const getUsers = (options?: { page?: number; limit?: number }) => {
|
|
227
|
+
return useFetch(`${baseUrl}/users`, {
|
|
228
|
+
key: `users-${options?.page || 1}`,
|
|
229
|
+
query: options
|
|
347
230
|
});
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// Client mode with $fetch
|
|
234
|
+
const createUser = async (userData: any) => {
|
|
235
|
+
return await $fetch(`${baseUrl}/users`, {
|
|
236
|
+
method: 'POST',
|
|
237
|
+
body: userData
|
|
354
238
|
});
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
await
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
operationsPerSecond?: number; // Processing speed
|
|
378
|
-
results: Array<{ // Detailed results
|
|
379
|
-
index: number;
|
|
380
|
-
status: 'completed' | 'failed';
|
|
381
|
-
result?: any;
|
|
382
|
-
error?: ApiError;
|
|
383
|
-
duration?: number;
|
|
384
|
-
}>;
|
|
385
|
-
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
const updateUser = async (id: string, userData: any) => {
|
|
242
|
+
return await $fetch(`${baseUrl}/users/${id}`, {
|
|
243
|
+
method: 'PATCH',
|
|
244
|
+
body: userData
|
|
245
|
+
});
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
const deleteUser = async (id: string) => {
|
|
249
|
+
return await $fetch(`${baseUrl}/users/${id}`, {
|
|
250
|
+
method: 'DELETE'
|
|
251
|
+
});
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
getUsers,
|
|
256
|
+
createUser,
|
|
257
|
+
updateUser,
|
|
258
|
+
deleteUser
|
|
259
|
+
};
|
|
260
|
+
};
|
|
386
261
|
```
|
|
387
262
|
|
|
388
263
|
### TypeScript Integration
|
|
@@ -401,24 +276,23 @@ interface ApiResponse<T> {
|
|
|
401
276
|
}
|
|
402
277
|
|
|
403
278
|
// Use with full type safety
|
|
404
|
-
const {
|
|
405
|
-
|
|
406
|
-
});
|
|
279
|
+
const { baseUrl } = useEnfyra();
|
|
280
|
+
const { data } = await useFetch<ApiResponse<User>>(`${baseUrl}/users`);
|
|
407
281
|
|
|
408
282
|
// TypeScript knows data.value is ApiResponse<User> | null
|
|
409
283
|
const users = computed(() => data.value?.data || []);
|
|
410
284
|
```
|
|
411
285
|
|
|
412
|
-
### Reactive Parameters
|
|
286
|
+
### Reactive Parameters with `useFetch`
|
|
413
287
|
|
|
414
288
|
```typescript
|
|
289
|
+
const { baseUrl } = useEnfyra();
|
|
415
290
|
const searchQuery = ref('');
|
|
416
291
|
const page = ref(1);
|
|
417
292
|
|
|
418
|
-
// SSR mode with reactive query
|
|
419
|
-
const { data, refresh } =
|
|
420
|
-
|
|
421
|
-
key: () => `users-${page.value}-${searchQuery.value}`, // Optional
|
|
293
|
+
// SSR mode with reactive query
|
|
294
|
+
const { data, refresh } = await useFetch(`${baseUrl}/users`, {
|
|
295
|
+
key: () => `users-${page.value}-${searchQuery.value}`,
|
|
422
296
|
query: computed(() => ({
|
|
423
297
|
search: searchQuery.value,
|
|
424
298
|
page: page.value,
|
|
@@ -430,24 +304,6 @@ const { data, refresh } = useEnfyraApi('/users', {
|
|
|
430
304
|
watch([searchQuery, page], () => refresh());
|
|
431
305
|
```
|
|
432
306
|
|
|
433
|
-
## Documentation
|
|
434
|
-
|
|
435
|
-
For comprehensive guides and examples:
|
|
436
|
-
|
|
437
|
-
📚 **[useEnfyraApi Complete Guide](https://github.com/dothinh115/enfyra-sdk-nuxt/blob/main/docs/useEnfyraApi.md)** - API client composable with SSR support, batch operations, and error handling
|
|
438
|
-
|
|
439
|
-
🔐 **[useEnfyraAuth Complete Guide](https://github.com/dothinh115/enfyra-sdk-nuxt/blob/main/docs/useEnfyraAuth.md)** - Authentication composable with user management and login/logout functionality
|
|
440
|
-
|
|
441
|
-
Key topics covered:
|
|
442
|
-
- SSR vs Client Mode comparison
|
|
443
|
-
- Authentication and headers forwarding
|
|
444
|
-
- Batch operations and CRUD patterns
|
|
445
|
-
- User management and authentication flows
|
|
446
|
-
- Error handling best practices
|
|
447
|
-
- TypeScript integration
|
|
448
|
-
- Performance optimization
|
|
449
|
-
- Migration guides
|
|
450
|
-
|
|
451
307
|
## Configuration
|
|
452
308
|
|
|
453
309
|
### Module Options
|
|
@@ -460,8 +316,8 @@ export default defineNuxtConfig({
|
|
|
460
316
|
// Required: Main API URL
|
|
461
317
|
apiUrl: process.env.ENFYRA_API_URL || "http://localhost:1105",
|
|
462
318
|
|
|
463
|
-
//
|
|
464
|
-
|
|
319
|
+
// Optional: API prefix (defaults to "/enfyra/api")
|
|
320
|
+
apiPrefix: "/enfyra/api",
|
|
465
321
|
},
|
|
466
322
|
})
|
|
467
323
|
```
|
|
@@ -471,97 +327,73 @@ export default defineNuxtConfig({
|
|
|
471
327
|
```bash
|
|
472
328
|
# .env
|
|
473
329
|
ENFYRA_API_URL=https://api.enfyra.com
|
|
474
|
-
ENFYRA_APP_URL=https://app.enfyra.com
|
|
475
330
|
```
|
|
476
331
|
|
|
477
332
|
## Best Practices
|
|
478
333
|
|
|
479
|
-
### 1.
|
|
334
|
+
### 1. Use `useFetch` for SSR Data
|
|
480
335
|
|
|
481
336
|
```typescript
|
|
482
|
-
// ✅ Use
|
|
483
|
-
const {
|
|
484
|
-
|
|
485
|
-
key: 'dashboard'
|
|
486
|
-
});
|
|
487
|
-
|
|
488
|
-
// ✅ Use Client mode for user interactions (manual execution)
|
|
489
|
-
const { execute: saveData } = useEnfyraApi('/settings', {
|
|
490
|
-
method: 'patch',
|
|
491
|
-
errorContext: 'Save Settings'
|
|
337
|
+
// ✅ Use useFetch for initial page data (runs immediately, SSR support)
|
|
338
|
+
const { baseUrl } = useEnfyra();
|
|
339
|
+
const { data } = await useFetch(`${baseUrl}/dashboard`, {
|
|
340
|
+
key: 'dashboard'
|
|
492
341
|
});
|
|
493
342
|
```
|
|
494
343
|
|
|
495
|
-
### 2.
|
|
344
|
+
### 2. Use `$fetch` for Client Actions
|
|
496
345
|
|
|
497
346
|
```typescript
|
|
498
|
-
// ✅
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
347
|
+
// ✅ Use $fetch for user interactions (manual execution)
|
|
348
|
+
const { baseUrl } = useEnfyra();
|
|
349
|
+
|
|
350
|
+
async function saveSettings(settings: any) {
|
|
351
|
+
try {
|
|
352
|
+
await $fetch(`${baseUrl}/settings`, {
|
|
353
|
+
method: 'PATCH',
|
|
354
|
+
body: settings
|
|
355
|
+
});
|
|
356
|
+
toast.success('Saved successfully');
|
|
357
|
+
} catch (error) {
|
|
358
|
+
toast.error('Failed to save');
|
|
504
359
|
}
|
|
505
|
-
|
|
506
|
-
// Success handling
|
|
507
|
-
toast.success('Saved successfully');
|
|
508
360
|
}
|
|
509
361
|
```
|
|
510
362
|
|
|
511
|
-
### 3.
|
|
363
|
+
### 3. Build Reusable Composables
|
|
512
364
|
|
|
513
365
|
```typescript
|
|
514
|
-
// ✅
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
})
|
|
366
|
+
// ✅ Create reusable composables for your API endpoints
|
|
367
|
+
export const useProducts = () => {
|
|
368
|
+
const { baseUrl } = useEnfyra();
|
|
369
|
+
|
|
370
|
+
return {
|
|
371
|
+
list: (query?: any) => useFetch(`${baseUrl}/products`, { query }),
|
|
372
|
+
get: (id: string) => useFetch(`${baseUrl}/products/${id}`),
|
|
373
|
+
create: (data: any) => $fetch(`${baseUrl}/products`, { method: 'POST', body: data }),
|
|
374
|
+
update: (id: string, data: any) => $fetch(`${baseUrl}/products/${id}`, { method: 'PATCH', body: data }),
|
|
375
|
+
delete: (id: string) => $fetch(`${baseUrl}/products/${id}`, { method: 'DELETE' }),
|
|
376
|
+
};
|
|
377
|
+
};
|
|
523
378
|
```
|
|
524
379
|
|
|
525
380
|
## Troubleshooting
|
|
526
381
|
|
|
527
382
|
### Common Issues
|
|
528
383
|
|
|
529
|
-
1. **
|
|
530
|
-
2. **
|
|
531
|
-
3. **
|
|
532
|
-
4. **TypeScript errors** - Check return type differences between modes
|
|
384
|
+
1. **Base URL is empty** - Ensure `apiUrl` is configured in `nuxt.config.ts`
|
|
385
|
+
2. **Assets not loading** - Check that `/assets/**` routes are accessible
|
|
386
|
+
3. **Authentication not working** - Verify cookies are being set and forwarded
|
|
533
387
|
|
|
534
388
|
### Performance Tips
|
|
535
389
|
|
|
536
|
-
- Use
|
|
537
|
-
- Use
|
|
538
|
-
-
|
|
539
|
-
-
|
|
390
|
+
- Use `useFetch` with cache keys for SSR data (better SEO, faster page loads)
|
|
391
|
+
- Use `$fetch` for user interactions (better UX)
|
|
392
|
+
- Build reusable composables to avoid code duplication
|
|
393
|
+
- Leverage Nuxt's built-in caching with `useFetch` keys
|
|
540
394
|
|
|
541
395
|
## Development
|
|
542
396
|
|
|
543
|
-
### Testing
|
|
544
|
-
|
|
545
|
-
The SDK includes a comprehensive test suite using Vitest:
|
|
546
|
-
|
|
547
|
-
```bash
|
|
548
|
-
# Run tests once
|
|
549
|
-
npm run test:run
|
|
550
|
-
|
|
551
|
-
# Run tests in watch mode
|
|
552
|
-
npm test
|
|
553
|
-
|
|
554
|
-
# Run tests with UI
|
|
555
|
-
npm run test:ui
|
|
556
|
-
```
|
|
557
|
-
|
|
558
|
-
**Test Coverage:**
|
|
559
|
-
- ✅ **Extension naming utilities** - UUID generation and validation
|
|
560
|
-
- ✅ **Vue SFC validation** - Syntax and structure validation
|
|
561
|
-
- ✅ **JS bundle validation** - Syntax and export validation
|
|
562
|
-
- ✅ **Extension processing** - Complete workflow testing
|
|
563
|
-
- ✅ **35 test cases** covering all edge cases and error handling
|
|
564
|
-
|
|
565
397
|
### Building
|
|
566
398
|
|
|
567
399
|
```bash
|
|
@@ -580,13 +412,8 @@ MIT
|
|
|
580
412
|
|
|
581
413
|
Pull requests are welcome! Please read our contributing guidelines and ensure tests pass before submitting.
|
|
582
414
|
|
|
583
|
-
## Changelog
|
|
584
|
-
|
|
585
|
-
See [CHANGELOG.md](https://github.com/dothinh115/enfyra-sdk-nuxt/blob/main/CHANGELOG.md) for a detailed history of changes and migration guides.
|
|
586
|
-
|
|
587
415
|
## Support
|
|
588
416
|
|
|
589
417
|
For issues and questions:
|
|
590
|
-
-
|
|
591
|
-
-
|
|
592
|
-
- 💬 [GitHub Discussions](https://github.com/dothinh115/enfyra-sdk-nuxt/discussions)
|
|
418
|
+
- 🐛 [Report bugs](https://github.com/enfyra/sdk-nuxt/issues)
|
|
419
|
+
- 💬 [GitHub Discussions](https://github.com/enfyra/sdk-nuxt/discussions)
|