@discord/intl 0.5.0 → 0.5.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/dist/format-config.d.ts +17 -0
- package/dist/format-config.js +61 -0
- package/dist/format.d.ts +5 -4
- package/dist/format.js +14 -14
- package/dist/intl-manager.d.ts +2 -0
- package/dist/intl-manager.js +4 -3
- package/dist/message-loader.js +8 -1
- package/package.json +1 -1
- package/src/format-config.ts +72 -0
- package/src/format.ts +25 -16
- package/src/intl-manager.ts +6 -3
- package/src/message-loader.ts +9 -3
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface FormatConfig {
|
|
2
|
+
number: {
|
|
3
|
+
[name: string]: Intl.NumberFormatOptions;
|
|
4
|
+
};
|
|
5
|
+
time: {
|
|
6
|
+
[name: string]: Intl.DateTimeFormatOptions;
|
|
7
|
+
};
|
|
8
|
+
date: {
|
|
9
|
+
[name: string]: Intl.DateTimeFormatOptions;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Default formatting configuration options for common date, time, and number formats. This is
|
|
14
|
+
* taken almost directly from FormatJS's defaults here, for the sake of compatibility.
|
|
15
|
+
* https://github.com/formatjs/formatjs/blob/c30975bfbe2db7eb62f4dbe6c8ad6ca5e786dcb3/packages/intl-messageformat/src/core.ts#L229-L296
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_FORMAT_CONFIG: FormatConfig;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_FORMAT_CONFIG = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Default formatting configuration options for common date, time, and number formats. This is
|
|
6
|
+
* taken almost directly from FormatJS's defaults here, for the sake of compatibility.
|
|
7
|
+
* https://github.com/formatjs/formatjs/blob/c30975bfbe2db7eb62f4dbe6c8ad6ca5e786dcb3/packages/intl-messageformat/src/core.ts#L229-L296
|
|
8
|
+
*/
|
|
9
|
+
exports.DEFAULT_FORMAT_CONFIG = {
|
|
10
|
+
number: {
|
|
11
|
+
integer: { maximumFractionDigits: 0 },
|
|
12
|
+
currency: { style: 'currency' },
|
|
13
|
+
percent: { style: 'percent' },
|
|
14
|
+
},
|
|
15
|
+
date: {
|
|
16
|
+
short: {
|
|
17
|
+
month: 'numeric',
|
|
18
|
+
day: 'numeric',
|
|
19
|
+
year: '2-digit',
|
|
20
|
+
},
|
|
21
|
+
medium: {
|
|
22
|
+
month: 'short',
|
|
23
|
+
day: 'numeric',
|
|
24
|
+
year: 'numeric',
|
|
25
|
+
},
|
|
26
|
+
long: {
|
|
27
|
+
month: 'long',
|
|
28
|
+
day: 'numeric',
|
|
29
|
+
year: 'numeric',
|
|
30
|
+
},
|
|
31
|
+
full: {
|
|
32
|
+
weekday: 'long',
|
|
33
|
+
month: 'long',
|
|
34
|
+
day: 'numeric',
|
|
35
|
+
year: 'numeric',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
time: {
|
|
39
|
+
short: {
|
|
40
|
+
hour: 'numeric',
|
|
41
|
+
minute: 'numeric',
|
|
42
|
+
},
|
|
43
|
+
medium: {
|
|
44
|
+
hour: 'numeric',
|
|
45
|
+
minute: 'numeric',
|
|
46
|
+
second: 'numeric',
|
|
47
|
+
},
|
|
48
|
+
long: {
|
|
49
|
+
hour: 'numeric',
|
|
50
|
+
minute: 'numeric',
|
|
51
|
+
second: 'numeric',
|
|
52
|
+
timeZoneName: 'short',
|
|
53
|
+
},
|
|
54
|
+
full: {
|
|
55
|
+
hour: 'numeric',
|
|
56
|
+
minute: 'numeric',
|
|
57
|
+
second: 'numeric',
|
|
58
|
+
timeZoneName: 'short',
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
};
|
package/dist/format.d.ts
CHANGED
|
@@ -17,8 +17,9 @@
|
|
|
17
17
|
* parameter, important to have React treat the resulting elements nicely.
|
|
18
18
|
*/
|
|
19
19
|
import { FormatJsNode } from './keyless-json';
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
20
|
+
import { Formatters } from 'intl-messageformat';
|
|
21
|
+
import type { FormatConfig } from './format-config';
|
|
22
|
+
import type { RichTextTagNames } from './types';
|
|
22
23
|
export declare abstract class FormatBuilder<Result> {
|
|
23
24
|
abstract pushRichTextTag(tag: RichTextTagNames, children: Result[]): void;
|
|
24
25
|
abstract pushLiteralText(text: string): void;
|
|
@@ -26,5 +27,5 @@ export declare abstract class FormatBuilder<Result> {
|
|
|
26
27
|
abstract finish(): Result[];
|
|
27
28
|
}
|
|
28
29
|
export type FormatBuilderConstructor<Result> = new () => FormatBuilder<Result>;
|
|
29
|
-
export declare function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>(builder: Builder, nodes: FormatJsNode[], locales: string | string[], formatters: Formatters,
|
|
30
|
-
export declare function bindFormatValues<Result>(Builder: FormatBuilderConstructor<Result>, nodes: FormatJsNode[], locales: string | string[], formatters: Formatters,
|
|
30
|
+
export declare function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>(builder: Builder, nodes: FormatJsNode[], locales: string | string[], formatters: Formatters, formatConfig: FormatConfig, values?: Record<string, string | object>, currentPluralValue?: number, originalMessage?: string): void;
|
|
31
|
+
export declare function bindFormatValues<Result>(Builder: FormatBuilderConstructor<Result>, nodes: FormatJsNode[], locales: string | string[], formatters: Formatters, formatConfig: FormatConfig, values?: Record<string, string | object>, currentPluralValue?: number): Result[];
|
package/dist/format.js
CHANGED
|
@@ -32,9 +32,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
32
32
|
exports.FormatBuilder = void 0;
|
|
33
33
|
exports.bindFormatValuesWithBuilder = bindFormatValuesWithBuilder;
|
|
34
34
|
exports.bindFormatValues = bindFormatValues;
|
|
35
|
+
var icu_skeleton_parser_1 = require("@formatjs/icu-skeleton-parser");
|
|
35
36
|
var keyless_json_1 = require("./keyless-json");
|
|
36
37
|
var intl_messageformat_1 = require("intl-messageformat");
|
|
37
|
-
var icu_skeleton_parser_1 = require("@formatjs/icu-skeleton-parser");
|
|
38
38
|
/**
|
|
39
39
|
* Returns true if the tag name should be considered a rich text tag that
|
|
40
40
|
* applies formatting to a message, rather than being a user-supplied value.
|
|
@@ -48,7 +48,7 @@ var FormatBuilder = /** @class */ (function () {
|
|
|
48
48
|
return FormatBuilder;
|
|
49
49
|
}());
|
|
50
50
|
exports.FormatBuilder = FormatBuilder;
|
|
51
|
-
function bindFormatValuesWithBuilder(builder, nodes, locales, formatters,
|
|
51
|
+
function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, formatConfig, values, currentPluralValue, originalMessage) {
|
|
52
52
|
var e_1, _a;
|
|
53
53
|
var _b, _c;
|
|
54
54
|
if (values === void 0) { values = {}; }
|
|
@@ -97,11 +97,11 @@ function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, format
|
|
|
97
97
|
case keyless_json_1.FormatJsNodeType.Date: {
|
|
98
98
|
// Distinct from FormatJS: We don't currently parse the skeleton ahead of time in the AST,
|
|
99
99
|
// so this manages parsing the skeleton as well before passing it onto the date formatter.
|
|
100
|
-
var style = node.style in
|
|
101
|
-
?
|
|
100
|
+
var style = node.style in formatConfig.date
|
|
101
|
+
? formatConfig.date[node.style]
|
|
102
102
|
: node.style != null
|
|
103
103
|
? (0, icu_skeleton_parser_1.parseDateTimeSkeleton)(node.style)
|
|
104
|
-
:
|
|
104
|
+
: formatConfig.time.medium;
|
|
105
105
|
// @ts-expect-error Cast string values to dates properly.
|
|
106
106
|
builder.pushLiteralText(formatters.getDateTimeFormat(locales, style).format(value));
|
|
107
107
|
break;
|
|
@@ -109,8 +109,8 @@ function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, format
|
|
|
109
109
|
case keyless_json_1.FormatJsNodeType.Time: {
|
|
110
110
|
// Distinct from FormatJS: We don't currently parse the skeleton ahead of time in the AST,
|
|
111
111
|
// so this manages parsing the skeleton as well before passing it onto the date formatter.
|
|
112
|
-
var style = node.style in
|
|
113
|
-
?
|
|
112
|
+
var style = node.style in formatConfig.time
|
|
113
|
+
? formatConfig.time[node.style]
|
|
114
114
|
: node.style != null
|
|
115
115
|
? (0, icu_skeleton_parser_1.parseDateTimeSkeleton)(node.style)
|
|
116
116
|
: undefined; // TODO: parseSkeleton();
|
|
@@ -122,8 +122,8 @@ function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, format
|
|
|
122
122
|
case keyless_json_1.FormatJsNodeType.Number: {
|
|
123
123
|
// Distinct from FormatJS: We don't currently parse the skeleton ahead of time in the AST,
|
|
124
124
|
// so this manages parsing the skeleton as well before passing it onto the date formatter.
|
|
125
|
-
var style = node.style in
|
|
126
|
-
?
|
|
125
|
+
var style = node.style in formatConfig.number
|
|
126
|
+
? formatConfig.number[node.style]
|
|
127
127
|
: node.style != null
|
|
128
128
|
? (0, icu_skeleton_parser_1.parseNumberSkeleton)((0, icu_skeleton_parser_1.parseNumberSkeletonFromString)(node.style))
|
|
129
129
|
: undefined;
|
|
@@ -135,7 +135,7 @@ function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, format
|
|
|
135
135
|
}
|
|
136
136
|
case keyless_json_1.FormatJsNodeType.Tag: {
|
|
137
137
|
var children = node.children;
|
|
138
|
-
var appliedChildren = bindFormatValues(builder.constructor, children, locales, formatters,
|
|
138
|
+
var appliedChildren = bindFormatValues(builder.constructor, children, locales, formatters, formatConfig, values, currentPluralValue);
|
|
139
139
|
if (isRichTextTag(variableName)) {
|
|
140
140
|
builder.pushRichTextTag(variableName, appliedChildren);
|
|
141
141
|
}
|
|
@@ -171,7 +171,7 @@ function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, format
|
|
|
171
171
|
if (option == null) {
|
|
172
172
|
throw "".concat(node.value, " is not a known option for select value ").concat(variableName, ". Valid options are ").concat(Object.keys(node.options).join(', '));
|
|
173
173
|
}
|
|
174
|
-
bindFormatValuesWithBuilder(builder, option.value, locales, formatters,
|
|
174
|
+
bindFormatValuesWithBuilder(builder, option.value, locales, formatters, formatConfig, values);
|
|
175
175
|
break;
|
|
176
176
|
}
|
|
177
177
|
case keyless_json_1.FormatJsNodeType.Plural: {
|
|
@@ -189,7 +189,7 @@ function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, format
|
|
|
189
189
|
if (option == null) {
|
|
190
190
|
throw "".concat(node.value, " is not a known option for plural value ").concat(variableName, ". Valid options are ").concat(Object.keys(node.options).join(', '));
|
|
191
191
|
}
|
|
192
|
-
bindFormatValuesWithBuilder(builder, option.value, locales, formatters,
|
|
192
|
+
bindFormatValuesWithBuilder(builder, option.value, locales, formatters, formatConfig, values,
|
|
193
193
|
// @ts-expect-error assert this `as number` properly.
|
|
194
194
|
value - ((_c = node.offset) !== null && _c !== void 0 ? _c : 0));
|
|
195
195
|
break;
|
|
@@ -210,9 +210,9 @@ function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, format
|
|
|
210
210
|
finally { if (e_1) throw e_1.error; }
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
|
-
function bindFormatValues(Builder, nodes, locales, formatters,
|
|
213
|
+
function bindFormatValues(Builder, nodes, locales, formatters, formatConfig, values, currentPluralValue) {
|
|
214
214
|
if (values === void 0) { values = {}; }
|
|
215
215
|
var builder = new Builder();
|
|
216
|
-
bindFormatValuesWithBuilder(builder, nodes, locales, formatters,
|
|
216
|
+
bindFormatValuesWithBuilder(builder, nodes, locales, formatters, formatConfig, values, currentPluralValue);
|
|
217
217
|
return builder.finish();
|
|
218
218
|
}
|
package/dist/intl-manager.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { IntlShape } from '@formatjs/intl';
|
|
|
2
2
|
import type { FormatterImplementation, IntlMessageGetter, RequiredFormatValues, TypedIntlMessageGetter } from './types';
|
|
3
3
|
import { InternalIntlMessage } from './message';
|
|
4
4
|
import { FormatBuilderConstructor } from './format';
|
|
5
|
+
import { FormatConfig } from './format-config';
|
|
5
6
|
/**
|
|
6
7
|
* Fallback locale used for all internationalization when an operation in the
|
|
7
8
|
* requested locale is not possible.
|
|
@@ -17,6 +18,7 @@ export declare class IntlManager {
|
|
|
17
18
|
defaultLocale: string;
|
|
18
19
|
currentLocale: string;
|
|
19
20
|
intl: IntlShape;
|
|
21
|
+
formatConfig: FormatConfig;
|
|
20
22
|
_localeSubscriptions: Set<(locale: string) => void>;
|
|
21
23
|
constructor(defaultLocale?: string);
|
|
22
24
|
/**
|
package/dist/intl-manager.js
CHANGED
|
@@ -29,8 +29,8 @@ var __read = (this && this.__read) || function (o, n) {
|
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
30
|
exports.IntlManager = exports.DEFAULT_LOCALE = void 0;
|
|
31
31
|
var intl_1 = require("@formatjs/intl");
|
|
32
|
-
var intl_messageformat_1 = require("intl-messageformat");
|
|
33
32
|
var format_1 = require("./format");
|
|
33
|
+
var format_config_1 = require("./format-config");
|
|
34
34
|
/**
|
|
35
35
|
* Fallback locale used for all internationalization when an operation in the
|
|
36
36
|
* requested locale is not possible.
|
|
@@ -49,8 +49,9 @@ var IntlManager = /** @class */ (function () {
|
|
|
49
49
|
};
|
|
50
50
|
this.defaultLocale = defaultLocale;
|
|
51
51
|
this.currentLocale = defaultLocale;
|
|
52
|
+
this.formatConfig = format_config_1.DEFAULT_FORMAT_CONFIG;
|
|
52
53
|
this.intl = (0, intl_1.createIntl)({
|
|
53
|
-
formats:
|
|
54
|
+
formats: format_config_1.DEFAULT_FORMAT_CONFIG,
|
|
54
55
|
defaultLocale: defaultLocale,
|
|
55
56
|
locale: defaultLocale,
|
|
56
57
|
});
|
|
@@ -144,7 +145,7 @@ var IntlManager = /** @class */ (function () {
|
|
|
144
145
|
return resolved.reserialize();
|
|
145
146
|
};
|
|
146
147
|
IntlManager.prototype.bindFormatValues = function (Builder, message, values) {
|
|
147
|
-
return (0, format_1.bindFormatValues)(Builder, message.ast, [this.currentLocale, this.defaultLocale], this.intl.formatters, this.
|
|
148
|
+
return (0, format_1.bindFormatValues)(Builder, message.ast, [this.currentLocale, this.defaultLocale], this.intl.formatters, this.formatConfig, values);
|
|
148
149
|
};
|
|
149
150
|
return IntlManager;
|
|
150
151
|
}());
|
package/dist/message-loader.js
CHANGED
|
@@ -206,7 +206,14 @@ var MessageLoader = /** @class */ (function () {
|
|
|
206
206
|
// requested locale. Shouldn't happen, but throwing here is much more
|
|
207
207
|
// contextual than whatever error would result otherwise.
|
|
208
208
|
if (this.localeImportMap[locale] == null) {
|
|
209
|
-
|
|
209
|
+
if (this.supportedLocales.includes(locale)) {
|
|
210
|
+
// `supportedLocales` is determined by the `localeImportMap`, so if it's present but
|
|
211
|
+
// nullish, it's almost definitely a configuration error and deserves to be reported loudly.
|
|
212
|
+
throw new Error("Requested to load locale ".concat(locale, ", which should be supported, but no source for translation data was provided."));
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
return [2 /*return*/];
|
|
216
|
+
}
|
|
210
217
|
}
|
|
211
218
|
// If the locale is already set in `messages`, then it doesn't need to be loaded again.
|
|
212
219
|
if (this.messages[locale] != null)
|
package/package.json
CHANGED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export interface FormatConfig {
|
|
2
|
+
number: { [name: string]: Intl.NumberFormatOptions };
|
|
3
|
+
time: { [name: string]: Intl.DateTimeFormatOptions };
|
|
4
|
+
date: { [name: string]: Intl.DateTimeFormatOptions };
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Default formatting configuration options for common date, time, and number formats. This is
|
|
9
|
+
* taken almost directly from FormatJS's defaults here, for the sake of compatibility.
|
|
10
|
+
* https://github.com/formatjs/formatjs/blob/c30975bfbe2db7eb62f4dbe6c8ad6ca5e786dcb3/packages/intl-messageformat/src/core.ts#L229-L296
|
|
11
|
+
*/
|
|
12
|
+
export const DEFAULT_FORMAT_CONFIG: FormatConfig = {
|
|
13
|
+
number: {
|
|
14
|
+
integer: { maximumFractionDigits: 0 },
|
|
15
|
+
currency: { style: 'currency' },
|
|
16
|
+
percent: { style: 'percent' },
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
date: {
|
|
20
|
+
short: {
|
|
21
|
+
month: 'numeric',
|
|
22
|
+
day: 'numeric',
|
|
23
|
+
year: '2-digit',
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
medium: {
|
|
27
|
+
month: 'short',
|
|
28
|
+
day: 'numeric',
|
|
29
|
+
year: 'numeric',
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
long: {
|
|
33
|
+
month: 'long',
|
|
34
|
+
day: 'numeric',
|
|
35
|
+
year: 'numeric',
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
full: {
|
|
39
|
+
weekday: 'long',
|
|
40
|
+
month: 'long',
|
|
41
|
+
day: 'numeric',
|
|
42
|
+
year: 'numeric',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
time: {
|
|
47
|
+
short: {
|
|
48
|
+
hour: 'numeric',
|
|
49
|
+
minute: 'numeric',
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
medium: {
|
|
53
|
+
hour: 'numeric',
|
|
54
|
+
minute: 'numeric',
|
|
55
|
+
second: 'numeric',
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
long: {
|
|
59
|
+
hour: 'numeric',
|
|
60
|
+
minute: 'numeric',
|
|
61
|
+
second: 'numeric',
|
|
62
|
+
timeZoneName: 'short',
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
full: {
|
|
66
|
+
hour: 'numeric',
|
|
67
|
+
minute: 'numeric',
|
|
68
|
+
second: 'numeric',
|
|
69
|
+
timeZoneName: 'short',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
};
|
package/src/format.ts
CHANGED
|
@@ -17,15 +17,17 @@
|
|
|
17
17
|
* parameter, important to have React treat the resulting elements nicely.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { FormatJsNode, FormatJsNodeType } from './keyless-json';
|
|
21
|
-
import { Formats, Formatters, MissingValueError } from 'intl-messageformat';
|
|
22
|
-
import { RichTextTagNames } from './types';
|
|
23
20
|
import {
|
|
24
21
|
parseDateTimeSkeleton,
|
|
25
22
|
parseNumberSkeleton,
|
|
26
23
|
parseNumberSkeletonFromString,
|
|
27
24
|
} from '@formatjs/icu-skeleton-parser';
|
|
28
25
|
|
|
26
|
+
import { FormatJsNode, FormatJsNodeType } from './keyless-json';
|
|
27
|
+
import { Formatters, MissingValueError } from 'intl-messageformat';
|
|
28
|
+
import type { FormatConfig } from './format-config';
|
|
29
|
+
import type { RichTextTagNames } from './types';
|
|
30
|
+
|
|
29
31
|
/**
|
|
30
32
|
* Returns true if the tag name should be considered a rich text tag that
|
|
31
33
|
* applies formatting to a message, rather than being a user-supplied value.
|
|
@@ -48,7 +50,7 @@ export function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>
|
|
|
48
50
|
nodes: FormatJsNode[],
|
|
49
51
|
locales: string | string[],
|
|
50
52
|
formatters: Formatters,
|
|
51
|
-
|
|
53
|
+
formatConfig: FormatConfig,
|
|
52
54
|
values: Record<string, string | object> = {},
|
|
53
55
|
currentPluralValue?: number,
|
|
54
56
|
originalMessage?: string,
|
|
@@ -102,11 +104,11 @@ export function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>
|
|
|
102
104
|
// Distinct from FormatJS: We don't currently parse the skeleton ahead of time in the AST,
|
|
103
105
|
// so this manages parsing the skeleton as well before passing it onto the date formatter.
|
|
104
106
|
const style =
|
|
105
|
-
node.style in
|
|
106
|
-
?
|
|
107
|
+
node.style in formatConfig.date
|
|
108
|
+
? formatConfig.date[node.style]
|
|
107
109
|
: node.style != null
|
|
108
110
|
? parseDateTimeSkeleton(node.style)
|
|
109
|
-
:
|
|
111
|
+
: formatConfig.time.medium;
|
|
110
112
|
// @ts-expect-error Cast string values to dates properly.
|
|
111
113
|
builder.pushLiteralText(formatters.getDateTimeFormat(locales, style).format(value));
|
|
112
114
|
break;
|
|
@@ -115,8 +117,8 @@ export function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>
|
|
|
115
117
|
// Distinct from FormatJS: We don't currently parse the skeleton ahead of time in the AST,
|
|
116
118
|
// so this manages parsing the skeleton as well before passing it onto the date formatter.
|
|
117
119
|
const style =
|
|
118
|
-
node.style in
|
|
119
|
-
?
|
|
120
|
+
node.style in formatConfig.time
|
|
121
|
+
? formatConfig.time[node.style]
|
|
120
122
|
: node.style != null
|
|
121
123
|
? parseDateTimeSkeleton(node.style)
|
|
122
124
|
: undefined; // TODO: parseSkeleton();
|
|
@@ -130,8 +132,8 @@ export function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>
|
|
|
130
132
|
// Distinct from FormatJS: We don't currently parse the skeleton ahead of time in the AST,
|
|
131
133
|
// so this manages parsing the skeleton as well before passing it onto the date formatter.
|
|
132
134
|
const style =
|
|
133
|
-
node.style in
|
|
134
|
-
?
|
|
135
|
+
node.style in formatConfig.number
|
|
136
|
+
? formatConfig.number[node.style]
|
|
135
137
|
: node.style != null
|
|
136
138
|
? parseNumberSkeleton(parseNumberSkeletonFromString(node.style))
|
|
137
139
|
: undefined;
|
|
@@ -149,7 +151,7 @@ export function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>
|
|
|
149
151
|
children,
|
|
150
152
|
locales,
|
|
151
153
|
formatters,
|
|
152
|
-
|
|
154
|
+
formatConfig,
|
|
153
155
|
values,
|
|
154
156
|
currentPluralValue,
|
|
155
157
|
);
|
|
@@ -177,7 +179,14 @@ export function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>
|
|
|
177
179
|
if (option == null) {
|
|
178
180
|
throw `${node.value} is not a known option for select value ${variableName}. Valid options are ${Object.keys(node.options).join(', ')}`;
|
|
179
181
|
}
|
|
180
|
-
bindFormatValuesWithBuilder(
|
|
182
|
+
bindFormatValuesWithBuilder(
|
|
183
|
+
builder,
|
|
184
|
+
option.value,
|
|
185
|
+
locales,
|
|
186
|
+
formatters,
|
|
187
|
+
formatConfig,
|
|
188
|
+
values,
|
|
189
|
+
);
|
|
181
190
|
break;
|
|
182
191
|
}
|
|
183
192
|
|
|
@@ -200,7 +209,7 @@ export function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>
|
|
|
200
209
|
option.value,
|
|
201
210
|
locales,
|
|
202
211
|
formatters,
|
|
203
|
-
|
|
212
|
+
formatConfig,
|
|
204
213
|
values,
|
|
205
214
|
// @ts-expect-error assert this `as number` properly.
|
|
206
215
|
(value as number) - (node.offset ?? 0),
|
|
@@ -216,7 +225,7 @@ export function bindFormatValues<Result>(
|
|
|
216
225
|
nodes: FormatJsNode[],
|
|
217
226
|
locales: string | string[],
|
|
218
227
|
formatters: Formatters,
|
|
219
|
-
|
|
228
|
+
formatConfig: FormatConfig,
|
|
220
229
|
values: Record<string, string | object> = {},
|
|
221
230
|
currentPluralValue?: number,
|
|
222
231
|
): Result[] {
|
|
@@ -226,7 +235,7 @@ export function bindFormatValues<Result>(
|
|
|
226
235
|
nodes,
|
|
227
236
|
locales,
|
|
228
237
|
formatters,
|
|
229
|
-
|
|
238
|
+
formatConfig,
|
|
230
239
|
values,
|
|
231
240
|
currentPluralValue,
|
|
232
241
|
);
|
package/src/intl-manager.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createIntl, IntlShape } from '@formatjs/intl';
|
|
2
|
-
import {
|
|
2
|
+
import { Formatters } from 'intl-messageformat';
|
|
3
3
|
|
|
4
4
|
import type {
|
|
5
5
|
FormatterImplementation,
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
import { InternalIntlMessage } from './message';
|
|
11
11
|
import { bindFormatValues, FormatBuilderConstructor } from './format';
|
|
12
12
|
import { FormatJsLiteral } from './keyless-json';
|
|
13
|
+
import { DEFAULT_FORMAT_CONFIG, FormatConfig } from './format-config';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Fallback locale used for all internationalization when an operation in the
|
|
@@ -41,14 +42,16 @@ export class IntlManager {
|
|
|
41
42
|
defaultLocale: string;
|
|
42
43
|
currentLocale: string;
|
|
43
44
|
intl: IntlShape;
|
|
45
|
+
formatConfig: FormatConfig;
|
|
44
46
|
|
|
45
47
|
_localeSubscriptions: Set<(locale: string) => void>;
|
|
46
48
|
|
|
47
49
|
constructor(defaultLocale: string = DEFAULT_LOCALE) {
|
|
48
50
|
this.defaultLocale = defaultLocale;
|
|
49
51
|
this.currentLocale = defaultLocale;
|
|
52
|
+
this.formatConfig = DEFAULT_FORMAT_CONFIG;
|
|
50
53
|
this.intl = createIntl({
|
|
51
|
-
formats:
|
|
54
|
+
formats: DEFAULT_FORMAT_CONFIG,
|
|
52
55
|
defaultLocale,
|
|
53
56
|
locale: defaultLocale,
|
|
54
57
|
});
|
|
@@ -148,7 +151,7 @@ export class IntlManager {
|
|
|
148
151
|
message.ast,
|
|
149
152
|
[this.currentLocale, this.defaultLocale],
|
|
150
153
|
this.intl.formatters as Formatters,
|
|
151
|
-
this.
|
|
154
|
+
this.formatConfig,
|
|
152
155
|
values,
|
|
153
156
|
);
|
|
154
157
|
}
|
package/src/message-loader.ts
CHANGED
|
@@ -210,9 +210,15 @@ export class MessageLoader {
|
|
|
210
210
|
// requested locale. Shouldn't happen, but throwing here is much more
|
|
211
211
|
// contextual than whatever error would result otherwise.
|
|
212
212
|
if (this.localeImportMap[locale] == null) {
|
|
213
|
-
|
|
214
|
-
`
|
|
215
|
-
|
|
213
|
+
if (this.supportedLocales.includes(locale)) {
|
|
214
|
+
// `supportedLocales` is determined by the `localeImportMap`, so if it's present but
|
|
215
|
+
// nullish, it's almost definitely a configuration error and deserves to be reported loudly.
|
|
216
|
+
throw new Error(
|
|
217
|
+
`Requested to load locale ${locale}, which should be supported, but no source for translation data was provided.`,
|
|
218
|
+
);
|
|
219
|
+
} else {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
216
222
|
}
|
|
217
223
|
|
|
218
224
|
// If the locale is already set in `messages`, then it doesn't need to be loaded again.
|