@enfyra/sdk-nuxt 0.3.0 → 0.3.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.
Files changed (47) hide show
  1. package/README.md +32 -2
  2. package/dist/composables/useEnfyraApi.mjs +48 -29
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +0 -1
  5. package/dist/module.cjs +27 -11
  6. package/dist/module.d.cts +0 -2
  7. package/dist/module.d.mts +0 -2
  8. package/dist/module.d.ts +0 -2
  9. package/dist/module.json +1 -1
  10. package/dist/module.mjs +28 -12
  11. package/dist/runtime/plugin/config-error.client.d.ts +0 -0
  12. package/dist/runtime/plugin/config-error.client.js +107 -0
  13. package/dist/runtime/plugin/config-error.client.mjs +107 -0
  14. package/dist/runtime/server/api/extension_definition/[id].patch.js +1 -1
  15. package/dist/runtime/server/api/extension_definition/[id].patch.mjs +1 -1
  16. package/dist/runtime/server/api/extension_definition.post.js +1 -1
  17. package/dist/runtime/server/api/extension_definition.post.mjs +1 -1
  18. package/dist/runtime/server/api/login.post.js +1 -1
  19. package/dist/runtime/server/api/login.post.mjs +1 -1
  20. package/dist/runtime/server/api/logout.post.js +1 -1
  21. package/dist/runtime/server/api/logout.post.mjs +1 -1
  22. package/dist/runtime/server/middleware/auth.js +8 -6
  23. package/dist/runtime/server/middleware/auth.mjs +8 -6
  24. package/dist/utils/server/extension/index.mjs +1 -0
  25. package/dist/utils/server/proxy.mjs +2 -2
  26. package/dist/utils/url.d.ts +0 -0
  27. package/dist/utils/url.mjs +39 -0
  28. package/package.json +1 -1
  29. package/src/composables/useEnfyraApi.ts +139 -118
  30. package/src/composables/useEnfyraAuth.ts +0 -5
  31. package/src/module.ts +30 -19
  32. package/src/runtime/plugin/config-error.client.ts +116 -0
  33. package/src/runtime/server/api/extension_definition/[id].patch.ts +1 -3
  34. package/src/runtime/server/api/extension_definition.post.ts +1 -3
  35. package/src/runtime/server/api/login.post.ts +1 -1
  36. package/src/runtime/server/api/logout.post.ts +1 -3
  37. package/src/runtime/server/middleware/auth.ts +8 -11
  38. package/src/types/index.ts +0 -11
  39. package/src/types/nuxt-imports.d.ts +44 -0
  40. package/src/utils/http.ts +0 -6
  41. package/src/utils/server/extension/compiler.ts +0 -2
  42. package/src/utils/server/extension/index.ts +2 -1
  43. package/src/utils/server/extension/processor.ts +0 -3
  44. package/src/utils/server/extension.ts +1 -2
  45. package/src/utils/server/proxy.ts +2 -3
  46. package/src/utils/server/refreshToken.ts +0 -6
  47. package/src/utils/url.ts +47 -0
package/README.md CHANGED
@@ -6,6 +6,7 @@ Nuxt SDK for Enfyra CMS - A powerful composable-based API client with full SSR s
6
6
 
7
7
  ✅ **SSR & Client-Side Support** - Automatic server-side rendering with `useFetch` or client-side with `$fetch`
8
8
  ✅ **Authentication Integration** - Built-in auth composables with automatic header forwarding
9
+ ✅ **Asset Proxy** - Automatic `/assets/**` proxy to backend with no configuration needed
9
10
  ✅ **TypeScript Support** - Full type safety with auto-generated declarations
10
11
  ✅ **Batch Operations** - Efficient bulk operations with real-time progress tracking (client-side)
11
12
  ✅ **Error Handling** - Automatic error management with console logging
@@ -26,12 +27,19 @@ Add the module to your `nuxt.config.ts`:
26
27
  export default defineNuxtConfig({
27
28
  modules: ["@enfyra/sdk-nuxt"],
28
29
  enfyraSDK: {
29
- apiUrl: "http://localhost:1105",
30
- appUrl: "http://localhost:3001",
30
+ apiUrl: "http://localhost:1105", // Only apiUrl is required
31
31
  },
32
32
  })
33
33
  ```
34
34
 
35
+ ### Automatic App URL Detection
36
+
37
+ The SDK automatically detects your application URL:
38
+
39
+ - **Client-side**: Uses `window.location.origin`
40
+ - **Server-side**: Detects from request headers (supports proxies with `X-Forwarded-*` headers)
41
+ - **No configuration needed**: Works out of the box with any deployment
42
+
35
43
  ## Quick Start
36
44
 
37
45
  ### SSR Mode - Perfect for Page Data
@@ -107,6 +115,28 @@ await logout();
107
115
  </script>
108
116
  ```
109
117
 
118
+ ### Asset URLs - Automatic Proxy
119
+
120
+ The SDK automatically proxies all asset requests to your backend. Simply use `/assets/**` paths directly:
121
+
122
+ ```vue
123
+ <template>
124
+ <!-- ✅ Assets are automatically proxied to your backend -->
125
+ <img src="/assets/images/logo.svg" alt="Logo" />
126
+ <img :src="`/assets/images/users/${user.id}/avatar.jpg`" alt="Avatar" />
127
+
128
+ <!-- Works with any asset type -->
129
+ <video src="/assets/videos/intro.mp4" controls />
130
+ <a :href="`/assets/documents/${doc.filename}`" download>Download PDF</a>
131
+ </template>
132
+ ```
133
+
134
+ **How it works:**
135
+ - All requests to `/assets/**` are automatically proxied to `{apiUrl}/enfyra/api/assets/**`
136
+ - No configuration needed - works out of the box
137
+ - Supports all asset types: images, videos, documents, etc.
138
+ - Maintains proper authentication headers
139
+
110
140
  ## Core Composables
111
141
 
112
142
  ### `useEnfyraApi<T>(path, options)`
@@ -1,5 +1,6 @@
1
1
  import { ref, unref, toRaw } from "vue";
2
2
  import { $fetch } from "../utils/http";
3
+ import { getAppUrl } from "../utils/url";
3
4
  import { ENFYRA_API_PREFIX } from "../constants/config";
4
5
  import { useRuntimeConfig, useFetch, useRequestHeaders } from "#imports";
5
6
  function handleError(error, context, customHandler) {
@@ -17,11 +18,14 @@ function handleError(error, context, customHandler) {
17
18
  return apiError;
18
19
  }
19
20
  export function useEnfyraApi(path, opts = {}) {
20
- const { method = "get", body, query, errorContext, onError, ssr, key, batchSize, concurrent, onProgress } = opts;
21
+ const { method = "get", body, query, errorContext, onError, ssr, key } = opts;
22
+ const batchOptions = opts;
23
+ const { batchSize, concurrent, onProgress } = batchOptions;
21
24
  if (ssr) {
22
25
  const config = useRuntimeConfig().public.enfyraSDK;
23
26
  const basePath = (typeof path === "function" ? path() : path).replace(/^\/?api\/?/, "").replace(/^\/+/, "");
24
- const finalUrl = (config?.appUrl || "") + (config?.apiPrefix || ENFYRA_API_PREFIX) + "/" + basePath;
27
+ const appUrl = getAppUrl();
28
+ const finalUrl = appUrl + (config?.apiPrefix || ENFYRA_API_PREFIX) + "/" + basePath;
25
29
  const clientHeaders = process.client ? {} : useRequestHeaders([
26
30
  "authorization",
27
31
  "cookie",
@@ -42,7 +46,6 @@ export function useEnfyraApi(path, opts = {}) {
42
46
  headers: {
43
47
  ...serverHeaders,
44
48
  ...opts.headers
45
- // Custom headers override client headers
46
49
  }
47
50
  };
48
51
  if (key) {
@@ -61,7 +64,7 @@ export function useEnfyraApi(path, opts = {}) {
61
64
  error.value = null;
62
65
  try {
63
66
  const config = useRuntimeConfig().public.enfyraSDK;
64
- const apiUrl = config?.appUrl;
67
+ const apiUrl = getAppUrl();
65
68
  const apiPrefix = config?.apiPrefix;
66
69
  const basePath = (typeof path === "function" ? path() : path).replace(/^\/?api\/?/, "").replace(/^\/+/, "");
67
70
  const finalBody = executeOpts?.body || unref(body);
@@ -82,7 +85,10 @@ export function useEnfyraApi(path, opts = {}) {
82
85
  let failed = 0;
83
86
  const chunks = effectiveBatchSize ? Array.from(
84
87
  { length: Math.ceil(items.length / effectiveBatchSize) },
85
- (_, i) => items.slice(i * effectiveBatchSize, i * effectiveBatchSize + effectiveBatchSize)
88
+ (_, i) => items.slice(
89
+ i * effectiveBatchSize,
90
+ i * effectiveBatchSize + effectiveBatchSize
91
+ )
86
92
  ) : [items];
87
93
  const totalBatches = chunks.length;
88
94
  let currentBatch = 0;
@@ -165,7 +171,9 @@ export function useEnfyraApi(path, opts = {}) {
165
171
  result,
166
172
  duration
167
173
  });
168
- updateProgress(Math.max(0, batch.length - (batchItemIndex + 1)));
174
+ updateProgress(
175
+ Math.max(0, batch.length - (batchItemIndex + 1))
176
+ );
169
177
  return result;
170
178
  } catch (error2) {
171
179
  const duration = Date.now() - itemStartTime;
@@ -177,7 +185,9 @@ export function useEnfyraApi(path, opts = {}) {
177
185
  error: error2,
178
186
  duration
179
187
  });
180
- updateProgress(Math.max(0, batch.length - (batchItemIndex + 1)));
188
+ updateProgress(
189
+ Math.max(0, batch.length - (batchItemIndex + 1))
190
+ );
181
191
  throw error2;
182
192
  }
183
193
  });
@@ -200,7 +210,9 @@ export function useEnfyraApi(path, opts = {}) {
200
210
  result,
201
211
  duration
202
212
  });
203
- updateProgress(Math.max(0, chunk.length - (chunkItemIndex + 1)));
213
+ updateProgress(
214
+ Math.max(0, chunk.length - (chunkItemIndex + 1))
215
+ );
204
216
  return result;
205
217
  } catch (error2) {
206
218
  const duration = Date.now() - itemStartTime;
@@ -212,7 +224,9 @@ export function useEnfyraApi(path, opts = {}) {
212
224
  error: error2,
213
225
  duration
214
226
  });
215
- updateProgress(Math.max(0, chunk.length - (chunkItemIndex + 1)));
227
+ updateProgress(
228
+ Math.max(0, chunk.length - (chunkItemIndex + 1))
229
+ );
216
230
  throw error2;
217
231
  }
218
232
  });
@@ -224,30 +238,35 @@ export function useEnfyraApi(path, opts = {}) {
224
238
  return results;
225
239
  }
226
240
  if (isBatchOperation && executeOpts?.ids && executeOpts.ids.length > 0) {
227
- const responses = await processBatch(executeOpts.ids, async (id, index) => {
228
- const finalPath2 = buildPath(basePath, id);
229
- return $fetch(finalPath2, {
230
- baseURL: fullBaseURL,
231
- method,
232
- body: finalBody ? toRaw(finalBody) : void 0,
233
- headers: opts.headers,
234
- query: finalQuery
235
- });
236
- });
241
+ const responses = await processBatch(
242
+ executeOpts.ids,
243
+ async (id) => {
244
+ const finalPath2 = buildPath(basePath, id);
245
+ return $fetch(finalPath2, {
246
+ baseURL: fullBaseURL,
247
+ method,
248
+ body: finalBody ? toRaw(finalBody) : void 0,
249
+ headers: opts.headers,
250
+ query: finalQuery
251
+ });
252
+ }
253
+ );
237
254
  data.value = responses;
238
255
  return responses;
239
256
  }
240
257
  if (isBatchOperation && executeOpts?.files && Array.isArray(executeOpts.files) && executeOpts.files.length > 0) {
241
- const responses = await processBatch(executeOpts.files, async (fileObj, index) => {
242
- return $fetch(basePath, {
243
- baseURL: fullBaseURL,
244
- method,
245
- body: fileObj,
246
- // {file: file1, folder: null}
247
- headers: opts.headers,
248
- query: finalQuery
249
- });
250
- });
258
+ const responses = await processBatch(
259
+ executeOpts.files,
260
+ async (fileObj) => {
261
+ return $fetch(basePath, {
262
+ baseURL: fullBaseURL,
263
+ method,
264
+ body: fileObj,
265
+ headers: opts.headers,
266
+ query: finalQuery
267
+ });
268
+ }
269
+ );
251
270
  data.value = responses;
252
271
  return responses;
253
272
  }
@@ -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,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,aAAa;IAC5B,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,8BAA8B;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,sDAAsD;IACtD,OAAO,EAAE,KAAK,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;QAC/B,MAAM,CAAC,EAAE,GAAG,CAAC;QACb,KAAK,CAAC,EAAE,QAAQ,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;CACJ;AAGD,UAAU,cAAc,CAAC,CAAC;IACxB,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,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;IAClB,iDAAiD;IACjD,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAGD,UAAU,eAAe;IACvB,yGAAyG;IACzG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4FAA4F;IAC5F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6FAA6F;IAC7F,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;CAChD;AAGD,KAAK,uBAAuB,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAA;CAAE,GAC5F,eAAe,GACf,CAAC,SAAS;IAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GACtC,eAAe,GACf,CAAC,SAAS;IAAE,MAAM,CAAC,EAAE,SAAS,CAAA;CAAE,GAChC,OAAO,CAAC,eAAe,CAAC,GACxB,EAAE,CAAC;AAGP,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,GAAG,uBAAuB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AAE3F,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;AAID,UAAU,kBAAkB;IAC1B,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACtB;AAGD,UAAU,mBAAmB;IAC3B,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;IACpB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;CAChD;AASD,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAAG,mBAAmB,CAAC;AAGtE,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"}
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,2 +1 @@
1
- // Re-export auth types
2
1
  export * from './auth';
package/dist/module.cjs CHANGED
@@ -10,25 +10,37 @@ const module$1 = kit.defineNuxtModule({
10
10
  configKey: "enfyraSDK"
11
11
  },
12
12
  defaults: {
13
- apiUrl: "",
14
- appUrl: ""
13
+ apiUrl: ""
15
14
  },
16
15
  setup(options, nuxt) {
17
16
  const { resolve } = kit.createResolver((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('module.cjs', document.baseURI).href)));
18
- if (!options.apiUrl || !options.appUrl) {
19
- throw new Error(
17
+ if (!options.apiUrl) {
18
+ console.warn(
20
19
  `[Enfyra SDK Nuxt] Missing required configuration:
21
- ${!options.apiUrl ? "- apiUrl is required\n" : ""}${!options.appUrl ? "- appUrl is required\n" : ""}Please configure both in your nuxt.config.ts:
20
+ - apiUrl is required
21
+ Please configure it in your nuxt.config.ts:
22
22
  enfyraSDK: {
23
- apiUrl: 'https://your-api-url',
24
- appUrl: 'https://your-app-url'
23
+ apiUrl: 'https://your-api-url'
25
24
  }`
26
25
  );
26
+ nuxt.options.runtimeConfig.public.enfyraSDK = {
27
+ ...options,
28
+ apiPrefix: config_mjs.ENFYRA_API_PREFIX,
29
+ configError: true,
30
+ configErrorMessage: "Enfyra SDK: apiUrl is required. Please configure it in nuxt.config.ts"
31
+ };
32
+ } else {
33
+ nuxt.options.runtimeConfig.public.enfyraSDK = {
34
+ ...options,
35
+ apiPrefix: config_mjs.ENFYRA_API_PREFIX
36
+ };
37
+ }
38
+ if (!options.apiUrl) {
39
+ kit.addPlugin({
40
+ src: resolve("./runtime/plugin/config-error.client"),
41
+ mode: "client"
42
+ });
27
43
  }
28
- nuxt.options.runtimeConfig.public.enfyraSDK = {
29
- ...options,
30
- apiPrefix: config_mjs.ENFYRA_API_PREFIX
31
- };
32
44
  kit.addImportsDir(resolve("./composables"));
33
45
  kit.addServerHandler({
34
46
  handler: resolve("./runtime/server/middleware/auth"),
@@ -54,6 +66,10 @@ enfyraSDK: {
54
66
  handler: resolve("./runtime/server/api/extension_definition/[id].patch"),
55
67
  method: "patch"
56
68
  });
69
+ kit.addServerHandler({
70
+ route: "/assets/**",
71
+ handler: resolve("./runtime/server/api/all")
72
+ });
57
73
  kit.addServerHandler({
58
74
  route: `${config_mjs.ENFYRA_API_PREFIX}/**`,
59
75
  handler: resolve("./runtime/server/api/all")
package/dist/module.d.cts CHANGED
@@ -2,10 +2,8 @@ import * as _nuxt_schema from '@nuxt/schema';
2
2
 
3
3
  declare const _default: _nuxt_schema.NuxtModule<{
4
4
  apiUrl: string;
5
- appUrl: string;
6
5
  }, {
7
6
  apiUrl: string;
8
- appUrl: string;
9
7
  }, false>;
10
8
 
11
9
  export { _default as default };
package/dist/module.d.mts CHANGED
@@ -2,10 +2,8 @@ import * as _nuxt_schema from '@nuxt/schema';
2
2
 
3
3
  declare const _default: _nuxt_schema.NuxtModule<{
4
4
  apiUrl: string;
5
- appUrl: string;
6
5
  }, {
7
6
  apiUrl: string;
8
- appUrl: string;
9
7
  }, false>;
10
8
 
11
9
  export { _default as default };
package/dist/module.d.ts CHANGED
@@ -2,10 +2,8 @@ import * as _nuxt_schema from '@nuxt/schema';
2
2
 
3
3
  declare const _default: _nuxt_schema.NuxtModule<{
4
4
  apiUrl: string;
5
- appUrl: string;
6
5
  }, {
7
6
  apiUrl: string;
8
- appUrl: string;
9
7
  }, false>;
10
8
 
11
9
  export { _default as default };
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@enfyra/sdk-nuxt",
3
3
  "configKey": "enfyraSDK",
4
- "version": "0.3.0",
4
+ "version": "0.3.2",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "0.8.4",
7
7
  "unbuild": "2.0.0"
package/dist/module.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { defineNuxtModule, createResolver, addImportsDir, addServerHandler } from '@nuxt/kit';
1
+ import { defineNuxtModule, createResolver, addPlugin, addImportsDir, addServerHandler } from '@nuxt/kit';
2
2
  import { ENFYRA_API_PREFIX } from '../dist/constants/config.mjs';
3
3
 
4
4
  const module = defineNuxtModule({
@@ -7,25 +7,37 @@ const module = defineNuxtModule({
7
7
  configKey: "enfyraSDK"
8
8
  },
9
9
  defaults: {
10
- apiUrl: "",
11
- appUrl: ""
10
+ apiUrl: ""
12
11
  },
13
12
  setup(options, nuxt) {
14
13
  const { resolve } = createResolver(import.meta.url);
15
- if (!options.apiUrl || !options.appUrl) {
16
- throw new Error(
14
+ if (!options.apiUrl) {
15
+ console.warn(
17
16
  `[Enfyra SDK Nuxt] Missing required configuration:
18
- ${!options.apiUrl ? "- apiUrl is required\n" : ""}${!options.appUrl ? "- appUrl is required\n" : ""}Please configure both in your nuxt.config.ts:
17
+ - apiUrl is required
18
+ Please configure it in your nuxt.config.ts:
19
19
  enfyraSDK: {
20
- apiUrl: 'https://your-api-url',
21
- appUrl: 'https://your-app-url'
20
+ apiUrl: 'https://your-api-url'
22
21
  }`
23
22
  );
23
+ nuxt.options.runtimeConfig.public.enfyraSDK = {
24
+ ...options,
25
+ apiPrefix: ENFYRA_API_PREFIX,
26
+ configError: true,
27
+ configErrorMessage: "Enfyra SDK: apiUrl is required. Please configure it in nuxt.config.ts"
28
+ };
29
+ } else {
30
+ nuxt.options.runtimeConfig.public.enfyraSDK = {
31
+ ...options,
32
+ apiPrefix: ENFYRA_API_PREFIX
33
+ };
34
+ }
35
+ if (!options.apiUrl) {
36
+ addPlugin({
37
+ src: resolve("./runtime/plugin/config-error.client"),
38
+ mode: "client"
39
+ });
24
40
  }
25
- nuxt.options.runtimeConfig.public.enfyraSDK = {
26
- ...options,
27
- apiPrefix: ENFYRA_API_PREFIX
28
- };
29
41
  addImportsDir(resolve("./composables"));
30
42
  addServerHandler({
31
43
  handler: resolve("./runtime/server/middleware/auth"),
@@ -51,6 +63,10 @@ enfyraSDK: {
51
63
  handler: resolve("./runtime/server/api/extension_definition/[id].patch"),
52
64
  method: "patch"
53
65
  });
66
+ addServerHandler({
67
+ route: "/assets/**",
68
+ handler: resolve("./runtime/server/api/all")
69
+ });
54
70
  addServerHandler({
55
71
  route: `${ENFYRA_API_PREFIX}/**`,
56
72
  handler: resolve("./runtime/server/api/all")
File without changes
@@ -0,0 +1,107 @@
1
+ import { defineNuxtPlugin, useRuntimeConfig } from "#imports";
2
+ export default defineNuxtPlugin(() => {
3
+ const config = useRuntimeConfig().public?.enfyraSDK;
4
+ if (config?.configError) {
5
+ if (typeof window !== "undefined" && document) {
6
+ let showError = function() {
7
+ const errorDiv = document.createElement("div");
8
+ errorDiv.id = "enfyra-config-error";
9
+ errorDiv.style.cssText = `
10
+ position: fixed;
11
+ top: 0;
12
+ left: 0;
13
+ right: 0;
14
+ bottom: 0;
15
+ background: rgba(0, 0, 0, 0.9);
16
+ display: flex;
17
+ align-items: center;
18
+ justify-content: center;
19
+ z-index: 999999;
20
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
21
+ `;
22
+ const content = document.createElement("div");
23
+ content.style.cssText = `
24
+ background: white;
25
+ padding: 40px;
26
+ border-radius: 12px;
27
+ max-width: 600px;
28
+ width: 90%;
29
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
30
+ `;
31
+ content.innerHTML = `
32
+ <div style="display: flex; align-items: center; margin-bottom: 20px;">
33
+ <svg width="32" height="32" viewBox="0 0 24 24" fill="none" style="margin-right: 12px;">
34
+ <circle cx="12" cy="12" r="10" stroke="#ef4444" stroke-width="2"/>
35
+ <path d="M12 8v4M12 16h.01" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/>
36
+ </svg>
37
+ <h1 style="margin: 0; color: #1f2937; font-size: 24px; font-weight: 600;">
38
+ Configuration Error
39
+ </h1>
40
+ </div>
41
+
42
+ <div style="color: #4b5563; margin-bottom: 24px; line-height: 1.6;">
43
+ <p style="margin: 0 0 16px 0; font-size: 16px;">
44
+ <strong>Enfyra SDK</strong> is not configured properly.
45
+ </p>
46
+ <p style="margin: 0; color: #6b7280; font-size: 14px;">
47
+ ${config?.configErrorMessage || "Missing required configuration"}
48
+ </p>
49
+ </div>
50
+
51
+ <div style="background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 8px; padding: 16px; margin-bottom: 24px;">
52
+ <p style="margin: 0 0 12px 0; color: #6b7280; font-size: 13px; text-transform: uppercase; letter-spacing: 0.5px;">
53
+ Add to your nuxt.config.ts:
54
+ </p>
55
+ <pre style="margin: 0; background: #1f2937; color: #f3f4f6; padding: 16px; border-radius: 6px; overflow-x: auto; font-size: 14px; line-height: 1.4;"><code>export default defineNuxtConfig({
56
+ modules: ["@enfyra/sdk-nuxt"],
57
+ enfyraSDK: {
58
+ <span style="color: #fbbf24;">apiUrl</span>: <span style="color: #34d399;">"https://your-api-url"</span>
59
+ }
60
+ })</code></pre>
61
+ </div>
62
+
63
+ <div style="display: flex; gap: 12px;">
64
+ <button onclick="location.reload()" style="
65
+ background: #3b82f6;
66
+ color: white;
67
+ border: none;
68
+ padding: 10px 20px;
69
+ border-radius: 6px;
70
+ font-size: 14px;
71
+ font-weight: 500;
72
+ cursor: pointer;
73
+ transition: background 0.2s;
74
+ " onmouseover="this.style.background='#2563eb'" onmouseout="this.style.background='#3b82f6'">
75
+ Reload Page
76
+ </button>
77
+ <button onclick="document.getElementById('enfyra-config-error').style.display='none'" style="
78
+ background: #f3f4f6;
79
+ color: #4b5563;
80
+ border: 1px solid #e5e7eb;
81
+ padding: 10px 20px;
82
+ border-radius: 6px;
83
+ font-size: 14px;
84
+ font-weight: 500;
85
+ cursor: pointer;
86
+ transition: all 0.2s;
87
+ " onmouseover="this.style.background='#e5e7eb'" onmouseout="this.style.background='#f3f4f6'">
88
+ Dismiss
89
+ </button>
90
+ </div>
91
+ `;
92
+ errorDiv.appendChild(content);
93
+ document.body.appendChild(errorDiv);
94
+ console.error(
95
+ "%c\u26A0\uFE0F Enfyra SDK Configuration Error",
96
+ "color: #ef4444; font-size: 16px; font-weight: bold;",
97
+ "\n\n" + (config?.configErrorMessage || "Missing required configuration") + '\n\nPlease add the following to your nuxt.config.ts:\n\nenfyraSDK: {\n apiUrl: "https://your-api-url"\n}'
98
+ );
99
+ };
100
+ if (document.readyState === "loading") {
101
+ document.addEventListener("DOMContentLoaded", showError);
102
+ } else {
103
+ showError();
104
+ }
105
+ }
106
+ }
107
+ });
@@ -0,0 +1,107 @@
1
+ import { defineNuxtPlugin, useRuntimeConfig } from "#imports";
2
+ export default defineNuxtPlugin(() => {
3
+ const config = useRuntimeConfig().public?.enfyraSDK;
4
+ if (config?.configError) {
5
+ if (typeof window !== "undefined" && document) {
6
+ let showError = function() {
7
+ const errorDiv = document.createElement("div");
8
+ errorDiv.id = "enfyra-config-error";
9
+ errorDiv.style.cssText = `
10
+ position: fixed;
11
+ top: 0;
12
+ left: 0;
13
+ right: 0;
14
+ bottom: 0;
15
+ background: rgba(0, 0, 0, 0.9);
16
+ display: flex;
17
+ align-items: center;
18
+ justify-content: center;
19
+ z-index: 999999;
20
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
21
+ `;
22
+ const content = document.createElement("div");
23
+ content.style.cssText = `
24
+ background: white;
25
+ padding: 40px;
26
+ border-radius: 12px;
27
+ max-width: 600px;
28
+ width: 90%;
29
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
30
+ `;
31
+ content.innerHTML = `
32
+ <div style="display: flex; align-items: center; margin-bottom: 20px;">
33
+ <svg width="32" height="32" viewBox="0 0 24 24" fill="none" style="margin-right: 12px;">
34
+ <circle cx="12" cy="12" r="10" stroke="#ef4444" stroke-width="2"/>
35
+ <path d="M12 8v4M12 16h.01" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/>
36
+ </svg>
37
+ <h1 style="margin: 0; color: #1f2937; font-size: 24px; font-weight: 600;">
38
+ Configuration Error
39
+ </h1>
40
+ </div>
41
+
42
+ <div style="color: #4b5563; margin-bottom: 24px; line-height: 1.6;">
43
+ <p style="margin: 0 0 16px 0; font-size: 16px;">
44
+ <strong>Enfyra SDK</strong> is not configured properly.
45
+ </p>
46
+ <p style="margin: 0; color: #6b7280; font-size: 14px;">
47
+ ${config?.configErrorMessage || "Missing required configuration"}
48
+ </p>
49
+ </div>
50
+
51
+ <div style="background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 8px; padding: 16px; margin-bottom: 24px;">
52
+ <p style="margin: 0 0 12px 0; color: #6b7280; font-size: 13px; text-transform: uppercase; letter-spacing: 0.5px;">
53
+ Add to your nuxt.config.ts:
54
+ </p>
55
+ <pre style="margin: 0; background: #1f2937; color: #f3f4f6; padding: 16px; border-radius: 6px; overflow-x: auto; font-size: 14px; line-height: 1.4;"><code>export default defineNuxtConfig({
56
+ modules: ["@enfyra/sdk-nuxt"],
57
+ enfyraSDK: {
58
+ <span style="color: #fbbf24;">apiUrl</span>: <span style="color: #34d399;">"https://your-api-url"</span>
59
+ }
60
+ })</code></pre>
61
+ </div>
62
+
63
+ <div style="display: flex; gap: 12px;">
64
+ <button onclick="location.reload()" style="
65
+ background: #3b82f6;
66
+ color: white;
67
+ border: none;
68
+ padding: 10px 20px;
69
+ border-radius: 6px;
70
+ font-size: 14px;
71
+ font-weight: 500;
72
+ cursor: pointer;
73
+ transition: background 0.2s;
74
+ " onmouseover="this.style.background='#2563eb'" onmouseout="this.style.background='#3b82f6'">
75
+ Reload Page
76
+ </button>
77
+ <button onclick="document.getElementById('enfyra-config-error').style.display='none'" style="
78
+ background: #f3f4f6;
79
+ color: #4b5563;
80
+ border: 1px solid #e5e7eb;
81
+ padding: 10px 20px;
82
+ border-radius: 6px;
83
+ font-size: 14px;
84
+ font-weight: 500;
85
+ cursor: pointer;
86
+ transition: all 0.2s;
87
+ " onmouseover="this.style.background='#e5e7eb'" onmouseout="this.style.background='#f3f4f6'">
88
+ Dismiss
89
+ </button>
90
+ </div>
91
+ `;
92
+ errorDiv.appendChild(content);
93
+ document.body.appendChild(errorDiv);
94
+ console.error(
95
+ "%c\u26A0\uFE0F Enfyra SDK Configuration Error",
96
+ "color: #ef4444; font-size: 16px; font-weight: bold;",
97
+ "\n\n" + (config?.configErrorMessage || "Missing required configuration") + '\n\nPlease add the following to your nuxt.config.ts:\n\nenfyraSDK: {\n apiUrl: "https://your-api-url"\n}'
98
+ );
99
+ };
100
+ if (document.readyState === "loading") {
101
+ document.addEventListener("DOMContentLoaded", showError);
102
+ } else {
103
+ showError();
104
+ }
105
+ }
106
+ }
107
+ });
@@ -17,7 +17,7 @@ export default defineEventHandler(async (event) => {
17
17
  body = processedBody;
18
18
  const config = useRuntimeConfig();
19
19
  const apiPath = event.path.replace("/enfyra/api", "");
20
- const targetUrl = `${config.public.enfyraSDK.apiUrl}${apiPath}`;
20
+ const targetUrl = `${config.public?.enfyraSDK?.apiUrl}${apiPath}`;
21
21
  const response = await $fetch(targetUrl, {
22
22
  method: "PATCH",
23
23
  headers: {
@@ -17,7 +17,7 @@ export default defineEventHandler(async (event) => {
17
17
  body = processedBody;
18
18
  const config = useRuntimeConfig();
19
19
  const apiPath = event.path.replace("/enfyra/api", "");
20
- const targetUrl = `${config.public.enfyraSDK.apiUrl}${apiPath}`;
20
+ const targetUrl = `${config.public?.enfyraSDK?.apiUrl}${apiPath}`;
21
21
  const response = await $fetch(targetUrl, {
22
22
  method: "PATCH",
23
23
  headers: {
@@ -17,7 +17,7 @@ export default defineEventHandler(async (event) => {
17
17
  body = processedBody;
18
18
  const config = useRuntimeConfig();
19
19
  const apiPath = event.path.replace("/enfyra/api", "");
20
- const targetUrl = `${config.public.enfyraSDK.apiUrl}${apiPath}`;
20
+ const targetUrl = `${config.public?.enfyraSDK?.apiUrl}${apiPath}`;
21
21
  const response = await $fetch(targetUrl, {
22
22
  method,
23
23
  headers: {
@@ -17,7 +17,7 @@ export default defineEventHandler(async (event) => {
17
17
  body = processedBody;
18
18
  const config = useRuntimeConfig();
19
19
  const apiPath = event.path.replace("/enfyra/api", "");
20
- const targetUrl = `${config.public.enfyraSDK.apiUrl}${apiPath}`;
20
+ const targetUrl = `${config.public?.enfyraSDK?.apiUrl}${apiPath}`;
21
21
  const response = await $fetch(targetUrl, {
22
22
  method,
23
23
  headers: {