@discord/intl 0.13.0 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/format.d.ts +3 -3
- package/dist/format.js +7 -0
- package/dist/formatters/ast.d.ts +3 -16
- package/dist/formatters/ast.js +2 -12
- package/dist/formatters/react.js +0 -2
- package/package.json +2 -2
- package/src/format.ts +15 -4
- package/src/formatters/ast.ts +5 -19
- package/src/formatters/react.ts +1 -3
package/dist/format.d.ts
CHANGED
|
@@ -20,12 +20,12 @@ import { AstNode } from '@discord/intl-ast';
|
|
|
20
20
|
import { Formatters } from 'intl-messageformat';
|
|
21
21
|
import type { FormatConfig } from './format-config';
|
|
22
22
|
import type { RichTextTagNames } from './types';
|
|
23
|
-
export declare abstract class FormatBuilder<Result> {
|
|
23
|
+
export declare abstract class FormatBuilder<Result, ObjectType = Result extends object ? Result : never> {
|
|
24
24
|
abstract pushRichTextTag(tag: RichTextTagNames, children: Result[], control: Result[]): void;
|
|
25
25
|
abstract pushLiteralText(text: string): void;
|
|
26
|
-
abstract pushObject(value:
|
|
26
|
+
abstract pushObject(value: ObjectType): void;
|
|
27
27
|
abstract finish(): Result[];
|
|
28
28
|
}
|
|
29
29
|
export type FormatBuilderConstructor<Result> = new () => FormatBuilder<Result>;
|
|
30
|
-
export declare function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>(builder: Builder, nodes: AstNode[], locales: string | string[], formatters: Formatters, formatConfig: FormatConfig, values?: Record<string, string | object>, currentPluralValue?: number, originalMessage?: string): void;
|
|
30
|
+
export declare function bindFormatValuesWithBuilder<T, ObjectType, Builder extends FormatBuilder<T, ObjectType>>(builder: Builder, nodes: AstNode[], locales: string | string[], formatters: Formatters, formatConfig: FormatConfig, values?: Record<string, string | object>, currentPluralValue?: number, originalMessage?: string): void;
|
|
31
31
|
export declare function bindFormatValues<Result>(Builder: FormatBuilderConstructor<Result>, nodes: string | AstNode[], locales: string | string[], formatters: Formatters, formatConfig: FormatConfig, values?: Record<string, string | object>, currentPluralValue?: number): Result[];
|
package/dist/format.js
CHANGED
|
@@ -67,6 +67,13 @@ function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, format
|
|
|
67
67
|
const value = values[variableName];
|
|
68
68
|
switch (nodeType) {
|
|
69
69
|
case intl_ast_1.FormatJsNodeType.Argument:
|
|
70
|
+
// `function` here captures ReactNodes, which can be functions that
|
|
71
|
+
// return elements. Basically everything else fits in the `object`
|
|
72
|
+
// type, and the generic type requires that an explicit ObjectType
|
|
73
|
+
// be specified for cases where it's not. That means there's an
|
|
74
|
+
// escape hatch that _might_ break this, but it would have to be
|
|
75
|
+
// intentionally set by internal code to function that way, so we'll
|
|
76
|
+
// operate on a promise that it won't for now.
|
|
70
77
|
if (typeof value === 'object' || typeof value === 'function') {
|
|
71
78
|
builder.pushObject(value);
|
|
72
79
|
}
|
package/dist/formatters/ast.d.ts
CHANGED
|
@@ -12,17 +12,7 @@ export declare enum RichTextNodeType {
|
|
|
12
12
|
Strikethrough = "s",
|
|
13
13
|
Code = "inlineCode",
|
|
14
14
|
Link = "link",
|
|
15
|
-
Paragraph = "paragraph"
|
|
16
|
-
/**
|
|
17
|
-
* A special extension for when the value of a placeholder is an object.
|
|
18
|
-
* Rather than casting to a string here, the object is preserved as-is for a
|
|
19
|
-
* future formatter to render as appropriate (i.e., using an object as a
|
|
20
|
-
* value when formatting to an AST should keep that object structure so that
|
|
21
|
-
* the final AST is accurate for what the user expects, but when rendering to
|
|
22
|
-
* a plain string, the final formatter can just cast that object to a string
|
|
23
|
-
* using its `toString` method or some other mechanism).
|
|
24
|
-
*/
|
|
25
|
-
Object = "object"
|
|
15
|
+
Paragraph = "paragraph"
|
|
26
16
|
}
|
|
27
17
|
interface RichTextNodeBase<ContentType> {
|
|
28
18
|
type: RichTextNodeType;
|
|
@@ -48,12 +38,9 @@ interface RichTextParagraphNode extends RichTextNodeBase<RichTextNode[]> {
|
|
|
48
38
|
}
|
|
49
39
|
interface RichTextLinkNode extends RichTextNodeBase<RichTextNode[]> {
|
|
50
40
|
type: RichTextNodeType.Link;
|
|
51
|
-
target:
|
|
41
|
+
target: object;
|
|
52
42
|
}
|
|
53
|
-
|
|
54
|
-
type: RichTextNodeType.Object;
|
|
55
|
-
}
|
|
56
|
-
export type RichTextNode = RichTextTextNode | RichTextStrongNode | RichTextEmphasisNode | RichTextStrikethroughNode | RichTextCodeNode | RichTextParagraphNode | RichTextLinkNode | RichTextObjectNode;
|
|
43
|
+
export type RichTextNode = RichTextTextNode | RichTextStrongNode | RichTextEmphasisNode | RichTextStrikethroughNode | RichTextCodeNode | RichTextParagraphNode | RichTextLinkNode;
|
|
57
44
|
/**
|
|
58
45
|
* Format the given message in the current locale with the provided values.
|
|
59
46
|
* The returned values is _always_ an Array of parts, even if the message is
|
package/dist/formatters/ast.js
CHANGED
|
@@ -15,16 +15,6 @@ var RichTextNodeType;
|
|
|
15
15
|
RichTextNodeType["Code"] = "inlineCode";
|
|
16
16
|
RichTextNodeType["Link"] = "link";
|
|
17
17
|
RichTextNodeType["Paragraph"] = "paragraph";
|
|
18
|
-
/**
|
|
19
|
-
* A special extension for when the value of a placeholder is an object.
|
|
20
|
-
* Rather than casting to a string here, the object is preserved as-is for a
|
|
21
|
-
* future formatter to render as appropriate (i.e., using an object as a
|
|
22
|
-
* value when formatting to an AST should keep that object structure so that
|
|
23
|
-
* the final AST is accurate for what the user expects, but when rendering to
|
|
24
|
-
* a plain string, the final formatter can just cast that object to a string
|
|
25
|
-
* using its `toString` method or some other mechanism).
|
|
26
|
-
*/
|
|
27
|
-
RichTextNodeType["Object"] = "object";
|
|
28
18
|
})(RichTextNodeType || (exports.RichTextNodeType = RichTextNodeType = {}));
|
|
29
19
|
const AST_RICH_TEXT_ELEMENTS = {
|
|
30
20
|
$b: (content) => ({ type: RichTextNodeType.Strong, content }),
|
|
@@ -33,7 +23,7 @@ const AST_RICH_TEXT_ELEMENTS = {
|
|
|
33
23
|
$code: (content) => ({ type: RichTextNodeType.Code, content }),
|
|
34
24
|
$link: (content, _, [target]) => ({
|
|
35
25
|
type: RichTextNodeType.Link,
|
|
36
|
-
target
|
|
26
|
+
target,
|
|
37
27
|
content,
|
|
38
28
|
}),
|
|
39
29
|
$p: (content) => ({ type: RichTextNodeType.Paragraph, content }),
|
|
@@ -65,7 +55,7 @@ class AstBuilder extends format_1.FormatBuilder {
|
|
|
65
55
|
}
|
|
66
56
|
}
|
|
67
57
|
pushObject(value) {
|
|
68
|
-
this.result.push(
|
|
58
|
+
this.result.push(value);
|
|
69
59
|
}
|
|
70
60
|
finish() {
|
|
71
61
|
return this.result;
|
package/dist/formatters/react.js
CHANGED
|
@@ -41,8 +41,6 @@ function createReactBuilder(richTextElements) {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
pushObject(value) {
|
|
44
|
-
// @ts-expect-error this is technically invalid, but we'll just assume that if a format
|
|
45
|
-
// returns an object, it'll be acting as some form of ReactNode.
|
|
46
44
|
this.result.push(value);
|
|
47
45
|
}
|
|
48
46
|
finish() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@discord/intl",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Client runtime for managing messages and translations in a React project.",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"@formatjs/intl": "^2.10.1",
|
|
24
24
|
"@intrnl/xxhash64": "^0.1.2",
|
|
25
25
|
"intl-messageformat": "^10.5.11",
|
|
26
|
-
"@discord/intl-ast": "0.13.
|
|
26
|
+
"@discord/intl-ast": "0.13.1"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@swc/cli": "^0.3.12",
|
package/src/format.ts
CHANGED
|
@@ -36,16 +36,20 @@ function isRichTextTag(name: string) {
|
|
|
36
36
|
return name[0] === '$';
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
export abstract class FormatBuilder<Result> {
|
|
39
|
+
export abstract class FormatBuilder<Result, ObjectType = Result extends object ? Result : never> {
|
|
40
40
|
abstract pushRichTextTag(tag: RichTextTagNames, children: Result[], control: Result[]): void;
|
|
41
41
|
abstract pushLiteralText(text: string): void;
|
|
42
|
-
abstract pushObject(value:
|
|
42
|
+
abstract pushObject(value: ObjectType): void;
|
|
43
43
|
abstract finish(): Result[];
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export type FormatBuilderConstructor<Result> = new () => FormatBuilder<Result>;
|
|
47
47
|
|
|
48
|
-
export function bindFormatValuesWithBuilder<
|
|
48
|
+
export function bindFormatValuesWithBuilder<
|
|
49
|
+
T,
|
|
50
|
+
ObjectType,
|
|
51
|
+
Builder extends FormatBuilder<T, ObjectType>,
|
|
52
|
+
>(
|
|
49
53
|
builder: Builder,
|
|
50
54
|
nodes: AstNode[],
|
|
51
55
|
locales: string | string[],
|
|
@@ -89,8 +93,15 @@ export function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>
|
|
|
89
93
|
const value = values[variableName];
|
|
90
94
|
switch (nodeType) {
|
|
91
95
|
case FormatJsNodeType.Argument:
|
|
96
|
+
// `function` here captures ReactNodes, which can be functions that
|
|
97
|
+
// return elements. Basically everything else fits in the `object`
|
|
98
|
+
// type, and the generic type requires that an explicit ObjectType
|
|
99
|
+
// be specified for cases where it's not. That means there's an
|
|
100
|
+
// escape hatch that _might_ break this, but it would have to be
|
|
101
|
+
// intentionally set by internal code to function that way, so we'll
|
|
102
|
+
// operate on a promise that it won't for now.
|
|
92
103
|
if (typeof value === 'object' || typeof value === 'function') {
|
|
93
|
-
builder.pushObject(value);
|
|
104
|
+
builder.pushObject(value as ObjectType);
|
|
94
105
|
} else {
|
|
95
106
|
// Taken from FormatJS: non-objects (strings, numbers, and falsy
|
|
96
107
|
// values) all get cast to strings immediately as literal nodes.
|
package/src/formatters/ast.ts
CHANGED
|
@@ -25,16 +25,6 @@ export enum RichTextNodeType {
|
|
|
25
25
|
Code = 'inlineCode',
|
|
26
26
|
Link = 'link',
|
|
27
27
|
Paragraph = 'paragraph',
|
|
28
|
-
/**
|
|
29
|
-
* A special extension for when the value of a placeholder is an object.
|
|
30
|
-
* Rather than casting to a string here, the object is preserved as-is for a
|
|
31
|
-
* future formatter to render as appropriate (i.e., using an object as a
|
|
32
|
-
* value when formatting to an AST should keep that object structure so that
|
|
33
|
-
* the final AST is accurate for what the user expects, but when rendering to
|
|
34
|
-
* a plain string, the final formatter can just cast that object to a string
|
|
35
|
-
* using its `toString` method or some other mechanism).
|
|
36
|
-
*/
|
|
37
|
-
Object = 'object',
|
|
38
28
|
}
|
|
39
29
|
|
|
40
30
|
interface RichTextNodeBase<ContentType> {
|
|
@@ -61,10 +51,7 @@ interface RichTextParagraphNode extends RichTextNodeBase<RichTextNode[]> {
|
|
|
61
51
|
}
|
|
62
52
|
interface RichTextLinkNode extends RichTextNodeBase<RichTextNode[]> {
|
|
63
53
|
type: RichTextNodeType.Link;
|
|
64
|
-
target:
|
|
65
|
-
}
|
|
66
|
-
interface RichTextObjectNode extends RichTextNodeBase<object> {
|
|
67
|
-
type: RichTextNodeType.Object;
|
|
54
|
+
target: object;
|
|
68
55
|
}
|
|
69
56
|
|
|
70
57
|
export type RichTextNode =
|
|
@@ -74,8 +61,7 @@ export type RichTextNode =
|
|
|
74
61
|
| RichTextStrikethroughNode
|
|
75
62
|
| RichTextCodeNode
|
|
76
63
|
| RichTextParagraphNode
|
|
77
|
-
| RichTextLinkNode
|
|
78
|
-
| RichTextObjectNode;
|
|
64
|
+
| RichTextLinkNode;
|
|
79
65
|
|
|
80
66
|
const AST_RICH_TEXT_ELEMENTS: RichTextFormattingMap<AstFunctionTypes['hook']> = {
|
|
81
67
|
$b: (content) => ({ type: RichTextNodeType.Strong, content }),
|
|
@@ -84,7 +70,7 @@ const AST_RICH_TEXT_ELEMENTS: RichTextFormattingMap<AstFunctionTypes['hook']> =
|
|
|
84
70
|
$code: (content) => ({ type: RichTextNodeType.Code, content }),
|
|
85
71
|
$link: (content, _, [target]) => ({
|
|
86
72
|
type: RichTextNodeType.Link,
|
|
87
|
-
target
|
|
73
|
+
target,
|
|
88
74
|
content,
|
|
89
75
|
}),
|
|
90
76
|
$p: (content) => ({ type: RichTextNodeType.Paragraph, content }),
|
|
@@ -114,8 +100,8 @@ class AstBuilder extends FormatBuilder<RichTextNode> {
|
|
|
114
100
|
}
|
|
115
101
|
}
|
|
116
102
|
|
|
117
|
-
pushObject(value:
|
|
118
|
-
this.result.push(
|
|
103
|
+
pushObject(value: RichTextNode) {
|
|
104
|
+
this.result.push(value);
|
|
119
105
|
}
|
|
120
106
|
|
|
121
107
|
finish(): RichTextNode[] {
|
package/src/formatters/react.ts
CHANGED
|
@@ -66,9 +66,7 @@ function createReactBuilder(richTextElements: RichTextFormattingMap<ReactFunctio
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
pushObject(value:
|
|
70
|
-
// @ts-expect-error this is technically invalid, but we'll just assume that if a format
|
|
71
|
-
// returns an object, it'll be acting as some form of ReactNode.
|
|
69
|
+
pushObject(value: React.ReactNode) {
|
|
72
70
|
this.result.push(value);
|
|
73
71
|
}
|
|
74
72
|
|