@discord/intl 0.1.3-rc.0 → 0.2.0
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 +30 -0
- package/dist/format.js +214 -0
- package/dist/formatters/ast.d.ts +67 -0
- package/dist/formatters/ast.js +148 -0
- package/dist/formatters/index.d.ts +4 -0
- package/dist/formatters/index.js +14 -0
- package/dist/formatters/markdown.d.ts +13 -0
- package/dist/formatters/markdown.js +80 -0
- package/dist/formatters/react.d.ts +28 -0
- package/dist/formatters/react.js +111 -0
- package/dist/formatters/string.d.ts +21 -0
- package/dist/formatters/string.js +90 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.js +16 -3
- package/dist/intl-manager.d.ts +25 -56
- package/dist/intl-manager.js +58 -79
- package/dist/keyless-json.d.ts +8 -1
- package/dist/message-loader.d.ts +2 -3
- package/dist/message.d.ts +6 -27
- package/dist/message.js +29 -78
- package/dist/types.d.ts +41 -45
- package/package.json +1 -2
- package/src/format.ts +224 -0
- package/src/formatters/ast.ts +155 -0
- package/src/formatters/index.ts +9 -0
- package/src/formatters/markdown.ts +54 -0
- package/src/formatters/react.ts +100 -0
- package/src/formatters/string.ts +62 -0
- package/src/index.ts +6 -6
- package/src/intl-manager.ts +70 -148
- package/src/keyless-json.ts +7 -0
- package/src/message-loader.ts +2 -4
- package/src/message.ts +16 -75
- package/src/types.d.ts +41 -45
- package/dist/react.d.ts +0 -38
- package/dist/react.js +0 -80
- package/src/react.ts +0 -80
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
18
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
19
|
+
if (!m) return o;
|
|
20
|
+
var i = m.call(o), r, ar = [], e;
|
|
21
|
+
try {
|
|
22
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
23
|
+
}
|
|
24
|
+
catch (error) { e = { error: error }; }
|
|
25
|
+
finally {
|
|
26
|
+
try {
|
|
27
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
28
|
+
}
|
|
29
|
+
finally { if (e) throw e.error; }
|
|
30
|
+
}
|
|
31
|
+
return ar;
|
|
32
|
+
};
|
|
33
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
34
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
35
|
+
if (ar || !(i in from)) {
|
|
36
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
37
|
+
ar[i] = from[i];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
41
|
+
};
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.reactFormatter = exports.DEFAULT_REACT_RICH_TEXT_ELEMENTS = void 0;
|
|
44
|
+
exports.formatReact = formatReact;
|
|
45
|
+
exports.makeReactFormatter = makeReactFormatter;
|
|
46
|
+
var React = require("react");
|
|
47
|
+
var format_1 = require("../format");
|
|
48
|
+
var h = React.createElement;
|
|
49
|
+
exports.DEFAULT_REACT_RICH_TEXT_ELEMENTS = {
|
|
50
|
+
$_: function () { return ''; },
|
|
51
|
+
$b: function (content) { return h('strong', undefined, content); },
|
|
52
|
+
$code: function (content) { return h('code', undefined, content); },
|
|
53
|
+
$i: function (content) { return h('em', undefined, content); },
|
|
54
|
+
// $link will always be [href, <empty>, ...content]
|
|
55
|
+
$link: function (_a) {
|
|
56
|
+
var _b = __read(_a), href = _b[0], content = _b.slice(1);
|
|
57
|
+
return h('a', { href: href }, content);
|
|
58
|
+
},
|
|
59
|
+
$p: function (content) { return h('p', undefined, content); },
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Creates a new `FormatBuilder` class that constructs a React element tree
|
|
63
|
+
* from the message using the given `richTextElements` to apply formatting.
|
|
64
|
+
* This allows consumers to inject their own design system components and
|
|
65
|
+
* overrides for rendering elements like links, paragraphs, and code blocks.
|
|
66
|
+
* @param richTextElements
|
|
67
|
+
*/
|
|
68
|
+
function createReactBuilder(richTextElements) {
|
|
69
|
+
return /** @class */ (function (_super) {
|
|
70
|
+
__extends(class_1, _super);
|
|
71
|
+
function class_1() {
|
|
72
|
+
var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
|
|
73
|
+
_this.result = [];
|
|
74
|
+
return _this;
|
|
75
|
+
}
|
|
76
|
+
class_1.prototype.pushRichTextTag = function (tag, children) {
|
|
77
|
+
this.result.push(richTextElements[tag](children));
|
|
78
|
+
};
|
|
79
|
+
class_1.prototype.pushLiteralText = function (text) {
|
|
80
|
+
this.result.push(text);
|
|
81
|
+
};
|
|
82
|
+
class_1.prototype.pushObject = function (value) {
|
|
83
|
+
// @ts-expect-error this is technically invalid, but we'll just assume that if a format returns
|
|
84
|
+
// an object, it'll be acting as some form of ReactNode.
|
|
85
|
+
this.result.push(value);
|
|
86
|
+
};
|
|
87
|
+
class_1.prototype.finish = function () {
|
|
88
|
+
return this.result;
|
|
89
|
+
};
|
|
90
|
+
return class_1;
|
|
91
|
+
}(format_1.FormatBuilder));
|
|
92
|
+
}
|
|
93
|
+
function formatReact(message, values, Builder) {
|
|
94
|
+
if (typeof message === 'string') {
|
|
95
|
+
return React.createElement(React.Fragment, undefined, message);
|
|
96
|
+
}
|
|
97
|
+
var parts = this.bindFormatValues(Builder, message, values);
|
|
98
|
+
return React.createElement(React.Fragment, undefined, parts);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Create a new React formatter with the given rich text elements replacing the defaults. Use this
|
|
102
|
+
* function to inject custom components for things like links and paragraphs, which may be best
|
|
103
|
+
* suited to use components from a Design System or other library rather than native DOM elements.
|
|
104
|
+
*/
|
|
105
|
+
function makeReactFormatter(richTextElements) {
|
|
106
|
+
return {
|
|
107
|
+
format: formatReact,
|
|
108
|
+
builder: createReactBuilder(richTextElements),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
exports.reactFormatter = makeReactFormatter(exports.DEFAULT_REACT_RICH_TEXT_ELEMENTS);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format the given message with the provided values, removing any styling
|
|
3
|
+
* and non-textual content from the message, returning a plain string.
|
|
4
|
+
*/
|
|
5
|
+
import { AnyIntlMessage, FormatterImplementation, FunctionTypes, RichTextTagNames } from '../types';
|
|
6
|
+
import { FormatBuilder } from '../format';
|
|
7
|
+
import { IntlManager } from '../intl-manager';
|
|
8
|
+
/**
|
|
9
|
+
* Types for formatting functions when calling `bindFormatValues`, ensuring the
|
|
10
|
+
* functions always yield plain strings.
|
|
11
|
+
*/
|
|
12
|
+
export type StringFunctionTypes = FunctionTypes<string>;
|
|
13
|
+
export declare class StringBuilder extends FormatBuilder<string> {
|
|
14
|
+
result: string;
|
|
15
|
+
pushRichTextTag(tag: RichTextTagNames, children: string[]): void;
|
|
16
|
+
pushLiteralText(text: string): void;
|
|
17
|
+
pushObject(value: object): void;
|
|
18
|
+
finish(): string[];
|
|
19
|
+
}
|
|
20
|
+
export declare function formatToPlainString(this: IntlManager, message: AnyIntlMessage, values: object): string;
|
|
21
|
+
export declare const stringFormatter: FormatterImplementation<StringFunctionTypes, string>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
18
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
19
|
+
if (!m) return o;
|
|
20
|
+
var i = m.call(o), r, ar = [], e;
|
|
21
|
+
try {
|
|
22
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
23
|
+
}
|
|
24
|
+
catch (error) { e = { error: error }; }
|
|
25
|
+
finally {
|
|
26
|
+
try {
|
|
27
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
28
|
+
}
|
|
29
|
+
finally { if (e) throw e.error; }
|
|
30
|
+
}
|
|
31
|
+
return ar;
|
|
32
|
+
};
|
|
33
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
34
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
35
|
+
if (ar || !(i in from)) {
|
|
36
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
37
|
+
ar[i] = from[i];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
41
|
+
};
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.stringFormatter = exports.StringBuilder = void 0;
|
|
44
|
+
exports.formatToPlainString = formatToPlainString;
|
|
45
|
+
var format_1 = require("../format");
|
|
46
|
+
var StringBuilder = /** @class */ (function (_super) {
|
|
47
|
+
__extends(StringBuilder, _super);
|
|
48
|
+
function StringBuilder() {
|
|
49
|
+
var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
|
|
50
|
+
_this.result = '';
|
|
51
|
+
return _this;
|
|
52
|
+
}
|
|
53
|
+
StringBuilder.prototype.pushRichTextTag = function (tag, children) {
|
|
54
|
+
// Plain string formatting ignores rich text tags and just takes the
|
|
55
|
+
// visible content from the children. This means the `target` element
|
|
56
|
+
// of a link is ignored, otherwise all the children are just joined
|
|
57
|
+
// together directly.
|
|
58
|
+
if (tag === '$link') {
|
|
59
|
+
this.result += children.slice(1).join('');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
this.result += children.join('');
|
|
63
|
+
};
|
|
64
|
+
StringBuilder.prototype.pushLiteralText = function (text) {
|
|
65
|
+
this.result += text;
|
|
66
|
+
};
|
|
67
|
+
StringBuilder.prototype.pushObject = function (value) {
|
|
68
|
+
// Objects are only included in the result if they specify a toString value directly.
|
|
69
|
+
// Otherwise, they would be rendered as `[object Object]`, which is never helpful.
|
|
70
|
+
if ('toString' in value) {
|
|
71
|
+
this.result += value.toString();
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
StringBuilder.prototype.finish = function () {
|
|
75
|
+
return [this.result];
|
|
76
|
+
};
|
|
77
|
+
return StringBuilder;
|
|
78
|
+
}(format_1.FormatBuilder));
|
|
79
|
+
exports.StringBuilder = StringBuilder;
|
|
80
|
+
function formatToPlainString(message, values) {
|
|
81
|
+
if (typeof message === 'string')
|
|
82
|
+
return message;
|
|
83
|
+
var result = this.bindFormatValues(StringBuilder, message, values);
|
|
84
|
+
// StringBuilder always creates a single element array with the string value.
|
|
85
|
+
return result[0];
|
|
86
|
+
}
|
|
87
|
+
exports.stringFormatter = {
|
|
88
|
+
format: formatToPlainString,
|
|
89
|
+
builder: StringBuilder,
|
|
90
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
export { IntlManager, createLoader, DEFAULT_LOCALE } from './intl-manager';
|
|
4
|
-
export
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { RichTextNode } from './formatters';
|
|
3
|
+
export { IntlManager, createLoader, DEFAULT_LOCALE, type FormatFunction } from './intl-manager';
|
|
4
|
+
export * from './formatters';
|
|
5
5
|
export type * from './types.d.ts';
|
|
6
6
|
/**
|
|
7
7
|
* A type representing any message that has been formatted using one of the
|
|
@@ -18,7 +18,7 @@ export type * from './types.d.ts';
|
|
|
18
18
|
* intl message, even if the actual value comes from elsewhere (like a
|
|
19
19
|
* user-generated string).
|
|
20
20
|
*/
|
|
21
|
-
export type ReactIntlMessage = string |
|
|
21
|
+
export type ReactIntlMessage = string | React.ReactElement;
|
|
22
22
|
/**
|
|
23
23
|
* The return value of `formatToParts` from `@discord/intl`, this type
|
|
24
24
|
* represents any AST structure for a message rendered using this system.
|
|
@@ -29,4 +29,4 @@ export type ReactIntlMessage = string | ReturnType<IntlManagerReact<any>['format
|
|
|
29
29
|
* from a call to `formatToParts`, meaning they are intended to be fully static
|
|
30
30
|
* structures passed around for custom rendering functions to use.
|
|
31
31
|
*/
|
|
32
|
-
export type IntlMessageAst =
|
|
32
|
+
export type IntlMessageAst = RichTextNode;
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
17
|
+
exports.DEFAULT_LOCALE = exports.createLoader = exports.IntlManager = void 0;
|
|
4
18
|
var intl_manager_1 = require("./intl-manager");
|
|
5
19
|
Object.defineProperty(exports, "IntlManager", { enumerable: true, get: function () { return intl_manager_1.IntlManager; } });
|
|
6
20
|
Object.defineProperty(exports, "createLoader", { enumerable: true, get: function () { return intl_manager_1.createLoader; } });
|
|
7
21
|
Object.defineProperty(exports, "DEFAULT_LOCALE", { enumerable: true, get: function () { return intl_manager_1.DEFAULT_LOCALE; } });
|
|
8
|
-
|
|
9
|
-
Object.defineProperty(exports, "IntlManagerReact", { enumerable: true, get: function () { return react_1.IntlManagerReact; } });
|
|
22
|
+
__exportStar(require("./formatters"), exports);
|
package/dist/intl-manager.d.ts
CHANGED
|
@@ -1,34 +1,36 @@
|
|
|
1
1
|
import { IntlShape } from '@formatjs/intl';
|
|
2
2
|
import { LocaleId, LocaleImportMap, MessageLoader } from './message-loader';
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* functions yield value AST nodes.
|
|
7
|
-
*/
|
|
8
|
-
type AstFunctionTypes = {
|
|
9
|
-
link: undefined | object | ((children: object) => Array<string | any>);
|
|
10
|
-
hook: undefined | object | ((children: object) => Array<string | any>);
|
|
11
|
-
handler: undefined | object | ((children: object) => Array<string | any>);
|
|
12
|
-
};
|
|
3
|
+
import type { FormatterImplementation, IntlMessageGetter, RequiredFormatValues, TypedIntlMessageGetter } from './types';
|
|
4
|
+
import { InternalIntlMessage } from './message';
|
|
5
|
+
import { FormatBuilderConstructor } from './format';
|
|
13
6
|
/**
|
|
14
7
|
* Fallback locale used for all internationalization when an operation in the
|
|
15
8
|
* requested locale is not possible.
|
|
16
9
|
*/
|
|
17
10
|
export declare const DEFAULT_LOCALE: string;
|
|
18
|
-
|
|
11
|
+
type FormatterReturnType<F extends FormatterImplementation<any, any>> = F extends FormatterImplementation<any, infer Return> ? Return : never;
|
|
12
|
+
type FormatterFunctionTypes<F extends FormatterImplementation<any, any>> = F extends FormatterImplementation<infer Functions, any> ? Functions : never;
|
|
13
|
+
export type FormatFunction<F extends FormatterImplementation<any, any>> = <T extends IntlMessageGetter>(this: IntlManager, message: T, values: RequiredFormatValues<T, FormatterFunctionTypes<F>>) => FormatterReturnType<F>;
|
|
14
|
+
type ThisWithFormatters<This, T extends Record<string, FormatterImplementation<any, any>>> = This & {
|
|
15
|
+
[K in keyof T]: FormatFunction<T[K]>;
|
|
16
|
+
};
|
|
17
|
+
export declare class IntlManager {
|
|
19
18
|
defaultLocale: string;
|
|
20
19
|
currentLocale: string;
|
|
21
20
|
intl: IntlShape;
|
|
21
|
+
_localeSubscriptions: Set<(locale: string) => void>;
|
|
22
|
+
constructor(defaultLocale?: string);
|
|
22
23
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* for a specific call, either by overriding the value or by calling a
|
|
26
|
-
* dedicated method like `formatToPlainString` which will remove all
|
|
27
|
-
* rich elements from the string and return only the plain text result.
|
|
24
|
+
* Add a set of formatter implementations to this manager, making each available as a direct
|
|
25
|
+
* property
|
|
28
26
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
withFormatters<const T extends Record<string, FormatterImplementation<any, any>>>(formatters: T): ThisWithFormatters<this, T>;
|
|
28
|
+
/**
|
|
29
|
+
* Return a new function bound to this manager that uses the given `FormatterImplementation` to
|
|
30
|
+
* format a message after it has been resolved for the current locale and potentially processed in
|
|
31
|
+
* other ways by the manager.
|
|
32
|
+
*/
|
|
33
|
+
makeFormatFunction<F extends FormatterImplementation<any, any>>({ format, builder, }: F): FormatFunction<FormatterReturnType<F>>;
|
|
32
34
|
/**
|
|
33
35
|
* Set the locale for this package to use. This is a global change, and all
|
|
34
36
|
* methods on this object will use this locale for formatting.
|
|
@@ -40,44 +42,11 @@ export declare class IntlManager<DefaultElements extends RichTextElementMap, Fun
|
|
|
40
42
|
*/
|
|
41
43
|
onLocaleChange: (callback: (locale: string) => void) => () => boolean;
|
|
42
44
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* a simple string value.
|
|
46
|
-
*
|
|
47
|
-
* This function is the basis of how messages are normally formatted, and can
|
|
48
|
-
* be used anywhere. However, it is not reactive and only functions on the
|
|
49
|
-
* data that is currently loaded and known. For a reactive function that
|
|
50
|
-
* automatically updates when the locale changes or when new data is loaded,
|
|
51
|
-
* use `format`, which will wrap the formatting in a React component that
|
|
52
|
-
* subscribes to the current locale and state of loaded messages.
|
|
53
|
-
*/
|
|
54
|
-
formatToParts<T extends TypedIntlMessageGetter<undefined>>(message: T): Array<string | any>;
|
|
55
|
-
formatToParts<T extends IntlMessageGetter>(message: T, values: RequiredFormatValues<T, DefaultElements, AstFunctionTypes>): Array<string | any>;
|
|
56
|
-
/**
|
|
57
|
-
* For messages with no formatting values (i.e., plain strings, they can skip
|
|
58
|
-
* a majority of the processing work and just resolve the message itself for
|
|
59
|
-
* the current locale, then return the plain string directly.
|
|
60
|
-
*
|
|
61
|
-
* This is separate from `formatToPlainString`, which still allows for
|
|
62
|
-
* formatting variables and other elements but reduces the output to only
|
|
63
|
-
* include textual elements in a plain string.
|
|
64
|
-
*/
|
|
65
|
-
string(message: TypedIntlMessageGetter<undefined>): string;
|
|
66
|
-
/**
|
|
67
|
-
* Format the given message with the provided values, removing any styling
|
|
68
|
-
* and non-textual content from the message, returning a plain string.
|
|
69
|
-
*/
|
|
70
|
-
formatToPlainString<T extends TypedIntlMessageGetter<undefined>>(message: T): string;
|
|
71
|
-
formatToPlainString<T extends IntlMessageGetter>(message: T, values: RequiredFormatValues<T, DefaultElements, FunctionTypes>): string;
|
|
72
|
-
/**
|
|
73
|
-
* Similar to `formatToPlainString`, format the given message with the provided
|
|
74
|
-
* values, but convert all rich text formatting back to Markdown syntax rather
|
|
75
|
-
* than rendering the actual rich content. The result is a plain string that
|
|
76
|
-
* can be sent through a separate Markdown renderer to get an equivalent
|
|
77
|
-
* result to formatting this message directly.
|
|
45
|
+
* For static messages with no rich text and no dynamic placeholders, use this method to
|
|
46
|
+
* immediately return the plain string value of the message in the current locale.
|
|
78
47
|
*/
|
|
79
|
-
|
|
80
|
-
|
|
48
|
+
string<T extends TypedIntlMessageGetter<undefined>>(message: T): string;
|
|
49
|
+
bindFormatValues<T>(Builder: FormatBuilderConstructor<T>, message: InternalIntlMessage, values: Record<string, any>): T[];
|
|
81
50
|
}
|
|
82
51
|
/**
|
|
83
52
|
* Create a new MessageLoader, which handles lazily loading messages for
|
package/dist/intl-manager.js
CHANGED
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
2
|
var __values = (this && this.__values) || function(o) {
|
|
14
3
|
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
15
4
|
if (m) return m.call(o);
|
|
@@ -21,19 +10,36 @@ var __values = (this && this.__values) || function(o) {
|
|
|
21
10
|
};
|
|
22
11
|
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
23
12
|
};
|
|
13
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
14
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
15
|
+
if (!m) return o;
|
|
16
|
+
var i = m.call(o), r, ar = [], e;
|
|
17
|
+
try {
|
|
18
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
19
|
+
}
|
|
20
|
+
catch (error) { e = { error: error }; }
|
|
21
|
+
finally {
|
|
22
|
+
try {
|
|
23
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
24
|
+
}
|
|
25
|
+
finally { if (e) throw e.error; }
|
|
26
|
+
}
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
24
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
30
|
exports.IntlManager = exports.DEFAULT_LOCALE = void 0;
|
|
26
31
|
exports.createLoader = createLoader;
|
|
27
32
|
var intl_1 = require("@formatjs/intl");
|
|
28
33
|
var intl_messageformat_1 = require("intl-messageformat");
|
|
29
34
|
var message_loader_1 = require("./message-loader");
|
|
35
|
+
var format_1 = require("./format");
|
|
30
36
|
/**
|
|
31
37
|
* Fallback locale used for all internationalization when an operation in the
|
|
32
38
|
* requested locale is not possible.
|
|
33
39
|
*/
|
|
34
40
|
exports.DEFAULT_LOCALE = 'en-US';
|
|
35
41
|
var IntlManager = /** @class */ (function () {
|
|
36
|
-
function IntlManager(defaultLocale
|
|
42
|
+
function IntlManager(defaultLocale) {
|
|
37
43
|
if (defaultLocale === void 0) { defaultLocale = exports.DEFAULT_LOCALE; }
|
|
38
44
|
var _this = this;
|
|
39
45
|
/**
|
|
@@ -50,24 +56,18 @@ var IntlManager = /** @class */ (function () {
|
|
|
50
56
|
defaultLocale: defaultLocale,
|
|
51
57
|
locale: defaultLocale,
|
|
52
58
|
});
|
|
53
|
-
this.defaultRichTextElements = defaultRichTextElements;
|
|
54
59
|
this._localeSubscriptions = new Set();
|
|
55
60
|
}
|
|
56
61
|
/**
|
|
57
|
-
*
|
|
58
|
-
*
|
|
62
|
+
* Add a set of formatter implementations to this manager, making each available as a direct
|
|
63
|
+
* property
|
|
59
64
|
*/
|
|
60
|
-
IntlManager.prototype.
|
|
61
|
-
this.currentLocale = locale;
|
|
62
|
-
this.intl = (0, intl_1.createIntl)({ defaultLocale: this.defaultLocale, locale: locale });
|
|
63
|
-
this.emitLocaleChange(locale);
|
|
64
|
-
};
|
|
65
|
-
IntlManager.prototype.emitLocaleChange = function (locale) {
|
|
65
|
+
IntlManager.prototype.withFormatters = function (formatters) {
|
|
66
66
|
var e_1, _a;
|
|
67
67
|
try {
|
|
68
|
-
for (var _b = __values(
|
|
69
|
-
var
|
|
70
|
-
|
|
68
|
+
for (var _b = __values(Object.entries(formatters)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
69
|
+
var _d = __read(_c.value, 2), name = _d[0], formatter = _d[1];
|
|
70
|
+
this[name] = this.makeFormatFunction(formatter);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
@@ -77,77 +77,56 @@ var IntlManager = /** @class */ (function () {
|
|
|
77
77
|
}
|
|
78
78
|
finally { if (e_1) throw e_1.error; }
|
|
79
79
|
}
|
|
80
|
+
return this;
|
|
80
81
|
};
|
|
81
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Return a new function bound to this manager that uses the given `FormatterImplementation` to
|
|
84
|
+
* format a message after it has been resolved for the current locale and potentially processed in
|
|
85
|
+
* other ways by the manager.
|
|
86
|
+
*/
|
|
87
|
+
IntlManager.prototype.makeFormatFunction = function (_a) {
|
|
88
|
+
var _this = this;
|
|
89
|
+
var format = _a.format, builder = _a.builder;
|
|
90
|
+
var formatter = format.bind(this);
|
|
91
|
+
return function (message, values) {
|
|
92
|
+
return formatter(message(_this.currentLocale), values, builder);
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Set the locale for this package to use. This is a global change, and all
|
|
97
|
+
* methods on this object will use this locale for formatting.
|
|
98
|
+
*/
|
|
99
|
+
IntlManager.prototype.setLocale = function (locale) {
|
|
100
|
+
this.currentLocale = locale;
|
|
101
|
+
this.intl = (0, intl_1.createIntl)({ defaultLocale: this.defaultLocale, locale: locale });
|
|
102
|
+
this.emitLocaleChange(locale);
|
|
103
|
+
};
|
|
104
|
+
IntlManager.prototype.emitLocaleChange = function (locale) {
|
|
82
105
|
var e_2, _a;
|
|
83
|
-
if (typeof message === 'string')
|
|
84
|
-
return [message];
|
|
85
|
-
var resolvedMessage = typeof message === 'function' ? message(this.currentLocale) : message;
|
|
86
|
-
if (typeof resolvedMessage === 'string')
|
|
87
|
-
return [resolvedMessage];
|
|
88
|
-
var resolvedValues = values != null
|
|
89
|
-
? __assign(__assign({}, this.defaultRichTextElements), values) : this.defaultRichTextElements;
|
|
90
|
-
var parts = resolvedMessage.formatToParts(this.intl.formatters, this.intl.formats, resolvedValues);
|
|
91
|
-
var result = [];
|
|
92
|
-
var inLiteral = false;
|
|
93
106
|
try {
|
|
94
|
-
for (var
|
|
95
|
-
var
|
|
96
|
-
|
|
97
|
-
// into single parts to reduce the number of nodes in the result. This
|
|
98
|
-
// condition will never be true on the first loop, ensuring that the
|
|
99
|
-
// array must at least have one entry before it attempts to concatenate
|
|
100
|
-
// onto that value again.
|
|
101
|
-
if (inLiteral && (inLiteral = part.type === intl_messageformat_1.PART_TYPE.literal)) {
|
|
102
|
-
result[result.length - 1] += part.value;
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
inLiteral = part.type === intl_messageformat_1.PART_TYPE.literal;
|
|
106
|
-
result.push(part.value);
|
|
107
|
+
for (var _b = __values(this._localeSubscriptions), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
108
|
+
var callback = _c.value;
|
|
109
|
+
callback(locale);
|
|
107
110
|
}
|
|
108
111
|
}
|
|
109
112
|
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
110
113
|
finally {
|
|
111
114
|
try {
|
|
112
|
-
if (
|
|
115
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
113
116
|
}
|
|
114
117
|
finally { if (e_2) throw e_2.error; }
|
|
115
118
|
}
|
|
116
|
-
return result;
|
|
117
119
|
};
|
|
118
120
|
/**
|
|
119
|
-
* For messages with no
|
|
120
|
-
*
|
|
121
|
-
* the current locale, then return the plain string directly.
|
|
122
|
-
*
|
|
123
|
-
* This is separate from `formatToPlainString`, which still allows for
|
|
124
|
-
* formatting variables and other elements but reduces the output to only
|
|
125
|
-
* include textual elements in a plain string.
|
|
121
|
+
* For static messages with no rich text and no dynamic placeholders, use this method to
|
|
122
|
+
* immediately return the plain string value of the message in the current locale.
|
|
126
123
|
*/
|
|
127
124
|
IntlManager.prototype.string = function (message) {
|
|
128
|
-
// TODO
|
|
129
|
-
return this.
|
|
130
|
-
};
|
|
131
|
-
IntlManager.prototype.formatToPlainString = function (message, values) {
|
|
132
|
-
if (typeof message === 'string')
|
|
133
|
-
return message;
|
|
134
|
-
var resolvedMessage = message(this.currentLocale);
|
|
135
|
-
if (typeof resolvedMessage === 'string')
|
|
136
|
-
return resolvedMessage;
|
|
137
|
-
// No need to pass in `defaultRichTextElements`, since the stylistic tags
|
|
138
|
-
// will be removed from the string anyway.
|
|
139
|
-
return resolvedMessage.formatToPlainString(this.intl.formatters, this.intl.formats, values);
|
|
125
|
+
// TODO: Figure out how to make this typing exact.
|
|
126
|
+
return message(this.currentLocale).message;
|
|
140
127
|
};
|
|
141
|
-
IntlManager.prototype.
|
|
142
|
-
|
|
143
|
-
if (typeof message === 'string')
|
|
144
|
-
return message;
|
|
145
|
-
var resolvedMessage = message(this.currentLocale);
|
|
146
|
-
if (typeof resolvedMessage === 'string')
|
|
147
|
-
return resolvedMessage;
|
|
148
|
-
// No need to pass in `defaultRichTextElements`, since the stylistic tags
|
|
149
|
-
// will be removed from the string anyway.
|
|
150
|
-
return resolvedMessage.formatToPlainString(this.intl.formatters, this.intl.formats, values);
|
|
128
|
+
IntlManager.prototype.bindFormatValues = function (Builder, message, values) {
|
|
129
|
+
return (0, format_1.bindFormatValues)(Builder, message.ast, [this.currentLocale, this.defaultLocale], this.intl.formatters, this.intl.formats, values);
|
|
151
130
|
};
|
|
152
131
|
return IntlManager;
|
|
153
132
|
}());
|
package/dist/keyless-json.d.ts
CHANGED
|
@@ -32,6 +32,13 @@ export interface FormatJsTime {
|
|
|
32
32
|
value: string;
|
|
33
33
|
style?: string;
|
|
34
34
|
}
|
|
35
|
+
export interface FormatJsSelect {
|
|
36
|
+
type: FormatJsNodeType.Select;
|
|
37
|
+
value: string;
|
|
38
|
+
options: Record<string, {
|
|
39
|
+
value: FormatJsNode[];
|
|
40
|
+
}>;
|
|
41
|
+
}
|
|
35
42
|
export type FormatJsPluralType = 'cardinal' | 'ordinal';
|
|
36
43
|
export interface FormatJsPlural {
|
|
37
44
|
type: FormatJsNodeType.Plural;
|
|
@@ -50,7 +57,7 @@ export interface FormatJsTag {
|
|
|
50
57
|
value: string;
|
|
51
58
|
children: FormatJsNode[];
|
|
52
59
|
}
|
|
53
|
-
export type FormatJsNode = FormatJsLiteral | FormatJsArgument | FormatJsNumber | FormatJsDate | FormatJsTime | FormatJsPlural | FormatJsPound | FormatJsTag;
|
|
60
|
+
export type FormatJsNode = FormatJsLiteral | FormatJsArgument | FormatJsNumber | FormatJsDate | FormatJsTime | FormatJsSelect | FormatJsPlural | FormatJsPound | FormatJsTag;
|
|
54
61
|
export declare const FORMAT_JS_POUND: FormatJsPound;
|
|
55
62
|
/**
|
|
56
63
|
* Hydrate the given keyless JSON into a FormatJS-compatible AST structure.
|
package/dist/message-loader.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
+
import { FormatJsNode } from './keyless-json';
|
|
1
2
|
import { InternalIntlMessage } from './message';
|
|
2
|
-
|
|
3
|
-
type AnyRawMessage = string | MessageFormatElement[];
|
|
4
|
-
type MessagesData = Record<string, AnyRawMessage>;
|
|
3
|
+
type MessagesData = Record<string, FormatJsNode[]>;
|
|
5
4
|
export interface IntlMessageGetterAdditions {
|
|
6
5
|
onChange(callback: () => void): () => void;
|
|
7
6
|
}
|