react-intl 3.12.0 → 4.1.1
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/CHANGELOG.md +47 -0
- package/dist/components/message.d.ts +1 -1
- package/dist/components/message.js +2 -2
- package/dist/components/plural.d.ts +1 -1
- package/dist/components/provider.js +13 -8
- package/dist/error.d.ts +11 -0
- package/dist/error.js +28 -0
- package/dist/formatters/dateTime.js +5 -4
- package/dist/formatters/displayName.js +4 -2
- package/dist/formatters/list.js +4 -2
- package/dist/formatters/message.d.ts +1 -2
- package/dist/formatters/message.js +17 -34
- package/dist/formatters/number.js +3 -2
- package/dist/formatters/plural.js +4 -2
- package/dist/formatters/relativeTime.js +4 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -4
- package/dist/react-intl.api.md +29 -22
- package/dist/react-intl.d.ts +77 -36
- package/dist/react-intl.js +6267 -5860
- package/dist/react-intl.js.map +1 -1
- package/dist/react-intl.min.js +1 -1
- package/dist/react-intl.min.js.map +1 -1
- package/dist/types.d.ts +5 -5
- package/dist/utils.d.ts +3 -4
- package/dist/utils.js +2 -18
- package/lib/components/message.d.ts +1 -1
- package/lib/components/message.js +2 -2
- package/lib/components/plural.d.ts +1 -1
- package/lib/components/provider.js +15 -10
- package/lib/error.d.ts +11 -0
- package/lib/error.js +9 -0
- package/lib/formatters/dateTime.js +6 -5
- package/lib/formatters/displayName.js +6 -4
- package/lib/formatters/list.js +6 -4
- package/lib/formatters/message.d.ts +1 -2
- package/lib/formatters/message.js +17 -31
- package/lib/formatters/number.js +4 -3
- package/lib/formatters/plural.js +6 -4
- package/lib/formatters/relativeTime.js +6 -4
- package/lib/index.d.ts +2 -2
- package/lib/index.js +4 -2
- package/lib/react-intl.d.ts +21 -17
- package/lib/tsdoc-metadata.json +1 -1
- package/lib/types.d.ts +5 -5
- package/lib/utils.d.ts +3 -4
- package/lib/utils.js +2 -16
- package/package.json +45 -47
- package/src/components/message.tsx +6 -5
- package/src/components/provider.tsx +25 -14
- package/src/error.ts +18 -0
- package/src/formatters/dateTime.ts +30 -5
- package/src/formatters/displayName.ts +15 -4
- package/src/formatters/list.ts +15 -4
- package/src/formatters/message.ts +49 -66
- package/src/formatters/number.ts +16 -3
- package/src/formatters/plural.ts +15 -4
- package/src/formatters/relativeTime.ts +15 -4
- package/src/index.ts +4 -2
- package/src/types.ts +5 -7
- package/src/utils.ts +4 -25
- package/dist/components/html-message.d.ts +0 -11
- package/dist/components/html-message.js +0 -75
- package/lib/components/html-message.d.ts +0 -11
- package/lib/components/html-message.js +0 -43
- package/src/components/html-message.tsx +0 -68
package/lib/tsdoc-metadata.json
CHANGED
package/lib/types.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import IntlMessageFormat, { Formats, PrimitiveType, FormatXMLElementFn } from 'intl-messageformat';
|
|
2
|
+
import IntlMessageFormat, { Formats, PrimitiveType, FormatXMLElementFn, FormatError } from 'intl-messageformat';
|
|
3
3
|
import IntlRelativeTimeFormat, { IntlRelativeTimeFormatOptions } from '@formatjs/intl-relativetimeformat';
|
|
4
4
|
import { MessageFormatElement } from 'intl-messageformat-parser';
|
|
5
5
|
import { UnifiedNumberFormatOptions } from '@formatjs/intl-unified-numberformat';
|
|
6
6
|
import IntlListFormat, { IntlListFormatOptions } from '@formatjs/intl-listformat';
|
|
7
7
|
import { DisplayNames, DisplayNamesOptions } from '@formatjs/intl-displaynames';
|
|
8
|
+
import { ReactIntlError } from './error';
|
|
8
9
|
export interface IntlConfig {
|
|
9
10
|
locale: string;
|
|
10
11
|
timeZone?: string;
|
|
@@ -13,7 +14,7 @@ export interface IntlConfig {
|
|
|
13
14
|
messages: Record<string, string> | Record<string, MessageFormatElement[]>;
|
|
14
15
|
defaultLocale: string;
|
|
15
16
|
defaultFormats: CustomFormats;
|
|
16
|
-
onError(err:
|
|
17
|
+
onError(err: ReactIntlError | FormatError): void;
|
|
17
18
|
}
|
|
18
19
|
export interface CustomFormats extends Partial<Formats> {
|
|
19
20
|
relative?: Record<string, IntlRelativeTimeFormatOptions>;
|
|
@@ -27,7 +28,7 @@ export declare type FormatRelativeTimeOptions = Exclude<IntlRelativeTimeFormatOp
|
|
|
27
28
|
export declare type FormatPluralOptions = Exclude<Intl.PluralRulesOptions, 'localeMatcher'> & CustomFormatConfig;
|
|
28
29
|
export declare type FormatListOptions = Exclude<IntlListFormatOptions, 'localeMatcher'>;
|
|
29
30
|
export declare type FormatDisplayNameOptions = Exclude<DisplayNamesOptions, 'localeMatcher'>;
|
|
30
|
-
export interface IntlFormatters {
|
|
31
|
+
export interface IntlFormatters<T = React.ReactNode> {
|
|
31
32
|
formatDate(value: Parameters<Intl.DateTimeFormat['format']>[0] | string, opts?: FormatDateOptions): string;
|
|
32
33
|
formatTime(value: Parameters<Intl.DateTimeFormat['format']>[0] | string, opts?: FormatDateOptions): string;
|
|
33
34
|
formatDateToParts(value: Parameters<Intl.DateTimeFormat['format']>[0] | string, opts?: FormatDateOptions): Intl.DateTimeFormatPart[];
|
|
@@ -37,8 +38,7 @@ export interface IntlFormatters {
|
|
|
37
38
|
formatNumberToParts(value: Parameters<Intl.NumberFormat['format']>[0], opts?: FormatNumberOptions): Intl.NumberFormatPart[];
|
|
38
39
|
formatPlural(value: Parameters<Intl.PluralRules['select']>[0], opts?: FormatPluralOptions): ReturnType<Intl.PluralRules['select']>;
|
|
39
40
|
formatMessage(descriptor: MessageDescriptor, values?: Record<string, PrimitiveType>): string;
|
|
40
|
-
formatMessage(descriptor: MessageDescriptor, values?: Record<string, PrimitiveType | React.ReactElement | FormatXMLElementFn
|
|
41
|
-
formatHTMLMessage(descriptor: MessageDescriptor, values?: Record<string, PrimitiveType>): React.ReactNode;
|
|
41
|
+
formatMessage(descriptor: MessageDescriptor, values?: Record<string, PrimitiveType | React.ReactElement | FormatXMLElementFn<T>>): string | React.ReactNodeArray;
|
|
42
42
|
formatList(values: Array<string>, opts?: FormatListOptions): string;
|
|
43
43
|
formatList(values: Array<string | React.ReactNode>, opts?: FormatListOptions): React.ReactNode;
|
|
44
44
|
formatDisplayName(value: Parameters<DisplayNames['of']>[0], opts?: FormatDisplayNameOptions): string | undefined;
|
package/lib/utils.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { IntlConfig, IntlCache, CustomFormats, Formatters } from './types';
|
|
2
2
|
import { IntlRelativeTimeFormatOptions } from '@formatjs/intl-relativetimeformat';
|
|
3
|
-
|
|
3
|
+
import { ReactIntlError } from './error';
|
|
4
4
|
export declare function filterProps<T extends Record<string, any>, K extends string>(props: T, whitelist: Array<K>, defaults?: Partial<T>): Pick<T, K>;
|
|
5
5
|
export declare function invariantIntlContext(intl?: any): asserts intl;
|
|
6
|
-
export declare function
|
|
7
|
-
export declare function defaultErrorHandler(error: string): void;
|
|
6
|
+
export declare function defaultErrorHandler(error: ReactIntlError): void;
|
|
8
7
|
export declare const DEFAULT_INTL_CONFIG: Pick<IntlConfig, 'formats' | 'messages' | 'timeZone' | 'textComponent' | 'defaultLocale' | 'defaultFormats' | 'onError'>;
|
|
9
8
|
export declare function createIntlCache(): IntlCache;
|
|
10
9
|
/**
|
|
@@ -12,4 +11,4 @@ export declare function createIntlCache(): IntlCache;
|
|
|
12
11
|
* @param cache explicit cache to prevent leaking memory
|
|
13
12
|
*/
|
|
14
13
|
export declare function createFormatters(cache?: IntlCache): Formatters;
|
|
15
|
-
export declare function getNamedFormat<T extends keyof CustomFormats>(formats: CustomFormats, type: T, name: string, onError: (err:
|
|
14
|
+
export declare function getNamedFormat<T extends keyof CustomFormats>(formats: CustomFormats, type: T, name: string, onError: (err: ReactIntlError) => void): Intl.NumberFormatOptions | Intl.DateTimeFormatOptions | IntlRelativeTimeFormatOptions | undefined;
|
package/lib/utils.js
CHANGED
|
@@ -12,17 +12,7 @@ import * as React from 'react';
|
|
|
12
12
|
import IntlMessageFormat from 'intl-messageformat';
|
|
13
13
|
import memoizeIntlConstructor from 'intl-format-cache';
|
|
14
14
|
import { invariant } from '@formatjs/intl-utils';
|
|
15
|
-
|
|
16
|
-
38: '&',
|
|
17
|
-
62: '>',
|
|
18
|
-
60: '<',
|
|
19
|
-
34: '"',
|
|
20
|
-
39: ''',
|
|
21
|
-
};
|
|
22
|
-
const UNSAFE_CHARS_REGEX = /[&><"']/g;
|
|
23
|
-
export function escape(str) {
|
|
24
|
-
return ('' + str).replace(UNSAFE_CHARS_REGEX, match => ESCAPED_CHARS[match.charCodeAt(0)]);
|
|
25
|
-
}
|
|
15
|
+
import { ReactIntlError } from './error';
|
|
26
16
|
export function filterProps(props, whitelist, defaults = {}) {
|
|
27
17
|
return whitelist.reduce((filtered, name) => {
|
|
28
18
|
if (name in props) {
|
|
@@ -38,10 +28,6 @@ export function invariantIntlContext(intl) {
|
|
|
38
28
|
invariant(intl, '[React Intl] Could not find required `intl` object. ' +
|
|
39
29
|
'<IntlProvider> needs to exist in the component ancestry.');
|
|
40
30
|
}
|
|
41
|
-
export function createError(message, exception) {
|
|
42
|
-
const eMsg = exception ? `\n${exception.stack}` : '';
|
|
43
|
-
return `[React Intl] ${message}${eMsg}`;
|
|
44
|
-
}
|
|
45
31
|
export function defaultErrorHandler(error) {
|
|
46
32
|
if (process.env.NODE_ENV !== 'production') {
|
|
47
33
|
console.error(error);
|
|
@@ -94,5 +80,5 @@ export function getNamedFormat(formats, type, name, onError) {
|
|
|
94
80
|
if (format) {
|
|
95
81
|
return format;
|
|
96
82
|
}
|
|
97
|
-
onError(
|
|
83
|
+
onError(new ReactIntlError("UNSUPPORTED_FORMATTER" /* UNSUPPORTED_FORMATTER */, `No ${type} format named: ${name}`));
|
|
98
84
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-intl",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.1.1",
|
|
4
4
|
"description": "Internationalize React apps. This library provides React components and an API to format dates, numbers, and strings, including pluralization and handling translations.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"intl",
|
|
@@ -131,75 +131,73 @@
|
|
|
131
131
|
"types": "./lib/react-intl.d.ts",
|
|
132
132
|
"sideEffects": false,
|
|
133
133
|
"dependencies": {
|
|
134
|
-
"@formatjs/intl-displaynames": "^1.2.
|
|
135
|
-
"@formatjs/intl-listformat": "^1.
|
|
136
|
-
"@formatjs/intl-relativetimeformat": "^4.5.
|
|
137
|
-
"@formatjs/intl-unified-numberformat": "^3.0
|
|
138
|
-
"@formatjs/intl-utils": "^2.0
|
|
139
|
-
"@formatjs/macro": "^0.2.6",
|
|
134
|
+
"@formatjs/intl-displaynames": "^1.2.1",
|
|
135
|
+
"@formatjs/intl-listformat": "^1.4.1",
|
|
136
|
+
"@formatjs/intl-relativetimeformat": "^4.5.9",
|
|
137
|
+
"@formatjs/intl-unified-numberformat": "^3.2.0",
|
|
138
|
+
"@formatjs/intl-utils": "^2.2.0",
|
|
140
139
|
"@types/hoist-non-react-statics": "^3.3.1",
|
|
141
140
|
"@types/invariant": "^2.2.31",
|
|
142
|
-
"hoist-non-react-statics": "^3.3.
|
|
143
|
-
"intl-format-cache": "^4.2.
|
|
144
|
-
"intl-
|
|
145
|
-
"intl-messageformat": "^
|
|
146
|
-
"intl-messageformat-parser": "^3.6.2",
|
|
141
|
+
"hoist-non-react-statics": "^3.3.2",
|
|
142
|
+
"intl-format-cache": "^4.2.21",
|
|
143
|
+
"intl-messageformat": "^8.2.1",
|
|
144
|
+
"intl-messageformat-parser": "^4.1.0",
|
|
147
145
|
"shallow-equal": "^1.2.1"
|
|
148
146
|
},
|
|
149
147
|
"peerDependencies": {
|
|
150
148
|
"react": "^16.3.0"
|
|
151
149
|
},
|
|
152
150
|
"devDependencies": {
|
|
153
|
-
"@babel/core": "^7.
|
|
154
|
-
"@babel/node": "^7.
|
|
155
|
-
"@babel/plugin-proposal-class-properties": "^7.
|
|
156
|
-
"@babel/plugin-transform-modules-commonjs": "^7.
|
|
157
|
-
"@babel/preset-env": "^7.
|
|
158
|
-
"@babel/preset-react": "^7.
|
|
159
|
-
"@formatjs/intl-pluralrules": "^1.5.
|
|
160
|
-
"@microsoft/api-documenter": "^7.7.
|
|
161
|
-
"@microsoft/api-extractor": "^7.7.
|
|
151
|
+
"@babel/core": "^7.8.7",
|
|
152
|
+
"@babel/node": "^7.8.7",
|
|
153
|
+
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
|
154
|
+
"@babel/plugin-transform-modules-commonjs": "^7.8.3",
|
|
155
|
+
"@babel/preset-env": "^7.8.7",
|
|
156
|
+
"@babel/preset-react": "^7.8.3",
|
|
157
|
+
"@formatjs/intl-pluralrules": "^1.5.2",
|
|
158
|
+
"@microsoft/api-documenter": "^7.7.12",
|
|
159
|
+
"@microsoft/api-extractor": "^7.7.8",
|
|
162
160
|
"@types/benchmark": "^1.0.31",
|
|
163
|
-
"@types/enzyme": "^3.10.
|
|
164
|
-
"@types/jest": "^
|
|
161
|
+
"@types/enzyme": "^3.10.5",
|
|
162
|
+
"@types/jest": "^25.1.3",
|
|
165
163
|
"@types/prop-types": "^15.7.3",
|
|
166
|
-
"@types/react": "^16.9.
|
|
167
|
-
"@types/react-dom": "^16.9.
|
|
168
|
-
"@typescript-eslint/eslint-plugin": "^2.
|
|
169
|
-
"@typescript-eslint/parser": "^2.
|
|
170
|
-
"babel-jest": "^
|
|
171
|
-
"benchmark": "^2.1.
|
|
172
|
-
"core-js": "^3.6.
|
|
173
|
-
"cross-env": "^
|
|
164
|
+
"@types/react": "^16.9.23",
|
|
165
|
+
"@types/react-dom": "^16.9.5",
|
|
166
|
+
"@typescript-eslint/eslint-plugin": "^2.22.0",
|
|
167
|
+
"@typescript-eslint/parser": "^2.22.0",
|
|
168
|
+
"babel-jest": "^25.1.0",
|
|
169
|
+
"benchmark": "^2.1.4",
|
|
170
|
+
"core-js": "^3.6.4",
|
|
171
|
+
"cross-env": "^7.0.2",
|
|
174
172
|
"enzyme": "^3.11.0",
|
|
175
173
|
"enzyme-adapter-react-16": "^1.15.2",
|
|
176
|
-
"enzyme-to-json": "^3.4.
|
|
174
|
+
"enzyme-to-json": "^3.4.4",
|
|
177
175
|
"eslint": "^6.8.0",
|
|
178
|
-
"eslint-plugin-react": "^7.
|
|
176
|
+
"eslint-plugin-react": "^7.18.3",
|
|
179
177
|
"fs-extra": "^8.1.0",
|
|
180
|
-
"full-icu": "^1.3.
|
|
178
|
+
"full-icu": "^1.3.1",
|
|
181
179
|
"glob": "^7.1.6",
|
|
182
|
-
"jest": "^
|
|
180
|
+
"jest": "^25.1.0",
|
|
183
181
|
"markdown-toc": "^1.2.0",
|
|
184
|
-
"mkdirp": "^0.
|
|
182
|
+
"mkdirp": "^1.0.3",
|
|
185
183
|
"parcel": "^1.12.4",
|
|
186
184
|
"pre-commit": "^1.2.2",
|
|
187
185
|
"prettier": "^1.19.1",
|
|
188
|
-
"react": "^16.
|
|
189
|
-
"react-dom": "^16.
|
|
190
|
-
"rimraf": "^3.0.
|
|
191
|
-
"rollup": "^1.
|
|
186
|
+
"react": "^16.13.0",
|
|
187
|
+
"react-dom": "^16.13.0",
|
|
188
|
+
"rimraf": "^3.0.2",
|
|
189
|
+
"rollup": "^1.32.0",
|
|
192
190
|
"rollup-plugin-babel": "^4.3.3",
|
|
193
191
|
"rollup-plugin-commonjs": "^10.1.0",
|
|
194
192
|
"rollup-plugin-node-resolve": "^5.2.0",
|
|
195
|
-
"rollup-plugin-replace": "^2.
|
|
196
|
-
"rollup-plugin-typescript2": "^0.
|
|
193
|
+
"rollup-plugin-replace": "^2.2.0",
|
|
194
|
+
"rollup-plugin-typescript2": "^0.26.0",
|
|
197
195
|
"rollup-plugin-uglify": "^6.0.4",
|
|
198
|
-
"standard-version": "^7.0
|
|
199
|
-
"ts-jest": "^
|
|
200
|
-
"ts-node": "^8.
|
|
201
|
-
"tslib": "^1.
|
|
202
|
-
"typescript": "^3.
|
|
196
|
+
"standard-version": "^7.1.0",
|
|
197
|
+
"ts-jest": "^25.2.1",
|
|
198
|
+
"ts-node": "^8.6.2",
|
|
199
|
+
"tslib": "^1.11.1",
|
|
200
|
+
"typescript": "^3.8.3"
|
|
203
201
|
},
|
|
204
202
|
"scripts": {
|
|
205
203
|
"benchmark": "cross-env NODE_ENV=production TS_NODE_PROJECT=./tsconfig.cjs.json ts-node test/perf/index.tsx",
|
|
@@ -18,13 +18,13 @@ import * as shallowEquals_ from 'shallow-equal/objects';
|
|
|
18
18
|
const shallowEquals: typeof shallowEquals_ =
|
|
19
19
|
(shallowEquals_ as any).default || shallowEquals_;
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
function defaultFormatMessage<T = React.ReactNode>(
|
|
22
22
|
descriptor: MessageDescriptor,
|
|
23
23
|
values?: Record<
|
|
24
24
|
string,
|
|
25
|
-
PrimitiveType | React.ReactElement | FormatXMLElementFn
|
|
25
|
+
PrimitiveType | React.ReactElement | FormatXMLElementFn<T>
|
|
26
26
|
>
|
|
27
|
-
): string
|
|
27
|
+
): string {
|
|
28
28
|
if (process.env.NODE_ENV !== 'production') {
|
|
29
29
|
console.error(
|
|
30
30
|
'[React Intl] Could not find required `intl` object. <IntlProvider> needs to exist in the component ancestry. Using default message as fallback.'
|
|
@@ -40,7 +40,7 @@ const defaultFormatMessage = (
|
|
|
40
40
|
descriptor,
|
|
41
41
|
values as any
|
|
42
42
|
);
|
|
43
|
-
}
|
|
43
|
+
}
|
|
44
44
|
|
|
45
45
|
export interface Props<
|
|
46
46
|
V extends Record<string, any> = Record<string, React.ReactNode>
|
|
@@ -51,9 +51,10 @@ export interface Props<
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
class FormattedMessage<
|
|
54
|
+
T = React.ReactNode,
|
|
54
55
|
V extends Record<string, any> = Record<
|
|
55
56
|
string,
|
|
56
|
-
PrimitiveType | React.ReactElement | FormatXMLElementFn
|
|
57
|
+
PrimitiveType | React.ReactElement | FormatXMLElementFn<T>
|
|
57
58
|
>
|
|
58
59
|
> extends React.Component<Props<V>> {
|
|
59
60
|
static displayName = 'FormattedMessage';
|
|
@@ -7,14 +7,12 @@
|
|
|
7
7
|
import * as React from 'react';
|
|
8
8
|
import {Provider} from './injectIntl';
|
|
9
9
|
import {
|
|
10
|
-
createError,
|
|
11
10
|
DEFAULT_INTL_CONFIG,
|
|
12
11
|
createFormatters,
|
|
13
12
|
invariantIntlContext,
|
|
14
13
|
createIntlCache,
|
|
15
14
|
} from '../utils';
|
|
16
15
|
import {IntlConfig, IntlShape, Omit, IntlCache} from '../types';
|
|
17
|
-
import areIntlLocalesSupported from 'intl-locales-supported';
|
|
18
16
|
import {formatNumber, formatNumberToParts} from '../formatters/number';
|
|
19
17
|
import {formatRelativeTime} from '../formatters/relativeTime';
|
|
20
18
|
import {
|
|
@@ -24,10 +22,11 @@ import {
|
|
|
24
22
|
formatTimeToParts,
|
|
25
23
|
} from '../formatters/dateTime';
|
|
26
24
|
import {formatPlural} from '../formatters/plural';
|
|
27
|
-
import {formatMessage
|
|
25
|
+
import {formatMessage} from '../formatters/message';
|
|
28
26
|
import * as shallowEquals_ from 'shallow-equal/objects';
|
|
29
27
|
import {formatList} from '../formatters/list';
|
|
30
28
|
import {formatDisplayName} from '../formatters/displayName';
|
|
29
|
+
import {ReactIntlError, ReactIntlErrorCode} from '../error';
|
|
31
30
|
const shallowEquals: typeof shallowEquals_ =
|
|
32
31
|
(shallowEquals_ as any).default || shallowEquals_;
|
|
33
32
|
|
|
@@ -80,26 +79,39 @@ export function createIntl(
|
|
|
80
79
|
): IntlShape {
|
|
81
80
|
const formatters = createFormatters(cache);
|
|
82
81
|
const resolvedConfig = {...DEFAULT_INTL_CONFIG, ...config};
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
) {
|
|
87
|
-
const {locale, defaultLocale, onError} = resolvedConfig;
|
|
88
|
-
if (typeof onError === 'function') {
|
|
82
|
+
const {locale, defaultLocale, onError} = resolvedConfig;
|
|
83
|
+
if (!locale) {
|
|
84
|
+
if (onError) {
|
|
89
85
|
onError(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
new ReactIntlError(
|
|
87
|
+
ReactIntlErrorCode.INVALID_CONFIG,
|
|
88
|
+
`"locale" was not configured, using "${defaultLocale}" as fallback. See https://github.com/formatjs/react-intl/blob/master/docs/API.md#intlshape for more details`
|
|
93
89
|
)
|
|
94
90
|
);
|
|
95
91
|
}
|
|
96
|
-
|
|
97
92
|
// Since there's no registered locale data for `locale`, this will
|
|
98
93
|
// fallback to the `defaultLocale` to make sure things can render.
|
|
99
94
|
// The `messages` are overridden to the `defaultProps` empty object
|
|
100
95
|
// to maintain referential equality across re-renders. It's assumed
|
|
101
96
|
// each <FormattedMessage> contains a `defaultMessage` prop.
|
|
102
97
|
resolvedConfig.locale = resolvedConfig.defaultLocale || 'en';
|
|
98
|
+
} else if (!Intl.NumberFormat.supportedLocalesOf(locale).length && onError) {
|
|
99
|
+
onError(
|
|
100
|
+
new ReactIntlError(
|
|
101
|
+
ReactIntlErrorCode.MISSING_DATA,
|
|
102
|
+
`Missing locale data for locale: "${locale}" in Intl.NumberFormat. Using default locale: "${defaultLocale}" as fallback. See https://github.com/formatjs/react-intl/blob/master/docs/Getting-Started.md#runtime-requirements for more details`
|
|
103
|
+
)
|
|
104
|
+
);
|
|
105
|
+
} else if (
|
|
106
|
+
!Intl.DateTimeFormat.supportedLocalesOf(locale).length &&
|
|
107
|
+
onError
|
|
108
|
+
) {
|
|
109
|
+
onError(
|
|
110
|
+
new ReactIntlError(
|
|
111
|
+
ReactIntlErrorCode.MISSING_DATA,
|
|
112
|
+
`Missing locale data for locale: "${locale}" in Intl.DateTimeFormat. Using default locale: "${defaultLocale}" as fallback. See https://github.com/formatjs/react-intl/blob/master/docs/Getting-Started.md#runtime-requirements for more details`
|
|
113
|
+
)
|
|
114
|
+
);
|
|
103
115
|
}
|
|
104
116
|
return {
|
|
105
117
|
...resolvedConfig,
|
|
@@ -145,7 +157,6 @@ export function createIntl(
|
|
|
145
157
|
formatters.getPluralRules
|
|
146
158
|
),
|
|
147
159
|
formatMessage: formatMessage.bind(null, resolvedConfig, formatters),
|
|
148
|
-
formatHTMLMessage: formatHTMLMessage.bind(null, resolvedConfig, formatters),
|
|
149
160
|
formatList: formatList.bind(null, resolvedConfig, formatters.getListFormat),
|
|
150
161
|
formatDisplayName: formatDisplayName.bind(
|
|
151
162
|
null,
|
package/src/error.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const enum ReactIntlErrorCode {
|
|
2
|
+
FORMAT_ERROR = 'FORMAT_ERROR',
|
|
3
|
+
UNSUPPORTED_FORMATTER = 'UNSUPPORTED_FORMATTER',
|
|
4
|
+
INVALID_CONFIG = 'INVALID_CONFIG',
|
|
5
|
+
MISSING_DATA = 'MISSING_DATA',
|
|
6
|
+
MISSING_TRANSLATION = 'MISSING_TRANSLATION'
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class ReactIntlError extends Error {
|
|
10
|
+
public code: ReactIntlErrorCode
|
|
11
|
+
constructor(code: ReactIntlErrorCode, message: string, exception?: Error) {
|
|
12
|
+
super(`[React Intl Error ${code}] ${message} ${exception ? `\n${exception.stack}` : ''}`)
|
|
13
|
+
this.code = code
|
|
14
|
+
if (typeof Error.captureStackTrace === 'function') {
|
|
15
|
+
Error.captureStackTrace(this, ReactIntlError)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
import {Formatters, IntlConfig, IntlFormatters} from '../types';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import {filterProps, getNamedFormat} from '../utils';
|
|
10
|
+
import {ReactIntlError, ReactIntlErrorCode} from '../error';
|
|
10
11
|
|
|
11
12
|
const DATE_TIME_FORMAT_OPTIONS: Array<keyof Intl.DateTimeFormatOptions> = [
|
|
12
13
|
'localeMatcher',
|
|
@@ -74,7 +75,13 @@ export function formatDate(
|
|
|
74
75
|
date
|
|
75
76
|
);
|
|
76
77
|
} catch (e) {
|
|
77
|
-
config.onError(
|
|
78
|
+
config.onError(
|
|
79
|
+
new ReactIntlError(
|
|
80
|
+
ReactIntlErrorCode.FORMAT_ERROR,
|
|
81
|
+
'Error formatting date.',
|
|
82
|
+
e
|
|
83
|
+
)
|
|
84
|
+
);
|
|
78
85
|
}
|
|
79
86
|
|
|
80
87
|
return String(date);
|
|
@@ -93,7 +100,13 @@ export function formatTime(
|
|
|
93
100
|
date
|
|
94
101
|
);
|
|
95
102
|
} catch (e) {
|
|
96
|
-
config.onError(
|
|
103
|
+
config.onError(
|
|
104
|
+
new ReactIntlError(
|
|
105
|
+
ReactIntlErrorCode.FORMAT_ERROR,
|
|
106
|
+
'Error formatting time.',
|
|
107
|
+
e
|
|
108
|
+
)
|
|
109
|
+
);
|
|
97
110
|
}
|
|
98
111
|
|
|
99
112
|
return String(date);
|
|
@@ -114,7 +127,13 @@ export function formatDateToParts(
|
|
|
114
127
|
options
|
|
115
128
|
).formatToParts(date);
|
|
116
129
|
} catch (e) {
|
|
117
|
-
config.onError(
|
|
130
|
+
config.onError(
|
|
131
|
+
new ReactIntlError(
|
|
132
|
+
ReactIntlErrorCode.FORMAT_ERROR,
|
|
133
|
+
'Error formatting date.',
|
|
134
|
+
e
|
|
135
|
+
)
|
|
136
|
+
);
|
|
118
137
|
}
|
|
119
138
|
|
|
120
139
|
return [];
|
|
@@ -136,7 +155,13 @@ export function formatTimeToParts(
|
|
|
136
155
|
options
|
|
137
156
|
).formatToParts(date);
|
|
138
157
|
} catch (e) {
|
|
139
|
-
config.onError(
|
|
158
|
+
config.onError(
|
|
159
|
+
new ReactIntlError(
|
|
160
|
+
ReactIntlErrorCode.FORMAT_ERROR,
|
|
161
|
+
'Error formatting time.',
|
|
162
|
+
e
|
|
163
|
+
)
|
|
164
|
+
);
|
|
140
165
|
}
|
|
141
166
|
|
|
142
167
|
return [];
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import {IntlConfig, Formatters, IntlFormatters} from '../types';
|
|
2
|
-
import {filterProps
|
|
2
|
+
import {filterProps} from '../utils';
|
|
3
3
|
import {
|
|
4
4
|
DisplayNamesOptions,
|
|
5
5
|
DisplayNames as IntlDisplayNames,
|
|
6
6
|
} from '@formatjs/intl-displaynames';
|
|
7
|
+
import {FormatError, ErrorCode} from 'intl-messageformat';
|
|
8
|
+
import {ReactIntlErrorCode, ReactIntlError} from '../error';
|
|
7
9
|
|
|
8
10
|
const DISPLAY_NAMES_OPTONS: Array<keyof DisplayNamesOptions> = [
|
|
9
11
|
'localeMatcher',
|
|
@@ -21,15 +23,24 @@ export function formatDisplayName(
|
|
|
21
23
|
const DisplayNames: typeof IntlDisplayNames = (Intl as any).DisplayNames;
|
|
22
24
|
if (!DisplayNames) {
|
|
23
25
|
onError(
|
|
24
|
-
|
|
26
|
+
new FormatError(
|
|
27
|
+
`Intl.DisplayNames is not available in this environment.
|
|
25
28
|
Try polyfilling it using "@formatjs/intl-displaynames"
|
|
26
|
-
|
|
29
|
+
`,
|
|
30
|
+
ErrorCode.MISSING_INTL_API
|
|
31
|
+
)
|
|
27
32
|
);
|
|
28
33
|
}
|
|
29
34
|
const filteredOptions = filterProps(options, DISPLAY_NAMES_OPTONS);
|
|
30
35
|
try {
|
|
31
36
|
return getDisplayNames(locale, filteredOptions).of(value);
|
|
32
37
|
} catch (e) {
|
|
33
|
-
onError(
|
|
38
|
+
onError(
|
|
39
|
+
new ReactIntlError(
|
|
40
|
+
ReactIntlErrorCode.FORMAT_ERROR,
|
|
41
|
+
'Error formatting display name.',
|
|
42
|
+
e
|
|
43
|
+
)
|
|
44
|
+
);
|
|
34
45
|
}
|
|
35
46
|
}
|
package/src/formatters/list.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import {IntlConfig, Formatters, IntlFormatters} from '../types';
|
|
3
|
-
import {filterProps
|
|
3
|
+
import {filterProps} from '../utils';
|
|
4
4
|
import IntlListFormat, {IntlListFormatOptions} from '@formatjs/intl-listformat';
|
|
5
|
+
import {FormatError, ErrorCode} from 'intl-messageformat';
|
|
6
|
+
import {ReactIntlError, ReactIntlErrorCode} from '../error';
|
|
5
7
|
|
|
6
8
|
const LIST_FORMAT_OPTIONS: Array<keyof IntlListFormatOptions> = [
|
|
7
9
|
'localeMatcher',
|
|
@@ -30,9 +32,12 @@ export function formatList(
|
|
|
30
32
|
const ListFormat: typeof IntlListFormat = (Intl as any).ListFormat;
|
|
31
33
|
if (!ListFormat) {
|
|
32
34
|
onError(
|
|
33
|
-
|
|
35
|
+
new FormatError(
|
|
36
|
+
`Intl.ListFormat is not available in this environment.
|
|
34
37
|
Try polyfilling it using "@formatjs/intl-listformat"
|
|
35
|
-
|
|
38
|
+
`,
|
|
39
|
+
ErrorCode.MISSING_INTL_API
|
|
40
|
+
)
|
|
36
41
|
);
|
|
37
42
|
}
|
|
38
43
|
const filteredOptions = filterProps(options, LIST_FORMAT_OPTIONS);
|
|
@@ -65,7 +70,13 @@ Try polyfilling it using "@formatjs/intl-listformat"
|
|
|
65
70
|
return all;
|
|
66
71
|
}, []);
|
|
67
72
|
} catch (e) {
|
|
68
|
-
onError(
|
|
73
|
+
onError(
|
|
74
|
+
new ReactIntlError(
|
|
75
|
+
ReactIntlErrorCode.FORMAT_ERROR,
|
|
76
|
+
'Error formatting list.',
|
|
77
|
+
e
|
|
78
|
+
)
|
|
79
|
+
);
|
|
69
80
|
}
|
|
70
81
|
|
|
71
82
|
return values;
|