@enfyra/sdk-nuxt 0.3.9 → 0.3.11
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/dist/composables/useEnfyraApi.mjs +7 -3
- package/dist/module.cjs +17 -10
- package/dist/module.d.cts +2 -0
- package/dist/module.d.mts +2 -0
- package/dist/module.d.ts +2 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +17 -10
- package/dist/runtime/server/api/login.post.js +2 -1
- package/dist/runtime/server/api/login.post.mjs +2 -1
- package/dist/runtime/server/api/logout.post.js +2 -1
- package/dist/runtime/server/api/logout.post.mjs +2 -1
- package/dist/utils/config.mjs +1 -5
- package/dist/utils/server/proxy.mjs +2 -1
- package/dist/utils/server/refreshToken.mjs +2 -1
- package/dist/utils/url.mjs +17 -0
- package/package.json +4 -9
- package/src/composables/useEnfyraApi.ts +7 -4
- package/src/constants/config.ts +0 -4
- package/src/module.ts +25 -9
- package/src/runtime/server/api/login.post.ts +2 -1
- package/src/runtime/server/api/logout.post.ts +2 -1
- package/src/utils/config.ts +1 -7
- package/src/utils/server/proxy.ts +2 -1
- package/src/utils/server/refreshToken.ts +2 -1
- package/src/utils/url.ts +39 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ref, unref, toRaw } from "vue";
|
|
2
2
|
import { $fetch } from "../utils/http";
|
|
3
|
-
import { getAppUrl } from "../utils/url";
|
|
3
|
+
import { getAppUrl, normalizeUrl } from "../utils/url";
|
|
4
4
|
import { ENFYRA_API_PREFIX } from "../constants/config";
|
|
5
5
|
import { useRuntimeConfig, useFetch, useRequestHeaders } from "#imports";
|
|
6
6
|
function handleError(error, context, customHandler) {
|
|
@@ -25,7 +25,11 @@ export function useEnfyraApi(path, opts = {}) {
|
|
|
25
25
|
const config = useRuntimeConfig().public.enfyraSDK;
|
|
26
26
|
const basePath = (typeof path === "function" ? path() : path).replace(/^\/?api\/?/, "").replace(/^\/+/, "");
|
|
27
27
|
const appUrl = getAppUrl();
|
|
28
|
-
const finalUrl =
|
|
28
|
+
const finalUrl = normalizeUrl(
|
|
29
|
+
appUrl,
|
|
30
|
+
config?.apiPrefix || ENFYRA_API_PREFIX,
|
|
31
|
+
basePath
|
|
32
|
+
);
|
|
29
33
|
const clientHeaders = process.client ? {} : useRequestHeaders([
|
|
30
34
|
"authorization",
|
|
31
35
|
"cookie",
|
|
@@ -76,7 +80,7 @@ export function useEnfyraApi(path, opts = {}) {
|
|
|
76
80
|
const buildPath = (...segments) => {
|
|
77
81
|
return segments.filter(Boolean).join("/");
|
|
78
82
|
};
|
|
79
|
-
const fullBaseURL = apiUrl
|
|
83
|
+
const fullBaseURL = normalizeUrl(apiUrl, apiPrefix || ENFYRA_API_PREFIX);
|
|
80
84
|
async function processBatch(items, processor) {
|
|
81
85
|
const results = [];
|
|
82
86
|
const progressResults = [];
|
package/dist/module.cjs
CHANGED
|
@@ -10,11 +10,18 @@ const module$1 = kit.defineNuxtModule({
|
|
|
10
10
|
configKey: "enfyraSDK"
|
|
11
11
|
},
|
|
12
12
|
defaults: {
|
|
13
|
-
apiUrl: ""
|
|
13
|
+
apiUrl: "",
|
|
14
|
+
apiPrefix: config_mjs.ENFYRA_API_PREFIX
|
|
14
15
|
},
|
|
15
16
|
setup(options, nuxt) {
|
|
17
|
+
const normalizedOptions = {
|
|
18
|
+
...options,
|
|
19
|
+
apiUrl: typeof options.apiUrl === "string" ? options.apiUrl.replace(/\/+$/, "") : options.apiUrl,
|
|
20
|
+
apiPrefix: typeof options.apiPrefix === "string" ? options.apiPrefix.trim() ? "/" + options.apiPrefix.replace(/^\/+|\/+$/g, "").replace(/\/+/g, "/") : config_mjs.ENFYRA_API_PREFIX : config_mjs.ENFYRA_API_PREFIX
|
|
21
|
+
};
|
|
22
|
+
const apiPrefix = normalizedOptions.apiPrefix;
|
|
16
23
|
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)));
|
|
17
|
-
if (!
|
|
24
|
+
if (!normalizedOptions.apiUrl) {
|
|
18
25
|
console.warn(
|
|
19
26
|
`[Enfyra SDK Nuxt] Missing required configuration:
|
|
20
27
|
- apiUrl is required
|
|
@@ -24,18 +31,18 @@ enfyraSDK: {
|
|
|
24
31
|
}`
|
|
25
32
|
);
|
|
26
33
|
nuxt.options.runtimeConfig.public.enfyraSDK = {
|
|
27
|
-
...
|
|
28
|
-
apiPrefix
|
|
34
|
+
...normalizedOptions,
|
|
35
|
+
apiPrefix,
|
|
29
36
|
configError: true,
|
|
30
37
|
configErrorMessage: "Enfyra SDK: apiUrl is required. Please configure it in nuxt.config.ts"
|
|
31
38
|
};
|
|
32
39
|
} else {
|
|
33
40
|
nuxt.options.runtimeConfig.public.enfyraSDK = {
|
|
34
|
-
...
|
|
35
|
-
apiPrefix
|
|
41
|
+
...normalizedOptions,
|
|
42
|
+
apiPrefix
|
|
36
43
|
};
|
|
37
44
|
}
|
|
38
|
-
if (!
|
|
45
|
+
if (!normalizedOptions.apiUrl) {
|
|
39
46
|
kit.addPlugin({
|
|
40
47
|
src: resolve("./runtime/plugin/config-error.client"),
|
|
41
48
|
mode: "client"
|
|
@@ -47,12 +54,12 @@ enfyraSDK: {
|
|
|
47
54
|
middleware: true
|
|
48
55
|
});
|
|
49
56
|
kit.addServerHandler({
|
|
50
|
-
route: `${
|
|
57
|
+
route: `${apiPrefix}/login`,
|
|
51
58
|
handler: resolve("./runtime/server/api/login.post"),
|
|
52
59
|
method: "post"
|
|
53
60
|
});
|
|
54
61
|
kit.addServerHandler({
|
|
55
|
-
route: `${
|
|
62
|
+
route: `${apiPrefix}/logout`,
|
|
56
63
|
handler: resolve("./runtime/server/api/logout.post"),
|
|
57
64
|
method: "post"
|
|
58
65
|
});
|
|
@@ -61,7 +68,7 @@ enfyraSDK: {
|
|
|
61
68
|
handler: resolve("./runtime/server/api/all")
|
|
62
69
|
});
|
|
63
70
|
kit.addServerHandler({
|
|
64
|
-
route: `${
|
|
71
|
+
route: `${apiPrefix}/**`,
|
|
65
72
|
handler: resolve("./runtime/server/api/all")
|
|
66
73
|
});
|
|
67
74
|
}
|
package/dist/module.d.cts
CHANGED
package/dist/module.d.mts
CHANGED
package/dist/module.d.ts
CHANGED
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -7,11 +7,18 @@ const module = defineNuxtModule({
|
|
|
7
7
|
configKey: "enfyraSDK"
|
|
8
8
|
},
|
|
9
9
|
defaults: {
|
|
10
|
-
apiUrl: ""
|
|
10
|
+
apiUrl: "",
|
|
11
|
+
apiPrefix: ENFYRA_API_PREFIX
|
|
11
12
|
},
|
|
12
13
|
setup(options, nuxt) {
|
|
14
|
+
const normalizedOptions = {
|
|
15
|
+
...options,
|
|
16
|
+
apiUrl: typeof options.apiUrl === "string" ? options.apiUrl.replace(/\/+$/, "") : options.apiUrl,
|
|
17
|
+
apiPrefix: typeof options.apiPrefix === "string" ? options.apiPrefix.trim() ? "/" + options.apiPrefix.replace(/^\/+|\/+$/g, "").replace(/\/+/g, "/") : ENFYRA_API_PREFIX : ENFYRA_API_PREFIX
|
|
18
|
+
};
|
|
19
|
+
const apiPrefix = normalizedOptions.apiPrefix;
|
|
13
20
|
const { resolve } = createResolver(import.meta.url);
|
|
14
|
-
if (!
|
|
21
|
+
if (!normalizedOptions.apiUrl) {
|
|
15
22
|
console.warn(
|
|
16
23
|
`[Enfyra SDK Nuxt] Missing required configuration:
|
|
17
24
|
- apiUrl is required
|
|
@@ -21,18 +28,18 @@ enfyraSDK: {
|
|
|
21
28
|
}`
|
|
22
29
|
);
|
|
23
30
|
nuxt.options.runtimeConfig.public.enfyraSDK = {
|
|
24
|
-
...
|
|
25
|
-
apiPrefix
|
|
31
|
+
...normalizedOptions,
|
|
32
|
+
apiPrefix,
|
|
26
33
|
configError: true,
|
|
27
34
|
configErrorMessage: "Enfyra SDK: apiUrl is required. Please configure it in nuxt.config.ts"
|
|
28
35
|
};
|
|
29
36
|
} else {
|
|
30
37
|
nuxt.options.runtimeConfig.public.enfyraSDK = {
|
|
31
|
-
...
|
|
32
|
-
apiPrefix
|
|
38
|
+
...normalizedOptions,
|
|
39
|
+
apiPrefix
|
|
33
40
|
};
|
|
34
41
|
}
|
|
35
|
-
if (!
|
|
42
|
+
if (!normalizedOptions.apiUrl) {
|
|
36
43
|
addPlugin({
|
|
37
44
|
src: resolve("./runtime/plugin/config-error.client"),
|
|
38
45
|
mode: "client"
|
|
@@ -44,12 +51,12 @@ enfyraSDK: {
|
|
|
44
51
|
middleware: true
|
|
45
52
|
});
|
|
46
53
|
addServerHandler({
|
|
47
|
-
route: `${
|
|
54
|
+
route: `${apiPrefix}/login`,
|
|
48
55
|
handler: resolve("./runtime/server/api/login.post"),
|
|
49
56
|
method: "post"
|
|
50
57
|
});
|
|
51
58
|
addServerHandler({
|
|
52
|
-
route: `${
|
|
59
|
+
route: `${apiPrefix}/logout`,
|
|
53
60
|
handler: resolve("./runtime/server/api/logout.post"),
|
|
54
61
|
method: "post"
|
|
55
62
|
});
|
|
@@ -58,7 +65,7 @@ enfyraSDK: {
|
|
|
58
65
|
handler: resolve("./runtime/server/api/all")
|
|
59
66
|
});
|
|
60
67
|
addServerHandler({
|
|
61
|
-
route: `${
|
|
68
|
+
route: `${apiPrefix}/**`,
|
|
62
69
|
handler: resolve("./runtime/server/api/all")
|
|
63
70
|
});
|
|
64
71
|
}
|
|
@@ -13,12 +13,13 @@ import {
|
|
|
13
13
|
REFRESH_TOKEN_KEY,
|
|
14
14
|
EXP_TIME_KEY
|
|
15
15
|
} from "../../../constants/auth";
|
|
16
|
+
import { normalizeUrl } from "../../../utils/url";
|
|
16
17
|
export default defineEventHandler(async (event) => {
|
|
17
18
|
const config = useRuntimeConfig();
|
|
18
19
|
const apiUrl = config.public.enfyraSDK?.apiUrl;
|
|
19
20
|
try {
|
|
20
21
|
const body = await readBody(event);
|
|
21
|
-
const response = await $fetch(
|
|
22
|
+
const response = await $fetch(normalizeUrl(apiUrl, "/auth/login"), {
|
|
22
23
|
method: "POST",
|
|
23
24
|
body,
|
|
24
25
|
headers: {
|
|
@@ -13,12 +13,13 @@ import {
|
|
|
13
13
|
REFRESH_TOKEN_KEY,
|
|
14
14
|
EXP_TIME_KEY
|
|
15
15
|
} from "../../../constants/auth";
|
|
16
|
+
import { normalizeUrl } from "../../../utils/url";
|
|
16
17
|
export default defineEventHandler(async (event) => {
|
|
17
18
|
const config = useRuntimeConfig();
|
|
18
19
|
const apiUrl = config.public.enfyraSDK?.apiUrl;
|
|
19
20
|
try {
|
|
20
21
|
const body = await readBody(event);
|
|
21
|
-
const response = await $fetch(
|
|
22
|
+
const response = await $fetch(normalizeUrl(apiUrl, "/auth/login"), {
|
|
22
23
|
method: "POST",
|
|
23
24
|
body,
|
|
24
25
|
headers: {
|
|
@@ -6,12 +6,13 @@ import {
|
|
|
6
6
|
REFRESH_TOKEN_KEY,
|
|
7
7
|
EXP_TIME_KEY
|
|
8
8
|
} from "../../../constants/auth";
|
|
9
|
+
import { normalizeUrl } from "../../../utils/url";
|
|
9
10
|
export default defineEventHandler(async (event) => {
|
|
10
11
|
const config = useRuntimeConfig();
|
|
11
12
|
const apiUrl = config.public?.enfyraSDK?.apiUrl;
|
|
12
13
|
const refreshToken = getCookie(event, REFRESH_TOKEN_KEY);
|
|
13
14
|
try {
|
|
14
|
-
const result = await $fetch(
|
|
15
|
+
const result = await $fetch(normalizeUrl(apiUrl, "/auth/logout"), {
|
|
15
16
|
method: "POST",
|
|
16
17
|
headers: {
|
|
17
18
|
cookie: getHeader(event, "cookie") || "",
|
|
@@ -6,12 +6,13 @@ import {
|
|
|
6
6
|
REFRESH_TOKEN_KEY,
|
|
7
7
|
EXP_TIME_KEY
|
|
8
8
|
} from "../../../constants/auth";
|
|
9
|
+
import { normalizeUrl } from "../../../utils/url";
|
|
9
10
|
export default defineEventHandler(async (event) => {
|
|
10
11
|
const config = useRuntimeConfig();
|
|
11
12
|
const apiUrl = config.public?.enfyraSDK?.apiUrl;
|
|
12
13
|
const refreshToken = getCookie(event, REFRESH_TOKEN_KEY);
|
|
13
14
|
try {
|
|
14
|
-
const result = await $fetch(
|
|
15
|
+
const result = await $fetch(normalizeUrl(apiUrl, "/auth/logout"), {
|
|
15
16
|
method: "POST",
|
|
16
17
|
headers: {
|
|
17
18
|
cookie: getHeader(event, "cookie") || "",
|
package/dist/utils/config.mjs
CHANGED
|
@@ -5,11 +5,7 @@ const config = ref({
|
|
|
5
5
|
});
|
|
6
6
|
export function useEnfyraConfig() {
|
|
7
7
|
const setConfig = (newConfig) => {
|
|
8
|
-
|
|
9
|
-
if (typeof normalizedConfig.apiUrl === "string") {
|
|
10
|
-
normalizedConfig.apiUrl = normalizedConfig.apiUrl.replace(/\/+$/, "");
|
|
11
|
-
}
|
|
12
|
-
config.value = { ...config.value, ...normalizedConfig };
|
|
8
|
+
config.value = { ...config.value, ...newConfig };
|
|
13
9
|
};
|
|
14
10
|
const getConfig = () => config.value;
|
|
15
11
|
return {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { proxyRequest } from "h3";
|
|
2
2
|
import { useRuntimeConfig } from "#imports";
|
|
3
3
|
import { ENFYRA_API_PREFIX } from "../../constants/config";
|
|
4
|
+
import { normalizeUrl } from "../../utils/url";
|
|
4
5
|
export function proxyToAPI(event, customPath) {
|
|
5
6
|
const config = useRuntimeConfig();
|
|
6
7
|
const apiPrefix = config.public?.enfyraSDK?.apiPrefix || ENFYRA_API_PREFIX;
|
|
7
8
|
const rawPath = customPath || event.path.replace(new RegExp(`^${apiPrefix}`), "");
|
|
8
|
-
const targetUrl =
|
|
9
|
+
const targetUrl = normalizeUrl(config.public?.enfyraSDK?.apiUrl, rawPath);
|
|
9
10
|
const headers = event.context.proxyHeaders || {};
|
|
10
11
|
return proxyRequest(event, targetUrl, {
|
|
11
12
|
headers
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
REFRESH_TOKEN_KEY,
|
|
6
6
|
EXP_TIME_KEY
|
|
7
7
|
} from "../../constants/auth";
|
|
8
|
+
import { normalizeUrl } from "../../utils/url";
|
|
8
9
|
export function decodeJWT(token) {
|
|
9
10
|
try {
|
|
10
11
|
const parts = token.split(".");
|
|
@@ -39,7 +40,7 @@ export function validateTokens(event) {
|
|
|
39
40
|
}
|
|
40
41
|
export async function refreshAccessToken(event, refreshToken, apiUrl) {
|
|
41
42
|
try {
|
|
42
|
-
const response = await $fetch(
|
|
43
|
+
const response = await $fetch(normalizeUrl(apiUrl, "/auth/refresh-token"), {
|
|
43
44
|
method: "POST",
|
|
44
45
|
body: { refreshToken }
|
|
45
46
|
});
|
package/dist/utils/url.mjs
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
export function normalizeUrl(...segments) {
|
|
2
|
+
const validSegments = segments.filter((s) => Boolean(s));
|
|
3
|
+
if (validSegments.length === 0) return "";
|
|
4
|
+
let result = validSegments[0].replace(/\/+$/, "");
|
|
5
|
+
for (let i = 1; i < validSegments.length; i++) {
|
|
6
|
+
const segment = validSegments[i].replace(/^\/+/, "").replace(/\/+$/, "").replace(/\/+/g, "/");
|
|
7
|
+
if (segment) {
|
|
8
|
+
result += "/" + segment;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
export function joinUrlPath(...paths) {
|
|
14
|
+
const validPaths = paths.filter((p) => Boolean(p));
|
|
15
|
+
if (validPaths.length === 0) return "";
|
|
16
|
+
return validPaths.map((path) => path.replace(/^\/+/, "").replace(/\/+$/, "")).filter(Boolean).join("/");
|
|
17
|
+
}
|
|
1
18
|
export function getAppUrl() {
|
|
2
19
|
if (process.client && typeof window !== "undefined") {
|
|
3
20
|
return window.location.origin;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enfyra/sdk-nuxt",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.11",
|
|
4
4
|
"description": "Nuxt SDK for Enfyra CMS",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -47,20 +47,15 @@
|
|
|
47
47
|
"vue": "^3.0.0"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@vitejs/plugin-vue": "^5.2.0",
|
|
51
|
-
"cookie": "^0.6.0",
|
|
52
|
-
"glob": "^8.1.0",
|
|
53
50
|
"h3": "^1.15.4",
|
|
54
|
-
"
|
|
55
|
-
"nuxt": "^3.18.1",
|
|
56
|
-
"ofetch": "^1.3.3",
|
|
57
|
-
"vite": "^6.0.7"
|
|
51
|
+
"ofetch": "^1.3.3"
|
|
58
52
|
},
|
|
59
53
|
"devDependencies": {
|
|
60
54
|
"@nuxt/module-builder": "^0.8.4",
|
|
61
|
-
"@types/cookie": "^0.6.0",
|
|
62
55
|
"@vitest/ui": "^3.2.4",
|
|
56
|
+
"nuxt": "^3.18.1",
|
|
63
57
|
"typescript": "^5.0.0",
|
|
58
|
+
"vite": "^6.0.7",
|
|
64
59
|
"vite-plugin-dts": "^4.3.0",
|
|
65
60
|
"vitest": "^3.2.4"
|
|
66
61
|
}
|
|
@@ -8,7 +8,7 @@ import type {
|
|
|
8
8
|
BatchProgress,
|
|
9
9
|
} from "../types";
|
|
10
10
|
import { $fetch } from "../utils/http";
|
|
11
|
-
import { getAppUrl } from "../utils/url";
|
|
11
|
+
import { getAppUrl, normalizeUrl } from "../utils/url";
|
|
12
12
|
import { ENFYRA_API_PREFIX } from "../constants/config";
|
|
13
13
|
|
|
14
14
|
import { useRuntimeConfig, useFetch, useRequestHeaders } from "#imports";
|
|
@@ -59,8 +59,11 @@ export function useEnfyraApi<T = any>(
|
|
|
59
59
|
.replace(/^\/+/, "");
|
|
60
60
|
|
|
61
61
|
const appUrl = getAppUrl();
|
|
62
|
-
const finalUrl =
|
|
63
|
-
appUrl
|
|
62
|
+
const finalUrl = normalizeUrl(
|
|
63
|
+
appUrl,
|
|
64
|
+
config?.apiPrefix || ENFYRA_API_PREFIX,
|
|
65
|
+
basePath
|
|
66
|
+
);
|
|
64
67
|
|
|
65
68
|
const clientHeaders = process.client
|
|
66
69
|
? {}
|
|
@@ -141,7 +144,7 @@ export function useEnfyraApi<T = any>(
|
|
|
141
144
|
return segments.filter(Boolean).join("/");
|
|
142
145
|
};
|
|
143
146
|
|
|
144
|
-
const fullBaseURL = apiUrl
|
|
147
|
+
const fullBaseURL = normalizeUrl(apiUrl, apiPrefix || ENFYRA_API_PREFIX);
|
|
145
148
|
|
|
146
149
|
async function processBatch<T>(
|
|
147
150
|
items: any[],
|
package/src/constants/config.ts
CHANGED
package/src/module.ts
CHANGED
|
@@ -14,11 +14,27 @@ export default defineNuxtModule({
|
|
|
14
14
|
},
|
|
15
15
|
defaults: {
|
|
16
16
|
apiUrl: "",
|
|
17
|
+
apiPrefix: ENFYRA_API_PREFIX,
|
|
17
18
|
},
|
|
18
19
|
setup(options, nuxt) {
|
|
20
|
+
const normalizedOptions = {
|
|
21
|
+
...options,
|
|
22
|
+
apiUrl:
|
|
23
|
+
typeof options.apiUrl === "string"
|
|
24
|
+
? options.apiUrl.replace(/\/+$/, "")
|
|
25
|
+
: options.apiUrl,
|
|
26
|
+
apiPrefix:
|
|
27
|
+
typeof options.apiPrefix === "string"
|
|
28
|
+
? (options.apiPrefix.trim()
|
|
29
|
+
? "/" + options.apiPrefix.replace(/^\/+|\/+$/g, "").replace(/\/+/g, "/")
|
|
30
|
+
: ENFYRA_API_PREFIX)
|
|
31
|
+
: ENFYRA_API_PREFIX,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const apiPrefix = normalizedOptions.apiPrefix;
|
|
19
35
|
const { resolve } = createResolver(import.meta.url);
|
|
20
36
|
|
|
21
|
-
if (!
|
|
37
|
+
if (!normalizedOptions.apiUrl) {
|
|
22
38
|
console.warn(
|
|
23
39
|
`[Enfyra SDK Nuxt] Missing required configuration:\n` +
|
|
24
40
|
`- apiUrl is required\n` +
|
|
@@ -29,20 +45,20 @@ export default defineNuxtModule({
|
|
|
29
45
|
);
|
|
30
46
|
|
|
31
47
|
nuxt.options.runtimeConfig.public.enfyraSDK = {
|
|
32
|
-
...
|
|
33
|
-
apiPrefix:
|
|
48
|
+
...normalizedOptions,
|
|
49
|
+
apiPrefix: apiPrefix,
|
|
34
50
|
configError: true,
|
|
35
51
|
configErrorMessage: 'Enfyra SDK: apiUrl is required. Please configure it in nuxt.config.ts'
|
|
36
52
|
};
|
|
37
53
|
} else {
|
|
38
54
|
nuxt.options.runtimeConfig.public.enfyraSDK = {
|
|
39
|
-
...
|
|
40
|
-
apiPrefix:
|
|
55
|
+
...normalizedOptions,
|
|
56
|
+
apiPrefix: apiPrefix,
|
|
41
57
|
};
|
|
42
58
|
}
|
|
43
59
|
|
|
44
60
|
|
|
45
|
-
if (!
|
|
61
|
+
if (!normalizedOptions.apiUrl) {
|
|
46
62
|
addPlugin({
|
|
47
63
|
src: resolve("./runtime/plugin/config-error.client"),
|
|
48
64
|
mode: 'client'
|
|
@@ -57,13 +73,13 @@ export default defineNuxtModule({
|
|
|
57
73
|
});
|
|
58
74
|
|
|
59
75
|
addServerHandler({
|
|
60
|
-
route: `${
|
|
76
|
+
route: `${apiPrefix}/login`,
|
|
61
77
|
handler: resolve("./runtime/server/api/login.post"),
|
|
62
78
|
method: "post",
|
|
63
79
|
});
|
|
64
80
|
|
|
65
81
|
addServerHandler({
|
|
66
|
-
route: `${
|
|
82
|
+
route: `${apiPrefix}/logout`,
|
|
67
83
|
handler: resolve("./runtime/server/api/logout.post"),
|
|
68
84
|
method: "post",
|
|
69
85
|
});
|
|
@@ -75,7 +91,7 @@ export default defineNuxtModule({
|
|
|
75
91
|
});
|
|
76
92
|
|
|
77
93
|
addServerHandler({
|
|
78
|
-
route: `${
|
|
94
|
+
route: `${apiPrefix}/**`,
|
|
79
95
|
handler: resolve("./runtime/server/api/all"),
|
|
80
96
|
});
|
|
81
97
|
},
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
REFRESH_TOKEN_KEY,
|
|
14
14
|
EXP_TIME_KEY,
|
|
15
15
|
} from "../../../constants/auth";
|
|
16
|
+
import { normalizeUrl } from "../../../utils/url";
|
|
16
17
|
|
|
17
18
|
export default defineEventHandler(async (event) => {
|
|
18
19
|
const config = useRuntimeConfig();
|
|
@@ -20,7 +21,7 @@ export default defineEventHandler(async (event) => {
|
|
|
20
21
|
|
|
21
22
|
try {
|
|
22
23
|
const body = await readBody(event);
|
|
23
|
-
const response = await $fetch<any>(
|
|
24
|
+
const response = await $fetch<any>(normalizeUrl(apiUrl, "/auth/login"), {
|
|
24
25
|
method: "POST",
|
|
25
26
|
body,
|
|
26
27
|
headers: {
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
REFRESH_TOKEN_KEY,
|
|
7
7
|
EXP_TIME_KEY,
|
|
8
8
|
} from "../../../constants/auth";
|
|
9
|
+
import { normalizeUrl } from "../../../utils/url";
|
|
9
10
|
|
|
10
11
|
export default defineEventHandler(async (event) => {
|
|
11
12
|
const config = useRuntimeConfig();
|
|
@@ -14,7 +15,7 @@ export default defineEventHandler(async (event) => {
|
|
|
14
15
|
const refreshToken = getCookie(event, REFRESH_TOKEN_KEY);
|
|
15
16
|
|
|
16
17
|
try {
|
|
17
|
-
const result = await $fetch(
|
|
18
|
+
const result = await $fetch(normalizeUrl(apiUrl, "/auth/logout"), {
|
|
18
19
|
method: "POST",
|
|
19
20
|
headers: {
|
|
20
21
|
cookie: getHeader(event, "cookie") || "",
|
package/src/utils/config.ts
CHANGED
|
@@ -8,13 +8,7 @@ const config = ref<EnfyraConfig>({
|
|
|
8
8
|
|
|
9
9
|
export function useEnfyraConfig() {
|
|
10
10
|
const setConfig = (newConfig: Partial<EnfyraConfig>) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (typeof normalizedConfig.apiUrl === 'string') {
|
|
14
|
-
normalizedConfig.apiUrl = normalizedConfig.apiUrl.replace(/\/+$/, '');
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
config.value = { ...config.value, ...normalizedConfig };
|
|
11
|
+
config.value = { ...config.value, ...newConfig };
|
|
18
12
|
};
|
|
19
13
|
|
|
20
14
|
const getConfig = () => config.value;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { H3Event, proxyRequest } from "h3";
|
|
2
2
|
import { useRuntimeConfig } from "#imports";
|
|
3
3
|
import { ENFYRA_API_PREFIX } from "../../constants/config";
|
|
4
|
+
import { normalizeUrl } from "../../utils/url";
|
|
4
5
|
|
|
5
6
|
export function proxyToAPI(event: H3Event, customPath?: string) {
|
|
6
7
|
const config = useRuntimeConfig();
|
|
7
8
|
const apiPrefix = config.public?.enfyraSDK?.apiPrefix || ENFYRA_API_PREFIX;
|
|
8
9
|
const rawPath =
|
|
9
10
|
customPath || event.path.replace(new RegExp(`^${apiPrefix}`), "");
|
|
10
|
-
const targetUrl =
|
|
11
|
+
const targetUrl = normalizeUrl(config.public?.enfyraSDK?.apiUrl, rawPath);
|
|
11
12
|
|
|
12
13
|
const headers = event.context.proxyHeaders || {};
|
|
13
14
|
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
REFRESH_TOKEN_KEY,
|
|
6
6
|
EXP_TIME_KEY,
|
|
7
7
|
} from "../../constants/auth";
|
|
8
|
+
import { normalizeUrl } from "../../utils/url";
|
|
8
9
|
|
|
9
10
|
interface TokenValidationResult {
|
|
10
11
|
accessToken: string | null;
|
|
@@ -58,7 +59,7 @@ export async function refreshAccessToken(
|
|
|
58
59
|
apiUrl: string
|
|
59
60
|
): Promise<string> {
|
|
60
61
|
try {
|
|
61
|
-
const response = await $fetch(
|
|
62
|
+
const response = await $fetch(normalizeUrl(apiUrl, "/auth/refresh-token"), {
|
|
62
63
|
method: "POST",
|
|
63
64
|
body: { refreshToken },
|
|
64
65
|
});
|
package/src/utils/url.ts
CHANGED
|
@@ -1,3 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes URL segments to avoid double slashes when concatenating
|
|
3
|
+
* Removes trailing slashes from base URL and leading slashes from path segments
|
|
4
|
+
* Also normalizes multiple consecutive slashes within segments
|
|
5
|
+
*/
|
|
6
|
+
export function normalizeUrl(...segments: (string | undefined | null)[]): string {
|
|
7
|
+
const validSegments = segments.filter((s): s is string => Boolean(s));
|
|
8
|
+
if (validSegments.length === 0) return '';
|
|
9
|
+
|
|
10
|
+
// First segment is the base URL - remove trailing slashes
|
|
11
|
+
let result = validSegments[0].replace(/\/+$/, '');
|
|
12
|
+
|
|
13
|
+
// For remaining segments, remove leading and trailing slashes, normalize internal slashes, then join
|
|
14
|
+
for (let i = 1; i < validSegments.length; i++) {
|
|
15
|
+
const segment = validSegments[i]
|
|
16
|
+
.replace(/^\/+/, '') // Remove leading slashes
|
|
17
|
+
.replace(/\/+$/, '') // Remove trailing slashes
|
|
18
|
+
.replace(/\/+/g, '/'); // Normalize multiple consecutive slashes to single slash
|
|
19
|
+
if (segment) {
|
|
20
|
+
result += '/' + segment;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Joins URL paths safely, avoiding double slashes
|
|
29
|
+
*/
|
|
30
|
+
export function joinUrlPath(...paths: (string | undefined | null)[]): string {
|
|
31
|
+
const validPaths = paths.filter((p): p is string => Boolean(p));
|
|
32
|
+
if (validPaths.length === 0) return '';
|
|
33
|
+
|
|
34
|
+
return validPaths
|
|
35
|
+
.map(path => path.replace(/^\/+/, '').replace(/\/+$/, ''))
|
|
36
|
+
.filter(Boolean)
|
|
37
|
+
.join('/');
|
|
38
|
+
}
|
|
39
|
+
|
|
1
40
|
export function getAppUrl(): string {
|
|
2
41
|
if (process.client && typeof window !== 'undefined') {
|
|
3
42
|
return window.location.origin;
|