@formatjs/intl 4.0.7 → 4.0.9
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 +19 -15
- package/index.js +14 -13
- package/package.json +5 -5
- package/src/create-intl.d.ts +11 -7
- package/src/create-intl.js +62 -44
- package/src/dateTime.d.ts +32 -32
- package/src/dateTime.js +79 -110
- package/src/displayName.d.ts +5 -5
- package/src/displayName.js +22 -21
- package/src/error.d.ts +19 -19
- package/src/error.js +68 -91
- package/src/list.d.ts +7 -7
- package/src/list.js +47 -57
- package/src/message.d.ts +14 -14
- package/src/message.js +103 -96
- package/src/number.d.ts +14 -14
- package/src/number.js +46 -54
- package/src/plural.d.ts +5 -5
- package/src/plural.js +18 -18
- package/src/relativeTime.d.ts +5 -5
- package/src/relativeTime.js +26 -27
- package/src/types.d.ts +84 -80
- package/src/types.js +3 -1
- package/src/utils.d.ts +10 -7
- package/src/utils.js +112 -155
package/src/error.d.ts
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import { MessageDescriptor } from
|
|
1
|
+
import { type MessageDescriptor } from "./types.js";
|
|
2
2
|
export declare enum IntlErrorCode {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
8
|
}
|
|
9
9
|
export declare class IntlError<T extends IntlErrorCode = IntlErrorCode.FORMAT_ERROR> extends Error {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
readonly code: T;
|
|
11
|
+
constructor(code: T, message: string, exception?: Error | unknown);
|
|
12
12
|
}
|
|
13
13
|
export declare class UnsupportedFormatterError extends IntlError<IntlErrorCode.UNSUPPORTED_FORMATTER> {
|
|
14
|
-
|
|
14
|
+
constructor(message: string, exception?: Error | unknown);
|
|
15
15
|
}
|
|
16
16
|
export declare class InvalidConfigError extends IntlError<IntlErrorCode.INVALID_CONFIG> {
|
|
17
|
-
|
|
17
|
+
constructor(message: string, exception?: Error | unknown);
|
|
18
18
|
}
|
|
19
19
|
export declare class MissingDataError extends IntlError<IntlErrorCode.MISSING_DATA> {
|
|
20
|
-
|
|
20
|
+
constructor(message: string, exception?: Error | unknown);
|
|
21
21
|
}
|
|
22
22
|
export declare class IntlFormatError extends IntlError<IntlErrorCode.FORMAT_ERROR> {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
readonly descriptor?: MessageDescriptor;
|
|
24
|
+
readonly locale: string;
|
|
25
|
+
constructor(message: string, locale: string, exception?: Error | unknown);
|
|
26
26
|
}
|
|
27
27
|
export declare class MessageFormatError extends IntlFormatError {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
readonly descriptor?: MessageDescriptor;
|
|
29
|
+
readonly locale: string;
|
|
30
|
+
constructor(message: string, locale: string, descriptor?: MessageDescriptor, exception?: Error | unknown);
|
|
31
31
|
}
|
|
32
32
|
export declare class MissingTranslationError extends IntlError<IntlErrorCode.MISSING_TRANSLATION> {
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
readonly descriptor?: MessageDescriptor;
|
|
34
|
+
constructor(descriptor: MessageDescriptor, locale: string);
|
|
35
35
|
}
|
package/src/error.js
CHANGED
|
@@ -1,91 +1,68 @@
|
|
|
1
|
-
import
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
_this.descriptor = descriptor;
|
|
70
|
-
_this.locale = locale;
|
|
71
|
-
return _this;
|
|
72
|
-
}
|
|
73
|
-
return MessageFormatError;
|
|
74
|
-
}(IntlFormatError));
|
|
75
|
-
export { MessageFormatError };
|
|
76
|
-
var MissingTranslationError = /** @class */ (function (_super) {
|
|
77
|
-
__extends(MissingTranslationError, _super);
|
|
78
|
-
function MissingTranslationError(descriptor, locale) {
|
|
79
|
-
var _this = _super.call(this, IntlErrorCode.MISSING_TRANSLATION, "Missing message: \"".concat(descriptor.id, "\" for locale \"").concat(locale, "\", using ").concat(descriptor.defaultMessage
|
|
80
|
-
? "default message (".concat(typeof descriptor.defaultMessage === 'string'
|
|
81
|
-
? descriptor.defaultMessage
|
|
82
|
-
: descriptor.defaultMessage
|
|
83
|
-
.map(function (e) { var _a; return (_a = e.value) !== null && _a !== void 0 ? _a : JSON.stringify(e); })
|
|
84
|
-
.join(), ")")
|
|
85
|
-
: 'id', " as fallback.")) || this;
|
|
86
|
-
_this.descriptor = descriptor;
|
|
87
|
-
return _this;
|
|
88
|
-
}
|
|
89
|
-
return MissingTranslationError;
|
|
90
|
-
}(IntlError));
|
|
91
|
-
export { MissingTranslationError };
|
|
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
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Formatters, IntlFormatters, OnErrorFn, Part } from
|
|
1
|
+
import { type Formatters, type IntlFormatters, type OnErrorFn, type Part } from "./types.js";
|
|
2
2
|
export declare function formatList(opts: {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}, getListFormat: Formatters[
|
|
3
|
+
locale: string;
|
|
4
|
+
onError: OnErrorFn;
|
|
5
|
+
}, getListFormat: Formatters["getListFormat"], values: Iterable<string>, options: Parameters<IntlFormatters["formatList"]>[1]): string;
|
|
6
6
|
export declare function formatListToParts<T>(opts: {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}, getListFormat: Formatters[
|
|
7
|
+
locale: string;
|
|
8
|
+
onError: OnErrorFn;
|
|
9
|
+
}, getListFormat: Formatters["getListFormat"], values: Iterable<string | T>, options: Parameters<IntlFormatters["formatList"]>[1]): Part[];
|
package/src/list.js
CHANGED
|
@@ -1,61 +1,51 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import { filterProps } from
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
'style',
|
|
8
|
-
];
|
|
9
|
-
var now = Date.now();
|
|
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();
|
|
10
7
|
function generateToken(i) {
|
|
11
|
-
|
|
8
|
+
return `${now}_${i}_${now}`;
|
|
12
9
|
}
|
|
13
|
-
export function formatList(opts, getListFormat, values, options) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return all;
|
|
27
|
-
}, []);
|
|
28
|
-
return results.length === 1 ? results[0] : results.length === 0 ? '' : results;
|
|
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;
|
|
29
23
|
}
|
|
30
|
-
export function formatListToParts(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
onError(new IntlFormatError('Error formatting list.', locale, e));
|
|
58
|
-
}
|
|
59
|
-
// @ts-ignore
|
|
60
|
-
return values;
|
|
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;
|
|
61
51
|
}
|
package/src/message.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { CustomFormats, Formatters, MessageDescriptor, OnErrorFn } from
|
|
2
|
-
import { MessageFormatElement } from
|
|
3
|
-
import { FormatXMLElementFn, Formatters as IntlMessageFormatFormatters, Options, PrimitiveType } from
|
|
4
|
-
export type FormatMessageFn<T> = ({ locale, formats, messages, defaultLocale, defaultFormats, fallbackOnEmptyString, onError, timeZone, defaultRichTextElements
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}, state: IntlMessageFormatFormatters & Pick<Formatters,
|
|
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
15
|
export declare const formatMessage: FormatMessageFn<any>;
|
package/src/message.js
CHANGED
|
@@ -1,103 +1,110 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { TYPE } from
|
|
3
|
-
import { IntlMessageFormat
|
|
4
|
-
import { MessageFormatError, MissingTranslationError } from
|
|
5
|
-
import { invariant } from
|
|
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
6
|
function setTimeZoneInOptions(opts, timeZone) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
return Object.keys(opts).reduce((all, k) => {
|
|
8
|
+
all[k] = {
|
|
9
|
+
timeZone,
|
|
10
|
+
...opts[k]
|
|
11
|
+
};
|
|
12
|
+
return all;
|
|
13
|
+
}, {});
|
|
11
14
|
}
|
|
12
15
|
function deepMergeOptions(opts1, opts2) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
+
}, {});
|
|
18
27
|
}
|
|
19
28
|
function deepMergeFormatsAndSetTimeZone(f1, timeZone) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
+
};
|
|
25
39
|
}
|
|
26
|
-
export
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (typeof message === 'string') {
|
|
97
|
-
return message;
|
|
98
|
-
}
|
|
99
|
-
if (typeof defaultMessage === 'string') {
|
|
100
|
-
return defaultMessage;
|
|
101
|
-
}
|
|
102
|
-
return id;
|
|
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
|
+
// IMPORTANT: Hot path straight lookup for performance
|
|
55
|
+
if (!values && message && typeof message === "string" && !defaultRichTextElements) {
|
|
56
|
+
return message.replace(/'\{(.*?)\}'/gi, `{$1}`);
|
|
57
|
+
}
|
|
58
|
+
values = {
|
|
59
|
+
...defaultRichTextElements,
|
|
60
|
+
...values
|
|
61
|
+
};
|
|
62
|
+
formats = deepMergeFormatsAndSetTimeZone(formats, timeZone);
|
|
63
|
+
defaultFormats = deepMergeFormatsAndSetTimeZone(defaultFormats, timeZone);
|
|
64
|
+
if (!message) {
|
|
65
|
+
if (fallbackOnEmptyString === false && message === "") {
|
|
66
|
+
return message;
|
|
67
|
+
}
|
|
68
|
+
if (!defaultMessage || locale && locale.toLowerCase() !== defaultLocale.toLowerCase()) {
|
|
69
|
+
// This prevents warnings from littering the console in development
|
|
70
|
+
// when no `messages` are passed into the <IntlProvider> for the
|
|
71
|
+
// default locale.
|
|
72
|
+
onError(new MissingTranslationError(messageDescriptor, locale));
|
|
73
|
+
}
|
|
74
|
+
if (defaultMessage) {
|
|
75
|
+
try {
|
|
76
|
+
const formatter = state.getMessageFormat(defaultMessage, defaultLocale, defaultFormats, opts);
|
|
77
|
+
return formatter.format(values);
|
|
78
|
+
} catch (e) {
|
|
79
|
+
onError(new MessageFormatError(`Error formatting default message for: "${id}", rendering default message verbatim`, locale, messageDescriptor, e));
|
|
80
|
+
return typeof defaultMessage === "string" ? defaultMessage : id;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return id;
|
|
84
|
+
}
|
|
85
|
+
// We have the translated message
|
|
86
|
+
try {
|
|
87
|
+
const formatter = state.getMessageFormat(message, locale, formats, {
|
|
88
|
+
formatters: state,
|
|
89
|
+
...opts
|
|
90
|
+
});
|
|
91
|
+
return formatter.format(values);
|
|
92
|
+
} catch (e) {
|
|
93
|
+
onError(new MessageFormatError(`Error formatting message: "${id}", using ${defaultMessage ? "default message" : "id"} as fallback.`, locale, messageDescriptor, e));
|
|
94
|
+
}
|
|
95
|
+
if (defaultMessage) {
|
|
96
|
+
try {
|
|
97
|
+
const formatter = state.getMessageFormat(defaultMessage, defaultLocale, defaultFormats, opts);
|
|
98
|
+
return formatter.format(values);
|
|
99
|
+
} catch (e) {
|
|
100
|
+
onError(new MessageFormatError(`Error formatting the default message for: "${id}", rendering message verbatim`, locale, messageDescriptor, e));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (typeof message === "string") {
|
|
104
|
+
return message;
|
|
105
|
+
}
|
|
106
|
+
if (typeof defaultMessage === "string") {
|
|
107
|
+
return defaultMessage;
|
|
108
|
+
}
|
|
109
|
+
return id;
|
|
103
110
|
};
|
package/src/number.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { CustomFormats, Formatters, IntlFormatters, OnErrorFn } from
|
|
2
|
-
export declare function getFormatter({ locale, formats, onError
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}, getNumberFormat: Formatters[
|
|
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
7
|
export declare function formatNumber(config: {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}, getNumberFormat: Formatters[
|
|
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
12
|
export declare function formatNumberToParts(config: {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}, getNumberFormat: Formatters[
|
|
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[];
|