Skip to content

Commit 984f923

Browse files
wilkmaialonglho
andauthored
feat(@formatjs/intl-locale): implement new proposal features for Intl.Locale (#3955)
Co-authored-by: Long Ho <[email protected]>
1 parent 37dd588 commit 984f923

28 files changed

+944
-33
lines changed

packages/intl-datetimeformat/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,7 @@ ts_script(
693693
"src/types.ts",
694694
":node_modules/@formatjs/ecma402-abstract",
695695
":node_modules/@formatjs/intl-locale",
696+
"//:node_modules/cldr-bcp47",
696697
"//:node_modules/cldr-core",
697698
"//:node_modules/cldr-dates-full",
698699
"//:node_modules/cldr-numbers-full",
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import type {Calendar} from './calendars.generated'
22
import {calendars} from './calendars.generated'
33

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

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

15-
export function getSupportedCalendars(): Calendar[] {
16-
return calendars.filter(isSupportedCalendar)
15+
export function getSupportedCalendars(localePrefix?: string): Calendar[] {
16+
return calendars.filter(calendar =>
17+
isSupportedCalendar(calendar, localePrefix)
18+
)
1719
}
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import type {Collation} from './collations.generated'
22
import {collations} from './collations.generated'
33

4-
function isSupported(collation: Collation): boolean {
4+
function isSupported(collation: Collation, locale: string = 'en'): boolean {
55
try {
66
return (
7-
Intl.Collator('en-u-co-' + collation).resolvedOptions().locale === 'en'
7+
Intl.Collator(`${locale}-u-co-${collation}`).resolvedOptions()
8+
.collation === collation
89
)
910
} catch (_err) {}
1011

1112
return false
1213
}
1314

14-
export function getSupportedCollations(): Collation[] {
15-
return collations.filter(isSupported)
15+
export function getSupportedCollations(locale?: string): Collation[] {
16+
return collations.filter(collation => isSupported(collation, locale))
1617
}

packages/intl-enumerator/src/get-supported-currencies.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import type {Currency} from './currencies.generated'
22
import {currencies} from './currencies.generated'
33

4-
function isSupportedCurrency(currency: Currency): boolean {
4+
function isSupportedCurrency(
5+
currency: Currency,
6+
locale: string = 'en'
7+
): boolean {
58
try {
6-
const numberFormat = new Intl.NumberFormat('en', {
9+
const numberFormat = new Intl.NumberFormat(locale, {
710
style: 'currency',
811
currencyDisplay: 'name',
912
currency,
@@ -22,13 +25,13 @@ function isSupportedCurrency(currency: Currency): boolean {
2225
return false
2326
}
2427

25-
export function getSupportedCurrencies(): Currency[] {
28+
export function getSupportedCurrencies(locale?: string): Currency[] {
2629
const ATOZ = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2730
const supportedCurrencies: Currency[] = []
2831

2932
for (const currency of currencies) {
3033
if (currency.length === 3) {
31-
if (isSupportedCurrency(currency)) {
34+
if (isSupportedCurrency(currency, locale)) {
3235
supportedCurrencies.push(currency)
3336
}
3437
} else if (currency.length === 5 && currency[3] === '~') {
@@ -37,7 +40,7 @@ export function getSupportedCurrencies(): Currency[] {
3740

3841
for (let i = start; i <= end; i++) {
3942
const currentCurrency = (currency.substring(0, 2) + ATOZ[i]) as Currency
40-
if (isSupportedCurrency(currentCurrency)) {
43+
if (isSupportedCurrency(currentCurrency, locale)) {
4144
supportedCurrencies.push(currentCurrency)
4245
}
4346
}

packages/intl-enumerator/src/get-supported-numbering-systems.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import {numberingSystemNames} from './numbering-systems.generated'
22

3-
function isSupportedNumberingSystem(system: string): boolean {
3+
function isSupportedNumberingSystem(
4+
system: string,
5+
locale: string = 'en'
6+
): boolean {
47
try {
5-
const numberFormat = new Intl.NumberFormat('en-u-nu-' + system)
8+
const numberFormat = new Intl.NumberFormat(`${locale}-u-nu-${system}`)
69
const options = numberFormat.resolvedOptions().numberingSystem
710

811
if (
@@ -16,6 +19,8 @@ function isSupportedNumberingSystem(system: string): boolean {
1619
return false
1720
}
1821

19-
export function getSupportedNumberingSystems(): string[] {
20-
return numberingSystemNames.filter(isSupportedNumberingSystem)
22+
export function getSupportedNumberingSystems(locale?: string): string[] {
23+
return numberingSystemNames.filter(numberingSystemName =>
24+
isSupportedNumberingSystem(numberingSystemName, locale)
25+
)
2126
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import type {Timezone} from './timezones.generated'
22
import {timezones} from './timezones.generated'
33

4-
function isSupported(timeZone: Timezone): boolean {
4+
function isSupported(timeZone: Timezone, locale: string = 'en'): boolean {
55
try {
6-
const formatter = new Intl.DateTimeFormat('en', {timeZone})
6+
const formatter = new Intl.DateTimeFormat(locale, {timeZone})
77
return formatter.resolvedOptions().timeZone === timeZone
88
} catch (_err) {}
99

1010
return false
1111
}
1212

13-
export function getSupportedTimeZones(): Timezone[] {
14-
return timezones.filter(isSupported)
13+
export function getSupportedTimeZones(locale?: string): Timezone[] {
14+
return timezones.filter(timezone => isSupported(timezone, locale))
1515
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import type {Unit} from './units.generated'
22
import {units} from './units.generated'
33

4-
function isSupported(unit: Unit): boolean {
4+
function isSupported(unit: Unit, locale: string = 'en'): boolean {
55
try {
6-
const formatter = new Intl.NumberFormat('en', {style: 'unit', unit})
6+
const formatter = new Intl.NumberFormat(locale, {style: 'unit', unit})
77
return formatter.resolvedOptions().unit === unit
88
} catch (_err) {}
99

1010
return false
1111
}
1212

13-
export function getSupportedUnits() {
14-
return units.filter(isSupported)
13+
export function getSupportedUnits(locale?: string) {
14+
return units.filter(unit => isSupported(unit, locale))
1515
}

packages/intl-enumerator/src/index.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,23 @@ export type SupportedValuesOf =
1313
| 'timeZone'
1414
| 'unit'
1515

16-
export function supportedValuesOf(key: SupportedValuesOf): string[] {
16+
export function supportedValuesOf(
17+
key: SupportedValuesOf,
18+
locale?: string
19+
): string[] {
1720
switch (key) {
1821
case 'calendar':
19-
return getSupportedCalendars()
22+
return getSupportedCalendars(locale)
2023
case 'collation':
21-
return getSupportedCollations()
24+
return getSupportedCollations(locale)
2225
case 'currency':
23-
return getSupportedCurrencies()
26+
return getSupportedCurrencies(locale)
2427
case 'numberingSystem':
25-
return getSupportedNumberingSystems()
28+
return getSupportedNumberingSystems(locale)
2629
case 'timeZone':
27-
return getSupportedTimeZones()
30+
return getSupportedTimeZones(locale)
2831
case 'unit':
29-
return getSupportedUnits()
32+
return getSupportedUnits(locale)
3033
default:
3134
throw RangeError('Invalid key: ' + key)
3235
}

packages/intl-locale/BUILD

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ load("@aspect_rules_js//npm/private:npm_package.bzl", "npm_package")
44
load("@aspect_rules_ts//ts:defs.bzl", "ts_project")
55
load("@npm//:defs.bzl", "npm_link_all_packages")
66
load("@npm//:test262-harness/package_json.bzl", test262_harness_bin = "bin")
7-
load("//tools:index.bzl", "check_format", "package_json_test", "ts_compile")
7+
load("//tools:index.bzl", "check_format", "package_json_test", "ts_compile", "generate_src_file")
88
load("//tools:jest.bzl", "jest_test")
99

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

3030
SRC_DEPS = [
3131
":node_modules/@formatjs/ecma402-abstract",
32+
":node_modules/@formatjs/intl-enumerator",
3233
":node_modules/@formatjs/intl-getcanonicallocales",
34+
"//:node_modules/cldr-core",
35+
"//:node_modules/cldr-bcp47",
3336
]
3437

3538
ts_compile(
@@ -121,6 +124,7 @@ check_format(
121124
],
122125
exclude = [
123126
"CHANGELOG.md",
127+
"*.generated.ts",
124128
],
125129
),
126130
)
@@ -129,3 +133,75 @@ package_json_test(
129133
name = "package_json_test",
130134
deps = SRC_DEPS,
131135
)
136+
137+
# character orders
138+
generate_src_file(
139+
name = "character-orders",
140+
src = "character-orders.generated.ts",
141+
data = [
142+
"scripts/common-types.ts",
143+
"scripts/utils.ts",
144+
"//:node_modules/cldr-localenames-full",
145+
"//:node_modules/cldr-misc-full",
146+
"//:node_modules/fast-glob",
147+
],
148+
entry_point = "scripts/character-orders.ts",
149+
)
150+
151+
# numbering systems
152+
generate_src_file(
153+
name = "numbering-systems",
154+
src = "numbering-systems.generated.ts",
155+
data = [
156+
"scripts/common-types.ts",
157+
"scripts/utils.ts",
158+
"//:node_modules/cldr-localenames-full",
159+
"//:node_modules/cldr-numbers-full",
160+
"//:node_modules/fast-glob",
161+
],
162+
entry_point = "scripts/numbering-systems.ts",
163+
)
164+
165+
# timezones
166+
generate_src_file(
167+
name = "timezones",
168+
src = "timezones.generated.ts",
169+
data = [
170+
"scripts/common-types.ts",
171+
"//:node_modules/cldr-bcp47",
172+
],
173+
entry_point = "scripts/timezones.ts",
174+
)
175+
176+
# hour cycles
177+
generate_src_file(
178+
name = "hour-cycles",
179+
src = "hour-cycles.generated.ts",
180+
data = [
181+
"scripts/common-types.ts",
182+
"//:node_modules/cldr-core",
183+
],
184+
entry_point = "scripts/hour-cycles.ts",
185+
)
186+
187+
# calendars
188+
generate_src_file(
189+
name = "calendars",
190+
src = "calendars.generated.ts",
191+
data = [
192+
"scripts/common-types.ts",
193+
"//:node_modules/cldr-core",
194+
],
195+
entry_point = "scripts/calendars.ts",
196+
)
197+
198+
# week data
199+
generate_src_file(
200+
name = "week-data",
201+
src = "week-data.generated.ts",
202+
data = [
203+
"scripts/common-types.ts",
204+
"//:node_modules/cldr-core",
205+
],
206+
entry_point = "scripts/week-data.ts",
207+
)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/* @generated */
2+
// prettier-ignore
3+
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
4+
export type CalendarsKey = keyof typeof calendars

0 commit comments

Comments
 (0)