Skip to content

Commit

Permalink
feat(@formatjs/intl-locale): implement new proposal features for Intl…
Browse files Browse the repository at this point in the history
….Locale (#3955)

Co-authored-by: Long Ho <longlho@users.noreply.github.com>
  • Loading branch information
wilkmaia and longlho authored Feb 20, 2023
1 parent 37dd588 commit 984f923
Show file tree
Hide file tree
Showing 28 changed files with 944 additions and 33 deletions.
1 change: 1 addition & 0 deletions packages/intl-datetimeformat/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,7 @@ ts_script(
"src/types.ts",
":node_modules/@formatjs/ecma402-abstract",
":node_modules/@formatjs/intl-locale",
"//:node_modules/cldr-bcp47",
"//:node_modules/cldr-core",
"//:node_modules/cldr-dates-full",
"//:node_modules/cldr-numbers-full",
Expand Down
10 changes: 6 additions & 4 deletions packages/intl-enumerator/src/get-supported-calendars.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type {Calendar} from './calendars.generated'
import {calendars} from './calendars.generated'

function isSupportedCalendar(item: Calendar): boolean {
function isSupportedCalendar(item: Calendar, locale: string = 'en'): boolean {
try {
const dateTimeFormat = new Intl.DateTimeFormat('en-u-ca' + item)
const dateTimeFormat = new Intl.DateTimeFormat(`${locale}-u-ca-${item}`)
const options = dateTimeFormat.resolvedOptions().calendar

if (item !== 'gregory' || options !== 'gregory') return true
Expand All @@ -12,6 +12,8 @@ function isSupportedCalendar(item: Calendar): boolean {
return false
}

export function getSupportedCalendars(): Calendar[] {
return calendars.filter(isSupportedCalendar)
export function getSupportedCalendars(localePrefix?: string): Calendar[] {
return calendars.filter(calendar =>
isSupportedCalendar(calendar, localePrefix)
)
}
9 changes: 5 additions & 4 deletions packages/intl-enumerator/src/get-supported-collations.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import type {Collation} from './collations.generated'
import {collations} from './collations.generated'

function isSupported(collation: Collation): boolean {
function isSupported(collation: Collation, locale: string = 'en'): boolean {
try {
return (
Intl.Collator('en-u-co-' + collation).resolvedOptions().locale === 'en'
Intl.Collator(`${locale}-u-co-${collation}`).resolvedOptions()
.collation === collation
)
} catch (_err) {}

return false
}

export function getSupportedCollations(): Collation[] {
return collations.filter(isSupported)
export function getSupportedCollations(locale?: string): Collation[] {
return collations.filter(collation => isSupported(collation, locale))
}
13 changes: 8 additions & 5 deletions packages/intl-enumerator/src/get-supported-currencies.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import type {Currency} from './currencies.generated'
import {currencies} from './currencies.generated'

function isSupportedCurrency(currency: Currency): boolean {
function isSupportedCurrency(
currency: Currency,
locale: string = 'en'
): boolean {
try {
const numberFormat = new Intl.NumberFormat('en', {
const numberFormat = new Intl.NumberFormat(locale, {
style: 'currency',
currencyDisplay: 'name',
currency,
Expand All @@ -22,13 +25,13 @@ function isSupportedCurrency(currency: Currency): boolean {
return false
}

export function getSupportedCurrencies(): Currency[] {
export function getSupportedCurrencies(locale?: string): Currency[] {
const ATOZ = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
const supportedCurrencies: Currency[] = []

for (const currency of currencies) {
if (currency.length === 3) {
if (isSupportedCurrency(currency)) {
if (isSupportedCurrency(currency, locale)) {
supportedCurrencies.push(currency)
}
} else if (currency.length === 5 && currency[3] === '~') {
Expand All @@ -37,7 +40,7 @@ export function getSupportedCurrencies(): Currency[] {

for (let i = start; i <= end; i++) {
const currentCurrency = (currency.substring(0, 2) + ATOZ[i]) as Currency
if (isSupportedCurrency(currentCurrency)) {
if (isSupportedCurrency(currentCurrency, locale)) {
supportedCurrencies.push(currentCurrency)
}
}
Expand Down
13 changes: 9 additions & 4 deletions packages/intl-enumerator/src/get-supported-numbering-systems.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import {numberingSystemNames} from './numbering-systems.generated'

function isSupportedNumberingSystem(system: string): boolean {
function isSupportedNumberingSystem(
system: string,
locale: string = 'en'
): boolean {
try {
const numberFormat = new Intl.NumberFormat('en-u-nu-' + system)
const numberFormat = new Intl.NumberFormat(`${locale}-u-nu-${system}`)
const options = numberFormat.resolvedOptions().numberingSystem

if (
Expand All @@ -16,6 +19,8 @@ function isSupportedNumberingSystem(system: string): boolean {
return false
}

export function getSupportedNumberingSystems(): string[] {
return numberingSystemNames.filter(isSupportedNumberingSystem)
export function getSupportedNumberingSystems(locale?: string): string[] {
return numberingSystemNames.filter(numberingSystemName =>
isSupportedNumberingSystem(numberingSystemName, locale)
)
}
8 changes: 4 additions & 4 deletions packages/intl-enumerator/src/get-supported-timezones.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import type {Timezone} from './timezones.generated'
import {timezones} from './timezones.generated'

function isSupported(timeZone: Timezone): boolean {
function isSupported(timeZone: Timezone, locale: string = 'en'): boolean {
try {
const formatter = new Intl.DateTimeFormat('en', {timeZone})
const formatter = new Intl.DateTimeFormat(locale, {timeZone})
return formatter.resolvedOptions().timeZone === timeZone
} catch (_err) {}

return false
}

export function getSupportedTimeZones(): Timezone[] {
return timezones.filter(isSupported)
export function getSupportedTimeZones(locale?: string): Timezone[] {
return timezones.filter(timezone => isSupported(timezone, locale))
}
8 changes: 4 additions & 4 deletions packages/intl-enumerator/src/get-supported-units.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import type {Unit} from './units.generated'
import {units} from './units.generated'

function isSupported(unit: Unit): boolean {
function isSupported(unit: Unit, locale: string = 'en'): boolean {
try {
const formatter = new Intl.NumberFormat('en', {style: 'unit', unit})
const formatter = new Intl.NumberFormat(locale, {style: 'unit', unit})
return formatter.resolvedOptions().unit === unit
} catch (_err) {}

return false
}

export function getSupportedUnits() {
return units.filter(isSupported)
export function getSupportedUnits(locale?: string) {
return units.filter(unit => isSupported(unit, locale))
}
17 changes: 10 additions & 7 deletions packages/intl-enumerator/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,23 @@ export type SupportedValuesOf =
| 'timeZone'
| 'unit'

export function supportedValuesOf(key: SupportedValuesOf): string[] {
export function supportedValuesOf(
key: SupportedValuesOf,
locale?: string
): string[] {
switch (key) {
case 'calendar':
return getSupportedCalendars()
return getSupportedCalendars(locale)
case 'collation':
return getSupportedCollations()
return getSupportedCollations(locale)
case 'currency':
return getSupportedCurrencies()
return getSupportedCurrencies(locale)
case 'numberingSystem':
return getSupportedNumberingSystems()
return getSupportedNumberingSystems(locale)
case 'timeZone':
return getSupportedTimeZones()
return getSupportedTimeZones(locale)
case 'unit':
return getSupportedUnits()
return getSupportedUnits(locale)
default:
throw RangeError('Invalid key: ' + key)
}
Expand Down
78 changes: 77 additions & 1 deletion packages/intl-locale/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ load("@aspect_rules_js//npm/private:npm_package.bzl", "npm_package")
load("@aspect_rules_ts//ts:defs.bzl", "ts_project")
load("@npm//:defs.bzl", "npm_link_all_packages")
load("@npm//:test262-harness/package_json.bzl", test262_harness_bin = "bin")
load("//tools:index.bzl", "check_format", "package_json_test", "ts_compile")
load("//tools:index.bzl", "check_format", "package_json_test", "ts_compile", "generate_src_file")
load("//tools:jest.bzl", "jest_test")

npm_link_all_packages(name = "node_modules")
Expand All @@ -29,7 +29,10 @@ SRCS = glob(["*.ts"])

SRC_DEPS = [
":node_modules/@formatjs/ecma402-abstract",
":node_modules/@formatjs/intl-enumerator",
":node_modules/@formatjs/intl-getcanonicallocales",
"//:node_modules/cldr-core",
"//:node_modules/cldr-bcp47",
]

ts_compile(
Expand Down Expand Up @@ -121,6 +124,7 @@ check_format(
],
exclude = [
"CHANGELOG.md",
"*.generated.ts",
],
),
)
Expand All @@ -129,3 +133,75 @@ package_json_test(
name = "package_json_test",
deps = SRC_DEPS,
)

# character orders
generate_src_file(
name = "character-orders",
src = "character-orders.generated.ts",
data = [
"scripts/common-types.ts",
"scripts/utils.ts",
"//:node_modules/cldr-localenames-full",
"//:node_modules/cldr-misc-full",
"//:node_modules/fast-glob",
],
entry_point = "scripts/character-orders.ts",
)

# numbering systems
generate_src_file(
name = "numbering-systems",
src = "numbering-systems.generated.ts",
data = [
"scripts/common-types.ts",
"scripts/utils.ts",
"//:node_modules/cldr-localenames-full",
"//:node_modules/cldr-numbers-full",
"//:node_modules/fast-glob",
],
entry_point = "scripts/numbering-systems.ts",
)

# timezones
generate_src_file(
name = "timezones",
src = "timezones.generated.ts",
data = [
"scripts/common-types.ts",
"//:node_modules/cldr-bcp47",
],
entry_point = "scripts/timezones.ts",
)

# hour cycles
generate_src_file(
name = "hour-cycles",
src = "hour-cycles.generated.ts",
data = [
"scripts/common-types.ts",
"//:node_modules/cldr-core",
],
entry_point = "scripts/hour-cycles.ts",
)

# calendars
generate_src_file(
name = "calendars",
src = "calendars.generated.ts",
data = [
"scripts/common-types.ts",
"//:node_modules/cldr-core",
],
entry_point = "scripts/calendars.ts",
)

# week data
generate_src_file(
name = "week-data",
src = "week-data.generated.ts",
data = [
"scripts/common-types.ts",
"//:node_modules/cldr-core",
],
entry_point = "scripts/week-data.ts",
)
4 changes: 4 additions & 0 deletions packages/intl-locale/calendars.generated.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/* @generated */
// prettier-ignore
export const calendars = {"001":["gregorian"],"AE":["gregorian","islamic-umalqura","islamic","islamic-civil","islamic-tbla"],"AF":["persian","gregorian","islamic","islamic-civil","islamic-tbla"],"BH":["gregorian","islamic-umalqura","islamic","islamic-civil","islamic-tbla"],"CN":["gregorian","chinese"],"CX":["gregorian","chinese"],"DJ":["gregorian","islamic","islamic-civil","islamic-tbla"],"DZ":["gregorian","islamic","islamic-civil","islamic-tbla"],"EG":["gregorian","coptic","islamic","islamic-civil","islamic-tbla"],"EH":["gregorian","islamic","islamic-civil","islamic-tbla"],"ER":["gregorian","islamic","islamic-civil","islamic-tbla"],"ET":["gregorian","ethiopic"],"HK":["gregorian","chinese"],"IL":["gregorian","hebrew","islamic","islamic-civil","islamic-tbla"],"IN":["gregorian","indian"],"IQ":["gregorian","islamic","islamic-civil","islamic-tbla"],"IR":["persian","gregorian","islamic","islamic-civil","islamic-tbla"],"JO":["gregorian","islamic","islamic-civil","islamic-tbla"],"JP":["gregorian","japanese"],"KM":["gregorian","islamic","islamic-civil","islamic-tbla"],"KR":["gregorian","dangi"],"KW":["gregorian","islamic-umalqura","islamic","islamic-civil","islamic-tbla"],"LB":["gregorian","islamic","islamic-civil","islamic-tbla"],"LY":["gregorian","islamic","islamic-civil","islamic-tbla"],"MA":["gregorian","islamic","islamic-civil","islamic-tbla"],"MO":["gregorian","chinese"],"MR":["gregorian","islamic","islamic-civil","islamic-tbla"],"OM":["gregorian","islamic","islamic-civil","islamic-tbla"],"PS":["gregorian","islamic","islamic-civil","islamic-tbla"],"QA":["gregorian","islamic-umalqura","islamic","islamic-civil","islamic-tbla"],"SA":["islamic-umalqura","gregorian","islamic","islamic-rgsa"],"SD":["gregorian","islamic","islamic-civil","islamic-tbla"],"SG":["gregorian","chinese"],"SY":["gregorian","islamic","islamic-civil","islamic-tbla"],"TD":["gregorian","islamic","islamic-civil","islamic-tbla"],"TH":["buddhist","gregorian"],"TN":["gregorian","islamic","islamic-civil","islamic-tbla"],"TW":["gregorian","roc","chinese"],"YE":["gregorian","islamic","islamic-civil","islamic-tbla"]} as const
export type CalendarsKey = keyof typeof calendars
Loading

0 comments on commit 984f923

Please sign in to comment.