@i18n-micro/astro 1.3.5 → 1.3.7
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.d.cts +3 -4
- package/dist/index.d.ts +3 -4
- package/dist/index.mjs +292 -287
- package/package.json +42 -42
- package/src/index.ts +3 -31
- package/src/utils.ts +16 -5
- package/dist/routing.d.ts +0 -23
- package/src/routing.ts +0 -94
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 R=require("@i18n-micro/core"),w=require("node:fs"),T=require("node:path"),C=require("@i18n-micro/utils/parse-path"),W=require("@i18n-micro/utils/accept-language");class j extends R.BaseI18n{constructor(e){const a=e._storage||{translations:new Map};if(super({storage:a,plural:e.plural,missingWarn:e.missingWarn,missingHandler:e.missingHandler}),this.initialMessages={},this.storage=a,this._locale=e.locale,this._fallbackLocale=e.fallbackLocale||e.locale,this._currentRoute="index",e.messages){this.initialMessages={...e.messages};for(const[r,i]of Object.entries(e.messages))this.helper.loadTranslations(r,i)}}cloneStorage(e){const a=new Map;for(const[r,i]of e.translations)a.set(r,{...i});return{translations:a}}clone(e){const a=this.cloneStorage(this.storage);return new j({locale:e||this._locale,fallbackLocale:this._fallbackLocale,plural:this.pluralFunc,missingWarn:this.missingWarn,missingHandler:this.missingHandler,_storage:a})}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,a){const r=`${e}:${a}`;return this.storage.translations.get(r)??null}addTranslations(e,a,r=!0){super.loadTranslationsCore(e,a,r)}addRouteTranslations(e,a,r,i=!0){super.loadRouteTranslationsCore(e,a,r,i)}mergeTranslations(e,a,r){this.helper.mergeTranslation(e,a,r,!0)}clearCache(){const e={...this.initialMessages};if(super.clearCache(),Object.keys(e).length>0)for(const[a,r]of Object.entries(e))this.helper.loadTranslations(a,r)}}let B=null;function N(){return B}function U(t){const{locale:e,fallbackLocale:a,translationDir:r,routingStrategy:i}=t;return B=i||null,{name:"@i18n-micro/astro",hooks:{"astro:config:setup":c=>{const{updateConfig:u}=c,o="virtual:i18n-micro/config",l=`\0${o}`,s={defaultLocale:e,fallbackLocale:a||e,locales:t.locales||[],localeCodes:(t.locales||[]).map(n=>n.code),translationDir:r||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(n){if(n===o)return l},load(n){if(n===l)return`export const config = ${JSON.stringify(s)}`}}]}})},"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
|
|
17
|
+
`})}}}}function H(t){return new j(t)}function A(t,e){if(w.existsSync(t))for(const a of w.readdirSync(t)){const r=T.join(t,a);if(w.statSync(r).isDirectory()){A(r,e);continue}a.endsWith(".json")&&e(r)}}function M(t){const{translationDir:e,rootDir:a=process.cwd(),disablePageLocales:r=!1}=t,i=T.resolve(a,e);if(!w.existsSync(i))return console.warn(`[i18n] Translation directory not found: ${i}`),{root:{},routes:{}};const c={root:{},routes:{}};return A(i,u=>{const o=T.relative(i,u).split(T.sep).join("/");try{const l=w.readFileSync(u,"utf-8"),s=JSON.parse(l);C.storeLoadedTranslationFile(c,o,s,r)}catch(l){console.error(`[i18n] Failed to load translation file: ${u}`,l)}}),c}function E(t,e){const{root:a,routes:r}=M(e);for(const[i,c]of Object.entries(a))t.addTranslations(i,c,!1);for(const[i,c]of Object.entries(r))for(const[u,o]of Object.entries(c))t.addRouteTranslations(u,i,C.mergeRouteTranslationsWithRoot(a[u],o),!1)}function z(t){const{i18n:e,defaultLocale:a,locales:r,localeObjects:i,autoDetect:c=!0,redirectToDefault:u=!1,routingStrategy:o}=t,l=o||N();return async(s,n)=>{if(s.locals.locale&&s.locals.i18n)return n();const f=s.url,d=f.pathname;if(!l){const L=e.clone(a),y=d==="/"||d===""?"index":d.split("/").filter(Boolean).join("-");return L.setRoute(y),s.locals.i18n=L,s.locals.locale=a,s.locals.defaultLocale=a,s.locals.locales=i||r.map(S=>({code:S})),s.locals.currentUrl=f,n()}const m={...l,getCurrentPath:()=>d,getRoute:()=>({fullPath:f.pathname+f.search,query:Object.fromEntries(f.searchParams)})},p=d.split("/").filter(Boolean)[0],b=p!==void 0&&r.includes(p);let P;b&&p?P=p:m.getLocaleFromPath?P=m.getLocaleFromPath(d,a,r):P=a;const k=e.clone(P),g=m.getRouteName?m.getRouteName(d,r):"index";return k.setRoute(g),s.locals.i18n=k,s.locals.locale=P,s.locals.defaultLocale=a,s.locals.locales=i||r.map(L=>({code:L})),s.locals.currentUrl=f,s.locals.routingStrategy=m,n()}}function x(t,e,a,r,i,c="i18n-locale"){const u=N();let o=r;if(u?.getLocaleFromPath)o=u.getLocaleFromPath(t,r,i);else{const s=t.split("/").filter(Boolean)[0];s&&i.includes(s)&&(o=s)}if(c!==null&&o===r&&e.get(c)){const l=e.get(c)?.value;l&&i.includes(l)&&(o=l)}if(o===r)try{const l=W.detectLocaleFromAcceptLanguage(a.get("accept-language")??void 0,i);l&&(o=l)}catch{}return o}function V(t,e,a){const r=t.map(n=>n.code),i=(n,f=[])=>{const d=n.replace(/^\//,"").replace(/\/$/,"");if(!d)return"index";const m=d.split("/").filter(Boolean),h=m[0];return h&&f.includes(h)&&m.shift(),m.length===0?"index":m.join("-")},c=(n,f="en",d=[])=>{const h=n.split("/").filter(Boolean)[0];return h&&d.includes(h)?h:f},u=(n,f,d=[],m)=>{const h=n.split("/").filter(Boolean),p=h[0];return p&&d.includes(p)&&h.shift(),(f!==m||m===void 0)&&h.unshift(f),`/${h.join("/")}`},o=(n,f,d=[],m)=>{const p=(n.replace(/^\//,"").replace(/\/$/,"")||"").split("/").filter(Boolean),b=p[0];return b&&d.includes(b)&&p.shift(),(f!==m||m===void 0)&&p.unshift(f),`/${p.join("/")}`};return{getCurrentPath:()=>a?a().pathname:typeof window<"u"?window.location.pathname:"/",getRouteName:i,getLocaleFromPath:c,switchLocalePath:u,localizePath:o,removeLocaleFromPath:(n,f=[])=>{const d=n.split("/").filter(Boolean),m=d[0];return m&&f.includes(m)&&d.shift(),`/${d.join("/")}`},resolvePath:(n,f)=>{const d=typeof n=="string"?n:n.path||"/";return o(d,f,r,e)},getRoute:()=>{if(a){const n=a();return{fullPath:n.pathname+n.search,query:Object.fromEntries(n.searchParams)}}if(typeof window<"u"){const n=new URL(window.location.href);return{fullPath:n.pathname+n.search,query:Object.fromEntries(n.searchParams)}}return{fullPath:"/",query:{}}},push:n=>{typeof window<"u"&&(window.location.href=n.path)},replace:n=>{typeof window<"u"&&window.location.replace(n.path)}}}function D(t){const e=t.og?.trim();if(e)return e;const a=t.iso?.trim();if(!a)return null;const r=a.indexOf("_");if(r>0){const c=a.slice(0,r),u=a.slice(r+1);if(c.length>=2&&u.length===2)return`${c.toLowerCase()}_${u.toUpperCase()}`}const i=a.indexOf("-");if(i>0){const c=a.slice(0,i),u=a.slice(i+1);if(c.length>=2&&u.length===2&&/^[A-Za-z]{2}$/.test(u))return`${c.toLowerCase()}_${u.toUpperCase()}`}return null}function F(t,e={}){if(D(t)!==null||e.missingWarn===!1||process.env.NODE_ENV==="production")return;const a=e.tag??"og:locale",r=String(t.code??"unknown"),i=t.iso?`, iso: '${t.iso}'`:"";console.warn(`[i18n] Cannot derive ${a} for locale '${r}'${i}. Set locale.og (e.g. 'en_US') or use iso with a 2-letter region (e.g. 'en-US').`)}function I(t){const e=t.locals.i18n;if(!e)throw new Error("i18n instance not found. Make sure i18n middleware is configured.");return e}function $(t){return t.locals.locale||"en"}function v(t){return t.locals.defaultLocale||"en"}function O(t){return t.locals.locales||[]}function q(t){return t.locals.routingStrategy||null}function J(t){const e=I(t),a=$(t),r=v(t),i=O(t),c=i.map(o=>o.code),u=q(t);return{locale:a,defaultLocale:r,locales:i,t:(o,l,s,n)=>e.t(o,l,s,n),ts:(o,l,s,n)=>e.ts(o,l,s,n),tc:(o,l,s)=>e.tc(o,l,s),tn:(o,l)=>e.tn(o,l),td:(o,l)=>e.td(o,l),tdr:(o,l)=>e.tdr(o,l),has:(o,l)=>e.has(o,l),getRoute:()=>e.getRoute(),getRouteName:o=>{const l=o||t.url.pathname;if(u?.getRouteName)return u.getRouteName(l,c);const s=l.replace(/^\//,"").replace(/\/$/,"");if(!s)return"index";const n=s.split("/").filter(Boolean),f=n[0];return f&&c.includes(f)&&n.shift(),n.length===0?"index":n.join("-")},getLocaleFromPath:o=>{const l=o||t.url.pathname;if(u?.getLocaleFromPath)return u.getLocaleFromPath(l,r,c);const n=l.split("/").filter(Boolean)[0];return n&&c.includes(n)?n:r},switchLocalePath:o=>{if(u?.switchLocalePath)return u.switchLocalePath(t.url.pathname,o,c,r);const l=t.url.pathname.split("/").filter(Boolean),s=l[0];return s&&c.includes(s)&&l.shift(),o!==r&&l.unshift(o),`/${l.join("/")}`},localizePath:(o,l)=>{if(u?.localizePath)return u.localizePath(o,l||a,c,r);const n=(o.replace(/^\//,"").replace(/\/$/,"")||"").split("/").filter(Boolean),f=n[0];return f&&c.includes(f)&&n.shift(),l&&l!==r&&n.unshift(l),`/${n.join("/")}`},getI18n:()=>e,getBasePath:o=>{const n=(o||t.url).pathname.split("/").filter(Boolean),f=n[0];return f&&c.includes(f)&&n.shift(),n.length>0?`/${n.join("/")}`:"/"},addTranslations:(o,l,s=!0)=>{e.addTranslations(o,l,s)},addRouteTranslations:(o,l,s,n=!0)=>{e.addRouteTranslations(o,l,s,n)},mergeTranslations:(o,l,s)=>{e.mergeTranslations(o,l,s)},clearCache:()=>{e.clearCache()}}}function G(t,e={}){const{baseUrl:a="/",addDirAttribute:r=!0,addSeoAttributes:i=!0}=e,c=$(t),u=v(t),l=O(t).filter(g=>!g.disabled),s=l.filter(g=>g.seo!==!1),n=l.find(g=>g.code===c);if(!n)return{htmlAttrs:{},link:[],meta:[]};const f=n.iso||c,d=D(n),m=n.dir||"auto",h={htmlAttrs:{lang:f,...r?{dir:m}:{}},link:[],meta:[]};if(!i)return h;const p=`${a}${t.url.pathname}`;h.link.push({rel:"canonical",href:p});const b=q(t),P=l.map(g=>g.code);for(const g of s){let L=t.url.pathname;if(b?.switchLocalePath)L=b.switchLocalePath(t.url.pathname,g.code,P,u);else{const S=t.url.pathname.split("/").filter(Boolean),_=S[0];_&&P.includes(_)&&S.shift(),g.code!==u&&S.unshift(g.code),L=`/${S.join("/")}`}const y=`${a}${L}`;h.link.push({rel:"alternate",href:y,hreflang:g.code}),g.iso&&g.iso!==g.code&&h.link.push({rel:"alternate",href:y,hreflang:g.iso})}if(l.find(g=>g.code===u)?.seo!==!1){let g=t.url.pathname;if(b?.switchLocalePath)g=b.switchLocalePath(t.url.pathname,u,P,u);else{const L=t.url.pathname.split("/").filter(Boolean),y=L[0];y&&P.includes(y)&&L.shift(),g=`/${L.join("/")}`}h.link.push({rel:"alternate",href:`${a}${g}`,hreflang:"x-default"})}d?h.meta.push({property:"og:locale",content:d}):F(n,{tag:"og:locale"}),h.meta.push({property:"og:url",content:p});for(const g of s){if(g.code===c)continue;const L=D(g);if(!L){F(g,{tag:"og:locale:alternate"});continue}h.meta.push({property:"og:locale:alternate",content:L})}return h}function K(t,e,a){const r=e.split(".");let i=t;for(let u=0;u<r.length-1;u++){const o=r[u];i[o]||(i[o]={}),i=i[o]}const c=r[r.length-1];c!==void 0&&(i[c]=a)}function Z(t,e){const a=I(t),r=$(t),i=v(t),c=a.getRoute(),u={};if(e&&e.length>0){const o={};for(const l of e){const s=a.t(l,void 0,void 0,c);s!=null&&s!==l&&K(o,l,s)}Object.keys(o).length>0&&(u[c]=o)}else{const o=a.getRouteTranslations(r,c);o&&(u[c]=o)}return{locale:r,fallbackLocale:i,currentRoute:c,translations:u}}Object.defineProperty(exports,"FormatService",{enumerable:!0,get:()=>R.FormatService});Object.defineProperty(exports,"defaultPlural",{enumerable:!0,get:()=>R.defaultPlural});Object.defineProperty(exports,"interpolate",{enumerable:!0,get:()=>R.interpolate});exports.AstroI18n=j;exports.createAstroRouterAdapter=V;exports.createI18n=H;exports.createI18nMiddleware=z;exports.detectLocale=x;exports.getDefaultLocale=v;exports.getI18n=I;exports.getI18nProps=Z;exports.getLocale=$;exports.getLocales=O;exports.i18nIntegration=U;exports.loadTranslationsFromDir=M;exports.loadTranslationsIntoI18n=E;exports.useI18n=J;exports.useLocaleHead=G;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
export { defaultPlural, FormatService, interpolate } from '@i18n-micro/core';
|
|
2
|
-
export type { CleanTranslation, Getter, Locale, LocaleCode, Params, PluralFunc, Translations
|
|
2
|
+
export type { CleanTranslation, Getter, Locale, LocaleCode, Params, PluralFunc, Translations } from '@i18n-micro/types';
|
|
3
3
|
export { AstroI18n, type AstroI18nOptions } from './composer';
|
|
4
4
|
export type { I18nIntegrationOptions } from './integration';
|
|
5
5
|
export { createI18n, i18nIntegration } from './integration';
|
|
6
6
|
export type { LoadedTranslations, LoadTranslationsOptions } from './load-translations';
|
|
7
|
-
export { loadTranslationsFromDir, loadTranslationsIntoI18n
|
|
7
|
+
export { loadTranslationsFromDir, loadTranslationsIntoI18n } from './load-translations';
|
|
8
8
|
export type { I18nMiddlewareOptions } from './middleware';
|
|
9
9
|
export { createI18nMiddleware, detectLocale } from './middleware';
|
|
10
10
|
export { createAstroRouterAdapter } from './router/adapter';
|
|
11
11
|
export type { I18nRoutingStrategy } from './router/types';
|
|
12
|
-
export { getLocaleFromPath, getRouteName, localizePath, removeLocaleFromPath, switchLocalePath, } from './routing';
|
|
13
12
|
export type { I18nClientProps, LocaleHeadOptions, LocaleHeadResult } from './utils';
|
|
14
|
-
export { getDefaultLocale, getI18n, getI18nProps, getLocale, getLocales, useI18n, useLocaleHead
|
|
13
|
+
export { getDefaultLocale, getI18n, getI18nProps, getLocale, getLocales, useI18n, useLocaleHead } from './utils';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
export { defaultPlural, FormatService, interpolate } from '@i18n-micro/core';
|
|
2
|
-
export type { CleanTranslation, Getter, Locale, LocaleCode, Params, PluralFunc, Translations
|
|
2
|
+
export type { CleanTranslation, Getter, Locale, LocaleCode, Params, PluralFunc, Translations } from '@i18n-micro/types';
|
|
3
3
|
export { AstroI18n, type AstroI18nOptions } from './composer';
|
|
4
4
|
export type { I18nIntegrationOptions } from './integration';
|
|
5
5
|
export { createI18n, i18nIntegration } from './integration';
|
|
6
6
|
export type { LoadedTranslations, LoadTranslationsOptions } from './load-translations';
|
|
7
|
-
export { loadTranslationsFromDir, loadTranslationsIntoI18n
|
|
7
|
+
export { loadTranslationsFromDir, loadTranslationsIntoI18n } from './load-translations';
|
|
8
8
|
export type { I18nMiddlewareOptions } from './middleware';
|
|
9
9
|
export { createI18nMiddleware, detectLocale } from './middleware';
|
|
10
10
|
export { createAstroRouterAdapter } from './router/adapter';
|
|
11
11
|
export type { I18nRoutingStrategy } from './router/types';
|
|
12
|
-
export { getLocaleFromPath, getRouteName, localizePath, removeLocaleFromPath, switchLocalePath, } from './routing';
|
|
13
12
|
export type { I18nClientProps, LocaleHeadOptions, LocaleHeadResult } from './utils';
|
|
14
|
-
export { getDefaultLocale, getI18n, getI18nProps, getLocale, getLocales, useI18n, useLocaleHead
|
|
13
|
+
export { getDefaultLocale, getI18n, getI18nProps, getLocale, getLocales, useI18n, useLocaleHead } from './utils';
|
package/dist/index.mjs
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import { BaseI18n as
|
|
2
|
-
import { FormatService as
|
|
3
|
-
import { existsSync as
|
|
4
|
-
import { resolve as
|
|
5
|
-
import { mergeRouteTranslationsWithRoot as
|
|
6
|
-
import { detectLocaleFromAcceptLanguage as
|
|
7
|
-
class
|
|
1
|
+
import { BaseI18n as N } from "@i18n-micro/core";
|
|
2
|
+
import { FormatService as fe, defaultPlural as ge, interpolate as he } from "@i18n-micro/core";
|
|
3
|
+
import { existsSync as D, readdirSync as M, statSync as W, readFileSync as A } from "node:fs";
|
|
4
|
+
import { resolve as U, join as q, relative as E, sep as H } from "node:path";
|
|
5
|
+
import { mergeRouteTranslationsWithRoot as x, storeLoadedTranslationFile as z } from "@i18n-micro/utils/parse-path";
|
|
6
|
+
import { detectLocaleFromAcceptLanguage as V } from "@i18n-micro/utils/accept-language";
|
|
7
|
+
class T extends N {
|
|
8
8
|
constructor(e) {
|
|
9
|
-
const
|
|
9
|
+
const a = e._storage || {
|
|
10
10
|
translations: /* @__PURE__ */ new Map()
|
|
11
11
|
};
|
|
12
12
|
if (super({
|
|
13
|
-
storage:
|
|
13
|
+
storage: a,
|
|
14
14
|
plural: e.plural,
|
|
15
15
|
missingWarn: e.missingWarn,
|
|
16
16
|
missingHandler: e.missingHandler
|
|
17
|
-
}), this.initialMessages = {}, this.storage =
|
|
17
|
+
}), this.initialMessages = {}, this.storage = a, this._locale = e.locale, this._fallbackLocale = e.fallbackLocale || e.locale, this._currentRoute = "index", e.messages) {
|
|
18
18
|
this.initialMessages = { ...e.messages };
|
|
19
|
-
for (const [
|
|
20
|
-
this.helper.loadTranslations(
|
|
19
|
+
for (const [r, i] of Object.entries(e.messages))
|
|
20
|
+
this.helper.loadTranslations(r, i);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
cloneStorage(e) {
|
|
24
|
-
const
|
|
25
|
-
for (const [
|
|
26
|
-
|
|
27
|
-
return { translations:
|
|
24
|
+
const a = /* @__PURE__ */ new Map();
|
|
25
|
+
for (const [r, i] of e.translations)
|
|
26
|
+
a.set(r, { ...i });
|
|
27
|
+
return { translations: a };
|
|
28
28
|
}
|
|
29
29
|
clone(e) {
|
|
30
|
-
const
|
|
31
|
-
return new
|
|
30
|
+
const a = this.cloneStorage(this.storage);
|
|
31
|
+
return new T({
|
|
32
32
|
locale: e || this._locale,
|
|
33
33
|
fallbackLocale: this._fallbackLocale,
|
|
34
34
|
plural: this.pluralFunc,
|
|
35
35
|
missingWarn: this.missingWarn,
|
|
36
36
|
missingHandler: this.missingHandler,
|
|
37
|
-
_storage:
|
|
37
|
+
_storage: a
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
get locale() {
|
|
@@ -61,43 +61,43 @@ class j extends O {
|
|
|
61
61
|
getRoute() {
|
|
62
62
|
return this._currentRoute;
|
|
63
63
|
}
|
|
64
|
-
getRouteTranslations(e,
|
|
65
|
-
const
|
|
66
|
-
return this.storage.translations.get(
|
|
64
|
+
getRouteTranslations(e, a) {
|
|
65
|
+
const r = `${e}:${a}`;
|
|
66
|
+
return this.storage.translations.get(r) ?? null;
|
|
67
67
|
}
|
|
68
|
-
addTranslations(e,
|
|
69
|
-
super.loadTranslationsCore(e,
|
|
68
|
+
addTranslations(e, a, r = !0) {
|
|
69
|
+
super.loadTranslationsCore(e, a, r);
|
|
70
70
|
}
|
|
71
|
-
addRouteTranslations(e,
|
|
72
|
-
super.loadRouteTranslationsCore(e,
|
|
71
|
+
addRouteTranslations(e, a, r, i = !0) {
|
|
72
|
+
super.loadRouteTranslationsCore(e, a, r, i);
|
|
73
73
|
}
|
|
74
|
-
mergeTranslations(e,
|
|
75
|
-
this.helper.mergeTranslation(e,
|
|
74
|
+
mergeTranslations(e, a, r) {
|
|
75
|
+
this.helper.mergeTranslation(e, a, r, !0);
|
|
76
76
|
}
|
|
77
77
|
clearCache() {
|
|
78
78
|
const e = { ...this.initialMessages };
|
|
79
79
|
if (super.clearCache(), Object.keys(e).length > 0)
|
|
80
|
-
for (const [
|
|
81
|
-
this.helper.loadTranslations(
|
|
80
|
+
for (const [a, r] of Object.entries(e))
|
|
81
|
+
this.helper.loadTranslations(a, r);
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
let
|
|
85
|
-
function
|
|
86
|
-
return
|
|
84
|
+
let _ = null;
|
|
85
|
+
function F() {
|
|
86
|
+
return _;
|
|
87
87
|
}
|
|
88
|
-
function
|
|
89
|
-
const { locale: e, fallbackLocale:
|
|
90
|
-
return
|
|
88
|
+
function ee(t) {
|
|
89
|
+
const { locale: e, fallbackLocale: a, translationDir: r, routingStrategy: i } = t;
|
|
90
|
+
return _ = i || null, {
|
|
91
91
|
name: "@i18n-micro/astro",
|
|
92
92
|
hooks: {
|
|
93
93
|
// 1. Vite setup (virtual module) happens here
|
|
94
94
|
"astro:config:setup": (c) => {
|
|
95
|
-
const { updateConfig: u } = c,
|
|
95
|
+
const { updateConfig: u } = c, o = "virtual:i18n-micro/config", l = `\0${o}`, s = {
|
|
96
96
|
defaultLocale: e,
|
|
97
|
-
fallbackLocale:
|
|
97
|
+
fallbackLocale: a || e,
|
|
98
98
|
locales: t.locales || [],
|
|
99
|
-
localeCodes: (t.locales || []).map((
|
|
100
|
-
translationDir:
|
|
99
|
+
localeCodes: (t.locales || []).map((n) => n.code),
|
|
100
|
+
translationDir: r || null,
|
|
101
101
|
autoDetect: t.autoDetect ?? !0,
|
|
102
102
|
redirectToDefault: t.redirectToDefault ?? !1,
|
|
103
103
|
localeCookie: t.localeCookie === null ? null : t.localeCookie || "i18n-locale",
|
|
@@ -108,13 +108,13 @@ function X(t) {
|
|
|
108
108
|
plugins: [
|
|
109
109
|
{
|
|
110
110
|
name: "vite-plugin-i18n-micro-config",
|
|
111
|
-
resolveId(
|
|
112
|
-
if (
|
|
113
|
-
return
|
|
111
|
+
resolveId(n) {
|
|
112
|
+
if (n === o)
|
|
113
|
+
return l;
|
|
114
114
|
},
|
|
115
|
-
load(
|
|
116
|
-
if (
|
|
117
|
-
return `export const config = ${JSON.stringify(
|
|
115
|
+
load(n) {
|
|
116
|
+
if (n === l)
|
|
117
|
+
return `export const config = ${JSON.stringify(s)}`;
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
]
|
|
@@ -148,141 +148,141 @@ function X(t) {
|
|
|
148
148
|
}
|
|
149
149
|
};
|
|
150
150
|
}
|
|
151
|
-
function
|
|
152
|
-
return new
|
|
151
|
+
function te(t) {
|
|
152
|
+
return new T(t);
|
|
153
153
|
}
|
|
154
|
-
function
|
|
155
|
-
if (
|
|
156
|
-
for (const
|
|
157
|
-
const
|
|
158
|
-
if (
|
|
159
|
-
|
|
154
|
+
function O(t, e) {
|
|
155
|
+
if (D(t))
|
|
156
|
+
for (const a of M(t)) {
|
|
157
|
+
const r = q(t, a);
|
|
158
|
+
if (W(r).isDirectory()) {
|
|
159
|
+
O(r, e);
|
|
160
160
|
continue;
|
|
161
161
|
}
|
|
162
|
-
|
|
162
|
+
a.endsWith(".json") && e(r);
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
|
-
function
|
|
166
|
-
const { translationDir: e, rootDir:
|
|
167
|
-
if (!
|
|
168
|
-
return console.warn(`[i18n] Translation directory not found: ${
|
|
165
|
+
function J(t) {
|
|
166
|
+
const { translationDir: e, rootDir: a = process.cwd(), disablePageLocales: r = !1 } = t, i = U(a, e);
|
|
167
|
+
if (!D(i))
|
|
168
|
+
return console.warn(`[i18n] Translation directory not found: ${i}`), { root: {}, routes: {} };
|
|
169
169
|
const c = { root: {}, routes: {} };
|
|
170
|
-
return
|
|
171
|
-
const
|
|
170
|
+
return O(i, (u) => {
|
|
171
|
+
const o = E(i, u).split(H).join("/");
|
|
172
172
|
try {
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
} catch (
|
|
176
|
-
console.error(`[i18n] Failed to load translation file: ${u}`,
|
|
173
|
+
const l = A(u, "utf-8"), s = JSON.parse(l);
|
|
174
|
+
z(c, o, s, r);
|
|
175
|
+
} catch (l) {
|
|
176
|
+
console.error(`[i18n] Failed to load translation file: ${u}`, l);
|
|
177
177
|
}
|
|
178
178
|
}), c;
|
|
179
179
|
}
|
|
180
|
-
function
|
|
181
|
-
const { root:
|
|
182
|
-
for (const [
|
|
183
|
-
t.addTranslations(
|
|
184
|
-
for (const [
|
|
185
|
-
for (const [u,
|
|
186
|
-
t.addRouteTranslations(u,
|
|
180
|
+
function ne(t, e) {
|
|
181
|
+
const { root: a, routes: r } = J(e);
|
|
182
|
+
for (const [i, c] of Object.entries(a))
|
|
183
|
+
t.addTranslations(i, c, !1);
|
|
184
|
+
for (const [i, c] of Object.entries(r))
|
|
185
|
+
for (const [u, o] of Object.entries(c))
|
|
186
|
+
t.addRouteTranslations(u, i, x(a[u], o), !1);
|
|
187
187
|
}
|
|
188
|
-
function
|
|
188
|
+
function oe(t) {
|
|
189
189
|
const {
|
|
190
190
|
i18n: e,
|
|
191
191
|
// This is the global singleton with cache
|
|
192
|
-
defaultLocale:
|
|
193
|
-
locales:
|
|
194
|
-
localeObjects:
|
|
192
|
+
defaultLocale: a,
|
|
193
|
+
locales: r,
|
|
194
|
+
localeObjects: i,
|
|
195
195
|
autoDetect: c = !0,
|
|
196
196
|
redirectToDefault: u = !1,
|
|
197
|
-
routingStrategy:
|
|
198
|
-
} = t,
|
|
199
|
-
return async (
|
|
200
|
-
if (
|
|
201
|
-
return
|
|
202
|
-
const f =
|
|
203
|
-
if (!
|
|
204
|
-
const
|
|
205
|
-
return
|
|
197
|
+
routingStrategy: o
|
|
198
|
+
} = t, l = o || F();
|
|
199
|
+
return async (s, n) => {
|
|
200
|
+
if (s.locals.locale && s.locals.i18n)
|
|
201
|
+
return n();
|
|
202
|
+
const f = s.url, h = f.pathname;
|
|
203
|
+
if (!l) {
|
|
204
|
+
const L = e.clone(a), S = h === "/" || h === "" ? "index" : h.split("/").filter(Boolean).join("-");
|
|
205
|
+
return L.setRoute(S), s.locals.i18n = L, s.locals.locale = a, s.locals.defaultLocale = a, s.locals.locales = i || r.map((y) => ({ code: y })), s.locals.currentUrl = f, n();
|
|
206
206
|
}
|
|
207
|
-
const
|
|
208
|
-
...
|
|
209
|
-
getCurrentPath: () =>
|
|
207
|
+
const m = {
|
|
208
|
+
...l,
|
|
209
|
+
getCurrentPath: () => h,
|
|
210
210
|
getRoute: () => ({
|
|
211
211
|
fullPath: f.pathname + f.search,
|
|
212
212
|
query: Object.fromEntries(f.searchParams)
|
|
213
213
|
})
|
|
214
|
-
},
|
|
215
|
-
let
|
|
216
|
-
|
|
217
|
-
const
|
|
218
|
-
return
|
|
214
|
+
}, p = h.split("/").filter(Boolean)[0], b = p !== void 0 && r.includes(p);
|
|
215
|
+
let P;
|
|
216
|
+
b && p ? P = p : m.getLocaleFromPath ? P = m.getLocaleFromPath(h, a, r) : P = a;
|
|
217
|
+
const w = e.clone(P), g = m.getRouteName ? m.getRouteName(h, r) : "index";
|
|
218
|
+
return w.setRoute(g), s.locals.i18n = w, s.locals.locale = P, s.locals.defaultLocale = a, s.locals.locales = i || r.map((L) => ({ code: L })), s.locals.currentUrl = f, s.locals.routingStrategy = m, n();
|
|
219
219
|
};
|
|
220
220
|
}
|
|
221
|
-
function
|
|
222
|
-
const u =
|
|
223
|
-
let
|
|
221
|
+
function ae(t, e, a, r, i, c = "i18n-locale") {
|
|
222
|
+
const u = F();
|
|
223
|
+
let o = r;
|
|
224
224
|
if (u?.getLocaleFromPath)
|
|
225
|
-
|
|
225
|
+
o = u.getLocaleFromPath(t, r, i);
|
|
226
226
|
else {
|
|
227
|
-
const
|
|
228
|
-
|
|
227
|
+
const s = t.split("/").filter(Boolean)[0];
|
|
228
|
+
s && i.includes(s) && (o = s);
|
|
229
229
|
}
|
|
230
|
-
if (c !== null &&
|
|
231
|
-
const
|
|
232
|
-
|
|
230
|
+
if (c !== null && o === r && e.get(c)) {
|
|
231
|
+
const l = e.get(c)?.value;
|
|
232
|
+
l && i.includes(l) && (o = l);
|
|
233
233
|
}
|
|
234
|
-
if (
|
|
234
|
+
if (o === r)
|
|
235
235
|
try {
|
|
236
|
-
const
|
|
237
|
-
|
|
236
|
+
const l = V(a.get("accept-language") ?? void 0, i);
|
|
237
|
+
l && (o = l);
|
|
238
238
|
} catch {
|
|
239
239
|
}
|
|
240
|
-
return
|
|
240
|
+
return o;
|
|
241
241
|
}
|
|
242
|
-
function
|
|
243
|
-
const
|
|
244
|
-
const
|
|
245
|
-
if (!
|
|
242
|
+
function le(t, e, a) {
|
|
243
|
+
const r = t.map((n) => n.code), i = (n, f = []) => {
|
|
244
|
+
const h = n.replace(/^\//, "").replace(/\/$/, "");
|
|
245
|
+
if (!h)
|
|
246
246
|
return "index";
|
|
247
|
-
const
|
|
248
|
-
return
|
|
249
|
-
}, c = (
|
|
250
|
-
const
|
|
251
|
-
return
|
|
252
|
-
}, u = (
|
|
253
|
-
const
|
|
254
|
-
return
|
|
255
|
-
},
|
|
256
|
-
const
|
|
257
|
-
return
|
|
247
|
+
const m = h.split("/").filter(Boolean), d = m[0];
|
|
248
|
+
return d && f.includes(d) && m.shift(), m.length === 0 ? "index" : m.join("-");
|
|
249
|
+
}, c = (n, f = "en", h = []) => {
|
|
250
|
+
const d = n.split("/").filter(Boolean)[0];
|
|
251
|
+
return d && h.includes(d) ? d : f;
|
|
252
|
+
}, u = (n, f, h = [], m) => {
|
|
253
|
+
const d = n.split("/").filter(Boolean), p = d[0];
|
|
254
|
+
return p && h.includes(p) && d.shift(), (f !== m || m === void 0) && d.unshift(f), `/${d.join("/")}`;
|
|
255
|
+
}, o = (n, f, h = [], m) => {
|
|
256
|
+
const p = (n.replace(/^\//, "").replace(/\/$/, "") || "").split("/").filter(Boolean), b = p[0];
|
|
257
|
+
return b && h.includes(b) && p.shift(), (f !== m || m === void 0) && p.unshift(f), `/${p.join("/")}`;
|
|
258
258
|
};
|
|
259
259
|
return {
|
|
260
|
-
getCurrentPath: () =>
|
|
261
|
-
getRouteName:
|
|
260
|
+
getCurrentPath: () => a ? a().pathname : typeof window < "u" ? window.location.pathname : "/",
|
|
261
|
+
getRouteName: i,
|
|
262
262
|
getLocaleFromPath: c,
|
|
263
263
|
switchLocalePath: u,
|
|
264
|
-
localizePath:
|
|
265
|
-
removeLocaleFromPath: (
|
|
266
|
-
const
|
|
267
|
-
return
|
|
264
|
+
localizePath: o,
|
|
265
|
+
removeLocaleFromPath: (n, f = []) => {
|
|
266
|
+
const h = n.split("/").filter(Boolean), m = h[0];
|
|
267
|
+
return m && f.includes(m) && h.shift(), `/${h.join("/")}`;
|
|
268
268
|
},
|
|
269
|
-
resolvePath: (
|
|
270
|
-
const
|
|
271
|
-
return
|
|
269
|
+
resolvePath: (n, f) => {
|
|
270
|
+
const h = typeof n == "string" ? n : n.path || "/";
|
|
271
|
+
return o(h, f, r, e);
|
|
272
272
|
},
|
|
273
273
|
getRoute: () => {
|
|
274
|
-
if (
|
|
275
|
-
const
|
|
274
|
+
if (a) {
|
|
275
|
+
const n = a();
|
|
276
276
|
return {
|
|
277
|
-
fullPath:
|
|
278
|
-
query: Object.fromEntries(
|
|
277
|
+
fullPath: n.pathname + n.search,
|
|
278
|
+
query: Object.fromEntries(n.searchParams)
|
|
279
279
|
};
|
|
280
280
|
}
|
|
281
281
|
if (typeof window < "u") {
|
|
282
|
-
const
|
|
282
|
+
const n = new URL(window.location.href);
|
|
283
283
|
return {
|
|
284
|
-
fullPath:
|
|
285
|
-
query: Object.fromEntries(
|
|
284
|
+
fullPath: n.pathname + n.search,
|
|
285
|
+
query: Object.fromEntries(n.searchParams)
|
|
286
286
|
};
|
|
287
287
|
}
|
|
288
288
|
return {
|
|
@@ -291,242 +291,247 @@ function ne(t, e, o) {
|
|
|
291
291
|
};
|
|
292
292
|
},
|
|
293
293
|
// Optional: client-side navigation for islands
|
|
294
|
-
push: (
|
|
295
|
-
typeof window < "u" && (window.location.href =
|
|
294
|
+
push: (n) => {
|
|
295
|
+
typeof window < "u" && (window.location.href = n.path);
|
|
296
296
|
},
|
|
297
|
-
replace: (
|
|
298
|
-
typeof window < "u" && window.location.replace(
|
|
297
|
+
replace: (n) => {
|
|
298
|
+
typeof window < "u" && window.location.replace(n.path);
|
|
299
299
|
}
|
|
300
300
|
};
|
|
301
301
|
}
|
|
302
|
-
function
|
|
303
|
-
const
|
|
304
|
-
if (
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
return
|
|
302
|
+
function R(t) {
|
|
303
|
+
const e = t.og?.trim();
|
|
304
|
+
if (e) return e;
|
|
305
|
+
const a = t.iso?.trim();
|
|
306
|
+
if (!a) return null;
|
|
307
|
+
const r = a.indexOf("_");
|
|
308
|
+
if (r > 0) {
|
|
309
|
+
const c = a.slice(0, r), u = a.slice(r + 1);
|
|
310
|
+
if (c.length >= 2 && u.length === 2)
|
|
311
|
+
return `${c.toLowerCase()}_${u.toUpperCase()}`;
|
|
312
|
+
}
|
|
313
|
+
const i = a.indexOf("-");
|
|
314
|
+
if (i > 0) {
|
|
315
|
+
const c = a.slice(0, i), u = a.slice(i + 1);
|
|
316
|
+
if (c.length >= 2 && u.length === 2 && /^[A-Za-z]{2}$/.test(u))
|
|
317
|
+
return `${c.toLowerCase()}_${u.toUpperCase()}`;
|
|
318
|
+
}
|
|
319
|
+
return null;
|
|
320
320
|
}
|
|
321
|
-
function
|
|
322
|
-
|
|
323
|
-
|
|
321
|
+
function k(t, e = {}) {
|
|
322
|
+
if (R(t) !== null || e.missingWarn === !1 || process.env.NODE_ENV === "production") return;
|
|
323
|
+
const a = e.tag ?? "og:locale", r = String(t.code ?? "unknown"), i = t.iso ? `, iso: '${t.iso}'` : "";
|
|
324
|
+
console.warn(
|
|
325
|
+
`[i18n] Cannot derive ${a} for locale '${r}'${i}. Set locale.og (e.g. 'en_US') or use iso with a 2-letter region (e.g. 'en-US').`
|
|
326
|
+
);
|
|
324
327
|
}
|
|
325
|
-
function
|
|
328
|
+
function C(t) {
|
|
326
329
|
const e = t.locals.i18n;
|
|
327
330
|
if (!e)
|
|
328
331
|
throw new Error("i18n instance not found. Make sure i18n middleware is configured.");
|
|
329
332
|
return e;
|
|
330
333
|
}
|
|
331
|
-
function
|
|
334
|
+
function $(t) {
|
|
332
335
|
return t.locals.locale || "en";
|
|
333
336
|
}
|
|
334
|
-
function
|
|
337
|
+
function v(t) {
|
|
335
338
|
return t.locals.defaultLocale || "en";
|
|
336
339
|
}
|
|
337
|
-
function
|
|
340
|
+
function B(t) {
|
|
338
341
|
return t.locals.locales || [];
|
|
339
342
|
}
|
|
340
343
|
function I(t) {
|
|
341
344
|
return t.locals.routingStrategy || null;
|
|
342
345
|
}
|
|
343
|
-
function
|
|
344
|
-
const e =
|
|
346
|
+
function re(t) {
|
|
347
|
+
const e = C(t), a = $(t), r = v(t), i = B(t), c = i.map((o) => o.code), u = I(t);
|
|
345
348
|
return {
|
|
346
349
|
// Current locale
|
|
347
|
-
locale:
|
|
348
|
-
defaultLocale:
|
|
349
|
-
locales:
|
|
350
|
+
locale: a,
|
|
351
|
+
defaultLocale: r,
|
|
352
|
+
locales: i,
|
|
350
353
|
// Translation methods
|
|
351
|
-
t: (
|
|
352
|
-
ts: (
|
|
353
|
-
tc: (
|
|
354
|
-
tn: (
|
|
355
|
-
td: (
|
|
356
|
-
tdr: (
|
|
357
|
-
has: (
|
|
354
|
+
t: (o, l, s, n) => e.t(o, l, s, n),
|
|
355
|
+
ts: (o, l, s, n) => e.ts(o, l, s, n),
|
|
356
|
+
tc: (o, l, s) => e.tc(o, l, s),
|
|
357
|
+
tn: (o, l) => e.tn(o, l),
|
|
358
|
+
td: (o, l) => e.td(o, l),
|
|
359
|
+
tdr: (o, l) => e.tdr(o, l),
|
|
360
|
+
has: (o, l) => e.has(o, l),
|
|
358
361
|
// Route management
|
|
359
362
|
getRoute: () => e.getRoute(),
|
|
360
|
-
getRouteName: (
|
|
361
|
-
const
|
|
363
|
+
getRouteName: (o) => {
|
|
364
|
+
const l = o || t.url.pathname;
|
|
362
365
|
if (u?.getRouteName)
|
|
363
|
-
return u.getRouteName(
|
|
364
|
-
const
|
|
365
|
-
if (!
|
|
366
|
-
const
|
|
367
|
-
return f && c.includes(f) &&
|
|
366
|
+
return u.getRouteName(l, c);
|
|
367
|
+
const s = l.replace(/^\//, "").replace(/\/$/, "");
|
|
368
|
+
if (!s) return "index";
|
|
369
|
+
const n = s.split("/").filter(Boolean), f = n[0];
|
|
370
|
+
return f && c.includes(f) && n.shift(), n.length === 0 ? "index" : n.join("-");
|
|
368
371
|
},
|
|
369
|
-
getLocaleFromPath: (
|
|
370
|
-
const
|
|
372
|
+
getLocaleFromPath: (o) => {
|
|
373
|
+
const l = o || t.url.pathname;
|
|
371
374
|
if (u?.getLocaleFromPath)
|
|
372
|
-
return u.getLocaleFromPath(
|
|
373
|
-
const
|
|
374
|
-
return
|
|
375
|
+
return u.getLocaleFromPath(l, r, c);
|
|
376
|
+
const n = l.split("/").filter(Boolean)[0];
|
|
377
|
+
return n && c.includes(n) ? n : r;
|
|
375
378
|
},
|
|
376
379
|
// Path utilities
|
|
377
|
-
switchLocalePath: (
|
|
380
|
+
switchLocalePath: (o) => {
|
|
378
381
|
if (u?.switchLocalePath)
|
|
379
|
-
return u.switchLocalePath(t.url.pathname,
|
|
380
|
-
const
|
|
381
|
-
return
|
|
382
|
+
return u.switchLocalePath(t.url.pathname, o, c, r);
|
|
383
|
+
const l = t.url.pathname.split("/").filter(Boolean), s = l[0];
|
|
384
|
+
return s && c.includes(s) && l.shift(), o !== r && l.unshift(o), `/${l.join("/")}`;
|
|
382
385
|
},
|
|
383
|
-
localizePath: (
|
|
386
|
+
localizePath: (o, l) => {
|
|
384
387
|
if (u?.localizePath)
|
|
385
|
-
return u.localizePath(
|
|
386
|
-
const
|
|
387
|
-
return f && c.includes(f) &&
|
|
388
|
+
return u.localizePath(o, l || a, c, r);
|
|
389
|
+
const n = (o.replace(/^\//, "").replace(/\/$/, "") || "").split("/").filter(Boolean), f = n[0];
|
|
390
|
+
return f && c.includes(f) && n.shift(), l && l !== r && n.unshift(l), `/${n.join("/")}`;
|
|
388
391
|
},
|
|
389
392
|
// Get i18n instance
|
|
390
393
|
getI18n: () => e,
|
|
391
394
|
// Get base path without locale (for rewrite)
|
|
392
|
-
getBasePath: (
|
|
393
|
-
const
|
|
394
|
-
return f && c.includes(f) &&
|
|
395
|
+
getBasePath: (o) => {
|
|
396
|
+
const n = (o || t.url).pathname.split("/").filter(Boolean), f = n[0];
|
|
397
|
+
return f && c.includes(f) && n.shift(), n.length > 0 ? `/${n.join("/")}` : "/";
|
|
395
398
|
},
|
|
396
399
|
// Translation management
|
|
397
|
-
addTranslations: (
|
|
398
|
-
e.addTranslations(
|
|
400
|
+
addTranslations: (o, l, s = !0) => {
|
|
401
|
+
e.addTranslations(o, l, s);
|
|
399
402
|
},
|
|
400
|
-
addRouteTranslations: (
|
|
401
|
-
e.addRouteTranslations(
|
|
403
|
+
addRouteTranslations: (o, l, s, n = !0) => {
|
|
404
|
+
e.addRouteTranslations(o, l, s, n);
|
|
402
405
|
},
|
|
403
|
-
mergeTranslations: (
|
|
404
|
-
e.mergeTranslations(
|
|
406
|
+
mergeTranslations: (o, l, s) => {
|
|
407
|
+
e.mergeTranslations(o, l, s);
|
|
405
408
|
},
|
|
406
409
|
clearCache: () => {
|
|
407
410
|
e.clearCache();
|
|
408
411
|
}
|
|
409
412
|
};
|
|
410
413
|
}
|
|
411
|
-
function
|
|
412
|
-
const { baseUrl:
|
|
413
|
-
if (!
|
|
414
|
+
function se(t, e = {}) {
|
|
415
|
+
const { baseUrl: a = "/", addDirAttribute: r = !0, addSeoAttributes: i = !0 } = e, c = $(t), u = v(t), l = B(t).filter((g) => !g.disabled), s = l.filter((g) => g.seo !== !1), n = l.find((g) => g.code === c);
|
|
416
|
+
if (!n)
|
|
414
417
|
return { htmlAttrs: {}, link: [], meta: [] };
|
|
415
|
-
const f =
|
|
418
|
+
const f = n.iso || c, h = R(n), m = n.dir || "auto", d = {
|
|
416
419
|
htmlAttrs: {
|
|
417
420
|
lang: f,
|
|
418
|
-
...
|
|
421
|
+
...r ? { dir: m } : {}
|
|
419
422
|
},
|
|
420
423
|
link: [],
|
|
421
424
|
meta: []
|
|
422
425
|
};
|
|
423
|
-
if (!
|
|
424
|
-
return
|
|
425
|
-
const p = `${
|
|
426
|
-
|
|
426
|
+
if (!i)
|
|
427
|
+
return d;
|
|
428
|
+
const p = `${a}${t.url.pathname}`;
|
|
429
|
+
d.link.push({
|
|
427
430
|
rel: "canonical",
|
|
428
431
|
href: p
|
|
429
432
|
});
|
|
430
|
-
const
|
|
431
|
-
for (const
|
|
432
|
-
let
|
|
433
|
-
if (
|
|
434
|
-
|
|
433
|
+
const b = I(t), P = l.map((g) => g.code);
|
|
434
|
+
for (const g of s) {
|
|
435
|
+
let L = t.url.pathname;
|
|
436
|
+
if (b?.switchLocalePath)
|
|
437
|
+
L = b.switchLocalePath(t.url.pathname, g.code, P, u);
|
|
435
438
|
else {
|
|
436
|
-
const y = t.url.pathname.split("/").filter(Boolean),
|
|
437
|
-
|
|
439
|
+
const y = t.url.pathname.split("/").filter(Boolean), j = y[0];
|
|
440
|
+
j && P.includes(j) && y.shift(), g.code !== u && y.unshift(g.code), L = `/${y.join("/")}`;
|
|
438
441
|
}
|
|
439
|
-
const
|
|
440
|
-
|
|
442
|
+
const S = `${a}${L}`;
|
|
443
|
+
d.link.push({
|
|
441
444
|
rel: "alternate",
|
|
442
|
-
href:
|
|
443
|
-
hreflang:
|
|
444
|
-
}),
|
|
445
|
+
href: S,
|
|
446
|
+
hreflang: g.code
|
|
447
|
+
}), g.iso && g.iso !== g.code && d.link.push({
|
|
445
448
|
rel: "alternate",
|
|
446
|
-
href:
|
|
447
|
-
hreflang:
|
|
449
|
+
href: S,
|
|
450
|
+
hreflang: g.iso
|
|
448
451
|
});
|
|
449
452
|
}
|
|
450
|
-
if (
|
|
451
|
-
let
|
|
452
|
-
if (
|
|
453
|
-
|
|
453
|
+
if (l.find((g) => g.code === u)?.seo !== !1) {
|
|
454
|
+
let g = t.url.pathname;
|
|
455
|
+
if (b?.switchLocalePath)
|
|
456
|
+
g = b.switchLocalePath(t.url.pathname, u, P, u);
|
|
454
457
|
else {
|
|
455
|
-
const
|
|
456
|
-
|
|
458
|
+
const L = t.url.pathname.split("/").filter(Boolean), S = L[0];
|
|
459
|
+
S && P.includes(S) && L.shift(), g = `/${L.join("/")}`;
|
|
457
460
|
}
|
|
458
|
-
|
|
461
|
+
d.link.push({
|
|
459
462
|
rel: "alternate",
|
|
460
|
-
href: `${
|
|
463
|
+
href: `${a}${g}`,
|
|
461
464
|
hreflang: "x-default"
|
|
462
465
|
});
|
|
463
466
|
}
|
|
464
|
-
|
|
467
|
+
h ? d.meta.push({
|
|
465
468
|
property: "og:locale",
|
|
466
|
-
content:
|
|
467
|
-
}),
|
|
469
|
+
content: h
|
|
470
|
+
}) : k(n, { tag: "og:locale" }), d.meta.push({
|
|
468
471
|
property: "og:url",
|
|
469
472
|
content: p
|
|
470
473
|
});
|
|
471
|
-
for (const
|
|
472
|
-
|
|
474
|
+
for (const g of s) {
|
|
475
|
+
if (g.code === c) continue;
|
|
476
|
+
const L = R(g);
|
|
477
|
+
if (!L) {
|
|
478
|
+
k(g, { tag: "og:locale:alternate" });
|
|
479
|
+
continue;
|
|
480
|
+
}
|
|
481
|
+
d.meta.push({
|
|
473
482
|
property: "og:locale:alternate",
|
|
474
|
-
content:
|
|
483
|
+
content: L
|
|
475
484
|
});
|
|
476
|
-
|
|
485
|
+
}
|
|
486
|
+
return d;
|
|
477
487
|
}
|
|
478
|
-
function
|
|
479
|
-
const
|
|
480
|
-
let
|
|
481
|
-
for (let u = 0; u <
|
|
482
|
-
const
|
|
483
|
-
|
|
488
|
+
function G(t, e, a) {
|
|
489
|
+
const r = e.split(".");
|
|
490
|
+
let i = t;
|
|
491
|
+
for (let u = 0; u < r.length - 1; u++) {
|
|
492
|
+
const o = r[u];
|
|
493
|
+
i[o] || (i[o] = {}), i = i[o];
|
|
484
494
|
}
|
|
485
|
-
const c =
|
|
486
|
-
c !== void 0 && (
|
|
495
|
+
const c = r[r.length - 1];
|
|
496
|
+
c !== void 0 && (i[c] = a);
|
|
487
497
|
}
|
|
488
|
-
function
|
|
489
|
-
const
|
|
498
|
+
function ie(t, e) {
|
|
499
|
+
const a = C(t), r = $(t), i = v(t), c = a.getRoute(), u = {};
|
|
490
500
|
if (e && e.length > 0) {
|
|
491
|
-
const
|
|
492
|
-
for (const
|
|
493
|
-
const
|
|
494
|
-
|
|
501
|
+
const o = {};
|
|
502
|
+
for (const l of e) {
|
|
503
|
+
const s = a.t(l, void 0, void 0, c);
|
|
504
|
+
s != null && s !== l && G(o, l, s);
|
|
495
505
|
}
|
|
496
|
-
Object.keys(
|
|
506
|
+
Object.keys(o).length > 0 && (u[c] = o);
|
|
497
507
|
} else {
|
|
498
|
-
const
|
|
499
|
-
|
|
508
|
+
const o = a.getRouteTranslations(r, c);
|
|
509
|
+
o && (u[c] = o);
|
|
500
510
|
}
|
|
501
511
|
return {
|
|
502
|
-
locale:
|
|
503
|
-
fallbackLocale:
|
|
512
|
+
locale: r,
|
|
513
|
+
fallbackLocale: i,
|
|
504
514
|
currentRoute: c,
|
|
505
515
|
translations: u
|
|
506
516
|
};
|
|
507
517
|
}
|
|
508
518
|
export {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
se as localizePath,
|
|
528
|
-
re as removeLocaleFromPath,
|
|
529
|
-
le as switchLocalePath,
|
|
530
|
-
ie as useI18n,
|
|
531
|
-
ce as useLocaleHead
|
|
519
|
+
T as AstroI18n,
|
|
520
|
+
fe as FormatService,
|
|
521
|
+
le as createAstroRouterAdapter,
|
|
522
|
+
te as createI18n,
|
|
523
|
+
oe as createI18nMiddleware,
|
|
524
|
+
ge as defaultPlural,
|
|
525
|
+
ae as detectLocale,
|
|
526
|
+
v as getDefaultLocale,
|
|
527
|
+
C as getI18n,
|
|
528
|
+
ie as getI18nProps,
|
|
529
|
+
$ as getLocale,
|
|
530
|
+
B as getLocales,
|
|
531
|
+
ee as i18nIntegration,
|
|
532
|
+
he as interpolate,
|
|
533
|
+
J as loadTranslationsFromDir,
|
|
534
|
+
ne as loadTranslationsIntoI18n,
|
|
535
|
+
re as useI18n,
|
|
536
|
+
se as useLocaleHead
|
|
532
537
|
};
|
package/package.json
CHANGED
|
@@ -1,22 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@i18n-micro/astro",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.7",
|
|
4
4
|
"description": "Astro integration for i18n-micro — translations, routing, and islands.",
|
|
5
|
-
"
|
|
5
|
+
"keywords": [
|
|
6
|
+
"astro",
|
|
7
|
+
"i18n",
|
|
8
|
+
"internationalization",
|
|
9
|
+
"translations"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://github.com/s00d/nuxt-i18n-micro/tree/main/packages/astro#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/s00d/nuxt-i18n-micro/issues"
|
|
14
|
+
},
|
|
6
15
|
"license": "MIT",
|
|
7
|
-
"sideEffects": false,
|
|
8
16
|
"repository": {
|
|
9
17
|
"type": "git",
|
|
10
18
|
"url": "git+https://github.com/s00d/nuxt-i18n-micro.git",
|
|
11
19
|
"directory": "packages/astro"
|
|
12
20
|
},
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"src",
|
|
24
|
+
"README.md",
|
|
25
|
+
"LICENSE"
|
|
26
|
+
],
|
|
27
|
+
"type": "module",
|
|
28
|
+
"sideEffects": false,
|
|
20
29
|
"main": "./dist/index.cjs",
|
|
21
30
|
"types": "./dist/index.d.ts",
|
|
22
31
|
"exports": {
|
|
@@ -64,33 +73,35 @@
|
|
|
64
73
|
},
|
|
65
74
|
"./package.json": "./package.json"
|
|
66
75
|
},
|
|
67
|
-
"files": [
|
|
68
|
-
"dist",
|
|
69
|
-
"src",
|
|
70
|
-
"README.md",
|
|
71
|
-
"LICENSE"
|
|
72
|
-
],
|
|
73
76
|
"publishConfig": {
|
|
74
77
|
"access": "public"
|
|
75
78
|
},
|
|
76
|
-
"keywords": [
|
|
77
|
-
"astro",
|
|
78
|
-
"i18n",
|
|
79
|
-
"internationalization",
|
|
80
|
-
"translations"
|
|
81
|
-
],
|
|
82
79
|
"dependencies": {
|
|
83
|
-
"@i18n-micro/
|
|
84
|
-
"@i18n-micro/
|
|
85
|
-
"@i18n-micro/utils": "1.0.
|
|
86
|
-
"@i18n-micro/node": "1.2.
|
|
80
|
+
"@i18n-micro/core": "1.3.2",
|
|
81
|
+
"@i18n-micro/types": "1.2.5",
|
|
82
|
+
"@i18n-micro/utils": "1.0.2",
|
|
83
|
+
"@i18n-micro/node": "1.2.3"
|
|
87
84
|
},
|
|
88
|
-
"
|
|
85
|
+
"devDependencies": {
|
|
86
|
+
"@types/jest": "^29.5.14",
|
|
89
87
|
"astro": "^5.16.5",
|
|
88
|
+
"jest": "^29.7.0",
|
|
89
|
+
"preact": "^10.0.0",
|
|
90
|
+
"publint": "^0.3.17",
|
|
91
|
+
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
|
90
92
|
"svelte": "^4.0.0 || ^5.0.0",
|
|
91
|
-
"
|
|
93
|
+
"ts-jest": "^29.4.6",
|
|
94
|
+
"vite": "^7.3.1",
|
|
95
|
+
"vite-plugin-dts": "^4.5.4",
|
|
96
|
+
"vitest": "^3.2.4",
|
|
97
|
+
"vue": "^3.5.25"
|
|
98
|
+
},
|
|
99
|
+
"peerDependencies": {
|
|
100
|
+
"astro": "^5.16.5",
|
|
101
|
+
"preact": "^10.0.0",
|
|
92
102
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
|
93
|
-
"
|
|
103
|
+
"svelte": "^4.0.0 || ^5.0.0",
|
|
104
|
+
"vue": "^3.5.25"
|
|
94
105
|
},
|
|
95
106
|
"peerDependenciesMeta": {
|
|
96
107
|
"svelte": {
|
|
@@ -106,19 +117,8 @@
|
|
|
106
117
|
"optional": true
|
|
107
118
|
}
|
|
108
119
|
},
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
-
"vite": "^7.3.1",
|
|
112
|
-
"vite-plugin-dts": "^4.5.4",
|
|
113
|
-
"jest": "^29.7.0",
|
|
114
|
-
"ts-jest": "^29.4.6",
|
|
115
|
-
"@types/jest": "^29.5.14",
|
|
116
|
-
"svelte": "^4.0.0 || ^5.0.0",
|
|
117
|
-
"vue": "^3.5.25",
|
|
118
|
-
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
|
119
|
-
"preact": "^10.0.0",
|
|
120
|
-
"publint": "^0.3.17",
|
|
121
|
-
"vitest": "^3.2.4"
|
|
120
|
+
"engines": {
|
|
121
|
+
"node": ">=18"
|
|
122
122
|
},
|
|
123
123
|
"scripts": {
|
|
124
124
|
"build": "vite build",
|
package/src/index.ts
CHANGED
|
@@ -4,15 +4,7 @@ import './env.d'
|
|
|
4
4
|
// Re-export utilities from core
|
|
5
5
|
export { defaultPlural, FormatService, interpolate } from '@i18n-micro/core'
|
|
6
6
|
// Re-export types from @i18n-micro/types
|
|
7
|
-
export type {
|
|
8
|
-
CleanTranslation,
|
|
9
|
-
Getter,
|
|
10
|
-
Locale,
|
|
11
|
-
LocaleCode,
|
|
12
|
-
Params,
|
|
13
|
-
PluralFunc,
|
|
14
|
-
Translations,
|
|
15
|
-
} from '@i18n-micro/types'
|
|
7
|
+
export type { CleanTranslation, Getter, Locale, LocaleCode, Params, PluralFunc, Translations } from '@i18n-micro/types'
|
|
16
8
|
export { AstroI18n, type AstroI18nOptions } from './composer'
|
|
17
9
|
// Export integration options type
|
|
18
10
|
export type { I18nIntegrationOptions } from './integration'
|
|
@@ -20,33 +12,13 @@ export type { I18nIntegrationOptions } from './integration'
|
|
|
20
12
|
export { createI18n, i18nIntegration } from './integration'
|
|
21
13
|
export type { LoadedTranslations, LoadTranslationsOptions } from './load-translations'
|
|
22
14
|
// Export translation loading utilities
|
|
23
|
-
export {
|
|
24
|
-
loadTranslationsFromDir,
|
|
25
|
-
loadTranslationsIntoI18n,
|
|
26
|
-
} from './load-translations'
|
|
15
|
+
export { loadTranslationsFromDir, loadTranslationsIntoI18n } from './load-translations'
|
|
27
16
|
export type { I18nMiddlewareOptions } from './middleware'
|
|
28
17
|
export { createI18nMiddleware, detectLocale } from './middleware'
|
|
29
18
|
export { createAstroRouterAdapter } from './router/adapter'
|
|
30
19
|
// Router abstraction
|
|
31
20
|
export type { I18nRoutingStrategy } from './router/types'
|
|
32
|
-
// Legacy routing utilities (deprecated, use routingStrategy instead)
|
|
33
|
-
// Kept for backward compatibility
|
|
34
|
-
export {
|
|
35
|
-
getLocaleFromPath,
|
|
36
|
-
getRouteName,
|
|
37
|
-
localizePath,
|
|
38
|
-
removeLocaleFromPath,
|
|
39
|
-
switchLocalePath,
|
|
40
|
-
} from './routing'
|
|
41
21
|
export type { I18nClientProps, LocaleHeadOptions, LocaleHeadResult } from './utils'
|
|
42
22
|
// Utilities
|
|
43
|
-
export {
|
|
44
|
-
getDefaultLocale,
|
|
45
|
-
getI18n,
|
|
46
|
-
getI18nProps,
|
|
47
|
-
getLocale,
|
|
48
|
-
getLocales,
|
|
49
|
-
useI18n,
|
|
50
|
-
useLocaleHead,
|
|
51
|
-
} from './utils'
|
|
23
|
+
export { getDefaultLocale, getI18n, getI18nProps, getLocale, getLocales, useI18n, useLocaleHead } from './utils'
|
|
52
24
|
// It's loaded directly by Astro via entrypoint in integration config
|
package/src/utils.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CleanTranslation, Locale, Params, TranslationKey, Translations } from '@i18n-micro/types'
|
|
2
|
+
import { resolveOgLocale, warnUnresolvedOgLocale } from '@i18n-micro/utils/resolve-og-locale'
|
|
2
3
|
import type { AstroGlobal } from 'astro'
|
|
3
4
|
import type { AstroI18n } from './composer'
|
|
4
5
|
import type { I18nRoutingStrategy } from './router/types'
|
|
@@ -225,6 +226,7 @@ export function useLocaleHead(astro: AstroGlobal, options: LocaleHeadOptions = {
|
|
|
225
226
|
}
|
|
226
227
|
|
|
227
228
|
const currentIso = currentLocaleObj.iso || locale
|
|
229
|
+
const currentOg = resolveOgLocale(currentLocaleObj)
|
|
228
230
|
const currentDir = currentLocaleObj.dir || 'auto'
|
|
229
231
|
|
|
230
232
|
const result: LocaleHeadResult = {
|
|
@@ -309,10 +311,14 @@ export function useLocaleHead(astro: AstroGlobal, options: LocaleHeadOptions = {
|
|
|
309
311
|
}
|
|
310
312
|
|
|
311
313
|
// Open Graph locale
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
314
|
+
if (currentOg) {
|
|
315
|
+
result.meta.push({
|
|
316
|
+
property: 'og:locale',
|
|
317
|
+
content: currentOg,
|
|
318
|
+
})
|
|
319
|
+
} else {
|
|
320
|
+
warnUnresolvedOgLocale(currentLocaleObj, { tag: 'og:locale' })
|
|
321
|
+
}
|
|
316
322
|
|
|
317
323
|
result.meta.push({
|
|
318
324
|
property: 'og:url',
|
|
@@ -322,9 +328,14 @@ export function useLocaleHead(astro: AstroGlobal, options: LocaleHeadOptions = {
|
|
|
322
328
|
// Alternate OG locales
|
|
323
329
|
for (const loc of localesForSeo) {
|
|
324
330
|
if (loc.code === locale) continue
|
|
331
|
+
const ogAlt = resolveOgLocale(loc)
|
|
332
|
+
if (!ogAlt) {
|
|
333
|
+
warnUnresolvedOgLocale(loc, { tag: 'og:locale:alternate' })
|
|
334
|
+
continue
|
|
335
|
+
}
|
|
325
336
|
result.meta.push({
|
|
326
337
|
property: 'og:locale:alternate',
|
|
327
|
-
content:
|
|
338
|
+
content: ogAlt,
|
|
328
339
|
})
|
|
329
340
|
}
|
|
330
341
|
|
package/dist/routing.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Get route name from Astro path
|
|
3
|
-
* Extracts route name from path (e.g., /en/about -> about)
|
|
4
|
-
*/
|
|
5
|
-
export declare function getRouteName(path: string, locales?: string[]): string;
|
|
6
|
-
/**
|
|
7
|
-
* Get locale from path
|
|
8
|
-
* Checks if first segment is a locale code
|
|
9
|
-
*/
|
|
10
|
-
export declare function getLocaleFromPath(path: string, defaultLocale?: string, locales?: string[]): string;
|
|
11
|
-
/**
|
|
12
|
-
* Switch locale in path
|
|
13
|
-
* Replaces or adds locale prefix to path
|
|
14
|
-
*/
|
|
15
|
-
export declare function switchLocalePath(path: string, newLocale: string, locales?: string[], defaultLocale?: string): string;
|
|
16
|
-
/**
|
|
17
|
-
* Localize path with locale prefix
|
|
18
|
-
*/
|
|
19
|
-
export declare function localizePath(path: string, locale: string, locales?: string[], defaultLocale?: string): string;
|
|
20
|
-
/**
|
|
21
|
-
* Remove locale from path
|
|
22
|
-
*/
|
|
23
|
-
export declare function removeLocaleFromPath(path: string, locales?: string[]): string;
|
package/src/routing.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Get route name from Astro path
|
|
3
|
-
* Extracts route name from path (e.g., /en/about -> about)
|
|
4
|
-
*/
|
|
5
|
-
export function getRouteName(path: string, locales: string[] = []): string {
|
|
6
|
-
// Normalize the path
|
|
7
|
-
const cleanPath = path.replace(/^\//, '').replace(/\/$/, '')
|
|
8
|
-
|
|
9
|
-
if (!cleanPath) {
|
|
10
|
-
return 'index'
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const segments = cleanPath.split('/').filter(Boolean)
|
|
14
|
-
|
|
15
|
-
// Remove locale from path if present
|
|
16
|
-
const firstSegment = segments[0]
|
|
17
|
-
if (firstSegment && locales.includes(firstSegment)) {
|
|
18
|
-
segments.shift()
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (segments.length === 0) {
|
|
22
|
-
return 'index'
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return segments.join('-')
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Get locale from path
|
|
30
|
-
* Checks if first segment is a locale code
|
|
31
|
-
*/
|
|
32
|
-
export function getLocaleFromPath(path: string, defaultLocale: string = 'en', locales: string[] = []): string {
|
|
33
|
-
const segments = path.split('/').filter(Boolean)
|
|
34
|
-
const firstSegment = segments[0]
|
|
35
|
-
if (firstSegment && locales.includes(firstSegment)) {
|
|
36
|
-
return firstSegment
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return defaultLocale
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Switch locale in path
|
|
44
|
-
* Replaces or adds locale prefix to path
|
|
45
|
-
*/
|
|
46
|
-
export function switchLocalePath(path: string, newLocale: string, locales: string[] = [], defaultLocale?: string): string {
|
|
47
|
-
const segments = path.split('/').filter(Boolean)
|
|
48
|
-
|
|
49
|
-
// Remove existing locale if present
|
|
50
|
-
const firstSegment = segments[0]
|
|
51
|
-
if (firstSegment && locales.includes(firstSegment)) {
|
|
52
|
-
segments.shift()
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Add new locale if not default or if default should be included
|
|
56
|
-
if (newLocale !== defaultLocale || defaultLocale === undefined) {
|
|
57
|
-
segments.unshift(newLocale)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return `/${segments.join('/')}`
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Localize path with locale prefix
|
|
65
|
-
*/
|
|
66
|
-
export function localizePath(path: string, locale: string, locales: string[] = [], defaultLocale?: string): string {
|
|
67
|
-
const cleanPath = path.replace(/^\//, '').replace(/\/$/, '') || ''
|
|
68
|
-
const segments = cleanPath.split('/').filter(Boolean)
|
|
69
|
-
|
|
70
|
-
// Remove existing locale if present
|
|
71
|
-
const firstSegment = segments[0]
|
|
72
|
-
if (firstSegment && locales.includes(firstSegment)) {
|
|
73
|
-
segments.shift()
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Add locale if not default or if default should be included
|
|
77
|
-
if (locale !== defaultLocale || defaultLocale === undefined) {
|
|
78
|
-
segments.unshift(locale)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return `/${segments.join('/')}`
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Remove locale from path
|
|
86
|
-
*/
|
|
87
|
-
export function removeLocaleFromPath(path: string, locales: string[] = []): string {
|
|
88
|
-
const segments = path.split('/').filter(Boolean)
|
|
89
|
-
const firstSegment = segments[0]
|
|
90
|
-
if (firstSegment && locales.includes(firstSegment)) {
|
|
91
|
-
segments.shift()
|
|
92
|
-
}
|
|
93
|
-
return `/${segments.join('/')}`
|
|
94
|
-
}
|