@discord/intl 0.10.0-rc.4 → 0.10.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.js +6 -7
- package/dist/message-loader.d.ts +11 -9
- package/dist/message-loader.js +8 -4
- package/dist/types.d.ts +2 -4
- package/package.json +2 -2
- package/src/format.ts +5 -6
- package/src/message-loader.ts +12 -13
- package/src/types.d.ts +2 -4
package/dist/format.js
CHANGED
|
@@ -35,7 +35,7 @@ class FormatBuilder {
|
|
|
35
35
|
}
|
|
36
36
|
exports.FormatBuilder = FormatBuilder;
|
|
37
37
|
function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, formatConfig, values = {}, currentPluralValue, originalMessage) {
|
|
38
|
-
var _a
|
|
38
|
+
var _a;
|
|
39
39
|
// Hot path for static messages that are just parsed as a single string element.
|
|
40
40
|
if (nodes.length === 1 && typeof nodes[0] === 'string') {
|
|
41
41
|
builder.pushLiteralText(nodes[0]);
|
|
@@ -146,17 +146,16 @@ function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, format
|
|
|
146
146
|
break;
|
|
147
147
|
}
|
|
148
148
|
case intl_ast_1.FormatJsNodeType.Select: {
|
|
149
|
-
const
|
|
149
|
+
const requestedOption = value;
|
|
150
150
|
const options = node[2 /* AstNodeIndices.Options */];
|
|
151
|
-
const option =
|
|
151
|
+
const option = requestedOption in options ? options[requestedOption] : options.other;
|
|
152
152
|
if (option == null) {
|
|
153
|
-
throw `${
|
|
153
|
+
throw `${requestedOption} is not a known option for select value ${variableName}. Valid options are ${Object.keys(options).join(', ')}`;
|
|
154
154
|
}
|
|
155
155
|
bindFormatValuesWithBuilder(builder, option, locales, formatters, formatConfig, values);
|
|
156
156
|
break;
|
|
157
157
|
}
|
|
158
158
|
case intl_ast_1.FormatJsNodeType.Plural: {
|
|
159
|
-
const value = node[1 /* AstNodeIndices.Value */];
|
|
160
159
|
const options = node[2 /* AstNodeIndices.Options */];
|
|
161
160
|
const offset = node[3 /* AstNodeIndices.Offset */];
|
|
162
161
|
const pluralType = node[4 /* AstNodeIndices.PluralType */];
|
|
@@ -175,8 +174,8 @@ function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, format
|
|
|
175
174
|
throw `${value} is not a known option for plural value ${variableName}. Valid options are ${Object.keys(options).join(', ')}`;
|
|
176
175
|
}
|
|
177
176
|
bindFormatValuesWithBuilder(builder, option, locales, formatters, formatConfig, values,
|
|
178
|
-
// @ts-expect-error assert this `as number` properly
|
|
179
|
-
value - (
|
|
177
|
+
// @ts-expect-error assert this `as number` properly
|
|
178
|
+
value - (offset !== null && offset !== void 0 ? offset : 0));
|
|
180
179
|
break;
|
|
181
180
|
}
|
|
182
181
|
}
|
package/dist/message-loader.d.ts
CHANGED
|
@@ -2,17 +2,12 @@ import { AstNode, FullFormatJsNode } from '@discord/intl-ast';
|
|
|
2
2
|
import { InternalIntlMessage } from './message';
|
|
3
3
|
/**
|
|
4
4
|
* Type representing the serialized content of a translations file, which is a record of hashed
|
|
5
|
-
* message keys to their AST structure. This type represents both compressed, keyless AstNodes
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* message keys to their AST structure. This type represents both compressed, keyless AstNodes and
|
|
6
|
+
* fully-typed, object FullFormatJsNodes as the message content, since either can be given depending
|
|
7
|
+
* on the configuration of the bundler/compiler.
|
|
8
8
|
*/
|
|
9
9
|
type MessagesData = Record<string, AstNode[] | FullFormatJsNode[]>;
|
|
10
|
-
export
|
|
11
|
-
onChange(callback: () => void): () => void;
|
|
12
|
-
}
|
|
13
|
-
export interface IntlMessageGetter extends IntlMessageGetterAdditions {
|
|
14
|
-
(locale: LocaleId): InternalIntlMessage;
|
|
15
|
-
}
|
|
10
|
+
export type IntlMessageGetter = (this: MessageLoader, locale: LocaleId) => InternalIntlMessage;
|
|
16
11
|
export type LocaleId = string;
|
|
17
12
|
export type LocaleImportMap = Record<LocaleId, () => Promise<{
|
|
18
13
|
default: MessagesData;
|
|
@@ -103,6 +98,13 @@ export declare class MessageLoader {
|
|
|
103
98
|
* for `get` with the that key as the first argument, allowing consumers to
|
|
104
99
|
* just call the function with a locale to retrieve the translated message
|
|
105
100
|
* for that key.
|
|
101
|
+
*
|
|
102
|
+
* This method is provided as a way to generate binds _at runtime_, but for
|
|
103
|
+
* very-large messages files (e.g., thousands of messages), this can be a
|
|
104
|
+
* non-negligible cost. Where feasible, consider generating these binds
|
|
105
|
+
* at build/bundle time, especially in cases where they can be substantially
|
|
106
|
+
* minified (i.e., Hermes bytecode). This is provided automatically as an
|
|
107
|
+
* option when using one of `@discord/intl`'s transformers.
|
|
106
108
|
*/
|
|
107
109
|
getBinds(): Record<string, IntlMessageGetter>;
|
|
108
110
|
_loadLocale(locale: LocaleId): Promise<void>;
|
package/dist/message-loader.js
CHANGED
|
@@ -105,14 +105,18 @@ class MessageLoader {
|
|
|
105
105
|
* for `get` with the that key as the first argument, allowing consumers to
|
|
106
106
|
* just call the function with a locale to retrieve the translated message
|
|
107
107
|
* for that key.
|
|
108
|
+
*
|
|
109
|
+
* This method is provided as a way to generate binds _at runtime_, but for
|
|
110
|
+
* very-large messages files (e.g., thousands of messages), this can be a
|
|
111
|
+
* non-negligible cost. Where feasible, consider generating these binds
|
|
112
|
+
* at build/bundle time, especially in cases where they can be substantially
|
|
113
|
+
* minified (i.e., Hermes bytecode). This is provided automatically as an
|
|
114
|
+
* option when using one of `@discord/intl`'s transformers.
|
|
108
115
|
*/
|
|
109
116
|
getBinds() {
|
|
110
|
-
const onChange = this.onChange.bind(this);
|
|
111
117
|
const result = {};
|
|
112
118
|
for (const key of this.messageKeys) {
|
|
113
|
-
|
|
114
|
-
bound.onChange = onChange;
|
|
115
|
-
result[key] = bound;
|
|
119
|
+
result[key] = this.get.bind(this, key);
|
|
116
120
|
}
|
|
117
121
|
return result;
|
|
118
122
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { InternalIntlMessage } from './message';
|
|
2
|
-
import type { IntlMessageGetterAdditions } from './message-loader';
|
|
3
2
|
import { FormatBuilderConstructor } from './format';
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -42,7 +41,7 @@ export type IntlTime = string | number | Date | null | undefined;
|
|
|
42
41
|
export type PlainIntlMessage = string;
|
|
43
42
|
export type AnyIntlMessage = PlainIntlMessage | InternalIntlMessage;
|
|
44
43
|
|
|
45
|
-
export interface IntlMessageGetter
|
|
44
|
+
export interface IntlMessageGetter {
|
|
46
45
|
(locale: string): InternalIntlMessage | PlainIntlMessage;
|
|
47
46
|
}
|
|
48
47
|
|
|
@@ -52,8 +51,7 @@ export interface IntlMessageGetter extends IntlMessageGetterAdditions {
|
|
|
52
51
|
* value types that are required to format the message, or `{}` to represent
|
|
53
52
|
* that there are no values required and the message is a plain string.
|
|
54
53
|
*/
|
|
55
|
-
export interface TypedIntlMessageGetter<FormatValues extends object>
|
|
56
|
-
extends IntlMessageGetterAdditions {
|
|
54
|
+
export interface TypedIntlMessageGetter<FormatValues extends object> {
|
|
57
55
|
// TODO: This is lossy and unfortunate that typing can't be propagated
|
|
58
56
|
// to the returned message type, but doing so causes problems with
|
|
59
57
|
// contravariance of the type. When returning a message getter from a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@discord/intl",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Client runtime for managing messages and translations in a React project.",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"@formatjs/intl": "^2.10.1",
|
|
20
20
|
"@intrnl/xxhash64": "^0.1.2",
|
|
21
21
|
"intl-messageformat": "^10.5.11",
|
|
22
|
-
"@discord/intl-ast": "0.10.
|
|
22
|
+
"@discord/intl-ast": "0.10.2"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@swc/cli": "^0.3.12",
|
package/src/format.ts
CHANGED
|
@@ -192,18 +192,17 @@ export function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>
|
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
case FormatJsNodeType.Select: {
|
|
195
|
-
const
|
|
195
|
+
const requestedOption = value as string;
|
|
196
196
|
const options = node[AstNodeIndices.Options];
|
|
197
|
-
const option =
|
|
197
|
+
const option = requestedOption in options ? options[requestedOption] : options.other;
|
|
198
198
|
if (option == null) {
|
|
199
|
-
throw `${
|
|
199
|
+
throw `${requestedOption} is not a known option for select value ${variableName}. Valid options are ${Object.keys(options).join(', ')}`;
|
|
200
200
|
}
|
|
201
201
|
bindFormatValuesWithBuilder(builder, option, locales, formatters, formatConfig, values);
|
|
202
202
|
break;
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
case FormatJsNodeType.Plural: {
|
|
206
|
-
const value = node[AstNodeIndices.Value];
|
|
207
206
|
const options = node[AstNodeIndices.Options];
|
|
208
207
|
const offset = node[AstNodeIndices.Offset];
|
|
209
208
|
const pluralType = node[AstNodeIndices.PluralType];
|
|
@@ -227,8 +226,8 @@ export function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>
|
|
|
227
226
|
formatters,
|
|
228
227
|
formatConfig,
|
|
229
228
|
values,
|
|
230
|
-
// @ts-expect-error assert this `as number` properly
|
|
231
|
-
(value as number) - (
|
|
229
|
+
// @ts-expect-error assert this `as number` properly
|
|
230
|
+
(value as number) - (offset ?? 0),
|
|
232
231
|
);
|
|
233
232
|
break;
|
|
234
233
|
}
|
package/src/message-loader.ts
CHANGED
|
@@ -3,18 +3,13 @@ import { InternalIntlMessage } from './message';
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Type representing the serialized content of a translations file, which is a record of hashed
|
|
6
|
-
* message keys to their AST structure. This type represents both compressed, keyless AstNodes
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* message keys to their AST structure. This type represents both compressed, keyless AstNodes and
|
|
7
|
+
* fully-typed, object FullFormatJsNodes as the message content, since either can be given depending
|
|
8
|
+
* on the configuration of the bundler/compiler.
|
|
9
9
|
*/
|
|
10
10
|
type MessagesData = Record<string, AstNode[] | FullFormatJsNode[]>;
|
|
11
|
-
export interface IntlMessageGetterAdditions {
|
|
12
|
-
onChange(callback: () => void): () => void;
|
|
13
|
-
}
|
|
14
11
|
|
|
15
|
-
export
|
|
16
|
-
(locale: LocaleId): InternalIntlMessage;
|
|
17
|
-
}
|
|
12
|
+
export type IntlMessageGetter = (this: MessageLoader, locale: LocaleId) => InternalIntlMessage;
|
|
18
13
|
|
|
19
14
|
export type LocaleId = string;
|
|
20
15
|
|
|
@@ -191,14 +186,18 @@ export class MessageLoader {
|
|
|
191
186
|
* for `get` with the that key as the first argument, allowing consumers to
|
|
192
187
|
* just call the function with a locale to retrieve the translated message
|
|
193
188
|
* for that key.
|
|
189
|
+
*
|
|
190
|
+
* This method is provided as a way to generate binds _at runtime_, but for
|
|
191
|
+
* very-large messages files (e.g., thousands of messages), this can be a
|
|
192
|
+
* non-negligible cost. Where feasible, consider generating these binds
|
|
193
|
+
* at build/bundle time, especially in cases where they can be substantially
|
|
194
|
+
* minified (i.e., Hermes bytecode). This is provided automatically as an
|
|
195
|
+
* option when using one of `@discord/intl`'s transformers.
|
|
194
196
|
*/
|
|
195
197
|
getBinds(): Record<string, IntlMessageGetter> {
|
|
196
|
-
const onChange = this.onChange.bind(this);
|
|
197
198
|
const result: Record<string, IntlMessageGetter> = {};
|
|
198
199
|
for (const key of this.messageKeys) {
|
|
199
|
-
|
|
200
|
-
bound.onChange = onChange;
|
|
201
|
-
result[key] = bound;
|
|
200
|
+
result[key] = this.get.bind(this, key);
|
|
202
201
|
}
|
|
203
202
|
|
|
204
203
|
return result;
|
package/src/types.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { InternalIntlMessage } from './message';
|
|
2
|
-
import type { IntlMessageGetterAdditions } from './message-loader';
|
|
3
2
|
import { FormatBuilderConstructor } from './format';
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -42,7 +41,7 @@ export type IntlTime = string | number | Date | null | undefined;
|
|
|
42
41
|
export type PlainIntlMessage = string;
|
|
43
42
|
export type AnyIntlMessage = PlainIntlMessage | InternalIntlMessage;
|
|
44
43
|
|
|
45
|
-
export interface IntlMessageGetter
|
|
44
|
+
export interface IntlMessageGetter {
|
|
46
45
|
(locale: string): InternalIntlMessage | PlainIntlMessage;
|
|
47
46
|
}
|
|
48
47
|
|
|
@@ -52,8 +51,7 @@ export interface IntlMessageGetter extends IntlMessageGetterAdditions {
|
|
|
52
51
|
* value types that are required to format the message, or `{}` to represent
|
|
53
52
|
* that there are no values required and the message is a plain string.
|
|
54
53
|
*/
|
|
55
|
-
export interface TypedIntlMessageGetter<FormatValues extends object>
|
|
56
|
-
extends IntlMessageGetterAdditions {
|
|
54
|
+
export interface TypedIntlMessageGetter<FormatValues extends object> {
|
|
57
55
|
// TODO: This is lossy and unfortunate that typing can't be propagated
|
|
58
56
|
// to the returned message type, but doing so causes problems with
|
|
59
57
|
// contravariance of the type. When returning a message getter from a
|