@i18n-micro/astro 1.1.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/core.d.ts +1 -1
- package/dist/client/index.d.ts +3 -3
- package/dist/client/index.js +9 -9
- package/dist/client/preact.d.ts +1 -1
- package/dist/client/preact.js +36 -21
- package/dist/client/react.d.ts +1 -1
- package/dist/client/react.js +35 -20
- package/dist/client/svelte.d.ts +1 -1
- package/dist/client/svelte.js +8 -14
- package/dist/client/vue.d.ts +1 -1
- package/dist/client/vue.js +11 -17
- package/dist/composer.d.ts +5 -20
- package/dist/env.d.ts +0 -2
- package/dist/index.cjs +4 -4
- package/dist/index.d.ts +11 -11
- package/dist/index.mjs +308 -343
- package/dist/integration.d.ts +2 -2
- package/dist/middleware.d.ts +3 -3
- package/dist/router/adapter.d.ts +1 -1
- package/dist/utils.d.ts +2 -2
- package/package.json +11 -11
- package/src/client/core.ts +5 -11
- package/src/client/index.ts +6 -8
- package/src/client/preact.tsx +74 -61
- package/src/client/react.tsx +73 -61
- package/src/client/svelte.ts +9 -25
- package/src/client/vue.ts +7 -23
- package/src/components/i18n-link.astro +3 -3
- package/src/components/i18n-switcher.astro +3 -3
- package/src/components/i18n-t.astro +3 -13
- package/src/composer.ts +18 -95
- package/src/env.d.ts +0 -2
- package/src/index.ts +35 -42
- package/src/integration.ts +8 -13
- package/src/load-translations.ts +11 -13
- package/src/middleware.ts +15 -25
- package/src/router/adapter.ts +7 -25
- package/src/routing.ts +3 -17
- package/src/utils.ts +18 -23
package/dist/index.mjs
CHANGED
|
@@ -1,78 +1,55 @@
|
|
|
1
|
-
import { BaseI18n as
|
|
2
|
-
import { FormatService as le, defaultPlural as re, interpolate as
|
|
3
|
-
import { existsSync as
|
|
4
|
-
import { resolve as
|
|
5
|
-
class
|
|
1
|
+
import { BaseI18n as I } from "@i18n-micro/core";
|
|
2
|
+
import { FormatService as le, defaultPlural as re, interpolate as ie } from "@i18n-micro/core";
|
|
3
|
+
import { existsSync as R, readdirSync as _, statSync as C, readFileSync as N } from "node:fs";
|
|
4
|
+
import { resolve as O, join as q } from "node:path";
|
|
5
|
+
class S extends I {
|
|
6
6
|
constructor(e) {
|
|
7
|
-
const s = e.
|
|
8
|
-
|
|
9
|
-
routeLocaleCache: {},
|
|
10
|
-
dynamicTranslationsCaches: [],
|
|
11
|
-
serverTranslationCache: {}
|
|
7
|
+
const s = e._storage || {
|
|
8
|
+
translations: /* @__PURE__ */ new Map()
|
|
12
9
|
};
|
|
13
10
|
if (super({
|
|
14
|
-
|
|
11
|
+
storage: s,
|
|
15
12
|
plural: e.plural,
|
|
16
13
|
missingWarn: e.missingWarn,
|
|
17
14
|
missingHandler: e.missingHandler
|
|
18
|
-
}), this.initialMessages = {}, this.
|
|
15
|
+
}), this.initialMessages = {}, this.storage = s, this._locale = e.locale, this._fallbackLocale = e.fallbackLocale || e.locale, this._currentRoute = "general", e.messages) {
|
|
19
16
|
this.initialMessages = { ...e.messages };
|
|
20
|
-
for (const [
|
|
21
|
-
this.helper.loadTranslations(
|
|
17
|
+
for (const [o, i] of Object.entries(e.messages))
|
|
18
|
+
this.helper.loadTranslations(o, i);
|
|
22
19
|
}
|
|
23
20
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
cloneCache(e) {
|
|
30
|
-
const s = (t) => typeof t == "object" && t !== null && "value" in t ? t.value : t, n = s(e.generalLocaleCache), r = s(e.routeLocaleCache), i = s(e.dynamicTranslationsCaches), f = s(e.serverTranslationCache);
|
|
31
|
-
return {
|
|
32
|
-
generalLocaleCache: { ...n },
|
|
33
|
-
routeLocaleCache: { ...r },
|
|
34
|
-
dynamicTranslationsCaches: [...i],
|
|
35
|
-
serverTranslationCache: { ...f }
|
|
36
|
-
};
|
|
21
|
+
cloneStorage(e) {
|
|
22
|
+
const s = /* @__PURE__ */ new Map();
|
|
23
|
+
for (const [o, i] of e.translations)
|
|
24
|
+
s.set(o, { ...i });
|
|
25
|
+
return { translations: s };
|
|
37
26
|
}
|
|
38
|
-
/**
|
|
39
|
-
* Create a request-scoped instance with isolated cache
|
|
40
|
-
* Prevents memory leaks by isolating per-request translations from global cache
|
|
41
|
-
*/
|
|
42
27
|
clone(e) {
|
|
43
|
-
const s = this.
|
|
44
|
-
return new
|
|
28
|
+
const s = this.cloneStorage(this.storage);
|
|
29
|
+
return new S({
|
|
45
30
|
locale: e || this._locale,
|
|
46
31
|
fallbackLocale: this._fallbackLocale,
|
|
47
32
|
plural: this.pluralFunc,
|
|
48
33
|
missingWarn: this.missingWarn,
|
|
49
34
|
missingHandler: this.missingHandler,
|
|
50
|
-
|
|
51
|
-
// Изолированный кэш для предотвращения утечек памяти
|
|
35
|
+
_storage: s
|
|
52
36
|
});
|
|
53
37
|
}
|
|
54
|
-
// Геттер/Сеттер для локали
|
|
55
38
|
get locale() {
|
|
56
39
|
return this._locale;
|
|
57
40
|
}
|
|
58
41
|
set locale(e) {
|
|
59
42
|
this._locale = e;
|
|
60
43
|
}
|
|
61
|
-
// Геттер/Сеттер для fallback локали
|
|
62
44
|
get fallbackLocale() {
|
|
63
45
|
return this._fallbackLocale;
|
|
64
46
|
}
|
|
65
47
|
set fallbackLocale(e) {
|
|
66
48
|
this._fallbackLocale = e;
|
|
67
49
|
}
|
|
68
|
-
// Геттер/Сеттер для текущего роута
|
|
69
|
-
get currentRoute() {
|
|
70
|
-
return this._currentRoute;
|
|
71
|
-
}
|
|
72
50
|
setRoute(e) {
|
|
73
51
|
this._currentRoute = e;
|
|
74
52
|
}
|
|
75
|
-
// --- Implementation of abstract methods ---
|
|
76
53
|
getLocale() {
|
|
77
54
|
return this._locale;
|
|
78
55
|
}
|
|
@@ -82,24 +59,18 @@ class T extends F {
|
|
|
82
59
|
getRoute() {
|
|
83
60
|
return this._currentRoute;
|
|
84
61
|
}
|
|
85
|
-
/**
|
|
86
|
-
* Get route-specific translations for a given locale and route
|
|
87
|
-
* This method encapsulates the cache key format, making it safe to use
|
|
88
|
-
* without direct cache access
|
|
89
|
-
*/
|
|
90
62
|
getRouteTranslations(e, s) {
|
|
91
|
-
const
|
|
92
|
-
return
|
|
63
|
+
const o = `${e}:${s}`;
|
|
64
|
+
return this.storage.translations.get(o) ?? null;
|
|
93
65
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
super.loadTranslationsCore(e, s, n);
|
|
66
|
+
addTranslations(e, s, o = !0) {
|
|
67
|
+
super.loadTranslationsCore(e, s, o);
|
|
97
68
|
}
|
|
98
|
-
addRouteTranslations(e, s,
|
|
99
|
-
super.loadRouteTranslationsCore(e, s,
|
|
69
|
+
addRouteTranslations(e, s, o, i = !0) {
|
|
70
|
+
super.loadRouteTranslationsCore(e, s, o, i);
|
|
100
71
|
}
|
|
101
|
-
mergeTranslations(e, s,
|
|
102
|
-
this.helper.mergeTranslation(e, s,
|
|
72
|
+
mergeTranslations(e, s, o) {
|
|
73
|
+
this.helper.mergeTranslation(e, s, o, !0);
|
|
103
74
|
}
|
|
104
75
|
mergeGlobalTranslations(e, s) {
|
|
105
76
|
this.helper.mergeGlobalTranslation(e, s, !0);
|
|
@@ -107,49 +78,44 @@ class T extends F {
|
|
|
107
78
|
clearCache() {
|
|
108
79
|
const e = { ...this.initialMessages };
|
|
109
80
|
if (super.clearCache(), Object.keys(e).length > 0)
|
|
110
|
-
for (const [s,
|
|
111
|
-
this.helper.loadTranslations(s,
|
|
81
|
+
for (const [s, o] of Object.entries(e))
|
|
82
|
+
this.helper.loadTranslations(s, o);
|
|
112
83
|
}
|
|
113
84
|
}
|
|
114
85
|
let j = null;
|
|
115
86
|
function v() {
|
|
116
87
|
return j;
|
|
117
88
|
}
|
|
118
|
-
function U(
|
|
119
|
-
const {
|
|
120
|
-
|
|
121
|
-
fallbackLocale: s,
|
|
122
|
-
translationDir: n,
|
|
123
|
-
routingStrategy: r
|
|
124
|
-
} = a;
|
|
125
|
-
return j = r || null, {
|
|
89
|
+
function U(n) {
|
|
90
|
+
const { locale: e, fallbackLocale: s, translationDir: o, routingStrategy: i } = n;
|
|
91
|
+
return j = i || null, {
|
|
126
92
|
name: "@i18n-micro/astro",
|
|
127
93
|
hooks: {
|
|
128
94
|
// 1. Настройка Vite (Виртуальный модуль) происходит здесь
|
|
129
|
-
"astro:config:setup": (
|
|
130
|
-
const { updateConfig: f } =
|
|
95
|
+
"astro:config:setup": (c) => {
|
|
96
|
+
const { updateConfig: f } = c, t = "virtual:i18n-micro/config", l = `\0${t}`, r = {
|
|
131
97
|
defaultLocale: e,
|
|
132
98
|
fallbackLocale: s || e,
|
|
133
|
-
locales:
|
|
134
|
-
localeCodes: (
|
|
135
|
-
translationDir:
|
|
136
|
-
autoDetect:
|
|
137
|
-
redirectToDefault:
|
|
138
|
-
localeCookie:
|
|
139
|
-
missingWarn:
|
|
99
|
+
locales: n.locales || [],
|
|
100
|
+
localeCodes: (n.locales || []).map((a) => a.code),
|
|
101
|
+
translationDir: o || null,
|
|
102
|
+
autoDetect: n.autoDetect ?? !0,
|
|
103
|
+
redirectToDefault: n.redirectToDefault ?? !1,
|
|
104
|
+
localeCookie: n.localeCookie === null ? null : n.localeCookie || "i18n-locale",
|
|
105
|
+
missingWarn: n.missingWarn ?? !1
|
|
140
106
|
};
|
|
141
107
|
f({
|
|
142
108
|
vite: {
|
|
143
109
|
plugins: [
|
|
144
110
|
{
|
|
145
111
|
name: "vite-plugin-i18n-micro-config",
|
|
146
|
-
resolveId(
|
|
147
|
-
if (
|
|
112
|
+
resolveId(a) {
|
|
113
|
+
if (a === t)
|
|
148
114
|
return l;
|
|
149
115
|
},
|
|
150
|
-
load(
|
|
151
|
-
if (
|
|
152
|
-
return `export const config = ${JSON.stringify(
|
|
116
|
+
load(a) {
|
|
117
|
+
if (a === l)
|
|
118
|
+
return `export const config = ${JSON.stringify(r)}`;
|
|
153
119
|
}
|
|
154
120
|
}
|
|
155
121
|
]
|
|
@@ -157,8 +123,8 @@ function U(a) {
|
|
|
157
123
|
});
|
|
158
124
|
},
|
|
159
125
|
// 2. Инъекция типов происходит здесь (согласно документации Astro)
|
|
160
|
-
"astro:config:done": (
|
|
161
|
-
const { injectTypes: f } =
|
|
126
|
+
"astro:config:done": (c) => {
|
|
127
|
+
const { injectTypes: f } = c;
|
|
162
128
|
f({
|
|
163
129
|
filename: "i18n-micro-env.d.ts",
|
|
164
130
|
content: `
|
|
@@ -173,8 +139,8 @@ function U(a) {
|
|
|
173
139
|
translationDir: string | null;
|
|
174
140
|
autoDetect: boolean;
|
|
175
141
|
redirectToDefault: boolean;
|
|
176
|
-
localeCookie: string;
|
|
177
|
-
missingWarn: boolean;
|
|
142
|
+
localeCookie: string | null;
|
|
143
|
+
missingWarn: boolean | null;
|
|
178
144
|
}
|
|
179
145
|
}
|
|
180
146
|
`
|
|
@@ -183,74 +149,106 @@ function U(a) {
|
|
|
183
149
|
}
|
|
184
150
|
};
|
|
185
151
|
}
|
|
186
|
-
function E(
|
|
187
|
-
return new
|
|
152
|
+
function E(n) {
|
|
153
|
+
return new S(n);
|
|
154
|
+
}
|
|
155
|
+
function M(n) {
|
|
156
|
+
const { translationDir: e, rootDir: s = process.cwd(), disablePageLocales: o = !1 } = n, i = O(s, e);
|
|
157
|
+
if (!R(i))
|
|
158
|
+
return console.warn(`[i18n] Translation directory not found: ${i}`), { general: {}, routes: {} };
|
|
159
|
+
const c = {}, f = {}, t = (l, r = "") => {
|
|
160
|
+
if (!R(l)) return;
|
|
161
|
+
const a = _(l);
|
|
162
|
+
for (const u of a) {
|
|
163
|
+
const h = q(l, u);
|
|
164
|
+
if (C(h).isDirectory())
|
|
165
|
+
u === "pages" && !o ? t(h, "") : r || o ? t(h, r) : t(h, u);
|
|
166
|
+
else if (u.endsWith(".json")) {
|
|
167
|
+
const m = u.replace(".json", "");
|
|
168
|
+
try {
|
|
169
|
+
const g = N(h, "utf-8"), p = JSON.parse(g);
|
|
170
|
+
r && !o ? (f[r] || (f[r] = {}), f[r][m] = p) : c[m] = p;
|
|
171
|
+
} catch (g) {
|
|
172
|
+
console.error(`[i18n] Failed to load translation file: ${h}`, g);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
return t(i), { general: c, routes: f };
|
|
178
|
+
}
|
|
179
|
+
function J(n, e) {
|
|
180
|
+
const { general: s, routes: o } = M(e);
|
|
181
|
+
for (const [i, c] of Object.entries(s))
|
|
182
|
+
n.addTranslations(i, c, !1);
|
|
183
|
+
for (const [i, c] of Object.entries(o))
|
|
184
|
+
for (const [f, t] of Object.entries(c))
|
|
185
|
+
n.addRouteTranslations(f, i, t, !1);
|
|
188
186
|
}
|
|
189
|
-
function
|
|
187
|
+
function V(n) {
|
|
190
188
|
const {
|
|
191
189
|
i18n: e,
|
|
192
190
|
// Это глобальный синглтон с кэшем
|
|
193
191
|
defaultLocale: s,
|
|
194
|
-
locales:
|
|
195
|
-
localeObjects:
|
|
196
|
-
autoDetect:
|
|
192
|
+
locales: o,
|
|
193
|
+
localeObjects: i,
|
|
194
|
+
autoDetect: c = !0,
|
|
197
195
|
redirectToDefault: f = !1,
|
|
198
196
|
routingStrategy: t
|
|
199
|
-
} =
|
|
200
|
-
return async (
|
|
201
|
-
if (
|
|
202
|
-
return
|
|
203
|
-
const u =
|
|
197
|
+
} = n, l = t || v();
|
|
198
|
+
return async (r, a) => {
|
|
199
|
+
if (r.locals.locale && r.locals.i18n)
|
|
200
|
+
return a();
|
|
201
|
+
const u = r.url, h = u.pathname;
|
|
204
202
|
if (!l) {
|
|
205
|
-
const
|
|
206
|
-
return
|
|
203
|
+
const y = e.clone(s), B = h === "/" || h === "" ? "index" : h.split("/").filter(Boolean).join("-");
|
|
204
|
+
return y.setRoute(B), r.locals.i18n = y, r.locals.locale = s, r.locals.defaultLocale = s, r.locals.locales = i || o.map((F) => ({ code: F })), r.locals.currentUrl = u, a();
|
|
207
205
|
}
|
|
208
206
|
const d = {
|
|
209
207
|
...l,
|
|
210
|
-
getCurrentPath: () =>
|
|
208
|
+
getCurrentPath: () => h,
|
|
211
209
|
getRoute: () => ({
|
|
212
210
|
fullPath: u.pathname + u.search,
|
|
213
211
|
query: Object.fromEntries(u.searchParams)
|
|
214
212
|
})
|
|
215
|
-
},
|
|
216
|
-
let
|
|
217
|
-
p &&
|
|
218
|
-
const
|
|
219
|
-
return
|
|
213
|
+
}, g = h.split("/").filter(Boolean)[0], p = g !== void 0 && o.includes(g);
|
|
214
|
+
let P;
|
|
215
|
+
p && g ? P = g : d.getLocaleFromPath ? P = d.getLocaleFromPath(h, s, o) : P = s;
|
|
216
|
+
const L = e.clone(P), b = d.getRouteName ? d.getRouteName(h, o) : "general";
|
|
217
|
+
return L.setRoute(b), r.locals.i18n = L, r.locals.locale = P, r.locals.defaultLocale = s, r.locals.locales = i || o.map((y) => ({ code: y })), r.locals.currentUrl = u, r.locals.routingStrategy = d, a();
|
|
220
218
|
};
|
|
221
219
|
}
|
|
222
|
-
function
|
|
223
|
-
const e = [], s =
|
|
224
|
-
for (const
|
|
225
|
-
const [
|
|
226
|
-
if (Number.parseFloat(
|
|
227
|
-
const t =
|
|
228
|
-
t && (e.push(t),
|
|
220
|
+
function W(n) {
|
|
221
|
+
const e = [], s = n.split(",");
|
|
222
|
+
for (const o of s) {
|
|
223
|
+
const [i, c = "1.0"] = o.trim().split(";q=");
|
|
224
|
+
if (Number.parseFloat(c) > 0 && i) {
|
|
225
|
+
const t = i.split("-")[0]?.toLowerCase();
|
|
226
|
+
t && (e.push(t), i !== t && e.push(i.toLowerCase()));
|
|
229
227
|
}
|
|
230
228
|
}
|
|
231
229
|
return e;
|
|
232
230
|
}
|
|
233
|
-
function K(
|
|
231
|
+
function K(n, e, s, o, i, c = "i18n-locale") {
|
|
234
232
|
const f = v();
|
|
235
|
-
let t =
|
|
233
|
+
let t = o;
|
|
236
234
|
if (f?.getLocaleFromPath)
|
|
237
|
-
t = f.getLocaleFromPath(
|
|
235
|
+
t = f.getLocaleFromPath(n, o, i);
|
|
238
236
|
else {
|
|
239
|
-
const
|
|
240
|
-
|
|
237
|
+
const r = n.split("/").filter(Boolean)[0];
|
|
238
|
+
r && i.includes(r) && (t = r);
|
|
241
239
|
}
|
|
242
|
-
if (t ===
|
|
243
|
-
const l = e.get(
|
|
244
|
-
l &&
|
|
240
|
+
if (c !== null && t === o && e.get(c)) {
|
|
241
|
+
const l = e.get(c)?.value;
|
|
242
|
+
l && i.includes(l) && (t = l);
|
|
245
243
|
}
|
|
246
|
-
if (t ===
|
|
244
|
+
if (t === o)
|
|
247
245
|
try {
|
|
248
246
|
const l = s.get("accept-language");
|
|
249
247
|
if (l) {
|
|
250
|
-
const
|
|
251
|
-
for (const
|
|
252
|
-
if (
|
|
253
|
-
t =
|
|
248
|
+
const r = W(l);
|
|
249
|
+
for (const a of r)
|
|
250
|
+
if (i.includes(a)) {
|
|
251
|
+
t = a;
|
|
254
252
|
break;
|
|
255
253
|
}
|
|
256
254
|
}
|
|
@@ -258,35 +256,118 @@ function K(a, e, s, n, r, i = "i18n-locale") {
|
|
|
258
256
|
}
|
|
259
257
|
return t;
|
|
260
258
|
}
|
|
261
|
-
function
|
|
262
|
-
const
|
|
259
|
+
function Q(n, e, s) {
|
|
260
|
+
const o = n.map((a) => a.code), i = (a, u = []) => {
|
|
261
|
+
const h = a.replace(/^\//, "").replace(/\/$/, "");
|
|
262
|
+
if (!h)
|
|
263
|
+
return "index";
|
|
264
|
+
const d = h.split("/").filter(Boolean), m = d[0];
|
|
265
|
+
return m && u.includes(m) && d.shift(), d.length === 0 ? "index" : d.join("-");
|
|
266
|
+
}, c = (a, u = "en", h = []) => {
|
|
267
|
+
const m = a.split("/").filter(Boolean)[0];
|
|
268
|
+
return m && h.includes(m) ? m : u;
|
|
269
|
+
}, f = (a, u, h = [], d) => {
|
|
270
|
+
const m = a.split("/").filter(Boolean), g = m[0];
|
|
271
|
+
return g && h.includes(g) && m.shift(), (u !== d || d === void 0) && m.unshift(u), `/${m.join("/")}`;
|
|
272
|
+
}, t = (a, u, h = [], d) => {
|
|
273
|
+
const g = (a.replace(/^\//, "").replace(/\/$/, "") || "").split("/").filter(Boolean), p = g[0];
|
|
274
|
+
return p && h.includes(p) && g.shift(), (u !== d || d === void 0) && g.unshift(u), `/${g.join("/")}`;
|
|
275
|
+
};
|
|
276
|
+
return {
|
|
277
|
+
getCurrentPath: () => s ? s().pathname : typeof window < "u" ? window.location.pathname : "/",
|
|
278
|
+
getRouteName: i,
|
|
279
|
+
getLocaleFromPath: c,
|
|
280
|
+
switchLocalePath: f,
|
|
281
|
+
localizePath: t,
|
|
282
|
+
removeLocaleFromPath: (a, u = []) => {
|
|
283
|
+
const h = a.split("/").filter(Boolean), d = h[0];
|
|
284
|
+
return d && u.includes(d) && h.shift(), `/${h.join("/")}`;
|
|
285
|
+
},
|
|
286
|
+
resolvePath: (a, u) => {
|
|
287
|
+
const h = typeof a == "string" ? a : a.path || "/";
|
|
288
|
+
return t(h, u, o, e);
|
|
289
|
+
},
|
|
290
|
+
getRoute: () => {
|
|
291
|
+
if (s) {
|
|
292
|
+
const a = s();
|
|
293
|
+
return {
|
|
294
|
+
fullPath: a.pathname + a.search,
|
|
295
|
+
query: Object.fromEntries(a.searchParams)
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
if (typeof window < "u") {
|
|
299
|
+
const a = new URL(window.location.href);
|
|
300
|
+
return {
|
|
301
|
+
fullPath: a.pathname + a.search,
|
|
302
|
+
query: Object.fromEntries(a.searchParams)
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
fullPath: "/",
|
|
307
|
+
query: {}
|
|
308
|
+
};
|
|
309
|
+
},
|
|
310
|
+
// Optional: client-side navigation for islands
|
|
311
|
+
push: (a) => {
|
|
312
|
+
typeof window < "u" && (window.location.href = a.path);
|
|
313
|
+
},
|
|
314
|
+
replace: (a) => {
|
|
315
|
+
typeof window < "u" && window.location.replace(a.path);
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
function X(n, e = []) {
|
|
320
|
+
const s = n.replace(/^\//, "").replace(/\/$/, "");
|
|
321
|
+
if (!s)
|
|
322
|
+
return "index";
|
|
323
|
+
const o = s.split("/").filter(Boolean), i = o[0];
|
|
324
|
+
return i && e.includes(i) && o.shift(), o.length === 0 ? "index" : o.join("-");
|
|
325
|
+
}
|
|
326
|
+
function Y(n, e = "en", s = []) {
|
|
327
|
+
const i = n.split("/").filter(Boolean)[0];
|
|
328
|
+
return i && s.includes(i) ? i : e;
|
|
329
|
+
}
|
|
330
|
+
function Z(n, e, s = [], o) {
|
|
331
|
+
const i = n.split("/").filter(Boolean), c = i[0];
|
|
332
|
+
return c && s.includes(c) && i.shift(), (e !== o || o === void 0) && i.unshift(e), `/${i.join("/")}`;
|
|
333
|
+
}
|
|
334
|
+
function x(n, e, s = [], o) {
|
|
335
|
+
const c = (n.replace(/^\//, "").replace(/\/$/, "") || "").split("/").filter(Boolean), f = c[0];
|
|
336
|
+
return f && s.includes(f) && c.shift(), (e !== o || o === void 0) && c.unshift(e), `/${c.join("/")}`;
|
|
337
|
+
}
|
|
338
|
+
function ee(n, e = []) {
|
|
339
|
+
const s = n.split("/").filter(Boolean), o = s[0];
|
|
340
|
+
return o && e.includes(o) && s.shift(), `/${s.join("/")}`;
|
|
341
|
+
}
|
|
342
|
+
function k(n) {
|
|
343
|
+
const e = n.locals.i18n;
|
|
263
344
|
if (!e)
|
|
264
345
|
throw new Error("i18n instance not found. Make sure i18n middleware is configured.");
|
|
265
346
|
return e;
|
|
266
347
|
}
|
|
267
|
-
function
|
|
268
|
-
return
|
|
348
|
+
function T(n) {
|
|
349
|
+
return n.locals.locale || "en";
|
|
269
350
|
}
|
|
270
|
-
function
|
|
271
|
-
return
|
|
351
|
+
function w(n) {
|
|
352
|
+
return n.locals.defaultLocale || "en";
|
|
272
353
|
}
|
|
273
|
-
function
|
|
274
|
-
return
|
|
354
|
+
function $(n) {
|
|
355
|
+
return n.locals.locales || [];
|
|
275
356
|
}
|
|
276
|
-
function
|
|
277
|
-
return
|
|
357
|
+
function D(n) {
|
|
358
|
+
return n.locals.routingStrategy || null;
|
|
278
359
|
}
|
|
279
|
-
function
|
|
280
|
-
const e =
|
|
360
|
+
function te(n) {
|
|
361
|
+
const e = k(n), s = T(n), o = w(n), i = $(n), c = i.map((t) => t.code), f = D(n);
|
|
281
362
|
return {
|
|
282
363
|
// Current locale
|
|
283
364
|
locale: s,
|
|
284
|
-
defaultLocale:
|
|
285
|
-
locales:
|
|
365
|
+
defaultLocale: o,
|
|
366
|
+
locales: i,
|
|
286
367
|
// Translation methods
|
|
287
|
-
t: (t, l,
|
|
288
|
-
ts: (t, l,
|
|
289
|
-
tc: (t, l,
|
|
368
|
+
t: (t, l, r, a) => e.t(t, l, r, a),
|
|
369
|
+
ts: (t, l, r, a) => e.ts(t, l, r, a),
|
|
370
|
+
tc: (t, l, r) => e.tc(t, l, r),
|
|
290
371
|
tn: (t, l) => e.tn(t, l),
|
|
291
372
|
td: (t, l) => e.td(t, l),
|
|
292
373
|
tdr: (t, l) => e.tdr(t, l),
|
|
@@ -294,50 +375,50 @@ function Q(a) {
|
|
|
294
375
|
// Route management
|
|
295
376
|
getRoute: () => e.getRoute(),
|
|
296
377
|
getRouteName: (t) => {
|
|
297
|
-
const l = t ||
|
|
378
|
+
const l = t || n.url.pathname;
|
|
298
379
|
if (f?.getRouteName)
|
|
299
|
-
return f.getRouteName(l,
|
|
300
|
-
const
|
|
301
|
-
if (!
|
|
302
|
-
const
|
|
303
|
-
return u &&
|
|
380
|
+
return f.getRouteName(l, c);
|
|
381
|
+
const r = l.replace(/^\//, "").replace(/\/$/, "");
|
|
382
|
+
if (!r) return "index";
|
|
383
|
+
const a = r.split("/").filter(Boolean), u = a[0];
|
|
384
|
+
return u && c.includes(u) && a.shift(), a.length === 0 ? "index" : a.join("-");
|
|
304
385
|
},
|
|
305
386
|
getLocaleFromPath: (t) => {
|
|
306
|
-
const l = t ||
|
|
387
|
+
const l = t || n.url.pathname;
|
|
307
388
|
if (f?.getLocaleFromPath)
|
|
308
|
-
return f.getLocaleFromPath(l,
|
|
309
|
-
const
|
|
310
|
-
return
|
|
389
|
+
return f.getLocaleFromPath(l, o, c);
|
|
390
|
+
const a = l.split("/").filter(Boolean)[0];
|
|
391
|
+
return a && c.includes(a) ? a : o;
|
|
311
392
|
},
|
|
312
393
|
// Path utilities
|
|
313
394
|
switchLocalePath: (t) => {
|
|
314
395
|
if (f?.switchLocalePath)
|
|
315
|
-
return f.switchLocalePath(
|
|
316
|
-
const l =
|
|
317
|
-
return
|
|
396
|
+
return f.switchLocalePath(n.url.pathname, t, c, o);
|
|
397
|
+
const l = n.url.pathname.split("/").filter(Boolean), r = l[0];
|
|
398
|
+
return r && c.includes(r) && l.shift(), t !== o && l.unshift(t), `/${l.join("/")}`;
|
|
318
399
|
},
|
|
319
400
|
localizePath: (t, l) => {
|
|
320
401
|
if (f?.localizePath)
|
|
321
|
-
return f.localizePath(t, l || s,
|
|
322
|
-
const
|
|
323
|
-
return u &&
|
|
402
|
+
return f.localizePath(t, l || s, c, o);
|
|
403
|
+
const a = (t.replace(/^\//, "").replace(/\/$/, "") || "").split("/").filter(Boolean), u = a[0];
|
|
404
|
+
return u && c.includes(u) && a.shift(), l && l !== o && a.unshift(l), `/${a.join("/")}`;
|
|
324
405
|
},
|
|
325
406
|
// Get i18n instance
|
|
326
407
|
getI18n: () => e,
|
|
327
408
|
// Get base path without locale (for rewrite)
|
|
328
409
|
getBasePath: (t) => {
|
|
329
|
-
const
|
|
330
|
-
return u &&
|
|
410
|
+
const a = (t || n.url).pathname.split("/").filter(Boolean), u = a[0];
|
|
411
|
+
return u && c.includes(u) && a.shift(), a.length > 0 ? `/${a.join("/")}` : "/";
|
|
331
412
|
},
|
|
332
413
|
// Translation management
|
|
333
|
-
addTranslations: (t, l,
|
|
334
|
-
e.addTranslations(t, l,
|
|
414
|
+
addTranslations: (t, l, r = !0) => {
|
|
415
|
+
e.addTranslations(t, l, r);
|
|
335
416
|
},
|
|
336
|
-
addRouteTranslations: (t, l,
|
|
337
|
-
e.addRouteTranslations(t, l,
|
|
417
|
+
addRouteTranslations: (t, l, r, a = !0) => {
|
|
418
|
+
e.addRouteTranslations(t, l, r, a);
|
|
338
419
|
},
|
|
339
|
-
mergeTranslations: (t, l,
|
|
340
|
-
e.mergeTranslations(t, l,
|
|
420
|
+
mergeTranslations: (t, l, r) => {
|
|
421
|
+
e.mergeTranslations(t, l, r);
|
|
341
422
|
},
|
|
342
423
|
mergeGlobalTranslations: (t, l) => {
|
|
343
424
|
e.mergeGlobalTranslations(t, l);
|
|
@@ -347,228 +428,112 @@ function Q(a) {
|
|
|
347
428
|
}
|
|
348
429
|
};
|
|
349
430
|
}
|
|
350
|
-
function
|
|
351
|
-
const {
|
|
352
|
-
baseUrl: s = "/",
|
|
353
|
-
addDirAttribute: n = !0,
|
|
354
|
-
addSeoAttributes: r = !0
|
|
355
|
-
} = e, i = S(a), f = R(a), t = k(a), l = t.find((h) => h.code === i);
|
|
431
|
+
function ne(n, e = {}) {
|
|
432
|
+
const { baseUrl: s = "/", addDirAttribute: o = !0, addSeoAttributes: i = !0 } = e, c = T(n), f = w(n), t = $(n), l = t.find((g) => g.code === c);
|
|
356
433
|
if (!l)
|
|
357
434
|
return { htmlAttrs: {}, link: [], meta: [] };
|
|
358
|
-
const
|
|
435
|
+
const r = l.iso || c, a = l.dir || "auto", u = {
|
|
359
436
|
htmlAttrs: {
|
|
360
|
-
lang:
|
|
361
|
-
...
|
|
437
|
+
lang: r,
|
|
438
|
+
...o ? { dir: a } : {}
|
|
362
439
|
},
|
|
363
440
|
link: [],
|
|
364
441
|
meta: []
|
|
365
442
|
};
|
|
366
|
-
if (!
|
|
443
|
+
if (!i)
|
|
367
444
|
return u;
|
|
368
|
-
const
|
|
445
|
+
const h = `${s}${n.url.pathname}`;
|
|
369
446
|
u.link.push({
|
|
370
447
|
rel: "canonical",
|
|
371
|
-
href:
|
|
448
|
+
href: h
|
|
372
449
|
});
|
|
373
|
-
const d =
|
|
374
|
-
for (const
|
|
375
|
-
if (
|
|
376
|
-
let p =
|
|
450
|
+
const d = D(n), m = t.map((g) => g.code);
|
|
451
|
+
for (const g of t) {
|
|
452
|
+
if (g.code === c) continue;
|
|
453
|
+
let p = n.url.pathname;
|
|
377
454
|
if (d?.switchLocalePath)
|
|
378
|
-
p = d.switchLocalePath(
|
|
455
|
+
p = d.switchLocalePath(n.url.pathname, g.code, m, f);
|
|
379
456
|
else {
|
|
380
|
-
const
|
|
381
|
-
|
|
457
|
+
const L = n.url.pathname.split("/").filter(Boolean), b = L[0];
|
|
458
|
+
b && m.includes(b) && L.shift(), g.code !== f && L.unshift(g.code), p = `/${L.join("/")}`;
|
|
382
459
|
}
|
|
383
|
-
const
|
|
460
|
+
const P = `${s}${p}`;
|
|
384
461
|
u.link.push({
|
|
385
462
|
rel: "alternate",
|
|
386
|
-
href:
|
|
387
|
-
hreflang:
|
|
388
|
-
}),
|
|
463
|
+
href: P,
|
|
464
|
+
hreflang: g.code
|
|
465
|
+
}), g.iso && g.iso !== g.code && u.link.push({
|
|
389
466
|
rel: "alternate",
|
|
390
|
-
href:
|
|
391
|
-
hreflang:
|
|
467
|
+
href: P,
|
|
468
|
+
hreflang: g.iso
|
|
392
469
|
});
|
|
393
470
|
}
|
|
394
471
|
u.meta.push({
|
|
395
472
|
property: "og:locale",
|
|
396
|
-
content:
|
|
473
|
+
content: r
|
|
397
474
|
}), u.meta.push({
|
|
398
475
|
property: "og:url",
|
|
399
|
-
content:
|
|
476
|
+
content: h
|
|
400
477
|
});
|
|
401
|
-
for (const
|
|
402
|
-
|
|
478
|
+
for (const g of t)
|
|
479
|
+
g.code !== c && u.meta.push({
|
|
403
480
|
property: "og:locale:alternate",
|
|
404
|
-
content:
|
|
481
|
+
content: g.iso || g.code
|
|
405
482
|
});
|
|
406
483
|
return u;
|
|
407
484
|
}
|
|
408
|
-
function
|
|
409
|
-
const
|
|
410
|
-
let
|
|
411
|
-
for (let
|
|
412
|
-
|
|
413
|
-
|
|
485
|
+
function A(n, e, s) {
|
|
486
|
+
const o = e.split(".");
|
|
487
|
+
let i = n;
|
|
488
|
+
for (let f = 0; f < o.length - 1; f++) {
|
|
489
|
+
const t = o[f];
|
|
490
|
+
i[t] || (i[t] = {}), i = i[t];
|
|
491
|
+
}
|
|
492
|
+
const c = o[o.length - 1];
|
|
493
|
+
c !== void 0 && (i[c] = s);
|
|
414
494
|
}
|
|
415
|
-
function
|
|
416
|
-
const s =
|
|
495
|
+
function oe(n, e) {
|
|
496
|
+
const s = k(n), o = T(n), i = w(n), c = s.getRoute(), f = {};
|
|
417
497
|
if (e && e.length > 0) {
|
|
418
498
|
const t = {};
|
|
419
499
|
for (const l of e) {
|
|
420
|
-
const
|
|
421
|
-
|
|
500
|
+
const r = s.t(l, void 0, void 0, c);
|
|
501
|
+
r != null && r !== l && A(t, l, r);
|
|
422
502
|
}
|
|
423
|
-
Object.keys(t).length > 0 && (f[
|
|
503
|
+
Object.keys(t).length > 0 && (f[c] = t);
|
|
424
504
|
} else {
|
|
425
|
-
const t = s.getRouteTranslations(
|
|
426
|
-
t && (f[
|
|
505
|
+
const t = s.getRouteTranslations(o, c);
|
|
506
|
+
t && (f[c] = t);
|
|
427
507
|
}
|
|
428
508
|
return {
|
|
429
|
-
locale:
|
|
430
|
-
fallbackLocale:
|
|
431
|
-
currentRoute:
|
|
509
|
+
locale: o,
|
|
510
|
+
fallbackLocale: i,
|
|
511
|
+
currentRoute: c,
|
|
432
512
|
translations: f
|
|
433
513
|
};
|
|
434
514
|
}
|
|
435
|
-
function Z(a, e, s) {
|
|
436
|
-
const n = a.map((o) => o.code), r = (o, u = []) => {
|
|
437
|
-
const g = o.replace(/^\//, "").replace(/\/$/, "");
|
|
438
|
-
if (!g)
|
|
439
|
-
return "index";
|
|
440
|
-
const d = g.split("/").filter(Boolean), m = d[0];
|
|
441
|
-
return m && u.includes(m) && d.shift(), d.length === 0 ? "index" : d.join("-");
|
|
442
|
-
}, i = (o, u = "en", g = []) => {
|
|
443
|
-
const m = o.split("/").filter(Boolean)[0];
|
|
444
|
-
return m && g.includes(m) ? m : u;
|
|
445
|
-
}, f = (o, u, g = [], d) => {
|
|
446
|
-
const m = o.split("/").filter(Boolean), h = m[0];
|
|
447
|
-
return h && g.includes(h) && m.shift(), (u !== d || d === void 0) && m.unshift(u), `/${m.join("/")}`;
|
|
448
|
-
}, t = (o, u, g = [], d) => {
|
|
449
|
-
const h = (o.replace(/^\//, "").replace(/\/$/, "") || "").split("/").filter(Boolean), p = h[0];
|
|
450
|
-
return p && g.includes(p) && h.shift(), (u !== d || d === void 0) && h.unshift(u), `/${h.join("/")}`;
|
|
451
|
-
};
|
|
452
|
-
return {
|
|
453
|
-
getCurrentPath: () => s ? s().pathname : typeof window < "u" ? window.location.pathname : "/",
|
|
454
|
-
getRouteName: r,
|
|
455
|
-
getLocaleFromPath: i,
|
|
456
|
-
switchLocalePath: f,
|
|
457
|
-
localizePath: t,
|
|
458
|
-
removeLocaleFromPath: (o, u = []) => {
|
|
459
|
-
const g = o.split("/").filter(Boolean), d = g[0];
|
|
460
|
-
return d && u.includes(d) && g.shift(), `/${g.join("/")}`;
|
|
461
|
-
},
|
|
462
|
-
resolvePath: (o, u) => {
|
|
463
|
-
const g = typeof o == "string" ? o : o.path || "/";
|
|
464
|
-
return t(g, u, n, e);
|
|
465
|
-
},
|
|
466
|
-
getRoute: () => {
|
|
467
|
-
if (s) {
|
|
468
|
-
const o = s();
|
|
469
|
-
return {
|
|
470
|
-
fullPath: o.pathname + o.search,
|
|
471
|
-
query: Object.fromEntries(o.searchParams)
|
|
472
|
-
};
|
|
473
|
-
}
|
|
474
|
-
if (typeof window < "u") {
|
|
475
|
-
const o = new URL(window.location.href);
|
|
476
|
-
return {
|
|
477
|
-
fullPath: o.pathname + o.search,
|
|
478
|
-
query: Object.fromEntries(o.searchParams)
|
|
479
|
-
};
|
|
480
|
-
}
|
|
481
|
-
return {
|
|
482
|
-
fullPath: "/",
|
|
483
|
-
query: {}
|
|
484
|
-
};
|
|
485
|
-
},
|
|
486
|
-
// Optional: client-side navigation for islands
|
|
487
|
-
push: (o) => {
|
|
488
|
-
typeof window < "u" && (window.location.href = o.path);
|
|
489
|
-
},
|
|
490
|
-
replace: (o) => {
|
|
491
|
-
typeof window < "u" && window.location.replace(o.path);
|
|
492
|
-
}
|
|
493
|
-
};
|
|
494
|
-
}
|
|
495
|
-
function V(a, e = []) {
|
|
496
|
-
const s = a.replace(/^\//, "").replace(/\/$/, "");
|
|
497
|
-
if (!s)
|
|
498
|
-
return "index";
|
|
499
|
-
const n = s.split("/").filter(Boolean), r = n[0];
|
|
500
|
-
return r && e.includes(r) && n.shift(), n.length === 0 ? "index" : n.join("-");
|
|
501
|
-
}
|
|
502
|
-
function x(a, e = "en", s = []) {
|
|
503
|
-
const r = a.split("/").filter(Boolean)[0];
|
|
504
|
-
return r && s.includes(r) ? r : e;
|
|
505
|
-
}
|
|
506
|
-
function ee(a, e, s = [], n) {
|
|
507
|
-
const r = a.split("/").filter(Boolean), i = r[0];
|
|
508
|
-
return i && s.includes(i) && r.shift(), (e !== n || n === void 0) && r.unshift(e), `/${r.join("/")}`;
|
|
509
|
-
}
|
|
510
|
-
function te(a, e, s = [], n) {
|
|
511
|
-
const i = (a.replace(/^\//, "").replace(/\/$/, "") || "").split("/").filter(Boolean), f = i[0];
|
|
512
|
-
return f && s.includes(f) && i.shift(), (e !== n || n === void 0) && i.unshift(e), `/${i.join("/")}`;
|
|
513
|
-
}
|
|
514
|
-
function ne(a, e = []) {
|
|
515
|
-
const s = a.split("/").filter(Boolean), n = s[0];
|
|
516
|
-
return n && e.includes(n) && s.shift(), `/${s.join("/")}`;
|
|
517
|
-
}
|
|
518
|
-
function W(a) {
|
|
519
|
-
const { translationDir: e, rootDir: s = process.cwd(), disablePageLocales: n = !1 } = a, r = q(s, e);
|
|
520
|
-
if (!C(r))
|
|
521
|
-
return console.warn(`[i18n] Translation directory not found: ${r}`), { general: {}, routes: {} };
|
|
522
|
-
const i = {}, f = {}, t = (l, c = "") => {
|
|
523
|
-
if (!C(l)) return;
|
|
524
|
-
const o = I(l);
|
|
525
|
-
for (const u of o) {
|
|
526
|
-
const g = O(l, u);
|
|
527
|
-
if (_(g).isDirectory())
|
|
528
|
-
u === "pages" && !n ? t(g, "") : c || n ? t(g, c) : t(g, u);
|
|
529
|
-
else if (u.endsWith(".json")) {
|
|
530
|
-
const m = u.replace(".json", "");
|
|
531
|
-
try {
|
|
532
|
-
const h = N(g, "utf-8"), p = JSON.parse(h);
|
|
533
|
-
c && !n ? (f[c] || (f[c] = {}), f[c][m] = p) : i[m] = p;
|
|
534
|
-
} catch (h) {
|
|
535
|
-
console.error(`[i18n] Failed to load translation file: ${g}`, h);
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
};
|
|
540
|
-
return t(r), { general: i, routes: f };
|
|
541
|
-
}
|
|
542
|
-
function ae(a, e) {
|
|
543
|
-
const { general: s, routes: n } = W(e);
|
|
544
|
-
for (const [r, i] of Object.entries(s))
|
|
545
|
-
a.addTranslations(r, i, !1);
|
|
546
|
-
for (const [r, i] of Object.entries(n))
|
|
547
|
-
for (const [f, t] of Object.entries(i))
|
|
548
|
-
a.addRouteTranslations(f, r, t, !1);
|
|
549
|
-
}
|
|
550
515
|
export {
|
|
551
|
-
|
|
516
|
+
S as AstroI18n,
|
|
552
517
|
le as FormatService,
|
|
553
|
-
|
|
518
|
+
Q as createAstroRouterAdapter,
|
|
554
519
|
E as createI18n,
|
|
555
|
-
|
|
520
|
+
V as createI18nMiddleware,
|
|
556
521
|
re as defaultPlural,
|
|
557
522
|
K as detectLocale,
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
523
|
+
w as getDefaultLocale,
|
|
524
|
+
k as getI18n,
|
|
525
|
+
oe as getI18nProps,
|
|
526
|
+
T as getLocale,
|
|
527
|
+
Y as getLocaleFromPath,
|
|
528
|
+
$ as getLocales,
|
|
529
|
+
X as getRouteName,
|
|
565
530
|
U as i18nIntegration,
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
531
|
+
ie as interpolate,
|
|
532
|
+
M as loadTranslationsFromDir,
|
|
533
|
+
J as loadTranslationsIntoI18n,
|
|
534
|
+
x as localizePath,
|
|
535
|
+
ee as removeLocaleFromPath,
|
|
536
|
+
Z as switchLocalePath,
|
|
537
|
+
te as useI18n,
|
|
538
|
+
ne as useLocaleHead
|
|
574
539
|
};
|