nuxt-i18n-micro 1.61.0 → 1.62.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 +8 -8
- package/dist/client/404.html +8 -8
- package/dist/client/_nuxt/{EwNUkbJF.js → AXE8DZQI.js} +1 -1
- package/dist/client/_nuxt/{DuZjM2Ym.js → D9gx-VEt.js} +1 -1
- package/dist/client/_nuxt/{C9njAg9E.js → Ddb0iCRU.js} +55 -55
- package/dist/client/_nuxt/{BIRJeTBr.js → Deg2o1hP.js} +1 -1
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/c8228d06-262a-456f-a053-aa7994ec21bb.json +1 -0
- package/dist/client/_nuxt/error-404.vh32VtAd.css +1 -0
- package/dist/client/_nuxt/error-500.EgQ3RNLZ.css +1 -0
- package/dist/client/index.html +8 -8
- package/dist/module.json +1 -1
- package/dist/module.mjs +150 -52
- package/dist/runtime/plugins/01.plugin.js +12 -4
- package/dist/runtime/server/routes/get.js +17 -0
- package/package.json +11 -10
- package/dist/client/_nuxt/builds/meta/019df560-5b4f-4d25-8ca1-a8cad935e3d2.json +0 -1
- package/dist/client/_nuxt/error-404.C8aNxDEl.css +0 -1
- package/dist/client/_nuxt/error-500.C2JGrgZX.css +0 -1
- package/dist/runtime/server/middleware/i18n-loader.js +0 -61
- /package/dist/runtime/server/{middleware/i18n-loader.d.ts → routes/get.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as a,o as i,c as u,a as e,t as r,b as c,w as l,d,e as p}from"./
|
|
1
|
+
import{_ as a,o as i,c as u,a as e,t as r,b as c,w as l,d,e as p}from"./Ddb0iCRU.js";import{u as f}from"./AXE8DZQI.js";const m={class:"antialiased bg-white dark:bg-black dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-black"},g={class:"max-w-520px text-center z-20"},h=["textContent"],b=["textContent"],x={class:"flex items-center justify-center w-full"},y={__name:"error-404",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},statusCode:{type:Number,default:404},statusMessage:{type:String,default:"Not Found"},description:{type:String,default:"Sorry, the page you are looking for could not be found."},backHome:{type:String,default:"Go back home"}},setup(t){const n=t;return f({title:`${n.statusCode} - ${n.statusMessage} | ${n.appName}`,script:[{children:`!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver((e=>{for(const o of e)if("childList"===o.type)for(const e of o.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)})).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;const r=function(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?r.credentials="include":"anonymous"===e.crossOrigin?r.credentials="omit":r.credentials="same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{children:'*,:after,:before{border-color:var(--un-default-border-color,#e5e7eb);border-style:solid;border-width:0;box-sizing:border-box}:after,:before{--un-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}h1{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}h1,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }'}]}),(k,o)=>{const s=p;return i(),u("div",m,[o[0]||(o[0]=e("div",{class:"fixed left-0 right-0 spotlight z-10"},null,-1)),e("div",g,[e("h1",{class:"font-medium mb-8 sm:text-10xl text-8xl",textContent:r(t.statusCode)},null,8,h),e("p",{class:"font-light leading-tight mb-16 px-8 sm:px-0 sm:text-4xl text-xl",textContent:r(t.description)},null,8,b),e("div",x,[c(s,{to:"/",class:"cursor-pointer gradient-border px-4 py-2 sm:px-6 sm:py-3 sm:text-xl text-md"},{default:l(()=>[d(r(t.backHome),1)]),_:1})])])])}}},v=a(y,[["__scopeId","data-v-c1463376"]]);export{v as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"id":"
|
|
1
|
+
{"id":"c8228d06-262a-456f-a053-aa7994ec21bb","timestamp":1737022232581}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"id":"c8228d06-262a-456f-a053-aa7994ec21bb","timestamp":1737022232581,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.spotlight[data-v-c1463376]{background:linear-gradient(45deg,#00dc82,#36e4da 50%,#0047e1);bottom:-30vh;filter:blur(20vh);height:40vh}.gradient-border[data-v-c1463376]{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-radius:.5rem;position:relative}@media (prefers-color-scheme:light){.gradient-border[data-v-c1463376]{background-color:#ffffff4d}.gradient-border[data-v-c1463376]:before{background:linear-gradient(90deg,#e2e2e2,#e2e2e2 25%,#00dc82,#36e4da 75%,#0047e1)}}@media (prefers-color-scheme:dark){.gradient-border[data-v-c1463376]{background-color:#1414144d}.gradient-border[data-v-c1463376]:before{background:linear-gradient(90deg,#303030,#303030 25%,#00dc82,#36e4da 75%,#0047e1)}}.gradient-border[data-v-c1463376]:before{background-size:400% auto;border-radius:.5rem;bottom:0;content:"";left:0;-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:.5;padding:2px;position:absolute;right:0;top:0;transition:background-position .3s ease-in-out,opacity .2s ease-in-out;width:100%}.gradient-border[data-v-c1463376]:hover:before{background-position:-50% 0;opacity:1}.fixed[data-v-c1463376]{position:fixed}.left-0[data-v-c1463376]{left:0}.right-0[data-v-c1463376]{right:0}.z-10[data-v-c1463376]{z-index:10}.z-20[data-v-c1463376]{z-index:20}.grid[data-v-c1463376]{display:grid}.mb-16[data-v-c1463376]{margin-bottom:4rem}.mb-8[data-v-c1463376]{margin-bottom:2rem}.max-w-520px[data-v-c1463376]{max-width:520px}.min-h-screen[data-v-c1463376]{min-height:100vh}.w-full[data-v-c1463376]{width:100%}.flex[data-v-c1463376]{display:flex}.cursor-pointer[data-v-c1463376]{cursor:pointer}.place-content-center[data-v-c1463376]{place-content:center}.items-center[data-v-c1463376]{align-items:center}.justify-center[data-v-c1463376]{justify-content:center}.overflow-hidden[data-v-c1463376]{overflow:hidden}.bg-white[data-v-c1463376]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-4[data-v-c1463376]{padding-left:1rem;padding-right:1rem}.px-8[data-v-c1463376]{padding-left:2rem;padding-right:2rem}.py-2[data-v-c1463376]{padding-bottom:.5rem;padding-top:.5rem}.text-center[data-v-c1463376]{text-align:center}.text-8xl[data-v-c1463376]{font-size:6rem;line-height:1}.text-xl[data-v-c1463376]{font-size:1.25rem;line-height:1.75rem}.text-black[data-v-c1463376]{--un-text-opacity:1;color:rgb(0 0 0/var(--un-text-opacity))}.font-light[data-v-c1463376]{font-weight:300}.font-medium[data-v-c1463376]{font-weight:500}.leading-tight[data-v-c1463376]{line-height:1.25}.font-sans[data-v-c1463376]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.antialiased[data-v-c1463376]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (prefers-color-scheme:dark){.dark\:bg-black[data-v-c1463376]{--un-bg-opacity:1;background-color:rgb(0 0 0/var(--un-bg-opacity))}.dark\:text-white[data-v-c1463376]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media (min-width:640px){.sm\:px-0[data-v-c1463376]{padding-left:0;padding-right:0}.sm\:px-6[data-v-c1463376]{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-3[data-v-c1463376]{padding-bottom:.75rem;padding-top:.75rem}.sm\:text-4xl[data-v-c1463376]{font-size:2.25rem;line-height:2.5rem}.sm\:text-xl[data-v-c1463376]{font-size:1.25rem;line-height:1.75rem}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.spotlight[data-v-05ddf355]{background:linear-gradient(45deg,#00dc82,#36e4da 50%,#0047e1);filter:blur(20vh)}.fixed[data-v-05ddf355]{position:fixed}.-bottom-1\/2[data-v-05ddf355]{bottom:-50%}.left-0[data-v-05ddf355]{left:0}.right-0[data-v-05ddf355]{right:0}.grid[data-v-05ddf355]{display:grid}.mb-16[data-v-05ddf355]{margin-bottom:4rem}.mb-8[data-v-05ddf355]{margin-bottom:2rem}.h-1\/2[data-v-05ddf355]{height:50%}.max-w-520px[data-v-05ddf355]{max-width:520px}.min-h-screen[data-v-05ddf355]{min-height:100vh}.place-content-center[data-v-05ddf355]{place-content:center}.overflow-hidden[data-v-05ddf355]{overflow:hidden}.bg-white[data-v-05ddf355]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-8[data-v-05ddf355]{padding-left:2rem;padding-right:2rem}.text-center[data-v-05ddf355]{text-align:center}.text-8xl[data-v-05ddf355]{font-size:6rem;line-height:1}.text-xl[data-v-05ddf355]{font-size:1.25rem;line-height:1.75rem}.text-black[data-v-05ddf355]{--un-text-opacity:1;color:rgb(0 0 0/var(--un-text-opacity))}.font-light[data-v-05ddf355]{font-weight:300}.font-medium[data-v-05ddf355]{font-weight:500}.leading-tight[data-v-05ddf355]{line-height:1.25}.font-sans[data-v-05ddf355]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.antialiased[data-v-05ddf355]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (prefers-color-scheme:dark){.dark\:bg-black[data-v-05ddf355]{--un-bg-opacity:1;background-color:rgb(0 0 0/var(--un-bg-opacity))}.dark\:text-white[data-v-05ddf355]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media (min-width:640px){.sm\:px-0[data-v-05ddf355]{padding-left:0;padding-right:0}.sm\:text-4xl[data-v-05ddf355]{font-size:2.25rem;line-height:2.5rem}}
|
package/dist/client/index.html
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<!DOCTYPE html><html data-capo=""><head><meta charset="utf-8">
|
|
2
2
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
3
3
|
<link rel="stylesheet" href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/entry.B5pGkSSX.css" crossorigin>
|
|
4
|
-
<link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/
|
|
4
|
+
<link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Ddb0iCRU.js">
|
|
5
5
|
<link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/CG55hV0U.js">
|
|
6
|
-
<link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.
|
|
7
|
-
<link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/
|
|
8
|
-
<link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/
|
|
9
|
-
<link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.
|
|
10
|
-
<link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/
|
|
11
|
-
<script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/
|
|
12
|
-
<script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"
|
|
6
|
+
<link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.vh32VtAd.css">
|
|
7
|
+
<link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Deg2o1hP.js">
|
|
8
|
+
<link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/AXE8DZQI.js">
|
|
9
|
+
<link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.EgQ3RNLZ.css">
|
|
10
|
+
<link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D9gx-VEt.js">
|
|
11
|
+
<script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Ddb0iCRU.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1737022239892,false]</script>
|
|
12
|
+
<script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"c8228d06-262a-456f-a053-aa7994ec21bb",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import path, { resolve } from 'node:path';
|
|
2
2
|
import * as fs from 'node:fs';
|
|
3
3
|
import fs__default, { readFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { readFile } from 'node:fs/promises';
|
|
4
5
|
import { useNuxt, defineNuxtModule, useLogger, createResolver, addTemplate, addImportsDir, addPlugin, addServerHandler, addComponentsDir, addTypeTemplate, extendPages, addPrerenderRoutes } from '@nuxt/kit';
|
|
5
6
|
import { watch } from 'chokidar';
|
|
7
|
+
import { globby } from 'globby';
|
|
6
8
|
import { fileURLToPath } from 'node:url';
|
|
7
9
|
import { onDevToolsInitialized, extendServerRpc } from '@nuxt/devtools-kit';
|
|
8
10
|
import sirv from 'sirv';
|
|
@@ -22,6 +24,9 @@ function setupDevToolsUI(options, resolve2) {
|
|
|
22
24
|
if (clientDirExists) {
|
|
23
25
|
nuxt.hook("vite:serverCreated", (server) => {
|
|
24
26
|
const indexHtmlPath = path.join(clientDir, "index.html");
|
|
27
|
+
if (!fs.existsSync(indexHtmlPath)) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
25
30
|
const indexContent = fs.readFileSync(indexHtmlPath);
|
|
26
31
|
const handleStatic = sirv(clientDir, {
|
|
27
32
|
dev: true,
|
|
@@ -374,6 +379,34 @@ declare module '#app' {
|
|
|
374
379
|
|
|
375
380
|
export {}`;
|
|
376
381
|
}
|
|
382
|
+
function deepMerge(target, source) {
|
|
383
|
+
if (typeof source !== "object" || source === null) {
|
|
384
|
+
return target === void 0 ? source : target;
|
|
385
|
+
}
|
|
386
|
+
if (Array.isArray(target)) {
|
|
387
|
+
return target;
|
|
388
|
+
}
|
|
389
|
+
if (source instanceof Object) {
|
|
390
|
+
if (!(target instanceof Object) || Array.isArray(target)) {
|
|
391
|
+
target = {};
|
|
392
|
+
}
|
|
393
|
+
for (const key in source) {
|
|
394
|
+
if (key === "__proto__" || key === "constructor")
|
|
395
|
+
continue;
|
|
396
|
+
if (target !== null && typeof target[key] === "object" && target[key] !== null) {
|
|
397
|
+
target[key] = deepMerge(
|
|
398
|
+
target[key],
|
|
399
|
+
source[key]
|
|
400
|
+
);
|
|
401
|
+
} else {
|
|
402
|
+
if (target instanceof Object && !(key in target)) {
|
|
403
|
+
target[key] = source[key];
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return target;
|
|
409
|
+
}
|
|
377
410
|
const module = defineNuxtModule({
|
|
378
411
|
meta: {
|
|
379
412
|
name: "nuxt-i18n-micro",
|
|
@@ -412,6 +445,7 @@ const module = defineNuxtModule({
|
|
|
412
445
|
customRegexMatcher: void 0
|
|
413
446
|
},
|
|
414
447
|
async setup(options, nuxt) {
|
|
448
|
+
const defaultLocale = process.env.DEFAULT_LOCALE ?? options.defaultLocale ?? "en";
|
|
415
449
|
const isSSG = nuxt.options._generate;
|
|
416
450
|
const isCloudflarePages = nuxt.options.nitro.preset === "cloudflare_pages" || process.env.NITRO_PRESET === "cloudflare-pages";
|
|
417
451
|
const logger = useLogger("nuxt-i18n-micro");
|
|
@@ -426,7 +460,7 @@ const module = defineNuxtModule({
|
|
|
426
460
|
const resolver = createResolver(import.meta.url);
|
|
427
461
|
const rootDirs = nuxt.options._layers.map((layer) => layer.config.rootDir).reverse();
|
|
428
462
|
const localeManager = new LocaleManager(options, rootDirs);
|
|
429
|
-
const pageManager = new PageManager(localeManager.locales,
|
|
463
|
+
const pageManager = new PageManager(localeManager.locales, defaultLocale, options.strategy, options.globalLocaleRoutes);
|
|
430
464
|
addTemplate({
|
|
431
465
|
filename: "i18n.plural.mjs",
|
|
432
466
|
write: true,
|
|
@@ -441,7 +475,7 @@ const module = defineNuxtModule({
|
|
|
441
475
|
define: options.define ?? true,
|
|
442
476
|
disableWatcher: options.disableWatcher ?? false,
|
|
443
477
|
disableUpdater: options.disableUpdater ?? false,
|
|
444
|
-
defaultLocale
|
|
478
|
+
defaultLocale,
|
|
445
479
|
translationDir: options.translationDir ?? "locales",
|
|
446
480
|
localeCookie: options.localeCookie ?? "user-locale",
|
|
447
481
|
autoDetectLanguage: options.autoDetectLanguage ?? true,
|
|
@@ -505,7 +539,7 @@ const module = defineNuxtModule({
|
|
|
505
539
|
}
|
|
506
540
|
addServerHandler({
|
|
507
541
|
route: `/${apiBaseUrl}/:page/:locale/data.json`,
|
|
508
|
-
handler: resolver.resolve("./runtime/server/
|
|
542
|
+
handler: resolver.resolve("./runtime/server/routes/get")
|
|
509
543
|
});
|
|
510
544
|
await addComponentsDir({
|
|
511
545
|
path: resolver.resolve("./runtime/components"),
|
|
@@ -519,27 +553,8 @@ const module = defineNuxtModule({
|
|
|
519
553
|
});
|
|
520
554
|
}
|
|
521
555
|
extendPages((pages) => {
|
|
522
|
-
if (isNoPrefixStrategy(options.strategy)) {
|
|
523
|
-
return;
|
|
524
|
-
}
|
|
525
|
-
const pagesNames = pages.map((page) => page.name).filter((name) => name !== void 0 && (!options.routesLocaleLinks || !options.routesLocaleLinks[name]));
|
|
526
|
-
if (!options.disableWatcher) {
|
|
527
|
-
localeManager.ensureTranslationFilesExist(pagesNames, options.translationDir, nuxt.options.rootDir);
|
|
528
|
-
}
|
|
529
|
-
pageManager.extendPages(pages, options.customRegexMatcher, isCloudflarePages);
|
|
530
|
-
if (isPrefixStrategy(options.strategy) && !isCloudflarePages) {
|
|
531
|
-
const fallbackRoute = {
|
|
532
|
-
path: "/:pathMatch(.*)*",
|
|
533
|
-
name: "custom-fallback-route",
|
|
534
|
-
file: resolver.resolve("./runtime/components/locale-redirect.vue"),
|
|
535
|
-
meta: {
|
|
536
|
-
globalLocaleRoutes: options.globalLocaleRoutes
|
|
537
|
-
}
|
|
538
|
-
};
|
|
539
|
-
pages.push(fallbackRoute);
|
|
540
|
-
}
|
|
541
|
-
nuxt.options.generate.routes = Array.isArray(nuxt.options.generate.routes) ? nuxt.options.generate.routes : [];
|
|
542
556
|
const prerenderRoutes = [];
|
|
557
|
+
const pagesNames = pages.map((page) => page.name).filter((name) => name !== void 0 && (!options.routesLocaleLinks || !options.routesLocaleLinks[name]));
|
|
543
558
|
localeManager.locales.forEach((locale) => {
|
|
544
559
|
if (!options.disablePageLocales) {
|
|
545
560
|
pagesNames.forEach((name) => {
|
|
@@ -548,36 +563,61 @@ const module = defineNuxtModule({
|
|
|
548
563
|
}
|
|
549
564
|
prerenderRoutes.push(`/${apiBaseUrl}/general/${locale.code}/data.json`);
|
|
550
565
|
});
|
|
551
|
-
if (
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
566
|
+
if (!isNoPrefixStrategy(options.strategy)) {
|
|
567
|
+
if (!options.disableWatcher) {
|
|
568
|
+
localeManager.ensureTranslationFilesExist(pagesNames, options.translationDir, nuxt.options.rootDir);
|
|
569
|
+
}
|
|
570
|
+
pageManager.extendPages(pages, options.customRegexMatcher, isCloudflarePages);
|
|
571
|
+
if (isPrefixStrategy(options.strategy) && !isCloudflarePages) {
|
|
572
|
+
const fallbackRoute = {
|
|
573
|
+
path: "/:pathMatch(.*)*",
|
|
574
|
+
name: "custom-fallback-route",
|
|
575
|
+
file: resolver.resolve("./runtime/components/locale-redirect.vue"),
|
|
576
|
+
meta: {
|
|
577
|
+
globalLocaleRoutes: options.globalLocaleRoutes
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
pages.push(fallbackRoute);
|
|
581
|
+
}
|
|
582
|
+
nuxt.options.generate.routes = Array.isArray(nuxt.options.generate.routes) ? nuxt.options.generate.routes : [];
|
|
583
|
+
if (isCloudflarePages) {
|
|
584
|
+
const processPageWithChildren = (page, parentPath = "") => {
|
|
585
|
+
if (!page.path)
|
|
586
|
+
return;
|
|
587
|
+
const fullPath = path.posix.normalize(`${parentPath}/${page.path}`);
|
|
588
|
+
const localeSegmentMatch = fullPath.match(/:locale\(([^)]+)\)/);
|
|
589
|
+
if (localeSegmentMatch) {
|
|
590
|
+
const availableLocales = localeSegmentMatch[1].split("|");
|
|
591
|
+
localeManager.locales.forEach((locale) => {
|
|
592
|
+
const localeCode = locale.code;
|
|
593
|
+
if (availableLocales.includes(localeCode)) {
|
|
594
|
+
let localizedPath = fullPath;
|
|
595
|
+
localizedPath = localizedPath.replace(/:locale\([^)]+\)/, localeCode);
|
|
596
|
+
prerenderRoutes.push(localizedPath);
|
|
597
|
+
}
|
|
598
|
+
});
|
|
599
|
+
} else {
|
|
600
|
+
prerenderRoutes.push(fullPath);
|
|
601
|
+
}
|
|
602
|
+
if (page.children && page.children.length) {
|
|
603
|
+
page.children.forEach((childPage) => processPageWithChildren(childPage, fullPath));
|
|
604
|
+
}
|
|
605
|
+
};
|
|
606
|
+
pages.forEach((page) => {
|
|
607
|
+
processPageWithChildren(page);
|
|
608
|
+
});
|
|
609
|
+
}
|
|
577
610
|
}
|
|
578
611
|
addPrerenderRoutes(prerenderRoutes);
|
|
579
612
|
});
|
|
580
613
|
nuxt.hook("nitro:config", (nitroConfig) => {
|
|
614
|
+
nitroConfig.bundledStorage = nitroConfig.bundledStorage || [];
|
|
615
|
+
nitroConfig.bundledStorage.push("i18n-locales");
|
|
616
|
+
nitroConfig.devStorage = nitroConfig.devStorage || {};
|
|
617
|
+
nitroConfig.devStorage["i18n-locales"] = {
|
|
618
|
+
driver: "fs",
|
|
619
|
+
base: path.join(nuxt.options.rootDir, "server/assets/i18n-locales")
|
|
620
|
+
};
|
|
581
621
|
if (nitroConfig.imports) {
|
|
582
622
|
nitroConfig.imports.presets = nitroConfig.imports.presets || [];
|
|
583
623
|
nitroConfig.imports.presets.push({
|
|
@@ -592,7 +632,7 @@ const module = defineNuxtModule({
|
|
|
592
632
|
nuxt.options.generate.routes = Array.isArray(nuxt.options.generate.routes) ? nuxt.options.generate.routes : [];
|
|
593
633
|
const pages = nuxt.options.generate.routes || [];
|
|
594
634
|
localeManager.locales.forEach((locale) => {
|
|
595
|
-
if (locale.code !==
|
|
635
|
+
if (locale.code !== defaultLocale || withPrefixStrategy(options.strategy)) {
|
|
596
636
|
pages.forEach((page) => {
|
|
597
637
|
if (!/\.[a-z0-9]+$/i.test(page)) {
|
|
598
638
|
routes.push(`/${locale.code}${page}`);
|
|
@@ -616,6 +656,64 @@ const module = defineNuxtModule({
|
|
|
616
656
|
}
|
|
617
657
|
}
|
|
618
658
|
});
|
|
659
|
+
nuxt.hook("nitro:init", async (nitro) => {
|
|
660
|
+
logger.debug("[nuxt-i18n-micro] clear storage cache");
|
|
661
|
+
await nitro.storage.clear("i18n-locales");
|
|
662
|
+
if (!await nitro.storage.hasItem(`i18n-locales:.gitignore`)) {
|
|
663
|
+
const dir = path.join(nuxt.options.rootDir, "server/assets/i18n-locales");
|
|
664
|
+
fs__default.mkdirSync(dir, { recursive: true });
|
|
665
|
+
fs__default.writeFileSync(`${dir}/.gitignore`, "*");
|
|
666
|
+
}
|
|
667
|
+
const translationDir = options.translationDir ?? "";
|
|
668
|
+
const fallbackLocale = options.fallbackLocale ?? null;
|
|
669
|
+
const translationsByLocale = {};
|
|
670
|
+
try {
|
|
671
|
+
for (const rootDir of rootDirs) {
|
|
672
|
+
const baseDir = path.resolve(rootDir, translationDir);
|
|
673
|
+
const files = await globby("**/*.json", { cwd: baseDir });
|
|
674
|
+
const promises = files.map(async (file) => {
|
|
675
|
+
const filePath = path.join(baseDir, file);
|
|
676
|
+
const content = await readFile(filePath, "utf-8");
|
|
677
|
+
const data = JSON.parse(content);
|
|
678
|
+
const parts = file.split("/");
|
|
679
|
+
const locale = parts.pop()?.replace(".json", "") || "";
|
|
680
|
+
const pageKey = parts.pop() || "general";
|
|
681
|
+
if (!translationsByLocale[locale]) {
|
|
682
|
+
translationsByLocale[locale] = {};
|
|
683
|
+
}
|
|
684
|
+
translationsByLocale[locale] = deepMerge({
|
|
685
|
+
[pageKey]: data
|
|
686
|
+
}, translationsByLocale[locale]);
|
|
687
|
+
});
|
|
688
|
+
await Promise.all(promises);
|
|
689
|
+
}
|
|
690
|
+
const savePromises = [];
|
|
691
|
+
for (const [locale, translations] of Object.entries(translationsByLocale)) {
|
|
692
|
+
for (const [key, value] of Object.entries(translations)) {
|
|
693
|
+
const storageKey = `i18n-locales:${locale}:${key}`;
|
|
694
|
+
const promise = (async () => {
|
|
695
|
+
let translation = value;
|
|
696
|
+
if (fallbackLocale) {
|
|
697
|
+
translation = deepMerge(
|
|
698
|
+
translation,
|
|
699
|
+
translationsByLocale[fallbackLocale][key] ?? {}
|
|
700
|
+
);
|
|
701
|
+
}
|
|
702
|
+
if (typeof translation === "object" && translation !== null) {
|
|
703
|
+
await nitro.storage.setItem(storageKey, translation);
|
|
704
|
+
if (options.debug) {
|
|
705
|
+
logger.log(`[nuxt-i18n-micro] Translation saved to Nitro storage with key: ${storageKey}`);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
})();
|
|
709
|
+
savePromises.push(promise);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
await Promise.all(savePromises);
|
|
713
|
+
} catch (err) {
|
|
714
|
+
logger.error("[nuxt-i18n-micro] Error processing translations:", err);
|
|
715
|
+
}
|
|
716
|
+
});
|
|
619
717
|
if (!options.disableUpdater) {
|
|
620
718
|
nuxt.hook("nitro:build:before", async (_nitro) => {
|
|
621
719
|
const isProd = nuxt.options.dev === false;
|
|
@@ -623,7 +721,7 @@ const module = defineNuxtModule({
|
|
|
623
721
|
const translationPath = path.resolve(nuxt.options.rootDir, options.translationDir);
|
|
624
722
|
logger.log("\u2139 add file watcher: " + translationPath);
|
|
625
723
|
const watcherEvent = async (path2) => {
|
|
626
|
-
watcher.close();
|
|
724
|
+
await watcher.close();
|
|
627
725
|
logger.log("\u21BB update store item: " + path2);
|
|
628
726
|
nuxt.callHook("restart");
|
|
629
727
|
};
|
|
@@ -643,7 +741,7 @@ const module = defineNuxtModule({
|
|
|
643
741
|
routesSet.forEach((route) => {
|
|
644
742
|
if (!/\.[a-z0-9]+$/i.test(route)) {
|
|
645
743
|
localeManager.locales.forEach((locale) => {
|
|
646
|
-
if (locale.code !==
|
|
744
|
+
if (locale.code !== defaultLocale) {
|
|
647
745
|
if (route === "/") {
|
|
648
746
|
additionalRoutes.add(`/${locale.code}`);
|
|
649
747
|
} else {
|
|
@@ -244,8 +244,13 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
244
244
|
return;
|
|
245
245
|
}
|
|
246
246
|
const locale = i18nHelper.getLocale();
|
|
247
|
-
const url = `/${apiBaseUrl}/${fRouteName}/${locale}/data.json
|
|
248
|
-
const data = await $fetch(url, {
|
|
247
|
+
const url = `/${apiBaseUrl}/${fRouteName}/${locale}/data.json`.replace(/\/{2,}/g, "/");
|
|
248
|
+
const data = await $fetch(url, {
|
|
249
|
+
baseURL: runtimeConfig.app.baseURL,
|
|
250
|
+
params: {
|
|
251
|
+
v: i18nConfig.dateBuild
|
|
252
|
+
}
|
|
253
|
+
});
|
|
249
254
|
await i18nHelper.loadPageTranslations(routeName, data ?? {});
|
|
250
255
|
}
|
|
251
256
|
} catch (_error) {
|
|
@@ -270,9 +275,12 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
270
275
|
}
|
|
271
276
|
if (!i18nHelper.hasGeneralTranslation()) {
|
|
272
277
|
const locale = i18nHelper.getLocale();
|
|
273
|
-
const url = `/${apiBaseUrl}/general/${locale}/data.json
|
|
278
|
+
const url = `/${apiBaseUrl}/general/${locale}/data.json`.replace(/\/{2,}/g, "/");
|
|
274
279
|
const data = await $fetch(url, {
|
|
275
|
-
baseURL: runtimeConfig.app.baseURL
|
|
280
|
+
baseURL: runtimeConfig.app.baseURL,
|
|
281
|
+
params: {
|
|
282
|
+
v: i18nConfig.dateBuild
|
|
283
|
+
}
|
|
276
284
|
});
|
|
277
285
|
await i18nHelper.loadTranslations(data ?? {});
|
|
278
286
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defineEventHandler } from "h3";
|
|
2
|
+
import { createError, useRuntimeConfig, useStorage } from "#imports";
|
|
3
|
+
export default defineEventHandler(async (event) => {
|
|
4
|
+
const { page, locale } = event.context.params;
|
|
5
|
+
const config = useRuntimeConfig();
|
|
6
|
+
const { customRegexMatcher, locales } = config.public.i18nConfig;
|
|
7
|
+
if (customRegexMatcher && locales && !locales.map((l) => l.code).includes(locale)) {
|
|
8
|
+
throw createError({ statusCode: 404 });
|
|
9
|
+
}
|
|
10
|
+
const cacheKey = `${locale}:${page}`;
|
|
11
|
+
const serverStorage = useStorage("i18n-locales");
|
|
12
|
+
if (await serverStorage.hasItem(cacheKey)) {
|
|
13
|
+
const rawContent = await serverStorage.getItem(cacheKey) || {};
|
|
14
|
+
return typeof rawContent === "string" ? JSON.parse(rawContent) : rawContent;
|
|
15
|
+
}
|
|
16
|
+
return {};
|
|
17
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-i18n-micro",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.62.0",
|
|
4
4
|
"description": "Nuxt I18n Micro is a lightweight, high-performance internationalization module for Nuxt, designed to handle multi-language support with minimal overhead, fast build times, and efficient runtime performance.",
|
|
5
5
|
"repository": "s00d/nuxt-i18n-micro",
|
|
6
6
|
"license": "MIT",
|
|
@@ -48,31 +48,32 @@
|
|
|
48
48
|
],
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@nuxt/devtools-kit": "^1.7.0",
|
|
51
|
-
"@nuxt/kit": "^3.15.
|
|
51
|
+
"@nuxt/kit": "^3.15.2",
|
|
52
52
|
"chokidar": "^3.6.0",
|
|
53
|
+
"globby": "^14.0.2",
|
|
53
54
|
"sirv": "^2.0.4",
|
|
54
55
|
"ufo": "^1.5.4",
|
|
55
|
-
"nuxt-i18n-micro-
|
|
56
|
-
"nuxt-i18n-micro-
|
|
56
|
+
"nuxt-i18n-micro-core": "1.0.11",
|
|
57
|
+
"nuxt-i18n-micro-test-utils": "1.0.4"
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
|
59
|
-
"@types/jest": "^29.5.14",
|
|
60
60
|
"@nuxt/devtools": "^1.7.0",
|
|
61
61
|
"@nuxt/devtools-ui-kit": "^1.7.0",
|
|
62
62
|
"@nuxt/eslint-config": "0.7.4",
|
|
63
63
|
"@nuxt/module-builder": "^0.8.4",
|
|
64
|
-
"@nuxt/schema": "^3.15.
|
|
65
|
-
"@nuxt/test-utils": "^3.15.
|
|
64
|
+
"@nuxt/schema": "^3.15.2",
|
|
65
|
+
"@nuxt/test-utils": "^3.15.4",
|
|
66
66
|
"@playwright/test": "^1.49.1",
|
|
67
|
+
"@types/jest": "^29.5.14",
|
|
67
68
|
"@types/node": "^20.17.10",
|
|
68
69
|
"changelogen": "^0.5.7",
|
|
69
70
|
"eslint": "^8.57.1",
|
|
70
|
-
"
|
|
71
|
+
"jest": "^29.7.0",
|
|
72
|
+
"nuxt": "^3.15.2",
|
|
73
|
+
"ts-jest": "^29.2.5",
|
|
71
74
|
"typescript": "5.6.3",
|
|
72
75
|
"vitepress": "^1.5.0",
|
|
73
76
|
"vitest": "^2.1.8",
|
|
74
|
-
"jest": "^29.7.0",
|
|
75
|
-
"ts-jest": "^29.2.5",
|
|
76
77
|
"vue-tsc": "2.1.10"
|
|
77
78
|
},
|
|
78
79
|
"optionalDependencies": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"id":"019df560-5b4f-4d25-8ca1-a8cad935e3d2","timestamp":1736953866014,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.spotlight[data-v-3074ece5]{background:linear-gradient(45deg,#00dc82,#36e4da 50%,#0047e1);bottom:-30vh;filter:blur(20vh);height:40vh}.gradient-border[data-v-3074ece5]{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-radius:.5rem;position:relative}@media (prefers-color-scheme:light){.gradient-border[data-v-3074ece5]{background-color:#ffffff4d}.gradient-border[data-v-3074ece5]:before{background:linear-gradient(90deg,#e2e2e2,#e2e2e2 25%,#00dc82,#36e4da 75%,#0047e1)}}@media (prefers-color-scheme:dark){.gradient-border[data-v-3074ece5]{background-color:#1414144d}.gradient-border[data-v-3074ece5]:before{background:linear-gradient(90deg,#303030,#303030 25%,#00dc82,#36e4da 75%,#0047e1)}}.gradient-border[data-v-3074ece5]:before{background-size:400% auto;border-radius:.5rem;bottom:0;content:"";left:0;-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:.5;padding:2px;position:absolute;right:0;top:0;transition:background-position .3s ease-in-out,opacity .2s ease-in-out;width:100%}.gradient-border[data-v-3074ece5]:hover:before{background-position:-50% 0;opacity:1}.fixed[data-v-3074ece5]{position:fixed}.left-0[data-v-3074ece5]{left:0}.right-0[data-v-3074ece5]{right:0}.z-10[data-v-3074ece5]{z-index:10}.z-20[data-v-3074ece5]{z-index:20}.grid[data-v-3074ece5]{display:grid}.mb-16[data-v-3074ece5]{margin-bottom:4rem}.mb-8[data-v-3074ece5]{margin-bottom:2rem}.max-w-520px[data-v-3074ece5]{max-width:520px}.min-h-screen[data-v-3074ece5]{min-height:100vh}.w-full[data-v-3074ece5]{width:100%}.flex[data-v-3074ece5]{display:flex}.cursor-pointer[data-v-3074ece5]{cursor:pointer}.place-content-center[data-v-3074ece5]{place-content:center}.items-center[data-v-3074ece5]{align-items:center}.justify-center[data-v-3074ece5]{justify-content:center}.overflow-hidden[data-v-3074ece5]{overflow:hidden}.bg-white[data-v-3074ece5]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-4[data-v-3074ece5]{padding-left:1rem;padding-right:1rem}.px-8[data-v-3074ece5]{padding-left:2rem;padding-right:2rem}.py-2[data-v-3074ece5]{padding-bottom:.5rem;padding-top:.5rem}.text-center[data-v-3074ece5]{text-align:center}.text-8xl[data-v-3074ece5]{font-size:6rem;line-height:1}.text-xl[data-v-3074ece5]{font-size:1.25rem;line-height:1.75rem}.text-black[data-v-3074ece5]{--un-text-opacity:1;color:rgb(0 0 0/var(--un-text-opacity))}.font-light[data-v-3074ece5]{font-weight:300}.font-medium[data-v-3074ece5]{font-weight:500}.leading-tight[data-v-3074ece5]{line-height:1.25}.font-sans[data-v-3074ece5]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.antialiased[data-v-3074ece5]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (prefers-color-scheme:dark){.dark\:bg-black[data-v-3074ece5]{--un-bg-opacity:1;background-color:rgb(0 0 0/var(--un-bg-opacity))}.dark\:text-white[data-v-3074ece5]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media (min-width:640px){.sm\:px-0[data-v-3074ece5]{padding-left:0;padding-right:0}.sm\:px-6[data-v-3074ece5]{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-3[data-v-3074ece5]{padding-bottom:.75rem;padding-top:.75rem}.sm\:text-4xl[data-v-3074ece5]{font-size:2.25rem;line-height:2.5rem}.sm\:text-xl[data-v-3074ece5]{font-size:1.25rem;line-height:1.75rem}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.spotlight[data-v-44593346]{background:linear-gradient(45deg,#00dc82,#36e4da 50%,#0047e1);filter:blur(20vh)}.fixed[data-v-44593346]{position:fixed}.-bottom-1\/2[data-v-44593346]{bottom:-50%}.left-0[data-v-44593346]{left:0}.right-0[data-v-44593346]{right:0}.grid[data-v-44593346]{display:grid}.mb-16[data-v-44593346]{margin-bottom:4rem}.mb-8[data-v-44593346]{margin-bottom:2rem}.h-1\/2[data-v-44593346]{height:50%}.max-w-520px[data-v-44593346]{max-width:520px}.min-h-screen[data-v-44593346]{min-height:100vh}.place-content-center[data-v-44593346]{place-content:center}.overflow-hidden[data-v-44593346]{overflow:hidden}.bg-white[data-v-44593346]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-8[data-v-44593346]{padding-left:2rem;padding-right:2rem}.text-center[data-v-44593346]{text-align:center}.text-8xl[data-v-44593346]{font-size:6rem;line-height:1}.text-xl[data-v-44593346]{font-size:1.25rem;line-height:1.75rem}.text-black[data-v-44593346]{--un-text-opacity:1;color:rgb(0 0 0/var(--un-text-opacity))}.font-light[data-v-44593346]{font-weight:300}.font-medium[data-v-44593346]{font-weight:500}.leading-tight[data-v-44593346]{line-height:1.25}.font-sans[data-v-44593346]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.antialiased[data-v-44593346]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (prefers-color-scheme:dark){.dark\:bg-black[data-v-44593346]{--un-bg-opacity:1;background-color:rgb(0 0 0/var(--un-bg-opacity))}.dark\:text-white[data-v-44593346]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media (min-width:640px){.sm\:px-0[data-v-44593346]{padding-left:0;padding-right:0}.sm\:text-4xl[data-v-44593346]{font-size:2.25rem;line-height:2.5rem}}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { resolve, join } from "node:path";
|
|
2
|
-
import { readFile } from "node:fs/promises";
|
|
3
|
-
import { defineEventHandler } from "h3";
|
|
4
|
-
import { useRuntimeConfig, createError, useStorage } from "#imports";
|
|
5
|
-
let storageInit = false;
|
|
6
|
-
function deepMerge(target, source) {
|
|
7
|
-
for (const key in source) {
|
|
8
|
-
if (key === "__proto__" || key === "constructor") continue;
|
|
9
|
-
if (Array.isArray(source[key])) {
|
|
10
|
-
target[key] = source[key];
|
|
11
|
-
} else if (source[key] instanceof Object) {
|
|
12
|
-
target[key] = target[key] instanceof Object ? deepMerge(target[key], source[key]) : source[key];
|
|
13
|
-
} else {
|
|
14
|
-
target[key] = source[key];
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return target;
|
|
18
|
-
}
|
|
19
|
-
export default defineEventHandler(async (event) => {
|
|
20
|
-
const { page, locale } = event.context.params;
|
|
21
|
-
const config = useRuntimeConfig();
|
|
22
|
-
const { rootDirs, debug } = config.i18nConfig;
|
|
23
|
-
const { translationDir, fallbackLocale, customRegexMatcher, locales } = config.public.i18nConfig;
|
|
24
|
-
if (customRegexMatcher && locales && !locales.map((l) => l.code).includes(locale)) {
|
|
25
|
-
throw createError({ statusCode: 404 });
|
|
26
|
-
}
|
|
27
|
-
const getTranslationPath = (locale2, page2) => page2 === "general" ? `${locale2}.json` : `pages/${page2}/${locale2}.json`;
|
|
28
|
-
const createPaths = (locale2) => rootDirs.map((dir) => ({
|
|
29
|
-
translationPath: resolve(dir, translationDir, getTranslationPath(locale2, page)),
|
|
30
|
-
name: `_locales/${getTranslationPath(locale2, page)}`
|
|
31
|
-
}));
|
|
32
|
-
const paths = [
|
|
33
|
-
...fallbackLocale && fallbackLocale !== locale ? createPaths(fallbackLocale) : [],
|
|
34
|
-
...createPaths(locale)
|
|
35
|
-
];
|
|
36
|
-
let translations = {};
|
|
37
|
-
const serverStorage = await useStorage("assets:server");
|
|
38
|
-
if (!storageInit) {
|
|
39
|
-
if (debug) console.log("[nuxt-i18n-micro] clear storage cache");
|
|
40
|
-
await Promise.all((await serverStorage.getKeys()).map((key) => serverStorage.removeItem(key)));
|
|
41
|
-
storageInit = true;
|
|
42
|
-
}
|
|
43
|
-
const cacheName = join("_locales", getTranslationPath(locale, page));
|
|
44
|
-
const isThereAsset = await serverStorage.hasItem(cacheName);
|
|
45
|
-
if (isThereAsset) {
|
|
46
|
-
const rawContent = await serverStorage.getItem(cacheName) ?? {};
|
|
47
|
-
return typeof rawContent === "string" ? JSON.parse(rawContent) : rawContent;
|
|
48
|
-
}
|
|
49
|
-
for (const { translationPath, name } of paths) {
|
|
50
|
-
try {
|
|
51
|
-
if (debug) console.log("[nuxt-i18n-micro] load locale", translationPath, name);
|
|
52
|
-
const content = await readFile(translationPath, "utf-8");
|
|
53
|
-
const fileContent = JSON.parse(content);
|
|
54
|
-
translations = deepMerge(translations, fileContent);
|
|
55
|
-
} catch (e) {
|
|
56
|
-
if (debug) console.error("[nuxt-i18n-micro] load locale error", e);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
await serverStorage.setItem(cacheName, translations);
|
|
60
|
-
return translations;
|
|
61
|
-
});
|
|
File without changes
|