@discord/intl 0.6.1 → 0.7.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.js CHANGED
@@ -37,16 +37,17 @@ exports.FormatBuilder = FormatBuilder;
37
37
  function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, formatConfig, values = {}, currentPluralValue, originalMessage) {
38
38
  var _a, _b;
39
39
  // Hot path for static messages that are just parsed as a single string element.
40
- if (nodes.length === 1 && nodes[0][intl_ast_1.AstNodeIndices.Type] === intl_ast_1.FormatJsNodeType.Literal) {
41
- builder.pushLiteralText(nodes[0][intl_ast_1.AstNodeIndices.Value]);
40
+ if (nodes.length === 1 && typeof nodes[0][0] === 'string') {
41
+ builder.pushLiteralText(nodes[0][0]);
42
42
  return;
43
43
  }
44
44
  for (const node of nodes) {
45
45
  const nodeType = node[intl_ast_1.AstNodeIndices.Type];
46
+ if (typeof nodeType === 'string') {
47
+ builder.pushLiteralText(nodeType);
48
+ continue;
49
+ }
46
50
  switch (nodeType) {
47
- case intl_ast_1.FormatJsNodeType.Literal:
48
- builder.pushLiteralText(node[intl_ast_1.AstNodeIndices.Value]);
49
- continue;
50
51
  case intl_ast_1.FormatJsNodeType.Pound:
51
52
  // Replace `#` in plural rules with the actual numeric value. Only
52
53
  // numeric values are replaced, otherwise the value is completed ignored?
@@ -150,7 +151,7 @@ function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, format
150
151
  if (option == null) {
151
152
  throw `${value} is not a known option for select value ${variableName}. Valid options are ${Object.keys(options).join(', ')}`;
152
153
  }
153
- bindFormatValuesWithBuilder(builder, option.value, locales, formatters, formatConfig, values);
154
+ bindFormatValuesWithBuilder(builder, option, locales, formatters, formatConfig, values);
154
155
  break;
155
156
  }
156
157
  case intl_ast_1.FormatJsNodeType.Plural: {
@@ -172,7 +173,7 @@ function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, format
172
173
  if (option == null) {
173
174
  throw `${value} is not a known option for plural value ${variableName}. Valid options are ${Object.keys(options).join(', ')}`;
174
175
  }
175
- bindFormatValuesWithBuilder(builder, option.value, locales, formatters, formatConfig, values,
176
+ bindFormatValuesWithBuilder(builder, option, locales, formatters, formatConfig, values,
176
177
  // @ts-expect-error assert this `as number` properly.
177
178
  value - ((_b = node.offset) !== null && _b !== void 0 ? _b : 0));
178
179
  break;
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.IntlManager = exports.DEFAULT_LOCALE = void 0;
4
- const intl_ast_1 = require("@discord/intl-ast");
5
4
  const intl_1 = require("@formatjs/intl");
6
5
  const format_1 = require("./format");
7
6
  const format_config_1 = require("./format-config");
@@ -72,12 +71,17 @@ class IntlManager {
72
71
  const resolved = message(this.currentLocale);
73
72
  if (resolved == null || resolved.ast.length === 0)
74
73
  return '';
74
+ const value = resolved.ast[0];
75
+ if (typeof value[0] !== 'string') {
76
+ throw new Error('Attempted to call `string` formatting on a non-literal message: ' +
77
+ JSON.stringify(resolved));
78
+ }
75
79
  // TODO: Figure out how to make this typing exact. This currently relies on
76
80
  // the generic typing being sound enough to know that the message can only
77
81
  // contain a single static text node and no placeholders or rich text.
78
82
  // As it stands, this is _technically_ typed as string | undefined, even though
79
83
  // TypeScript doesn't actually complain about it.
80
- return resolved.ast[0][intl_ast_1.AstNodeIndices.Value];
84
+ return value[0];
81
85
  }
82
86
  /**
83
87
  * Return a raw string representing the syntax of the original message, as
package/dist/message.js CHANGED
@@ -22,10 +22,11 @@ exports.InternalIntlMessage = InternalIntlMessage;
22
22
  // appended, rather than creating a bunch of intermediate strings.
23
23
  function serializeAst(ast, result) {
24
24
  for (const node of ast) {
25
+ if (typeof node[0] === 'string') {
26
+ result.value += node[0];
27
+ return;
28
+ }
25
29
  switch (node[intl_ast_1.AstNodeIndices.Type]) {
26
- case intl_ast_1.FormatJsNodeType.Literal:
27
- result.value += node[intl_ast_1.AstNodeIndices.Value];
28
- return;
29
30
  case intl_ast_1.FormatJsNodeType.Argument:
30
31
  // Empties are an artifact of our parsing strategy, not necessary here.
31
32
  if (result.value === '$_')
@@ -61,7 +62,7 @@ function serializeAst(ast, result) {
61
62
  }
62
63
  for (const [name, arm] of Object.entries(node[intl_ast_1.AstNodeIndices.Options])) {
63
64
  result.value += ' ' + name + ' {';
64
- serializeAst(arm.value, result);
65
+ serializeAst(arm, result);
65
66
  result.value += '}';
66
67
  }
67
68
  return;
@@ -73,7 +74,7 @@ function serializeAst(ast, result) {
73
74
  result.value += '{' + node[intl_ast_1.AstNodeIndices.Value] + ', select, ';
74
75
  for (const [name, arm] of Object.entries(node[intl_ast_1.AstNodeIndices.Options])) {
75
76
  result.value += ' ' + name + ' {';
76
- serializeAst(arm.value, result);
77
+ serializeAst(arm, result);
77
78
  result.value += '}';
78
79
  }
79
80
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@discord/intl",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
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.6.1"
22
+ "@discord/intl-ast": "0.7.0"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@swc/cli": "^0.3.12",
package/src/format.ts CHANGED
@@ -56,18 +56,18 @@ export function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>
56
56
  originalMessage?: string,
57
57
  ) {
58
58
  // Hot path for static messages that are just parsed as a single string element.
59
- if (nodes.length === 1 && nodes[0][AstNodeIndices.Type] === FormatJsNodeType.Literal) {
60
- builder.pushLiteralText(nodes[0][AstNodeIndices.Value]);
59
+ if (nodes.length === 1 && typeof nodes[0][0] === 'string') {
60
+ builder.pushLiteralText(nodes[0][0]);
61
61
  return;
62
62
  }
63
63
 
64
64
  for (const node of nodes) {
65
65
  const nodeType = node[AstNodeIndices.Type];
66
+ if (typeof nodeType === 'string') {
67
+ builder.pushLiteralText(nodeType);
68
+ continue;
69
+ }
66
70
  switch (nodeType) {
67
- case FormatJsNodeType.Literal:
68
- builder.pushLiteralText(node[AstNodeIndices.Value]);
69
- continue;
70
-
71
71
  case FormatJsNodeType.Pound:
72
72
  // Replace `#` in plural rules with the actual numeric value. Only
73
73
  // numeric values are replaced, otherwise the value is completed ignored?
@@ -184,14 +184,7 @@ export function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>
184
184
  if (option == null) {
185
185
  throw `${value} is not a known option for select value ${variableName}. Valid options are ${Object.keys(options).join(', ')}`;
186
186
  }
187
- bindFormatValuesWithBuilder(
188
- builder,
189
- option.value,
190
- locales,
191
- formatters,
192
- formatConfig,
193
- values,
194
- );
187
+ bindFormatValuesWithBuilder(builder, option, locales, formatters, formatConfig, values);
195
188
  break;
196
189
  }
197
190
 
@@ -215,7 +208,7 @@ export function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>
215
208
  }
216
209
  bindFormatValuesWithBuilder(
217
210
  builder,
218
- option.value,
211
+ option,
219
212
  locales,
220
213
  formatters,
221
214
  formatConfig,
@@ -1,4 +1,4 @@
1
- import { AstNodeIndices } from '@discord/intl-ast';
1
+ import { LiteralNode } from '@discord/intl-ast';
2
2
  import { createIntl, IntlShape } from '@formatjs/intl';
3
3
  import { Formatters } from 'intl-messageformat';
4
4
 
@@ -120,12 +120,20 @@ export class IntlManager {
120
120
  const resolved = message(this.currentLocale);
121
121
  if (resolved == null || resolved.ast.length === 0) return '';
122
122
 
123
+ const value = resolved.ast[0] as LiteralNode;
124
+ if (typeof value[0] !== 'string') {
125
+ throw new Error(
126
+ 'Attempted to call `string` formatting on a non-literal message: ' +
127
+ JSON.stringify(resolved),
128
+ );
129
+ }
130
+
123
131
  // TODO: Figure out how to make this typing exact. This currently relies on
124
132
  // the generic typing being sound enough to know that the message can only
125
133
  // contain a single static text node and no placeholders or rich text.
126
134
  // As it stands, this is _technically_ typed as string | undefined, even though
127
135
  // TypeScript doesn't actually complain about it.
128
- return resolved.ast[0][AstNodeIndices.Value];
136
+ return value[0];
129
137
  }
130
138
 
131
139
  /**
package/src/message.ts CHANGED
@@ -32,10 +32,12 @@ export class InternalIntlMessage {
32
32
  // appended, rather than creating a bunch of intermediate strings.
33
33
  function serializeAst(ast: AstNode[], result: { value: string }) {
34
34
  for (const node of ast) {
35
+ if (typeof node[0] === 'string') {
36
+ result.value += node[0];
37
+ return;
38
+ }
39
+
35
40
  switch (node[AstNodeIndices.Type]) {
36
- case FormatJsNodeType.Literal:
37
- result.value += node[AstNodeIndices.Value];
38
- return;
39
41
  case FormatJsNodeType.Argument:
40
42
  // Empties are an artifact of our parsing strategy, not necessary here.
41
43
  if (result.value === '$_') return;
@@ -71,7 +73,7 @@ function serializeAst(ast: AstNode[], result: { value: string }) {
71
73
  }
72
74
  for (const [name, arm] of Object.entries(node[AstNodeIndices.Options])) {
73
75
  result.value += ' ' + name + ' {';
74
- serializeAst(arm.value, result);
76
+ serializeAst(arm, result);
75
77
  result.value += '}';
76
78
  }
77
79
  return;
@@ -83,7 +85,7 @@ function serializeAst(ast: AstNode[], result: { value: string }) {
83
85
  result.value += '{' + node[AstNodeIndices.Value] + ', select, ';
84
86
  for (const [name, arm] of Object.entries(node[AstNodeIndices.Options])) {
85
87
  result.value += ' ' + name + ' {';
86
- serializeAst(arm.value, result);
88
+ serializeAst(arm, result);
87
89
  result.value += '}';
88
90
  }
89
91
  return;