@uipkge/nuxt 0.1.0 → 0.1.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/dist/module.json +1 -1
- package/dist/module.mjs +1 -1
- package/dist/runtime/plugin.client.js +16 -9
- package/dist/runtime/plugin.js +10 -3
- package/dist/runtime/server/sync.js +9 -3
- package/package.json +10 -5
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -9,7 +9,7 @@ const module$1 = defineNuxtModule({
|
|
|
9
9
|
// Auto-install @nuxtjs/i18n when the user hasn't added it themselves.
|
|
10
10
|
// It ships as a dependency of @uipkge/nuxt so no separate install is needed.
|
|
11
11
|
moduleDependencies: {
|
|
12
|
-
"@nuxtjs/i18n": { version: "^9.0.0" }
|
|
12
|
+
"@nuxtjs/i18n": { version: "^9.0.0 || ^10.0.0" }
|
|
13
13
|
},
|
|
14
14
|
defaults: {
|
|
15
15
|
host: "https://i18now.com",
|
|
@@ -3,7 +3,7 @@ const MAX_TRACKED = 2e3;
|
|
|
3
3
|
const MAX_RETRIES = 3;
|
|
4
4
|
export default defineNuxtPlugin(async (nuxtApp) => {
|
|
5
5
|
const { projectId, cdnUrl, environment, syncIn, locale: configLocale } = useRuntimeConfig().public.i18now;
|
|
6
|
-
if (!syncIn.includes(
|
|
6
|
+
if (!syncIn.includes(import.meta.dev ? "development" : "production")) return;
|
|
7
7
|
if (!projectId) {
|
|
8
8
|
console.warn("[i18now] projectId is not set \u2014 key sync disabled.");
|
|
9
9
|
return;
|
|
@@ -13,19 +13,20 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
13
13
|
const locale = i18nGlobal?.locale?.value ?? i18nGlobal?.locale ?? configLocale;
|
|
14
14
|
async function loadLocale(targetLocale) {
|
|
15
15
|
try {
|
|
16
|
-
const
|
|
16
|
+
const url = `${cdnUrl}/${projectId}/publish/${environment}/${targetLocale}.json`;
|
|
17
|
+
const res = await fetch(url, { signal: AbortSignal.timeout(8e3) });
|
|
17
18
|
if (res.ok) {
|
|
18
19
|
const data = await res.json();
|
|
19
20
|
existingKeys.clear();
|
|
20
21
|
for (const key of Object.keys(data)) existingKeys.add(key);
|
|
21
22
|
i18nGlobal?.setLocaleMessage(targetLocale, data);
|
|
22
|
-
} else if (
|
|
23
|
+
} else if (import.meta.dev) {
|
|
23
24
|
console.warn(
|
|
24
|
-
`[i18now] Could not load translations from CDN (${res.status}). All keys will be sent to sync \u2014 this is safe, the backend deduplicates them. URL: ${
|
|
25
|
+
`[i18now] Could not load translations from CDN (${res.status}). All keys will be sent to sync \u2014 this is safe, the backend deduplicates them. URL: ${url}`
|
|
25
26
|
);
|
|
26
27
|
}
|
|
27
28
|
} catch (err) {
|
|
28
|
-
if (
|
|
29
|
+
if (import.meta.dev) {
|
|
29
30
|
console.warn(`[i18now] CDN fetch failed for locale '${targetLocale}':`, err);
|
|
30
31
|
}
|
|
31
32
|
}
|
|
@@ -46,20 +47,26 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
46
47
|
body: JSON.stringify({ keys })
|
|
47
48
|
}).then((res) => {
|
|
48
49
|
if (!res.ok) {
|
|
49
|
-
if (
|
|
50
|
+
if (import.meta.dev) {
|
|
50
51
|
res.json().then((data) => console.warn(`[i18now] Sync failed (${res.status}):`, data?.statusMessage ?? data)).catch(() => console.warn(`[i18now] Sync failed with status ${res.status}`));
|
|
51
52
|
}
|
|
52
|
-
throw new Error(`${res.status}`);
|
|
53
|
+
throw Object.assign(new Error(`${res.status}`), { status: res.status });
|
|
53
54
|
}
|
|
54
|
-
}).catch(() => {
|
|
55
|
+
}).catch((err) => {
|
|
56
|
+
const status = err.status ?? 0;
|
|
57
|
+
const retryable = status === 0 || status >= 500;
|
|
55
58
|
for (const { key } of keys) {
|
|
59
|
+
if (!retryable) {
|
|
60
|
+
retries.delete(key);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
56
63
|
const attempts = (retries.get(key) ?? 0) + 1;
|
|
57
64
|
if (attempts < MAX_RETRIES) {
|
|
58
65
|
retries.set(key, attempts);
|
|
59
66
|
synced.delete(key);
|
|
60
67
|
} else {
|
|
61
68
|
retries.delete(key);
|
|
62
|
-
if (
|
|
69
|
+
if (import.meta.dev) {
|
|
63
70
|
console.warn(`[i18now] Sync failed after ${MAX_RETRIES} attempts for key "${key}". Giving up.`);
|
|
64
71
|
}
|
|
65
72
|
}
|
package/dist/runtime/plugin.js
CHANGED
|
@@ -5,12 +5,19 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
5
5
|
async function loadLocale(locale) {
|
|
6
6
|
try {
|
|
7
7
|
const url = `${cdnUrl}/${projectId}/publish/${environment}/${locale}.json`;
|
|
8
|
-
const res = await fetch(url);
|
|
9
|
-
if (!res.ok)
|
|
8
|
+
const res = await fetch(url, { signal: AbortSignal.timeout(8e3) });
|
|
9
|
+
if (!res.ok) {
|
|
10
|
+
if (import.meta.dev) {
|
|
11
|
+
console.warn(
|
|
12
|
+
`[i18now] Could not load locale '${locale}' from CDN (${res.status}). Default values will be used as fallback. URL: ${url}`
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
10
17
|
const messages = await res.json();
|
|
11
18
|
if (i18n) i18n.setLocaleMessage(locale, messages);
|
|
12
19
|
} catch (err) {
|
|
13
|
-
if (
|
|
20
|
+
if (import.meta.dev) {
|
|
14
21
|
console.warn(`[i18now] Failed to load locale '${locale}' from CDN:`, err);
|
|
15
22
|
}
|
|
16
23
|
}
|
|
@@ -2,7 +2,7 @@ import { createError, defineEventHandler, readBody } from "h3";
|
|
|
2
2
|
export default defineEventHandler(async (event) => {
|
|
3
3
|
const config = useRuntimeConfig(event);
|
|
4
4
|
const publicConfig = config.public?.i18now;
|
|
5
|
-
const env =
|
|
5
|
+
const env = import.meta.dev ? "development" : "production";
|
|
6
6
|
if (!publicConfig?.syncIn?.includes(env)) {
|
|
7
7
|
throw createError({ statusCode: 403, statusMessage: "Key sync is disabled in this environment" });
|
|
8
8
|
}
|
|
@@ -23,7 +23,13 @@ export default defineEventHandler(async (event) => {
|
|
|
23
23
|
if (!Array.isArray(body?.keys)) {
|
|
24
24
|
throw createError({ statusCode: 400, statusMessage: 'Request body must contain a "keys" array' });
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
const validKeys = body.keys.filter(
|
|
27
|
+
(item) => item !== null && typeof item === "object" && typeof item.key === "string" && item.key.length > 0 && typeof item.value === "string" && item.value.length > 0
|
|
28
|
+
);
|
|
29
|
+
if (validKeys.length === 0) {
|
|
30
|
+
return { synced: 0 };
|
|
31
|
+
}
|
|
32
|
+
if (validKeys.length > 100) {
|
|
27
33
|
throw createError({ statusCode: 400, statusMessage: "Maximum 100 keys per request" });
|
|
28
34
|
}
|
|
29
35
|
const res = await fetch(
|
|
@@ -31,7 +37,7 @@ export default defineEventHandler(async (event) => {
|
|
|
31
37
|
{
|
|
32
38
|
method: "POST",
|
|
33
39
|
headers: { "Content-Type": "application/json" },
|
|
34
|
-
body: JSON.stringify({ apiKey, keys:
|
|
40
|
+
body: JSON.stringify({ apiKey, keys: validKeys })
|
|
35
41
|
}
|
|
36
42
|
);
|
|
37
43
|
const data = await res.json();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipkge/nuxt",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
11
|
"main": "./dist/module.mjs",
|
|
12
|
-
"files": [
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
13
15
|
"scripts": {
|
|
14
16
|
"build": "nuxt-module-build build",
|
|
15
17
|
"dev": "nuxt-module-build prepare",
|
|
@@ -21,16 +23,19 @@
|
|
|
21
23
|
},
|
|
22
24
|
"dependencies": {
|
|
23
25
|
"@nuxt/kit": "^3.0.0",
|
|
24
|
-
"@nuxtjs/i18n": "^9.0.0"
|
|
26
|
+
"@nuxtjs/i18n": "^9.0.0 || ^10.0.0"
|
|
25
27
|
},
|
|
26
28
|
"peerDependencies": {
|
|
27
|
-
"vue-i18n": "^9.0.0 || ^10.0.0"
|
|
29
|
+
"vue-i18n": "^9.0.0 || ^10.0.0 || ^11.0.0"
|
|
28
30
|
},
|
|
29
31
|
"peerDependenciesMeta": {
|
|
30
|
-
"vue-i18n": {
|
|
32
|
+
"vue-i18n": {
|
|
33
|
+
"optional": true
|
|
34
|
+
}
|
|
31
35
|
},
|
|
32
36
|
"devDependencies": {
|
|
33
37
|
"@nuxt/module-builder": "^1.0.0",
|
|
38
|
+
"@uipkge/nuxt": "file:uipkge-nuxt-0.1.0.tgz",
|
|
34
39
|
"happy-dom": "^17.0.0",
|
|
35
40
|
"nuxt": "^3.0.0",
|
|
36
41
|
"vitest": "^4.0.0"
|