@formatjs/intl 4.1.4 → 4.1.6
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/index.d.ts +306 -20
- package/index.js +521 -14
- package/index.js.map +1 -0
- package/package.json +4 -13
- package/src/create-intl.d.ts +0 -14
- package/src/create-intl.js +0 -69
- package/src/dateTime.d.ts +0 -37
- package/src/dateTime.js +0 -86
- package/src/displayName.d.ts +0 -5
- package/src/displayName.js +0 -24
- package/src/error.d.ts +0 -35
- package/src/error.js +0 -68
- package/src/list.d.ts +0 -9
- package/src/list.js +0 -51
- package/src/message.d.ts +0 -15
- package/src/message.js +0 -106
- package/src/number.d.ts +0 -16
- package/src/number.js +0 -50
- package/src/plural.d.ts +0 -5
- package/src/plural.js +0 -19
- package/src/relativeTime.d.ts +0 -6
- package/src/relativeTime.js +0 -28
- package/src/types.d.ts +0 -111
- package/src/types.js +0 -3
- package/src/utils.d.ts +0 -15
- package/src/utils.js +0 -125
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formatjs/intl",
|
|
3
3
|
"description": "Internationalize JS apps. This library provides an API to format dates, numbers, and strings, including pluralization and handling translations.",
|
|
4
|
-
"version": "4.1.
|
|
4
|
+
"version": "4.1.6",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Long Ho <holevietlong@gmail.com>",
|
|
7
7
|
"type": "module",
|
|
@@ -11,13 +11,9 @@
|
|
|
11
11
|
".": "./index.js"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@formatjs/icu-messageformat-parser": "3.5.
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"@formatjs/ecma402-abstract": "3.2.0"
|
|
18
|
-
},
|
|
19
|
-
"peerDependencies": {
|
|
20
|
-
"typescript": "^5.6.0"
|
|
14
|
+
"@formatjs/icu-messageformat-parser": "3.5.4",
|
|
15
|
+
"intl-messageformat": "11.2.1",
|
|
16
|
+
"@formatjs/fast-memoize": "3.1.2"
|
|
21
17
|
},
|
|
22
18
|
"bugs": "https://github.com/formatjs/formatjs/issues",
|
|
23
19
|
"homepage": "https://formatjs.github.io",
|
|
@@ -34,10 +30,5 @@
|
|
|
34
30
|
"translate",
|
|
35
31
|
"translation"
|
|
36
32
|
],
|
|
37
|
-
"peerDependenciesMeta": {
|
|
38
|
-
"typescript": {
|
|
39
|
-
"optional": true
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
33
|
"repository": "git@github.com:formatjs/formatjs.git"
|
|
43
34
|
}
|
package/src/create-intl.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { type IntlCache, type IntlConfig, type IntlShape } from "./types.js";
|
|
2
|
-
export interface CreateIntlFn<
|
|
3
|
-
T = string,
|
|
4
|
-
C extends IntlConfig<T> = IntlConfig<T>,
|
|
5
|
-
S extends IntlShape<T> = IntlShape<T>
|
|
6
|
-
> {
|
|
7
|
-
(config: C, cache?: IntlCache): S;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Create intl object
|
|
11
|
-
* @param config intl config
|
|
12
|
-
* @param cache cache for formatter instances to prevent memory leak
|
|
13
|
-
*/
|
|
14
|
-
export declare function createIntl<T = string>(config: IntlConfig<T>, cache?: IntlCache): IntlShape<T>;
|
package/src/create-intl.js
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import "@formatjs/icu-messageformat-parser";
|
|
2
|
-
import { formatDate, formatDateTimeRange, formatDateToParts, formatTime, formatTimeToParts } from "./dateTime.js";
|
|
3
|
-
import { formatDisplayName } from "./displayName.js";
|
|
4
|
-
import { InvalidConfigError, MissingDataError } from "./error.js";
|
|
5
|
-
import { formatList, formatListToParts } from "./list.js";
|
|
6
|
-
import { formatMessage } from "./message.js";
|
|
7
|
-
import { formatNumber, formatNumberToParts } from "./number.js";
|
|
8
|
-
import { formatPlural } from "./plural.js";
|
|
9
|
-
import { formatRelativeTime } from "./relativeTime.js";
|
|
10
|
-
import "./types.js";
|
|
11
|
-
import { createFormatters, DEFAULT_INTL_CONFIG } from "./utils.js";
|
|
12
|
-
function messagesContainString(messages) {
|
|
13
|
-
const firstMessage = messages ? messages[Object.keys(messages)[0]] : undefined;
|
|
14
|
-
return typeof firstMessage === "string";
|
|
15
|
-
}
|
|
16
|
-
function verifyConfigMessages(config) {
|
|
17
|
-
if (config.onWarn && config.defaultRichTextElements && messagesContainString(config.messages || {})) {
|
|
18
|
-
config.onWarn(`[@formatjs/intl] "defaultRichTextElements" was specified but "message" was not pre-compiled.
|
|
19
|
-
Please consider using "@formatjs/cli" to pre-compile your messages for performance.
|
|
20
|
-
For more details see https://formatjs.github.io/docs/getting-started/message-distribution`);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Create intl object
|
|
25
|
-
* @param config intl config
|
|
26
|
-
* @param cache cache for formatter instances to prevent memory leak
|
|
27
|
-
*/
|
|
28
|
-
export function createIntl(config, cache) {
|
|
29
|
-
const formatters = createFormatters(cache);
|
|
30
|
-
const resolvedConfig = {
|
|
31
|
-
...DEFAULT_INTL_CONFIG,
|
|
32
|
-
...config
|
|
33
|
-
};
|
|
34
|
-
const { locale, defaultLocale, onError } = resolvedConfig;
|
|
35
|
-
if (!locale) {
|
|
36
|
-
if (onError) {
|
|
37
|
-
onError(new InvalidConfigError(`"locale" was not configured, using "${defaultLocale}" as fallback. See https://formatjs.github.io/docs/react-intl/api#intlshape for more details`));
|
|
38
|
-
}
|
|
39
|
-
// Since there's no registered locale data for `locale`, this will
|
|
40
|
-
// fallback to the `defaultLocale` to make sure things can render.
|
|
41
|
-
// The `messages` are overridden to the `defaultProps` empty object
|
|
42
|
-
// to maintain referential equality across re-renders. It's assumed
|
|
43
|
-
// each <FormattedMessage> contains a `defaultMessage` prop.
|
|
44
|
-
resolvedConfig.locale = resolvedConfig.defaultLocale || "en";
|
|
45
|
-
} else if (!Intl.NumberFormat.supportedLocalesOf(locale).length && onError) {
|
|
46
|
-
onError(new MissingDataError(`Missing locale data for locale: "${locale}" in Intl.NumberFormat. Using default locale: "${defaultLocale}" as fallback. See https://formatjs.github.io/docs/react-intl#runtime-requirements for more details`));
|
|
47
|
-
} else if (!Intl.DateTimeFormat.supportedLocalesOf(locale).length && onError) {
|
|
48
|
-
onError(new MissingDataError(`Missing locale data for locale: "${locale}" in Intl.DateTimeFormat. Using default locale: "${defaultLocale}" as fallback. See https://formatjs.github.io/docs/react-intl#runtime-requirements for more details`));
|
|
49
|
-
}
|
|
50
|
-
verifyConfigMessages(resolvedConfig);
|
|
51
|
-
return {
|
|
52
|
-
...resolvedConfig,
|
|
53
|
-
formatters,
|
|
54
|
-
formatNumber: formatNumber.bind(null, resolvedConfig, formatters.getNumberFormat),
|
|
55
|
-
formatNumberToParts: formatNumberToParts.bind(null, resolvedConfig, formatters.getNumberFormat),
|
|
56
|
-
formatRelativeTime: formatRelativeTime.bind(null, resolvedConfig, formatters.getRelativeTimeFormat),
|
|
57
|
-
formatDate: formatDate.bind(null, resolvedConfig, formatters.getDateTimeFormat),
|
|
58
|
-
formatDateToParts: formatDateToParts.bind(null, resolvedConfig, formatters.getDateTimeFormat),
|
|
59
|
-
formatTime: formatTime.bind(null, resolvedConfig, formatters.getDateTimeFormat),
|
|
60
|
-
formatDateTimeRange: formatDateTimeRange.bind(null, resolvedConfig, formatters.getDateTimeFormat),
|
|
61
|
-
formatTimeToParts: formatTimeToParts.bind(null, resolvedConfig, formatters.getDateTimeFormat),
|
|
62
|
-
formatPlural: formatPlural.bind(null, resolvedConfig, formatters.getPluralRules),
|
|
63
|
-
formatMessage: formatMessage.bind(null, resolvedConfig, formatters),
|
|
64
|
-
$t: formatMessage.bind(null, resolvedConfig, formatters),
|
|
65
|
-
formatList: formatList.bind(null, resolvedConfig, formatters.getListFormat),
|
|
66
|
-
formatListToParts: formatListToParts.bind(null, resolvedConfig, formatters.getListFormat),
|
|
67
|
-
formatDisplayName: formatDisplayName.bind(null, resolvedConfig, formatters.getDisplayNames)
|
|
68
|
-
};
|
|
69
|
-
}
|
package/src/dateTime.d.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { type CustomFormats, type Formatters, type IntlFormatters, type OnErrorFn } from "./types.js";
|
|
2
|
-
export declare function getFormatter({ locale, formats, onError, timeZone }: {
|
|
3
|
-
locale: string;
|
|
4
|
-
timeZone?: string;
|
|
5
|
-
formats: CustomFormats;
|
|
6
|
-
onError: OnErrorFn;
|
|
7
|
-
}, type: "date" | "time" | "dateTimeRange", getDateTimeFormat: Formatters["getDateTimeFormat"], options?: Parameters<IntlFormatters["formatDate"]>[1]): Intl.DateTimeFormat;
|
|
8
|
-
export declare function formatDate(config: {
|
|
9
|
-
locale: string;
|
|
10
|
-
timeZone?: string;
|
|
11
|
-
formats: CustomFormats;
|
|
12
|
-
onError: OnErrorFn;
|
|
13
|
-
}, getDateTimeFormat: Formatters["getDateTimeFormat"], value: Parameters<IntlFormatters["formatDate"]>[0], options?: Parameters<IntlFormatters["formatDate"]>[1]): string;
|
|
14
|
-
export declare function formatTime(config: {
|
|
15
|
-
locale: string;
|
|
16
|
-
timeZone?: string;
|
|
17
|
-
formats: CustomFormats;
|
|
18
|
-
onError: OnErrorFn;
|
|
19
|
-
}, getDateTimeFormat: Formatters["getDateTimeFormat"], value: Parameters<IntlFormatters["formatTime"]>[0], options?: Parameters<IntlFormatters["formatTime"]>[1]): string;
|
|
20
|
-
export declare function formatDateTimeRange(config: {
|
|
21
|
-
locale: string;
|
|
22
|
-
timeZone?: string;
|
|
23
|
-
formats: CustomFormats;
|
|
24
|
-
onError: OnErrorFn;
|
|
25
|
-
}, getDateTimeFormat: Formatters["getDateTimeFormat"], from: Parameters<IntlFormatters["formatDateTimeRange"]>[0], to: Parameters<IntlFormatters["formatDateTimeRange"]>[1], options?: Parameters<IntlFormatters["formatDateTimeRange"]>[2]): string;
|
|
26
|
-
export declare function formatDateToParts(config: {
|
|
27
|
-
locale: string;
|
|
28
|
-
timeZone?: string;
|
|
29
|
-
formats: CustomFormats;
|
|
30
|
-
onError: OnErrorFn;
|
|
31
|
-
}, getDateTimeFormat: Formatters["getDateTimeFormat"], value: Parameters<IntlFormatters["formatDate"]>[0], options?: Parameters<IntlFormatters["formatDate"]>[1]): Intl.DateTimeFormatPart[];
|
|
32
|
-
export declare function formatTimeToParts(config: {
|
|
33
|
-
locale: string;
|
|
34
|
-
timeZone?: string;
|
|
35
|
-
formats: CustomFormats;
|
|
36
|
-
onError: OnErrorFn;
|
|
37
|
-
}, getDateTimeFormat: Formatters["getDateTimeFormat"], value: Parameters<IntlFormatters["formatTimeToParts"]>[0], options?: Parameters<IntlFormatters["formatTimeToParts"]>[1]): Intl.DateTimeFormatPart[];
|
package/src/dateTime.js
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import "./types.js";
|
|
2
|
-
import { IntlFormatError } from "./error.js";
|
|
3
|
-
import { filterProps, getNamedFormat } from "./utils.js";
|
|
4
|
-
const DATE_TIME_FORMAT_OPTIONS = [
|
|
5
|
-
"formatMatcher",
|
|
6
|
-
"timeZone",
|
|
7
|
-
"hour12",
|
|
8
|
-
"weekday",
|
|
9
|
-
"era",
|
|
10
|
-
"year",
|
|
11
|
-
"month",
|
|
12
|
-
"day",
|
|
13
|
-
"hour",
|
|
14
|
-
"minute",
|
|
15
|
-
"second",
|
|
16
|
-
"timeZoneName",
|
|
17
|
-
"hourCycle",
|
|
18
|
-
"dateStyle",
|
|
19
|
-
"timeStyle",
|
|
20
|
-
"calendar",
|
|
21
|
-
"numberingSystem",
|
|
22
|
-
"fractionalSecondDigits"
|
|
23
|
-
];
|
|
24
|
-
export function getFormatter({ locale, formats, onError, timeZone }, type, getDateTimeFormat, options = {}) {
|
|
25
|
-
const { format } = options;
|
|
26
|
-
const defaults = {
|
|
27
|
-
...timeZone && { timeZone },
|
|
28
|
-
...format && getNamedFormat(formats, type, format, onError)
|
|
29
|
-
};
|
|
30
|
-
let filteredOptions = filterProps(options, DATE_TIME_FORMAT_OPTIONS, defaults);
|
|
31
|
-
if (type === "time" && !filteredOptions.hour && !filteredOptions.minute && !filteredOptions.second && !filteredOptions.timeStyle && !filteredOptions.dateStyle) {
|
|
32
|
-
// Add default formatting options if hour, minute, or second isn't defined.
|
|
33
|
-
filteredOptions = {
|
|
34
|
-
...filteredOptions,
|
|
35
|
-
hour: "numeric",
|
|
36
|
-
minute: "numeric"
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
return getDateTimeFormat(locale, filteredOptions);
|
|
40
|
-
}
|
|
41
|
-
export function formatDate(config, getDateTimeFormat, value, options = {}) {
|
|
42
|
-
const date = typeof value === "string" ? new Date(value || 0) : value;
|
|
43
|
-
try {
|
|
44
|
-
return getFormatter(config, "date", getDateTimeFormat, options).format(date);
|
|
45
|
-
} catch (e) {
|
|
46
|
-
config.onError(new IntlFormatError("Error formatting date.", config.locale, e));
|
|
47
|
-
}
|
|
48
|
-
return String(date);
|
|
49
|
-
}
|
|
50
|
-
export function formatTime(config, getDateTimeFormat, value, options = {}) {
|
|
51
|
-
const date = typeof value === "string" ? new Date(value || 0) : value;
|
|
52
|
-
try {
|
|
53
|
-
return getFormatter(config, "time", getDateTimeFormat, options).format(date);
|
|
54
|
-
} catch (e) {
|
|
55
|
-
config.onError(new IntlFormatError("Error formatting time.", config.locale, e));
|
|
56
|
-
}
|
|
57
|
-
return String(date);
|
|
58
|
-
}
|
|
59
|
-
export function formatDateTimeRange(config, getDateTimeFormat, from, to, options = {}) {
|
|
60
|
-
const fromDate = typeof from === "string" ? new Date(from || 0) : from;
|
|
61
|
-
const toDate = typeof to === "string" ? new Date(to || 0) : to;
|
|
62
|
-
try {
|
|
63
|
-
return getFormatter(config, "dateTimeRange", getDateTimeFormat, options).formatRange(fromDate, toDate);
|
|
64
|
-
} catch (e) {
|
|
65
|
-
config.onError(new IntlFormatError("Error formatting date time range.", config.locale, e));
|
|
66
|
-
}
|
|
67
|
-
return String(fromDate);
|
|
68
|
-
}
|
|
69
|
-
export function formatDateToParts(config, getDateTimeFormat, value, options = {}) {
|
|
70
|
-
const date = typeof value === "string" ? new Date(value || 0) : value;
|
|
71
|
-
try {
|
|
72
|
-
return getFormatter(config, "date", getDateTimeFormat, options).formatToParts(date);
|
|
73
|
-
} catch (e) {
|
|
74
|
-
config.onError(new IntlFormatError("Error formatting date.", config.locale, e));
|
|
75
|
-
}
|
|
76
|
-
return [];
|
|
77
|
-
}
|
|
78
|
-
export function formatTimeToParts(config, getDateTimeFormat, value, options = {}) {
|
|
79
|
-
const date = typeof value === "string" ? new Date(value || 0) : value;
|
|
80
|
-
try {
|
|
81
|
-
return getFormatter(config, "time", getDateTimeFormat, options).formatToParts(date);
|
|
82
|
-
} catch (e) {
|
|
83
|
-
config.onError(new IntlFormatError("Error formatting time.", config.locale, e));
|
|
84
|
-
}
|
|
85
|
-
return [];
|
|
86
|
-
}
|
package/src/displayName.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { type Formatters, type IntlFormatters, type OnErrorFn } from "./types.js";
|
|
2
|
-
export declare function formatDisplayName({ locale, onError }: {
|
|
3
|
-
locale: string;
|
|
4
|
-
onError: OnErrorFn;
|
|
5
|
-
}, getDisplayNames: Formatters["getDisplayNames"], value: Parameters<IntlFormatters["formatDisplayName"]>[0], options: Parameters<IntlFormatters["formatDisplayName"]>[1]): string | undefined;
|
package/src/displayName.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import "./types.js";
|
|
2
|
-
import { filterProps } from "./utils.js";
|
|
3
|
-
import { ErrorCode, FormatError } from "intl-messageformat";
|
|
4
|
-
import { IntlFormatError } from "./error.js";
|
|
5
|
-
const DISPLAY_NAMES_OPTONS = [
|
|
6
|
-
"style",
|
|
7
|
-
"type",
|
|
8
|
-
"fallback",
|
|
9
|
-
"languageDisplay"
|
|
10
|
-
];
|
|
11
|
-
export function formatDisplayName({ locale, onError }, getDisplayNames, value, options) {
|
|
12
|
-
const DisplayNames = Intl.DisplayNames;
|
|
13
|
-
if (!DisplayNames) {
|
|
14
|
-
onError(new FormatError(`Intl.DisplayNames is not available in this environment.
|
|
15
|
-
Try polyfilling it using "@formatjs/intl-displaynames"
|
|
16
|
-
`, ErrorCode.MISSING_INTL_API));
|
|
17
|
-
}
|
|
18
|
-
const filteredOptions = filterProps(options, DISPLAY_NAMES_OPTONS);
|
|
19
|
-
try {
|
|
20
|
-
return getDisplayNames(locale, filteredOptions).of(value);
|
|
21
|
-
} catch (e) {
|
|
22
|
-
onError(new IntlFormatError("Error formatting display name.", locale, e));
|
|
23
|
-
}
|
|
24
|
-
}
|
package/src/error.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { type MessageDescriptor } from "./types.js";
|
|
2
|
-
export declare enum IntlErrorCode {
|
|
3
|
-
FORMAT_ERROR = "FORMAT_ERROR",
|
|
4
|
-
UNSUPPORTED_FORMATTER = "UNSUPPORTED_FORMATTER",
|
|
5
|
-
INVALID_CONFIG = "INVALID_CONFIG",
|
|
6
|
-
MISSING_DATA = "MISSING_DATA",
|
|
7
|
-
MISSING_TRANSLATION = "MISSING_TRANSLATION"
|
|
8
|
-
}
|
|
9
|
-
export declare class IntlError<T extends IntlErrorCode = IntlErrorCode.FORMAT_ERROR> extends Error {
|
|
10
|
-
readonly code: T;
|
|
11
|
-
constructor(code: T, message: string, exception?: Error | unknown);
|
|
12
|
-
}
|
|
13
|
-
export declare class UnsupportedFormatterError extends IntlError<IntlErrorCode.UNSUPPORTED_FORMATTER> {
|
|
14
|
-
constructor(message: string, exception?: Error | unknown);
|
|
15
|
-
}
|
|
16
|
-
export declare class InvalidConfigError extends IntlError<IntlErrorCode.INVALID_CONFIG> {
|
|
17
|
-
constructor(message: string, exception?: Error | unknown);
|
|
18
|
-
}
|
|
19
|
-
export declare class MissingDataError extends IntlError<IntlErrorCode.MISSING_DATA> {
|
|
20
|
-
constructor(message: string, exception?: Error | unknown);
|
|
21
|
-
}
|
|
22
|
-
export declare class IntlFormatError extends IntlError<IntlErrorCode.FORMAT_ERROR> {
|
|
23
|
-
readonly descriptor?: MessageDescriptor;
|
|
24
|
-
readonly locale: string;
|
|
25
|
-
constructor(message: string, locale: string, exception?: Error | unknown);
|
|
26
|
-
}
|
|
27
|
-
export declare class MessageFormatError extends IntlFormatError {
|
|
28
|
-
readonly descriptor?: MessageDescriptor;
|
|
29
|
-
readonly locale: string;
|
|
30
|
-
constructor(message: string, locale: string, descriptor?: MessageDescriptor, exception?: Error | unknown);
|
|
31
|
-
}
|
|
32
|
-
export declare class MissingTranslationError extends IntlError<IntlErrorCode.MISSING_TRANSLATION> {
|
|
33
|
-
readonly descriptor?: MessageDescriptor;
|
|
34
|
-
constructor(descriptor: MessageDescriptor, locale: string);
|
|
35
|
-
}
|
package/src/error.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import "./types.js";
|
|
2
|
-
export let IntlErrorCode = /* @__PURE__ */ function(IntlErrorCode) {
|
|
3
|
-
IntlErrorCode["FORMAT_ERROR"] = "FORMAT_ERROR";
|
|
4
|
-
IntlErrorCode["UNSUPPORTED_FORMATTER"] = "UNSUPPORTED_FORMATTER";
|
|
5
|
-
IntlErrorCode["INVALID_CONFIG"] = "INVALID_CONFIG";
|
|
6
|
-
IntlErrorCode["MISSING_DATA"] = "MISSING_DATA";
|
|
7
|
-
IntlErrorCode["MISSING_TRANSLATION"] = "MISSING_TRANSLATION";
|
|
8
|
-
return IntlErrorCode;
|
|
9
|
-
}({});
|
|
10
|
-
export class IntlError extends Error {
|
|
11
|
-
code;
|
|
12
|
-
constructor(code, message, exception) {
|
|
13
|
-
const err = exception ? exception instanceof Error ? exception : new Error(String(exception)) : undefined;
|
|
14
|
-
super(`[@formatjs/intl Error ${code}] ${message}
|
|
15
|
-
${err ? `\n${err.message}\n${err.stack}` : ""}`);
|
|
16
|
-
this.code = code;
|
|
17
|
-
// @ts-ignore just so we don't need to declare dep on @types/node
|
|
18
|
-
if (typeof Error.captureStackTrace === "function") {
|
|
19
|
-
// @ts-ignore just so we don't need to declare dep on @types/node
|
|
20
|
-
Error.captureStackTrace(this, IntlError);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
export class UnsupportedFormatterError extends IntlError {
|
|
25
|
-
constructor(message, exception) {
|
|
26
|
-
super(IntlErrorCode.UNSUPPORTED_FORMATTER, message, exception);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
export class InvalidConfigError extends IntlError {
|
|
30
|
-
constructor(message, exception) {
|
|
31
|
-
super(IntlErrorCode.INVALID_CONFIG, message, exception);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
export class MissingDataError extends IntlError {
|
|
35
|
-
constructor(message, exception) {
|
|
36
|
-
super(IntlErrorCode.MISSING_DATA, message, exception);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
export class IntlFormatError extends IntlError {
|
|
40
|
-
descriptor;
|
|
41
|
-
locale;
|
|
42
|
-
constructor(message, locale, exception) {
|
|
43
|
-
super(IntlErrorCode.FORMAT_ERROR, `${message}
|
|
44
|
-
Locale: ${locale}
|
|
45
|
-
`, exception);
|
|
46
|
-
this.locale = locale;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
export class MessageFormatError extends IntlFormatError {
|
|
50
|
-
descriptor;
|
|
51
|
-
locale;
|
|
52
|
-
constructor(message, locale, descriptor, exception) {
|
|
53
|
-
super(`${message}
|
|
54
|
-
MessageID: ${descriptor?.id}
|
|
55
|
-
Default Message: ${descriptor?.defaultMessage}
|
|
56
|
-
Description: ${descriptor?.description}
|
|
57
|
-
`, locale, exception);
|
|
58
|
-
this.descriptor = descriptor;
|
|
59
|
-
this.locale = locale;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
export class MissingTranslationError extends IntlError {
|
|
63
|
-
descriptor;
|
|
64
|
-
constructor(descriptor, locale) {
|
|
65
|
-
super(IntlErrorCode.MISSING_TRANSLATION, `Missing message: "${descriptor.id}" for locale "${locale}", using ${descriptor.defaultMessage ? `default message (${typeof descriptor.defaultMessage === "string" ? descriptor.defaultMessage : descriptor.defaultMessage.map((e) => e.value ?? JSON.stringify(e)).join()})` : "id"} as fallback.`);
|
|
66
|
-
this.descriptor = descriptor;
|
|
67
|
-
}
|
|
68
|
-
}
|
package/src/list.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type Formatters, type IntlFormatters, type OnErrorFn, type Part } from "./types.js";
|
|
2
|
-
export declare function formatList(opts: {
|
|
3
|
-
locale: string;
|
|
4
|
-
onError: OnErrorFn;
|
|
5
|
-
}, getListFormat: Formatters["getListFormat"], values: Iterable<string>, options: Parameters<IntlFormatters["formatList"]>[1]): string;
|
|
6
|
-
export declare function formatListToParts<T>(opts: {
|
|
7
|
-
locale: string;
|
|
8
|
-
onError: OnErrorFn;
|
|
9
|
-
}, getListFormat: Formatters["getListFormat"], values: Iterable<string | T>, options: Parameters<IntlFormatters["formatList"]>[1]): Part[];
|
package/src/list.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { ErrorCode, FormatError } from "intl-messageformat";
|
|
2
|
-
import { IntlFormatError } from "./error.js";
|
|
3
|
-
import "./types.js";
|
|
4
|
-
import { filterProps } from "./utils.js";
|
|
5
|
-
const LIST_FORMAT_OPTIONS = ["type", "style"];
|
|
6
|
-
const now = Date.now();
|
|
7
|
-
function generateToken(i) {
|
|
8
|
-
return `${now}_${i}_${now}`;
|
|
9
|
-
}
|
|
10
|
-
export function formatList(opts, getListFormat, values, options = {}) {
|
|
11
|
-
const results = formatListToParts(opts, getListFormat, values, options).reduce((all, el) => {
|
|
12
|
-
const val = el.value;
|
|
13
|
-
if (typeof val !== "string") {
|
|
14
|
-
all.push(val);
|
|
15
|
-
} else if (typeof all[all.length - 1] === "string") {
|
|
16
|
-
all[all.length - 1] += val;
|
|
17
|
-
} else {
|
|
18
|
-
all.push(val);
|
|
19
|
-
}
|
|
20
|
-
return all;
|
|
21
|
-
}, []);
|
|
22
|
-
return results.length === 1 ? results[0] : results.length === 0 ? "" : results;
|
|
23
|
-
}
|
|
24
|
-
export function formatListToParts({ locale, onError }, getListFormat, values, options = {}) {
|
|
25
|
-
const ListFormat = Intl.ListFormat;
|
|
26
|
-
if (!ListFormat) {
|
|
27
|
-
onError(new FormatError(`Intl.ListFormat is not available in this environment.
|
|
28
|
-
Try polyfilling it using "@formatjs/intl-listformat"
|
|
29
|
-
`, ErrorCode.MISSING_INTL_API));
|
|
30
|
-
}
|
|
31
|
-
const filteredOptions = filterProps(options, LIST_FORMAT_OPTIONS);
|
|
32
|
-
try {
|
|
33
|
-
const richValues = {};
|
|
34
|
-
const serializedValues = Array.from(values).map((v, i) => {
|
|
35
|
-
if (typeof v === "object" && v !== null) {
|
|
36
|
-
const id = generateToken(i);
|
|
37
|
-
richValues[id] = v;
|
|
38
|
-
return id;
|
|
39
|
-
}
|
|
40
|
-
return String(v);
|
|
41
|
-
});
|
|
42
|
-
return getListFormat(locale, filteredOptions).formatToParts(serializedValues).map((part) => part.type === "literal" ? part : {
|
|
43
|
-
...part,
|
|
44
|
-
value: richValues[part.value] || part.value
|
|
45
|
-
});
|
|
46
|
-
} catch (e) {
|
|
47
|
-
onError(new IntlFormatError("Error formatting list.", locale, e));
|
|
48
|
-
}
|
|
49
|
-
// @ts-ignore
|
|
50
|
-
return values;
|
|
51
|
-
}
|
package/src/message.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { type CustomFormats, type Formatters, type MessageDescriptor, type OnErrorFn } from "./types.js";
|
|
2
|
-
import { type MessageFormatElement } from "@formatjs/icu-messageformat-parser";
|
|
3
|
-
import { type FormatXMLElementFn, type Formatters as IntlMessageFormatFormatters, type Options, type PrimitiveType } from "intl-messageformat";
|
|
4
|
-
export type FormatMessageFn<T> = ({ locale, formats, messages, defaultLocale, defaultFormats, fallbackOnEmptyString, onError, timeZone, defaultRichTextElements }: {
|
|
5
|
-
locale: string;
|
|
6
|
-
timeZone?: string;
|
|
7
|
-
formats: CustomFormats;
|
|
8
|
-
messages: Record<string, string> | Record<string, MessageFormatElement[]>;
|
|
9
|
-
defaultLocale: string;
|
|
10
|
-
defaultFormats: CustomFormats;
|
|
11
|
-
defaultRichTextElements?: Record<string, FormatXMLElementFn<T>>;
|
|
12
|
-
fallbackOnEmptyString?: boolean;
|
|
13
|
-
onError: OnErrorFn;
|
|
14
|
-
}, state: IntlMessageFormatFormatters & Pick<Formatters, "getMessageFormat">, messageDescriptor: MessageDescriptor, values?: Record<string, PrimitiveType | T | FormatXMLElementFn<T>>, opts?: Options) => T extends string ? string : Array<T | string> | string | T;
|
|
15
|
-
export declare const formatMessage: FormatMessageFn<any>;
|
package/src/message.js
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import "./types.js";
|
|
2
|
-
import { TYPE } from "@formatjs/icu-messageformat-parser";
|
|
3
|
-
import { IntlMessageFormat } from "intl-messageformat";
|
|
4
|
-
import { MessageFormatError, MissingTranslationError } from "./error.js";
|
|
5
|
-
import { invariant } from "./utils.js";
|
|
6
|
-
function setTimeZoneInOptions(opts, timeZone) {
|
|
7
|
-
return Object.keys(opts).reduce((all, k) => {
|
|
8
|
-
all[k] = {
|
|
9
|
-
timeZone,
|
|
10
|
-
...opts[k]
|
|
11
|
-
};
|
|
12
|
-
return all;
|
|
13
|
-
}, {});
|
|
14
|
-
}
|
|
15
|
-
function deepMergeOptions(opts1, opts2) {
|
|
16
|
-
const keys = Object.keys({
|
|
17
|
-
...opts1,
|
|
18
|
-
...opts2
|
|
19
|
-
});
|
|
20
|
-
return keys.reduce((all, k) => {
|
|
21
|
-
all[k] = {
|
|
22
|
-
...opts1[k],
|
|
23
|
-
...opts2[k]
|
|
24
|
-
};
|
|
25
|
-
return all;
|
|
26
|
-
}, {});
|
|
27
|
-
}
|
|
28
|
-
function deepMergeFormatsAndSetTimeZone(f1, timeZone) {
|
|
29
|
-
if (!timeZone) {
|
|
30
|
-
return f1;
|
|
31
|
-
}
|
|
32
|
-
const mfFormats = IntlMessageFormat.formats;
|
|
33
|
-
return {
|
|
34
|
-
...mfFormats,
|
|
35
|
-
...f1,
|
|
36
|
-
date: deepMergeOptions(setTimeZoneInOptions(mfFormats.date, timeZone), setTimeZoneInOptions(f1.date || {}, timeZone)),
|
|
37
|
-
time: deepMergeOptions(setTimeZoneInOptions(mfFormats.time, timeZone), setTimeZoneInOptions(f1.time || {}, timeZone))
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
export const formatMessage = ({ locale, formats, messages, defaultLocale, defaultFormats, fallbackOnEmptyString, onError, timeZone, defaultRichTextElements }, state, messageDescriptor = { id: "" }, values, opts) => {
|
|
41
|
-
const { id: msgId, defaultMessage } = messageDescriptor;
|
|
42
|
-
// `id` is a required field of a Message Descriptor.
|
|
43
|
-
invariant(!!msgId, `[@formatjs/intl] An \`id\` must be provided to format a message. You can either:
|
|
44
|
-
1. Configure your build toolchain with [babel-plugin-formatjs](https://formatjs.github.io/docs/tooling/babel-plugin)
|
|
45
|
-
or [@formatjs/ts-transformer](https://formatjs.github.io/docs/tooling/ts-transformer) OR
|
|
46
|
-
2. Configure your \`eslint\` config to include [eslint-plugin-formatjs](https://formatjs.github.io/docs/tooling/linter#enforce-id)
|
|
47
|
-
to autofix this issue`);
|
|
48
|
-
const id = String(msgId);
|
|
49
|
-
const message = messages && Object.prototype.hasOwnProperty.call(messages, id) && messages[id];
|
|
50
|
-
// IMPORTANT: Hot path if `message` is AST with a single literal node
|
|
51
|
-
if (Array.isArray(message) && message.length === 1 && message[0].type === TYPE.literal) {
|
|
52
|
-
return message[0].value;
|
|
53
|
-
}
|
|
54
|
-
values = {
|
|
55
|
-
...defaultRichTextElements,
|
|
56
|
-
...values
|
|
57
|
-
};
|
|
58
|
-
formats = deepMergeFormatsAndSetTimeZone(formats, timeZone);
|
|
59
|
-
defaultFormats = deepMergeFormatsAndSetTimeZone(defaultFormats, timeZone);
|
|
60
|
-
if (!message) {
|
|
61
|
-
if (fallbackOnEmptyString === false && message === "") {
|
|
62
|
-
return message;
|
|
63
|
-
}
|
|
64
|
-
if (!defaultMessage || locale && locale.toLowerCase() !== defaultLocale.toLowerCase()) {
|
|
65
|
-
// This prevents warnings from littering the console in development
|
|
66
|
-
// when no `messages` are passed into the <IntlProvider> for the
|
|
67
|
-
// default locale.
|
|
68
|
-
onError(new MissingTranslationError(messageDescriptor, locale));
|
|
69
|
-
}
|
|
70
|
-
if (defaultMessage) {
|
|
71
|
-
try {
|
|
72
|
-
const formatter = state.getMessageFormat(defaultMessage, defaultLocale, defaultFormats, opts);
|
|
73
|
-
return formatter.format(values);
|
|
74
|
-
} catch (e) {
|
|
75
|
-
onError(new MessageFormatError(`Error formatting default message for: "${id}", rendering default message verbatim`, locale, messageDescriptor, e));
|
|
76
|
-
return typeof defaultMessage === "string" ? defaultMessage : id;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return id;
|
|
80
|
-
}
|
|
81
|
-
// We have the translated message
|
|
82
|
-
try {
|
|
83
|
-
const formatter = state.getMessageFormat(message, locale, formats, {
|
|
84
|
-
formatters: state,
|
|
85
|
-
...opts
|
|
86
|
-
});
|
|
87
|
-
return formatter.format(values);
|
|
88
|
-
} catch (e) {
|
|
89
|
-
onError(new MessageFormatError(`Error formatting message: "${id}", using ${defaultMessage ? "default message" : "id"} as fallback.`, locale, messageDescriptor, e));
|
|
90
|
-
}
|
|
91
|
-
if (defaultMessage) {
|
|
92
|
-
try {
|
|
93
|
-
const formatter = state.getMessageFormat(defaultMessage, defaultLocale, defaultFormats, opts);
|
|
94
|
-
return formatter.format(values);
|
|
95
|
-
} catch (e) {
|
|
96
|
-
onError(new MessageFormatError(`Error formatting the default message for: "${id}", rendering message verbatim`, locale, messageDescriptor, e));
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
if (typeof message === "string") {
|
|
100
|
-
return message;
|
|
101
|
-
}
|
|
102
|
-
if (typeof defaultMessage === "string") {
|
|
103
|
-
return defaultMessage;
|
|
104
|
-
}
|
|
105
|
-
return id;
|
|
106
|
-
};
|
package/src/number.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { type CustomFormats, type Formatters, type IntlFormatters, type OnErrorFn } from "./types.js";
|
|
2
|
-
export declare function getFormatter({ locale, formats, onError }: {
|
|
3
|
-
locale: string;
|
|
4
|
-
formats: CustomFormats;
|
|
5
|
-
onError: OnErrorFn;
|
|
6
|
-
}, getNumberFormat: Formatters["getNumberFormat"], options?: Parameters<IntlFormatters["formatNumber"]>[1]): Intl.NumberFormat;
|
|
7
|
-
export declare function formatNumber(config: {
|
|
8
|
-
locale: string;
|
|
9
|
-
formats: CustomFormats;
|
|
10
|
-
onError: OnErrorFn;
|
|
11
|
-
}, getNumberFormat: Formatters["getNumberFormat"], value: Parameters<IntlFormatters["formatNumber"]>[0], options?: Parameters<IntlFormatters["formatNumber"]>[1]): string;
|
|
12
|
-
export declare function formatNumberToParts(config: {
|
|
13
|
-
locale: string;
|
|
14
|
-
formats: CustomFormats;
|
|
15
|
-
onError: OnErrorFn;
|
|
16
|
-
}, getNumberFormat: Formatters["getNumberFormat"], value: Parameters<IntlFormatters["formatNumber"]>[0], options?: Parameters<IntlFormatters["formatNumber"]>[1]): Intl.NumberFormatPart[];
|
package/src/number.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import "@formatjs/ecma402-abstract";
|
|
2
|
-
import { IntlFormatError } from "./error.js";
|
|
3
|
-
import "./types.js";
|
|
4
|
-
import { filterProps, getNamedFormat } from "./utils.js";
|
|
5
|
-
const NUMBER_FORMAT_OPTIONS = [
|
|
6
|
-
"style",
|
|
7
|
-
"currency",
|
|
8
|
-
"unit",
|
|
9
|
-
"unitDisplay",
|
|
10
|
-
"useGrouping",
|
|
11
|
-
"minimumIntegerDigits",
|
|
12
|
-
"minimumFractionDigits",
|
|
13
|
-
"maximumFractionDigits",
|
|
14
|
-
"minimumSignificantDigits",
|
|
15
|
-
"maximumSignificantDigits",
|
|
16
|
-
"compactDisplay",
|
|
17
|
-
"currencyDisplay",
|
|
18
|
-
"currencySign",
|
|
19
|
-
"notation",
|
|
20
|
-
"signDisplay",
|
|
21
|
-
"unit",
|
|
22
|
-
"unitDisplay",
|
|
23
|
-
"numberingSystem",
|
|
24
|
-
"trailingZeroDisplay",
|
|
25
|
-
"roundingPriority",
|
|
26
|
-
"roundingIncrement",
|
|
27
|
-
"roundingMode"
|
|
28
|
-
];
|
|
29
|
-
export function getFormatter({ locale, formats, onError }, getNumberFormat, options = {}) {
|
|
30
|
-
const { format } = options;
|
|
31
|
-
const defaults = format && getNamedFormat(formats, "number", format, onError) || {};
|
|
32
|
-
const filteredOptions = filterProps(options, NUMBER_FORMAT_OPTIONS, defaults);
|
|
33
|
-
return getNumberFormat(locale, filteredOptions);
|
|
34
|
-
}
|
|
35
|
-
export function formatNumber(config, getNumberFormat, value, options = {}) {
|
|
36
|
-
try {
|
|
37
|
-
return getFormatter(config, getNumberFormat, options).format(value);
|
|
38
|
-
} catch (e) {
|
|
39
|
-
config.onError(new IntlFormatError("Error formatting number.", config.locale, e));
|
|
40
|
-
}
|
|
41
|
-
return String(value);
|
|
42
|
-
}
|
|
43
|
-
export function formatNumberToParts(config, getNumberFormat, value, options = {}) {
|
|
44
|
-
try {
|
|
45
|
-
return getFormatter(config, getNumberFormat, options).formatToParts(value);
|
|
46
|
-
} catch (e) {
|
|
47
|
-
config.onError(new IntlFormatError("Error formatting number.", config.locale, e));
|
|
48
|
-
}
|
|
49
|
-
return [];
|
|
50
|
-
}
|
package/src/plural.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { type Formatters, type IntlFormatters, type OnErrorFn } from "./types.js";
|
|
2
|
-
export declare function formatPlural({ locale, onError }: {
|
|
3
|
-
locale: string;
|
|
4
|
-
onError: OnErrorFn;
|
|
5
|
-
}, getPluralRules: Formatters["getPluralRules"], value: Parameters<IntlFormatters["formatPlural"]>[0], options?: Parameters<IntlFormatters["formatPlural"]>[1]): Intl.LDMLPluralRule;
|
package/src/plural.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { ErrorCode, FormatError } from "intl-messageformat";
|
|
2
|
-
import { IntlFormatError } from "./error.js";
|
|
3
|
-
import "./types.js";
|
|
4
|
-
import { filterProps } from "./utils.js";
|
|
5
|
-
const PLURAL_FORMAT_OPTIONS = ["type"];
|
|
6
|
-
export function formatPlural({ locale, onError }, getPluralRules, value, options = {}) {
|
|
7
|
-
if (!Intl.PluralRules) {
|
|
8
|
-
onError(new FormatError(`Intl.PluralRules is not available in this environment.
|
|
9
|
-
Try polyfilling it using "@formatjs/intl-pluralrules"
|
|
10
|
-
`, ErrorCode.MISSING_INTL_API));
|
|
11
|
-
}
|
|
12
|
-
const filteredOptions = filterProps(options, PLURAL_FORMAT_OPTIONS);
|
|
13
|
-
try {
|
|
14
|
-
return getPluralRules(locale, filteredOptions).select(value);
|
|
15
|
-
} catch (e) {
|
|
16
|
-
onError(new IntlFormatError("Error formatting plural.", locale, e));
|
|
17
|
-
}
|
|
18
|
-
return "other";
|
|
19
|
-
}
|