@discord/intl 0.4.2 → 0.5.1-canary.7ec6789

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.
@@ -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 { Formats, Formatters } from 'intl-messageformat';
21
- import { RichTextTagNames } from './types';
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, formats: Formats, values?: Record<string, string | object>, currentPluralValue?: number, originalMessage?: string): void;
30
- export declare function bindFormatValues<Result>(Builder: FormatBuilderConstructor<Result>, nodes: FormatJsNode[], locales: string | string[], formatters: Formatters, formats: Formats, values?: Record<string, string | object>, currentPluralValue?: number): Result[];
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, formats, values, currentPluralValue, originalMessage) {
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 formats.date
101
- ? formats.date[node.style]
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
- : undefined;
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 formats.time
113
- ? formats.time[node.style]
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 formats.number
126
- ? formats.number[node.style]
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, formats, values, currentPluralValue);
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, formats, values);
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, formats, values,
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, formats, values, currentPluralValue) {
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, formats, values, currentPluralValue);
216
+ bindFormatValuesWithBuilder(builder, nodes, locales, formatters, formatConfig, values, currentPluralValue);
217
217
  return builder.finish();
218
218
  }
@@ -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
  /**
@@ -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: intl_messageformat_1.IntlMessageFormat.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.intl.formats, values);
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@discord/intl",
3
- "version": "0.4.2",
3
+ "version": "0.5.1-canary.7ec6789",
4
4
  "license": "MIT",
5
5
  "description": "Client runtime for managing messages and translations in a React project.",
6
6
  "main": "./dist/index.js",
@@ -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
- formats: Formats,
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 formats.date
106
- ? formats.date[node.style]
107
+ node.style in formatConfig.date
108
+ ? formatConfig.date[node.style]
107
109
  : node.style != null
108
110
  ? parseDateTimeSkeleton(node.style)
109
- : undefined;
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 formats.time
119
- ? formats.time[node.style]
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 formats.number
134
- ? formats.number[node.style]
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
- formats,
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(builder, option.value, locales, formatters, formats, values);
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
- formats,
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
- formats: Formats,
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
- formats,
238
+ formatConfig,
230
239
  values,
231
240
  currentPluralValue,
232
241
  );
@@ -1,5 +1,5 @@
1
1
  import { createIntl, IntlShape } from '@formatjs/intl';
2
- import { Formats, Formatters, IntlMessageFormat } from 'intl-messageformat';
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: IntlMessageFormat.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.intl.formats as Formats,
154
+ this.formatConfig,
152
155
  values,
153
156
  );
154
157
  }