@prosopo/locale 3.1.28 → 3.2.5
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/.turbo/turbo-build$colon$cjs.log +6 -6
- package/.turbo/turbo-build$colon$tsc.log +5 -5
- package/.turbo/turbo-build.log +5 -5
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +73 -0
- package/dist/cjs/i18SharedOptions.cjs +2 -1
- package/dist/cjs/locales/en/translation.json.cjs +4 -4
- package/dist/i18SharedOptions.d.ts.map +1 -1
- package/dist/i18SharedOptions.js +2 -1
- package/dist/i18SharedOptions.js.map +1 -1
- package/dist/locales/ar/translation.json +18 -3
- package/dist/locales/az/translation.json +18 -3
- package/dist/locales/cs/translation.json +18 -3
- package/dist/locales/de/translation.json +18 -3
- package/dist/locales/el/translation.json +18 -3
- package/dist/locales/en/translation.json +18 -3
- package/dist/locales/en/translation.json.js +4 -4
- package/dist/locales/es/translation.json +19 -4
- package/dist/locales/fi/translation.json +18 -3
- package/dist/locales/fr/translation.json +18 -3
- package/dist/locales/hi/translation.json +18 -3
- package/dist/locales/hu/translation.json +18 -3
- package/dist/locales/id/translation.json +18 -3
- package/dist/locales/it/translation.json +18 -3
- package/dist/locales/ja/translation.json +18 -3
- package/dist/locales/jv/translation.json +18 -3
- package/dist/locales/ko/translation.json +18 -3
- package/dist/locales/ml/translation.json +18 -3
- package/dist/locales/ms/translation.json +18 -3
- package/dist/locales/nl/translation.json +18 -3
- package/dist/locales/no/translation.json +18 -3
- package/dist/locales/pl/translation.json +18 -3
- package/dist/locales/pt/translation.json +18 -3
- package/dist/locales/pt-BR/translation.json +18 -3
- package/dist/locales/ro/translation.json +18 -3
- package/dist/locales/ru/translation.json +18 -3
- package/dist/locales/sr/translation.json +426 -411
- package/dist/locales/sv/translation.json +18 -3
- package/dist/locales/th/translation.json +18 -3
- package/dist/locales/tr/translation.json +18 -3
- package/dist/locales/uk/translation.json +18 -3
- package/dist/locales/vi/translation.json +18 -3
- package/dist/locales/zh-CN/translation.json +18 -3
- package/package.json +4 -3
- package/src/i18SharedOptions.ts +29 -0
- package/src/i18nBackend.ts +53 -0
- package/src/i18nFrontend.ts +81 -0
- package/src/i18nMiddleware.ts +25 -0
- package/src/index.ts +22 -0
- package/src/loadI18next.ts +49 -0
- package/src/locales/ar/translation.json +460 -0
- package/src/locales/az/translation.json +460 -0
- package/src/locales/cs/translation.json +460 -0
- package/src/locales/de/translation.json +460 -0
- package/src/locales/el/translation.json +460 -0
- package/src/locales/en/translation.json +460 -0
- package/src/locales/es/translation.json +460 -0
- package/src/locales/fi/translation.json +460 -0
- package/src/locales/fr/translation.json +460 -0
- package/src/locales/hi/translation.json +460 -0
- package/src/locales/hu/translation.json +460 -0
- package/src/locales/id/translation.json +460 -0
- package/src/locales/it/translation.json +460 -0
- package/src/locales/ja/translation.json +460 -0
- package/src/locales/jv/translation.json +460 -0
- package/src/locales/ko/translation.json +460 -0
- package/src/locales/ml/translation.json +460 -0
- package/src/locales/ms/translation.json +460 -0
- package/src/locales/nl/translation.json +460 -0
- package/src/locales/no/translation.json +460 -0
- package/src/locales/pl/translation.json +460 -0
- package/src/locales/pt/translation.json +460 -0
- package/src/locales/pt-BR/translation.json +460 -0
- package/src/locales/ro/translation.json +460 -0
- package/src/locales/ru/translation.json +460 -0
- package/src/locales/sr/translation.json +460 -0
- package/src/locales/sv/translation.json +460 -0
- package/src/locales/th/translation.json +460 -0
- package/src/locales/tr/translation.json +460 -0
- package/src/locales/uk/translation.json +460 -0
- package/src/locales/vi/translation.json +460 -0
- package/src/locales/zh-CN/translation.json +460 -0
- package/src/tests/locales.unit.test.ts +79 -0
- package/src/translationKey.ts +48 -0
- package/src/translations.ts +54 -0
- package/src/useTranslation.ts +32 -0
- package/src/util.ts +25 -0
- package/tsconfig.cjs.json +18 -0
- package/tsconfig.json +19 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/tsconfig.types.json +9 -0
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"ACCESS_POLICY_BLOCK": "Åtkomst blockerad av policy",
|
|
22
22
|
"FORBIDDEN": "Förbjuden",
|
|
23
23
|
"PROVIDER_VERIFY_FAILED": "Leverantörsverifiering misslyckades",
|
|
24
|
+
"SPAM_EMAIL_DOMAIN": "E-postdomänen är inte tillåten",
|
|
24
25
|
"UNAUTHORIZED": "Obehörig",
|
|
25
26
|
"MISSING_BODY": "Saknad kropp",
|
|
26
27
|
"NO_CONTENT_TYPE_HEADER": "Ingen innehållstypshuvud. Antogs JSON-kodad kropp men misslyckades med att tolka.",
|
|
@@ -40,7 +41,17 @@
|
|
|
40
41
|
"INVALID_IP": "Ogiltig IP",
|
|
41
42
|
"INVALID_URL": "Ogiltig URL",
|
|
42
43
|
"INVALID_BODY": "Ogiltig body",
|
|
43
|
-
"PARSE_ERROR": "Fel vid tolkning av förfrågan"
|
|
44
|
+
"PARSE_ERROR": "Fel vid tolkning av förfrågan",
|
|
45
|
+
"SPAM_EMAIL_RULE": "E-postadressen blockerad av spamfilterregler",
|
|
46
|
+
"VPN_BLOCKED": "Förfrågningar från VPN-anslutningar är inte tillåtna för denna webbplats",
|
|
47
|
+
"PROXY_BLOCKED": "Förfrågningar från proxyservrar är inte tillåtna för denna webbplats",
|
|
48
|
+
"TOR_BLOCKED": "Förfrågningar från Tor-utgångsnoder är inte tillåtna för denna webbplats",
|
|
49
|
+
"ABUSER_BLOCKED": "Förfrågningar från nätverk markerade för missbruk är inte tillåtna för denna webbplats",
|
|
50
|
+
"DATACENTER_BLOCKED": "Förfrågningar från datacenter-IP-adresser är inte tillåtna för denna webbplats",
|
|
51
|
+
"MOBILE_BLOCKED": "Förfrågningar från mobilnätverksanslutningar är inte tillåtna för denna webbplats",
|
|
52
|
+
"SATELLITE_BLOCKED": "Förfrågningar från satellitanslutningar är inte tillåtna för denna webbplats",
|
|
53
|
+
"CRAWLER_BLOCKED": "Förfrågningar från kända crawlers är inte tillåtna för denna webbplats",
|
|
54
|
+
"DISALLOWED_WEBVIEW": "Förfrågningar från inbäddade webbläsare (WebView) är inte tillåtna för denna webbplats"
|
|
44
55
|
},
|
|
45
56
|
"PORTAL": {
|
|
46
57
|
"CANNOT_MODIFY_OWNER_USER": "Kan inte ändra ägare användare",
|
|
@@ -48,7 +59,9 @@
|
|
|
48
59
|
"CANNOT_DELETE_LAST_USER": "Kan inte ta bort sista användaren",
|
|
49
60
|
"USER_ALREADY_EXISTS": "Användaren finns redan",
|
|
50
61
|
"NO_SUGGESTIONS_FOUND": "Inga förslag hittades",
|
|
51
|
-
"CANNOT_DEACTIVATE_LAST_SITE": "Kan inte inaktivera den sista aktiva platsen"
|
|
62
|
+
"CANNOT_DEACTIVATE_LAST_SITE": "Kan inte inaktivera den sista aktiva platsen",
|
|
63
|
+
"DUPLICATE_SITE_NAME": "En webbplats med detta namn finns redan",
|
|
64
|
+
"INVALID_SITE_NAME": "Webbplatsnamnet får bara innehålla bokstäver, siffror, bindestreck och understreck"
|
|
52
65
|
},
|
|
53
66
|
"TARGET": {
|
|
54
67
|
"airplanes": "flygplan",
|
|
@@ -361,7 +374,8 @@
|
|
|
361
374
|
"I_AM_HUMAN": "Jag är en människa",
|
|
362
375
|
"NO_ACCOUNTS_FOUND": "Inga konton hittades",
|
|
363
376
|
"ACCOUNT_NOT_FOUND": "Konto hittades inte",
|
|
364
|
-
"NO_EXTENSION_FOUND": "Ingen förlängning hittades"
|
|
377
|
+
"NO_EXTENSION_FOUND": "Ingen förlängning hittades",
|
|
378
|
+
"INSECURE_CONTEXT": "Procaptcha kräver en säker (HTTPS) anslutning"
|
|
365
379
|
},
|
|
366
380
|
"CONTRACT": {
|
|
367
381
|
"INVALID_ADDRESS": "Misslyckades att koda ogiltig adress",
|
|
@@ -422,6 +436,7 @@
|
|
|
422
436
|
"NO_CAPTCHA": "Ingen CAPTCHA hittades",
|
|
423
437
|
"NO_SESSION_FOUND": "Inget-session-hittades",
|
|
424
438
|
"IP_ADDRESS_MISMATCH": "IP-adresser matchar inte",
|
|
439
|
+
"INVALID_SALT": "Ogiltigt salt",
|
|
425
440
|
"INVALID_TOKEN": "Ogiltig token",
|
|
426
441
|
"INVALID_SOLUTION": "Ogiltig lösning",
|
|
427
442
|
"DECRYPTION_ERROR": "Fel vid avkryptering"
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"ACCESS_POLICY_BLOCK": "การเข้าถึงถูกบล็อกโดยนโยบาย",
|
|
22
22
|
"FORBIDDEN": "ห้าม",
|
|
23
23
|
"PROVIDER_VERIFY_FAILED": "การตรวจสอบผู้ให้บริการล้มเหลว",
|
|
24
|
+
"SPAM_EMAIL_DOMAIN": "โดเมนอีเมลไม่ได้รับอนุญาต",
|
|
24
25
|
"UNAUTHORIZED": "Unauthorized",
|
|
25
26
|
"MISSING_BODY": "Missing body",
|
|
26
27
|
"NO_CONTENT_TYPE_HEADER": "No content-type header. Assumed JSON encoded body but failed to parse.",
|
|
@@ -40,7 +41,17 @@
|
|
|
40
41
|
"INVALID_IP": "IP ไม่ถูกต้อง",
|
|
41
42
|
"INVALID_URL": "URL ไม่ถูกต้อง",
|
|
42
43
|
"INVALID_BODY": "ข้อมูลไม่ถูกต้อง",
|
|
43
|
-
"PARSE_ERROR": "ข้อผิดพลาดในการแปลคำขอ"
|
|
44
|
+
"PARSE_ERROR": "ข้อผิดพลาดในการแปลคำขอ",
|
|
45
|
+
"SPAM_EMAIL_RULE": "ที่อยู่อีเมลถูกบล็อกโดยกฎตัวกรองสแปม",
|
|
46
|
+
"VPN_BLOCKED": "คำขอจากการเชื่อมต่อ VPN ไม่ได้รับอนุญาตสำหรับเว็บไซต์นี้",
|
|
47
|
+
"PROXY_BLOCKED": "คำขอจากเซิร์ฟเวอร์พร็อกซีไม่ได้รับอนุญาตสำหรับเว็บไซต์นี้",
|
|
48
|
+
"TOR_BLOCKED": "คำขอจากโหนดทางออก Tor ไม่ได้รับอนุญาตสำหรับเว็บไซต์นี้",
|
|
49
|
+
"ABUSER_BLOCKED": "คำขอจากเครือข่ายที่ถูกระบุว่ามีการใช้งานในทางที่ผิดไม่ได้รับอนุญาตสำหรับเว็บไซต์นี้",
|
|
50
|
+
"DATACENTER_BLOCKED": "คำขอจากที่อยู่ IP ของศูนย์ข้อมูลไม่ได้รับอนุญาตสำหรับเว็บไซต์นี้",
|
|
51
|
+
"MOBILE_BLOCKED": "คำขอจากการเชื่อมต่อเครือข่ายมือถือไม่ได้รับอนุญาตสำหรับเว็บไซต์นี้",
|
|
52
|
+
"SATELLITE_BLOCKED": "คำขอจากการเชื่อมต่อดาวเทียมไม่ได้รับอนุญาตสำหรับเว็บไซต์นี้",
|
|
53
|
+
"CRAWLER_BLOCKED": "คำขอจากโปรแกรมรวบรวมข้อมูลที่รู้จักไม่ได้รับอนุญาตสำหรับเว็บไซต์นี้",
|
|
54
|
+
"DISALLOWED_WEBVIEW": "ไม่อนุญาตให้ส่งคำขอจากเบราว์เซอร์ในแอป (WebView) สำหรับเว็บไซต์นี้"
|
|
44
55
|
},
|
|
45
56
|
"PORTAL": {
|
|
46
57
|
"CANNOT_MODIFY_OWNER_USER": "ไม่สามารถแก้ไขผู้ใช้เจ้าของ",
|
|
@@ -48,7 +59,9 @@
|
|
|
48
59
|
"CANNOT_DELETE_LAST_USER": "ไม่สามารถลบผู้ใช้สุดท้าย",
|
|
49
60
|
"USER_ALREADY_EXISTS": "ผู้ใช้มีอยู่แล้ว",
|
|
50
61
|
"NO_SUGGESTIONS_FOUND": "ไม่พบข้อเสนอ",
|
|
51
|
-
"CANNOT_DEACTIVATE_LAST_SITE": "ไม่สามารถปิดใช้งานเว็บไซต์ที่ใช้งานอยู่ครั้งสุดท้าย"
|
|
62
|
+
"CANNOT_DEACTIVATE_LAST_SITE": "ไม่สามารถปิดใช้งานเว็บไซต์ที่ใช้งานอยู่ครั้งสุดท้าย",
|
|
63
|
+
"DUPLICATE_SITE_NAME": "มีไซต์ที่ใช้ชื่อนี้อยู่แล้ว",
|
|
64
|
+
"INVALID_SITE_NAME": "ชื่อไซต์ต้องประกอบด้วยตัวอักษร ตัวเลข ขีดกลาง และขีดล่างเท่านั้น"
|
|
52
65
|
},
|
|
53
66
|
"TARGET": {
|
|
54
67
|
"airplanes": "เครื่องบิน",
|
|
@@ -361,7 +374,8 @@
|
|
|
361
374
|
"I_AM_HUMAN": "ฉันเป็นมนุษย์",
|
|
362
375
|
"NO_ACCOUNTS_FOUND": "ไม่พบบัญชี",
|
|
363
376
|
"ACCOUNT_NOT_FOUND": "ไม่พบบัญชี",
|
|
364
|
-
"NO_EXTENSION_FOUND": "ไม่พบส่วนขยาย"
|
|
377
|
+
"NO_EXTENSION_FOUND": "ไม่พบส่วนขยาย",
|
|
378
|
+
"INSECURE_CONTEXT": "Procaptcha ต้องใช้การเชื่อมต่อที่ปลอดภัย (HTTPS)"
|
|
365
379
|
},
|
|
366
380
|
"CONTRACT": {
|
|
367
381
|
"INVALID_ADDRESS": "ล้มเหลวในการเข้ารหัสที่อยู่ไม่ถูกต้อง",
|
|
@@ -422,6 +436,7 @@
|
|
|
422
436
|
"NO_CAPTCHA": "ไม่พบ captcha",
|
|
423
437
|
"NO_SESSION_FOUND": "ไม่พบเซสชัน",
|
|
424
438
|
"IP_ADDRESS_MISMATCH": "ที่อยู่ IP ไม่ตรงกัน",
|
|
439
|
+
"INVALID_SALT": "Salt ไม่ถูกต้อง",
|
|
425
440
|
"INVALID_TOKEN": "โทเคนไม่ถูกต้อง",
|
|
426
441
|
"INVALID_SOLUTION": "คำตอบไม่ถูกต้อง",
|
|
427
442
|
"DECRYPTION_ERROR": "เกิดข้อผิดพลาดในการถอดรหัส"
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"ACCESS_POLICY_BLOCK": "Erişim politika tarafından engellendi",
|
|
22
22
|
"FORBIDDEN": "Forbidden",
|
|
23
23
|
"PROVIDER_VERIFY_FAILED": "Provider verification failed",
|
|
24
|
+
"SPAM_EMAIL_DOMAIN": "E-posta alan adına izin verilmiyor",
|
|
24
25
|
"UNAUTHORIZED": "Yetkisiz",
|
|
25
26
|
"MISSING_BODY": "Eksik gövde",
|
|
26
27
|
"NO_CONTENT_TYPE_HEADER": "İçerik tipi başlığı yok. JSON kodlu gövde varsayılmış ancak ayrıştırılamadı.",
|
|
@@ -40,7 +41,17 @@
|
|
|
40
41
|
"INVALID_IP": "Geçersiz IP",
|
|
41
42
|
"INVALID_URL": "Geçersiz URL",
|
|
42
43
|
"INVALID_BODY": "Geçersiz gövde",
|
|
43
|
-
"PARSE_ERROR": "İstek ayrıştırma hatası"
|
|
44
|
+
"PARSE_ERROR": "İstek ayrıştırma hatası",
|
|
45
|
+
"SPAM_EMAIL_RULE": "E-posta adresi spam filtresi kuralları tarafından engellendi",
|
|
46
|
+
"VPN_BLOCKED": "Bu site için VPN bağlantılarından gelen isteklere izin verilmiyor",
|
|
47
|
+
"PROXY_BLOCKED": "Bu site için proxy sunucularından gelen isteklere izin verilmiyor",
|
|
48
|
+
"TOR_BLOCKED": "Bu site için Tor çıkış düğümlerinden gelen isteklere izin verilmiyor",
|
|
49
|
+
"ABUSER_BLOCKED": "Bu site için kötüye kullanım olarak işaretlenen ağlardan gelen isteklere izin verilmiyor",
|
|
50
|
+
"DATACENTER_BLOCKED": "Bu site için veri merkezi IP adreslerinden gelen isteklere izin verilmiyor",
|
|
51
|
+
"MOBILE_BLOCKED": "Bu site için mobil ağ bağlantılarından gelen isteklere izin verilmiyor",
|
|
52
|
+
"SATELLITE_BLOCKED": "Bu site için uydu bağlantılarından gelen isteklere izin verilmiyor",
|
|
53
|
+
"CRAWLER_BLOCKED": "Bu site için bilinen tarayıcılardan gelen isteklere izin verilmiyor",
|
|
54
|
+
"DISALLOWED_WEBVIEW": "Bu site için uygulama içi tarayıcılardan (WebView) gelen isteklere izin verilmiyor"
|
|
44
55
|
},
|
|
45
56
|
"PORTAL": {
|
|
46
57
|
"CANNOT_MODIFY_OWNER_USER": "Cannot modify owner user",
|
|
@@ -48,7 +59,9 @@
|
|
|
48
59
|
"CANNOT_DELETE_LAST_USER": "Cannot delete last user",
|
|
49
60
|
"USER_ALREADY_EXISTS": "User already exists",
|
|
50
61
|
"NO_SUGGESTIONS_FOUND": "No suggestions found",
|
|
51
|
-
"CANNOT_DEACTIVATE_LAST_SITE": "Cannot deactivate the last active site"
|
|
62
|
+
"CANNOT_DEACTIVATE_LAST_SITE": "Cannot deactivate the last active site",
|
|
63
|
+
"DUPLICATE_SITE_NAME": "Bu ada sahip bir site zaten mevcut",
|
|
64
|
+
"INVALID_SITE_NAME": "Site adı yalnızca harf, rakam, tire ve alt çizgi içermelidir"
|
|
52
65
|
},
|
|
53
66
|
"TARGET": {
|
|
54
67
|
"airplanes": "uçaklar",
|
|
@@ -361,7 +374,8 @@
|
|
|
361
374
|
"I_AM_HUMAN": "Ben bir insanım",
|
|
362
375
|
"NO_ACCOUNTS_FOUND": "Hesap bulunamadı",
|
|
363
376
|
"ACCOUNT_NOT_FOUND": "Hesap bulunamadı",
|
|
364
|
-
"NO_EXTENSION_FOUND": "Eklenti bulunamadı"
|
|
377
|
+
"NO_EXTENSION_FOUND": "Eklenti bulunamadı",
|
|
378
|
+
"INSECURE_CONTEXT": "Procaptcha güvenli bir (HTTPS) bağlantı gerektirir"
|
|
365
379
|
},
|
|
366
380
|
"CONTRACT": {
|
|
367
381
|
"INVALID_ADDRESS": "Geçersiz adresi kodlama başarısız oldu",
|
|
@@ -422,6 +436,7 @@
|
|
|
422
436
|
"NO_CAPTCHA": "Hiçbir captcha bulunamadı",
|
|
423
437
|
"NO_SESSION_FOUND": "Oturum bulunamadı",
|
|
424
438
|
"IP_ADDRESS_MISMATCH": "IP adresleri eşleşmiyor",
|
|
439
|
+
"INVALID_SALT": "Geçersiz salt",
|
|
425
440
|
"INVALID_TOKEN": "Geçersiz belirteç",
|
|
426
441
|
"INVALID_SOLUTION": "Geçersiz çözüm",
|
|
427
442
|
"DECRYPTION_ERROR": "Şifreleme hatası"
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"ACCESS_POLICY_BLOCK": "Доступ заблоковано політикою",
|
|
22
22
|
"FORBIDDEN": "Forbidden",
|
|
23
23
|
"PROVIDER_VERIFY_FAILED": "Provider verification failed",
|
|
24
|
+
"SPAM_EMAIL_DOMAIN": "Домен електронної пошти не дозволено",
|
|
24
25
|
"UNAUTHORIZED": "Unauthorised",
|
|
25
26
|
"MISSING_BODY": "Missing body",
|
|
26
27
|
"NO_CONTENT_TYPE_HEADER": "No content-type header. Assumed JSON encoded body but failed to parse.",
|
|
@@ -40,7 +41,17 @@
|
|
|
40
41
|
"INVALID_IP": "Invalid IP",
|
|
41
42
|
"INVALID_URL": "Invalid URL",
|
|
42
43
|
"INVALID_BODY": "Invalid body",
|
|
43
|
-
"PARSE_ERROR": "Error parsing request"
|
|
44
|
+
"PARSE_ERROR": "Error parsing request",
|
|
45
|
+
"SPAM_EMAIL_RULE": "Адресу електронної пошти заблоковано правилами спам-фільтра",
|
|
46
|
+
"VPN_BLOCKED": "Запити з VPN-з'єднань не дозволені для цього сайту",
|
|
47
|
+
"PROXY_BLOCKED": "Запити з проксі-серверів не дозволені для цього сайту",
|
|
48
|
+
"TOR_BLOCKED": "Запити з вихідних вузлів Tor не дозволені для цього сайту",
|
|
49
|
+
"ABUSER_BLOCKED": "Запити з мереж, позначених за зловживання, не дозволені для цього сайту",
|
|
50
|
+
"DATACENTER_BLOCKED": "Запити з IP-адрес дата-центрів не дозволені для цього сайту",
|
|
51
|
+
"MOBILE_BLOCKED": "Запити з мобільних мережевих з'єднань не дозволені для цього сайту",
|
|
52
|
+
"SATELLITE_BLOCKED": "Запити із супутникових з'єднань не дозволені для цього сайту",
|
|
53
|
+
"CRAWLER_BLOCKED": "Запити від відомих пошукових роботів не дозволені для цього сайту",
|
|
54
|
+
"DISALLOWED_WEBVIEW": "Запити з вбудованих браузерів (WebView) не дозволені для цього сайту"
|
|
44
55
|
},
|
|
45
56
|
"PORTAL": {
|
|
46
57
|
"CANNOT_MODIFY_OWNER_USER": "Cannot modify owner user",
|
|
@@ -48,7 +59,9 @@
|
|
|
48
59
|
"CANNOT_DELETE_LAST_USER": "Cannot delete last user",
|
|
49
60
|
"USER_ALREADY_EXISTS": "User already exists",
|
|
50
61
|
"NO_SUGGESTIONS_FOUND": "No suggestions found",
|
|
51
|
-
"CANNOT_DEACTIVATE_LAST_SITE": "Cannot deactivate the last active site"
|
|
62
|
+
"CANNOT_DEACTIVATE_LAST_SITE": "Cannot deactivate the last active site",
|
|
63
|
+
"DUPLICATE_SITE_NAME": "Сайт із такою назвою вже існує",
|
|
64
|
+
"INVALID_SITE_NAME": "Назва сайту повинна містити лише літери, цифри, дефіси та символи підкреслення"
|
|
52
65
|
},
|
|
53
66
|
"TARGET": {
|
|
54
67
|
"airplanes": "aeroplanes",
|
|
@@ -361,7 +374,8 @@
|
|
|
361
374
|
"I_AM_HUMAN": "I am human",
|
|
362
375
|
"NO_ACCOUNTS_FOUND": "No accounts found",
|
|
363
376
|
"ACCOUNT_NOT_FOUND": "Account not found",
|
|
364
|
-
"NO_EXTENSION_FOUND": "No extension found"
|
|
377
|
+
"NO_EXTENSION_FOUND": "No extension found",
|
|
378
|
+
"INSECURE_CONTEXT": "Procaptcha потребує безпечного з'єднання (HTTPS)"
|
|
365
379
|
},
|
|
366
380
|
"CONTRACT": {
|
|
367
381
|
"INVALID_ADDRESS": "Failed to encode invalid address",
|
|
@@ -422,6 +436,7 @@
|
|
|
422
436
|
"NO_CAPTCHA": "No captcha found",
|
|
423
437
|
"NO_SESSION_FOUND": "No session found",
|
|
424
438
|
"IP_ADDRESS_MISMATCH": "IP address mismatch detected",
|
|
439
|
+
"INVALID_SALT": "Недійсна сіль",
|
|
425
440
|
"INVALID_TOKEN": "Invalid token",
|
|
426
441
|
"INVALID_SOLUTION": "Invalid solution",
|
|
427
442
|
"DECRYPTION_ERROR": "Error decrypting"
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"ACCESS_POLICY_BLOCK": "Truy cập bị chặn bởi chính sách",
|
|
22
22
|
"FORBIDDEN": "Bị cấm",
|
|
23
23
|
"PROVIDER_VERIFY_FAILED": "Xác thực nhà cung cấp không thành công",
|
|
24
|
+
"SPAM_EMAIL_DOMAIN": "Tên miền email không được phép",
|
|
24
25
|
"UNAUTHORIZED": "Không được phép",
|
|
25
26
|
"MISSING_BODY": "Thiếu nội dung",
|
|
26
27
|
"NO_CONTENT_TYPE_HEADER": "Không có tiêu đề content-type. Giả định nội dung được mã hóa JSON nhưng không thể phân tích.",
|
|
@@ -40,7 +41,17 @@
|
|
|
40
41
|
"INVALID_IP": "IP không hợp lệ",
|
|
41
42
|
"INVALID_URL": "URL không hợp lệ",
|
|
42
43
|
"INVALID_BODY": "Nội dung không hợp lệ",
|
|
43
|
-
"PARSE_ERROR": "Lỗi phân tích yêu cầu"
|
|
44
|
+
"PARSE_ERROR": "Lỗi phân tích yêu cầu",
|
|
45
|
+
"SPAM_EMAIL_RULE": "Địa chỉ email bị chặn bởi quy tắc bộ lọc spam",
|
|
46
|
+
"VPN_BLOCKED": "Các yêu cầu từ kết nối VPN không được phép cho trang web này",
|
|
47
|
+
"PROXY_BLOCKED": "Các yêu cầu từ máy chủ proxy không được phép cho trang web này",
|
|
48
|
+
"TOR_BLOCKED": "Các yêu cầu từ nút thoát Tor không được phép cho trang web này",
|
|
49
|
+
"ABUSER_BLOCKED": "Các yêu cầu từ mạng bị gắn cờ lạm dụng không được phép cho trang web này",
|
|
50
|
+
"DATACENTER_BLOCKED": "Các yêu cầu từ địa chỉ IP trung tâm dữ liệu không được phép cho trang web này",
|
|
51
|
+
"MOBILE_BLOCKED": "Các yêu cầu từ kết nối mạng di động không được phép cho trang web này",
|
|
52
|
+
"SATELLITE_BLOCKED": "Các yêu cầu từ kết nối vệ tinh không được phép cho trang web này",
|
|
53
|
+
"CRAWLER_BLOCKED": "Các yêu cầu từ trình thu thập dữ liệu đã biết không được phép cho trang web này",
|
|
54
|
+
"DISALLOWED_WEBVIEW": "Yêu cầu từ trình duyệt trong ứng dụng (WebView) không được phép cho trang web này"
|
|
44
55
|
},
|
|
45
56
|
"PORTAL": {
|
|
46
57
|
"CANNOT_MODIFY_OWNER_USER": "Không thể sửa đổi người dùng chủ sở hữu",
|
|
@@ -48,7 +59,9 @@
|
|
|
48
59
|
"CANNOT_DELETE_LAST_USER": "Không thể xóa người dùng cuối cùng",
|
|
49
60
|
"USER_ALREADY_EXISTS": "Người dùng đã tồn tại",
|
|
50
61
|
"NO_SUGGESTIONS_FOUND": "Không tìm thấy gợi ý nào",
|
|
51
|
-
"CANNOT_DEACTIVATE_LAST_SITE": "Không thể vô hiệu hóa trang cuối cùng hoạt động"
|
|
62
|
+
"CANNOT_DEACTIVATE_LAST_SITE": "Không thể vô hiệu hóa trang cuối cùng hoạt động",
|
|
63
|
+
"DUPLICATE_SITE_NAME": "Đã tồn tại một trang web với tên này",
|
|
64
|
+
"INVALID_SITE_NAME": "Tên trang web chỉ được chứa chữ cái, chữ số, dấu gạch ngang và dấu gạch dưới"
|
|
52
65
|
},
|
|
53
66
|
"TARGET": {
|
|
54
67
|
"airplanes": "máy bay",
|
|
@@ -361,7 +374,8 @@
|
|
|
361
374
|
"I_AM_HUMAN": "Tôi là con người",
|
|
362
375
|
"NO_ACCOUNTS_FOUND": "Không tìm thấy tài khoản",
|
|
363
376
|
"ACCOUNT_NOT_FOUND": "Không tìm thấy tài khoản",
|
|
364
|
-
"NO_EXTENSION_FOUND": "Không tìm thấy tiện ích"
|
|
377
|
+
"NO_EXTENSION_FOUND": "Không tìm thấy tiện ích",
|
|
378
|
+
"INSECURE_CONTEXT": "Procaptcha yêu cầu kết nối an toàn (HTTPS)"
|
|
365
379
|
},
|
|
366
380
|
"CONTRACT": {
|
|
367
381
|
"INVALID_ADDRESS": "Không thể mã hóa địa chỉ không hợp lệ",
|
|
@@ -422,6 +436,7 @@
|
|
|
422
436
|
"NO_CAPTCHA": "Không tìm thấy CAPTCHA",
|
|
423
437
|
"NO_SESSION_FOUND": "Không tìm thấy phiên",
|
|
424
438
|
"IP_ADDRESS_MISMATCH": "Phát hiện không khớp địa chỉ IP",
|
|
439
|
+
"INVALID_SALT": "Salt không hợp lệ",
|
|
425
440
|
"INVALID_TOKEN": "Token không hợp lệ",
|
|
426
441
|
"INVALID_SOLUTION": "Giải pháp không hợp lệ",
|
|
427
442
|
"DECRYPTION_ERROR": "Lỗi giải mã"
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"ACCESS_POLICY_BLOCK": "访问被策略阻止",
|
|
22
22
|
"FORBIDDEN": "禁止",
|
|
23
23
|
"PROVIDER_VERIFY_FAILED": "提供商验证失败",
|
|
24
|
+
"SPAM_EMAIL_DOMAIN": "不允许此电子邮件域名",
|
|
24
25
|
"UNAUTHORIZED": "未授权",
|
|
25
26
|
"MISSING_BODY": "缺少主体",
|
|
26
27
|
"NO_CONTENT_TYPE_HEADER": "没有内容类型标头。假定为JSON编码主体,但无法解析。",
|
|
@@ -40,7 +41,17 @@
|
|
|
40
41
|
"INVALID_IP": "无效的IP",
|
|
41
42
|
"INVALID_URL": "无效的URL",
|
|
42
43
|
"INVALID_BODY": "无效的主体",
|
|
43
|
-
"PARSE_ERROR": "解析请求时出错"
|
|
44
|
+
"PARSE_ERROR": "解析请求时出错",
|
|
45
|
+
"SPAM_EMAIL_RULE": "电子邮件地址被垃圾邮件过滤规则拦截",
|
|
46
|
+
"VPN_BLOCKED": "此网站不允许来自VPN连接的请求",
|
|
47
|
+
"PROXY_BLOCKED": "此网站不允许来自代理服务器的请求",
|
|
48
|
+
"TOR_BLOCKED": "此网站不允许来自Tor出口节点的请求",
|
|
49
|
+
"ABUSER_BLOCKED": "此网站不允许来自被标记为滥用的网络的请求",
|
|
50
|
+
"DATACENTER_BLOCKED": "此网站不允许来自数据中心IP地址的请求",
|
|
51
|
+
"MOBILE_BLOCKED": "此网站不允许来自移动网络连接的请求",
|
|
52
|
+
"SATELLITE_BLOCKED": "此网站不允许来自卫星连接的请求",
|
|
53
|
+
"CRAWLER_BLOCKED": "此网站不允许来自已知爬虫的请求",
|
|
54
|
+
"DISALLOWED_WEBVIEW": "此站点不允许来自应用内浏览器 (WebView) 的请求"
|
|
44
55
|
},
|
|
45
56
|
"PORTAL": {
|
|
46
57
|
"CANNOT_MODIFY_OWNER_USER": "无法修改所有者用户",
|
|
@@ -48,7 +59,9 @@
|
|
|
48
59
|
"CANNOT_DELETE_LAST_USER": "无法删除最后一个用户",
|
|
49
60
|
"USER_ALREADY_EXISTS": "用户已经存在",
|
|
50
61
|
"NO_SUGGESTIONS_FOUND": "未找到建议",
|
|
51
|
-
"CANNOT_DEACTIVATE_LAST_SITE": "无法停用最后一个活动站点"
|
|
62
|
+
"CANNOT_DEACTIVATE_LAST_SITE": "无法停用最后一个活动站点",
|
|
63
|
+
"DUPLICATE_SITE_NAME": "已存在同名站点",
|
|
64
|
+
"INVALID_SITE_NAME": "站点名称只能包含字母、数字、连字符和下划线"
|
|
52
65
|
},
|
|
53
66
|
"TARGET": {
|
|
54
67
|
"airplanes": "飞机",
|
|
@@ -361,7 +374,8 @@
|
|
|
361
374
|
"I_AM_HUMAN": "我是人类",
|
|
362
375
|
"NO_ACCOUNTS_FOUND": "找不到帐户",
|
|
363
376
|
"ACCOUNT_NOT_FOUND": "找不到帐户",
|
|
364
|
-
"NO_EXTENSION_FOUND": "找不到扩展"
|
|
377
|
+
"NO_EXTENSION_FOUND": "找不到扩展",
|
|
378
|
+
"INSECURE_CONTEXT": "Procaptcha 需要安全连接 (HTTPS)"
|
|
365
379
|
},
|
|
366
380
|
"CONTRACT": {
|
|
367
381
|
"INVALID_ADDRESS": "无法编码无效地址",
|
|
@@ -422,6 +436,7 @@
|
|
|
422
436
|
"NO_CAPTCHA": "找不到验证码",
|
|
423
437
|
"NO_SESSION_FOUND": "找不到会话",
|
|
424
438
|
"IP_ADDRESS_MISMATCH": "检测到 IP 地址不匹配",
|
|
439
|
+
"INVALID_SALT": "盐值无效",
|
|
425
440
|
"INVALID_TOKEN": "无效的令牌",
|
|
426
441
|
"INVALID_SOLUTION": "无效的解决方案",
|
|
427
442
|
"DECRYPTION_ERROR": "解密错误"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prosopo/locale",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.5",
|
|
4
4
|
"description": "Prosopo locale library",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"zod": "3.23.8"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@prosopo/config": "3.3.
|
|
46
|
+
"@prosopo/config": "3.3.2",
|
|
47
47
|
"@types/node": "22.10.2",
|
|
48
48
|
"@vitest/coverage-v8": "3.2.4",
|
|
49
49
|
"concurrently": "9.0.1",
|
|
@@ -58,7 +58,8 @@
|
|
|
58
58
|
},
|
|
59
59
|
"repository": {
|
|
60
60
|
"type": "git",
|
|
61
|
-
"url": "git+https://github.com/prosopo/captcha.git"
|
|
61
|
+
"url": "git+https://github.com/prosopo/captcha.git",
|
|
62
|
+
"directory": "packages/locale"
|
|
62
63
|
},
|
|
63
64
|
"bugs": {
|
|
64
65
|
"url": "https://github.com/prosopo/captcha/issues"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import { LanguageSchema, Languages } from "./translations.js";
|
|
15
|
+
|
|
16
|
+
// Guard the `process.env` read so the module is loadable in a plain browser
|
|
17
|
+
// runtime where `process` is undefined. Without the guard, any side-effectful
|
|
18
|
+
// runtime import of `@prosopo/types` (which transitively reaches here via
|
|
19
|
+
// `LanguageSchema`) crashes the page in Vite's dev/preview mode.
|
|
20
|
+
const logLevel =
|
|
21
|
+
typeof process !== "undefined" ? process.env?.PROSOPO_LOG_LEVEL : undefined;
|
|
22
|
+
|
|
23
|
+
export const i18nSharedOptions = {
|
|
24
|
+
debug: logLevel === "debug",
|
|
25
|
+
fallbackLng: LanguageSchema.enum.en,
|
|
26
|
+
namespace: "translation",
|
|
27
|
+
supportedLngs: Object.values(Languages),
|
|
28
|
+
nonExplicitSupportedLngs: false,
|
|
29
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
import i18n from "i18next";
|
|
17
|
+
import FSBackend from "i18next-fs-backend/cjs"; // https://github.com/i18next/i18next-fs-backend/issues/57
|
|
18
|
+
import { LanguageDetector as MiddlewareLanguageDetector } from "i18next-http-middleware";
|
|
19
|
+
import { i18nSharedOptions } from "./i18SharedOptions.js";
|
|
20
|
+
import { isServerSide } from "./util.js";
|
|
21
|
+
|
|
22
|
+
const loadPath =
|
|
23
|
+
`${path.dirname(import.meta.url)}/locales/{{lng}}/{{ns}}.json`.replace(
|
|
24
|
+
"file://",
|
|
25
|
+
"",
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export function initializeI18n(
|
|
29
|
+
i18nLoadedCallback?: (value: typeof i18n) => void,
|
|
30
|
+
) {
|
|
31
|
+
if (!i18n.isInitialized && isServerSide()) {
|
|
32
|
+
const lngDetector = new MiddlewareLanguageDetector(null, {
|
|
33
|
+
order: ["header", "query", "cookie"],
|
|
34
|
+
});
|
|
35
|
+
i18n
|
|
36
|
+
// @ts-ignore https://github.com/i18next/i18next-fs-backend/issues/57
|
|
37
|
+
.use(FSBackend)
|
|
38
|
+
.use(lngDetector) // this line should switch the language to the one the user reports in the Accept-Language header
|
|
39
|
+
.init({
|
|
40
|
+
...i18nSharedOptions,
|
|
41
|
+
ns: ["translation"],
|
|
42
|
+
backend: {
|
|
43
|
+
loadPath,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
i18n.on("loaded", () => {
|
|
47
|
+
i18nLoadedCallback?.(i18n);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return i18n;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export default initializeI18n;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
import i18n, { type InitOptions } from "i18next";
|
|
16
|
+
import I18nextBrowserLanguageDetector from "i18next-browser-languagedetector";
|
|
17
|
+
import ChainedBackend from "i18next-chained-backend";
|
|
18
|
+
import HttpBackend from "i18next-http-backend";
|
|
19
|
+
import resourcesToBackend from "i18next-resources-to-backend";
|
|
20
|
+
import { initReactI18next } from "react-i18next";
|
|
21
|
+
import { i18nSharedOptions } from "./i18SharedOptions.js";
|
|
22
|
+
|
|
23
|
+
const reactOptions: InitOptions = {
|
|
24
|
+
react: {
|
|
25
|
+
useSuspense: true,
|
|
26
|
+
},
|
|
27
|
+
detection: {
|
|
28
|
+
order: ["navigator", "htmlTag", "path", "subdomain"],
|
|
29
|
+
caches: ["localStorage", "cookie"],
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const getLoadPath = (language: string, namespace: string) => {
|
|
34
|
+
const filename = import.meta.url.split("/").pop();
|
|
35
|
+
return `${import.meta.url.replace(`/${filename}`, "")}/locales/${language}/${namespace}.json`;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export function initializeI18n(
|
|
39
|
+
i18nLoadedCallback?: (value: typeof i18n) => void,
|
|
40
|
+
) {
|
|
41
|
+
if (!i18n.isInitialized) {
|
|
42
|
+
i18n
|
|
43
|
+
// @ts-ignore
|
|
44
|
+
.use(ChainedBackend)
|
|
45
|
+
.use(
|
|
46
|
+
new I18nextBrowserLanguageDetector(null, {
|
|
47
|
+
order: ["cookie", "localStorage", "navigator"],
|
|
48
|
+
lookupQuerystring: "lng",
|
|
49
|
+
lookupCookie: "i18next",
|
|
50
|
+
lookupLocalStorage: "i18nextLng",
|
|
51
|
+
caches: ["localStorage", "cookie"],
|
|
52
|
+
}),
|
|
53
|
+
)
|
|
54
|
+
.use(initReactI18next)
|
|
55
|
+
.init({
|
|
56
|
+
...i18nSharedOptions,
|
|
57
|
+
backend: {
|
|
58
|
+
backends: [
|
|
59
|
+
HttpBackend, // if a namespace can't be loaded via normal http-backend loadPath, then the inMemoryLocalBackend will try to return the correct resources
|
|
60
|
+
// with dynamic import, you have to use the "default" key of the module ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#importing_defaults )
|
|
61
|
+
resourcesToBackend(
|
|
62
|
+
(language: string, namespace: string) =>
|
|
63
|
+
import(getLoadPath(language, namespace)),
|
|
64
|
+
),
|
|
65
|
+
],
|
|
66
|
+
backendOptions: [
|
|
67
|
+
{
|
|
68
|
+
loadPath: getLoadPath("{{lng}}", "{{ns}}"),
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
...reactOptions,
|
|
73
|
+
} as InitOptions);
|
|
74
|
+
i18n.on("loaded", () => {
|
|
75
|
+
i18nLoadedCallback?.(i18n);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return i18n;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export default initializeI18n;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
import { type HandleOptions, handle } from "i18next-http-middleware";
|
|
16
|
+
import loadI18next from "./loadI18next.js";
|
|
17
|
+
|
|
18
|
+
async function i18nMiddleware(
|
|
19
|
+
options: HandleOptions,
|
|
20
|
+
): Promise<ReturnType<typeof handle>> {
|
|
21
|
+
const i18n = await loadI18next(true);
|
|
22
|
+
return handle(i18n, { ...options });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export default i18nMiddleware;
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
export { default as i18nMiddleware } from "./i18nMiddleware.js";
|
|
16
|
+
export { default as loadI18next } from "./loadI18next.js";
|
|
17
|
+
export { Languages, LanguageSchema } from "./translations.js";
|
|
18
|
+
export { isClientSide } from "./util.js";
|
|
19
|
+
export { TranslationKeysSchema } from "./translationKey.js";
|
|
20
|
+
export type { TranslationKey } from "./translationKey.js";
|
|
21
|
+
export { default as useTranslation } from "./useTranslation.js";
|
|
22
|
+
export type { Ti18n } from "./loadI18next.js";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
import type { i18n } from "i18next";
|
|
16
|
+
let i18nInstance: i18n;
|
|
17
|
+
async function loadI18next(backend: boolean): Promise<i18n> {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
try {
|
|
20
|
+
if (backend) {
|
|
21
|
+
import("./i18nBackend.js").then(({ default: initializeI18n }) => {
|
|
22
|
+
if (!i18nInstance) {
|
|
23
|
+
// pass the resolver into the i18n init fn which will resolve after i18n connected fires
|
|
24
|
+
i18nInstance = initializeI18n(resolve);
|
|
25
|
+
} else {
|
|
26
|
+
// we've already initialised i18n so just return it
|
|
27
|
+
resolve(i18nInstance);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
} else {
|
|
31
|
+
import("./i18nFrontend.js").then(({ default: initializeI18n }) => {
|
|
32
|
+
if (!i18nInstance) {
|
|
33
|
+
// pass the resolver into the i18 init fn which will resolve after i18 connected fires
|
|
34
|
+
i18nInstance = initializeI18n(resolve);
|
|
35
|
+
} else {
|
|
36
|
+
// we've already initialised i18n so just return it
|
|
37
|
+
resolve(i18nInstance);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
} catch (e) {
|
|
42
|
+
reject(e);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type { i18n as Ti18n };
|
|
48
|
+
|
|
49
|
+
export default loadI18next;
|