@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/index.mjs CHANGED
@@ -1,78 +1,55 @@
1
- import { BaseI18n as F } from "@i18n-micro/core";
2
- import { FormatService as le, defaultPlural as re, interpolate as ce } from "@i18n-micro/core";
3
- import { existsSync as C, readdirSync as I, statSync as _, readFileSync as N } from "node:fs";
4
- import { resolve as q, join as O } from "node:path";
5
- class T extends F {
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._cache || {
8
- generalLocaleCache: {},
9
- routeLocaleCache: {},
10
- dynamicTranslationsCaches: [],
11
- serverTranslationCache: {}
7
+ const s = e._storage || {
8
+ translations: /* @__PURE__ */ new Map()
12
9
  };
13
10
  if (super({
14
- cache: s,
11
+ storage: s,
15
12
  plural: e.plural,
16
13
  missingWarn: e.missingWarn,
17
14
  missingHandler: e.missingHandler
18
- }), this.initialMessages = {}, this.cache = s, this._locale = e.locale, this._fallbackLocale = e.fallbackLocale || e.locale, this._currentRoute = "general", e.messages) {
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 [n, r] of Object.entries(e.messages))
21
- this.helper.loadTranslations(n, r);
17
+ for (const [o, i] of Object.entries(e.messages))
18
+ this.helper.loadTranslations(o, i);
22
19
  }
23
20
  }
24
- /**
25
- * Clone cache with shallow copy to prevent memory leaks
26
- * Each request-scoped instance gets its own cache structure,
27
- * but can read from the global cache (read-only access to existing translations)
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.cloneCache(this.cache);
44
- return new T({
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
- _cache: s
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 n = `${e}:${s}`, r = this.cache.routeLocaleCache;
92
- return r && typeof r == "object" && !Array.isArray(r) && r[n] || null;
63
+ const o = `${e}:${s}`;
64
+ return this.storage.translations.get(o) ?? null;
93
65
  }
94
- // Методы для добавления переводов
95
- addTranslations(e, s, n = !0) {
96
- super.loadTranslationsCore(e, s, n);
66
+ addTranslations(e, s, o = !0) {
67
+ super.loadTranslationsCore(e, s, o);
97
68
  }
98
- addRouteTranslations(e, s, n, r = !0) {
99
- super.loadRouteTranslationsCore(e, s, n, r);
69
+ addRouteTranslations(e, s, o, i = !0) {
70
+ super.loadRouteTranslationsCore(e, s, o, i);
100
71
  }
101
- mergeTranslations(e, s, n) {
102
- this.helper.mergeTranslation(e, s, n, !0);
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, n] of Object.entries(e))
111
- this.helper.loadTranslations(s, n);
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(a) {
119
- const {
120
- locale: e,
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": (i) => {
130
- const { updateConfig: f } = i, t = "virtual:i18n-micro/config", l = "\0" + t, c = {
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: a.locales || [],
134
- localeCodes: (a.locales || []).map((o) => o.code),
135
- translationDir: n || null,
136
- autoDetect: a.autoDetect ?? !0,
137
- redirectToDefault: a.redirectToDefault ?? !1,
138
- localeCookie: a.localeCookie || "i18n-locale",
139
- missingWarn: a.missingWarn ?? !1
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(o) {
147
- if (o === t)
112
+ resolveId(a) {
113
+ if (a === t)
148
114
  return l;
149
115
  },
150
- load(o) {
151
- if (o === l)
152
- return `export const config = ${JSON.stringify(c)}`;
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": (i) => {
161
- const { injectTypes: f } = i;
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(a) {
187
- return new T(a);
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 J(a) {
187
+ function V(n) {
190
188
  const {
191
189
  i18n: e,
192
190
  // Это глобальный синглтон с кэшем
193
191
  defaultLocale: s,
194
- locales: n,
195
- localeObjects: r,
196
- autoDetect: i = !0,
192
+ locales: o,
193
+ localeObjects: i,
194
+ autoDetect: c = !0,
197
195
  redirectToDefault: f = !1,
198
196
  routingStrategy: t
199
- } = a, l = t || v();
200
- return async (c, o) => {
201
- if (c.locals.locale && c.locals.i18n)
202
- return o();
203
- const u = c.url, g = u.pathname;
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 b = e.clone(s), D = g === "/" || g === "" ? "index" : g.split("/").filter(Boolean).join("-");
206
- return b.setRoute(D), c.locals.i18n = b, c.locals.locale = s, c.locals.defaultLocale = s, c.locals.locales = r || n.map((B) => ({ code: B })), c.locals.currentUrl = u, o();
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: () => g,
208
+ getCurrentPath: () => h,
211
209
  getRoute: () => ({
212
210
  fullPath: u.pathname + u.search,
213
211
  query: Object.fromEntries(u.searchParams)
214
212
  })
215
- }, h = g.split("/").filter(Boolean)[0], p = h !== void 0 && n.includes(h);
216
- let L;
217
- p && h ? L = h : d.getLocaleFromPath ? L = d.getLocaleFromPath(g, s, n) : L = s;
218
- const y = e.clone(L), P = d.getRouteName ? d.getRouteName(g, n) : "general";
219
- return y.setRoute(P), c.locals.i18n = y, c.locals.locale = L, c.locals.defaultLocale = s, c.locals.locales = r || n.map((b) => ({ code: b })), c.locals.currentUrl = u, c.locals.routingStrategy = d, o();
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 A(a) {
223
- const e = [], s = a.split(",");
224
- for (const n of s) {
225
- const [r, i = "1.0"] = n.trim().split(";q=");
226
- if (Number.parseFloat(i) > 0 && r) {
227
- const t = r.split("-")[0]?.toLowerCase();
228
- t && (e.push(t), r !== t && e.push(r.toLowerCase()));
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(a, e, s, n, r, i = "i18n-locale") {
231
+ function K(n, e, s, o, i, c = "i18n-locale") {
234
232
  const f = v();
235
- let t = n;
233
+ let t = o;
236
234
  if (f?.getLocaleFromPath)
237
- t = f.getLocaleFromPath(a, n, r);
235
+ t = f.getLocaleFromPath(n, o, i);
238
236
  else {
239
- const c = a.split("/").filter(Boolean)[0];
240
- c && r.includes(c) && (t = c);
237
+ const r = n.split("/").filter(Boolean)[0];
238
+ r && i.includes(r) && (t = r);
241
239
  }
242
- if (t === n && e.get(i)) {
243
- const l = e.get(i)?.value;
244
- l && r.includes(l) && (t = 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 === n)
244
+ if (t === o)
247
245
  try {
248
246
  const l = s.get("accept-language");
249
247
  if (l) {
250
- const c = A(l);
251
- for (const o of c)
252
- if (r.includes(o)) {
253
- t = o;
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 w(a) {
262
- const e = a.locals.i18n;
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 S(a) {
268
- return a.locals.locale || "en";
348
+ function T(n) {
349
+ return n.locals.locale || "en";
269
350
  }
270
- function R(a) {
271
- return a.locals.defaultLocale || "en";
351
+ function w(n) {
352
+ return n.locals.defaultLocale || "en";
272
353
  }
273
- function k(a) {
274
- return a.locals.locales || [];
354
+ function $(n) {
355
+ return n.locals.locales || [];
275
356
  }
276
- function $(a) {
277
- return a.locals.routingStrategy || null;
357
+ function D(n) {
358
+ return n.locals.routingStrategy || null;
278
359
  }
279
- function Q(a) {
280
- const e = w(a), s = S(a), n = R(a), r = k(a), i = r.map((t) => t.code), f = $(a);
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: n,
285
- locales: r,
365
+ defaultLocale: o,
366
+ locales: i,
286
367
  // Translation methods
287
- t: (t, l, c, o) => e.t(t, l, c, o),
288
- ts: (t, l, c, o) => e.ts(t, l, c, o),
289
- tc: (t, l, c) => e.tc(t, l, c),
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 || a.url.pathname;
378
+ const l = t || n.url.pathname;
298
379
  if (f?.getRouteName)
299
- return f.getRouteName(l, i);
300
- const c = l.replace(/^\//, "").replace(/\/$/, "");
301
- if (!c) return "index";
302
- const o = c.split("/").filter(Boolean), u = o[0];
303
- return u && i.includes(u) && o.shift(), o.length === 0 ? "index" : o.join("-");
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 || a.url.pathname;
387
+ const l = t || n.url.pathname;
307
388
  if (f?.getLocaleFromPath)
308
- return f.getLocaleFromPath(l, n, i);
309
- const o = l.split("/").filter(Boolean)[0];
310
- return o && i.includes(o) ? o : n;
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(a.url.pathname, t, i, n);
316
- const l = a.url.pathname.split("/").filter(Boolean), c = l[0];
317
- return c && i.includes(c) && l.shift(), t !== n && l.unshift(t), `/${l.join("/")}`;
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, i, n);
322
- const o = (t.replace(/^\//, "").replace(/\/$/, "") || "").split("/").filter(Boolean), u = o[0];
323
- return u && i.includes(u) && o.shift(), l && l !== n && o.unshift(l), `/${o.join("/")}`;
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 o = (t || a.url).pathname.split("/").filter(Boolean), u = o[0];
330
- return u && i.includes(u) && o.shift(), o.length > 0 ? `/${o.join("/")}` : "/";
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, c = !0) => {
334
- e.addTranslations(t, l, c);
414
+ addTranslations: (t, l, r = !0) => {
415
+ e.addTranslations(t, l, r);
335
416
  },
336
- addRouteTranslations: (t, l, c, o = !0) => {
337
- e.addRouteTranslations(t, l, c, o);
417
+ addRouteTranslations: (t, l, r, a = !0) => {
418
+ e.addRouteTranslations(t, l, r, a);
338
419
  },
339
- mergeTranslations: (t, l, c) => {
340
- e.mergeTranslations(t, l, c);
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 X(a, e = {}) {
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 c = l.iso || i, o = l.dir || "auto", u = {
435
+ const r = l.iso || c, a = l.dir || "auto", u = {
359
436
  htmlAttrs: {
360
- lang: c,
361
- ...n ? { dir: o } : {}
437
+ lang: r,
438
+ ...o ? { dir: a } : {}
362
439
  },
363
440
  link: [],
364
441
  meta: []
365
442
  };
366
- if (!r)
443
+ if (!i)
367
444
  return u;
368
- const g = `${s}${a.url.pathname}`;
445
+ const h = `${s}${n.url.pathname}`;
369
446
  u.link.push({
370
447
  rel: "canonical",
371
- href: g
448
+ href: h
372
449
  });
373
- const d = $(a), m = t.map((h) => h.code);
374
- for (const h of t) {
375
- if (h.code === i) continue;
376
- let p = a.url.pathname;
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(a.url.pathname, h.code, m, f);
455
+ p = d.switchLocalePath(n.url.pathname, g.code, m, f);
379
456
  else {
380
- const y = a.url.pathname.split("/").filter(Boolean), P = y[0];
381
- P && m.includes(P) && y.shift(), h.code !== f && y.unshift(h.code), p = `/${y.join("/")}`;
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 L = `${s}${p}`;
460
+ const P = `${s}${p}`;
384
461
  u.link.push({
385
462
  rel: "alternate",
386
- href: L,
387
- hreflang: h.code
388
- }), h.iso && h.iso !== h.code && u.link.push({
463
+ href: P,
464
+ hreflang: g.code
465
+ }), g.iso && g.iso !== g.code && u.link.push({
389
466
  rel: "alternate",
390
- href: L,
391
- hreflang: h.iso
467
+ href: P,
468
+ hreflang: g.iso
392
469
  });
393
470
  }
394
471
  u.meta.push({
395
472
  property: "og:locale",
396
- content: c
473
+ content: r
397
474
  }), u.meta.push({
398
475
  property: "og:url",
399
- content: g
476
+ content: h
400
477
  });
401
- for (const h of t)
402
- h.code !== i && u.meta.push({
478
+ for (const g of t)
479
+ g.code !== c && u.meta.push({
403
480
  property: "og:locale:alternate",
404
- content: h.iso || h.code
481
+ content: g.iso || g.code
405
482
  });
406
483
  return u;
407
484
  }
408
- function M(a, e, s) {
409
- const n = e.split(".");
410
- let r = a;
411
- for (let i = 0; i < n.length - 1; i++)
412
- r[n[i]] || (r[n[i]] = {}), r = r[n[i]];
413
- r[n[n.length - 1]] = s;
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 Y(a, e) {
416
- const s = w(a), n = S(a), r = R(a), i = s.getRoute(), f = {};
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 c = s.t(l, void 0, void 0, i);
421
- c != null && c !== l && M(t, l, c);
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[i] = t);
503
+ Object.keys(t).length > 0 && (f[c] = t);
424
504
  } else {
425
- const t = s.getRouteTranslations(n, i);
426
- t && (f[i] = t);
505
+ const t = s.getRouteTranslations(o, c);
506
+ t && (f[c] = t);
427
507
  }
428
508
  return {
429
- locale: n,
430
- fallbackLocale: r,
431
- currentRoute: i,
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
- T as AstroI18n,
516
+ S as AstroI18n,
552
517
  le as FormatService,
553
- Z as createAstroRouterAdapter,
518
+ Q as createAstroRouterAdapter,
554
519
  E as createI18n,
555
- J as createI18nMiddleware,
520
+ V as createI18nMiddleware,
556
521
  re as defaultPlural,
557
522
  K as detectLocale,
558
- R as getDefaultLocale,
559
- w as getI18n,
560
- Y as getI18nProps,
561
- S as getLocale,
562
- x as getLocaleFromPath,
563
- k as getLocales,
564
- V as getRouteName,
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
- ce as interpolate,
567
- W as loadTranslationsFromDir,
568
- ae as loadTranslationsIntoI18n,
569
- te as localizePath,
570
- ne as removeLocaleFromPath,
571
- ee as switchLocalePath,
572
- Q as useI18n,
573
- X as useLocaleHead
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
  };