@i18n-micro/astro 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +279 -266
- package/package.json +3 -3
- package/src/utils.ts +26 -5
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const w=require("@i18n-micro/core"),S=require("node:fs"),k=require("node:path");class j extends w.BaseI18n{constructor(e){const s=e._storage||{translations:new Map};if(super({storage:s,plural:e.plural,missingWarn:e.missingWarn,missingHandler:e.missingHandler}),this.initialMessages={},this.storage=s,this._locale=e.locale,this._fallbackLocale=e.fallbackLocale||e.locale,this._currentRoute="index",e.messages){this.initialMessages={...e.messages};for(const[a,i]of Object.entries(e.messages))this.helper.loadTranslations(a,i)}}cloneStorage(e){const s=new Map;for(const[a,i]of e.translations)s.set(a,{...i});return{translations:s}}clone(e){const s=this.cloneStorage(this.storage);return new j({locale:e||this._locale,fallbackLocale:this._fallbackLocale,plural:this.pluralFunc,missingWarn:this.missingWarn,missingHandler:this.missingHandler,_storage:s})}get locale(){return this._locale}set locale(e){this._locale=e}get fallbackLocale(){return this._fallbackLocale}set fallbackLocale(e){this._fallbackLocale=e}setRoute(e){this._currentRoute=e}getLocale(){return this._locale}getFallbackLocale(){return this._fallbackLocale}getRoute(){return this._currentRoute}getRouteTranslations(e,s){const a=`${e}:${s}`;return this.storage.translations.get(a)??null}addTranslations(e,s,a=!0){super.loadTranslationsCore(e,s,a)}addRouteTranslations(e,s,a,i=!0){super.loadRouteTranslationsCore(e,s,a,i)}mergeTranslations(e,s,a){this.helper.mergeTranslation(e,s,a,!0)}clearCache(){const e={...this.initialMessages};if(super.clearCache(),Object.keys(e).length>0)for(const[s,a]of Object.entries(e))this.helper.loadTranslations(s,a)}}let I=null;function D(){return I}function C(t){const{locale:e,fallbackLocale:s,translationDir:a,routingStrategy:i}=t;return I=i||null,{name:"@i18n-micro/astro",hooks:{"astro:config:setup":c=>{const{updateConfig:u}=c,n="virtual:i18n-micro/config",l=`\0${n}`,r={defaultLocale:e,fallbackLocale:s||e,locales:t.locales||[],localeCodes:(t.locales||[]).map(o=>o.code),translationDir:a||null,autoDetect:t.autoDetect??!0,redirectToDefault:t.redirectToDefault??!1,localeCookie:t.localeCookie===null?null:t.localeCookie||"i18n-locale",missingWarn:t.missingWarn??!1};u({vite:{plugins:[{name:"vite-plugin-i18n-micro-config",resolveId(o){if(o===n)return l},load(o){if(o===l)return`export const config = ${JSON.stringify(r)}`}}]}})},"astro:config:done":c=>{const{injectTypes:u}=c;u({filename:"i18n-micro-env.d.ts",content:`
|
|
2
2
|
/// <reference types="@i18n-micro/astro/env" />
|
|
3
3
|
|
|
4
4
|
declare module 'virtual:i18n-micro/config' {
|
|
@@ -14,4 +14,4 @@
|
|
|
14
14
|
missingWarn: boolean | null;
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
`})}}}}function N(
|
|
17
|
+
`})}}}}function N(t){return new j(t)}function F(t){const{translationDir:e,rootDir:s=process.cwd(),disablePageLocales:a=!1}=t,i=k.resolve(s,e);if(!S.existsSync(i))return console.warn(`[i18n] Translation directory not found: ${i}`),{root:{},routes:{}};const c={},u={},n=(l,r="")=>{if(!S.existsSync(l))return;const o=S.readdirSync(l);for(const g of o){const f=k.join(l,g);if(S.statSync(f).isDirectory())g==="pages"&&!a?n(f,""):r||a?n(f,r):n(f,g);else if(g.endsWith(".json")){const m=g.replace(".json","");try{const p=S.readFileSync(f,"utf-8"),h=JSON.parse(p);r&&!a?(u[r]||(u[r]={}),u[r][m]=h):c[m]=h}catch(p){console.error(`[i18n] Failed to load translation file: ${f}`,p)}}}};return n(i),{root:c,routes:u}}function q(t,e){const{root:s,routes:a}=F(e);for(const[i,c]of Object.entries(s))t.addTranslations(i,c,!1);for(const[i,c]of Object.entries(a))for(const[u,n]of Object.entries(c)){const l=s[u]||{};t.addRouteTranslations(u,i,{...l,...n},!1)}}function M(t){const{i18n:e,defaultLocale:s,locales:a,localeObjects:i,autoDetect:c=!0,redirectToDefault:u=!1,routingStrategy:n}=t,l=n||D();return async(r,o)=>{if(r.locals.locale&&r.locals.i18n)return o();const g=r.url,f=g.pathname;if(!l){const b=e.clone(s),O=f==="/"||f===""?"index":f.split("/").filter(Boolean).join("-");return b.setRoute(O),r.locals.i18n=b,r.locals.locale=s,r.locals.defaultLocale=s,r.locals.locales=i||a.map(_=>({code:_})),r.locals.currentUrl=g,o()}const d={...l,getCurrentPath:()=>f,getRoute:()=>({fullPath:g.pathname+g.search,query:Object.fromEntries(g.searchParams)})},p=f.split("/").filter(Boolean)[0],h=p!==void 0&&a.includes(p);let P;h&&p?P=p:d.getLocaleFromPath?P=d.getLocaleFromPath(f,s,a):P=s;const L=e.clone(P),y=d.getRouteName?d.getRouteName(f,a):"index";return L.setRoute(y),r.locals.i18n=L,r.locals.locale=P,r.locals.defaultLocale=s,r.locals.locales=i||a.map(b=>({code:b})),r.locals.currentUrl=g,r.locals.routingStrategy=d,o()}}function A(t){const e=[],s=t.split(",");for(const a of s){const[i,c="1.0"]=a.trim().split(";q=");if(Number.parseFloat(c)>0&&i){const n=i.split("-")[0]?.toLowerCase();n&&(e.push(n),i!==n&&e.push(i.toLowerCase()))}}return e}function W(t,e,s,a,i,c="i18n-locale"){const u=D();let n=a;if(u?.getLocaleFromPath)n=u.getLocaleFromPath(t,a,i);else{const r=t.split("/").filter(Boolean)[0];r&&i.includes(r)&&(n=r)}if(c!==null&&n===a&&e.get(c)){const l=e.get(c)?.value;l&&i.includes(l)&&(n=l)}if(n===a)try{const l=s.get("accept-language");if(l){const r=A(l);for(const o of r)if(i.includes(o)){n=o;break}}}catch{}return n}function z(t,e,s){const a=t.map(o=>o.code),i=(o,g=[])=>{const f=o.replace(/^\//,"").replace(/\/$/,"");if(!f)return"index";const d=f.split("/").filter(Boolean),m=d[0];return m&&g.includes(m)&&d.shift(),d.length===0?"index":d.join("-")},c=(o,g="en",f=[])=>{const m=o.split("/").filter(Boolean)[0];return m&&f.includes(m)?m:g},u=(o,g,f=[],d)=>{const m=o.split("/").filter(Boolean),p=m[0];return p&&f.includes(p)&&m.shift(),(g!==d||d===void 0)&&m.unshift(g),`/${m.join("/")}`},n=(o,g,f=[],d)=>{const p=(o.replace(/^\//,"").replace(/\/$/,"")||"").split("/").filter(Boolean),h=p[0];return h&&f.includes(h)&&p.shift(),(g!==d||d===void 0)&&p.unshift(g),`/${p.join("/")}`};return{getCurrentPath:()=>s?s().pathname:typeof window<"u"?window.location.pathname:"/",getRouteName:i,getLocaleFromPath:c,switchLocalePath:u,localizePath:n,removeLocaleFromPath:(o,g=[])=>{const f=o.split("/").filter(Boolean),d=f[0];return d&&g.includes(d)&&f.shift(),`/${f.join("/")}`},resolvePath:(o,g)=>{const f=typeof o=="string"?o:o.path||"/";return n(f,g,a,e)},getRoute:()=>{if(s){const o=s();return{fullPath:o.pathname+o.search,query:Object.fromEntries(o.searchParams)}}if(typeof window<"u"){const o=new URL(window.location.href);return{fullPath:o.pathname+o.search,query:Object.fromEntries(o.searchParams)}}return{fullPath:"/",query:{}}},push:o=>{typeof window<"u"&&(window.location.href=o.path)},replace:o=>{typeof window<"u"&&window.location.replace(o.path)}}}function H(t,e=[]){const s=t.replace(/^\//,"").replace(/\/$/,"");if(!s)return"index";const a=s.split("/").filter(Boolean),i=a[0];return i&&e.includes(i)&&a.shift(),a.length===0?"index":a.join("-")}function U(t,e="en",s=[]){const i=t.split("/").filter(Boolean)[0];return i&&s.includes(i)?i:e}function E(t,e,s=[],a){const i=t.split("/").filter(Boolean),c=i[0];return c&&s.includes(c)&&i.shift(),(e!==a||a===void 0)&&i.unshift(e),`/${i.join("/")}`}function J(t,e,s=[],a){const c=(t.replace(/^\//,"").replace(/\/$/,"")||"").split("/").filter(Boolean),u=c[0];return u&&s.includes(u)&&c.shift(),(e!==a||a===void 0)&&c.unshift(e),`/${c.join("/")}`}function V(t,e=[]){const s=t.split("/").filter(Boolean),a=s[0];return a&&e.includes(a)&&s.shift(),`/${s.join("/")}`}function v(t){const e=t.locals.i18n;if(!e)throw new Error("i18n instance not found. Make sure i18n middleware is configured.");return e}function R(t){return t.locals.locale||"en"}function T(t){return t.locals.defaultLocale||"en"}function $(t){return t.locals.locales||[]}function B(t){return t.locals.routingStrategy||null}function G(t){const e=v(t),s=R(t),a=T(t),i=$(t),c=i.map(n=>n.code),u=B(t);return{locale:s,defaultLocale:a,locales:i,t:(n,l,r,o)=>e.t(n,l,r,o),ts:(n,l,r,o)=>e.ts(n,l,r,o),tc:(n,l,r)=>e.tc(n,l,r),tn:(n,l)=>e.tn(n,l),td:(n,l)=>e.td(n,l),tdr:(n,l)=>e.tdr(n,l),has:(n,l)=>e.has(n,l),getRoute:()=>e.getRoute(),getRouteName:n=>{const l=n||t.url.pathname;if(u?.getRouteName)return u.getRouteName(l,c);const r=l.replace(/^\//,"").replace(/\/$/,"");if(!r)return"index";const o=r.split("/").filter(Boolean),g=o[0];return g&&c.includes(g)&&o.shift(),o.length===0?"index":o.join("-")},getLocaleFromPath:n=>{const l=n||t.url.pathname;if(u?.getLocaleFromPath)return u.getLocaleFromPath(l,a,c);const o=l.split("/").filter(Boolean)[0];return o&&c.includes(o)?o:a},switchLocalePath:n=>{if(u?.switchLocalePath)return u.switchLocalePath(t.url.pathname,n,c,a);const l=t.url.pathname.split("/").filter(Boolean),r=l[0];return r&&c.includes(r)&&l.shift(),n!==a&&l.unshift(n),`/${l.join("/")}`},localizePath:(n,l)=>{if(u?.localizePath)return u.localizePath(n,l||s,c,a);const o=(n.replace(/^\//,"").replace(/\/$/,"")||"").split("/").filter(Boolean),g=o[0];return g&&c.includes(g)&&o.shift(),l&&l!==a&&o.unshift(l),`/${o.join("/")}`},getI18n:()=>e,getBasePath:n=>{const o=(n||t.url).pathname.split("/").filter(Boolean),g=o[0];return g&&c.includes(g)&&o.shift(),o.length>0?`/${o.join("/")}`:"/"},addTranslations:(n,l,r=!0)=>{e.addTranslations(n,l,r)},addRouteTranslations:(n,l,r,o=!0)=>{e.addRouteTranslations(n,l,r,o)},mergeTranslations:(n,l,r)=>{e.mergeTranslations(n,l,r)},clearCache:()=>{e.clearCache()}}}function K(t,e={}){const{baseUrl:s="/",addDirAttribute:a=!0,addSeoAttributes:i=!0}=e,c=R(t),u=T(t),l=$(t).filter(h=>!h.disabled),r=l.find(h=>h.code===c);if(!r)return{htmlAttrs:{},link:[],meta:[]};const o=r.iso||c,g=r.dir||"auto",f={htmlAttrs:{lang:o,...a?{dir:g}:{}},link:[],meta:[]};if(!i)return f;const d=`${s}${t.url.pathname}`;f.link.push({rel:"canonical",href:d});const m=B(t),p=l.map(h=>h.code);for(const h of l){let P=t.url.pathname;if(m?.switchLocalePath)P=m.switchLocalePath(t.url.pathname,h.code,p,u);else{const y=t.url.pathname.split("/").filter(Boolean),b=y[0];b&&p.includes(b)&&y.shift(),h.code!==u&&y.unshift(h.code),P=`/${y.join("/")}`}const L=`${s}${P}`;f.link.push({rel:"alternate",href:L,hreflang:h.code}),h.iso&&h.iso!==h.code&&f.link.push({rel:"alternate",href:L,hreflang:h.iso})}{let h=t.url.pathname;if(m?.switchLocalePath)h=m.switchLocalePath(t.url.pathname,u,p,u);else{const P=t.url.pathname.split("/").filter(Boolean),L=P[0];L&&p.includes(L)&&P.shift(),h=`/${P.join("/")}`}f.link.push({rel:"alternate",href:`${s}${h}`,hreflang:"x-default"})}f.meta.push({property:"og:locale",content:o}),f.meta.push({property:"og:url",content:d});for(const h of l)h.code!==c&&f.meta.push({property:"og:locale:alternate",content:h.iso||h.code});return f}function Q(t,e,s){const a=e.split(".");let i=t;for(let u=0;u<a.length-1;u++){const n=a[u];i[n]||(i[n]={}),i=i[n]}const c=a[a.length-1];c!==void 0&&(i[c]=s)}function X(t,e){const s=v(t),a=R(t),i=T(t),c=s.getRoute(),u={};if(e&&e.length>0){const n={};for(const l of e){const r=s.t(l,void 0,void 0,c);r!=null&&r!==l&&Q(n,l,r)}Object.keys(n).length>0&&(u[c]=n)}else{const n=s.getRouteTranslations(a,c);n&&(u[c]=n)}return{locale:a,fallbackLocale:i,currentRoute:c,translations:u}}Object.defineProperty(exports,"FormatService",{enumerable:!0,get:()=>w.FormatService});Object.defineProperty(exports,"defaultPlural",{enumerable:!0,get:()=>w.defaultPlural});Object.defineProperty(exports,"interpolate",{enumerable:!0,get:()=>w.interpolate});exports.AstroI18n=j;exports.createAstroRouterAdapter=z;exports.createI18n=N;exports.createI18nMiddleware=M;exports.detectLocale=W;exports.getDefaultLocale=T;exports.getI18n=v;exports.getI18nProps=X;exports.getLocale=R;exports.getLocaleFromPath=U;exports.getLocales=$;exports.getRouteName=H;exports.i18nIntegration=C;exports.loadTranslationsFromDir=F;exports.loadTranslationsIntoI18n=q;exports.localizePath=J;exports.removeLocaleFromPath=V;exports.switchLocalePath=E;exports.useI18n=G;exports.useLocaleHead=K;
|
package/dist/index.mjs
CHANGED
|
@@ -4,35 +4,35 @@ import { existsSync as j, readdirSync as _, statSync as C, readFileSync as N } f
|
|
|
4
4
|
import { resolve as O, join as q } from "node:path";
|
|
5
5
|
class S extends I {
|
|
6
6
|
constructor(e) {
|
|
7
|
-
const
|
|
7
|
+
const s = e._storage || {
|
|
8
8
|
translations: /* @__PURE__ */ new Map()
|
|
9
9
|
};
|
|
10
10
|
if (super({
|
|
11
|
-
storage:
|
|
11
|
+
storage: s,
|
|
12
12
|
plural: e.plural,
|
|
13
13
|
missingWarn: e.missingWarn,
|
|
14
14
|
missingHandler: e.missingHandler
|
|
15
|
-
}), this.initialMessages = {}, this.storage =
|
|
15
|
+
}), this.initialMessages = {}, this.storage = s, this._locale = e.locale, this._fallbackLocale = e.fallbackLocale || e.locale, this._currentRoute = "index", e.messages) {
|
|
16
16
|
this.initialMessages = { ...e.messages };
|
|
17
|
-
for (const [
|
|
18
|
-
this.helper.loadTranslations(
|
|
17
|
+
for (const [a, i] of Object.entries(e.messages))
|
|
18
|
+
this.helper.loadTranslations(a, i);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
cloneStorage(e) {
|
|
22
|
-
const
|
|
23
|
-
for (const [
|
|
24
|
-
|
|
25
|
-
return { translations:
|
|
22
|
+
const s = /* @__PURE__ */ new Map();
|
|
23
|
+
for (const [a, i] of e.translations)
|
|
24
|
+
s.set(a, { ...i });
|
|
25
|
+
return { translations: s };
|
|
26
26
|
}
|
|
27
27
|
clone(e) {
|
|
28
|
-
const
|
|
28
|
+
const s = this.cloneStorage(this.storage);
|
|
29
29
|
return new S({
|
|
30
30
|
locale: e || this._locale,
|
|
31
31
|
fallbackLocale: this._fallbackLocale,
|
|
32
32
|
plural: this.pluralFunc,
|
|
33
33
|
missingWarn: this.missingWarn,
|
|
34
34
|
missingHandler: this.missingHandler,
|
|
35
|
-
_storage:
|
|
35
|
+
_storage: s
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
get locale() {
|
|
@@ -59,59 +59,59 @@ class S extends I {
|
|
|
59
59
|
getRoute() {
|
|
60
60
|
return this._currentRoute;
|
|
61
61
|
}
|
|
62
|
-
getRouteTranslations(e,
|
|
63
|
-
const
|
|
64
|
-
return this.storage.translations.get(
|
|
62
|
+
getRouteTranslations(e, s) {
|
|
63
|
+
const a = `${e}:${s}`;
|
|
64
|
+
return this.storage.translations.get(a) ?? null;
|
|
65
65
|
}
|
|
66
|
-
addTranslations(e,
|
|
67
|
-
super.loadTranslationsCore(e,
|
|
66
|
+
addTranslations(e, s, a = !0) {
|
|
67
|
+
super.loadTranslationsCore(e, s, a);
|
|
68
68
|
}
|
|
69
|
-
addRouteTranslations(e,
|
|
70
|
-
super.loadRouteTranslationsCore(e,
|
|
69
|
+
addRouteTranslations(e, s, a, i = !0) {
|
|
70
|
+
super.loadRouteTranslationsCore(e, s, a, i);
|
|
71
71
|
}
|
|
72
|
-
mergeTranslations(e,
|
|
73
|
-
this.helper.mergeTranslation(e,
|
|
72
|
+
mergeTranslations(e, s, a) {
|
|
73
|
+
this.helper.mergeTranslation(e, s, a, !0);
|
|
74
74
|
}
|
|
75
75
|
clearCache() {
|
|
76
76
|
const e = { ...this.initialMessages };
|
|
77
77
|
if (super.clearCache(), Object.keys(e).length > 0)
|
|
78
|
-
for (const [
|
|
79
|
-
this.helper.loadTranslations(
|
|
78
|
+
for (const [s, a] of Object.entries(e))
|
|
79
|
+
this.helper.loadTranslations(s, a);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
let T = null;
|
|
83
|
-
function
|
|
83
|
+
function $() {
|
|
84
84
|
return T;
|
|
85
85
|
}
|
|
86
|
-
function E(
|
|
87
|
-
const { locale: e, fallbackLocale:
|
|
86
|
+
function E(t) {
|
|
87
|
+
const { locale: e, fallbackLocale: s, translationDir: a, routingStrategy: i } = t;
|
|
88
88
|
return T = i || null, {
|
|
89
89
|
name: "@i18n-micro/astro",
|
|
90
90
|
hooks: {
|
|
91
91
|
// 1. Vite setup (virtual module) happens here
|
|
92
92
|
"astro:config:setup": (c) => {
|
|
93
|
-
const { updateConfig:
|
|
93
|
+
const { updateConfig: u } = c, n = "virtual:i18n-micro/config", l = `\0${n}`, r = {
|
|
94
94
|
defaultLocale: e,
|
|
95
|
-
fallbackLocale:
|
|
96
|
-
locales:
|
|
97
|
-
localeCodes: (
|
|
98
|
-
translationDir:
|
|
99
|
-
autoDetect:
|
|
100
|
-
redirectToDefault:
|
|
101
|
-
localeCookie:
|
|
102
|
-
missingWarn:
|
|
95
|
+
fallbackLocale: s || e,
|
|
96
|
+
locales: t.locales || [],
|
|
97
|
+
localeCodes: (t.locales || []).map((o) => o.code),
|
|
98
|
+
translationDir: a || null,
|
|
99
|
+
autoDetect: t.autoDetect ?? !0,
|
|
100
|
+
redirectToDefault: t.redirectToDefault ?? !1,
|
|
101
|
+
localeCookie: t.localeCookie === null ? null : t.localeCookie || "i18n-locale",
|
|
102
|
+
missingWarn: t.missingWarn ?? !1
|
|
103
103
|
};
|
|
104
|
-
|
|
104
|
+
u({
|
|
105
105
|
vite: {
|
|
106
106
|
plugins: [
|
|
107
107
|
{
|
|
108
108
|
name: "vite-plugin-i18n-micro-config",
|
|
109
|
-
resolveId(
|
|
110
|
-
if (
|
|
109
|
+
resolveId(o) {
|
|
110
|
+
if (o === n)
|
|
111
111
|
return l;
|
|
112
112
|
},
|
|
113
|
-
load(
|
|
114
|
-
if (
|
|
113
|
+
load(o) {
|
|
114
|
+
if (o === l)
|
|
115
115
|
return `export const config = ${JSON.stringify(r)}`;
|
|
116
116
|
}
|
|
117
117
|
}
|
|
@@ -121,8 +121,8 @@ function E(n) {
|
|
|
121
121
|
},
|
|
122
122
|
// 2. Type injection happens here (per Astro documentation)
|
|
123
123
|
"astro:config:done": (c) => {
|
|
124
|
-
const { injectTypes:
|
|
125
|
-
|
|
124
|
+
const { injectTypes: u } = c;
|
|
125
|
+
u({
|
|
126
126
|
filename: "i18n-micro-env.d.ts",
|
|
127
127
|
content: `
|
|
128
128
|
/// <reference types="@i18n-micro/astro/env" />
|
|
@@ -146,159 +146,159 @@ function E(n) {
|
|
|
146
146
|
}
|
|
147
147
|
};
|
|
148
148
|
}
|
|
149
|
-
function J(
|
|
150
|
-
return new S(
|
|
149
|
+
function J(t) {
|
|
150
|
+
return new S(t);
|
|
151
151
|
}
|
|
152
|
-
function M(
|
|
153
|
-
const { translationDir: e, rootDir:
|
|
152
|
+
function M(t) {
|
|
153
|
+
const { translationDir: e, rootDir: s = process.cwd(), disablePageLocales: a = !1 } = t, i = O(s, e);
|
|
154
154
|
if (!j(i))
|
|
155
155
|
return console.warn(`[i18n] Translation directory not found: ${i}`), { root: {}, routes: {} };
|
|
156
|
-
const c = {},
|
|
156
|
+
const c = {}, u = {}, n = (l, r = "") => {
|
|
157
157
|
if (!j(l)) return;
|
|
158
|
-
const
|
|
159
|
-
for (const
|
|
160
|
-
const
|
|
161
|
-
if (C(
|
|
162
|
-
|
|
163
|
-
else if (
|
|
164
|
-
const m =
|
|
158
|
+
const o = _(l);
|
|
159
|
+
for (const g of o) {
|
|
160
|
+
const f = q(l, g);
|
|
161
|
+
if (C(f).isDirectory())
|
|
162
|
+
g === "pages" && !a ? n(f, "") : r || a ? n(f, r) : n(f, g);
|
|
163
|
+
else if (g.endsWith(".json")) {
|
|
164
|
+
const m = g.replace(".json", "");
|
|
165
165
|
try {
|
|
166
|
-
const
|
|
167
|
-
r && !
|
|
168
|
-
} catch (
|
|
169
|
-
console.error(`[i18n] Failed to load translation file: ${
|
|
166
|
+
const p = N(f, "utf-8"), h = JSON.parse(p);
|
|
167
|
+
r && !a ? (u[r] || (u[r] = {}), u[r][m] = h) : c[m] = h;
|
|
168
|
+
} catch (p) {
|
|
169
|
+
console.error(`[i18n] Failed to load translation file: ${f}`, p);
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
};
|
|
174
|
-
return
|
|
174
|
+
return n(i), { root: c, routes: u };
|
|
175
175
|
}
|
|
176
|
-
function V(
|
|
177
|
-
const { root:
|
|
176
|
+
function V(t, e) {
|
|
177
|
+
const { root: s, routes: a } = M(e);
|
|
178
|
+
for (const [i, c] of Object.entries(s))
|
|
179
|
+
t.addTranslations(i, c, !1);
|
|
178
180
|
for (const [i, c] of Object.entries(a))
|
|
179
|
-
n.
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const l = a[f] || {};
|
|
183
|
-
n.addRouteTranslations(f, i, { ...l, ...t }, !1);
|
|
181
|
+
for (const [u, n] of Object.entries(c)) {
|
|
182
|
+
const l = s[u] || {};
|
|
183
|
+
t.addRouteTranslations(u, i, { ...l, ...n }, !1);
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
|
-
function G(
|
|
186
|
+
function G(t) {
|
|
187
187
|
const {
|
|
188
188
|
i18n: e,
|
|
189
189
|
// This is the global singleton with cache
|
|
190
|
-
defaultLocale:
|
|
191
|
-
locales:
|
|
190
|
+
defaultLocale: s,
|
|
191
|
+
locales: a,
|
|
192
192
|
localeObjects: i,
|
|
193
193
|
autoDetect: c = !0,
|
|
194
|
-
redirectToDefault:
|
|
195
|
-
routingStrategy:
|
|
196
|
-
} =
|
|
197
|
-
return async (r,
|
|
194
|
+
redirectToDefault: u = !1,
|
|
195
|
+
routingStrategy: n
|
|
196
|
+
} = t, l = n || $();
|
|
197
|
+
return async (r, o) => {
|
|
198
198
|
if (r.locals.locale && r.locals.i18n)
|
|
199
|
-
return
|
|
200
|
-
const
|
|
199
|
+
return o();
|
|
200
|
+
const g = r.url, f = g.pathname;
|
|
201
201
|
if (!l) {
|
|
202
|
-
const b = e.clone(
|
|
203
|
-
return b.setRoute(B), r.locals.i18n = b, r.locals.locale =
|
|
202
|
+
const b = e.clone(s), B = f === "/" || f === "" ? "index" : f.split("/").filter(Boolean).join("-");
|
|
203
|
+
return b.setRoute(B), r.locals.i18n = b, r.locals.locale = s, r.locals.defaultLocale = s, r.locals.locales = i || a.map((F) => ({ code: F })), r.locals.currentUrl = g, o();
|
|
204
204
|
}
|
|
205
205
|
const d = {
|
|
206
206
|
...l,
|
|
207
|
-
getCurrentPath: () =>
|
|
207
|
+
getCurrentPath: () => f,
|
|
208
208
|
getRoute: () => ({
|
|
209
|
-
fullPath:
|
|
210
|
-
query: Object.fromEntries(
|
|
209
|
+
fullPath: g.pathname + g.search,
|
|
210
|
+
query: Object.fromEntries(g.searchParams)
|
|
211
211
|
})
|
|
212
|
-
},
|
|
212
|
+
}, p = f.split("/").filter(Boolean)[0], h = p !== void 0 && a.includes(p);
|
|
213
213
|
let P;
|
|
214
|
-
|
|
215
|
-
const L = e.clone(P), y = d.getRouteName ? d.getRouteName(
|
|
216
|
-
return L.setRoute(y), r.locals.i18n = L, r.locals.locale = P, r.locals.defaultLocale =
|
|
214
|
+
h && p ? P = p : d.getLocaleFromPath ? P = d.getLocaleFromPath(f, s, a) : P = s;
|
|
215
|
+
const L = e.clone(P), y = d.getRouteName ? d.getRouteName(f, a) : "index";
|
|
216
|
+
return L.setRoute(y), r.locals.i18n = L, r.locals.locale = P, r.locals.defaultLocale = s, r.locals.locales = i || a.map((b) => ({ code: b })), r.locals.currentUrl = g, r.locals.routingStrategy = d, o();
|
|
217
217
|
};
|
|
218
218
|
}
|
|
219
|
-
function W(
|
|
220
|
-
const e = [],
|
|
221
|
-
for (const
|
|
222
|
-
const [i, c = "1.0"] =
|
|
219
|
+
function W(t) {
|
|
220
|
+
const e = [], s = t.split(",");
|
|
221
|
+
for (const a of s) {
|
|
222
|
+
const [i, c = "1.0"] = a.trim().split(";q=");
|
|
223
223
|
if (Number.parseFloat(c) > 0 && i) {
|
|
224
|
-
const
|
|
225
|
-
|
|
224
|
+
const n = i.split("-")[0]?.toLowerCase();
|
|
225
|
+
n && (e.push(n), i !== n && e.push(i.toLowerCase()));
|
|
226
226
|
}
|
|
227
227
|
}
|
|
228
228
|
return e;
|
|
229
229
|
}
|
|
230
|
-
function K(
|
|
231
|
-
const
|
|
232
|
-
let
|
|
233
|
-
if (
|
|
234
|
-
|
|
230
|
+
function K(t, e, s, a, i, c = "i18n-locale") {
|
|
231
|
+
const u = $();
|
|
232
|
+
let n = a;
|
|
233
|
+
if (u?.getLocaleFromPath)
|
|
234
|
+
n = u.getLocaleFromPath(t, a, i);
|
|
235
235
|
else {
|
|
236
|
-
const r =
|
|
237
|
-
r && i.includes(r) && (
|
|
236
|
+
const r = t.split("/").filter(Boolean)[0];
|
|
237
|
+
r && i.includes(r) && (n = r);
|
|
238
238
|
}
|
|
239
|
-
if (c !== null &&
|
|
239
|
+
if (c !== null && n === a && e.get(c)) {
|
|
240
240
|
const l = e.get(c)?.value;
|
|
241
|
-
l && i.includes(l) && (
|
|
241
|
+
l && i.includes(l) && (n = l);
|
|
242
242
|
}
|
|
243
|
-
if (
|
|
243
|
+
if (n === a)
|
|
244
244
|
try {
|
|
245
|
-
const l =
|
|
245
|
+
const l = s.get("accept-language");
|
|
246
246
|
if (l) {
|
|
247
247
|
const r = W(l);
|
|
248
|
-
for (const
|
|
249
|
-
if (i.includes(
|
|
250
|
-
|
|
248
|
+
for (const o of r)
|
|
249
|
+
if (i.includes(o)) {
|
|
250
|
+
n = o;
|
|
251
251
|
break;
|
|
252
252
|
}
|
|
253
253
|
}
|
|
254
254
|
} catch {
|
|
255
255
|
}
|
|
256
|
-
return
|
|
256
|
+
return n;
|
|
257
257
|
}
|
|
258
|
-
function
|
|
259
|
-
const
|
|
260
|
-
const
|
|
261
|
-
if (!
|
|
258
|
+
function x(t, e, s) {
|
|
259
|
+
const a = t.map((o) => o.code), i = (o, g = []) => {
|
|
260
|
+
const f = o.replace(/^\//, "").replace(/\/$/, "");
|
|
261
|
+
if (!f)
|
|
262
262
|
return "index";
|
|
263
|
-
const d =
|
|
264
|
-
return m &&
|
|
265
|
-
}, c = (
|
|
266
|
-
const m =
|
|
267
|
-
return m &&
|
|
268
|
-
},
|
|
269
|
-
const m =
|
|
270
|
-
return
|
|
271
|
-
},
|
|
272
|
-
const
|
|
273
|
-
return
|
|
263
|
+
const d = f.split("/").filter(Boolean), m = d[0];
|
|
264
|
+
return m && g.includes(m) && d.shift(), d.length === 0 ? "index" : d.join("-");
|
|
265
|
+
}, c = (o, g = "en", f = []) => {
|
|
266
|
+
const m = o.split("/").filter(Boolean)[0];
|
|
267
|
+
return m && f.includes(m) ? m : g;
|
|
268
|
+
}, u = (o, g, f = [], d) => {
|
|
269
|
+
const m = o.split("/").filter(Boolean), p = m[0];
|
|
270
|
+
return p && f.includes(p) && m.shift(), (g !== d || d === void 0) && m.unshift(g), `/${m.join("/")}`;
|
|
271
|
+
}, n = (o, g, f = [], d) => {
|
|
272
|
+
const p = (o.replace(/^\//, "").replace(/\/$/, "") || "").split("/").filter(Boolean), h = p[0];
|
|
273
|
+
return h && f.includes(h) && p.shift(), (g !== d || d === void 0) && p.unshift(g), `/${p.join("/")}`;
|
|
274
274
|
};
|
|
275
275
|
return {
|
|
276
|
-
getCurrentPath: () =>
|
|
276
|
+
getCurrentPath: () => s ? s().pathname : typeof window < "u" ? window.location.pathname : "/",
|
|
277
277
|
getRouteName: i,
|
|
278
278
|
getLocaleFromPath: c,
|
|
279
|
-
switchLocalePath:
|
|
280
|
-
localizePath:
|
|
281
|
-
removeLocaleFromPath: (
|
|
282
|
-
const
|
|
283
|
-
return d &&
|
|
279
|
+
switchLocalePath: u,
|
|
280
|
+
localizePath: n,
|
|
281
|
+
removeLocaleFromPath: (o, g = []) => {
|
|
282
|
+
const f = o.split("/").filter(Boolean), d = f[0];
|
|
283
|
+
return d && g.includes(d) && f.shift(), `/${f.join("/")}`;
|
|
284
284
|
},
|
|
285
|
-
resolvePath: (
|
|
286
|
-
const
|
|
287
|
-
return
|
|
285
|
+
resolvePath: (o, g) => {
|
|
286
|
+
const f = typeof o == "string" ? o : o.path || "/";
|
|
287
|
+
return n(f, g, a, e);
|
|
288
288
|
},
|
|
289
289
|
getRoute: () => {
|
|
290
|
-
if (
|
|
291
|
-
const
|
|
290
|
+
if (s) {
|
|
291
|
+
const o = s();
|
|
292
292
|
return {
|
|
293
|
-
fullPath:
|
|
294
|
-
query: Object.fromEntries(
|
|
293
|
+
fullPath: o.pathname + o.search,
|
|
294
|
+
query: Object.fromEntries(o.searchParams)
|
|
295
295
|
};
|
|
296
296
|
}
|
|
297
297
|
if (typeof window < "u") {
|
|
298
|
-
const
|
|
298
|
+
const o = new URL(window.location.href);
|
|
299
299
|
return {
|
|
300
|
-
fullPath:
|
|
301
|
-
query: Object.fromEntries(
|
|
300
|
+
fullPath: o.pathname + o.search,
|
|
301
|
+
query: Object.fromEntries(o.searchParams)
|
|
302
302
|
};
|
|
303
303
|
}
|
|
304
304
|
return {
|
|
@@ -307,229 +307,242 @@ function Q(n, e, a) {
|
|
|
307
307
|
};
|
|
308
308
|
},
|
|
309
309
|
// Optional: client-side navigation for islands
|
|
310
|
-
push: (
|
|
311
|
-
typeof window < "u" && (window.location.href =
|
|
310
|
+
push: (o) => {
|
|
311
|
+
typeof window < "u" && (window.location.href = o.path);
|
|
312
312
|
},
|
|
313
|
-
replace: (
|
|
314
|
-
typeof window < "u" && window.location.replace(
|
|
313
|
+
replace: (o) => {
|
|
314
|
+
typeof window < "u" && window.location.replace(o.path);
|
|
315
315
|
}
|
|
316
316
|
};
|
|
317
317
|
}
|
|
318
|
-
function
|
|
319
|
-
const
|
|
320
|
-
if (!
|
|
318
|
+
function Q(t, e = []) {
|
|
319
|
+
const s = t.replace(/^\//, "").replace(/\/$/, "");
|
|
320
|
+
if (!s)
|
|
321
321
|
return "index";
|
|
322
|
-
const
|
|
323
|
-
return i && e.includes(i) &&
|
|
322
|
+
const a = s.split("/").filter(Boolean), i = a[0];
|
|
323
|
+
return i && e.includes(i) && a.shift(), a.length === 0 ? "index" : a.join("-");
|
|
324
324
|
}
|
|
325
|
-
function
|
|
326
|
-
const i =
|
|
327
|
-
return i &&
|
|
325
|
+
function X(t, e = "en", s = []) {
|
|
326
|
+
const i = t.split("/").filter(Boolean)[0];
|
|
327
|
+
return i && s.includes(i) ? i : e;
|
|
328
328
|
}
|
|
329
|
-
function
|
|
330
|
-
const i =
|
|
331
|
-
return c &&
|
|
329
|
+
function Y(t, e, s = [], a) {
|
|
330
|
+
const i = t.split("/").filter(Boolean), c = i[0];
|
|
331
|
+
return c && s.includes(c) && i.shift(), (e !== a || a === void 0) && i.unshift(e), `/${i.join("/")}`;
|
|
332
332
|
}
|
|
333
|
-
function
|
|
334
|
-
const c = (
|
|
335
|
-
return
|
|
333
|
+
function Z(t, e, s = [], a) {
|
|
334
|
+
const c = (t.replace(/^\//, "").replace(/\/$/, "") || "").split("/").filter(Boolean), u = c[0];
|
|
335
|
+
return u && s.includes(u) && c.shift(), (e !== a || a === void 0) && c.unshift(e), `/${c.join("/")}`;
|
|
336
336
|
}
|
|
337
|
-
function ee(
|
|
338
|
-
const
|
|
339
|
-
return
|
|
337
|
+
function ee(t, e = []) {
|
|
338
|
+
const s = t.split("/").filter(Boolean), a = s[0];
|
|
339
|
+
return a && e.includes(a) && s.shift(), `/${s.join("/")}`;
|
|
340
340
|
}
|
|
341
|
-
function
|
|
342
|
-
const e =
|
|
341
|
+
function v(t) {
|
|
342
|
+
const e = t.locals.i18n;
|
|
343
343
|
if (!e)
|
|
344
344
|
throw new Error("i18n instance not found. Make sure i18n middleware is configured.");
|
|
345
345
|
return e;
|
|
346
346
|
}
|
|
347
|
-
function w(
|
|
348
|
-
return
|
|
347
|
+
function w(t) {
|
|
348
|
+
return t.locals.locale || "en";
|
|
349
349
|
}
|
|
350
|
-
function R(
|
|
351
|
-
return
|
|
350
|
+
function R(t) {
|
|
351
|
+
return t.locals.defaultLocale || "en";
|
|
352
352
|
}
|
|
353
|
-
function
|
|
354
|
-
return
|
|
353
|
+
function k(t) {
|
|
354
|
+
return t.locals.locales || [];
|
|
355
355
|
}
|
|
356
|
-
function D(
|
|
357
|
-
return
|
|
356
|
+
function D(t) {
|
|
357
|
+
return t.locals.routingStrategy || null;
|
|
358
358
|
}
|
|
359
|
-
function te(
|
|
360
|
-
const e =
|
|
359
|
+
function te(t) {
|
|
360
|
+
const e = v(t), s = w(t), a = R(t), i = k(t), c = i.map((n) => n.code), u = D(t);
|
|
361
361
|
return {
|
|
362
362
|
// Current locale
|
|
363
|
-
locale:
|
|
364
|
-
defaultLocale:
|
|
363
|
+
locale: s,
|
|
364
|
+
defaultLocale: a,
|
|
365
365
|
locales: i,
|
|
366
366
|
// Translation methods
|
|
367
|
-
t: (
|
|
368
|
-
ts: (
|
|
369
|
-
tc: (
|
|
370
|
-
tn: (
|
|
371
|
-
td: (
|
|
372
|
-
tdr: (
|
|
373
|
-
has: (
|
|
367
|
+
t: (n, l, r, o) => e.t(n, l, r, o),
|
|
368
|
+
ts: (n, l, r, o) => e.ts(n, l, r, o),
|
|
369
|
+
tc: (n, l, r) => e.tc(n, l, r),
|
|
370
|
+
tn: (n, l) => e.tn(n, l),
|
|
371
|
+
td: (n, l) => e.td(n, l),
|
|
372
|
+
tdr: (n, l) => e.tdr(n, l),
|
|
373
|
+
has: (n, l) => e.has(n, l),
|
|
374
374
|
// Route management
|
|
375
375
|
getRoute: () => e.getRoute(),
|
|
376
|
-
getRouteName: (
|
|
377
|
-
const l =
|
|
378
|
-
if (
|
|
379
|
-
return
|
|
376
|
+
getRouteName: (n) => {
|
|
377
|
+
const l = n || t.url.pathname;
|
|
378
|
+
if (u?.getRouteName)
|
|
379
|
+
return u.getRouteName(l, c);
|
|
380
380
|
const r = l.replace(/^\//, "").replace(/\/$/, "");
|
|
381
381
|
if (!r) return "index";
|
|
382
|
-
const
|
|
383
|
-
return
|
|
382
|
+
const o = r.split("/").filter(Boolean), g = o[0];
|
|
383
|
+
return g && c.includes(g) && o.shift(), o.length === 0 ? "index" : o.join("-");
|
|
384
384
|
},
|
|
385
|
-
getLocaleFromPath: (
|
|
386
|
-
const l =
|
|
387
|
-
if (
|
|
388
|
-
return
|
|
389
|
-
const
|
|
390
|
-
return
|
|
385
|
+
getLocaleFromPath: (n) => {
|
|
386
|
+
const l = n || t.url.pathname;
|
|
387
|
+
if (u?.getLocaleFromPath)
|
|
388
|
+
return u.getLocaleFromPath(l, a, c);
|
|
389
|
+
const o = l.split("/").filter(Boolean)[0];
|
|
390
|
+
return o && c.includes(o) ? o : a;
|
|
391
391
|
},
|
|
392
392
|
// Path utilities
|
|
393
|
-
switchLocalePath: (
|
|
394
|
-
if (
|
|
395
|
-
return
|
|
396
|
-
const l =
|
|
397
|
-
return r && c.includes(r) && l.shift(),
|
|
393
|
+
switchLocalePath: (n) => {
|
|
394
|
+
if (u?.switchLocalePath)
|
|
395
|
+
return u.switchLocalePath(t.url.pathname, n, c, a);
|
|
396
|
+
const l = t.url.pathname.split("/").filter(Boolean), r = l[0];
|
|
397
|
+
return r && c.includes(r) && l.shift(), n !== a && l.unshift(n), `/${l.join("/")}`;
|
|
398
398
|
},
|
|
399
|
-
localizePath: (
|
|
400
|
-
if (
|
|
401
|
-
return
|
|
402
|
-
const
|
|
403
|
-
return
|
|
399
|
+
localizePath: (n, l) => {
|
|
400
|
+
if (u?.localizePath)
|
|
401
|
+
return u.localizePath(n, l || s, c, a);
|
|
402
|
+
const o = (n.replace(/^\//, "").replace(/\/$/, "") || "").split("/").filter(Boolean), g = o[0];
|
|
403
|
+
return g && c.includes(g) && o.shift(), l && l !== a && o.unshift(l), `/${o.join("/")}`;
|
|
404
404
|
},
|
|
405
405
|
// Get i18n instance
|
|
406
406
|
getI18n: () => e,
|
|
407
407
|
// Get base path without locale (for rewrite)
|
|
408
|
-
getBasePath: (
|
|
409
|
-
const
|
|
410
|
-
return
|
|
408
|
+
getBasePath: (n) => {
|
|
409
|
+
const o = (n || t.url).pathname.split("/").filter(Boolean), g = o[0];
|
|
410
|
+
return g && c.includes(g) && o.shift(), o.length > 0 ? `/${o.join("/")}` : "/";
|
|
411
411
|
},
|
|
412
412
|
// Translation management
|
|
413
|
-
addTranslations: (
|
|
414
|
-
e.addTranslations(
|
|
413
|
+
addTranslations: (n, l, r = !0) => {
|
|
414
|
+
e.addTranslations(n, l, r);
|
|
415
415
|
},
|
|
416
|
-
addRouteTranslations: (
|
|
417
|
-
e.addRouteTranslations(
|
|
416
|
+
addRouteTranslations: (n, l, r, o = !0) => {
|
|
417
|
+
e.addRouteTranslations(n, l, r, o);
|
|
418
418
|
},
|
|
419
|
-
mergeTranslations: (
|
|
420
|
-
e.mergeTranslations(
|
|
419
|
+
mergeTranslations: (n, l, r) => {
|
|
420
|
+
e.mergeTranslations(n, l, r);
|
|
421
421
|
},
|
|
422
422
|
clearCache: () => {
|
|
423
423
|
e.clearCache();
|
|
424
424
|
}
|
|
425
425
|
};
|
|
426
426
|
}
|
|
427
|
-
function ne(
|
|
428
|
-
const { baseUrl:
|
|
429
|
-
if (!
|
|
427
|
+
function ne(t, e = {}) {
|
|
428
|
+
const { baseUrl: s = "/", addDirAttribute: a = !0, addSeoAttributes: i = !0 } = e, c = w(t), u = R(t), l = k(t).filter((h) => !h.disabled), r = l.find((h) => h.code === c);
|
|
429
|
+
if (!r)
|
|
430
430
|
return { htmlAttrs: {}, link: [], meta: [] };
|
|
431
|
-
const
|
|
431
|
+
const o = r.iso || c, g = r.dir || "auto", f = {
|
|
432
432
|
htmlAttrs: {
|
|
433
|
-
lang:
|
|
434
|
-
...
|
|
433
|
+
lang: o,
|
|
434
|
+
...a ? { dir: g } : {}
|
|
435
435
|
},
|
|
436
436
|
link: [],
|
|
437
437
|
meta: []
|
|
438
438
|
};
|
|
439
439
|
if (!i)
|
|
440
|
-
return
|
|
441
|
-
const
|
|
442
|
-
|
|
440
|
+
return f;
|
|
441
|
+
const d = `${s}${t.url.pathname}`;
|
|
442
|
+
f.link.push({
|
|
443
443
|
rel: "canonical",
|
|
444
|
-
href:
|
|
444
|
+
href: d
|
|
445
445
|
});
|
|
446
|
-
const
|
|
447
|
-
for (const
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
p = d.switchLocalePath(n.url.pathname, g.code, m, f);
|
|
446
|
+
const m = D(t), p = l.map((h) => h.code);
|
|
447
|
+
for (const h of l) {
|
|
448
|
+
let P = t.url.pathname;
|
|
449
|
+
if (m?.switchLocalePath)
|
|
450
|
+
P = m.switchLocalePath(t.url.pathname, h.code, p, u);
|
|
452
451
|
else {
|
|
453
|
-
const
|
|
454
|
-
|
|
452
|
+
const y = t.url.pathname.split("/").filter(Boolean), b = y[0];
|
|
453
|
+
b && p.includes(b) && y.shift(), h.code !== u && y.unshift(h.code), P = `/${y.join("/")}`;
|
|
455
454
|
}
|
|
456
|
-
const
|
|
457
|
-
|
|
455
|
+
const L = `${s}${P}`;
|
|
456
|
+
f.link.push({
|
|
458
457
|
rel: "alternate",
|
|
459
|
-
href:
|
|
460
|
-
hreflang:
|
|
461
|
-
}),
|
|
458
|
+
href: L,
|
|
459
|
+
hreflang: h.code
|
|
460
|
+
}), h.iso && h.iso !== h.code && f.link.push({
|
|
462
461
|
rel: "alternate",
|
|
463
|
-
href:
|
|
464
|
-
hreflang:
|
|
462
|
+
href: L,
|
|
463
|
+
hreflang: h.iso
|
|
465
464
|
});
|
|
466
465
|
}
|
|
467
|
-
|
|
466
|
+
{
|
|
467
|
+
let h = t.url.pathname;
|
|
468
|
+
if (m?.switchLocalePath)
|
|
469
|
+
h = m.switchLocalePath(t.url.pathname, u, p, u);
|
|
470
|
+
else {
|
|
471
|
+
const P = t.url.pathname.split("/").filter(Boolean), L = P[0];
|
|
472
|
+
L && p.includes(L) && P.shift(), h = `/${P.join("/")}`;
|
|
473
|
+
}
|
|
474
|
+
f.link.push({
|
|
475
|
+
rel: "alternate",
|
|
476
|
+
href: `${s}${h}`,
|
|
477
|
+
hreflang: "x-default"
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
f.meta.push({
|
|
468
481
|
property: "og:locale",
|
|
469
|
-
content:
|
|
470
|
-
}),
|
|
482
|
+
content: o
|
|
483
|
+
}), f.meta.push({
|
|
471
484
|
property: "og:url",
|
|
472
|
-
content:
|
|
485
|
+
content: d
|
|
473
486
|
});
|
|
474
|
-
for (const
|
|
475
|
-
|
|
487
|
+
for (const h of l)
|
|
488
|
+
h.code !== c && f.meta.push({
|
|
476
489
|
property: "og:locale:alternate",
|
|
477
|
-
content:
|
|
490
|
+
content: h.iso || h.code
|
|
478
491
|
});
|
|
479
|
-
return
|
|
492
|
+
return f;
|
|
480
493
|
}
|
|
481
|
-
function A(
|
|
482
|
-
const
|
|
483
|
-
let i =
|
|
484
|
-
for (let
|
|
485
|
-
const
|
|
486
|
-
i[
|
|
494
|
+
function A(t, e, s) {
|
|
495
|
+
const a = e.split(".");
|
|
496
|
+
let i = t;
|
|
497
|
+
for (let u = 0; u < a.length - 1; u++) {
|
|
498
|
+
const n = a[u];
|
|
499
|
+
i[n] || (i[n] = {}), i = i[n];
|
|
487
500
|
}
|
|
488
|
-
const c =
|
|
489
|
-
c !== void 0 && (i[c] =
|
|
501
|
+
const c = a[a.length - 1];
|
|
502
|
+
c !== void 0 && (i[c] = s);
|
|
490
503
|
}
|
|
491
|
-
function oe(
|
|
492
|
-
const
|
|
504
|
+
function oe(t, e) {
|
|
505
|
+
const s = v(t), a = w(t), i = R(t), c = s.getRoute(), u = {};
|
|
493
506
|
if (e && e.length > 0) {
|
|
494
|
-
const
|
|
507
|
+
const n = {};
|
|
495
508
|
for (const l of e) {
|
|
496
|
-
const r =
|
|
497
|
-
r != null && r !== l && A(
|
|
509
|
+
const r = s.t(l, void 0, void 0, c);
|
|
510
|
+
r != null && r !== l && A(n, l, r);
|
|
498
511
|
}
|
|
499
|
-
Object.keys(
|
|
512
|
+
Object.keys(n).length > 0 && (u[c] = n);
|
|
500
513
|
} else {
|
|
501
|
-
const
|
|
502
|
-
|
|
514
|
+
const n = s.getRouteTranslations(a, c);
|
|
515
|
+
n && (u[c] = n);
|
|
503
516
|
}
|
|
504
517
|
return {
|
|
505
|
-
locale:
|
|
518
|
+
locale: a,
|
|
506
519
|
fallbackLocale: i,
|
|
507
520
|
currentRoute: c,
|
|
508
|
-
translations:
|
|
521
|
+
translations: u
|
|
509
522
|
};
|
|
510
523
|
}
|
|
511
524
|
export {
|
|
512
525
|
S as AstroI18n,
|
|
513
526
|
le as FormatService,
|
|
514
|
-
|
|
527
|
+
x as createAstroRouterAdapter,
|
|
515
528
|
J as createI18n,
|
|
516
529
|
G as createI18nMiddleware,
|
|
517
530
|
re as defaultPlural,
|
|
518
531
|
K as detectLocale,
|
|
519
532
|
R as getDefaultLocale,
|
|
520
|
-
|
|
533
|
+
v as getI18n,
|
|
521
534
|
oe as getI18nProps,
|
|
522
535
|
w as getLocale,
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
536
|
+
X as getLocaleFromPath,
|
|
537
|
+
k as getLocales,
|
|
538
|
+
Q as getRouteName,
|
|
526
539
|
E as i18nIntegration,
|
|
527
540
|
ie as interpolate,
|
|
528
541
|
M as loadTranslationsFromDir,
|
|
529
542
|
V as loadTranslationsIntoI18n,
|
|
530
|
-
|
|
543
|
+
Z as localizePath,
|
|
531
544
|
ee as removeLocaleFromPath,
|
|
532
|
-
|
|
545
|
+
Y as switchLocalePath,
|
|
533
546
|
te as useI18n,
|
|
534
547
|
ne as useLocaleHead
|
|
535
548
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@i18n-micro/astro",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@i18n-micro/core": "1.2.0",
|
|
55
|
-
"@i18n-micro/
|
|
56
|
-
"@i18n-micro/
|
|
55
|
+
"@i18n-micro/node": "1.2.0",
|
|
56
|
+
"@i18n-micro/types": "1.1.6"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"astro": "^5.16.5",
|
package/src/utils.ts
CHANGED
|
@@ -215,7 +215,8 @@ export function useLocaleHead(astro: AstroGlobal, options: LocaleHeadOptions = {
|
|
|
215
215
|
|
|
216
216
|
const locale = getLocale(astro)
|
|
217
217
|
const defaultLocale = getDefaultLocale(astro)
|
|
218
|
-
const
|
|
218
|
+
const allLocales = getLocales(astro)
|
|
219
|
+
const locales = allLocales.filter((l) => !l.disabled)
|
|
219
220
|
const currentLocaleObj = locales.find((l) => l.code === locale)
|
|
220
221
|
|
|
221
222
|
if (!currentLocaleObj) {
|
|
@@ -238,7 +239,7 @@ export function useLocaleHead(astro: AstroGlobal, options: LocaleHeadOptions = {
|
|
|
238
239
|
return result
|
|
239
240
|
}
|
|
240
241
|
|
|
241
|
-
// Canonical URL
|
|
242
|
+
// Canonical URL (uses pathname only — query params are excluded)
|
|
242
243
|
const canonicalUrl = `${baseUrl}${astro.url.pathname}`
|
|
243
244
|
result.link.push({
|
|
244
245
|
rel: 'canonical',
|
|
@@ -249,10 +250,8 @@ export function useLocaleHead(astro: AstroGlobal, options: LocaleHeadOptions = {
|
|
|
249
250
|
const routingStrategy = getRoutingStrategy(astro)
|
|
250
251
|
const allLocaleCodes = locales.map((l) => l.code)
|
|
251
252
|
|
|
252
|
-
// Alternate languages
|
|
253
|
+
// Alternate languages (includes current locale for self-referencing hreflang, per Google guidelines)
|
|
253
254
|
for (const loc of locales) {
|
|
254
|
-
if (loc.code === locale) continue
|
|
255
|
-
|
|
256
255
|
let alternatePath = astro.url.pathname
|
|
257
256
|
if (routingStrategy?.switchLocalePath) {
|
|
258
257
|
alternatePath = routingStrategy.switchLocalePath(astro.url.pathname, loc.code, allLocaleCodes, defaultLocale)
|
|
@@ -285,6 +284,28 @@ export function useLocaleHead(astro: AstroGlobal, options: LocaleHeadOptions = {
|
|
|
285
284
|
}
|
|
286
285
|
}
|
|
287
286
|
|
|
287
|
+
// x-default hreflang — points to the default locale's URL.
|
|
288
|
+
// Tells search engines which URL to show when none of the
|
|
289
|
+
// specified languages match the user's browser settings.
|
|
290
|
+
{
|
|
291
|
+
let xDefaultPath = astro.url.pathname
|
|
292
|
+
if (routingStrategy?.switchLocalePath) {
|
|
293
|
+
xDefaultPath = routingStrategy.switchLocalePath(astro.url.pathname, defaultLocale, allLocaleCodes, defaultLocale)
|
|
294
|
+
} else {
|
|
295
|
+
const segments = astro.url.pathname.split('/').filter(Boolean)
|
|
296
|
+
const firstSegment = segments[0]
|
|
297
|
+
if (firstSegment && allLocaleCodes.includes(firstSegment)) {
|
|
298
|
+
segments.shift()
|
|
299
|
+
}
|
|
300
|
+
xDefaultPath = `/${segments.join('/')}`
|
|
301
|
+
}
|
|
302
|
+
result.link.push({
|
|
303
|
+
rel: 'alternate',
|
|
304
|
+
href: `${baseUrl}${xDefaultPath}`,
|
|
305
|
+
hreflang: 'x-default',
|
|
306
|
+
})
|
|
307
|
+
}
|
|
308
|
+
|
|
288
309
|
// Open Graph locale
|
|
289
310
|
result.meta.push({
|
|
290
311
|
property: 'og:locale',
|