nuxt-i18n-micro 3.18.3 → 3.19.0
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/client/200.html +1 -1
- package/dist/client/404.html +1 -1
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/bbe443af-4371-4ec3-b41c-7a5e9deb9b9b.json +1 -0
- package/dist/client/index.html +1 -1
- package/dist/module.d.mts +1 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +57 -149
- package/dist/runtime/composables/useI18nLocale.js +3 -3
- package/dist/runtime/composables/useLocaleHead.js +1 -1
- package/dist/runtime/plugins/01.plugin.js +6 -3
- package/dist/runtime/plugins/02.meta.js +2 -2
- package/dist/runtime/plugins/05.hooks.js +1 -1
- package/dist/runtime/plugins/06.redirect.js +4 -4
- package/dist/runtime/server/middleware/i18n.global.js +4 -4
- package/dist/runtime/server/plugins/watcher.dev.js +36 -66
- package/dist/runtime/server/routes/i18n.js +2 -2
- package/dist/runtime/server/utils/locale-detector.js +11 -1
- package/dist/runtime/server/utils/locale-server-middleware.js +2 -2
- package/dist/runtime/server/utils/server-loader.d.ts +3 -3
- package/dist/runtime/server/utils/server-loader.js +32 -8
- package/dist/runtime/server/utils/translation-server-middleware.js +2 -2
- package/dist/runtime/utils/storage.d.ts +4 -6
- package/dist/runtime/utils/storage.js +20 -11
- package/dist/types.d.mts +2 -0
- package/package.json +11 -8
- package/dist/client/_nuxt/builds/meta/c5d2004e-f981-4363-a9ec-4d72cf7f4a8f.json +0 -1
- package/dist/runtime/utils/accept-language.d.ts +0 -3
- package/dist/runtime/utils/accept-language.js +0 -21
- package/dist/runtime/utils/active-locales.d.ts +0 -4
- package/dist/runtime/utils/active-locales.js +0 -9
- package/dist/runtime/utils/cache-control.d.ts +0 -50
- package/dist/runtime/utils/cache-control.js +0 -88
- package/dist/runtime/utils/cookie.d.ts +0 -24
- package/dist/runtime/utils/cookie.js +0 -22
- package/dist/runtime/utils/deep-merge.d.ts +0 -15
- package/dist/runtime/utils/deep-merge.js +0 -14
- package/dist/runtime/utils/resolve-server-locale.d.ts +0 -21
- package/dist/runtime/utils/resolve-server-locale.js +0 -30
- package/dist/runtime/utils/route-utils.d.ts +0 -33
- package/dist/runtime/utils/route-utils.js +0 -63
- package/dist/runtime/utils/runtime-i18n-config.d.ts +0 -8
- package/dist/runtime/utils/runtime-i18n-config.js +0 -90
package/dist/client/200.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/entry.Kj_DYE7z.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/B-cq5x_h.js"><script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/B-cq5x_h.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.CyBDSRXN.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/BCTbvRLO.js"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D6byAye8.js"><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.DJtCwW7w.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/BNXusRXY.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/entry.Kj_DYE7z.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/B-cq5x_h.js"><script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/B-cq5x_h.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.CyBDSRXN.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/BCTbvRLO.js"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D6byAye8.js"><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.DJtCwW7w.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/BNXusRXY.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"bbe443af-4371-4ec3-b41c-7a5e9deb9b9b",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1781425543266,false]</script></body></html>
|
package/dist/client/404.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/entry.Kj_DYE7z.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/B-cq5x_h.js"><script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/B-cq5x_h.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.CyBDSRXN.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/BCTbvRLO.js"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D6byAye8.js"><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.DJtCwW7w.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/BNXusRXY.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/entry.Kj_DYE7z.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/B-cq5x_h.js"><script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/B-cq5x_h.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.CyBDSRXN.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/BCTbvRLO.js"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D6byAye8.js"><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.DJtCwW7w.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/BNXusRXY.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"bbe443af-4371-4ec3-b41c-7a5e9deb9b9b",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1781425543266,false]</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"id":"
|
|
1
|
+
{"id":"bbe443af-4371-4ec3-b41c-7a5e9deb9b9b","timestamp":1781425540376}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"id":"bbe443af-4371-4ec3-b41c-7a5e9deb9b9b","timestamp":1781425540376,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
|
package/dist/client/index.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/entry.Kj_DYE7z.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/B-cq5x_h.js"><script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/B-cq5x_h.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.CyBDSRXN.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/BCTbvRLO.js"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D6byAye8.js"><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.DJtCwW7w.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/BNXusRXY.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/entry.Kj_DYE7z.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/B-cq5x_h.js"><script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/B-cq5x_h.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.CyBDSRXN.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/BCTbvRLO.js"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D6byAye8.js"><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.DJtCwW7w.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/BNXusRXY.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"bbe443af-4371-4ec3-b41c-7a5e9deb9b9b",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1781425543266,false]</script></body></html>
|
package/dist/module.d.mts
CHANGED
|
@@ -3,6 +3,7 @@ import { HookResult } from '@nuxt/schema';
|
|
|
3
3
|
import { ModuleOptions } from '@i18n-micro/types';
|
|
4
4
|
export { Getter, GlobalLocaleRoutes, Locale, LocaleCode, ModuleOptions, PluralFunc, Strategies } from '@i18n-micro/types';
|
|
5
5
|
export { PluginsInjections } from '../dist/runtime/plugins/01.plugin.js';
|
|
6
|
+
export { TranslationPayloadMode, resolveTranslationPayloadMode, resolveTranslationPayloadOptions, resolveTranslationPayloadPublicDir } from '@i18n-micro/utils/payload-config';
|
|
6
7
|
|
|
7
8
|
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
8
9
|
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
|
-
import fs__default, { readFileSync, existsSync
|
|
2
|
+
import fs__default, { readFileSync, existsSync } from 'node:fs';
|
|
3
3
|
import { createRequire } from 'node:module';
|
|
4
4
|
import path, { resolve, join, dirname } from 'node:path';
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
6
6
|
import { defaultPlural, isNoPrefixStrategy, withPrefixStrategy } from '@i18n-micro/core';
|
|
7
|
+
import { generateHmrPlugin } from '@i18n-micro/hmr/generate-plugin';
|
|
7
8
|
import { RouteGenerator, isLocaleAllowedForUnlocalizedRoute, normalizePath, isInternalPath } from '@i18n-micro/route-strategy';
|
|
9
|
+
import { buildTranslationSourceLayers, preMergeLocales } from '@i18n-micro/utils/build';
|
|
10
|
+
import { resolveTranslationPayloadOptions, getTranslationPayloadMisconfigurationWarnings, getTranslationPayloadSizeWarning, resolveTranslationPayloadWarningThresholds, resolveTranslationPayloadPublicDir } from '@i18n-micro/utils/payload-config';
|
|
11
|
+
export { resolveTranslationPayloadMode, resolveTranslationPayloadOptions, resolveTranslationPayloadPublicDir } from '@i18n-micro/utils/payload-config';
|
|
12
|
+
import { scanTranslationPayloadDirectory } from '@i18n-micro/utils/payload-stats';
|
|
8
13
|
import { useNuxt, defineNuxtModule, useLogger, createResolver, addTemplate, addImportsDir, addPlugin, addServerHandler, addComponentsDir, addTypeTemplate, addPrerenderRoutes } from '@nuxt/kit';
|
|
9
14
|
import { globby } from 'globby';
|
|
10
15
|
import { onDevToolsInitialized, extendServerRpc } from '@nuxt/devtools-kit';
|
|
@@ -118,46 +123,6 @@ function setupDevToolsUI(options, resolve2, rootDirs) {
|
|
|
118
123
|
});
|
|
119
124
|
}
|
|
120
125
|
|
|
121
|
-
function generateHmrPlugin(files) {
|
|
122
|
-
const accepts = files.map((file) => {
|
|
123
|
-
const isPage = /\/pages\//.test(file);
|
|
124
|
-
let pageName = "";
|
|
125
|
-
let locale = "";
|
|
126
|
-
if (isPage) {
|
|
127
|
-
const m = /\/pages\/(.+)\/([^/]+)\.json$/.exec(file);
|
|
128
|
-
pageName = m?.[1] || "";
|
|
129
|
-
locale = m?.[2] || "";
|
|
130
|
-
} else {
|
|
131
|
-
const m = /\/([^/]+)\.json$/.exec(file);
|
|
132
|
-
locale = m?.[1] || "";
|
|
133
|
-
}
|
|
134
|
-
return `
|
|
135
|
-
if (import.meta.hot) {
|
|
136
|
-
import.meta.hot.accept('${file}', async (mod) => {
|
|
137
|
-
const nuxtApp = useNuxtApp()
|
|
138
|
-
const data = (mod && typeof mod === 'object' && Object.prototype.hasOwnProperty.call(mod, 'default'))
|
|
139
|
-
? mod.default
|
|
140
|
-
: mod
|
|
141
|
-
try {
|
|
142
|
-
${isPage ? `await nuxtApp.$loadPageTranslations('${locale}', '${pageName}', data)` : `await nuxtApp.$loadTranslations('${locale}', data)`}
|
|
143
|
-
console.log('[i18n HMR] Translations reloaded:', '${isPage ? "page" : "global"}', '${locale}'${isPage ? `, '${pageName}'` : ""})
|
|
144
|
-
}
|
|
145
|
-
catch (e) {
|
|
146
|
-
console.warn('[i18n HMR] Failed to reload translations for', '${file}', e)
|
|
147
|
-
}
|
|
148
|
-
})
|
|
149
|
-
}
|
|
150
|
-
`.trim();
|
|
151
|
-
}).join("\n");
|
|
152
|
-
return `
|
|
153
|
-
import { defineNuxtPlugin, useNuxtApp } from '#imports'
|
|
154
|
-
|
|
155
|
-
export default defineNuxtPlugin(() => {
|
|
156
|
-
${accepts}
|
|
157
|
-
})
|
|
158
|
-
`.trim();
|
|
159
|
-
}
|
|
160
|
-
|
|
161
126
|
function shouldLocalizeRouteRulePath(originalPath) {
|
|
162
127
|
const routeRulePath = originalPath.trim();
|
|
163
128
|
if (!routeRulePath) return true;
|
|
@@ -286,97 +251,7 @@ function extractDefineI18nRouteData(content, _filePath) {
|
|
|
286
251
|
}
|
|
287
252
|
}
|
|
288
253
|
|
|
289
|
-
function deepMergeTranslations(target, source) {
|
|
290
|
-
if (!target || Object.keys(target).length === 0) return { ...source };
|
|
291
|
-
const output = { ...target };
|
|
292
|
-
for (const key in source) {
|
|
293
|
-
if (key === "__proto__" || key === "constructor") continue;
|
|
294
|
-
const src = source[key];
|
|
295
|
-
const dst = output[key];
|
|
296
|
-
if (src && typeof src === "object" && !Array.isArray(src) && dst && typeof dst === "object" && !Array.isArray(dst)) {
|
|
297
|
-
output[key] = deepMergeTranslations(dst, src);
|
|
298
|
-
} else {
|
|
299
|
-
output[key] = src;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
return output;
|
|
303
|
-
}
|
|
304
254
|
const DEFAULT_CANONICAL_QUERY_WHITELIST = ["page", "sort", "filter", "search", "q", "query", "tag"];
|
|
305
|
-
async function preMergeLocales(rootDirs, translationDirName, outputDir, locales, globalFallbackLocale, disablePageLocales) {
|
|
306
|
-
if (existsSync(outputDir)) fs__default.rmSync(outputDir, { recursive: true, force: true });
|
|
307
|
-
mkdirSync(outputDir, { recursive: true });
|
|
308
|
-
const layerPaths = rootDirs.map((dir) => join(dir, translationDirName));
|
|
309
|
-
const allFiles = /* @__PURE__ */ new Set();
|
|
310
|
-
for (const lp of layerPaths) {
|
|
311
|
-
if (!existsSync(lp)) continue;
|
|
312
|
-
const files = await globby("**/*.json", { cwd: lp });
|
|
313
|
-
files.forEach((f) => allFiles.add(f));
|
|
314
|
-
}
|
|
315
|
-
const merged = /* @__PURE__ */ new Map();
|
|
316
|
-
for (const file of allFiles) {
|
|
317
|
-
let content = {};
|
|
318
|
-
for (const lp of layerPaths) {
|
|
319
|
-
const fp = join(lp, file);
|
|
320
|
-
if (existsSync(fp)) {
|
|
321
|
-
try {
|
|
322
|
-
content = deepMergeTranslations(content, JSON.parse(readFileSync(fp, "utf-8")));
|
|
323
|
-
} catch {
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
merged.set(file, content);
|
|
328
|
-
}
|
|
329
|
-
const rootMap = /* @__PURE__ */ new Map();
|
|
330
|
-
const pageMap = /* @__PURE__ */ new Map();
|
|
331
|
-
for (const [file, content] of merged) {
|
|
332
|
-
const dir = dirname(file);
|
|
333
|
-
const locale = file.slice(file.lastIndexOf("/") + 1).replace(".json", "");
|
|
334
|
-
if (dir === ".") {
|
|
335
|
-
rootMap.set(locale, content);
|
|
336
|
-
} else {
|
|
337
|
-
if (!pageMap.has(dir)) pageMap.set(dir, /* @__PURE__ */ new Map());
|
|
338
|
-
pageMap.get(dir).set(locale, content);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
const knownCodes = new Set(locales.map((l) => l.code));
|
|
342
|
-
const applyFallback = (map) => {
|
|
343
|
-
for (const locale of locales) {
|
|
344
|
-
const chain = [globalFallbackLocale, locale.fallbackLocale, locale.code].filter((l) => !!l && knownCodes.has(l)).filter((v, i, arr) => arr.indexOf(v) === i);
|
|
345
|
-
if (chain.length <= 1) continue;
|
|
346
|
-
let result = {};
|
|
347
|
-
for (const code of chain) {
|
|
348
|
-
const data = map.get(code);
|
|
349
|
-
if (data) result = deepMergeTranslations(result, data);
|
|
350
|
-
}
|
|
351
|
-
map.set(locale.code, result);
|
|
352
|
-
}
|
|
353
|
-
};
|
|
354
|
-
applyFallback(rootMap);
|
|
355
|
-
for (const localeMap of pageMap.values()) {
|
|
356
|
-
applyFallback(localeMap);
|
|
357
|
-
}
|
|
358
|
-
if (disablePageLocales || pageMap.size === 0) {
|
|
359
|
-
const indexMap = /* @__PURE__ */ new Map();
|
|
360
|
-
for (const [locale, data] of rootMap) {
|
|
361
|
-
indexMap.set(locale, { ...data });
|
|
362
|
-
}
|
|
363
|
-
pageMap.set("pages/index", indexMap);
|
|
364
|
-
} else {
|
|
365
|
-
for (const [, localeMap] of pageMap) {
|
|
366
|
-
for (const [locale, rootData] of rootMap) {
|
|
367
|
-
const pageData = localeMap.get(locale);
|
|
368
|
-
localeMap.set(locale, pageData ? deepMergeTranslations(rootData, pageData) : { ...rootData });
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
for (const [context, localeMap] of pageMap) {
|
|
373
|
-
for (const [locale, data] of localeMap) {
|
|
374
|
-
const targetPath = join(outputDir, context, `${locale}.json`);
|
|
375
|
-
mkdirSync(dirname(targetPath), { recursive: true });
|
|
376
|
-
writeFileSync(targetPath, JSON.stringify(data));
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
255
|
function generateI18nTypes() {
|
|
381
256
|
return `
|
|
382
257
|
import type {PluginsInjections} from "nuxt-i18n-micro";
|
|
@@ -425,6 +300,13 @@ const module = defineNuxtModule({
|
|
|
425
300
|
apiBaseUrl: "_locales",
|
|
426
301
|
apiBaseClientHost: void 0,
|
|
427
302
|
apiBaseServerHost: void 0,
|
|
303
|
+
translationPayloads: {
|
|
304
|
+
mode: "premerged",
|
|
305
|
+
serverAssets: true,
|
|
306
|
+
serverHandler: true,
|
|
307
|
+
publicAssets: true,
|
|
308
|
+
prerenderRoutes: true
|
|
309
|
+
},
|
|
428
310
|
routesLocaleLinks: {},
|
|
429
311
|
globalLocaleRoutes: {},
|
|
430
312
|
canonicalQueryWhitelist: void 0,
|
|
@@ -452,13 +334,33 @@ const module = defineNuxtModule({
|
|
|
452
334
|
const resolver = createResolver(import.meta.url);
|
|
453
335
|
const rootDirs = nuxt.options._layers.map((layer) => layer.config.rootDir).reverse();
|
|
454
336
|
const mergedLocalesDir = resolve(nuxt.options.buildDir, "i18n-merged");
|
|
337
|
+
const sourceLocalesDir = resolve(nuxt.options.buildDir, "i18n-source");
|
|
455
338
|
const translationDirName = options.translationDir || "locales";
|
|
339
|
+
const translationPayloads = resolveTranslationPayloadOptions(options);
|
|
340
|
+
const translationAssetsDir = translationPayloads.mode === "source" ? sourceLocalesDir : mergedLocalesDir;
|
|
341
|
+
for (const warning of getTranslationPayloadMisconfigurationWarnings({
|
|
342
|
+
translationPayloads,
|
|
343
|
+
apiBaseClientHost: options.apiBaseClientHost,
|
|
344
|
+
apiBaseServerHost: options.apiBaseServerHost
|
|
345
|
+
})) {
|
|
346
|
+
logger.warn(warning.replace("[nuxt-i18n-micro] ", ""));
|
|
347
|
+
}
|
|
456
348
|
const localeInfos = (options.locales ?? []).map(
|
|
457
349
|
(l) => typeof l === "string" ? { code: l } : { code: l.code, fallbackLocale: l.fallbackLocale }
|
|
458
350
|
);
|
|
459
351
|
nuxt.hook("build:before", async () => {
|
|
460
|
-
|
|
461
|
-
|
|
352
|
+
if (translationPayloads.mode === "source") {
|
|
353
|
+
await buildTranslationSourceLayers(rootDirs, translationDirName, sourceLocalesDir);
|
|
354
|
+
logger.info(`Built compact translation source from ${rootDirs.length} layer(s) into ${sourceLocalesDir}`);
|
|
355
|
+
} else {
|
|
356
|
+
await preMergeLocales(rootDirs, translationDirName, mergedLocalesDir, localeInfos, options.fallbackLocale, options.disablePageLocales);
|
|
357
|
+
logger.info(`Pre-merged translations from ${rootDirs.length} layer(s) into ${mergedLocalesDir}`);
|
|
358
|
+
}
|
|
359
|
+
const payloadStats = scanTranslationPayloadDirectory(translationAssetsDir);
|
|
360
|
+
const sizeWarning = getTranslationPayloadSizeWarning(payloadStats, resolveTranslationPayloadWarningThresholds(options.translationPayloads));
|
|
361
|
+
if (sizeWarning) {
|
|
362
|
+
logger.warn(sizeWarning.replace("[nuxt-i18n-micro] ", ""));
|
|
363
|
+
}
|
|
462
364
|
});
|
|
463
365
|
const routeLocales = { ...options.routeLocales ?? {} };
|
|
464
366
|
const globalLocaleRoutes = {};
|
|
@@ -569,7 +471,8 @@ const module = defineNuxtModule({
|
|
|
569
471
|
debug: options.debug ?? false,
|
|
570
472
|
customRegexMatcher: options.customRegexMatcher instanceof RegExp ? options.customRegexMatcher.source : options.customRegexMatcher,
|
|
571
473
|
cacheMaxSize: options.cacheMaxSize ?? 0,
|
|
572
|
-
cacheTtl: options.cacheTtl ?? 0
|
|
474
|
+
cacheTtl: options.cacheTtl ?? 0,
|
|
475
|
+
translationPayloadMode: translationPayloads.mode
|
|
573
476
|
};
|
|
574
477
|
const fullConfigJson = JSON.stringify(fullConfig);
|
|
575
478
|
const strategyTemplate = addTemplate({
|
|
@@ -679,10 +582,12 @@ export function getI18nPrivateConfig() { return __privateConfig }
|
|
|
679
582
|
name: "i18n-plugin-redirect",
|
|
680
583
|
order: 10
|
|
681
584
|
});
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
585
|
+
if (translationPayloads.serverHandler) {
|
|
586
|
+
addServerHandler({
|
|
587
|
+
route: `/${apiBaseUrl}/:page/:locale/data.json`,
|
|
588
|
+
handler: resolver.resolve("./runtime/server/routes/i18n")
|
|
589
|
+
});
|
|
590
|
+
}
|
|
686
591
|
if (options.components !== false) {
|
|
687
592
|
addComponentsDir({
|
|
688
593
|
path: resolver.resolve("./runtime/components"),
|
|
@@ -758,6 +663,7 @@ declare module '#i18n-internal/plural' {
|
|
|
758
663
|
}
|
|
759
664
|
});
|
|
760
665
|
const addDataRoutes = (pages = []) => {
|
|
666
|
+
if (!translationPayloads.prerenderRoutes) return;
|
|
761
667
|
const pagesForDataRoutes = pages.filter((p) => p.name !== void 0 && (!options.routesLocaleLinks || !options.routesLocaleLinks[p.name]));
|
|
762
668
|
const dataRoutes = routeGenerator.generateDataRoutes(pagesForDataRoutes, apiBaseUrl, !!options.disablePageLocales);
|
|
763
669
|
addPrerenderRoutes(dataRoutes);
|
|
@@ -794,11 +700,13 @@ declare module '#i18n-internal/plural' {
|
|
|
794
700
|
nitroConfig.alias["#i18n-internal/plural"] = pluralTemplate.dst;
|
|
795
701
|
nitroConfig.alias["#i18n-internal/strategy"] = strategyTemplate.dst;
|
|
796
702
|
nitroConfig.alias["#i18n-internal/config"] = configTemplate.dst;
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
703
|
+
if (translationPayloads.serverAssets) {
|
|
704
|
+
nitroConfig.serverAssets = nitroConfig.serverAssets || [];
|
|
705
|
+
nitroConfig.serverAssets.push({
|
|
706
|
+
baseName: "i18n",
|
|
707
|
+
dir: translationAssetsDir
|
|
708
|
+
});
|
|
709
|
+
}
|
|
802
710
|
if (nitroConfig.imports) {
|
|
803
711
|
nitroConfig.imports.presets = nitroConfig.imports.presets || [];
|
|
804
712
|
nitroConfig.imports.presets.push({
|
|
@@ -838,14 +746,14 @@ declare module '#i18n-internal/plural' {
|
|
|
838
746
|
});
|
|
839
747
|
nuxt.hook("nitro:build:public-assets", (nitro) => {
|
|
840
748
|
const isProd = nuxt.options.dev === false;
|
|
841
|
-
if (isProd) {
|
|
842
|
-
const publicDir =
|
|
749
|
+
if (isProd && translationPayloads.publicAssets) {
|
|
750
|
+
const publicDir = resolveTranslationPayloadPublicDir(nitro.options.output.publicDir, options);
|
|
843
751
|
try {
|
|
844
|
-
if (existsSync(
|
|
845
|
-
fs__default.cpSync(
|
|
846
|
-
logger.log(`
|
|
752
|
+
if (existsSync(translationAssetsDir)) {
|
|
753
|
+
fs__default.cpSync(translationAssetsDir, publicDir, { recursive: true });
|
|
754
|
+
logger.log(`Translation payloads copied to public directory`);
|
|
847
755
|
} else {
|
|
848
|
-
logger.warn(`
|
|
756
|
+
logger.warn(`Translation assets directory not found: ${translationAssetsDir}`);
|
|
849
757
|
}
|
|
850
758
|
} catch (err) {
|
|
851
759
|
logger.error("Error copying translations:", err);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { getEnabledLocaleCodes } from "@i18n-micro/utils/active-locales";
|
|
2
|
+
import { getHashCookieName, getLocaleCookieName, getLocaleCookieOptions } from "@i18n-micro/utils/cookie";
|
|
3
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "@i18n-micro/utils/runtime-config";
|
|
1
4
|
import { useNuxtApp, useState } from "#app";
|
|
2
5
|
import { getI18nConfig } from "#build/i18n.strategy.mjs";
|
|
3
6
|
import { useCookie } from "#imports";
|
|
4
|
-
import { getEnabledLocaleCodes } from "../utils/active-locales.js";
|
|
5
|
-
import { getHashCookieName, getLocaleCookieName, getLocaleCookieOptions } from "../utils/cookie.js";
|
|
6
|
-
import { resolveI18nConfigWithRuntimeOverrides } from "../utils/runtime-i18n-config.js";
|
|
7
7
|
export function useI18nLocale() {
|
|
8
8
|
const nuxtApp = useNuxtApp();
|
|
9
9
|
const i18nConfig = resolveI18nConfigWithRuntimeOverrides(nuxtApp.$getI18nConfig?.() ?? getI18nConfig());
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { isNoPrefixStrategy } from "@i18n-micro/core";
|
|
2
|
+
import { findAllowedLocalesForRoute } from "@i18n-micro/utils/route";
|
|
2
3
|
import { joinURL, parseURL, withQuery } from "ufo";
|
|
3
4
|
import { ref, unref, watch } from "vue";
|
|
4
5
|
import { useNuxtApp, useRoute } from "#imports";
|
|
5
|
-
import { findAllowedLocalesForRoute } from "../utils/route-utils.js";
|
|
6
6
|
export const useLocaleHead = ({
|
|
7
7
|
addDirAttribute = true,
|
|
8
8
|
identifierAttribute = "id",
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { FormatService, isNoPrefixStrategy } from "@i18n-micro/core";
|
|
2
|
+
import { deepMergeTranslations } from "@i18n-micro/utils/deep-merge";
|
|
3
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "@i18n-micro/utils/runtime-config";
|
|
2
4
|
import { shallowRef, triggerRef, unref } from "vue";
|
|
3
5
|
import { useState } from "#app";
|
|
4
6
|
import { plural } from "#build/i18n.plural.mjs";
|
|
5
7
|
import { createI18nStrategy, getI18nConfig } from "#build/i18n.strategy.mjs";
|
|
6
8
|
import { createError, defineNuxtPlugin, navigateTo, useHead, useRouter, useRuntimeConfig } from "#imports";
|
|
7
9
|
import { useI18nLocale } from "../composables/useI18nLocale.js";
|
|
8
|
-
import { deepMergeTranslations } from "../utils/deep-merge.js";
|
|
9
|
-
import { resolveI18nConfigWithRuntimeOverrides } from "../utils/runtime-i18n-config.js";
|
|
10
10
|
import { translationStorage } from "../utils/storage.js";
|
|
11
11
|
const isDev = process.env.NODE_ENV !== "production";
|
|
12
12
|
const RE_TOKEN = /\{(\w+)\}/g;
|
|
@@ -81,7 +81,10 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
81
81
|
const loadOptions = {
|
|
82
82
|
apiBaseUrl: i18nConfig.apiBaseUrl ?? "_locales",
|
|
83
83
|
baseURL: runtimeConfig.app.baseURL,
|
|
84
|
-
|
|
84
|
+
apiBaseClientHost: i18nConfig.apiBaseClientHost,
|
|
85
|
+
apiBaseServerHost: i18nConfig.apiBaseServerHost,
|
|
86
|
+
dateBuild: i18nConfig.dateBuild,
|
|
87
|
+
routesLocaleLinks: i18nConfig.routesLocaleLinks
|
|
85
88
|
};
|
|
86
89
|
const getCacheKey = (locale, routeName) => {
|
|
87
90
|
return `${locale}:${routeName || "index"}`;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { isMetaDisabledForRoute } from "@i18n-micro/utils/route";
|
|
2
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "@i18n-micro/utils/runtime-config";
|
|
1
3
|
import { watch } from "vue";
|
|
2
4
|
import { getI18nConfig } from "#build/i18n.strategy.mjs";
|
|
3
5
|
import { defineNuxtPlugin, useHead, useRequestURL, useRoute } from "#imports";
|
|
4
6
|
import { useLocaleHead } from "../composables/useLocaleHead.js";
|
|
5
|
-
import { isMetaDisabledForRoute } from "../utils/route-utils.js";
|
|
6
|
-
import { resolveI18nConfigWithRuntimeOverrides } from "../utils/runtime-i18n-config.js";
|
|
7
7
|
export default defineNuxtPlugin((nuxtApp) => {
|
|
8
8
|
const route = useRoute();
|
|
9
9
|
const getRuntimeConfig = nuxtApp.$getI18nConfig;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isNoPrefixStrategy } from "@i18n-micro/core";
|
|
2
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "@i18n-micro/utils/runtime-config";
|
|
2
3
|
import { getI18nConfig } from "#build/i18n.strategy.mjs";
|
|
3
4
|
import { defineNuxtPlugin, useNuxtApp, useRouter } from "#imports";
|
|
4
|
-
import { resolveI18nConfigWithRuntimeOverrides } from "../utils/runtime-i18n-config.js";
|
|
5
5
|
const isDev = process.env.NODE_ENV !== "production";
|
|
6
6
|
export default defineNuxtPlugin(async (nuxtApp) => {
|
|
7
7
|
const getRuntimeConfig = nuxtApp.$getI18nConfig;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { getEnabledLocaleCodes } from "@i18n-micro/utils/active-locales";
|
|
2
|
+
import { getLocaleCookieName, getLocaleCookieOptions } from "@i18n-micro/utils/cookie";
|
|
3
|
+
import { resolvePreferredLocale } from "@i18n-micro/utils/resolve-locale";
|
|
4
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "@i18n-micro/utils/runtime-config";
|
|
1
5
|
import { getCookie, getHeader, getRequestURL, setCookie } from "h3";
|
|
2
6
|
import { createI18nStrategy, getI18nConfig } from "#build/i18n.strategy.mjs";
|
|
3
7
|
import { createError, defineNuxtPlugin, navigateTo, useRequestEvent, useRoute, useRouter, useState } from "#imports";
|
|
4
8
|
import { useI18nLocale } from "../composables/useI18nLocale.js";
|
|
5
|
-
import { getEnabledLocaleCodes } from "../utils/active-locales.js";
|
|
6
|
-
import { getLocaleCookieName, getLocaleCookieOptions } from "../utils/cookie.js";
|
|
7
|
-
import { resolvePreferredLocale } from "../utils/resolve-server-locale.js";
|
|
8
|
-
import { resolveI18nConfigWithRuntimeOverrides } from "../utils/runtime-i18n-config.js";
|
|
9
9
|
const DEBUG = process.env.NUXT_I18N_DEBUG_REDIRECT === "1";
|
|
10
10
|
const DEFAULT_STATIC_PATTERNS = [
|
|
11
11
|
/^\/sitemap.*\.xml$/,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { getEnabledLocaleCodes } from "@i18n-micro/utils/active-locales";
|
|
2
|
+
import { getLocaleCookieName } from "@i18n-micro/utils/cookie";
|
|
3
|
+
import { resolveServerLocale } from "@i18n-micro/utils/resolve-locale";
|
|
4
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "@i18n-micro/utils/runtime-config";
|
|
1
5
|
import { defineEventHandler, getCookie, getHeader, getQuery, getRequestURL } from "h3";
|
|
2
6
|
import { getI18nConfig } from "#i18n-internal/strategy";
|
|
3
7
|
import { useRuntimeConfig } from "#imports";
|
|
4
|
-
import { getEnabledLocaleCodes } from "../../utils/active-locales.js";
|
|
5
|
-
import { getLocaleCookieName } from "../../utils/cookie.js";
|
|
6
|
-
import { resolveServerLocale } from "../../utils/resolve-server-locale.js";
|
|
7
|
-
import { resolveI18nConfigWithRuntimeOverrides } from "../../utils/runtime-i18n-config.js";
|
|
8
8
|
export default defineEventHandler(async (event) => {
|
|
9
9
|
const path = event.path || getRequestURL(event).pathname;
|
|
10
10
|
if (path.startsWith("/api") || path.startsWith("/_nuxt") || path.startsWith("/_locales") || path.startsWith("/__")) return;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { SERVER_CC_KEY, STORAGE_CC_KEY } from "@i18n-micro/hmr/cache-keys";
|
|
4
|
+
import { handleTranslationWatchChange, parseTranslationWatchRelativePath } from "@i18n-micro/hmr/watcher";
|
|
5
|
+
import { CacheControl } from "@i18n-micro/utils/cache-control";
|
|
3
6
|
import { watch } from "chokidar";
|
|
4
7
|
import { defineNitroPlugin } from "nitropack/runtime";
|
|
5
8
|
import { getI18nPrivateConfig } from "#i18n-internal/config";
|
|
6
|
-
import {
|
|
7
|
-
const SERVER_CC_KEY = Symbol.for("__NUXT_I18N_SERVER_CACHE_CC__");
|
|
8
|
-
const STORAGE_CC_KEY = Symbol.for("__NUXT_I18N_STORAGE_CC__");
|
|
9
|
+
import { getI18nConfig } from "#i18n-internal/strategy";
|
|
9
10
|
function getCacheByKey(key) {
|
|
10
11
|
const g = globalThis;
|
|
11
12
|
const cc = g[key];
|
|
@@ -39,24 +40,6 @@ function readJsonSafe(filePath) {
|
|
|
39
40
|
}
|
|
40
41
|
return {};
|
|
41
42
|
}
|
|
42
|
-
function deepMerge(target, source) {
|
|
43
|
-
const result = { ...target };
|
|
44
|
-
for (const key in source) {
|
|
45
|
-
if (key === "__proto__" || key === "constructor") continue;
|
|
46
|
-
const src = source[key];
|
|
47
|
-
const dst = result[key];
|
|
48
|
-
if (src !== null && typeof src === "object" && !Array.isArray(src) && dst !== null && typeof dst === "object" && !Array.isArray(dst)) {
|
|
49
|
-
result[key] = { ...dst, ...src };
|
|
50
|
-
} else {
|
|
51
|
-
result[key] = src;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return result;
|
|
55
|
-
}
|
|
56
|
-
function buildCacheEntry(data) {
|
|
57
|
-
const json = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
58
|
-
return { data, json };
|
|
59
|
-
}
|
|
60
43
|
let watcherInstance = null;
|
|
61
44
|
export default defineNitroPlugin((nitroApp) => {
|
|
62
45
|
if (watcherInstance) {
|
|
@@ -75,56 +58,43 @@ export default defineNitroPlugin((nitroApp) => {
|
|
|
75
58
|
const routesLocaleLinks = i18nConfig.routesLocaleLinks || {};
|
|
76
59
|
const translationsRoot = path.resolve(i18nConfig.rootDir, i18nConfig.translationDir);
|
|
77
60
|
log(`Watching for translation changes in: ${translationsRoot}`);
|
|
78
|
-
function mergeAndSet(serverCache, locale, pageName) {
|
|
79
|
-
const rootData = readJsonSafe(path.join(translationsRoot, `${locale}.json`));
|
|
80
|
-
const pageData = readJsonSafe(path.join(translationsRoot, "pages", pageName, `${locale}.json`));
|
|
81
|
-
const merged = deepMerge(rootData, pageData);
|
|
82
|
-
const cacheKey = `${locale}:${pageName}`;
|
|
83
|
-
serverCache.set(cacheKey, buildCacheEntry(merged));
|
|
84
|
-
const storageCache = getStorageCache();
|
|
85
|
-
if (storageCache) {
|
|
86
|
-
storageCache.delete(cacheKey);
|
|
87
|
-
}
|
|
88
|
-
log(`Re-merged and cached '${cacheKey}'`);
|
|
89
|
-
const aliases = Object.keys(routesLocaleLinks).filter((alias) => routesLocaleLinks[alias] === pageName);
|
|
90
|
-
for (const alias of aliases) {
|
|
91
|
-
const aliasKey = `${locale}:${alias}`;
|
|
92
|
-
serverCache.set(aliasKey, buildCacheEntry(merged));
|
|
93
|
-
if (storageCache) {
|
|
94
|
-
storageCache.delete(aliasKey);
|
|
95
|
-
}
|
|
96
|
-
log(`Re-merged and cached alias '${aliasKey}'`);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
61
|
const invalidateAndRefresh = async (filePath, event) => {
|
|
100
|
-
if (!filePath.endsWith(".json")) return;
|
|
101
62
|
const relativePath = path.relative(translationsRoot, filePath).replace(/\\/g, "/");
|
|
102
|
-
const
|
|
103
|
-
const serverCache = getOrCreateServerCache();
|
|
63
|
+
const runtimeConfig = getI18nConfig();
|
|
104
64
|
try {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const match = relativePath.match(/^([^/]+)\.json$/);
|
|
113
|
-
if (!match || !match[1]) return;
|
|
114
|
-
const locale = match[1];
|
|
115
|
-
if (!configuredLocales.has(locale)) {
|
|
116
|
-
warn(`Detected ${event} for '${relativePath}', but locale '${locale}' is not in i18n.locales. Update config and restart dev server.`);
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
const pagesDir = path.join(translationsRoot, "pages");
|
|
120
|
-
if (existsSync(pagesDir)) {
|
|
121
|
-
const pageDirs = readdirSync(pagesDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
122
|
-
for (const pageName of pageDirs) {
|
|
123
|
-
mergeAndSet(serverCache, locale, pageName);
|
|
65
|
+
const result = await handleTranslationWatchChange({
|
|
66
|
+
relativePath,
|
|
67
|
+
configuredLocales,
|
|
68
|
+
listPageNames: () => {
|
|
69
|
+
const pagesDir = path.join(translationsRoot, "pages");
|
|
70
|
+
if (!existsSync(pagesDir)) {
|
|
71
|
+
return [];
|
|
124
72
|
}
|
|
73
|
+
return readdirSync(pagesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
74
|
+
},
|
|
75
|
+
serverCache: getOrCreateServerCache(),
|
|
76
|
+
storageCache: getStorageCache(),
|
|
77
|
+
routesLocaleLinks,
|
|
78
|
+
mergeInput: {
|
|
79
|
+
translationPayloadMode: runtimeConfig.translationPayloadMode,
|
|
80
|
+
locales: runtimeConfig.locales,
|
|
81
|
+
fallbackLocale: runtimeConfig.fallbackLocale,
|
|
82
|
+
disablePageLocales: runtimeConfig.disablePageLocales,
|
|
83
|
+
readLocaleFile: (relativeFilePath) => readJsonSafe(path.join(translationsRoot, relativeFilePath))
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
if (result === "root") {
|
|
87
|
+
const parsed = parseTranslationWatchRelativePath(relativePath);
|
|
88
|
+
if (parsed.type === "root") {
|
|
89
|
+
log(`Re-merged ALL pages for locale '${parsed.locale}'`);
|
|
90
|
+
}
|
|
91
|
+
} else if (result === "page") {
|
|
92
|
+
log(`Re-merged page cache for '${relativePath}'`);
|
|
93
|
+
} else if (result === "ignored") {
|
|
94
|
+
const parsed = parseTranslationWatchRelativePath(relativePath);
|
|
95
|
+
if (parsed.type === "root" && !configuredLocales.has(parsed.locale)) {
|
|
96
|
+
warn(`Detected ${event} for '${relativePath}', but locale '${parsed.locale}' is not in i18n.locales. Update config and restart dev server.`);
|
|
125
97
|
}
|
|
126
|
-
mergeAndSet(serverCache, locale, "index");
|
|
127
|
-
log(`Re-merged ALL pages for locale '${locale}'`);
|
|
128
98
|
}
|
|
129
99
|
} catch (e) {
|
|
130
100
|
warn("Failed to refresh server cache for", filePath, e);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { isEnabledLocale } from "@i18n-micro/utils/active-locales";
|
|
2
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "@i18n-micro/utils/runtime-config";
|
|
1
3
|
import { createError, defineEventHandler, getRouterParam, send, setResponseHeader } from "h3";
|
|
2
4
|
import { getI18nConfig } from "#i18n-internal/strategy";
|
|
3
5
|
import { useRuntimeConfig } from "#imports";
|
|
4
|
-
import { isEnabledLocale } from "../../utils/active-locales.js";
|
|
5
|
-
import { resolveI18nConfigWithRuntimeOverrides } from "../../utils/runtime-i18n-config.js";
|
|
6
6
|
import { loadTranslationsFromServer } from "../utils/server-loader.js";
|
|
7
7
|
export default defineEventHandler(async (event) => {
|
|
8
8
|
const page = getRouterParam(event, "page");
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { detectLocaleFromAcceptLanguage } from "@i18n-micro/utils/accept-language";
|
|
1
2
|
import { getCookie, getQuery, getRequestURL } from "h3";
|
|
2
3
|
export const detectCurrentLocale = (event, config, defaultLocale) => {
|
|
3
4
|
const { fallbackLocale, defaultLocale: configDefaultLocale, locales } = config;
|
|
@@ -20,5 +21,14 @@ export const detectCurrentLocale = (event, config, defaultLocale) => {
|
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
|
-
|
|
24
|
+
const cookieLocale = getCookie(event, "user-locale");
|
|
25
|
+
if (cookieLocale) {
|
|
26
|
+
return cookieLocale.toString();
|
|
27
|
+
}
|
|
28
|
+
const localeCodes = locales?.map((locale) => locale.code) ?? [];
|
|
29
|
+
const detectedFromHeader = detectLocaleFromAcceptLanguage(event.headers.get("accept-language") ?? void 0, localeCodes);
|
|
30
|
+
if (detectedFromHeader) {
|
|
31
|
+
return detectedFromHeader;
|
|
32
|
+
}
|
|
33
|
+
return (fallbackLocale || defaultLocale || configDefaultLocale || "en").toString();
|
|
24
34
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { getEnabledLocaleCodes, getEnabledLocales } from "@i18n-micro/utils/active-locales";
|
|
2
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "@i18n-micro/utils/runtime-config";
|
|
1
3
|
import { getI18nConfig } from "#i18n-internal/strategy";
|
|
2
4
|
import { useRuntimeConfig } from "#imports";
|
|
3
|
-
import { getEnabledLocaleCodes, getEnabledLocales } from "../../utils/active-locales.js";
|
|
4
|
-
import { resolveI18nConfigWithRuntimeOverrides } from "../../utils/runtime-i18n-config.js";
|
|
5
5
|
import { detectCurrentLocale } from "./locale-detector.js";
|
|
6
6
|
export const useLocaleServerMiddleware = (event, defaultLocale, currentLocale) => {
|
|
7
7
|
const {
|