[READ-ONLY] a fast, modern browser for the npm registry
at main 442 lines 12 kB view raw
1import type { 2 DateTimeFormats, 3 NumberFormats, 4 PluralizationRule, 5 PluralizationRules, 6} from '@intlify/core-base' 7import type { LocaleObject } from '@nuxtjs/i18n' 8 9interface LocaleObjectData extends LocaleObject { 10 numberFormats?: NumberFormats 11 dateTimeFormats?: DateTimeFormats 12 pluralRule?: PluralizationRule 13} 14 15export const countryLocaleVariants: Record<string, (LocaleObjectData & { country?: boolean })[]> = { 16 ar: [ 17 // ar.json contains ar-EG translations 18 // { code: 'ar-DZ', name: 'Arabic (Algeria)' }, 19 // { code: 'ar-BH', name: 'Arabic (Bahrain)' }, 20 { country: true, code: 'ar-EG', name: 'العربية' }, 21 // { code: 'ar-EG', name: 'Arabic (Egypt)' }, 22 // { code: 'ar-IQ', name: 'Arabic (Iraq)' }, 23 // { code: 'ar-JO', name: 'Arabic (Jordan)' }, 24 // { code: 'ar-KW', name: 'Arabic (Kuwait)' }, 25 // { code: 'ar-LB', name: 'Arabic (Lebanon)' }, 26 // { code: 'ar-LY', name: 'Arabic (Libya)' }, 27 // { code: 'ar-MA', name: 'Arabic (Morocco)' }, 28 // { code: 'ar-OM', name: 'Arabic (Oman)' }, 29 // { code: 'ar-QA', name: 'Arabic (Qatar)' }, 30 // { code: 'ar-SA', name: 'Arabic (Saudi Arabia)' }, 31 // { code: 'ar-SY', name: 'Arabic (Syria)' }, 32 // { code: 'ar-TN', name: 'Arabic (Tunisia)' }, 33 // { code: 'ar-AE', name: 'Arabic (U.A.E.)' }, 34 // { code: 'ar-YE', name: 'Arabic (Yemen)' }, 35 ], 36 en: [ 37 // en.json contains en-US translations 38 { country: true, code: 'en-US', name: 'English (US)' }, 39 // { code: 'en-CA', name: 'English (Canada)' }, 40 { code: 'en-GB', name: 'English (UK)' }, 41 ], 42 /*ca: [ 43 // ca.json contains ca-ES translations 44 // { code: 'ca-AD', name: 'Català (Andorra)' }, 45 { country: true, code: 'ca-ES', name: 'Català (Espanya)' }, 46 { code: 'ca-valencia', name: 'Català (valencià)' }, 47 // { code: 'ca-FR', name: 'Català (França)' }, 48 // { code: 'ca-IT', name: 'Català (Itàlia)' }, 49 ],*/ 50 es: [ 51 // es.json contains es-ES translations 52 // { code: 'es-AR', name: 'Español (Argentina)' }, 53 // { code: 'es-BO', name: 'Español (Bolivia)' }, 54 // { code: 'es-CL', name: 'Español (Chile)' }, 55 // { code: 'es-CO', name: 'Español (Colombia)' }, 56 // { code: 'es-CR', name: 'Español (Costa Rica)' }, 57 // { code: 'es-DO', name: 'Español (República Dominicana)' }, 58 // { code: 'es-EC', name: 'Español (Ecuador)' }, 59 { country: true, code: 'es-ES', name: 'Español (España)' }, 60 // TODO: Support es-419, if we include spanish country variants remove also fix on utils/language.ts module 61 { code: 'es-419', name: 'Español (Latinoamérica)' }, 62 // { code: 'es-GT', name: 'Español (Guatemala)' }, 63 // { code: 'es-HN', name: 'Español (Honduras)' }, 64 // { code: 'es-MX', name: 'Español (México)' }, 65 // { code: 'es-NI', name: 'Español (Nicaragua)' }, 66 // { code: 'es-PA', name: 'Español (Panamá)' }, 67 // { code: 'es-PE', name: 'Español (Perú)' }, 68 // { code: 'es-PR', name: 'Español (Puerto Rico)' }, 69 // { code: 'es-SV', name: 'Español (El Salvador)' }, 70 // { code: 'es-US', name: 'Español (Estados Unidos)' }, 71 // { code: 'es-UY', name: 'Español (Uruguay)' }, 72 // { code: 'es-VE', name: 'Español (Venezuela)' }, 73 ], 74 /*pt: [ 75 // pt.json contains pt-PT translations 76 { country: true, code: 'pt-PT', name: 'Português (Portugal)' }, 77 { code: 'pt-BR', name: 'Português (Brasil)' }, 78 ],*/ 79} 80 81function createPluralRule(locale: string, mapping: Record<string, number>) { 82 return (choice: number, choicesLength: number) => { 83 const name = new Intl.PluralRules(locale).select(choice) 84 const plural = mapping[name] || 0 85 86 // In case translation doesn't have all plural forms, use the last available form 87 if (plural > choicesLength - 1) { 88 if (import.meta.dev) { 89 // oxlint-disable-next-line no-console -- warn logging 90 console.warn( 91 `Plural form index ${plural} for choice ${choice} exceeds available forms ${choicesLength} for locale ${locale}.`, 92 ) 93 } 94 return choicesLength - 1 95 } 96 97 return plural 98 } 99} 100 101const locales: (LocaleObjectData | (Omit<LocaleObjectData, 'code'> & { code: string }))[] = [ 102 { 103 code: 'en', 104 file: 'en.json', 105 name: 'English', 106 }, 107 { 108 code: 'ar', 109 file: 'ar.json', 110 name: 'العربية', 111 dir: 'rtl', 112 pluralRule: createPluralRule('ar-EG', { zero: 0, one: 1, two: 2, few: 3, many: 4, other: 5 }), 113 }, 114 { 115 code: 'az-AZ', 116 file: 'az-AZ.json', 117 name: 'Azərbaycanca', 118 }, 119 { 120 code: 'bn-IN', 121 file: 'bn-IN.json', 122 name: 'বাংলা', 123 }, 124 { 125 code: 'bg-BG', 126 file: 'bg-BG.json', 127 name: 'Български', 128 pluralRule: createPluralRule('bg-BG', { zero: 1, one: 0, two: 1, few: 1, many: 1, other: 1 }), 129 }, 130 /*{ 131 code: 'ckb', 132 file: 'ckb.json', 133 name: 'کوردیی ناوەندی', 134 dir: 'rtl', 135 pluralRule: (choice: number) => { 136 const name = new Intl.PluralRules('ckb').select(choice) 137 return { zero: 0, one: 1, two: 2, few: 3, many: 4, other: 5 }[name] 138 }, 139 }, 140 { 141 code: 'fa-IR', 142 file: 'fa-IR.json', 143 name: 'فارسی', 144 dir: 'rtl', 145 pluralRule: (choice: number) => { 146 const name = new Intl.PluralRules('fa-IR').select(choice) 147 return { zero: 0, one: 1, two: 2, few: 3, many: 4, other: 5 }[name] 148 }, 149 }, 150 { 151 code: 'ca', 152 file: 'ca.json', 153 name: 'Català', 154 }, 155 { 156 code: 'el-GR', 157 file: 'el-GR.json', 158 name: 'Ελληνικά', 159 },*/ 160 { 161 code: 'de-DE', 162 file: 'de-DE.json', 163 name: 'Deutsch', 164 }, 165 { 166 code: 'hi-IN', 167 file: 'hi-IN.json', 168 name: 'हिंदी', 169 }, 170 { 171 code: 'te-IN', 172 file: 'te-IN.json', 173 name: 'తెలుగు', 174 }, 175 { 176 code: 'mr-IN', 177 file: 'mr-IN.json', 178 name: 'मराठी', 179 }, 180 { 181 code: 'hu-HU', 182 file: 'hu-HU.json', 183 name: 'Magyar', 184 pluralRule: createPluralRule('hu-HU', { zero: 0, one: 0, two: 1, few: 1, many: 1, other: 1 }), 185 }, 186 { 187 code: 'zh-CN', 188 file: 'zh-CN.json', 189 name: '简体中文', 190 }, 191 { 192 code: 'zh-TW', 193 file: 'zh-TW.json', 194 name: '繁體中文', 195 }, 196 { 197 code: 'ja-JP', 198 file: 'ja-JP.json', 199 name: '日本語', 200 }, 201 { 202 code: 'ne-NP', 203 file: 'ne-NP.json', 204 name: 'नेपाली', 205 }, 206 /*{ 207 code: 'nl-NL', 208 file: 'nl-NL.json', 209 name: 'Nederlands', 210 },*/ 211 { 212 code: 'es', 213 file: 'es.json', 214 name: 'Español', 215 }, 216 /*{ 217 code: 'eu-ES', 218 file: 'eu-ES.json', 219 name: 'Euskara', 220 },*/ 221 { 222 code: 'fr-FR', 223 file: 'fr-FR.json', 224 name: 'Français', 225 }, 226 { 227 code: 'ru-RU', 228 file: 'ru-RU.json', 229 name: 'Русский', 230 pluralRule: createPluralRule('ru-RU', { zero: 2, one: 0, two: 1, few: 1, many: 2, other: 3 }), 231 }, 232 { 233 code: 'uk-UA', 234 file: 'uk-UA.json', 235 name: 'Українська', 236 pluralRule: createPluralRule('uk-UA', { zero: 0, one: 1, two: 0, few: 2, many: 3, other: 4 }), 237 }, 238 /*{ 239 code: 'ru-RU', 240 file: 'ru-RU.json', 241 name: 'Русский', 242 pluralRule: (choice: number) => { 243 const name = new Intl.PluralRules('ru-RU').select(choice) 244 return { zero: 2 /!* not used *!/, one: 0, two: 1 /!* not used *!/, few: 1, many: 2, other: 3 }[name] 245 }, 246 },*/ 247 { 248 code: 'cs-CZ', 249 file: 'cs-CZ.json', 250 name: 'Čeština', 251 pluralRule: createPluralRule('cs-CZ', { zero: 2, one: 0, two: 1, few: 1, many: 2, other: 2 }), 252 } /* 253 { 254 code: 'pl-PL', 255 file: 'pl-PL.json', 256 name: 'Polski', 257 pluralRule: (choice: number) => { 258 if (choice === 0) 259 return 0 260 261 const name = new Intl.PluralRules('pl-PL').select(choice) 262 return { zero: 0, one: 1, two: 0 /!* not used *!/, few: 2, many: 3, other: 4 }[name] 263 }, 264 }, 265 { 266 code: 'pt', 267 file: 'pt.json', 268 name: 'Português', 269 }, 270 { 271 code: 'tr-TR', 272 file: 'tr-TR.json', 273 name: 'Türkçe', 274 }, 275 { 276 code: 'id-ID', 277 file: 'id-ID.json', 278 name: 'Indonesia', 279 }, 280 { 281 code: 'fi', 282 file: 'fi.json', 283 name: 'Suomi', 284 }, 285 { 286 code: 'gl-ES', 287 file: 'gl-ES.json', 288 name: 'Galego', 289 }, 290 { 291 code: 'ko-KR', 292 file: 'ko-KR.json', 293 name: '한국어', 294 },*/, 295 { 296 code: 'id-ID', 297 file: 'id-ID.json', 298 name: 'Indonesia', 299 }, 300 { 301 code: 'it-IT', 302 file: 'it-IT.json', 303 name: 'Italiano', 304 }, 305 { 306 code: 'pl-PL', 307 file: 'pl-PL.json', 308 name: 'Polski', 309 pluralRule: createPluralRule('pl-PL', { zero: 0, one: 1, two: 0, few: 2, many: 3, other: 4 }), 310 }, 311 { 312 code: 'pt-BR', 313 file: 'pt-BR.json', 314 name: 'Português (Brasil)', 315 }, 316 /*{ 317 code: 'sv', 318 file: 'sv.json', 319 name: 'Svenska', 320 }, 321 { 322 code: 'th-TH', 323 file: 'th-TH.json', 324 name: 'ไทย', 325 }, 326 { 327 code: 'tl-PH', 328 file: 'tl-PH.json', 329 name: 'Tagalog', 330 }, 331 { 332 code: 'vi-VN', 333 file: 'vi-VN.json', 334 name: 'Tiếng Việt', 335 }, 336 { 337 code: 'cy', 338 file: 'cy.json', 339 name: 'Cymraeg', 340 },*/ 341 { 342 code: 'nb-NO', 343 file: 'nb-NO.json', 344 name: 'Norsk (Bokmål)', 345 }, 346] 347 348const lunariaJSONFiles: Record<string, string> = {} 349 350function buildLocales() { 351 const useLocales = Object.values(locales).reduce((acc, data) => { 352 const locales = countryLocaleVariants[data.code] 353 if (locales) { 354 locales.forEach(l => { 355 const entry: LocaleObjectData = { 356 ...data, 357 code: l.code, 358 name: l.name, 359 files: [data.file as string, `${l.code}.json`], 360 } 361 lunariaJSONFiles[l.code] = l.country ? (data.file as string) : `${l.code}.json` 362 delete entry.file 363 acc.push(entry) 364 }) 365 } else { 366 lunariaJSONFiles[data.code] = data.file as string 367 acc.push(data as LocaleObjectData) 368 } 369 return acc 370 }, [] as LocaleObjectData[]) 371 372 return useLocales.sort((a, b) => a.code.localeCompare(b.code)) 373} 374 375export const currentLocales = buildLocales() 376 377export { lunariaJSONFiles } 378 379export const datetimeFormats = Object.values(currentLocales).reduce((acc, data) => { 380 const dateTimeFormats = data.dateTimeFormats 381 if (dateTimeFormats) { 382 acc[data.code] = { ...dateTimeFormats } 383 delete data.dateTimeFormats 384 } else { 385 acc[data.code] = { 386 shortDate: { 387 dateStyle: 'short', 388 }, 389 short: { 390 dateStyle: 'short', 391 timeStyle: 'short', 392 }, 393 long: { 394 dateStyle: 'long', 395 timeStyle: 'medium', 396 }, 397 } 398 } 399 400 return acc 401}, {} as DateTimeFormats) 402 403export const numberFormats = Object.values(currentLocales).reduce((acc, data) => { 404 const numberFormats = data.numberFormats 405 if (numberFormats) { 406 acc[data.code] = { ...numberFormats } 407 delete data.numberFormats 408 } else { 409 acc[data.code] = { 410 percentage: { 411 style: 'percent', 412 maximumFractionDigits: 1, 413 }, 414 smallCounting: { 415 style: 'decimal', 416 maximumFractionDigits: 0, 417 }, 418 kiloCounting: { 419 notation: 'compact', 420 compactDisplay: 'short', 421 maximumFractionDigits: 1, 422 }, 423 millionCounting: { 424 notation: 'compact', 425 compactDisplay: 'short', 426 maximumFractionDigits: 2, 427 }, 428 } 429 } 430 431 return acc 432}, {} as NumberFormats) 433 434export const pluralRules = Object.values(currentLocales).reduce((acc, data) => { 435 const pluralRule = data.pluralRule 436 if (pluralRule) { 437 acc[data.code] = pluralRule 438 delete data.pluralRule 439 } 440 441 return acc 442}, {} as PluralizationRules)