@formatjs/intl 2.3.1 → 2.3.2
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/BUILD +79 -0
- package/CHANGELOG.md +537 -0
- package/LICENSE.md +0 -0
- package/README.md +0 -0
- package/index.ts +38 -0
- package/package.json +12 -8
- package/src/create-intl.ts +159 -0
- package/src/dateTime.ts +204 -0
- package/src/displayName.ts +54 -0
- package/src/error.ts +106 -0
- package/src/list.ts +119 -0
- package/src/message.ts +246 -0
- package/src/number.ts +101 -0
- package/src/plural.ts +45 -0
- package/src/relativeTime.ts +74 -0
- package/src/types.ts +234 -0
- package/src/utils.ts +177 -0
- package/tests/__snapshots__/formatDate.test.ts.snap +13 -0
- package/tests/__snapshots__/formatMessage.test.ts.snap +45 -0
- package/tests/__snapshots__/formatNumber.test.ts.snap +13 -0
- package/tests/__snapshots__/formatRelativeTime.test.ts.snap +19 -0
- package/tests/__snapshots__/formatTime.test.ts.snap +13 -0
- package/tests/create-intl.test.ts +60 -0
- package/tests/error.test.ts +25 -0
- package/tests/formatDate.test.ts +167 -0
- package/tests/formatDisplayNames.test.ts +63 -0
- package/tests/formatList.test.ts +51 -0
- package/tests/formatMessage.test.ts +495 -0
- package/tests/formatNumber.test.ts +172 -0
- package/tests/formatPlural.test.ts +119 -0
- package/tests/formatRelativeTime.test.ts +145 -0
- package/tests/formatTime.test.ts +234 -0
- package/tests/global.d.ts +7 -0
- package/tsconfig.json +5 -0
- package/index.d.ts +0 -17
- package/index.d.ts.map +0 -1
- package/index.js +0 -40
- package/lib/index.d.ts +0 -17
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -17
- package/lib/src/create-intl.d.ts +0 -11
- package/lib/src/create-intl.d.ts.map +0 -1
- package/lib/src/create-intl.js +0 -51
- package/lib/src/dateTime.d.ts +0 -38
- package/lib/src/dateTime.d.ts.map +0 -1
- package/lib/src/dateTime.js +0 -117
- package/lib/src/displayName.d.ts +0 -6
- package/lib/src/displayName.d.ts.map +0 -1
- package/lib/src/displayName.js +0 -22
- package/lib/src/error.d.ts +0 -34
- package/lib/src/error.d.ts.map +0 -1
- package/lib/src/error.js +0 -88
- package/lib/src/list.d.ts +0 -11
- package/lib/src/list.d.ts.map +0 -1
- package/lib/src/list.js +0 -61
- package/lib/src/message.d.ts +0 -16
- package/lib/src/message.d.ts.map +0 -1
- package/lib/src/message.js +0 -103
- package/lib/src/number.d.ts +0 -17
- package/lib/src/number.d.ts.map +0 -1
- package/lib/src/number.js +0 -54
- package/lib/src/plural.d.ts +0 -7
- package/lib/src/plural.d.ts.map +0 -1
- package/lib/src/plural.js +0 -19
- package/lib/src/relativeTime.d.ts +0 -7
- package/lib/src/relativeTime.d.ts.map +0 -1
- package/lib/src/relativeTime.js +0 -29
- package/lib/src/types.d.ts +0 -103
- package/lib/src/types.d.ts.map +0 -1
- package/lib/src/types.js +0 -1
- package/lib/src/utils.d.ts +0 -12
- package/lib/src/utils.d.ts.map +0 -1
- package/lib/src/utils.js +0 -162
- package/src/create-intl.d.ts +0 -11
- package/src/create-intl.d.ts.map +0 -1
- package/src/create-intl.js +0 -55
- package/src/dateTime.d.ts +0 -38
- package/src/dateTime.d.ts.map +0 -1
- package/src/dateTime.js +0 -126
- package/src/displayName.d.ts +0 -6
- package/src/displayName.d.ts.map +0 -1
- package/src/displayName.js +0 -26
- package/src/error.d.ts +0 -34
- package/src/error.d.ts.map +0 -1
- package/src/error.js +0 -91
- package/src/list.d.ts +0 -11
- package/src/list.d.ts.map +0 -1
- package/src/list.js +0 -66
- package/src/message.d.ts +0 -16
- package/src/message.d.ts.map +0 -1
- package/src/message.js +0 -107
- package/src/number.d.ts +0 -17
- package/src/number.d.ts.map +0 -1
- package/src/number.js +0 -60
- package/src/plural.d.ts +0 -7
- package/src/plural.d.ts.map +0 -1
- package/src/plural.js +0 -23
- package/src/relativeTime.d.ts +0 -7
- package/src/relativeTime.d.ts.map +0 -1
- package/src/relativeTime.js +0 -33
- package/src/types.d.ts +0 -103
- package/src/types.d.ts.map +0 -1
- package/src/types.js +0 -2
- package/src/utils.d.ts +0 -12
- package/src/utils.d.ts.map +0 -1
- package/src/utils.js +0 -169
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/camelcase */
|
|
2
|
+
|
|
3
|
+
import {formatPlural as formatPluralFn} from '../src/plural'
|
|
4
|
+
|
|
5
|
+
import {IntlFormatters, IntlConfig} from '../src/types'
|
|
6
|
+
|
|
7
|
+
describe('format API', () => {
|
|
8
|
+
const {NODE_ENV} = process.env
|
|
9
|
+
|
|
10
|
+
let config: IntlConfig<any>
|
|
11
|
+
|
|
12
|
+
let getPluralRules: any
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
config = {
|
|
15
|
+
locale: 'en',
|
|
16
|
+
|
|
17
|
+
messages: {},
|
|
18
|
+
|
|
19
|
+
defaultLocale: 'en',
|
|
20
|
+
defaultFormats: {},
|
|
21
|
+
|
|
22
|
+
onError: jest.fn(),
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
getPluralRules = jest
|
|
26
|
+
.fn()
|
|
27
|
+
.mockImplementation((...args) => new Intl.PluralRules(...args))
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
afterEach(() => {
|
|
31
|
+
process.env.NODE_ENV = NODE_ENV
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
describe('formatPlural()', () => {
|
|
35
|
+
let pf: Intl.PluralRules
|
|
36
|
+
let formatPlural: IntlFormatters['formatPlural']
|
|
37
|
+
|
|
38
|
+
beforeEach(() => {
|
|
39
|
+
pf = new Intl.PluralRules(config.locale)
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
formatPlural = formatPluralFn.bind(null, config, getPluralRules)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('should warn for invalid opt', function () {
|
|
45
|
+
// @ts-ignore
|
|
46
|
+
expect(formatPlural(0, {type: 'invalid'})).toBe('other')
|
|
47
|
+
expect(config.onError as jest.Mock).toHaveBeenCalledTimes(1)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it('formats falsy values', () => {
|
|
51
|
+
// @ts-ignore
|
|
52
|
+
expect(formatPlural(undefined)).toBe(pf.select(undefined))
|
|
53
|
+
|
|
54
|
+
// @ts-ignore
|
|
55
|
+
expect(formatPlural(false)).toBe(pf.select(false))
|
|
56
|
+
|
|
57
|
+
// @ts-ignore
|
|
58
|
+
expect(formatPlural(null)).toBe(pf.select(null))
|
|
59
|
+
|
|
60
|
+
// @ts-ignore
|
|
61
|
+
expect(formatPlural(NaN)).toBe(pf.select(NaN))
|
|
62
|
+
|
|
63
|
+
// @ts-ignore
|
|
64
|
+
expect(formatPlural('')).toBe(pf.select(''))
|
|
65
|
+
expect(formatPlural(0)).toBe(pf.select(0))
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('formats integer values', () => {
|
|
69
|
+
expect(formatPlural(0)).toBe(pf.select(0))
|
|
70
|
+
expect(formatPlural(1)).toBe(pf.select(1))
|
|
71
|
+
expect(formatPlural(2)).toBe(pf.select(2))
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it('formats decimal values', () => {
|
|
75
|
+
expect(formatPlural(0.1)).toBe(pf.select(0.1))
|
|
76
|
+
expect(formatPlural(1.0)).toBe(pf.select(1.0))
|
|
77
|
+
expect(formatPlural(1.1)).toBe(pf.select(1.1))
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('formats string values parsed as numbers', () => {
|
|
81
|
+
expect(Number('0')).toBe(0)
|
|
82
|
+
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
expect(formatPlural('0')).toBe(pf.select('0'))
|
|
85
|
+
expect(Number('1')).toBe(1)
|
|
86
|
+
|
|
87
|
+
// @ts-ignore
|
|
88
|
+
expect(formatPlural('1')).toBe(pf.select('1'))
|
|
89
|
+
|
|
90
|
+
expect(Number('0.1')).toBe(0.1)
|
|
91
|
+
|
|
92
|
+
// @ts-ignore
|
|
93
|
+
expect(formatPlural('0.1')).toBe(pf.select('0.1'))
|
|
94
|
+
expect(Number('1.0')).toBe(1.0)
|
|
95
|
+
|
|
96
|
+
// @ts-ignore
|
|
97
|
+
expect(formatPlural('1.0')).toBe(pf.select('1.0'))
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
describe('options', () => {
|
|
101
|
+
it('accepts empty options', () => {
|
|
102
|
+
expect(formatPlural(0, {})).toBe(pf.select(0))
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
it('accepts valid IntlPluralFormat options', () => {
|
|
106
|
+
expect(() => formatPlural(22, {type: 'ordinal'})).not.toThrow()
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
describe('ordinals', () => {
|
|
110
|
+
it('formats using ordinal plural rules', () => {
|
|
111
|
+
const opts = {type: 'ordinal'} as Intl.PluralRulesOptions
|
|
112
|
+
pf = new Intl.PluralRules(config.locale, opts)
|
|
113
|
+
|
|
114
|
+
expect(formatPlural(22, opts)).toBe(pf.select(22))
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
})
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/camelcase */
|
|
2
|
+
import {formatRelativeTime as formatRelativeTimeFn} from '../src/relativeTime'
|
|
3
|
+
import {IntlConfig, IntlFormatters} from '../src/types'
|
|
4
|
+
|
|
5
|
+
describe('format API', () => {
|
|
6
|
+
const {NODE_ENV} = process.env
|
|
7
|
+
|
|
8
|
+
let config: IntlConfig<any>
|
|
9
|
+
|
|
10
|
+
let getRelativeTimeFormat: any
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
config = {
|
|
13
|
+
locale: 'en',
|
|
14
|
+
|
|
15
|
+
messages: {},
|
|
16
|
+
formats: {
|
|
17
|
+
relative: {
|
|
18
|
+
seconds: {
|
|
19
|
+
style: 'narrow',
|
|
20
|
+
},
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
missing: undefined,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
defaultLocale: 'en',
|
|
26
|
+
defaultFormats: {},
|
|
27
|
+
|
|
28
|
+
onError: jest.fn(),
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
getRelativeTimeFormat = jest
|
|
32
|
+
.fn()
|
|
33
|
+
.mockImplementation((...args) => new Intl.RelativeTimeFormat(...args))
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
afterEach(() => {
|
|
37
|
+
process.env.NODE_ENV = NODE_ENV
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
describe('formatRelativeTime()', () => {
|
|
41
|
+
let rf: any
|
|
42
|
+
let formatRelativeTime: IntlFormatters['formatRelativeTime']
|
|
43
|
+
|
|
44
|
+
beforeEach(() => {
|
|
45
|
+
rf = new Intl.RelativeTimeFormat(config.locale, undefined)
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
formatRelativeTime = formatRelativeTimeFn.bind(
|
|
48
|
+
null,
|
|
49
|
+
config,
|
|
50
|
+
getRelativeTimeFormat
|
|
51
|
+
)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('falls back and warns when no value is provided', () => {
|
|
55
|
+
// @ts-ignore
|
|
56
|
+
expect(formatRelativeTime()).toBe('undefined')
|
|
57
|
+
expect(
|
|
58
|
+
(config.onError as jest.Mock).mock.calls.map(c => c[0].code)
|
|
59
|
+
).toMatchSnapshot()
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('falls back and warns when a non-finite value is provided', () => {
|
|
63
|
+
expect(formatRelativeTime(NaN)).toBe('NaN')
|
|
64
|
+
expect(config.onError as jest.Mock).toHaveBeenCalledTimes(1)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('formats falsy finite values', () => {
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
expect(formatRelativeTime(false)).toBe('in 0 seconds')
|
|
70
|
+
|
|
71
|
+
// @ts-ignore
|
|
72
|
+
expect(formatRelativeTime(null)).toBe('in 0 seconds')
|
|
73
|
+
expect(formatRelativeTime(0)).toBe(rf.format(0, 'second'))
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('formats with short format', () => {
|
|
77
|
+
expect(formatRelativeTime(-59, 'second', {style: 'short'})).toBe(
|
|
78
|
+
'59 sec. ago'
|
|
79
|
+
)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
describe('options', () => {
|
|
83
|
+
it('accepts empty options', () => {
|
|
84
|
+
expect(formatRelativeTime(0, 'second', {})).toBe(rf.format(0, 'second'))
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it('accepts valid IntlRelativeFormat options', () => {
|
|
88
|
+
expect(() =>
|
|
89
|
+
formatRelativeTime(0, 'second', {numeric: 'auto'})
|
|
90
|
+
).not.toThrow()
|
|
91
|
+
expect(() =>
|
|
92
|
+
formatRelativeTime(0, 'second', {style: 'short'})
|
|
93
|
+
).not.toThrow()
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('falls back and warns on invalid IntlRelativeFormat options', () => {
|
|
97
|
+
// @ts-ignore
|
|
98
|
+
expect(formatRelativeTime(0, 'invalid')).toBe('0')
|
|
99
|
+
expect(
|
|
100
|
+
(config.onError as jest.Mock).mock.calls.map(c => c[0].code)
|
|
101
|
+
).toMatchSnapshot()
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it('uses configured named formats', () => {
|
|
105
|
+
const format = 'seconds'
|
|
106
|
+
|
|
107
|
+
const {locale, formats} = config
|
|
108
|
+
|
|
109
|
+
rf = new Intl.RelativeTimeFormat(locale, formats!.relative![format])
|
|
110
|
+
|
|
111
|
+
expect(formatRelativeTime(-120, 'second', {format})).toBe(
|
|
112
|
+
rf.format(-120, 'second', {style: 'narrow'})
|
|
113
|
+
)
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('uses named formats as defaults', () => {
|
|
117
|
+
const opts = {numeric: 'auto' as const}
|
|
118
|
+
const format = 'seconds'
|
|
119
|
+
|
|
120
|
+
const {locale, formats} = config
|
|
121
|
+
rf = new Intl.RelativeTimeFormat(locale, {
|
|
122
|
+
...opts,
|
|
123
|
+
...formats!.relative![format],
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
expect(formatRelativeTime(0, 'minute', {...opts, format})).toBe(
|
|
127
|
+
rf.format(0, 'minute', {numeric: 'auto'})
|
|
128
|
+
)
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
it('handles missing named formats and warns', () => {
|
|
132
|
+
const format = 'missing'
|
|
133
|
+
|
|
134
|
+
rf = new Intl.RelativeTimeFormat(config.locale, undefined)
|
|
135
|
+
|
|
136
|
+
expect(formatRelativeTime(-1, 'second', {format})).toBe(
|
|
137
|
+
rf.format(-1, 'second')
|
|
138
|
+
)
|
|
139
|
+
expect(
|
|
140
|
+
(config.onError as jest.Mock).mock.calls.map(c => c[0].code)
|
|
141
|
+
).toMatchSnapshot()
|
|
142
|
+
})
|
|
143
|
+
})
|
|
144
|
+
})
|
|
145
|
+
})
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/camelcase */
|
|
2
|
+
import {DateTimeFormat} from '@formatjs/ecma402-abstract'
|
|
3
|
+
import {formatTime as formatTimeFn} from '../src/dateTime'
|
|
4
|
+
import {IntlConfig, IntlFormatters, Formatters} from '../src/types'
|
|
5
|
+
import '@formatjs/intl-datetimeformat/polyfill'
|
|
6
|
+
import '@formatjs/intl-datetimeformat/locale-data/en'
|
|
7
|
+
import '@formatjs/intl-datetimeformat/add-all-tz'
|
|
8
|
+
|
|
9
|
+
describe('format API', () => {
|
|
10
|
+
const {NODE_ENV} = process.env
|
|
11
|
+
|
|
12
|
+
let config: IntlConfig<any>
|
|
13
|
+
|
|
14
|
+
let getDateTimeFormat: Formatters['getDateTimeFormat'] = (
|
|
15
|
+
...args: ConstructorParameters<typeof Intl.DateTimeFormat>
|
|
16
|
+
) => new Intl.DateTimeFormat(...args) as DateTimeFormat
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
config = {
|
|
19
|
+
locale: 'en',
|
|
20
|
+
|
|
21
|
+
messages: {},
|
|
22
|
+
|
|
23
|
+
formats: {
|
|
24
|
+
time: {
|
|
25
|
+
'hour-only': {
|
|
26
|
+
hour: '2-digit',
|
|
27
|
+
hour12: false,
|
|
28
|
+
},
|
|
29
|
+
missing: undefined,
|
|
30
|
+
},
|
|
31
|
+
} as any,
|
|
32
|
+
|
|
33
|
+
defaultLocale: 'en',
|
|
34
|
+
defaultFormats: {},
|
|
35
|
+
|
|
36
|
+
onError: jest.fn(),
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
afterEach(() => {
|
|
41
|
+
process.env.NODE_ENV = NODE_ENV
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
describe('formatTime()', () => {
|
|
45
|
+
let df: Intl.DateTimeFormat
|
|
46
|
+
let formatTime: IntlFormatters['formatTime']
|
|
47
|
+
|
|
48
|
+
beforeEach(() => {
|
|
49
|
+
df = new Intl.DateTimeFormat(config.locale, {
|
|
50
|
+
hour: 'numeric',
|
|
51
|
+
minute: 'numeric',
|
|
52
|
+
})
|
|
53
|
+
// @ts-ignore
|
|
54
|
+
formatTime = formatTimeFn.bind(null, config, getDateTimeFormat)
|
|
55
|
+
;(config.onError as jest.Mock).mockClear()
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('render now if no value is provided', () => {
|
|
59
|
+
// @ts-ignore
|
|
60
|
+
expect(formatTime()).toBe(df.format())
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('should not inject additional hour/minute when dateStyle are used', function () {
|
|
64
|
+
expect(config.onError).not.toHaveBeenCalled()
|
|
65
|
+
formatTimeFn(config as any, getDateTimeFormat, new Date(), {
|
|
66
|
+
dateStyle: 'short',
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
expect(config.onError).not.toHaveBeenCalled()
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('should not inject additional hour/minute when timeStyle are used', function () {
|
|
73
|
+
expect(config.onError).not.toHaveBeenCalled()
|
|
74
|
+
formatTimeFn(config as any, getDateTimeFormat, new Date(), {
|
|
75
|
+
timeStyle: 'short',
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
expect(config.onError).not.toHaveBeenCalled()
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('falls back and warns when a non-finite value is provided', () => {
|
|
82
|
+
expect(formatTime(NaN)).toBe('NaN')
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
expect(formatTime('')).toBe(df.format(''))
|
|
85
|
+
expect(config.onError as jest.Mock).toHaveBeenCalledTimes(1)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('formats falsy finite values', () => {
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
expect(formatTime(false)).toBe(df.format(false))
|
|
91
|
+
// @ts-ignore
|
|
92
|
+
expect(formatTime(null)).toBe(df.format(null))
|
|
93
|
+
expect(formatTime(0)).toBe(df.format(0))
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('formats date instance values', () => {
|
|
97
|
+
expect(formatTime(new Date(0))).toBe(df.format(new Date(0)))
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('formats date string values', () => {
|
|
101
|
+
expect(formatTime(new Date(0).toString())).toBe(df.format(0))
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it('formats date ms timestamp values', () => {
|
|
105
|
+
const timestamp = Date.now()
|
|
106
|
+
expect(formatTime(timestamp)).toBe(df.format(timestamp))
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('uses the time zone specified by the provider', () => {
|
|
110
|
+
const timestamp = Date.now()
|
|
111
|
+
config.timeZone = 'Africa/Johannesburg'
|
|
112
|
+
// @ts-ignore
|
|
113
|
+
formatTime = formatTimeFn.bind(null, config, getDateTimeFormat)
|
|
114
|
+
const johannesburgDf = new Intl.DateTimeFormat(config.locale, {
|
|
115
|
+
hour: 'numeric',
|
|
116
|
+
minute: 'numeric',
|
|
117
|
+
timeZone: 'Africa/Johannesburg',
|
|
118
|
+
})
|
|
119
|
+
expect(formatTime(timestamp)).toBe(johannesburgDf.format(timestamp))
|
|
120
|
+
config.timeZone = 'America/Chicago'
|
|
121
|
+
// @ts-ignore
|
|
122
|
+
formatTime = formatTimeFn.bind(null, config, getDateTimeFormat)
|
|
123
|
+
const chicagoDf = new Intl.DateTimeFormat(config.locale, {
|
|
124
|
+
hour: 'numeric',
|
|
125
|
+
minute: 'numeric',
|
|
126
|
+
timeZone: 'America/Chicago',
|
|
127
|
+
})
|
|
128
|
+
expect(formatTime(timestamp)).toBe(chicagoDf.format(timestamp))
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
describe('options', () => {
|
|
132
|
+
it('accepts empty options', () => {
|
|
133
|
+
expect(formatTime(0, {})).toBe(df.format(0))
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it('accepts valid Intl.DateTimeFormat options', () => {
|
|
137
|
+
expect(() => formatTime(0, {hour: '2-digit'})).not.toThrow()
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
it('falls back and warns on invalid Intl.DateTimeFormat options', () => {
|
|
141
|
+
// @ts-expect-error just for test
|
|
142
|
+
expect(formatTime(0, {hour: 'invalid'})).toBe('0')
|
|
143
|
+
expect(
|
|
144
|
+
(config.onError as jest.Mock).mock.calls.map(c => c[0].code)
|
|
145
|
+
).toMatchSnapshot()
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
it('uses configured named formats', () => {
|
|
149
|
+
const date = new Date()
|
|
150
|
+
const format = 'hour-only'
|
|
151
|
+
|
|
152
|
+
const {locale, formats} = config
|
|
153
|
+
df = new Intl.DateTimeFormat(locale, formats!.time![format])
|
|
154
|
+
|
|
155
|
+
expect(formatTime(date, {format})).toBe(df.format(date))
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
it('uses named formats as defaults', () => {
|
|
159
|
+
const date = new Date()
|
|
160
|
+
const opts: Intl.DateTimeFormatOptions = {minute: '2-digit'}
|
|
161
|
+
const format = 'hour-only'
|
|
162
|
+
|
|
163
|
+
const {locale, formats} = config
|
|
164
|
+
df = new Intl.DateTimeFormat(locale, {
|
|
165
|
+
...opts,
|
|
166
|
+
...formats!.time![format],
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
expect(formatTime(date, {...opts, format})).toBe(df.format(date))
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
it('handles missing named formats and warns', () => {
|
|
173
|
+
const date = new Date()
|
|
174
|
+
const format = 'missing'
|
|
175
|
+
|
|
176
|
+
expect(formatTime(date, {format})).toBe(df.format(date))
|
|
177
|
+
expect(
|
|
178
|
+
(config.onError as jest.Mock).mock.calls.map(c => c[0].code)
|
|
179
|
+
).toMatchSnapshot()
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
it('should set default values', () => {
|
|
183
|
+
const date = new Date()
|
|
184
|
+
const {locale} = config
|
|
185
|
+
const day = 'numeric'
|
|
186
|
+
df = new Intl.DateTimeFormat(locale, {
|
|
187
|
+
hour: 'numeric',
|
|
188
|
+
minute: 'numeric',
|
|
189
|
+
day,
|
|
190
|
+
})
|
|
191
|
+
expect(formatTime(date, {day})).toBe(df.format(date))
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
it('should not set default values when second is provided', () => {
|
|
195
|
+
const date = new Date()
|
|
196
|
+
const {locale} = config
|
|
197
|
+
const second = 'numeric'
|
|
198
|
+
df = new Intl.DateTimeFormat(locale, {second})
|
|
199
|
+
expect(formatTime(date, {second})).toBe(df.format(date))
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('should not set default values when minute is provided', () => {
|
|
203
|
+
const date = new Date()
|
|
204
|
+
const {locale} = config
|
|
205
|
+
const minute = 'numeric'
|
|
206
|
+
df = new Intl.DateTimeFormat(locale, {minute})
|
|
207
|
+
expect(formatTime(date, {minute})).toBe(df.format(date))
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
it('should not set default values when hour is provided', () => {
|
|
211
|
+
const date = new Date()
|
|
212
|
+
const {locale} = config
|
|
213
|
+
const hour = 'numeric'
|
|
214
|
+
df = new Intl.DateTimeFormat(locale, {hour})
|
|
215
|
+
expect(formatTime(date, {hour})).toBe(df.format(date))
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
it('uses time zone specified in options over the one passed through by the provider', () => {
|
|
219
|
+
const timestamp = Date.now()
|
|
220
|
+
config.timeZone = 'Africa/Johannesburg'
|
|
221
|
+
// @ts-ignore
|
|
222
|
+
formatTime = formatTimeFn.bind(null, config, getDateTimeFormat)
|
|
223
|
+
const chicagoDf = new Intl.DateTimeFormat(config.locale, {
|
|
224
|
+
hour: 'numeric',
|
|
225
|
+
minute: 'numeric',
|
|
226
|
+
timeZone: 'America/Chicago',
|
|
227
|
+
})
|
|
228
|
+
expect(formatTime(timestamp, {timeZone: 'America/Chicago'})).toBe(
|
|
229
|
+
chicagoDf.format(timestamp)
|
|
230
|
+
)
|
|
231
|
+
})
|
|
232
|
+
})
|
|
233
|
+
})
|
|
234
|
+
})
|
package/tsconfig.json
ADDED
package/index.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { MessageDescriptor } from './src/types';
|
|
2
|
-
export * from './src/types';
|
|
3
|
-
export declare function defineMessages<K extends keyof any, T = MessageDescriptor, U extends Record<K, T> = Record<K, T>>(msgs: U): U;
|
|
4
|
-
export declare function defineMessage<T>(msg: T): T;
|
|
5
|
-
export { createIntlCache, filterProps, DEFAULT_INTL_CONFIG, createFormatters, getNamedFormat, } from './src/utils';
|
|
6
|
-
export * from './src/error';
|
|
7
|
-
export { formatMessage } from './src/message';
|
|
8
|
-
export type { FormatMessageFn } from './src/message';
|
|
9
|
-
export { formatDate, formatDateToParts, formatTime, formatTimeToParts, } from './src/dateTime';
|
|
10
|
-
export { formatDisplayName } from './src/displayName';
|
|
11
|
-
export { formatList } from './src/list';
|
|
12
|
-
export { formatPlural } from './src/plural';
|
|
13
|
-
export { formatRelativeTime } from './src/relativeTime';
|
|
14
|
-
export { formatNumber, formatNumberToParts } from './src/number';
|
|
15
|
-
export { createIntl } from './src/create-intl';
|
|
16
|
-
export type { CreateIntlFn } from './src/create-intl';
|
|
17
|
-
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/intl/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,aAAa,CAAA;AAC7C,cAAc,aAAa,CAAA;AAE3B,wBAAgB,cAAc,CAC5B,CAAC,SAAS,MAAM,GAAG,EACnB,CAAC,GAAG,iBAAiB,EACrB,CAAC,SAAS,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EACrC,IAAI,EAAE,CAAC,GAAG,CAAC,CAEZ;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAE1C;AAED,OAAO,EACL,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,GACf,MAAM,aAAa,CAAA;AACpB,cAAc,aAAa,CAAA;AAC3B,OAAO,EAAC,aAAa,EAAC,MAAM,eAAe,CAAA;AAC3C,YAAY,EAAC,eAAe,EAAC,MAAM,eAAe,CAAA;AAClD,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,iBAAiB,GAClB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAC,iBAAiB,EAAC,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAA;AACrC,OAAO,EAAC,YAAY,EAAC,MAAM,cAAc,CAAA;AACzC,OAAO,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAC,YAAY,EAAE,mBAAmB,EAAC,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAA;AAC5C,YAAY,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAA"}
|
package/index.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createIntl = exports.formatNumberToParts = exports.formatNumber = exports.formatRelativeTime = exports.formatPlural = exports.formatList = exports.formatDisplayName = exports.formatTimeToParts = exports.formatTime = exports.formatDateToParts = exports.formatDate = exports.formatMessage = exports.getNamedFormat = exports.createFormatters = exports.DEFAULT_INTL_CONFIG = exports.filterProps = exports.createIntlCache = exports.defineMessage = exports.defineMessages = void 0;
|
|
4
|
-
var tslib_1 = require("tslib");
|
|
5
|
-
(0, tslib_1.__exportStar)(require("./src/types"), exports);
|
|
6
|
-
function defineMessages(msgs) {
|
|
7
|
-
return msgs;
|
|
8
|
-
}
|
|
9
|
-
exports.defineMessages = defineMessages;
|
|
10
|
-
function defineMessage(msg) {
|
|
11
|
-
return msg;
|
|
12
|
-
}
|
|
13
|
-
exports.defineMessage = defineMessage;
|
|
14
|
-
var utils_1 = require("./src/utils");
|
|
15
|
-
Object.defineProperty(exports, "createIntlCache", { enumerable: true, get: function () { return utils_1.createIntlCache; } });
|
|
16
|
-
Object.defineProperty(exports, "filterProps", { enumerable: true, get: function () { return utils_1.filterProps; } });
|
|
17
|
-
Object.defineProperty(exports, "DEFAULT_INTL_CONFIG", { enumerable: true, get: function () { return utils_1.DEFAULT_INTL_CONFIG; } });
|
|
18
|
-
Object.defineProperty(exports, "createFormatters", { enumerable: true, get: function () { return utils_1.createFormatters; } });
|
|
19
|
-
Object.defineProperty(exports, "getNamedFormat", { enumerable: true, get: function () { return utils_1.getNamedFormat; } });
|
|
20
|
-
(0, tslib_1.__exportStar)(require("./src/error"), exports);
|
|
21
|
-
var message_1 = require("./src/message");
|
|
22
|
-
Object.defineProperty(exports, "formatMessage", { enumerable: true, get: function () { return message_1.formatMessage; } });
|
|
23
|
-
var dateTime_1 = require("./src/dateTime");
|
|
24
|
-
Object.defineProperty(exports, "formatDate", { enumerable: true, get: function () { return dateTime_1.formatDate; } });
|
|
25
|
-
Object.defineProperty(exports, "formatDateToParts", { enumerable: true, get: function () { return dateTime_1.formatDateToParts; } });
|
|
26
|
-
Object.defineProperty(exports, "formatTime", { enumerable: true, get: function () { return dateTime_1.formatTime; } });
|
|
27
|
-
Object.defineProperty(exports, "formatTimeToParts", { enumerable: true, get: function () { return dateTime_1.formatTimeToParts; } });
|
|
28
|
-
var displayName_1 = require("./src/displayName");
|
|
29
|
-
Object.defineProperty(exports, "formatDisplayName", { enumerable: true, get: function () { return displayName_1.formatDisplayName; } });
|
|
30
|
-
var list_1 = require("./src/list");
|
|
31
|
-
Object.defineProperty(exports, "formatList", { enumerable: true, get: function () { return list_1.formatList; } });
|
|
32
|
-
var plural_1 = require("./src/plural");
|
|
33
|
-
Object.defineProperty(exports, "formatPlural", { enumerable: true, get: function () { return plural_1.formatPlural; } });
|
|
34
|
-
var relativeTime_1 = require("./src/relativeTime");
|
|
35
|
-
Object.defineProperty(exports, "formatRelativeTime", { enumerable: true, get: function () { return relativeTime_1.formatRelativeTime; } });
|
|
36
|
-
var number_1 = require("./src/number");
|
|
37
|
-
Object.defineProperty(exports, "formatNumber", { enumerable: true, get: function () { return number_1.formatNumber; } });
|
|
38
|
-
Object.defineProperty(exports, "formatNumberToParts", { enumerable: true, get: function () { return number_1.formatNumberToParts; } });
|
|
39
|
-
var create_intl_1 = require("./src/create-intl");
|
|
40
|
-
Object.defineProperty(exports, "createIntl", { enumerable: true, get: function () { return create_intl_1.createIntl; } });
|
package/lib/index.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { MessageDescriptor } from './src/types';
|
|
2
|
-
export * from './src/types';
|
|
3
|
-
export declare function defineMessages<K extends keyof any, T = MessageDescriptor, U extends Record<K, T> = Record<K, T>>(msgs: U): U;
|
|
4
|
-
export declare function defineMessage<T>(msg: T): T;
|
|
5
|
-
export { createIntlCache, filterProps, DEFAULT_INTL_CONFIG, createFormatters, getNamedFormat, } from './src/utils';
|
|
6
|
-
export * from './src/error';
|
|
7
|
-
export { formatMessage } from './src/message';
|
|
8
|
-
export type { FormatMessageFn } from './src/message';
|
|
9
|
-
export { formatDate, formatDateToParts, formatTime, formatTimeToParts, } from './src/dateTime';
|
|
10
|
-
export { formatDisplayName } from './src/displayName';
|
|
11
|
-
export { formatList } from './src/list';
|
|
12
|
-
export { formatPlural } from './src/plural';
|
|
13
|
-
export { formatRelativeTime } from './src/relativeTime';
|
|
14
|
-
export { formatNumber, formatNumberToParts } from './src/number';
|
|
15
|
-
export { createIntl } from './src/create-intl';
|
|
16
|
-
export type { CreateIntlFn } from './src/create-intl';
|
|
17
|
-
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../packages/intl/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,aAAa,CAAA;AAC7C,cAAc,aAAa,CAAA;AAE3B,wBAAgB,cAAc,CAC5B,CAAC,SAAS,MAAM,GAAG,EACnB,CAAC,GAAG,iBAAiB,EACrB,CAAC,SAAS,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EACrC,IAAI,EAAE,CAAC,GAAG,CAAC,CAEZ;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAE1C;AAED,OAAO,EACL,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,GACf,MAAM,aAAa,CAAA;AACpB,cAAc,aAAa,CAAA;AAC3B,OAAO,EAAC,aAAa,EAAC,MAAM,eAAe,CAAA;AAC3C,YAAY,EAAC,eAAe,EAAC,MAAM,eAAe,CAAA;AAClD,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,iBAAiB,GAClB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAC,iBAAiB,EAAC,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAA;AACrC,OAAO,EAAC,YAAY,EAAC,MAAM,cAAc,CAAA;AACzC,OAAO,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAC,YAAY,EAAE,mBAAmB,EAAC,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAA;AAC5C,YAAY,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAA"}
|
package/lib/index.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export * from './src/types';
|
|
2
|
-
export function defineMessages(msgs) {
|
|
3
|
-
return msgs;
|
|
4
|
-
}
|
|
5
|
-
export function defineMessage(msg) {
|
|
6
|
-
return msg;
|
|
7
|
-
}
|
|
8
|
-
export { createIntlCache, filterProps, DEFAULT_INTL_CONFIG, createFormatters, getNamedFormat, } from './src/utils';
|
|
9
|
-
export * from './src/error';
|
|
10
|
-
export { formatMessage } from './src/message';
|
|
11
|
-
export { formatDate, formatDateToParts, formatTime, formatTimeToParts, } from './src/dateTime';
|
|
12
|
-
export { formatDisplayName } from './src/displayName';
|
|
13
|
-
export { formatList } from './src/list';
|
|
14
|
-
export { formatPlural } from './src/plural';
|
|
15
|
-
export { formatRelativeTime } from './src/relativeTime';
|
|
16
|
-
export { formatNumber, formatNumberToParts } from './src/number';
|
|
17
|
-
export { createIntl } from './src/create-intl';
|
package/lib/src/create-intl.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { IntlCache, IntlShape, IntlConfig } from './types';
|
|
2
|
-
export interface CreateIntlFn<T = string, C extends IntlConfig<T> = IntlConfig<T>, S extends IntlShape<T> = IntlShape<T>> {
|
|
3
|
-
(config: C, cache?: IntlCache): S;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* Create intl object
|
|
7
|
-
* @param config intl config
|
|
8
|
-
* @param cache cache for formatter instances to prevent memory leak
|
|
9
|
-
*/
|
|
10
|
-
export declare function createIntl<T = string>(config: IntlConfig<T>, cache?: IntlCache): IntlShape<T>;
|
|
11
|
-
//# sourceMappingURL=create-intl.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create-intl.d.ts","sourceRoot":"","sources":["../../../../../../../packages/intl/src/create-intl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAqB,MAAM,SAAS,CAAA;AAkB5E,MAAM,WAAW,YAAY,CAC3B,CAAC,GAAG,MAAM,EACV,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,EACvC,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAErC,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,CAAC,CAAA;CAClC;AAsBD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,GAAG,MAAM,EACnC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,EACrB,KAAK,CAAC,EAAE,SAAS,GAChB,SAAS,CAAC,CAAC,CAAC,CAsGd"}
|