@uipkge/nuxt 0.1.1 → 0.1.4
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 +3 -5
- package/dist/module.json +1 -1
- package/dist/module.mjs +1 -5
- package/dist/runtime/plugin.client.js +10 -56
- package/dist/runtime/plugin.js +1 -0
- package/dist/runtime/plugin.suppress-warnings.js +12 -7
- package/dist/runtime/server/sync.js +1 -1
- package/package.json +17 -14
package/README.md
CHANGED
|
@@ -14,20 +14,18 @@ Nuxt module for [i18now](https://i18now.com) — loads translations from the i18
|
|
|
14
14
|
## Installation
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
npm install @uipkge/nuxt
|
|
17
|
+
npm install @uipkge/nuxt @nuxtjs/i18n
|
|
18
18
|
# or
|
|
19
|
-
pnpm add @uipkge/nuxt
|
|
19
|
+
pnpm add @uipkge/nuxt @nuxtjs/i18n
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
`@nuxtjs/i18n` is a dependency and will be installed automatically.
|
|
23
|
-
|
|
24
22
|
## Setup
|
|
25
23
|
|
|
26
24
|
Add the module to `nuxt.config.ts`:
|
|
27
25
|
|
|
28
26
|
```ts
|
|
29
27
|
export default defineNuxtConfig({
|
|
30
|
-
modules: ['@uipkge/nuxt'],
|
|
28
|
+
modules: ['@nuxtjs/i18n', '@uipkge/nuxt'],
|
|
31
29
|
|
|
32
30
|
i18now: {
|
|
33
31
|
projectId: process.env.I18NOW_PROJECT_ID ?? '',
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -6,11 +6,6 @@ const module$1 = defineNuxtModule({
|
|
|
6
6
|
configKey: "i18now",
|
|
7
7
|
compatibility: { nuxt: ">=3.0.0" }
|
|
8
8
|
},
|
|
9
|
-
// Auto-install @nuxtjs/i18n when the user hasn't added it themselves.
|
|
10
|
-
// It ships as a dependency of @uipkge/nuxt so no separate install is needed.
|
|
11
|
-
moduleDependencies: {
|
|
12
|
-
"@nuxtjs/i18n": { version: "^9.0.0 || ^10.0.0" }
|
|
13
|
-
},
|
|
14
9
|
defaults: {
|
|
15
10
|
host: "https://i18now.com",
|
|
16
11
|
cdnUrl: "https://cdn.i18now.com",
|
|
@@ -49,6 +44,7 @@ const module$1 = defineNuxtModule({
|
|
|
49
44
|
src: resolver.resolve("./runtime/plugin"),
|
|
50
45
|
mode: "server"
|
|
51
46
|
});
|
|
47
|
+
nuxt.options.build.transpile.push("@uipkge/core");
|
|
52
48
|
if (nuxt.options.dev) {
|
|
53
49
|
addServerHandler({
|
|
54
50
|
route: "/api/_i18now/sync",
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { defineNuxtPlugin, useRuntimeConfig } from "#app";
|
|
2
|
-
|
|
3
|
-
const MAX_RETRIES = 3;
|
|
2
|
+
import { createI18nowSyncer } from "@uipkge/core";
|
|
4
3
|
export default defineNuxtPlugin(async (nuxtApp) => {
|
|
5
4
|
const { projectId, cdnUrl, environment, syncIn, locale: configLocale } = useRuntimeConfig().public.i18now;
|
|
6
|
-
if (!syncIn.includes(
|
|
5
|
+
if (!syncIn.includes(process.env.NODE_ENV ?? "production")) return;
|
|
7
6
|
if (!projectId) {
|
|
8
7
|
console.warn("[i18now] projectId is not set \u2014 key sync disabled.");
|
|
9
8
|
return;
|
|
10
9
|
}
|
|
11
10
|
const i18nGlobal = nuxtApp.$i18n ?? nuxtApp.vueApp.config.globalProperties.$i18n;
|
|
12
|
-
const
|
|
11
|
+
const syncer = createI18nowSyncer({
|
|
12
|
+
endpoint: "/api/_i18now/sync",
|
|
13
|
+
debug: import.meta.dev
|
|
14
|
+
});
|
|
13
15
|
const locale = i18nGlobal?.locale?.value ?? i18nGlobal?.locale ?? configLocale;
|
|
14
16
|
async function loadLocale(targetLocale) {
|
|
15
17
|
try {
|
|
@@ -17,8 +19,7 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
17
19
|
const res = await fetch(url, { signal: AbortSignal.timeout(8e3) });
|
|
18
20
|
if (res.ok) {
|
|
19
21
|
const data = await res.json();
|
|
20
|
-
|
|
21
|
-
for (const key of Object.keys(data)) existingKeys.add(key);
|
|
22
|
+
syncer.setExistingKeys(Object.keys(data));
|
|
22
23
|
i18nGlobal?.setLocaleMessage(targetLocale, data);
|
|
23
24
|
} else if (import.meta.dev) {
|
|
24
25
|
console.warn(
|
|
@@ -32,59 +33,12 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
35
|
await loadLocale(locale);
|
|
35
|
-
const synced = /* @__PURE__ */ new Set();
|
|
36
|
-
const retries = /* @__PURE__ */ new Map();
|
|
37
|
-
const pending = /* @__PURE__ */ new Map();
|
|
38
|
-
let flushTimer = null;
|
|
39
|
-
function flush() {
|
|
40
|
-
flushTimer = null;
|
|
41
|
-
if (pending.size === 0) return;
|
|
42
|
-
const keys = Array.from(pending.entries()).map(([key, value]) => ({ key, value }));
|
|
43
|
-
pending.clear();
|
|
44
|
-
fetch("/api/_i18now/sync", {
|
|
45
|
-
method: "POST",
|
|
46
|
-
headers: { "Content-Type": "application/json" },
|
|
47
|
-
body: JSON.stringify({ keys })
|
|
48
|
-
}).then((res) => {
|
|
49
|
-
if (!res.ok) {
|
|
50
|
-
if (import.meta.dev) {
|
|
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}`));
|
|
52
|
-
}
|
|
53
|
-
throw Object.assign(new Error(`${res.status}`), { status: res.status });
|
|
54
|
-
}
|
|
55
|
-
}).catch((err) => {
|
|
56
|
-
const status = err.status ?? 0;
|
|
57
|
-
const retryable = status === 0 || status >= 500;
|
|
58
|
-
for (const { key } of keys) {
|
|
59
|
-
if (!retryable) {
|
|
60
|
-
retries.delete(key);
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
const attempts = (retries.get(key) ?? 0) + 1;
|
|
64
|
-
if (attempts < MAX_RETRIES) {
|
|
65
|
-
retries.set(key, attempts);
|
|
66
|
-
synced.delete(key);
|
|
67
|
-
} else {
|
|
68
|
-
retries.delete(key);
|
|
69
|
-
if (import.meta.dev) {
|
|
70
|
-
console.warn(`[i18now] Sync failed after ${MAX_RETRIES} attempts for key "${key}". Giving up.`);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
function syncKey(key, value) {
|
|
77
|
-
if (synced.has(key) || synced.size >= MAX_TRACKED) return;
|
|
78
|
-
synced.add(key);
|
|
79
|
-
pending.set(key, value);
|
|
80
|
-
if (!flushTimer) flushTimer = setTimeout(flush, 0);
|
|
81
|
-
}
|
|
82
36
|
const originalGlobalT = nuxtApp.vueApp.config.globalProperties.$t;
|
|
83
37
|
if (originalGlobalT) {
|
|
84
38
|
nuxtApp.vueApp.config.globalProperties.$t = function(key, defaultValue, ...rest) {
|
|
85
39
|
const result = originalGlobalT.call(this, key, defaultValue, ...rest);
|
|
86
|
-
if (!existingKeys.has(key) && typeof defaultValue === "string") {
|
|
87
|
-
syncKey(key, defaultValue);
|
|
40
|
+
if (!syncer.existingKeys.has(key) && typeof defaultValue === "string") {
|
|
41
|
+
syncer.syncKey(key, defaultValue);
|
|
88
42
|
}
|
|
89
43
|
return result;
|
|
90
44
|
};
|
|
@@ -94,7 +48,7 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
94
48
|
});
|
|
95
49
|
return {
|
|
96
50
|
provide: {
|
|
97
|
-
i18nowSync: { syncKey, existingKeys }
|
|
51
|
+
i18nowSync: { syncKey: syncer.syncKey, existingKeys: syncer.existingKeys }
|
|
98
52
|
}
|
|
99
53
|
};
|
|
100
54
|
});
|
package/dist/runtime/plugin.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { defineNuxtPlugin, useRuntimeConfig } from "#app";
|
|
2
2
|
export default defineNuxtPlugin(async (nuxtApp) => {
|
|
3
3
|
const { projectId, cdnUrl, environment, locale: configLocale } = useRuntimeConfig().public.i18now;
|
|
4
|
+
if (!projectId) return;
|
|
4
5
|
const i18n = nuxtApp.$i18n ?? nuxtApp.vueApp.config.globalProperties.$i18n;
|
|
5
6
|
async function loadLocale(locale) {
|
|
6
7
|
try {
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { defineNuxtPlugin } from "#app";
|
|
2
2
|
export default defineNuxtPlugin((nuxtApp) => {
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
const directGlobal = nuxtApp.$i18n?.global;
|
|
4
|
+
let symbolGlobal;
|
|
5
|
+
if (!directGlobal) {
|
|
6
|
+
const provides = nuxtApp.vueApp._context?.provides ?? {};
|
|
7
|
+
const i18nSym = Object.getOwnPropertySymbols(provides).find((s) => s.toString() === "Symbol(vue-i18n)");
|
|
8
|
+
const i18nInstance = i18nSym ? provides[i18nSym] : void 0;
|
|
9
|
+
symbolGlobal = i18nInstance?.global;
|
|
10
|
+
}
|
|
11
|
+
const globalComposer = directGlobal ?? symbolGlobal;
|
|
12
|
+
if (globalComposer) {
|
|
13
|
+
globalComposer.missingWarn = false;
|
|
14
|
+
globalComposer.fallbackWarn = false;
|
|
10
15
|
}
|
|
11
16
|
});
|
|
@@ -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 = process.env.NODE_ENV ?? "production";
|
|
6
6
|
if (!publicConfig?.syncIn?.includes(env)) {
|
|
7
7
|
throw createError({ statusCode: 403, statusMessage: "Key sync is disabled in this environment" });
|
|
8
8
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipkge/nuxt",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -12,32 +12,35 @@
|
|
|
12
12
|
"files": [
|
|
13
13
|
"dist"
|
|
14
14
|
],
|
|
15
|
-
"scripts": {
|
|
16
|
-
"build": "nuxt-module-build build",
|
|
17
|
-
"dev": "nuxt-module-build prepare",
|
|
18
|
-
"dev:playground": "nuxi dev playground",
|
|
19
|
-
"prepack": "nuxt-module-build build",
|
|
20
|
-
"test": "vitest run",
|
|
21
|
-
"test:watch": "vitest",
|
|
22
|
-
"test:coverage": "vitest run --coverage"
|
|
23
|
-
},
|
|
24
15
|
"dependencies": {
|
|
25
16
|
"@nuxt/kit": "^3.0.0",
|
|
26
|
-
"@
|
|
17
|
+
"@uipkge/core": "0.1.1"
|
|
27
18
|
},
|
|
28
19
|
"peerDependencies": {
|
|
29
|
-
"vue-i18n": "^9.0.0 || ^10.0.0 || ^11.0.0"
|
|
20
|
+
"vue-i18n": "^9.0.0 || ^10.0.0 || ^11.0.0",
|
|
21
|
+
"@nuxtjs/i18n": "^9.0.0 || ^10.0.0"
|
|
30
22
|
},
|
|
31
23
|
"peerDependenciesMeta": {
|
|
32
24
|
"vue-i18n": {
|
|
25
|
+
"optional": false
|
|
26
|
+
},
|
|
27
|
+
"@nuxtjs/i18n": {
|
|
33
28
|
"optional": true
|
|
34
29
|
}
|
|
35
30
|
},
|
|
36
31
|
"devDependencies": {
|
|
37
32
|
"@nuxt/module-builder": "^1.0.0",
|
|
38
|
-
"@uipkge/nuxt": "file:uipkge-nuxt-0.1.0.tgz",
|
|
39
33
|
"happy-dom": "^17.0.0",
|
|
40
34
|
"nuxt": "^3.0.0",
|
|
41
35
|
"vitest": "^4.0.0"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "nuxt-module-build build",
|
|
39
|
+
"dev": "nuxt-module-build prepare",
|
|
40
|
+
"dev:playground": "nuxi dev playground",
|
|
41
|
+
"test": "vitest run",
|
|
42
|
+
"test:watch": "vitest",
|
|
43
|
+
"test:coverage": "vitest run --coverage",
|
|
44
|
+
"release": "vitest run && nuxt-module-build build && pnpm publish --access public --no-git-checks"
|
|
42
45
|
}
|
|
43
|
-
}
|
|
46
|
+
}
|