@enfyra/sdk-nuxt 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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
- '@enfyra/sdk-nuxt'
29
- ],
30
- runtimeConfig: {
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 rendering with caching
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 - Automatic execution
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,15 +137,19 @@ 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
- - `key?: string` - Cache key (SSR mode only)
146
+ - `key?: string` - Cache key (SSR mode, optional)
152
147
  - `default?: () => T` - Default value (SSR mode only)
153
148
 
149
+ **⚠️ Important: Return Types Differ**
150
+ - **SSR Mode**: Returns `useFetch` result `{ data, pending, error, refresh }`
151
+ - **Client Mode**: Returns custom result `{ data, pending, error, execute }`
152
+
154
153
  **Execute Options (Client mode only):**
155
154
  - `id?: string | number` - Single resource ID
156
155
  - `ids?: (string | number)[]` - Batch operation IDs (PATCH/DELETE)
@@ -228,10 +227,10 @@ const users = computed(() => data.value?.data || []);
228
227
  const searchQuery = ref('');
229
228
  const page = ref(1);
230
229
 
231
- // SSR mode with reactive query
230
+ // SSR mode with reactive query (executes immediately)
232
231
  const { data, refresh } = useEnfyraApi('/users', {
233
232
  ssr: true,
234
- key: () => `users-${page.value}-${searchQuery.value}`,
233
+ key: () => `users-${page.value}-${searchQuery.value}`, // Optional
235
234
  query: computed(() => ({
236
235
  search: searchQuery.value,
237
236
  page: page.value,
@@ -247,7 +246,7 @@ watch([searchQuery, page], () => refresh());
247
246
 
248
247
  For comprehensive guides and examples:
249
248
 
250
- 📚 **[useEnfyraApi Complete Guide](./docs/useEnfyraApi.md)** - Detailed documentation with examples, best practices, and troubleshooting
249
+ 📚 **[useEnfyraApi Complete Guide](https://github.com/dothinh115/enfyra-sdk-nuxt/blob/main/docs/useEnfyraApi.md)** - Detailed documentation with examples, best practices, and troubleshooting
251
250
 
252
251
  Key topics covered:
253
252
  - SSR vs Client Mode comparison
@@ -260,30 +259,21 @@ Key topics covered:
260
259
 
261
260
  ## Configuration
262
261
 
263
- ### Runtime Config Options
262
+ ### Module Options
264
263
 
265
264
  ```typescript
266
265
  // nuxt.config.ts
267
266
  export default defineNuxtConfig({
268
- runtimeConfig: {
269
- public: {
270
- enfyraSDK: {
271
- // Required: Main API URL
272
- apiUrl: process.env.ENFYRA_API_URL,
273
-
274
- // Optional: API path prefix (default: '')
275
- apiPrefix: '/api/v1',
276
-
277
- // Required: App URL for SSR requests
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
- },
267
+ modules: ["@enfyra/sdk-nuxt"],
268
+ enfyraSDK: {
269
+ // Required: Main API URL
270
+ apiUrl: process.env.ENFYRA_API_URL || "http://localhost:1105",
271
+
272
+ // Optional: API path prefix (default: '')
273
+ apiPrefix: '/api/v1',
274
+
275
+ // Required: App URL for SSR requests
276
+ appUrl: process.env.ENFYRA_APP_URL || "http://localhost:3001",
287
277
  },
288
278
  })
289
279
  ```
@@ -301,13 +291,13 @@ ENFYRA_APP_URL=https://app.enfyra.com
301
291
  ### 1. Choose the Right Mode
302
292
 
303
293
  ```typescript
304
- // ✅ Use SSR for initial page data
294
+ // ✅ Use SSR for initial page data (runs immediately)
305
295
  const { data } = useEnfyraApi('/dashboard', {
306
296
  ssr: true,
307
- key: 'dashboard'
297
+ key: 'dashboard' // Optional
308
298
  });
309
299
 
310
- // ✅ Use Client mode for user interactions
300
+ // ✅ Use Client mode for user interactions (manual execution)
311
301
  const { execute: saveData } = useEnfyraApi('/settings', {
312
302
  method: 'patch',
313
303
  errorContext: 'Save Settings'
@@ -370,11 +360,11 @@ Pull requests are welcome! Please read our contributing guidelines and ensure te
370
360
 
371
361
  ## Changelog
372
362
 
373
- See [CHANGELOG.md](./CHANGELOG.md) for a detailed history of changes and migration guides.
363
+ See [CHANGELOG.md](https://github.com/dothinh115/enfyra-sdk-nuxt/blob/main/CHANGELOG.md) for a detailed history of changes and migration guides.
374
364
 
375
365
  ## Support
376
366
 
377
367
  For issues and questions:
378
- - 📖 Check the [detailed documentation](./docs/useEnfyraApi.md)
379
- - 🐛 [Report bugs](https://github.com/enfyra/sdk-nuxt/issues)
380
- - 💬 [Join our community](https://discord.gg/enfyra)
368
+ - 📖 Check the [detailed documentation](https://github.com/dothinh115/enfyra-sdk-nuxt/blob/main/docs/useEnfyraApi.md)
369
+ - 🐛 [Report bugs](https://github.com/dothinh115/enfyra-sdk-nuxt/issues)
370
+ - 💬 [GitHub Discussions](https://github.com/dothinh115/enfyra-sdk-nuxt/discussions)
@@ -1,2 +1,12 @@
1
- import type { ApiOptions, UseEnfyraApiReturn } from "../types";
2
- export declare function useEnfyraApi<T = any>(path: (() => string) | string, opts?: ApiOptions<T>): UseEnfyraApiReturn<T>;
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 handleApiError(error, context) {
5
- let message = "Request failed";
6
- let errorCode = "UNKNOWN_ERROR";
7
- let correlationId;
8
- if (error?.response?.data) {
9
- const responseData = error.response.data;
10
- if (responseData.error) {
11
- message = responseData.error.message || responseData.message || "Request failed";
12
- errorCode = responseData.error.code;
13
- correlationId = responseData.error.correlationId;
14
- } else {
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
- console.error(`[Enfyra API Error] ${errorCode}: ${message}`, {
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 } = opts;
37
20
  if (ssr) {
38
21
  const config = useRuntimeConfig().public.enfyraSDK;
39
22
  const basePath = (typeof path === "function" ? path() : path).replace(/^\/?api\/?/, "").replace(/^\/+/, "");
@@ -127,8 +110,8 @@ export function useEnfyraApi(path, opts = {}) {
127
110
  data.value = response;
128
111
  return response;
129
112
  } catch (err) {
130
- error.value = err;
131
- handleApiError(err, errorContext);
113
+ const apiError = handleError(err, errorContext, onError);
114
+ error.value = apiError;
132
115
  return null;
133
116
  } finally {
134
117
  pending.value = false;
@@ -1,5 +1,6 @@
1
1
  import type { Ref, ComputedRef } from 'vue';
2
- import type { LoginPayload, User, ApiOptions, UseEnfyraApiReturn } from './index';
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
- export declare function useEnfyraApi<T = any>(path: (() => string) | string, opts?: ApiOptions<T>): UseEnfyraApiReturn<T>;
11
- //# sourceMappingURL=composables.d.ts.map
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,12 +3,19 @@ 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;
13
20
  default?: () => T;
14
21
  /** Enable SSR with useFetch instead of $fetch */
@@ -32,9 +39,16 @@ export interface BackendErrorExtended extends BackendError {
32
39
  };
33
40
  }
34
41
  import type { Ref } from 'vue';
35
- export interface UseEnfyraApiReturn<T> {
42
+ import type { AsyncData } from 'nuxt/app';
43
+ export interface UseEnfyraApiSSRReturn<T> extends AsyncData<T | null, ApiError> {
44
+ data: Ref<T | null>;
45
+ pending: Ref<boolean>;
46
+ error: Ref<ApiError | null>;
47
+ refresh: () => Promise<void>;
48
+ }
49
+ export interface UseEnfyraApiClientReturn<T> {
36
50
  data: Ref<T | null>;
37
- error: Ref<any>;
51
+ error: Ref<ApiError | null>;
38
52
  pending: Ref<boolean>;
39
53
  execute: (executeOpts?: {
40
54
  body?: any;
@@ -44,5 +58,4 @@ export interface UseEnfyraApiReturn<T> {
44
58
  }) => Promise<T | T[] | null>;
45
59
  }
46
60
  export * from './auth';
47
- export * from './composables';
48
61
  //# sourceMappingURL=index.d.ts.map
@@ -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;AAE/B,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,IAAI,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACpB,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACtB,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE;QACtB,IAAI,CAAC,EAAE,GAAG,CAAC;QACX,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACrB,GAAG,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;QAC1B,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;KACf,KAAK,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;CAC/B;AAGD,cAAc,QAAQ,CAAC;AAGvB,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/types/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,4 +1,2 @@
1
1
  // Re-export auth types
2
2
  export * from './auth';
3
- // Re-export composables types
4
- export * from './composables';
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@enfyra/sdk-nuxt",
3
3
  "configKey": "enfyraSDK",
4
- "version": "0.2.0",
4
+ "version": "0.2.1",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "0.8.4",
7
7
  "unbuild": "2.0.0"
package/package.json CHANGED
@@ -1,7 +1,15 @@
1
1
  {
2
2
  "name": "@enfyra/sdk-nuxt",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
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,52 @@
1
1
  import { ref, unref, toRaw } from "vue";
2
2
  import type {
3
3
  ApiOptions,
4
+ ApiError,
4
5
  BackendErrorExtended,
5
- UseEnfyraApiReturn,
6
+ UseEnfyraApiSSRReturn,
7
+ UseEnfyraApiClientReturn,
6
8
  } from "../types";
7
9
  import { $fetch } from "../utils/http";
8
10
  import { useRuntimeConfig, useFetch, useRequestHeaders } from "#imports";
9
11
 
10
- function handleApiError(error: any, context?: string) {
11
- let message = "Request failed";
12
- let errorCode = "UNKNOWN_ERROR";
13
- let correlationId: string | undefined;
14
-
15
- // Handle backend error response format
16
- if (error?.response?.data) {
17
- const responseData = error.response.data as BackendErrorExtended;
18
- if (responseData.error) {
19
- message =
20
- responseData.error.message || responseData.message || "Request failed";
21
- errorCode = responseData.error.code;
22
- correlationId = responseData.error.correlationId;
23
- } else {
24
- message = responseData.message || "Request failed";
25
- }
26
- } else if (error?.data) {
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;
12
+ function handleError(
13
+ error: any,
14
+ context?: string,
15
+ customHandler?: (error: ApiError, context?: string) => void
16
+ ) {
17
+ // Transform error to ApiError format
18
+ const apiError: ApiError = {
19
+ message: error?.message || error?.data?.message || "Request failed",
20
+ status: error?.status || error?.response?.status,
21
+ data: error?.data || error?.response?.data,
22
+ response: error?.response || error
23
+ };
24
+
25
+ if (customHandler) {
26
+ customHandler(apiError, context);
27
+ } else {
28
+ console.error(`[Enfyra API Error]`, { error: apiError, context });
38
29
  }
39
30
 
40
- // You can customize error handling here
41
- // For now, just log the error
42
- console.error(`[Enfyra API Error] ${errorCode}: ${message}`, {
43
- context,
44
- correlationId,
45
- error,
46
- });
31
+ return apiError;
47
32
  }
48
33
 
34
+ // Function overloads for proper TypeScript support
35
+ export function useEnfyraApi<T = any>(
36
+ path: (() => string) | string,
37
+ opts: ApiOptions<T> & { ssr: true }
38
+ ): UseEnfyraApiSSRReturn<T>;
39
+
40
+ export function useEnfyraApi<T = any>(
41
+ path: (() => string) | string,
42
+ opts?: ApiOptions<T> & { ssr?: false | undefined }
43
+ ): UseEnfyraApiClientReturn<T>;
44
+
49
45
  export function useEnfyraApi<T = any>(
50
46
  path: (() => string) | string,
51
47
  opts: ApiOptions<T> = {}
52
- ): UseEnfyraApiReturn<T> {
53
- const { method = "get", body, query, errorContext, ssr, key } = opts;
48
+ ): UseEnfyraApiSSRReturn<T> | UseEnfyraApiClientReturn<T> {
49
+ const { method = "get", body, query, errorContext, onError, ssr, key } = opts;
54
50
 
55
51
  // SSR mode - use useFetch
56
52
  if (ssr) {
@@ -99,10 +95,10 @@ export function useEnfyraApi<T = any>(
99
95
  fetchOptions.default = opts.default;
100
96
  }
101
97
 
102
- return useFetch<T>(finalUrl, fetchOptions) as any;
98
+ return useFetch<T>(finalUrl, fetchOptions) as UseEnfyraApiSSRReturn<T>;
103
99
  }
104
100
  const data = ref<T | null>(null);
105
- const error = ref<any>(null);
101
+ const error = ref<ApiError | null>(null);
106
102
  const pending = ref(false);
107
103
 
108
104
  const execute = async (executeOpts?: {
@@ -195,8 +191,8 @@ export function useEnfyraApi<T = any>(
195
191
  data.value = response;
196
192
  return response;
197
193
  } catch (err) {
198
- error.value = err;
199
- handleApiError(err, errorContext);
194
+ const apiError = handleError(err, errorContext, onError);
195
+ error.value = apiError;
200
196
  return null;
201
197
  } finally {
202
198
  pending.value = false;
@@ -204,9 +200,9 @@ export function useEnfyraApi<T = any>(
204
200
  };
205
201
 
206
202
  return {
207
- data: data as any,
203
+ data,
208
204
  error,
209
205
  pending,
210
206
  execute,
211
- };
207
+ } as UseEnfyraApiClientReturn<T>;
212
208
  }
@@ -4,12 +4,20 @@ 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;
14
22
  default?: () => T;
15
23
  /** Enable SSR with useFetch instead of $fetch */
@@ -36,10 +44,20 @@ export interface BackendErrorExtended extends BackendError {
36
44
  }
37
45
 
38
46
  import type { Ref } from 'vue';
47
+ import type { AsyncData } from 'nuxt/app';
48
+
49
+ // SSR Mode return type (same as useFetch)
50
+ export interface UseEnfyraApiSSRReturn<T> extends AsyncData<T | null, ApiError> {
51
+ data: Ref<T | null>;
52
+ pending: Ref<boolean>;
53
+ error: Ref<ApiError | null>;
54
+ refresh: () => Promise<void>;
55
+ }
39
56
 
40
- export interface UseEnfyraApiReturn<T> {
57
+ // Client Mode return type
58
+ export interface UseEnfyraApiClientReturn<T> {
41
59
  data: Ref<T | null>;
42
- error: Ref<any>;
60
+ error: Ref<ApiError | null>;
43
61
  pending: Ref<boolean>;
44
62
  execute: (executeOpts?: {
45
63
  body?: any;
@@ -49,8 +67,7 @@ export interface UseEnfyraApiReturn<T> {
49
67
  }) => Promise<T | T[] | null>;
50
68
  }
51
69
 
70
+
52
71
  // Re-export auth types
53
72
  export * from './auth';
54
73
 
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"}
@@ -1 +0,0 @@
1
- export {};
@@ -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>