@zachhandley/ez-i18n 0.3.3 → 0.3.4

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.d.ts CHANGED
@@ -2,6 +2,43 @@ import { AstroIntegration } from 'astro';
2
2
  import { E as EzI18nConfig } from './types-Cg77gLzO.js';
3
3
  export { T as TranslateFunction } from './types-Cg77gLzO.js';
4
4
 
5
+ /**
6
+ * Comprehensive locale database for ez-i18n
7
+ * Contains display names (in native language) and BCP47 codes
8
+ */
9
+ interface LocaleInfo {
10
+ /** Display name in native language */
11
+ name: string;
12
+ /** Display name in English */
13
+ englishName: string;
14
+ /** BCP47 language tag */
15
+ bcp47: string;
16
+ /** Text direction */
17
+ dir: 'ltr' | 'rtl';
18
+ }
19
+ /**
20
+ * Comprehensive mapping of locale codes to their metadata
21
+ * Covers all major languages and regional variants
22
+ */
23
+ declare const LOCALE_DATABASE: Record<string, LocaleInfo>;
24
+ /**
25
+ * Get locale info for a given locale code
26
+ * Falls back to a generated entry if not found
27
+ */
28
+ declare function getLocaleInfo(locale: string): LocaleInfo;
29
+ /**
30
+ * Build locale names mapping for discovered locales
31
+ */
32
+ declare function buildLocaleNames(locales: string[]): Record<string, string>;
33
+ /**
34
+ * Build locale to BCP47 mapping for discovered locales
35
+ */
36
+ declare function buildLocaleToBCP47(locales: string[]): Record<string, string>;
37
+ /**
38
+ * Build locale directions mapping for discovered locales
39
+ */
40
+ declare function buildLocaleDirections(locales: string[]): Record<string, 'ltr' | 'rtl'>;
41
+
5
42
  /**
6
43
  * ez-i18n Astro integration
7
44
  *
@@ -26,4 +63,4 @@ export { T as TranslateFunction } from './types-Cg77gLzO.js';
26
63
  */
27
64
  declare function ezI18n(config: EzI18nConfig): AstroIntegration;
28
65
 
29
- export { EzI18nConfig, ezI18n as default };
66
+ export { EzI18nConfig, LOCALE_DATABASE, type LocaleInfo, buildLocaleDirections, buildLocaleNames, buildLocaleToBCP47, ezI18n as default, getLocaleInfo };
package/dist/index.js CHANGED
@@ -194,6 +194,168 @@ function __wrapWithNamespace(namespace, content) {
194
194
  }`;
195
195
  }
196
196
 
197
+ // src/utils/locales.ts
198
+ var LOCALE_DATABASE = {
199
+ // Major Western European Languages
200
+ en: { name: "English", englishName: "English", bcp47: "en-US", dir: "ltr" },
201
+ "en-US": { name: "English (US)", englishName: "English (US)", bcp47: "en-US", dir: "ltr" },
202
+ "en-GB": { name: "English (UK)", englishName: "English (UK)", bcp47: "en-GB", dir: "ltr" },
203
+ "en-AU": { name: "English (Australia)", englishName: "English (Australia)", bcp47: "en-AU", dir: "ltr" },
204
+ "en-CA": { name: "English (Canada)", englishName: "English (Canada)", bcp47: "en-CA", dir: "ltr" },
205
+ de: { name: "Deutsch", englishName: "German", bcp47: "de-DE", dir: "ltr" },
206
+ "de-DE": { name: "Deutsch (Deutschland)", englishName: "German (Germany)", bcp47: "de-DE", dir: "ltr" },
207
+ "de-AT": { name: "Deutsch (\xD6sterreich)", englishName: "German (Austria)", bcp47: "de-AT", dir: "ltr" },
208
+ "de-CH": { name: "Deutsch (Schweiz)", englishName: "German (Switzerland)", bcp47: "de-CH", dir: "ltr" },
209
+ fr: { name: "Fran\xE7ais", englishName: "French", bcp47: "fr-FR", dir: "ltr" },
210
+ "fr-FR": { name: "Fran\xE7ais (France)", englishName: "French (France)", bcp47: "fr-FR", dir: "ltr" },
211
+ "fr-CA": { name: "Fran\xE7ais (Canada)", englishName: "French (Canada)", bcp47: "fr-CA", dir: "ltr" },
212
+ "fr-BE": { name: "Fran\xE7ais (Belgique)", englishName: "French (Belgium)", bcp47: "fr-BE", dir: "ltr" },
213
+ "fr-CH": { name: "Fran\xE7ais (Suisse)", englishName: "French (Switzerland)", bcp47: "fr-CH", dir: "ltr" },
214
+ es: { name: "Espa\xF1ol", englishName: "Spanish", bcp47: "es-ES", dir: "ltr" },
215
+ "es-ES": { name: "Espa\xF1ol (Espa\xF1a)", englishName: "Spanish (Spain)", bcp47: "es-ES", dir: "ltr" },
216
+ "es-MX": { name: "Espa\xF1ol (M\xE9xico)", englishName: "Spanish (Mexico)", bcp47: "es-MX", dir: "ltr" },
217
+ "es-AR": { name: "Espa\xF1ol (Argentina)", englishName: "Spanish (Argentina)", bcp47: "es-AR", dir: "ltr" },
218
+ "es-CO": { name: "Espa\xF1ol (Colombia)", englishName: "Spanish (Colombia)", bcp47: "es-CO", dir: "ltr" },
219
+ "es-419": { name: "Espa\xF1ol (Latinoam\xE9rica)", englishName: "Spanish (Latin America)", bcp47: "es-419", dir: "ltr" },
220
+ it: { name: "Italiano", englishName: "Italian", bcp47: "it-IT", dir: "ltr" },
221
+ "it-IT": { name: "Italiano (Italia)", englishName: "Italian (Italy)", bcp47: "it-IT", dir: "ltr" },
222
+ "it-CH": { name: "Italiano (Svizzera)", englishName: "Italian (Switzerland)", bcp47: "it-CH", dir: "ltr" },
223
+ pt: { name: "Portugu\xEAs", englishName: "Portuguese", bcp47: "pt-PT", dir: "ltr" },
224
+ "pt-PT": { name: "Portugu\xEAs (Portugal)", englishName: "Portuguese (Portugal)", bcp47: "pt-PT", dir: "ltr" },
225
+ "pt-BR": { name: "Portugu\xEAs (Brasil)", englishName: "Portuguese (Brazil)", bcp47: "pt-BR", dir: "ltr" },
226
+ nl: { name: "Nederlands", englishName: "Dutch", bcp47: "nl-NL", dir: "ltr" },
227
+ "nl-NL": { name: "Nederlands (Nederland)", englishName: "Dutch (Netherlands)", bcp47: "nl-NL", dir: "ltr" },
228
+ "nl-BE": { name: "Nederlands (Belgi\xEB)", englishName: "Dutch (Belgium)", bcp47: "nl-BE", dir: "ltr" },
229
+ // Nordic Languages
230
+ sv: { name: "Svenska", englishName: "Swedish", bcp47: "sv-SE", dir: "ltr" },
231
+ "sv-SE": { name: "Svenska (Sverige)", englishName: "Swedish (Sweden)", bcp47: "sv-SE", dir: "ltr" },
232
+ da: { name: "Dansk", englishName: "Danish", bcp47: "da-DK", dir: "ltr" },
233
+ "da-DK": { name: "Dansk (Danmark)", englishName: "Danish (Denmark)", bcp47: "da-DK", dir: "ltr" },
234
+ no: { name: "Norsk", englishName: "Norwegian", bcp47: "nb-NO", dir: "ltr" },
235
+ nb: { name: "Norsk bokm\xE5l", englishName: "Norwegian Bokm\xE5l", bcp47: "nb-NO", dir: "ltr" },
236
+ nn: { name: "Norsk nynorsk", englishName: "Norwegian Nynorsk", bcp47: "nn-NO", dir: "ltr" },
237
+ fi: { name: "Suomi", englishName: "Finnish", bcp47: "fi-FI", dir: "ltr" },
238
+ "fi-FI": { name: "Suomi (Suomi)", englishName: "Finnish (Finland)", bcp47: "fi-FI", dir: "ltr" },
239
+ is: { name: "\xCDslenska", englishName: "Icelandic", bcp47: "is-IS", dir: "ltr" },
240
+ // Eastern European Languages
241
+ pl: { name: "Polski", englishName: "Polish", bcp47: "pl-PL", dir: "ltr" },
242
+ "pl-PL": { name: "Polski (Polska)", englishName: "Polish (Poland)", bcp47: "pl-PL", dir: "ltr" },
243
+ cs: { name: "\u010Ce\u0161tina", englishName: "Czech", bcp47: "cs-CZ", dir: "ltr" },
244
+ "cs-CZ": { name: "\u010Ce\u0161tina (\u010Cesko)", englishName: "Czech (Czech Republic)", bcp47: "cs-CZ", dir: "ltr" },
245
+ sk: { name: "Sloven\u010Dina", englishName: "Slovak", bcp47: "sk-SK", dir: "ltr" },
246
+ "sk-SK": { name: "Sloven\u010Dina (Slovensko)", englishName: "Slovak (Slovakia)", bcp47: "sk-SK", dir: "ltr" },
247
+ hu: { name: "Magyar", englishName: "Hungarian", bcp47: "hu-HU", dir: "ltr" },
248
+ "hu-HU": { name: "Magyar (Magyarorsz\xE1g)", englishName: "Hungarian (Hungary)", bcp47: "hu-HU", dir: "ltr" },
249
+ ro: { name: "Rom\xE2n\u0103", englishName: "Romanian", bcp47: "ro-RO", dir: "ltr" },
250
+ "ro-RO": { name: "Rom\xE2n\u0103 (Rom\xE2nia)", englishName: "Romanian (Romania)", bcp47: "ro-RO", dir: "ltr" },
251
+ bg: { name: "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", englishName: "Bulgarian", bcp47: "bg-BG", dir: "ltr" },
252
+ "bg-BG": { name: "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438 (\u0411\u044A\u043B\u0433\u0430\u0440\u0438\u044F)", englishName: "Bulgarian (Bulgaria)", bcp47: "bg-BG", dir: "ltr" },
253
+ hr: { name: "Hrvatski", englishName: "Croatian", bcp47: "hr-HR", dir: "ltr" },
254
+ sr: { name: "\u0421\u0440\u043F\u0441\u043A\u0438", englishName: "Serbian", bcp47: "sr-RS", dir: "ltr" },
255
+ sl: { name: "Sloven\u0161\u010Dina", englishName: "Slovenian", bcp47: "sl-SI", dir: "ltr" },
256
+ uk: { name: "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", englishName: "Ukrainian", bcp47: "uk-UA", dir: "ltr" },
257
+ "uk-UA": { name: "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430 (\u0423\u043A\u0440\u0430\u0457\u043D\u0430)", englishName: "Ukrainian (Ukraine)", bcp47: "uk-UA", dir: "ltr" },
258
+ ru: { name: "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", englishName: "Russian", bcp47: "ru-RU", dir: "ltr" },
259
+ "ru-RU": { name: "\u0420\u0443\u0441\u0441\u043A\u0438\u0439 (\u0420\u043E\u0441\u0441\u0438\u044F)", englishName: "Russian (Russia)", bcp47: "ru-RU", dir: "ltr" },
260
+ // Baltic Languages
261
+ lt: { name: "Lietuvi\u0173", englishName: "Lithuanian", bcp47: "lt-LT", dir: "ltr" },
262
+ lv: { name: "Latvie\u0161u", englishName: "Latvian", bcp47: "lv-LV", dir: "ltr" },
263
+ et: { name: "Eesti", englishName: "Estonian", bcp47: "et-EE", dir: "ltr" },
264
+ // Greek
265
+ el: { name: "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", englishName: "Greek", bcp47: "el-GR", dir: "ltr" },
266
+ "el-GR": { name: "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC (\u0395\u03BB\u03BB\u03AC\u03B4\u03B1)", englishName: "Greek (Greece)", bcp47: "el-GR", dir: "ltr" },
267
+ // Asian Languages
268
+ zh: { name: "\u4E2D\u6587", englishName: "Chinese", bcp47: "zh-CN", dir: "ltr" },
269
+ "zh-CN": { name: "\u4E2D\u6587 (\u7B80\u4F53)", englishName: "Chinese (Simplified)", bcp47: "zh-CN", dir: "ltr" },
270
+ "zh-TW": { name: "\u4E2D\u6587 (\u7E41\u9AD4)", englishName: "Chinese (Traditional)", bcp47: "zh-TW", dir: "ltr" },
271
+ "zh-HK": { name: "\u4E2D\u6587 (\u9999\u6E2F)", englishName: "Chinese (Hong Kong)", bcp47: "zh-HK", dir: "ltr" },
272
+ ja: { name: "\u65E5\u672C\u8A9E", englishName: "Japanese", bcp47: "ja-JP", dir: "ltr" },
273
+ "ja-JP": { name: "\u65E5\u672C\u8A9E (\u65E5\u672C)", englishName: "Japanese (Japan)", bcp47: "ja-JP", dir: "ltr" },
274
+ ko: { name: "\uD55C\uAD6D\uC5B4", englishName: "Korean", bcp47: "ko-KR", dir: "ltr" },
275
+ "ko-KR": { name: "\uD55C\uAD6D\uC5B4 (\uB300\uD55C\uBBFC\uAD6D)", englishName: "Korean (South Korea)", bcp47: "ko-KR", dir: "ltr" },
276
+ vi: { name: "Ti\u1EBFng Vi\u1EC7t", englishName: "Vietnamese", bcp47: "vi-VN", dir: "ltr" },
277
+ "vi-VN": { name: "Ti\u1EBFng Vi\u1EC7t (Vi\u1EC7t Nam)", englishName: "Vietnamese (Vietnam)", bcp47: "vi-VN", dir: "ltr" },
278
+ th: { name: "\u0E44\u0E17\u0E22", englishName: "Thai", bcp47: "th-TH", dir: "ltr" },
279
+ "th-TH": { name: "\u0E44\u0E17\u0E22 (\u0E1B\u0E23\u0E30\u0E40\u0E17\u0E28\u0E44\u0E17\u0E22)", englishName: "Thai (Thailand)", bcp47: "th-TH", dir: "ltr" },
280
+ id: { name: "Bahasa Indonesia", englishName: "Indonesian", bcp47: "id-ID", dir: "ltr" },
281
+ "id-ID": { name: "Bahasa Indonesia (Indonesia)", englishName: "Indonesian (Indonesia)", bcp47: "id-ID", dir: "ltr" },
282
+ ms: { name: "Bahasa Melayu", englishName: "Malay", bcp47: "ms-MY", dir: "ltr" },
283
+ "ms-MY": { name: "Bahasa Melayu (Malaysia)", englishName: "Malay (Malaysia)", bcp47: "ms-MY", dir: "ltr" },
284
+ tl: { name: "Tagalog", englishName: "Tagalog", bcp47: "tl-PH", dir: "ltr" },
285
+ fil: { name: "Filipino", englishName: "Filipino", bcp47: "fil-PH", dir: "ltr" },
286
+ // South Asian Languages
287
+ hi: { name: "\u0939\u093F\u0928\u094D\u0926\u0940", englishName: "Hindi", bcp47: "hi-IN", dir: "ltr" },
288
+ "hi-IN": { name: "\u0939\u093F\u0928\u094D\u0926\u0940 (\u092D\u093E\u0930\u0924)", englishName: "Hindi (India)", bcp47: "hi-IN", dir: "ltr" },
289
+ bn: { name: "\u09AC\u09BE\u0982\u09B2\u09BE", englishName: "Bengali", bcp47: "bn-BD", dir: "ltr" },
290
+ "bn-BD": { name: "\u09AC\u09BE\u0982\u09B2\u09BE (\u09AC\u09BE\u0982\u09B2\u09BE\u09A6\u09C7\u09B6)", englishName: "Bengali (Bangladesh)", bcp47: "bn-BD", dir: "ltr" },
291
+ "bn-IN": { name: "\u09AC\u09BE\u0982\u09B2\u09BE (\u09AD\u09BE\u09B0\u09A4)", englishName: "Bengali (India)", bcp47: "bn-IN", dir: "ltr" },
292
+ ta: { name: "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", englishName: "Tamil", bcp47: "ta-IN", dir: "ltr" },
293
+ te: { name: "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", englishName: "Telugu", bcp47: "te-IN", dir: "ltr" },
294
+ mr: { name: "\u092E\u0930\u093E\u0920\u0940", englishName: "Marathi", bcp47: "mr-IN", dir: "ltr" },
295
+ gu: { name: "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", englishName: "Gujarati", bcp47: "gu-IN", dir: "ltr" },
296
+ kn: { name: "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", englishName: "Kannada", bcp47: "kn-IN", dir: "ltr" },
297
+ ml: { name: "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", englishName: "Malayalam", bcp47: "ml-IN", dir: "ltr" },
298
+ pa: { name: "\u0A2A\u0A70\u0A1C\u0A3E\u0A2C\u0A40", englishName: "Punjabi", bcp47: "pa-IN", dir: "ltr" },
299
+ ur: { name: "\u0627\u0631\u062F\u0648", englishName: "Urdu", bcp47: "ur-PK", dir: "rtl" },
300
+ // Middle Eastern Languages (RTL)
301
+ ar: { name: "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", englishName: "Arabic", bcp47: "ar-SA", dir: "rtl" },
302
+ "ar-SA": { name: "\u0627\u0644\u0639\u0631\u0628\u064A\u0629 (\u0627\u0644\u0633\u0639\u0648\u062F\u064A\u0629)", englishName: "Arabic (Saudi Arabia)", bcp47: "ar-SA", dir: "rtl" },
303
+ "ar-EG": { name: "\u0627\u0644\u0639\u0631\u0628\u064A\u0629 (\u0645\u0635\u0631)", englishName: "Arabic (Egypt)", bcp47: "ar-EG", dir: "rtl" },
304
+ "ar-AE": { name: "\u0627\u0644\u0639\u0631\u0628\u064A\u0629 (\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062A)", englishName: "Arabic (UAE)", bcp47: "ar-AE", dir: "rtl" },
305
+ he: { name: "\u05E2\u05D1\u05E8\u05D9\u05EA", englishName: "Hebrew", bcp47: "he-IL", dir: "rtl" },
306
+ "he-IL": { name: "\u05E2\u05D1\u05E8\u05D9\u05EA (\u05D9\u05E9\u05E8\u05D0\u05DC)", englishName: "Hebrew (Israel)", bcp47: "he-IL", dir: "rtl" },
307
+ fa: { name: "\u0641\u0627\u0631\u0633\u06CC", englishName: "Persian", bcp47: "fa-IR", dir: "rtl" },
308
+ "fa-IR": { name: "\u0641\u0627\u0631\u0633\u06CC (\u0627\u06CC\u0631\u0627\u0646)", englishName: "Persian (Iran)", bcp47: "fa-IR", dir: "rtl" },
309
+ tr: { name: "T\xFCrk\xE7e", englishName: "Turkish", bcp47: "tr-TR", dir: "ltr" },
310
+ "tr-TR": { name: "T\xFCrk\xE7e (T\xFCrkiye)", englishName: "Turkish (Turkey)", bcp47: "tr-TR", dir: "ltr" },
311
+ // African Languages
312
+ sw: { name: "Kiswahili", englishName: "Swahili", bcp47: "sw-KE", dir: "ltr" },
313
+ af: { name: "Afrikaans", englishName: "Afrikaans", bcp47: "af-ZA", dir: "ltr" },
314
+ zu: { name: "isiZulu", englishName: "Zulu", bcp47: "zu-ZA", dir: "ltr" },
315
+ // Celtic Languages
316
+ cy: { name: "Cymraeg", englishName: "Welsh", bcp47: "cy-GB", dir: "ltr" },
317
+ ga: { name: "Gaeilge", englishName: "Irish", bcp47: "ga-IE", dir: "ltr" },
318
+ gd: { name: "G\xE0idhlig", englishName: "Scottish Gaelic", bcp47: "gd-GB", dir: "ltr" },
319
+ // Other European Languages
320
+ ca: { name: "Catal\xE0", englishName: "Catalan", bcp47: "ca-ES", dir: "ltr" },
321
+ eu: { name: "Euskara", englishName: "Basque", bcp47: "eu-ES", dir: "ltr" },
322
+ gl: { name: "Galego", englishName: "Galician", bcp47: "gl-ES", dir: "ltr" },
323
+ // Constructed Languages
324
+ eo: { name: "Esperanto", englishName: "Esperanto", bcp47: "eo", dir: "ltr" }
325
+ };
326
+ function getLocaleInfo(locale) {
327
+ if (LOCALE_DATABASE[locale]) {
328
+ return LOCALE_DATABASE[locale];
329
+ }
330
+ return {
331
+ name: locale.toUpperCase(),
332
+ englishName: locale.toUpperCase(),
333
+ bcp47: locale,
334
+ dir: "ltr"
335
+ };
336
+ }
337
+ function buildLocaleNames(locales) {
338
+ const names = {};
339
+ for (const locale of locales) {
340
+ names[locale] = getLocaleInfo(locale).name;
341
+ }
342
+ return names;
343
+ }
344
+ function buildLocaleToBCP47(locales) {
345
+ const bcp47 = {};
346
+ for (const locale of locales) {
347
+ bcp47[locale] = getLocaleInfo(locale).bcp47;
348
+ }
349
+ return bcp47;
350
+ }
351
+ function buildLocaleDirections(locales) {
352
+ const dirs = {};
353
+ for (const locale of locales) {
354
+ dirs[locale] = getLocaleInfo(locale).dir;
355
+ }
356
+ return dirs;
357
+ }
358
+
197
359
  // src/vite-plugin.ts
198
360
  import * as path2 from "path";
199
361
  var VIRTUAL_CONFIG = "ez-i18n:config";
@@ -319,10 +481,22 @@ function vitePlugin(config) {
319
481
  },
320
482
  load(id) {
321
483
  if (id === RESOLVED_PREFIX + VIRTUAL_CONFIG) {
484
+ const localeNames = buildLocaleNames(resolved.locales);
485
+ const localeToBCP47 = buildLocaleToBCP47(resolved.locales);
486
+ const localeDirections = buildLocaleDirections(resolved.locales);
322
487
  return `
323
488
  export const locales = ${JSON.stringify(resolved.locales)};
324
489
  export const defaultLocale = ${JSON.stringify(resolved.defaultLocale)};
325
490
  export const cookieName = ${JSON.stringify(resolved.cookieName)};
491
+
492
+ /** Display names for each locale (in native language) */
493
+ export const localeNames = ${JSON.stringify(localeNames)};
494
+
495
+ /** BCP47 language tags for each locale */
496
+ export const localeToBCP47 = ${JSON.stringify(localeToBCP47)};
497
+
498
+ /** Text direction for each locale ('ltr' or 'rtl') */
499
+ export const localeDirections = ${JSON.stringify(localeDirections)};
326
500
  `;
327
501
  }
328
502
  if (id === RESOLVED_PREFIX + VIRTUAL_RUNTIME) {
@@ -769,6 +943,12 @@ function ezI18n(config) {
769
943
  export const defaultLocale: string;
770
944
  /** Cookie name used to store locale preference */
771
945
  export const cookieName: string;
946
+ /** Display names for each locale (in native language) */
947
+ export const localeNames: Record<string, string>;
948
+ /** BCP47 language tags for each locale */
949
+ export const localeToBCP47: Record<string, string>;
950
+ /** Text direction for each locale ('ltr' or 'rtl') */
951
+ export const localeDirections: Record<string, 'ltr' | 'rtl'>;
772
952
  }
773
953
 
774
954
  declare module 'ez-i18n:runtime' {
@@ -808,5 +988,10 @@ declare module 'ez-i18n:translations' {
808
988
  };
809
989
  }
810
990
  export {
811
- ezI18n as default
991
+ LOCALE_DATABASE,
992
+ buildLocaleDirections,
993
+ buildLocaleNames,
994
+ buildLocaleToBCP47,
995
+ ezI18n as default,
996
+ getLocaleInfo
812
997
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zachhandley/ez-i18n",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
package/src/index.ts CHANGED
@@ -3,6 +3,8 @@ import type { EzI18nConfig } from './types';
3
3
  import { vitePlugin, resolveConfig } from './vite-plugin';
4
4
 
5
5
  export type { EzI18nConfig, TranslateFunction } from './types';
6
+ export { LOCALE_DATABASE, getLocaleInfo, buildLocaleNames, buildLocaleToBCP47, buildLocaleDirections } from './utils/locales';
7
+ export type { LocaleInfo } from './utils/locales';
6
8
 
7
9
  /**
8
10
  * ez-i18n Astro integration
@@ -82,6 +84,12 @@ declare module 'ez-i18n:config' {
82
84
  export const defaultLocale: string;
83
85
  /** Cookie name used to store locale preference */
84
86
  export const cookieName: string;
87
+ /** Display names for each locale (in native language) */
88
+ export const localeNames: Record<string, string>;
89
+ /** BCP47 language tags for each locale */
90
+ export const localeToBCP47: Record<string, string>;
91
+ /** Text direction for each locale ('ltr' or 'rtl') */
92
+ export const localeDirections: Record<string, 'ltr' | 'rtl'>;
85
93
  }
86
94
 
87
95
  declare module 'ez-i18n:runtime' {
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Comprehensive locale database for ez-i18n
3
+ * Contains display names (in native language) and BCP47 codes
4
+ */
5
+
6
+ export interface LocaleInfo {
7
+ /** Display name in native language */
8
+ name: string;
9
+ /** Display name in English */
10
+ englishName: string;
11
+ /** BCP47 language tag */
12
+ bcp47: string;
13
+ /** Text direction */
14
+ dir: 'ltr' | 'rtl';
15
+ }
16
+
17
+ /**
18
+ * Comprehensive mapping of locale codes to their metadata
19
+ * Covers all major languages and regional variants
20
+ */
21
+ export const LOCALE_DATABASE: Record<string, LocaleInfo> = {
22
+ // Major Western European Languages
23
+ en: { name: 'English', englishName: 'English', bcp47: 'en-US', dir: 'ltr' },
24
+ 'en-US': { name: 'English (US)', englishName: 'English (US)', bcp47: 'en-US', dir: 'ltr' },
25
+ 'en-GB': { name: 'English (UK)', englishName: 'English (UK)', bcp47: 'en-GB', dir: 'ltr' },
26
+ 'en-AU': { name: 'English (Australia)', englishName: 'English (Australia)', bcp47: 'en-AU', dir: 'ltr' },
27
+ 'en-CA': { name: 'English (Canada)', englishName: 'English (Canada)', bcp47: 'en-CA', dir: 'ltr' },
28
+
29
+ de: { name: 'Deutsch', englishName: 'German', bcp47: 'de-DE', dir: 'ltr' },
30
+ 'de-DE': { name: 'Deutsch (Deutschland)', englishName: 'German (Germany)', bcp47: 'de-DE', dir: 'ltr' },
31
+ 'de-AT': { name: 'Deutsch (Österreich)', englishName: 'German (Austria)', bcp47: 'de-AT', dir: 'ltr' },
32
+ 'de-CH': { name: 'Deutsch (Schweiz)', englishName: 'German (Switzerland)', bcp47: 'de-CH', dir: 'ltr' },
33
+
34
+ fr: { name: 'Français', englishName: 'French', bcp47: 'fr-FR', dir: 'ltr' },
35
+ 'fr-FR': { name: 'Français (France)', englishName: 'French (France)', bcp47: 'fr-FR', dir: 'ltr' },
36
+ 'fr-CA': { name: 'Français (Canada)', englishName: 'French (Canada)', bcp47: 'fr-CA', dir: 'ltr' },
37
+ 'fr-BE': { name: 'Français (Belgique)', englishName: 'French (Belgium)', bcp47: 'fr-BE', dir: 'ltr' },
38
+ 'fr-CH': { name: 'Français (Suisse)', englishName: 'French (Switzerland)', bcp47: 'fr-CH', dir: 'ltr' },
39
+
40
+ es: { name: 'Español', englishName: 'Spanish', bcp47: 'es-ES', dir: 'ltr' },
41
+ 'es-ES': { name: 'Español (España)', englishName: 'Spanish (Spain)', bcp47: 'es-ES', dir: 'ltr' },
42
+ 'es-MX': { name: 'Español (México)', englishName: 'Spanish (Mexico)', bcp47: 'es-MX', dir: 'ltr' },
43
+ 'es-AR': { name: 'Español (Argentina)', englishName: 'Spanish (Argentina)', bcp47: 'es-AR', dir: 'ltr' },
44
+ 'es-CO': { name: 'Español (Colombia)', englishName: 'Spanish (Colombia)', bcp47: 'es-CO', dir: 'ltr' },
45
+ 'es-419': { name: 'Español (Latinoamérica)', englishName: 'Spanish (Latin America)', bcp47: 'es-419', dir: 'ltr' },
46
+
47
+ it: { name: 'Italiano', englishName: 'Italian', bcp47: 'it-IT', dir: 'ltr' },
48
+ 'it-IT': { name: 'Italiano (Italia)', englishName: 'Italian (Italy)', bcp47: 'it-IT', dir: 'ltr' },
49
+ 'it-CH': { name: 'Italiano (Svizzera)', englishName: 'Italian (Switzerland)', bcp47: 'it-CH', dir: 'ltr' },
50
+
51
+ pt: { name: 'Português', englishName: 'Portuguese', bcp47: 'pt-PT', dir: 'ltr' },
52
+ 'pt-PT': { name: 'Português (Portugal)', englishName: 'Portuguese (Portugal)', bcp47: 'pt-PT', dir: 'ltr' },
53
+ 'pt-BR': { name: 'Português (Brasil)', englishName: 'Portuguese (Brazil)', bcp47: 'pt-BR', dir: 'ltr' },
54
+
55
+ nl: { name: 'Nederlands', englishName: 'Dutch', bcp47: 'nl-NL', dir: 'ltr' },
56
+ 'nl-NL': { name: 'Nederlands (Nederland)', englishName: 'Dutch (Netherlands)', bcp47: 'nl-NL', dir: 'ltr' },
57
+ 'nl-BE': { name: 'Nederlands (België)', englishName: 'Dutch (Belgium)', bcp47: 'nl-BE', dir: 'ltr' },
58
+
59
+ // Nordic Languages
60
+ sv: { name: 'Svenska', englishName: 'Swedish', bcp47: 'sv-SE', dir: 'ltr' },
61
+ 'sv-SE': { name: 'Svenska (Sverige)', englishName: 'Swedish (Sweden)', bcp47: 'sv-SE', dir: 'ltr' },
62
+
63
+ da: { name: 'Dansk', englishName: 'Danish', bcp47: 'da-DK', dir: 'ltr' },
64
+ 'da-DK': { name: 'Dansk (Danmark)', englishName: 'Danish (Denmark)', bcp47: 'da-DK', dir: 'ltr' },
65
+
66
+ no: { name: 'Norsk', englishName: 'Norwegian', bcp47: 'nb-NO', dir: 'ltr' },
67
+ nb: { name: 'Norsk bokmål', englishName: 'Norwegian Bokmål', bcp47: 'nb-NO', dir: 'ltr' },
68
+ nn: { name: 'Norsk nynorsk', englishName: 'Norwegian Nynorsk', bcp47: 'nn-NO', dir: 'ltr' },
69
+
70
+ fi: { name: 'Suomi', englishName: 'Finnish', bcp47: 'fi-FI', dir: 'ltr' },
71
+ 'fi-FI': { name: 'Suomi (Suomi)', englishName: 'Finnish (Finland)', bcp47: 'fi-FI', dir: 'ltr' },
72
+
73
+ is: { name: 'Íslenska', englishName: 'Icelandic', bcp47: 'is-IS', dir: 'ltr' },
74
+
75
+ // Eastern European Languages
76
+ pl: { name: 'Polski', englishName: 'Polish', bcp47: 'pl-PL', dir: 'ltr' },
77
+ 'pl-PL': { name: 'Polski (Polska)', englishName: 'Polish (Poland)', bcp47: 'pl-PL', dir: 'ltr' },
78
+
79
+ cs: { name: 'Čeština', englishName: 'Czech', bcp47: 'cs-CZ', dir: 'ltr' },
80
+ 'cs-CZ': { name: 'Čeština (Česko)', englishName: 'Czech (Czech Republic)', bcp47: 'cs-CZ', dir: 'ltr' },
81
+
82
+ sk: { name: 'Slovenčina', englishName: 'Slovak', bcp47: 'sk-SK', dir: 'ltr' },
83
+ 'sk-SK': { name: 'Slovenčina (Slovensko)', englishName: 'Slovak (Slovakia)', bcp47: 'sk-SK', dir: 'ltr' },
84
+
85
+ hu: { name: 'Magyar', englishName: 'Hungarian', bcp47: 'hu-HU', dir: 'ltr' },
86
+ 'hu-HU': { name: 'Magyar (Magyarország)', englishName: 'Hungarian (Hungary)', bcp47: 'hu-HU', dir: 'ltr' },
87
+
88
+ ro: { name: 'Română', englishName: 'Romanian', bcp47: 'ro-RO', dir: 'ltr' },
89
+ 'ro-RO': { name: 'Română (România)', englishName: 'Romanian (Romania)', bcp47: 'ro-RO', dir: 'ltr' },
90
+
91
+ bg: { name: 'Български', englishName: 'Bulgarian', bcp47: 'bg-BG', dir: 'ltr' },
92
+ 'bg-BG': { name: 'Български (България)', englishName: 'Bulgarian (Bulgaria)', bcp47: 'bg-BG', dir: 'ltr' },
93
+
94
+ hr: { name: 'Hrvatski', englishName: 'Croatian', bcp47: 'hr-HR', dir: 'ltr' },
95
+ sr: { name: 'Српски', englishName: 'Serbian', bcp47: 'sr-RS', dir: 'ltr' },
96
+ sl: { name: 'Slovenščina', englishName: 'Slovenian', bcp47: 'sl-SI', dir: 'ltr' },
97
+
98
+ uk: { name: 'Українська', englishName: 'Ukrainian', bcp47: 'uk-UA', dir: 'ltr' },
99
+ 'uk-UA': { name: 'Українська (Україна)', englishName: 'Ukrainian (Ukraine)', bcp47: 'uk-UA', dir: 'ltr' },
100
+
101
+ ru: { name: 'Русский', englishName: 'Russian', bcp47: 'ru-RU', dir: 'ltr' },
102
+ 'ru-RU': { name: 'Русский (Россия)', englishName: 'Russian (Russia)', bcp47: 'ru-RU', dir: 'ltr' },
103
+
104
+ // Baltic Languages
105
+ lt: { name: 'Lietuvių', englishName: 'Lithuanian', bcp47: 'lt-LT', dir: 'ltr' },
106
+ lv: { name: 'Latviešu', englishName: 'Latvian', bcp47: 'lv-LV', dir: 'ltr' },
107
+ et: { name: 'Eesti', englishName: 'Estonian', bcp47: 'et-EE', dir: 'ltr' },
108
+
109
+ // Greek
110
+ el: { name: 'Ελληνικά', englishName: 'Greek', bcp47: 'el-GR', dir: 'ltr' },
111
+ 'el-GR': { name: 'Ελληνικά (Ελλάδα)', englishName: 'Greek (Greece)', bcp47: 'el-GR', dir: 'ltr' },
112
+
113
+ // Asian Languages
114
+ zh: { name: '中文', englishName: 'Chinese', bcp47: 'zh-CN', dir: 'ltr' },
115
+ 'zh-CN': { name: '中文 (简体)', englishName: 'Chinese (Simplified)', bcp47: 'zh-CN', dir: 'ltr' },
116
+ 'zh-TW': { name: '中文 (繁體)', englishName: 'Chinese (Traditional)', bcp47: 'zh-TW', dir: 'ltr' },
117
+ 'zh-HK': { name: '中文 (香港)', englishName: 'Chinese (Hong Kong)', bcp47: 'zh-HK', dir: 'ltr' },
118
+
119
+ ja: { name: '日本語', englishName: 'Japanese', bcp47: 'ja-JP', dir: 'ltr' },
120
+ 'ja-JP': { name: '日本語 (日本)', englishName: 'Japanese (Japan)', bcp47: 'ja-JP', dir: 'ltr' },
121
+
122
+ ko: { name: '한국어', englishName: 'Korean', bcp47: 'ko-KR', dir: 'ltr' },
123
+ 'ko-KR': { name: '한국어 (대한민국)', englishName: 'Korean (South Korea)', bcp47: 'ko-KR', dir: 'ltr' },
124
+
125
+ vi: { name: 'Tiếng Việt', englishName: 'Vietnamese', bcp47: 'vi-VN', dir: 'ltr' },
126
+ 'vi-VN': { name: 'Tiếng Việt (Việt Nam)', englishName: 'Vietnamese (Vietnam)', bcp47: 'vi-VN', dir: 'ltr' },
127
+
128
+ th: { name: 'ไทย', englishName: 'Thai', bcp47: 'th-TH', dir: 'ltr' },
129
+ 'th-TH': { name: 'ไทย (ประเทศไทย)', englishName: 'Thai (Thailand)', bcp47: 'th-TH', dir: 'ltr' },
130
+
131
+ id: { name: 'Bahasa Indonesia', englishName: 'Indonesian', bcp47: 'id-ID', dir: 'ltr' },
132
+ 'id-ID': { name: 'Bahasa Indonesia (Indonesia)', englishName: 'Indonesian (Indonesia)', bcp47: 'id-ID', dir: 'ltr' },
133
+
134
+ ms: { name: 'Bahasa Melayu', englishName: 'Malay', bcp47: 'ms-MY', dir: 'ltr' },
135
+ 'ms-MY': { name: 'Bahasa Melayu (Malaysia)', englishName: 'Malay (Malaysia)', bcp47: 'ms-MY', dir: 'ltr' },
136
+
137
+ tl: { name: 'Tagalog', englishName: 'Tagalog', bcp47: 'tl-PH', dir: 'ltr' },
138
+ fil: { name: 'Filipino', englishName: 'Filipino', bcp47: 'fil-PH', dir: 'ltr' },
139
+
140
+ // South Asian Languages
141
+ hi: { name: 'हिन्दी', englishName: 'Hindi', bcp47: 'hi-IN', dir: 'ltr' },
142
+ 'hi-IN': { name: 'हिन्दी (भारत)', englishName: 'Hindi (India)', bcp47: 'hi-IN', dir: 'ltr' },
143
+
144
+ bn: { name: 'বাংলা', englishName: 'Bengali', bcp47: 'bn-BD', dir: 'ltr' },
145
+ 'bn-BD': { name: 'বাংলা (বাংলাদেশ)', englishName: 'Bengali (Bangladesh)', bcp47: 'bn-BD', dir: 'ltr' },
146
+ 'bn-IN': { name: 'বাংলা (ভারত)', englishName: 'Bengali (India)', bcp47: 'bn-IN', dir: 'ltr' },
147
+
148
+ ta: { name: 'தமிழ்', englishName: 'Tamil', bcp47: 'ta-IN', dir: 'ltr' },
149
+ te: { name: 'తెలుగు', englishName: 'Telugu', bcp47: 'te-IN', dir: 'ltr' },
150
+ mr: { name: 'मराठी', englishName: 'Marathi', bcp47: 'mr-IN', dir: 'ltr' },
151
+ gu: { name: 'ગુજરાતી', englishName: 'Gujarati', bcp47: 'gu-IN', dir: 'ltr' },
152
+ kn: { name: 'ಕನ್ನಡ', englishName: 'Kannada', bcp47: 'kn-IN', dir: 'ltr' },
153
+ ml: { name: 'മലയാളം', englishName: 'Malayalam', bcp47: 'ml-IN', dir: 'ltr' },
154
+ pa: { name: 'ਪੰਜਾਬੀ', englishName: 'Punjabi', bcp47: 'pa-IN', dir: 'ltr' },
155
+ ur: { name: 'اردو', englishName: 'Urdu', bcp47: 'ur-PK', dir: 'rtl' },
156
+
157
+ // Middle Eastern Languages (RTL)
158
+ ar: { name: 'العربية', englishName: 'Arabic', bcp47: 'ar-SA', dir: 'rtl' },
159
+ 'ar-SA': { name: 'العربية (السعودية)', englishName: 'Arabic (Saudi Arabia)', bcp47: 'ar-SA', dir: 'rtl' },
160
+ 'ar-EG': { name: 'العربية (مصر)', englishName: 'Arabic (Egypt)', bcp47: 'ar-EG', dir: 'rtl' },
161
+ 'ar-AE': { name: 'العربية (الإمارات)', englishName: 'Arabic (UAE)', bcp47: 'ar-AE', dir: 'rtl' },
162
+
163
+ he: { name: 'עברית', englishName: 'Hebrew', bcp47: 'he-IL', dir: 'rtl' },
164
+ 'he-IL': { name: 'עברית (ישראל)', englishName: 'Hebrew (Israel)', bcp47: 'he-IL', dir: 'rtl' },
165
+
166
+ fa: { name: 'فارسی', englishName: 'Persian', bcp47: 'fa-IR', dir: 'rtl' },
167
+ 'fa-IR': { name: 'فارسی (ایران)', englishName: 'Persian (Iran)', bcp47: 'fa-IR', dir: 'rtl' },
168
+
169
+ tr: { name: 'Türkçe', englishName: 'Turkish', bcp47: 'tr-TR', dir: 'ltr' },
170
+ 'tr-TR': { name: 'Türkçe (Türkiye)', englishName: 'Turkish (Turkey)', bcp47: 'tr-TR', dir: 'ltr' },
171
+
172
+ // African Languages
173
+ sw: { name: 'Kiswahili', englishName: 'Swahili', bcp47: 'sw-KE', dir: 'ltr' },
174
+ af: { name: 'Afrikaans', englishName: 'Afrikaans', bcp47: 'af-ZA', dir: 'ltr' },
175
+ zu: { name: 'isiZulu', englishName: 'Zulu', bcp47: 'zu-ZA', dir: 'ltr' },
176
+
177
+ // Celtic Languages
178
+ cy: { name: 'Cymraeg', englishName: 'Welsh', bcp47: 'cy-GB', dir: 'ltr' },
179
+ ga: { name: 'Gaeilge', englishName: 'Irish', bcp47: 'ga-IE', dir: 'ltr' },
180
+ gd: { name: 'Gàidhlig', englishName: 'Scottish Gaelic', bcp47: 'gd-GB', dir: 'ltr' },
181
+
182
+ // Other European Languages
183
+ ca: { name: 'Català', englishName: 'Catalan', bcp47: 'ca-ES', dir: 'ltr' },
184
+ eu: { name: 'Euskara', englishName: 'Basque', bcp47: 'eu-ES', dir: 'ltr' },
185
+ gl: { name: 'Galego', englishName: 'Galician', bcp47: 'gl-ES', dir: 'ltr' },
186
+
187
+ // Constructed Languages
188
+ eo: { name: 'Esperanto', englishName: 'Esperanto', bcp47: 'eo', dir: 'ltr' },
189
+ };
190
+
191
+ /**
192
+ * Get locale info for a given locale code
193
+ * Falls back to a generated entry if not found
194
+ */
195
+ export function getLocaleInfo(locale: string): LocaleInfo {
196
+ if (LOCALE_DATABASE[locale]) {
197
+ return LOCALE_DATABASE[locale];
198
+ }
199
+
200
+ // Generate fallback for unknown locales
201
+ return {
202
+ name: locale.toUpperCase(),
203
+ englishName: locale.toUpperCase(),
204
+ bcp47: locale,
205
+ dir: 'ltr',
206
+ };
207
+ }
208
+
209
+ /**
210
+ * Build locale names mapping for discovered locales
211
+ */
212
+ export function buildLocaleNames(locales: string[]): Record<string, string> {
213
+ const names: Record<string, string> = {};
214
+ for (const locale of locales) {
215
+ names[locale] = getLocaleInfo(locale).name;
216
+ }
217
+ return names;
218
+ }
219
+
220
+ /**
221
+ * Build locale to BCP47 mapping for discovered locales
222
+ */
223
+ export function buildLocaleToBCP47(locales: string[]): Record<string, string> {
224
+ const bcp47: Record<string, string> = {};
225
+ for (const locale of locales) {
226
+ bcp47[locale] = getLocaleInfo(locale).bcp47;
227
+ }
228
+ return bcp47;
229
+ }
230
+
231
+ /**
232
+ * Build locale directions mapping for discovered locales
233
+ */
234
+ export function buildLocaleDirections(locales: string[]): Record<string, 'ltr' | 'rtl'> {
235
+ const dirs: Record<string, 'ltr' | 'rtl'> = {};
236
+ for (const locale of locales) {
237
+ dirs[locale] = getLocaleInfo(locale).dir;
238
+ }
239
+ return dirs;
240
+ }
package/src/virtual.d.ts CHANGED
@@ -12,6 +12,12 @@ declare module 'ez-i18n:config' {
12
12
  export const defaultLocale: string;
13
13
  /** Cookie name used to store locale preference */
14
14
  export const cookieName: string;
15
+ /** Display names for each locale (in native language) */
16
+ export const localeNames: Record<string, string>;
17
+ /** BCP47 language tags for each locale */
18
+ export const localeToBCP47: Record<string, string>;
19
+ /** Text direction for each locale ('ltr' or 'rtl') */
20
+ export const localeDirections: Record<string, 'ltr' | 'rtl'>;
15
21
  }
16
22
 
17
23
  declare module 'ez-i18n:runtime' {
@@ -14,6 +14,11 @@ import {
14
14
  toPublicUrl,
15
15
  getLocaleBaseDirForNamespace,
16
16
  } from './utils/translations';
17
+ import {
18
+ buildLocaleNames,
19
+ buildLocaleToBCP47,
20
+ buildLocaleDirections,
21
+ } from './utils/locales';
17
22
  import * as path from 'node:path';
18
23
 
19
24
  const VIRTUAL_CONFIG = 'ez-i18n:config';
@@ -205,10 +210,23 @@ export function vitePlugin(config: EzI18nConfig): Plugin {
205
210
  load(id) {
206
211
  // ez-i18n:config - Static config values
207
212
  if (id === RESOLVED_PREFIX + VIRTUAL_CONFIG) {
213
+ const localeNames = buildLocaleNames(resolved.locales);
214
+ const localeToBCP47 = buildLocaleToBCP47(resolved.locales);
215
+ const localeDirections = buildLocaleDirections(resolved.locales);
216
+
208
217
  return `
209
218
  export const locales = ${JSON.stringify(resolved.locales)};
210
219
  export const defaultLocale = ${JSON.stringify(resolved.defaultLocale)};
211
220
  export const cookieName = ${JSON.stringify(resolved.cookieName)};
221
+
222
+ /** Display names for each locale (in native language) */
223
+ export const localeNames = ${JSON.stringify(localeNames)};
224
+
225
+ /** BCP47 language tags for each locale */
226
+ export const localeToBCP47 = ${JSON.stringify(localeToBCP47)};
227
+
228
+ /** Text direction for each locale ('ltr' or 'rtl') */
229
+ export const localeDirections = ${JSON.stringify(localeDirections)};
212
230
  `;
213
231
  }
214
232