@i18n-micro/astro 1.3.0 → 1.3.2
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/core.d.ts +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/preact.js +1 -1
- package/dist/client/react.js +1 -1
- package/dist/client/svelte.js +1 -1
- package/dist/client/vue.js +1 -1
- package/dist/core-B-Ia_nzr.cjs +1 -0
- package/dist/core-Bk6qZuDf.js +37 -0
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +279 -266
- package/package.json +2 -2
- package/src/client/core.ts +2 -22
- package/src/load-translations.ts +0 -1
- package/src/utils.ts +26 -5
- package/dist/core-Bx9n-eFD.cjs +0 -1
- package/dist/core-D32Y48CN.js +0 -42
package/dist/client/core.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export interface I18nState {
|
|
|
12
12
|
* Pure function to get a translation from state
|
|
13
13
|
*
|
|
14
14
|
* Note: This is a simplified version optimized for client-side islands.
|
|
15
|
-
* It supports basic translation lookup
|
|
15
|
+
* It supports basic translation lookup and interpolation.
|
|
16
16
|
* Returns CleanTranslation which can be string, number, boolean, object, or null.
|
|
17
17
|
* For advanced features like Linked Messages (@:path.to.key), use the server-side i18n instance.
|
|
18
18
|
*/
|
package/dist/client/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { h as s, t as o } from "../core-
|
|
1
|
+
import { h as s, t as o } from "../core-Bk6qZuDf.js";
|
|
2
2
|
import { I18nProvider as a, useAstroI18n as n } from "./preact.js";
|
|
3
3
|
import { I18nProvider as u, useAstroI18n as A } from "./react.js";
|
|
4
4
|
import { createI18nStore as f, useAstroI18n as i } from "./svelte.js";
|
package/dist/client/preact.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FormatService as g, defaultPlural as w } from "@i18n-micro/core";
|
|
2
2
|
import { createContext as x, createElement as L } from "preact";
|
|
3
3
|
import { useState as P, useContext as S, useMemo as a } from "preact/hooks";
|
|
4
|
-
import { t as C, h as A } from "../core-
|
|
4
|
+
import { t as C, h as A } from "../core-Bk6qZuDf.js";
|
|
5
5
|
const s = new g(), i = x(null), F = ({ children: t, value: o }) => {
|
|
6
6
|
const [l] = P(() => ({
|
|
7
7
|
locale: o.locale,
|
package/dist/client/react.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FormatService as g, defaultPlural as w } from "@i18n-micro/core";
|
|
2
2
|
import x, { createContext as L, useState as P, useContext as S, useMemo as a } from "react";
|
|
3
|
-
import { t as C, h as A } from "../core-
|
|
3
|
+
import { t as C, h as A } from "../core-Bk6qZuDf.js";
|
|
4
4
|
const s = new g(), i = L(null);
|
|
5
5
|
function D({ children: t, value: o }) {
|
|
6
6
|
const [l] = P(() => ({
|
package/dist/client/svelte.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FormatService as R, defaultPlural as b } from "@i18n-micro/core";
|
|
2
2
|
import { writable as d, get as v } from "svelte/store";
|
|
3
|
-
import { h as L, t as S } from "../core-
|
|
3
|
+
import { h as L, t as S } from "../core-Bk6qZuDf.js";
|
|
4
4
|
const l = new R();
|
|
5
5
|
function F(o) {
|
|
6
6
|
return d({
|
package/dist/client/vue.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FormatService as wt, defaultPlural as yt } from "@i18n-micro/core";
|
|
2
|
-
import { h as St, t as Ot } from "../core-
|
|
2
|
+
import { h as St, t as Ot } from "../core-Bk6qZuDf.js";
|
|
3
3
|
// @__NO_SIDE_EFFECTS__
|
|
4
4
|
function Rt(e) {
|
|
5
5
|
const t = /* @__PURE__ */ Object.create(null);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const s=require("@i18n-micro/core");function l(r,t){if(r===null||typeof t!="string")return null;let n=r;if(r[t])n=r[t];else{const o=t.toString().split(".");for(const u of o)if(n&&typeof n=="object"&&n!==null&&u in n)n=n[u];else return null}return n??null}function f(r,t,n,o,u){if(!t)return o||t||"";const i=u||r.currentRoute;let e=null;return r.translations[i]&&(e=l(r.translations[i],t)),e||(e=o===void 0?t:o||t),typeof e=="string"&&n?s.interpolate(e,n):e}function c(r,t,n){const o=n||r.currentRoute,u=r.translations[o];if(u){const i=l(u,t);if(i!==null&&typeof i!="object")return!0}return!1}exports.hasTranslation=c;exports.translate=f;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { interpolate as f } from "@i18n-micro/core";
|
|
2
|
+
function e(r, t) {
|
|
3
|
+
if (r === null || typeof t != "string")
|
|
4
|
+
return null;
|
|
5
|
+
let n = r;
|
|
6
|
+
if (r[t])
|
|
7
|
+
n = r[t];
|
|
8
|
+
else {
|
|
9
|
+
const o = t.toString().split(".");
|
|
10
|
+
for (const u of o)
|
|
11
|
+
if (n && typeof n == "object" && n !== null && u in n)
|
|
12
|
+
n = n[u];
|
|
13
|
+
else
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return n ?? null;
|
|
17
|
+
}
|
|
18
|
+
function c(r, t, n, o, u) {
|
|
19
|
+
if (!t)
|
|
20
|
+
return o || t || "";
|
|
21
|
+
const l = u || r.currentRoute;
|
|
22
|
+
let i = null;
|
|
23
|
+
return r.translations[l] && (i = e(r.translations[l], t)), i || (i = o === void 0 ? t : o || t), typeof i == "string" && n ? f(i, n) : i;
|
|
24
|
+
}
|
|
25
|
+
function a(r, t, n) {
|
|
26
|
+
const o = n || r.currentRoute, u = r.translations[o];
|
|
27
|
+
if (u) {
|
|
28
|
+
const l = e(u, t);
|
|
29
|
+
if (l !== null && typeof l != "object")
|
|
30
|
+
return !0;
|
|
31
|
+
}
|
|
32
|
+
return !1;
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
a as h,
|
|
36
|
+
c as t
|
|
37
|
+
};
|
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.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@i18n-micro/core": "1.2.0",
|
|
55
|
-
"@i18n-micro/types": "1.1.
|
|
55
|
+
"@i18n-micro/types": "1.1.6",
|
|
56
56
|
"@i18n-micro/node": "1.2.0"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
package/src/client/core.ts
CHANGED
|
@@ -44,7 +44,7 @@ function findTranslation<T = unknown>(translations: Translations | null, key: st
|
|
|
44
44
|
* Pure function to get a translation from state
|
|
45
45
|
*
|
|
46
46
|
* Note: This is a simplified version optimized for client-side islands.
|
|
47
|
-
* It supports basic translation lookup
|
|
47
|
+
* It supports basic translation lookup and interpolation.
|
|
48
48
|
* Returns CleanTranslation which can be string, number, boolean, object, or null.
|
|
49
49
|
* For advanced features like Linked Messages (@:path.to.key), use the server-side i18n instance.
|
|
50
50
|
*/
|
|
@@ -62,28 +62,18 @@ export function translate(
|
|
|
62
62
|
const route = routeName || state.currentRoute
|
|
63
63
|
let value: string | number | boolean | Translations | null = null
|
|
64
64
|
|
|
65
|
-
// 1. Look in route-specific translations
|
|
66
65
|
if (state.translations[route]) {
|
|
67
66
|
value = findTranslation<string | number | boolean | Translations>(state.translations[route], key)
|
|
68
67
|
}
|
|
69
68
|
|
|
70
|
-
//
|
|
71
|
-
if (!value && state.translations.general) {
|
|
72
|
-
value = findTranslation<string | number | boolean | Translations>(state.translations.general, key)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// 3. If not found, use defaultValue or key
|
|
69
|
+
// If not found, use defaultValue or key
|
|
76
70
|
if (!value) {
|
|
77
71
|
value = defaultValue === undefined ? key : defaultValue || key
|
|
78
72
|
}
|
|
79
73
|
|
|
80
|
-
// 4. Parameter interpolation (strings only)
|
|
81
74
|
if (typeof value === 'string' && params) {
|
|
82
75
|
return interpolate(value, params)
|
|
83
76
|
}
|
|
84
|
-
|
|
85
|
-
// 5. Return value as-is (can be string, number, boolean, object, or null)
|
|
86
|
-
// This matches the CleanTranslation type
|
|
87
77
|
return value
|
|
88
78
|
}
|
|
89
79
|
|
|
@@ -93,9 +83,7 @@ export function translate(
|
|
|
93
83
|
export function hasTranslation(state: I18nState, key: string, routeName?: string): boolean {
|
|
94
84
|
const route = routeName || state.currentRoute
|
|
95
85
|
const routeTranslations = state.translations[route]
|
|
96
|
-
const generalTranslations = state.translations.general
|
|
97
86
|
|
|
98
|
-
// Check in route-specific translations
|
|
99
87
|
if (routeTranslations) {
|
|
100
88
|
const value = findTranslation(routeTranslations, key)
|
|
101
89
|
if (value !== null && typeof value !== 'object') {
|
|
@@ -103,13 +91,5 @@ export function hasTranslation(state: I18nState, key: string, routeName?: string
|
|
|
103
91
|
}
|
|
104
92
|
}
|
|
105
93
|
|
|
106
|
-
// Check in general translations
|
|
107
|
-
if (generalTranslations) {
|
|
108
|
-
const value = findTranslation(generalTranslations, key)
|
|
109
|
-
if (value !== null && typeof value !== 'object') {
|
|
110
|
-
return true
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
94
|
return false
|
|
115
95
|
}
|
package/src/load-translations.ts
CHANGED
|
@@ -65,7 +65,6 @@ export function loadTranslationsFromDir(options: LoadTranslationsOptions): Loade
|
|
|
65
65
|
if (entry === 'pages' && !disablePageLocales) {
|
|
66
66
|
loadFiles(fullPath, '')
|
|
67
67
|
} else if (routePrefix || disablePageLocales) {
|
|
68
|
-
// Continue in general translations
|
|
69
68
|
loadFiles(fullPath, routePrefix)
|
|
70
69
|
} else {
|
|
71
70
|
// This is a route directory (e.g., pages/home/)
|
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',
|
package/dist/core-Bx9n-eFD.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const s=require("@i18n-micro/core");function u(n,t){if(n===null||typeof t!="string")return null;let o=n;if(n[t])o=n[t];else{const l=t.toString().split(".");for(const e of l)if(o&&typeof o=="object"&&o!==null&&e in o)o=o[e];else return null}return o??null}function a(n,t,o,l,e){if(!t)return l||t||"";const i=e||n.currentRoute;let r=null;return n.translations[i]&&(r=u(n.translations[i],t)),!r&&n.translations.general&&(r=u(n.translations.general,t)),r||(r=l===void 0?t:l||t),typeof r=="string"&&o?s.interpolate(r,o):r}function f(n,t,o){const l=o||n.currentRoute,e=n.translations[l],i=n.translations.general;if(e){const r=u(e,t);if(r!==null&&typeof r!="object")return!0}if(i){const r=u(i,t);if(r!==null&&typeof r!="object")return!0}return!1}exports.hasTranslation=f;exports.translate=a;
|
package/dist/core-D32Y48CN.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { interpolate as s } from "@i18n-micro/core";
|
|
2
|
-
function u(n, t) {
|
|
3
|
-
if (n === null || typeof t != "string")
|
|
4
|
-
return null;
|
|
5
|
-
let o = n;
|
|
6
|
-
if (n[t])
|
|
7
|
-
o = n[t];
|
|
8
|
-
else {
|
|
9
|
-
const l = t.toString().split(".");
|
|
10
|
-
for (const i of l)
|
|
11
|
-
if (o && typeof o == "object" && o !== null && i in o)
|
|
12
|
-
o = o[i];
|
|
13
|
-
else
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
return o ?? null;
|
|
17
|
-
}
|
|
18
|
-
function a(n, t, o, l, i) {
|
|
19
|
-
if (!t)
|
|
20
|
-
return l || t || "";
|
|
21
|
-
const e = i || n.currentRoute;
|
|
22
|
-
let r = null;
|
|
23
|
-
return n.translations[e] && (r = u(n.translations[e], t)), !r && n.translations.general && (r = u(n.translations.general, t)), r || (r = l === void 0 ? t : l || t), typeof r == "string" && o ? s(r, o) : r;
|
|
24
|
-
}
|
|
25
|
-
function c(n, t, o) {
|
|
26
|
-
const l = o || n.currentRoute, i = n.translations[l], e = n.translations.general;
|
|
27
|
-
if (i) {
|
|
28
|
-
const r = u(i, t);
|
|
29
|
-
if (r !== null && typeof r != "object")
|
|
30
|
-
return !0;
|
|
31
|
-
}
|
|
32
|
-
if (e) {
|
|
33
|
-
const r = u(e, t);
|
|
34
|
-
if (r !== null && typeof r != "object")
|
|
35
|
-
return !0;
|
|
36
|
-
}
|
|
37
|
-
return !1;
|
|
38
|
-
}
|
|
39
|
-
export {
|
|
40
|
-
c as h,
|
|
41
|
-
a as t
|
|
42
|
-
};
|