@forgedevstack/lingo 1.0.0

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.js ADDED
@@ -0,0 +1,553 @@
1
+ import { Lingo as Ae, LingoProvider as Re, LocaleSwitcher as Ie, T as Ke, useDirection as Me, useLingo as Pe, useLocale as Ue, useTranslate as _e } from "./react/index.js";
2
+ const je = "1.0.0", Se = "local", H = "remote", S = "hybrid", L = "[Lingo]", se = /* @__PURE__ */ new Set([
3
+ "ar",
4
+ "he",
5
+ "fa",
6
+ "ur",
7
+ "ps",
8
+ "sd",
9
+ "yi",
10
+ "ku"
11
+ ]), le = [
12
+ { code: "en", name: "English", nativeName: "English", direction: "ltr", flag: "🇺🇸" },
13
+ { code: "es", name: "Spanish", nativeName: "Español", direction: "ltr", flag: "🇪🇸" },
14
+ { code: "fr", name: "French", nativeName: "Français", direction: "ltr", flag: "🇫🇷" },
15
+ { code: "de", name: "German", nativeName: "Deutsch", direction: "ltr", flag: "🇩🇪" },
16
+ { code: "it", name: "Italian", nativeName: "Italiano", direction: "ltr", flag: "🇮🇹" },
17
+ { code: "pt", name: "Portuguese", nativeName: "Português", direction: "ltr", flag: "🇧🇷" },
18
+ { code: "nl", name: "Dutch", nativeName: "Nederlands", direction: "ltr", flag: "🇳🇱" },
19
+ { code: "pl", name: "Polish", nativeName: "Polski", direction: "ltr", flag: "🇵🇱" },
20
+ { code: "ru", name: "Russian", nativeName: "Русский", direction: "ltr", flag: "🇷🇺" },
21
+ { code: "uk", name: "Ukrainian", nativeName: "Українська", direction: "ltr", flag: "🇺🇦" },
22
+ { code: "ja", name: "Japanese", nativeName: "日本語", direction: "ltr", flag: "🇯🇵" },
23
+ { code: "ko", name: "Korean", nativeName: "한국어", direction: "ltr", flag: "🇰🇷" },
24
+ { code: "zh", name: "Chinese", nativeName: "中文", direction: "ltr", flag: "🇨🇳" },
25
+ { code: "ar", name: "Arabic", nativeName: "العربية", direction: "rtl", flag: "🇸🇦" },
26
+ { code: "he", name: "Hebrew", nativeName: "עברית", direction: "rtl", flag: "🇮🇱" },
27
+ { code: "fa", name: "Persian", nativeName: "فارسی", direction: "rtl", flag: "🇮🇷" },
28
+ { code: "hi", name: "Hindi", nativeName: "हिन्दी", direction: "ltr", flag: "🇮🇳" },
29
+ { code: "tr", name: "Turkish", nativeName: "Türkçe", direction: "ltr", flag: "🇹🇷" },
30
+ { code: "th", name: "Thai", nativeName: "ไทย", direction: "ltr", flag: "🇹🇭" },
31
+ { code: "vi", name: "Vietnamese", nativeName: "Tiếng Việt", direction: "ltr", flag: "🇻🇳" },
32
+ { code: "sv", name: "Swedish", nativeName: "Svenska", direction: "ltr", flag: "🇸🇪" },
33
+ { code: "da", name: "Danish", nativeName: "Dansk", direction: "ltr", flag: "🇩🇰" },
34
+ { code: "fi", name: "Finnish", nativeName: "Suomi", direction: "ltr", flag: "🇫🇮" },
35
+ { code: "no", name: "Norwegian", nativeName: "Norsk", direction: "ltr", flag: "🇳🇴" },
36
+ { code: "cs", name: "Czech", nativeName: "Čeština", direction: "ltr", flag: "🇨🇿" },
37
+ { code: "ro", name: "Romanian", nativeName: "Română", direction: "ltr", flag: "🇷🇴" },
38
+ { code: "hu", name: "Hungarian", nativeName: "Magyar", direction: "ltr", flag: "🇭🇺" },
39
+ { code: "el", name: "Greek", nativeName: "Ελληνικά", direction: "ltr", flag: "🇬🇷" },
40
+ { code: "id", name: "Indonesian", nativeName: "Bahasa Indonesia", direction: "ltr", flag: "🇮🇩" },
41
+ { code: "ms", name: "Malay", nativeName: "Bahasa Melayu", direction: "ltr", flag: "🇲🇾" },
42
+ { code: "bn", name: "Bengali", nativeName: "বাংলা", direction: "ltr", flag: "🇧🇩" },
43
+ { code: "ur", name: "Urdu", nativeName: "اردو", direction: "rtl", flag: "🇵🇰" }
44
+ ], A = "lingo_locale", ue = "https://lingo.forgedevstack.com/api", fe = {
45
+ cache: !0,
46
+ storageKey: A,
47
+ debug: !0
48
+ };
49
+ function B(e, t) {
50
+ const n = t.split(".");
51
+ let o = e;
52
+ for (const r of n) {
53
+ if (o == null || typeof o != "object") return;
54
+ o = o[r];
55
+ }
56
+ if (typeof o == "string" || o && typeof o == "object" && "other" in o) return o;
57
+ }
58
+ function C(e, t) {
59
+ return t ? e.replace(/\{\{(\s*\w+\s*)\}\}/g, (n, o) => {
60
+ const r = o.trim();
61
+ return t[r] != null ? String(t[r]) : `{{${r}}}`;
62
+ }) : e;
63
+ }
64
+ function de(e, t, n) {
65
+ const o = Math.abs(t), r = me(o, n);
66
+ return r === "zero" && e.zero ? e.zero : r === "one" && e.one ? e.one : r === "two" && e.two ? e.two : r === "few" && e.few ? e.few : r === "many" && e.many ? e.many : e.other;
67
+ }
68
+ function me(e, t) {
69
+ const n = t.split("-")[0];
70
+ if (e === 0) return "zero";
71
+ switch (n) {
72
+ case "ar":
73
+ return e === 1 ? "one" : e === 2 ? "two" : e % 100 >= 3 && e % 100 <= 10 ? "few" : e % 100 >= 11 && e % 100 <= 99 ? "many" : "other";
74
+ case "he":
75
+ return e === 1 ? "one" : e === 2 ? "two" : "other";
76
+ case "ru":
77
+ case "uk":
78
+ case "pl":
79
+ case "cs": {
80
+ const o = e % 10, r = e % 100;
81
+ return o === 1 && r !== 11 ? "one" : o >= 2 && o <= 4 && !(r >= 12 && r <= 14) ? "few" : "many";
82
+ }
83
+ case "fr":
84
+ case "pt":
85
+ return e <= 1 ? "one" : "other";
86
+ case "ja":
87
+ case "ko":
88
+ case "zh":
89
+ case "th":
90
+ case "vi":
91
+ case "id":
92
+ case "ms":
93
+ return "other";
94
+ default:
95
+ return e === 1 ? "one" : "other";
96
+ }
97
+ }
98
+ function k(e) {
99
+ return se.has(e.split("-")[0]) ? "rtl" : "ltr";
100
+ }
101
+ function N(e, t = "") {
102
+ const n = {};
103
+ for (const [o, r] of Object.entries(e)) {
104
+ const s = t ? `${t}.${o}` : o;
105
+ typeof r == "string" ? n[s] = r : Object.assign(n, N(r, s));
106
+ }
107
+ return n;
108
+ }
109
+ function ge(e) {
110
+ const t = { ...e };
111
+ for (const [n, o] of Object.entries(e)) {
112
+ const r = n.split(".");
113
+ if (r.length >= 3 && r[0] === r[1]) {
114
+ const s = r.slice(1).join(".");
115
+ t[s] === void 0 && (t[s] = o);
116
+ }
117
+ }
118
+ return t;
119
+ }
120
+ function I(e) {
121
+ const t = {};
122
+ for (const [n, o] of Object.entries(e)) {
123
+ const r = n.split(".");
124
+ let s = t;
125
+ for (let a = 0; a < r.length - 1; a++) {
126
+ const d = r[a];
127
+ (!s[d] || typeof s[d] == "string") && (s[d] = {}), s = s[d];
128
+ }
129
+ s[r[r.length - 1]] = o;
130
+ }
131
+ return t;
132
+ }
133
+ function E(e, t) {
134
+ const n = { ...e };
135
+ for (const [o, r] of Object.entries(t))
136
+ typeof r == "string" ? n[o] = r : typeof n[o] == "object" && typeof r == "object" ? n[o] = E(n[o], r) : n[o] = r;
137
+ return n;
138
+ }
139
+ function D(e, t) {
140
+ const n = /* @__PURE__ */ new Set([...Object.keys(e), ...Object.keys(t)]), o = {};
141
+ for (const r of n)
142
+ o[r] = E(e[r] ?? {}, t[r] ?? {});
143
+ return o;
144
+ }
145
+ function ye(e, t, n) {
146
+ if (!n) return;
147
+ const o = N(e), r = N(t);
148
+ for (const s of Object.keys(r))
149
+ Object.prototype.hasOwnProperty.call(o, s) && console.warn(`${L} Local file overlay overrides remote for "${s}" (local wins).`);
150
+ }
151
+ function pe(e, t, n) {
152
+ if (n == null) return;
153
+ if (typeof n == "function") return n(e, t);
154
+ if (typeof n == "string") return n;
155
+ const o = Array.isArray(n) ? n : [n];
156
+ for (const r of o) {
157
+ if (r[e] !== void 0) return r[e];
158
+ const s = e.indexOf(".");
159
+ if (s !== -1) {
160
+ const a = e.slice(0, s);
161
+ if (r[a] !== void 0) return r[a];
162
+ }
163
+ }
164
+ }
165
+ function ke(e) {
166
+ const t = e.trim();
167
+ if (t) {
168
+ if (t.startsWith("[") || t.startsWith("{"))
169
+ try {
170
+ const n = JSON.parse(t);
171
+ if (Array.isArray(n) && n.every((o) => o != null && typeof o == "object" && !Array.isArray(o)) || n != null && typeof n == "object" && !Array.isArray(n))
172
+ return n;
173
+ } catch {
174
+ return t;
175
+ }
176
+ return t;
177
+ }
178
+ }
179
+ const V = /\.(json|mjs|cjs|ts|js)$/i;
180
+ function X(e) {
181
+ var n;
182
+ const t = ((n = e.split("/").pop()) == null ? void 0 : n.split("\\").pop()) ?? "";
183
+ return /^hybrid-overlay-/i.test(t) || /^overlay[-.]/i.test(t);
184
+ }
185
+ function Y(e) {
186
+ var o;
187
+ const n = (((o = e.split("/").pop()) == null ? void 0 : o.split("\\").pop()) ?? "").replace(V, "");
188
+ return !n || X(e) ? null : n;
189
+ }
190
+ function he(e) {
191
+ var s;
192
+ const n = (((s = e.split("/").pop()) == null ? void 0 : s.split("\\").pop()) ?? "").replace(V, ""), o = n.match(/^hybrid-overlay-(.+)$/i);
193
+ if (o) return o[1] ?? null;
194
+ const r = n.match(/^overlay[-.](.+)$/i);
195
+ return r ? r[1] ?? null : Y(e);
196
+ }
197
+ function G(e) {
198
+ const t = e && typeof e == "object" && "default" in e && e.default !== void 0 ? e.default : e;
199
+ if (!t || typeof t != "object") return {};
200
+ const n = t, o = Object.values(n);
201
+ return o.length > 0 && o.every((r) => typeof r == "string") ? n : N(n);
202
+ }
203
+ function W(e) {
204
+ return Object.fromEntries(e.map((t) => [t, {}]));
205
+ }
206
+ function ve(e, t, n, o) {
207
+ if (o)
208
+ for (const r of Object.keys(t))
209
+ Object.prototype.hasOwnProperty.call(e, r) && console.warn(
210
+ `${L} "${r}" exists in multiple ${n} files; later value wins (use local overlay to override remote).`
211
+ );
212
+ }
213
+ function x(e, t, n, o, r) {
214
+ const s = N(e[t] ?? {});
215
+ ve(s, n, r, o);
216
+ const a = { ...s, ...n };
217
+ e[t] = I(a);
218
+ }
219
+ function be(e) {
220
+ const t = W(e.locales), n = W(e.locales), o = e.debug === !0;
221
+ for (const [s, a] of Object.entries(e.baseGlob)) {
222
+ if (X(s)) continue;
223
+ const d = Y(s);
224
+ if (!d || !e.locales.includes(d)) continue;
225
+ const y = G(a);
226
+ x(t, d, y, o, "base locale file");
227
+ }
228
+ const r = e.overlayGlob ?? {};
229
+ for (const [s, a] of Object.entries(r)) {
230
+ const d = he(s);
231
+ if (!d || !e.locales.includes(d)) continue;
232
+ const y = G(a);
233
+ x(n, d, y, o, "overlay locale file");
234
+ }
235
+ return { translations: t, overlay: n };
236
+ }
237
+ function we(e) {
238
+ if (!e.localeLayersFromGlobs) return e;
239
+ const { translations: t, overlay: n } = be({
240
+ ...e.localeLayersFromGlobs,
241
+ debug: e.debug
242
+ }), o = e.source;
243
+ let r = o;
244
+ if (o.type === "local")
245
+ r = { type: "local", translations: t };
246
+ else if (o.type === "hybrid") {
247
+ let d = D(t, n);
248
+ const y = o.local;
249
+ y && Object.keys(y).length > 0 && (d = D(d, y)), r = { type: "hybrid", remote: o.remote, local: d };
250
+ }
251
+ const { localeLayersFromGlobs: s, ...a } = e;
252
+ return { ...a, source: r };
253
+ }
254
+ function R(e) {
255
+ return JSON.parse(JSON.stringify(e));
256
+ }
257
+ function Le(e) {
258
+ if (e.type === H) {
259
+ if ("remotes" in e && Array.isArray(e.remotes))
260
+ return e.remotes;
261
+ const t = e;
262
+ return [{ projectId: t.projectId, endpoint: t.endpoint, apiKey: t.apiKey }];
263
+ }
264
+ if (e.type === S) {
265
+ const t = e.remote;
266
+ return Array.isArray(t) ? t : [t];
267
+ }
268
+ return null;
269
+ }
270
+ function z(e) {
271
+ return e.type === H || e.type === S;
272
+ }
273
+ function Oe(e) {
274
+ const t = e.source;
275
+ return t.type === "local" ? R(t.translations) : t.type === S ? R(t.local ?? {}) : {};
276
+ }
277
+ function J(e, t) {
278
+ var n;
279
+ return e.source.type !== S ? {} : R({ [t]: ((n = e.source.local) == null ? void 0 : n[t]) ?? {} })[t] ?? {};
280
+ }
281
+ function Ee(e) {
282
+ const t = we({
283
+ ...fe,
284
+ ...e
285
+ }), n = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map();
286
+ let a = {
287
+ locale: Q(t) ?? t.defaultLocale,
288
+ direction: k(t.defaultLocale),
289
+ isLoading: !1,
290
+ translations: Oe(t),
291
+ stateRevision: 0,
292
+ remoteFetchError: null
293
+ };
294
+ a.direction = k(a.locale), z(t.source) && $(a.locale);
295
+ let d = null;
296
+ function y() {
297
+ var l;
298
+ const i = (l = t.remoteBundleWebSocketUrl) == null ? void 0 : l.trim();
299
+ if (typeof WebSocket > "u" || !i) return;
300
+ const c = () => {
301
+ d = new WebSocket(i), d.onmessage = (f) => {
302
+ let g;
303
+ try {
304
+ const u = JSON.parse(String(f.data));
305
+ ((u == null ? void 0 : u.type) === "lingo:bundle-updated" || (u == null ? void 0 : u.type) === "bundle-updated") && (g = u.locales);
306
+ } catch {
307
+ return;
308
+ }
309
+ if (g != null && g.length)
310
+ for (const u of g)
311
+ o.delete(u);
312
+ else
313
+ o.clear();
314
+ M({ force: !0 });
315
+ }, d.onclose = () => {
316
+ t.remoteBundleWebSocketUrl && typeof window < "u" && window.setTimeout(c, 4e3);
317
+ };
318
+ };
319
+ c();
320
+ }
321
+ typeof window < "u" && t.remoteBundleWebSocketUrl && y();
322
+ function q() {
323
+ for (const i of n)
324
+ i(a);
325
+ }
326
+ function b(i) {
327
+ const c = typeof i == "function" ? i(a) : i;
328
+ a = { ...a, ...c }, q();
329
+ }
330
+ function Q(i) {
331
+ if (!i.cache || typeof window > "u") return null;
332
+ try {
333
+ const c = localStorage.getItem(i.storageKey ?? A);
334
+ if (c && i.locales.includes(c)) return c;
335
+ } catch {
336
+ }
337
+ return null;
338
+ }
339
+ function Z(i) {
340
+ if (!(!t.cache || typeof window > "u"))
341
+ try {
342
+ localStorage.setItem(t.storageKey ?? A, i);
343
+ } catch {
344
+ }
345
+ }
346
+ function ee(i, c) {
347
+ if (c || !o.has(i)) return !1;
348
+ const l = t.remoteRevalidateIntervalMs;
349
+ return l == null ? !0 : Date.now() - (s.get(i) ?? 0) < l;
350
+ }
351
+ function K(i, c) {
352
+ if (!i) return;
353
+ let l = B(i, c);
354
+ if (l !== void 0) return l;
355
+ const f = t.namespaces;
356
+ if (f != null && f.length && !c.includes(".")) {
357
+ for (const u of f)
358
+ if (l = B(i, `${u}.${c}`), l !== void 0) return l;
359
+ const g = N(i);
360
+ for (const u of f) {
361
+ const w = `${u}.${c}`;
362
+ let m, p = 1 / 0;
363
+ for (const [h, O] of Object.entries(g))
364
+ if (typeof O == "string") {
365
+ if (h === w) return O;
366
+ h.endsWith(`.${w}`) && h.length < p && (m = O, p = h.length);
367
+ }
368
+ if (m !== void 0) return m;
369
+ }
370
+ }
371
+ }
372
+ async function $(i, c) {
373
+ const l = Le(t.source);
374
+ if (!(l != null && l.length)) return;
375
+ const f = (c == null ? void 0 : c.force) === !0;
376
+ if (ee(i, f)) return;
377
+ const g = r.get(i);
378
+ if (g) return g;
379
+ const u = (async () => {
380
+ var w;
381
+ b({ isLoading: !0 });
382
+ try {
383
+ let m = {};
384
+ for (let v = 0; v < l.length; v++) {
385
+ const j = l[v], P = `${j.endpoint ?? ue}/translations/${j.projectId}/${i}`, F = (w = j.apiKey) == null ? void 0 : w.trim(), ce = F != null && F !== "" ? `${P}?${new URLSearchParams({ apiKey: F }).toString()}` : P, T = await fetch(ce);
386
+ if (!T.ok) throw new Error(`${L} failed to fetch ${i} (${T.status})`);
387
+ const U = await T.json();
388
+ if (t.debug)
389
+ for (const _ of Object.keys(U))
390
+ Object.prototype.hasOwnProperty.call(m, _) && console.warn(
391
+ `${L} Remote key "${_}" duplicated across remote sources; later source wins (index ${v}).`
392
+ );
393
+ m = { ...m, ...U };
394
+ }
395
+ m = ge(m);
396
+ const p = t.remoteKeysAllowlist;
397
+ if (p != null && p.length) {
398
+ const v = new Set(p);
399
+ m = Object.fromEntries(Object.entries(m).filter(([j]) => v.has(j)));
400
+ }
401
+ let h = I(m);
402
+ const O = J(t, i);
403
+ ye(h, O, t.debug === !0), h = E(h, O), b((v) => ({
404
+ isLoading: !1,
405
+ remoteFetchError: null,
406
+ translations: {
407
+ ...v.translations,
408
+ [i]: h
409
+ }
410
+ })), o.add(i), s.set(i, Date.now());
411
+ } catch (m) {
412
+ t.debug && console.warn(L, m);
413
+ const p = m instanceof Error ? m.message : String(m);
414
+ b({ isLoading: !1, remoteFetchError: p });
415
+ }
416
+ })();
417
+ r.set(i, u);
418
+ try {
419
+ await u;
420
+ } finally {
421
+ r.delete(i);
422
+ }
423
+ }
424
+ async function M(i) {
425
+ const c = (i == null ? void 0 : i.locale) ?? a.locale;
426
+ (i == null ? void 0 : i.force) === !0 && (o.delete(c), t.source.type === S ? b((f) => ({
427
+ translations: {
428
+ ...f.translations,
429
+ [c]: J(t, c)
430
+ }
431
+ })) : b((f) => {
432
+ const g = { ...f.translations };
433
+ return delete g[c], { translations: g };
434
+ })), await $(c, { force: !0 });
435
+ }
436
+ function te(i, c) {
437
+ var g;
438
+ const l = a.translations[a.locale];
439
+ let f = K(l, i);
440
+ if (f === void 0 && t.fallbackLocale && t.fallbackLocale !== a.locale) {
441
+ const u = a.translations[t.fallbackLocale];
442
+ f = K(u, i);
443
+ }
444
+ if (f === void 0) {
445
+ t.debug && console.warn(`${L} Missing key: "${i}" (locale: ${a.locale})`), (g = t.onMissingKey) == null || g.call(t, i, a.locale);
446
+ const u = pe(i, a.locale, t.missingKeyFallback);
447
+ return u !== void 0 ? u : i;
448
+ }
449
+ if (typeof f == "object") {
450
+ const u = (c == null ? void 0 : c.count) != null ? Number(c.count) : 0, w = de(f, u, a.locale);
451
+ return C(w, c);
452
+ }
453
+ return C(f, c);
454
+ }
455
+ async function ne(i) {
456
+ var c;
457
+ if (!t.locales.includes(i)) {
458
+ t.debug && console.warn(`${L} Locale "${i}" not in supported list`);
459
+ return;
460
+ }
461
+ z(t.source) && await $(i), Z(i), b({
462
+ locale: i,
463
+ direction: k(i)
464
+ }), typeof document < "u" && (document.documentElement.dir = k(i), document.documentElement.lang = i), (c = t.onLocaleChange) == null || c.call(t, i);
465
+ }
466
+ function oe(i) {
467
+ return le.find((c) => c.code === i);
468
+ }
469
+ function re(i) {
470
+ return n.add(i), i(a), () => n.delete(i);
471
+ }
472
+ function ie() {
473
+ return a.translations[a.locale] ?? {};
474
+ }
475
+ function ae(i, c) {
476
+ b((l) => {
477
+ const f = l.translations[i] ?? {};
478
+ return {
479
+ translations: {
480
+ ...l.translations,
481
+ [i]: E(f, c)
482
+ }
483
+ };
484
+ });
485
+ }
486
+ return {
487
+ t: te,
488
+ get locale() {
489
+ return a.locale;
490
+ },
491
+ setLocale: ne,
492
+ locales: t.locales,
493
+ get direction() {
494
+ return a.direction;
495
+ },
496
+ getLocaleInfo: oe,
497
+ get isLoading() {
498
+ return a.isLoading;
499
+ },
500
+ get remoteFetchError() {
501
+ return a.remoteFetchError;
502
+ },
503
+ subscribe: re,
504
+ getTranslations: ie,
505
+ addTranslations: ae,
506
+ refreshRemote: M
507
+ };
508
+ }
509
+ async function $e(e) {
510
+ const t = {}, n = Object.entries(e);
511
+ return await Promise.all(
512
+ n.map(async ([o, r]) => {
513
+ const s = await fetch(r);
514
+ if (!s.ok) throw new Error(`[Lingo] Failed to load ${r} (${s.status})`);
515
+ const a = await s.json();
516
+ t[o] = I(a);
517
+ })
518
+ ), t;
519
+ }
520
+ export {
521
+ ue as DEFAULT_REMOTE_ENDPOINT,
522
+ A as DEFAULT_STORAGE_KEY,
523
+ le as LOCALE_CATALOG,
524
+ L as LOG_PREFIX,
525
+ Ae as Lingo,
526
+ Re as LingoProvider,
527
+ Ie as LocaleSwitcher,
528
+ se as RTL_LOCALES,
529
+ S as SOURCE_HYBRID,
530
+ Se as SOURCE_LOCAL,
531
+ H as SOURCE_REMOTE,
532
+ Ke as T,
533
+ je as VERSION,
534
+ be as buildLocaleLayersFromGlobs,
535
+ Ee as createLingo,
536
+ ge as dedupeStutterNamespaceInFlatKeys,
537
+ N as flattenTranslations,
538
+ k as getDirection,
539
+ C as interpolate,
540
+ X as isLikelyOverlayLocalePath,
541
+ $e as loadLocalBundlesFromUrls,
542
+ D as mergeTranslationBundles,
543
+ E as mergeTranslations,
544
+ ke as parseMissingKeyFallbackEnv,
545
+ B as resolveKey,
546
+ pe as resolveMissingKeyFallback,
547
+ de as selectPlural,
548
+ I as unflattenTranslations,
549
+ Me as useDirection,
550
+ Pe as useLingo,
551
+ Ue as useLocale,
552
+ _e as useTranslate
553
+ };
@@ -0,0 +1,53 @@
1
+ import { ReactNode, FC } from 'react';
2
+ import { LingoInstance, Locale, TranslateVars, Direction, LocaleInfo } from '../types';
3
+ interface LingoContextValue {
4
+ t: (key: string, vars?: TranslateVars) => string;
5
+ locale: Locale;
6
+ setLocale: (locale: Locale) => Promise<void>;
7
+ locales: Locale[];
8
+ direction: Direction;
9
+ isLoading: boolean;
10
+ remoteFetchError: string | null;
11
+ getLocaleInfo: (locale: Locale) => LocaleInfo | undefined;
12
+ refreshRemote: (options?: {
13
+ locale?: Locale;
14
+ force?: boolean;
15
+ }) => Promise<void>;
16
+ }
17
+ interface LingoProviderProps {
18
+ instance: LingoInstance;
19
+ children: ReactNode;
20
+ }
21
+ export declare const LingoProvider: FC<LingoProviderProps>;
22
+ export declare function useLingo(): LingoContextValue;
23
+ export declare function useTranslate(): (key: string, vars?: TranslateVars) => string;
24
+ export declare function useLocale(): {
25
+ locale: Locale;
26
+ setLocale: (l: Locale) => Promise<void>;
27
+ locales: Locale[];
28
+ };
29
+ export declare function useDirection(): Direction;
30
+ interface TProps {
31
+ k: string;
32
+ vars?: TranslateVars;
33
+ as?: keyof HTMLElementTagNameMap;
34
+ className?: string;
35
+ style?: React.CSSProperties;
36
+ }
37
+ export declare const T: FC<TProps>;
38
+ interface LingoProps {
39
+ k: string;
40
+ vars?: TranslateVars;
41
+ as?: keyof HTMLElementTagNameMap;
42
+ className?: string;
43
+ style?: React.CSSProperties;
44
+ children?: (translated: string) => ReactNode;
45
+ }
46
+ export declare const Lingo: FC<LingoProps>;
47
+ interface LocaleSwitcherProps {
48
+ className?: string;
49
+ style?: React.CSSProperties;
50
+ }
51
+ export declare const LocaleSwitcher: FC<LocaleSwitcherProps>;
52
+ export {};
53
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lingo-react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,SAAS,EACd,KAAK,EAAE,EAER,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE5F,UAAU,iBAAiB;IACzB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,KAAK,MAAM,CAAC;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;IAC1D,aAAa,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClF;AAID,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CAkDhD,CAAC;AAEF,wBAAgB,QAAQ,IAAI,iBAAiB,CAM5C;AAED,wBAAgB,YAAY,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,KAAK,MAAM,CAG5E;AAED,wBAAgB,SAAS,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAG1G;AAED,wBAAgB,YAAY,IAAI,SAAS,CAGxC;AAGD,UAAU,MAAM;IACd,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,EAAE,CAAC,EAAE,MAAM,qBAAqB,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED,eAAO,MAAM,CAAC,EAAE,EAAE,CAAC,MAAM,CAGxB,CAAC;AAIF,UAAU,UAAU;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,EAAE,CAAC,EAAE,MAAM,qBAAqB,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,SAAS,CAAC;CAC9C;AAED,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC,UAAU,CAShC,CAAC;AAEF,UAAU,mBAAmB;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CAqBlD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Locale, TranslationBundle } from './types';
2
+ export declare function loadLocalBundlesFromUrls(pathsByLocale: Record<Locale, string>): Promise<TranslationBundle>;
3
+ //# sourceMappingURL=load-local-bundles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-local-bundles.d.ts","sourceRoot":"","sources":["../src/load-local-bundles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAGzD,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC,OAAO,CAAC,iBAAiB,CAAC,CAY5B"}
@@ -0,0 +1,13 @@
1
+ import { Locale, TranslationBundle } from './types';
2
+ export declare function isLikelyOverlayLocalePath(path: string): boolean;
3
+ export type LocaleGlobMapsOptions = {
4
+ locales: Locale[];
5
+ baseGlob: Record<string, unknown>;
6
+ overlayGlob?: Record<string, unknown>;
7
+ debug?: boolean;
8
+ };
9
+ export declare function buildLocaleLayersFromGlobs(opts: LocaleGlobMapsOptions): {
10
+ translations: TranslationBundle;
11
+ overlay: TranslationBundle;
12
+ };
13
+ //# sourceMappingURL=locale-globs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale-globs.d.ts","sourceRoot":"","sources":["../src/locale-globs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAkB,MAAM,SAAS,CAAC;AAMzE,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAG/D;AAoED,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,qBAAqB,GAC1B;IAAE,YAAY,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,CAsBjE"}
package/dist/logo.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Lingo Logo — Speech bubble with "A文" symbolizing translation.
3
+ * Use: <LingoLogo size={32} color="#6366f1" />
4
+ */
5
+ export declare const LINGO_LOGO_SVG = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" fill=\"none\">\n <!-- Speech bubble -->\n <path d=\"M8 12C8 8.68629 10.6863 6 14 6H50C53.3137 6 56 8.68629 56 12V38C56 41.3137 53.3137 44 50 44H30L18 54V44H14C10.6863 44 8 41.3137 8 38V12Z\" fill=\"currentColor\" opacity=\"0.15\"/>\n <path d=\"M8 12C8 8.68629 10.6863 6 14 6H50C53.3137 6 56 8.68629 56 12V38C56 41.3137 53.3137 44 50 44H30L18 54V44H14C10.6863 44 8 41.3137 8 38V12Z\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <!-- \"A\" on left -->\n <text x=\"19\" y=\"33\" font-family=\"system-ui, sans-serif\" font-size=\"18\" font-weight=\"700\" fill=\"currentColor\">A</text>\n <!-- Arrow -->\n <path d=\"M33 25H39M39 25L36.5 22.5M39 25L36.5 27.5\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <!-- \"\u6587\" on right -->\n <text x=\"40\" y=\"33\" font-family=\"system-ui, sans-serif\" font-size=\"16\" font-weight=\"700\" fill=\"currentColor\">\u6587</text>\n</svg>";
6
+ export declare const LINGO_ICON_SVG = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\" fill=\"none\">\n <path d=\"M4 6C4 4.34315 5.34315 3 7 3H25C26.6569 3 28 4.34315 28 6V19C28 20.6569 26.6569 22 25 22H15L9 27V22H7C5.34315 22 4 20.6569 4 19V6Z\" fill=\"currentColor\" opacity=\"0.15\"/>\n <path d=\"M4 6C4 4.34315 5.34315 3 7 3H25C26.6569 3 28 4.34315 28 6V19C28 20.6569 26.6569 22 25 22H15L9 27V22H7C5.34315 22 4 20.6569 4 19V6Z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <text x=\"9\" y=\"17\" font-family=\"system-ui, sans-serif\" font-size=\"10\" font-weight=\"700\" fill=\"currentColor\">A\u6587</text>\n</svg>";
7
+ //# sourceMappingURL=logo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logo.d.ts","sourceRoot":"","sources":["../src/logo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,cAAc,oiCAUpB,CAAC;AAER,eAAO,MAAM,cAAc,kpBAIpB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { LingoConfig } from './types';
2
+ export declare function normalizeLingoConfig(cfg: LingoConfig): LingoConfig;
3
+ //# sourceMappingURL=normalize-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize-config.d.ts","sourceRoot":"","sources":["../src/normalize-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAI3C,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,WAAW,GAAG,WAAW,CAoBlE"}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react"),m=t.createContext(null),h=({instance:e,children:s})=>{const[o,c]=t.useState(e.locale),[n,a]=t.useState(e.direction),[r,l]=t.useState(e.isLoading),[v,E]=t.useState(0),[g,S]=t.useState(null);t.useEffect(()=>e.subscribe(u=>{c(u.locale),a(u.direction),l(u.isLoading),E(u.stateRevision),S(u.remoteFetchError)}),[e]);const d=t.useCallback(async L=>{await e.setLocale(L)},[e]),f=t.useCallback((L,u)=>e.t(L,u),[e,v]),b=t.useMemo(()=>({t:f,locale:o,setLocale:d,locales:e.locales,direction:n,isLoading:r,remoteFetchError:g,getLocaleInfo:e.getLocaleInfo,refreshRemote:e.refreshRemote.bind(e)}),[e,f,o,n,r,g,d]);return t.createElement(m.Provider,{value:b},t.createElement("div",{dir:n,lang:o},s))};function i(){const e=t.useContext(m);if(!e)throw new Error("useLingo must be used within a <LingoProvider>");return e}function w(){const{t:e}=i();return e}function C(){const{locale:e,setLocale:s,locales:o}=i();return{locale:e,setLocale:s,locales:o}}function R(){const{direction:e}=i();return e}const p=({k:e,vars:s,as:o="span",className:c,style:n})=>{const{t:a}=i();return t.createElement(o,{className:c,style:n},a(e,s))},P=({k:e,vars:s,as:o="span",className:c,style:n,children:a})=>{const{t:r}=i(),l=r(e,s);return a?t.createElement(o,{className:c,style:n},a(l)):t.createElement(o,{className:c,style:n},l)},I=({className:e,style:s})=>{const{locale:o,setLocale:c,locales:n,getLocaleInfo:a}=i();return t.createElement("select",{value:o,onChange:r=>c(r.target.value),className:e,style:s,"aria-label":"Select language"},n.map(r=>{const l=a(r);return t.createElement("option",{key:r,value:r},l?`${l.flag??""} ${l.nativeName}`:r)}))};exports.Lingo=P;exports.LingoProvider=h;exports.LocaleSwitcher=I;exports.T=p;exports.useDirection=R;exports.useLingo=i;exports.useLocale=C;exports.useTranslate=w;
@@ -0,0 +1,2 @@
1
+ export * from '../lingo-react/index'
2
+ export {}