@ultraq/icu-message-formatter 0.14.2 → 0.15.0-beta.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.
@@ -1,46 +1,11 @@
1
- 'use strict';
2
-
3
- var functionUtils = require('@ultraq/function-utils');
4
-
5
- /*
6
- * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)
7
- *
8
- * Licensed under the Apache License, Version 2.0 (the "License");
9
- * you may not use this file except in compliance with the License.
10
- * You may obtain a copy of the License at
11
- *
12
- * http://www.apache.org/licenses/LICENSE-2.0
13
- *
14
- * Unless required by applicable law or agreed to in writing, software
15
- * distributed under the License is distributed on an "AS IS" BASIS,
16
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
- * See the License for the specific language governing permissions and
18
- * limitations under the License.
19
- */
20
-
21
- /**
22
- * @typedef ParseCasesResult
23
- * @property {string[]} args
24
- * A list of prepended arguments.
25
- * @property {Record<string,string>} cases
26
- * A map of all cases.
27
- */
28
-
29
- /**
30
- * Most branch-based type handlers are based around "cases". For example,
31
- * `select` and `plural` compare compare a value to "case keys" to choose a
32
- * subtranslation.
33
- *
34
- * This util splits "matches" portions provided to the aforementioned handlers
35
- * into case strings, and extracts any prepended arguments (for example,
36
- * `plural` supports an `offset:n` argument used for populating the magic `#`
37
- * variable).
38
- *
39
- * @param {string} string
40
- * @return {ParseCasesResult}
41
- */
42
- function parseCases(string = '') {
43
- const isWhitespace = ch => /\s/.test(ch);
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
6
+ const functionUtils = require("@ultraq/function-utils");
7
+ function parseCases(string = "") {
8
+ const isWhitespace = (ch) => /\s/.test(ch);
44
9
  const args = [];
45
10
  const cases = {};
46
11
  let currTermStart = 0;
@@ -48,31 +13,21 @@ function parseCases(string = '') {
48
13
  let inTerm = false;
49
14
  let i = 0;
50
15
  while (i < string.length) {
51
- // Term ended
52
- if (inTerm && (isWhitespace(string[i]) || string[i] === '{')) {
16
+ if (inTerm && (isWhitespace(string[i]) || string[i] === "{")) {
53
17
  inTerm = false;
54
18
  latestTerm = string.slice(currTermStart, i);
55
-
56
- // We want to process the opening char again so the case will be properly registered.
57
- if (string[i] === '{') {
19
+ if (string[i] === "{") {
58
20
  i--;
59
21
  }
60
- }
61
-
62
- // New term
63
- else if (!inTerm && !isWhitespace(string[i])) {
64
- const caseBody = string[i] === '{';
65
-
66
- // If there's a previous term, we can either handle a whole
67
- // case, or add that as an argument.
22
+ } else if (!inTerm && !isWhitespace(string[i])) {
23
+ const caseBody = string[i] === "{";
68
24
  if (latestTerm && caseBody) {
69
25
  const branchEndIndex = findClosingBracket(string, i);
70
26
  if (branchEndIndex === -1) {
71
27
  throw new Error(`Unbalanced curly braces in string: "${string}"`);
72
28
  }
73
- cases[latestTerm] = string.slice(i + 1, branchEndIndex); // Don't include the braces
74
-
75
- i = branchEndIndex; // Will be moved up where needed at end of loop.
29
+ cases[latestTerm] = string.slice(i + 1, branchEndIndex);
30
+ i = branchEndIndex;
76
31
  latestTerm = null;
77
32
  } else {
78
33
  if (latestTerm) {
@@ -96,57 +51,24 @@ function parseCases(string = '') {
96
51
  cases
97
52
  };
98
53
  }
99
-
100
- /**
101
- * Finds the index of the matching closing curly bracket, including through
102
- * strings that could have nested brackets.
103
- *
104
- * @param {string} string
105
- * @param {number} fromIndex
106
- * @return {number}
107
- * The index of the matching closing bracket, or -1 if no closing bracket
108
- * could be found.
109
- */
110
54
  function findClosingBracket(string, fromIndex) {
111
55
  let depth = 0;
112
56
  for (let i = fromIndex + 1; i < string.length; i++) {
113
57
  let char = string.charAt(i);
114
- if (char === '}') {
58
+ if (char === "}") {
115
59
  if (depth === 0) {
116
60
  return i;
117
61
  }
118
62
  depth--;
119
- } else if (char === '{') {
63
+ } else if (char === "{") {
120
64
  depth++;
121
65
  }
122
66
  }
123
67
  return -1;
124
68
  }
125
-
126
- /**
127
- * Split a `{key, type, format}` block into those 3 parts, taking into account
128
- * nested message syntax that can exist in the `format` part.
129
- *
130
- * @param {string} block
131
- * @return {string[]}
132
- * An array with `key`, `type`, and `format` items in that order, if present
133
- * in the formatted argument block.
134
- */
135
69
  function splitFormattedArgument(block) {
136
- return split(block.slice(1, -1), ',', 3);
70
+ return split(block.slice(1, -1), ",", 3);
137
71
  }
138
-
139
- /**
140
- * Like `String.prototype.split()` but where the limit parameter causes the
141
- * remainder of the string to be grouped together in a final entry.
142
- *
143
- * @private
144
- * @param {string} string
145
- * @param {string} separator
146
- * @param {number} limit
147
- * @param {string[]} accumulator
148
- * @return {string[]}
149
- */
150
72
  function split(string, separator, limit, accumulator = []) {
151
73
  if (!string) {
152
74
  return accumulator;
@@ -165,57 +87,6 @@ function split(string, separator, limit, accumulator = []) {
165
87
  accumulator.push(head);
166
88
  return split(tail, separator, limit - 1, accumulator);
167
89
  }
168
-
169
- /*
170
- * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)
171
- *
172
- * Licensed under the Apache License, Version 2.0 (the "License");
173
- * you may not use this file except in compliance with the License.
174
- * You may obtain a copy of the License at
175
- *
176
- * http://www.apache.org/licenses/LICENSE-2.0
177
- *
178
- * Unless required by applicable law or agreed to in writing, software
179
- * distributed under the License is distributed on an "AS IS" BASIS,
180
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
181
- * See the License for the specific language governing permissions and
182
- * limitations under the License.
183
- */
184
-
185
-
186
- /**
187
- * @typedef {Record<string,any>} FormatValues
188
- */
189
-
190
- /**
191
- * @callback ProcessFunction
192
- * @param {string} message
193
- * @param {FormatValues} [values={}]
194
- * @return {any[]}
195
- */
196
-
197
- /**
198
- * @callback TypeHandler
199
- * @param {any} value
200
- * The object which matched the key of the block being processed.
201
- * @param {string} matches
202
- * Any format options associated with the block being processed.
203
- * @param {string} locale
204
- * The locale to use for formatting.
205
- * @param {FormatValues} values
206
- * The object of placeholder data given to the original `format`/`process`
207
- * call.
208
- * @param {ProcessFunction} process
209
- * The `process` function itself so that sub-messages can be processed by type
210
- * handlers.
211
- * @return {any | any[]}
212
- */
213
-
214
- /**
215
- * The main class for formatting messages.
216
- *
217
- * @author Emanuel Rabina
218
- */
219
90
  class MessageFormatter {
220
91
  /**
221
92
  * Creates a new formatter that can work using any of the custom type handlers
@@ -228,20 +99,18 @@ class MessageFormatter {
228
99
  * string for the data and locale they are given.
229
100
  */
230
101
  constructor(locale, typeHandlers = {}) {
102
+ /**
103
+ * Formats an ICU message syntax string using `values` for placeholder data
104
+ * and any currently-registered type handlers.
105
+ *
106
+ * @type {(message: string, values?: FormatValues) => string}
107
+ */
108
+ __publicField(this, "format", functionUtils.memoize((message, values = {}) => {
109
+ return this.process(message, values).flat(Infinity).join("");
110
+ }));
231
111
  this.locale = locale;
232
112
  this.typeHandlers = typeHandlers;
233
113
  }
234
-
235
- /**
236
- * Formats an ICU message syntax string using `values` for placeholder data
237
- * and any currently-registered type handlers.
238
- *
239
- * @type {(message: string, values?: FormatValues) => string}
240
- */
241
- format = functionUtils.memoize((message, values = {}) => {
242
- return this.process(message, values).flat(Infinity).join('');
243
- });
244
-
245
114
  /**
246
115
  * Process an ICU message syntax string using `values` for placeholder data
247
116
  * and any currently-registered type handlers. The result of this method is
@@ -261,7 +130,7 @@ class MessageFormatter {
261
130
  if (!message) {
262
131
  return [];
263
132
  }
264
- let blockStartIndex = message.indexOf('{');
133
+ let blockStartIndex = message.indexOf("{");
265
134
  if (blockStartIndex !== -1) {
266
135
  let blockEndIndex = findClosingBracket(message, blockStartIndex);
267
136
  if (blockEndIndex !== -1) {
@@ -274,8 +143,8 @@ class MessageFormatter {
274
143
  }
275
144
  let [key, type, format] = splitFormattedArgument(block);
276
145
  let body = values[key];
277
- if (body === null || body === undefined) {
278
- body = '';
146
+ if (body === null || body === void 0) {
147
+ body = "";
279
148
  }
280
149
  let typeHandler = type && this.typeHandlers[type];
281
150
  result.push(typeHandler ? typeHandler(body, format, this.locale, values, this.process.bind(this)) : body);
@@ -292,52 +161,26 @@ class MessageFormatter {
292
161
  return [message];
293
162
  }
294
163
  }
295
-
296
- /*
297
- * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)
298
- *
299
- * Licensed under the Apache License, Version 2.0 (the "License");
300
- * you may not use this file except in compliance with the License.
301
- * You may obtain a copy of the License at
302
- *
303
- * http://www.apache.org/licenses/LICENSE-2.0
304
- *
305
- * Unless required by applicable law or agreed to in writing, software
306
- * distributed under the License is distributed on an "AS IS" BASIS,
307
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
308
- * See the License for the specific language governing permissions and
309
- * limitations under the License.
310
- */
311
-
312
164
  let pluralFormatter;
313
165
  let keyCounter = 0;
314
-
315
- // All the special keywords that can be used in `plural` blocks for the various branches
316
- const ONE = 'one';
317
- const OTHER$1 = 'other';
318
-
319
- /**
320
- * @private
321
- * @param {string} caseBody
322
- * @param {number} value
323
- * @return {{caseBody: string, numberValues: object}}
324
- */
166
+ const ONE = "one";
167
+ const OTHER$1 = "other";
325
168
  function replaceNumberSign(caseBody, value) {
326
169
  let i = 0;
327
- let output = '';
170
+ let output = "";
328
171
  let numBraces = 0;
329
172
  const numberValues = {};
330
173
  while (i < caseBody.length) {
331
- if (caseBody[i] === '#' && !numBraces) {
174
+ if (caseBody[i] === "#" && !numBraces) {
332
175
  let keyParam = `__hashToken${keyCounter++}`;
333
176
  output += `{${keyParam}, number}`;
334
177
  numberValues[keyParam] = value;
335
178
  } else {
336
179
  output += caseBody[i];
337
180
  }
338
- if (caseBody[i] === '{') {
181
+ if (caseBody[i] === "{") {
339
182
  numBraces++;
340
- } else if (caseBody[i] === '}') {
183
+ } else if (caseBody[i] === "}") {
341
184
  numBraces--;
342
185
  }
343
186
  i++;
@@ -347,41 +190,20 @@ function replaceNumberSign(caseBody, value) {
347
190
  numberValues
348
191
  };
349
192
  }
350
-
351
- /**
352
- * Handler for `plural` statements within ICU message syntax strings. Returns
353
- * a formatted string for the branch that closely matches the current value.
354
- *
355
- * See https://formatjs.io/docs/core-concepts/icu-syntax#plural-format for more
356
- * details on how the `plural` statement works.
357
- *
358
- * @param {string} value
359
- * @param {string} matches
360
- * @param {string} locale
361
- * @param {import('./MessageFormatter.js').FormatValues} values
362
- * @param {import('./MessageFormatter.js').ProcessFunction} process
363
- * @return {any | any[]}
364
- */
365
193
  function pluralTypeHandler(value, matches, locale, values, process) {
366
- const {
367
- args,
368
- cases
369
- } = parseCases(matches);
194
+ const { args, cases } = parseCases(matches);
370
195
  let intValue = parseInt(value);
371
- args.forEach(arg => {
372
- if (arg.startsWith('offset:')) {
373
- intValue -= parseInt(arg.slice('offset:'.length));
196
+ args.forEach((arg) => {
197
+ if (arg.startsWith("offset:")) {
198
+ intValue -= parseInt(arg.slice("offset:".length));
374
199
  }
375
200
  });
376
201
  const keywordPossibilities = [];
377
- if ('PluralRules' in Intl) {
378
- // Effectively memoize because instantiation of `Int.*` objects is expensive.
379
- if (pluralFormatter === undefined || pluralFormatter.resolvedOptions().locale !== locale) {
202
+ if ("PluralRules" in Intl) {
203
+ if (pluralFormatter === void 0 || pluralFormatter.resolvedOptions().locale !== locale) {
380
204
  pluralFormatter = new Intl.PluralRules(locale);
381
205
  }
382
206
  const pluralKeyword = pluralFormatter.select(intValue);
383
-
384
- // Other is always added last with least priority, so we don't want to add it here.
385
207
  if (pluralKeyword !== OTHER$1) {
386
208
  keywordPossibilities.push(pluralKeyword);
387
209
  }
@@ -393,10 +215,7 @@ function pluralTypeHandler(value, matches, locale, values, process) {
393
215
  for (let i = 0; i < keywordPossibilities.length; i++) {
394
216
  const keyword = keywordPossibilities[i];
395
217
  if (keyword in cases) {
396
- const {
397
- caseBody,
398
- numberValues
399
- } = replaceNumberSign(cases[keyword], intValue);
218
+ const { caseBody, numberValues } = replaceNumberSign(cases[keyword], intValue);
400
219
  return process(caseBody, {
401
220
  ...values,
402
221
  ...numberValues
@@ -405,43 +224,9 @@ function pluralTypeHandler(value, matches, locale, values, process) {
405
224
  }
406
225
  return value;
407
226
  }
408
-
409
- /*
410
- * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)
411
- *
412
- * Licensed under the Apache License, Version 2.0 (the "License");
413
- * you may not use this file except in compliance with the License.
414
- * You may obtain a copy of the License at
415
- *
416
- * http://www.apache.org/licenses/LICENSE-2.0
417
- *
418
- * Unless required by applicable law or agreed to in writing, software
419
- * distributed under the License is distributed on an "AS IS" BASIS,
420
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
421
- * See the License for the specific language governing permissions and
422
- * limitations under the License.
423
- */
424
-
425
- const OTHER = 'other';
426
-
427
- /**
428
- * Handler for `select` statements within ICU message syntax strings. Returns
429
- * a formatted string for the branch that closely matches the current value.
430
- *
431
- * See https://formatjs.io/docs/core-concepts/icu-syntax#select-format for more
432
- * details on how the `select` statement works.
433
- *
434
- * @param {string} value
435
- * @param {string} matches
436
- * @param {string} locale
437
- * @param {import('./MessageFormatter.js').FormatValues} values
438
- * @param {import('./MessageFormatter.js').ProcessFunction} process
439
- * @return {any | any[]}
440
- */
227
+ const OTHER = "other";
441
228
  function selectTypeHandler(value, matches, locale, values, process) {
442
- const {
443
- cases
444
- } = parseCases(matches);
229
+ const { cases } = parseCases(matches);
445
230
  if (value in cases) {
446
231
  return process(cases[value], values);
447
232
  } else if (OTHER in cases) {
@@ -449,7 +234,6 @@ function selectTypeHandler(value, matches, locale, values, process) {
449
234
  }
450
235
  return value;
451
236
  }
452
-
453
237
  exports.MessageFormatter = MessageFormatter;
454
238
  exports.findClosingBracket = findClosingBracket;
455
239
  exports.parseCases = parseCases;
@@ -1 +1 @@
1
- {"version":3,"file":"icu-message-formatter.cjs","sources":["../source/utilities.js","../source/MessageFormatter.js","../source/pluralTypeHandler.js","../source/selectTypeHandler.js"],"sourcesContent":["/*\n * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @typedef ParseCasesResult\n * @property {string[]} args\n * A list of prepended arguments.\n * @property {Record<string,string>} cases\n * A map of all cases.\n */\n\n/**\n * Most branch-based type handlers are based around \"cases\". For example,\n * `select` and `plural` compare compare a value to \"case keys\" to choose a\n * subtranslation.\n *\n * This util splits \"matches\" portions provided to the aforementioned handlers\n * into case strings, and extracts any prepended arguments (for example,\n * `plural` supports an `offset:n` argument used for populating the magic `#`\n * variable).\n *\n * @param {string} string\n * @return {ParseCasesResult}\n */\nexport function parseCases(string = '') {\n\tconst isWhitespace = ch => /\\s/.test(ch);\n\n\tconst args = [];\n\tconst cases = {};\n\n\tlet currTermStart = 0;\n\tlet latestTerm = null;\n\tlet inTerm = false;\n\n\tlet i = 0;\n\twhile (i < string.length) {\n\t\t// Term ended\n\t\tif (inTerm && (isWhitespace(string[i]) || string[i] === '{')) {\n\t\t\tinTerm = false;\n\t\t\tlatestTerm = string.slice(currTermStart, i);\n\n\t\t\t// We want to process the opening char again so the case will be properly registered.\n\t\t\tif (string[i] === '{') {\n\t\t\t\ti--;\n\t\t\t}\n\t\t}\n\n\t\t// New term\n\t\telse if (!inTerm && !isWhitespace(string[i])) {\n\t\t\tconst caseBody = string[i] === '{';\n\n\t\t\t// If there's a previous term, we can either handle a whole\n\t\t\t// case, or add that as an argument.\n\t\t\tif (latestTerm && caseBody) {\n\t\t\t\tconst branchEndIndex = findClosingBracket(string, i);\n\n\t\t\t\tif (branchEndIndex === -1) {\n\t\t\t\t\tthrow new Error(`Unbalanced curly braces in string: \"${string}\"`);\n\t\t\t\t}\n\n\t\t\t\tcases[latestTerm] = string.slice(i + 1, branchEndIndex); // Don't include the braces\n\n\t\t\t\ti = branchEndIndex; // Will be moved up where needed at end of loop.\n\t\t\t\tlatestTerm = null;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (latestTerm) {\n\t\t\t\t\targs.push(latestTerm);\n\t\t\t\t\tlatestTerm = null;\n\t\t\t\t}\n\n\t\t\t\tinTerm = true;\n\t\t\t\tcurrTermStart = i;\n\t\t\t}\n\t\t}\n\t\ti++;\n\t}\n\n\tif (inTerm) {\n\t\tlatestTerm = string.slice(currTermStart);\n\t}\n\n\tif (latestTerm) {\n\t\targs.push(latestTerm);\n\t}\n\n\treturn {\n\t\targs,\n\t\tcases\n\t};\n}\n\n/**\n * Finds the index of the matching closing curly bracket, including through\n * strings that could have nested brackets.\n *\n * @param {string} string\n * @param {number} fromIndex\n * @return {number}\n * The index of the matching closing bracket, or -1 if no closing bracket\n * could be found.\n */\nexport function findClosingBracket(string, fromIndex) {\n\tlet depth = 0;\n\tfor (let i = fromIndex + 1; i < string.length; i++) {\n\t\tlet char = string.charAt(i);\n\t\tif (char === '}') {\n\t\t\tif (depth === 0) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t\tdepth--;\n\t\t}\n\t\telse if (char === '{') {\n\t\t\tdepth++;\n\t\t}\n\t}\n\treturn -1;\n}\n\n/**\n * Split a `{key, type, format}` block into those 3 parts, taking into account\n * nested message syntax that can exist in the `format` part.\n *\n * @param {string} block\n * @return {string[]}\n * An array with `key`, `type`, and `format` items in that order, if present\n * in the formatted argument block.\n */\nexport function splitFormattedArgument(block) {\n\treturn split(block.slice(1, -1), ',', 3);\n}\n\n/**\n * Like `String.prototype.split()` but where the limit parameter causes the\n * remainder of the string to be grouped together in a final entry.\n *\n * @private\n * @param {string} string\n * @param {string} separator\n * @param {number} limit\n * @param {string[]} accumulator\n * @return {string[]}\n */\nfunction split(string, separator, limit, accumulator = []) {\n\tif (!string) {\n\t\treturn accumulator;\n\t}\n\tif (limit === 1) {\n\t\taccumulator.push(string);\n\t\treturn accumulator;\n\t}\n\tlet indexOfDelimiter = string.indexOf(separator);\n\tif (indexOfDelimiter === -1) {\n\t\taccumulator.push(string);\n\t\treturn accumulator;\n\t}\n\tlet head = string.substring(0, indexOfDelimiter).trim();\n\tlet tail = string.substring(indexOfDelimiter + separator.length + 1).trim();\n\taccumulator.push(head);\n\treturn split(tail, separator, limit - 1, accumulator);\n}\n","/*\n * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {findClosingBracket, splitFormattedArgument} from './utilities.js';\n\nimport {memoize} from '@ultraq/function-utils';\n\n/**\n * @typedef {Record<string,any>} FormatValues\n */\n\n/**\n * @callback ProcessFunction\n * @param {string} message\n * @param {FormatValues} [values={}]\n * @return {any[]}\n */\n\n/**\n * @callback TypeHandler\n * @param {any} value\n * The object which matched the key of the block being processed.\n * @param {string} matches\n * Any format options associated with the block being processed.\n * @param {string} locale\n * The locale to use for formatting.\n * @param {FormatValues} values\n * The object of placeholder data given to the original `format`/`process`\n * call.\n * @param {ProcessFunction} process\n * The `process` function itself so that sub-messages can be processed by type\n * handlers.\n * @return {any | any[]}\n */\n\n/**\n * The main class for formatting messages.\n *\n * @author Emanuel Rabina\n */\nexport default class MessageFormatter {\n\n\t/**\n\t * Creates a new formatter that can work using any of the custom type handlers\n\t * you register.\n\t *\n\t * @param {string} locale\n\t * @param {Record<string,TypeHandler>} [typeHandlers]\n\t * Optional object where the keys are the names of the types to register,\n\t * their values being the functions that will return a nicely formatted\n\t * string for the data and locale they are given.\n\t */\n\tconstructor(locale, typeHandlers = {}) {\n\n\t\tthis.locale = locale;\n\t\tthis.typeHandlers = typeHandlers;\n\t}\n\n\t/**\n\t * Formats an ICU message syntax string using `values` for placeholder data\n\t * and any currently-registered type handlers.\n\t *\n\t * @type {(message: string, values?: FormatValues) => string}\n\t */\n\tformat = memoize((message, values = {}) => {\n\n\t\treturn this.process(message, values).flat(Infinity).join('');\n\t});\n\n\t/**\n\t * Process an ICU message syntax string using `values` for placeholder data\n\t * and any currently-registered type handlers. The result of this method is\n\t * an array of the component parts after they have been processed in turn by\n\t * their own type handlers. This raw output is useful for other renderers,\n\t * eg: React where components can be used instead of being forced to return\n\t * raw strings.\n\t *\n\t * This method is used by {@link MessageFormatter#format} where it acts as a\n\t * string renderer.\n\t *\n\t * @param {string} message\n\t * @param {FormatValues} [values]\n\t * @return {any[]}\n\t */\n\tprocess(message, values = {}) {\n\n\t\tif (!message) {\n\t\t\treturn [];\n\t\t}\n\n\t\tlet blockStartIndex = message.indexOf('{');\n\t\tif (blockStartIndex !== -1) {\n\t\t\tlet blockEndIndex = findClosingBracket(message, blockStartIndex);\n\t\t\tif (blockEndIndex !== -1) {\n\t\t\t\tlet block = message.substring(blockStartIndex, blockEndIndex + 1);\n\t\t\t\tif (block) {\n\t\t\t\t\tlet result = [];\n\t\t\t\t\tlet head = message.substring(0, blockStartIndex);\n\t\t\t\t\tif (head) {\n\t\t\t\t\t\tresult.push(head);\n\t\t\t\t\t}\n\t\t\t\t\tlet [key, type, format] = splitFormattedArgument(block);\n\t\t\t\t\tlet body = values[key];\n\t\t\t\t\tif (body === null || body === undefined) {\n\t\t\t\t\t\tbody = '';\n\t\t\t\t\t}\n\t\t\t\t\tlet typeHandler = type && this.typeHandlers[type];\n\t\t\t\t\tresult.push(typeHandler ?\n\t\t\t\t\t\ttypeHandler(body, format, this.locale, values, this.process.bind(this)) :\n\t\t\t\t\t\tbody);\n\t\t\t\t\tlet tail = message.substring(blockEndIndex + 1);\n\t\t\t\t\tif (tail) {\n\t\t\t\t\t\tresult.push(this.process(tail, values));\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new Error(`Unbalanced curly braces in string: \"${message}\"`);\n\t\t\t}\n\t\t}\n\t\treturn [message];\n\t}\n}\n","/*\n * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {parseCases} from './utilities.js';\n\nlet pluralFormatter;\n\nlet keyCounter = 0;\n\n// All the special keywords that can be used in `plural` blocks for the various branches\nconst ONE = 'one';\nconst OTHER = 'other';\n\n/**\n * @private\n * @param {string} caseBody\n * @param {number} value\n * @return {{caseBody: string, numberValues: object}}\n */\nfunction replaceNumberSign(caseBody, value) {\n\tlet i = 0;\n\tlet output = '';\n\tlet numBraces = 0;\n\tconst numberValues = {};\n\n\twhile (i < caseBody.length) {\n\t\tif (caseBody[i] === '#' && !numBraces) {\n\t\t\tlet keyParam = `__hashToken${keyCounter++}`;\n\t\t\toutput += `{${keyParam}, number}`;\n\t\t\tnumberValues[keyParam] = value;\n\t\t}\n\t\telse {\n\t\t\toutput += caseBody[i];\n\t\t}\n\n\t\tif (caseBody[i] === '{') {\n\t\t\tnumBraces++;\n\t\t}\n\t\telse if (caseBody[i] === '}') {\n\t\t\tnumBraces--;\n\t\t}\n\n\t\ti++;\n\t}\n\n\treturn {\n\t\tcaseBody: output,\n\t\tnumberValues\n\t};\n}\n\n/**\n * Handler for `plural` statements within ICU message syntax strings. Returns\n * a formatted string for the branch that closely matches the current value.\n *\n * See https://formatjs.io/docs/core-concepts/icu-syntax#plural-format for more\n * details on how the `plural` statement works.\n *\n * @param {string} value\n * @param {string} matches\n * @param {string} locale\n * @param {import('./MessageFormatter.js').FormatValues} values\n * @param {import('./MessageFormatter.js').ProcessFunction} process\n * @return {any | any[]}\n */\nexport default function pluralTypeHandler(value, matches, locale, values, process) {\n\tconst {args, cases} = parseCases(matches);\n\n\tlet intValue = parseInt(value);\n\n\targs.forEach((arg) => {\n\t\tif (arg.startsWith('offset:')) {\n\t\t\tintValue -= parseInt(arg.slice('offset:'.length));\n\t\t}\n\t});\n\n\tconst keywordPossibilities = [];\n\n\tif ('PluralRules' in Intl) {\n\t\t// Effectively memoize because instantiation of `Int.*` objects is expensive.\n\t\tif (pluralFormatter === undefined || pluralFormatter.resolvedOptions().locale !== locale) {\n\t\t\tpluralFormatter = new Intl.PluralRules(locale);\n\t\t}\n\n\t\tconst pluralKeyword = pluralFormatter.select(intValue);\n\n\t\t// Other is always added last with least priority, so we don't want to add it here.\n\t\tif (pluralKeyword !== OTHER) {\n\t\t\tkeywordPossibilities.push(pluralKeyword);\n\t\t}\n\t}\n\tif (intValue === 1) {\n\t\tkeywordPossibilities.push(ONE);\n\t}\n\tkeywordPossibilities.push(`=${intValue}`, OTHER);\n\n\tfor (let i = 0; i < keywordPossibilities.length; i++) {\n\t\tconst keyword = keywordPossibilities[i];\n\t\tif (keyword in cases) {\n\t\t\tconst {caseBody, numberValues} = replaceNumberSign(cases[keyword], intValue);\n\t\t\treturn process(caseBody, {\n\t\t\t\t...values,\n\t\t\t\t...numberValues\n\t\t\t});\n\t\t}\n\t}\n\n\treturn value;\n}\n","/*\n * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {parseCases} from './utilities.js';\n\nconst OTHER = 'other';\n\n/**\n * Handler for `select` statements within ICU message syntax strings. Returns\n * a formatted string for the branch that closely matches the current value.\n *\n * See https://formatjs.io/docs/core-concepts/icu-syntax#select-format for more\n * details on how the `select` statement works.\n *\n * @param {string} value\n * @param {string} matches\n * @param {string} locale\n * @param {import('./MessageFormatter.js').FormatValues} values\n * @param {import('./MessageFormatter.js').ProcessFunction} process\n * @return {any | any[]}\n */\nexport default function selectTypeHandler(value, matches, locale, values, process) {\n\tconst {cases} = parseCases(matches);\n\n\tif (value in cases) {\n\t\treturn process(cases[value], values);\n\t}\n\telse if (OTHER in cases) {\n\t\treturn process(cases[OTHER], values);\n\t}\n\n\treturn value;\n}\n"],"names":["parseCases","string","isWhitespace","ch","test","args","cases","currTermStart","latestTerm","inTerm","i","length","slice","caseBody","branchEndIndex","findClosingBracket","Error","push","fromIndex","depth","char","charAt","splitFormattedArgument","block","split","separator","limit","accumulator","indexOfDelimiter","indexOf","head","substring","trim","tail","MessageFormatter","constructor","locale","typeHandlers","format","memoize","message","values","process","flat","Infinity","join","blockStartIndex","blockEndIndex","result","key","type","body","undefined","typeHandler","bind","pluralFormatter","keyCounter","ONE","OTHER","replaceNumberSign","value","output","numBraces","numberValues","keyParam","pluralTypeHandler","matches","intValue","parseInt","forEach","arg","startsWith","keywordPossibilities","Intl","resolvedOptions","PluralRules","pluralKeyword","select","keyword","selectTypeHandler"],"mappings":"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"}
1
+ {"version":3,"file":"icu-message-formatter.cjs","sources":["../source/utilities.js","../source/MessageFormatter.js","../source/pluralTypeHandler.js","../source/selectTypeHandler.js"],"sourcesContent":["/*\n * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @typedef ParseCasesResult\n * @property {string[]} args\n * A list of prepended arguments.\n * @property {Record<string,string>} cases\n * A map of all cases.\n */\n\n/**\n * Most branch-based type handlers are based around \"cases\". For example,\n * `select` and `plural` compare compare a value to \"case keys\" to choose a\n * subtranslation.\n *\n * This util splits \"matches\" portions provided to the aforementioned handlers\n * into case strings, and extracts any prepended arguments (for example,\n * `plural` supports an `offset:n` argument used for populating the magic `#`\n * variable).\n *\n * @param {string} string\n * @return {ParseCasesResult}\n */\nexport function parseCases(string = '') {\n\tconst isWhitespace = ch => /\\s/.test(ch);\n\n\tconst args = [];\n\tconst cases = {};\n\n\tlet currTermStart = 0;\n\tlet latestTerm = null;\n\tlet inTerm = false;\n\n\tlet i = 0;\n\twhile (i < string.length) {\n\t\t// Term ended\n\t\tif (inTerm && (isWhitespace(string[i]) || string[i] === '{')) {\n\t\t\tinTerm = false;\n\t\t\tlatestTerm = string.slice(currTermStart, i);\n\n\t\t\t// We want to process the opening char again so the case will be properly registered.\n\t\t\tif (string[i] === '{') {\n\t\t\t\ti--;\n\t\t\t}\n\t\t}\n\n\t\t// New term\n\t\telse if (!inTerm && !isWhitespace(string[i])) {\n\t\t\tconst caseBody = string[i] === '{';\n\n\t\t\t// If there's a previous term, we can either handle a whole\n\t\t\t// case, or add that as an argument.\n\t\t\tif (latestTerm && caseBody) {\n\t\t\t\tconst branchEndIndex = findClosingBracket(string, i);\n\n\t\t\t\tif (branchEndIndex === -1) {\n\t\t\t\t\tthrow new Error(`Unbalanced curly braces in string: \"${string}\"`);\n\t\t\t\t}\n\n\t\t\t\tcases[latestTerm] = string.slice(i + 1, branchEndIndex); // Don't include the braces\n\n\t\t\t\ti = branchEndIndex; // Will be moved up where needed at end of loop.\n\t\t\t\tlatestTerm = null;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (latestTerm) {\n\t\t\t\t\targs.push(latestTerm);\n\t\t\t\t\tlatestTerm = null;\n\t\t\t\t}\n\n\t\t\t\tinTerm = true;\n\t\t\t\tcurrTermStart = i;\n\t\t\t}\n\t\t}\n\t\ti++;\n\t}\n\n\tif (inTerm) {\n\t\tlatestTerm = string.slice(currTermStart);\n\t}\n\n\tif (latestTerm) {\n\t\targs.push(latestTerm);\n\t}\n\n\treturn {\n\t\targs,\n\t\tcases\n\t};\n}\n\n/**\n * Finds the index of the matching closing curly bracket, including through\n * strings that could have nested brackets.\n *\n * @param {string} string\n * @param {number} fromIndex\n * @return {number}\n * The index of the matching closing bracket, or -1 if no closing bracket\n * could be found.\n */\nexport function findClosingBracket(string, fromIndex) {\n\tlet depth = 0;\n\tfor (let i = fromIndex + 1; i < string.length; i++) {\n\t\tlet char = string.charAt(i);\n\t\tif (char === '}') {\n\t\t\tif (depth === 0) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t\tdepth--;\n\t\t}\n\t\telse if (char === '{') {\n\t\t\tdepth++;\n\t\t}\n\t}\n\treturn -1;\n}\n\n/**\n * Split a `{key, type, format}` block into those 3 parts, taking into account\n * nested message syntax that can exist in the `format` part.\n *\n * @param {string} block\n * @return {string[]}\n * An array with `key`, `type`, and `format` items in that order, if present\n * in the formatted argument block.\n */\nexport function splitFormattedArgument(block) {\n\treturn split(block.slice(1, -1), ',', 3);\n}\n\n/**\n * Like `String.prototype.split()` but where the limit parameter causes the\n * remainder of the string to be grouped together in a final entry.\n *\n * @private\n * @param {string} string\n * @param {string} separator\n * @param {number} limit\n * @param {string[]} accumulator\n * @return {string[]}\n */\nfunction split(string, separator, limit, accumulator = []) {\n\tif (!string) {\n\t\treturn accumulator;\n\t}\n\tif (limit === 1) {\n\t\taccumulator.push(string);\n\t\treturn accumulator;\n\t}\n\tlet indexOfDelimiter = string.indexOf(separator);\n\tif (indexOfDelimiter === -1) {\n\t\taccumulator.push(string);\n\t\treturn accumulator;\n\t}\n\tlet head = string.substring(0, indexOfDelimiter).trim();\n\tlet tail = string.substring(indexOfDelimiter + separator.length + 1).trim();\n\taccumulator.push(head);\n\treturn split(tail, separator, limit - 1, accumulator);\n}\n","/*\n * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {findClosingBracket, splitFormattedArgument} from './utilities.js';\n\nimport {memoize} from '@ultraq/function-utils';\n\n/**\n * @typedef {Record<string,any>} FormatValues\n */\n\n/**\n * @callback ProcessFunction\n * @param {string} message\n * @param {FormatValues} [values={}]\n * @return {any[]}\n */\n\n/**\n * @callback TypeHandler\n * @param {any} value\n * The object which matched the key of the block being processed.\n * @param {string} matches\n * Any format options associated with the block being processed.\n * @param {string} locale\n * The locale to use for formatting.\n * @param {FormatValues} values\n * The object of placeholder data given to the original `format`/`process`\n * call.\n * @param {ProcessFunction} process\n * The `process` function itself so that sub-messages can be processed by type\n * handlers.\n * @return {any | any[]}\n */\n\n/**\n * The main class for formatting messages.\n *\n * @author Emanuel Rabina\n */\nexport default class MessageFormatter {\n\n\t/**\n\t * Creates a new formatter that can work using any of the custom type handlers\n\t * you register.\n\t *\n\t * @param {string} locale\n\t * @param {Record<string,TypeHandler>} [typeHandlers]\n\t * Optional object where the keys are the names of the types to register,\n\t * their values being the functions that will return a nicely formatted\n\t * string for the data and locale they are given.\n\t */\n\tconstructor(locale, typeHandlers = {}) {\n\n\t\tthis.locale = locale;\n\t\tthis.typeHandlers = typeHandlers;\n\t}\n\n\t/**\n\t * Formats an ICU message syntax string using `values` for placeholder data\n\t * and any currently-registered type handlers.\n\t *\n\t * @type {(message: string, values?: FormatValues) => string}\n\t */\n\tformat = memoize((message, values = {}) => {\n\n\t\treturn this.process(message, values).flat(Infinity).join('');\n\t});\n\n\t/**\n\t * Process an ICU message syntax string using `values` for placeholder data\n\t * and any currently-registered type handlers. The result of this method is\n\t * an array of the component parts after they have been processed in turn by\n\t * their own type handlers. This raw output is useful for other renderers,\n\t * eg: React where components can be used instead of being forced to return\n\t * raw strings.\n\t *\n\t * This method is used by {@link MessageFormatter#format} where it acts as a\n\t * string renderer.\n\t *\n\t * @param {string} message\n\t * @param {FormatValues} [values]\n\t * @return {any[]}\n\t */\n\tprocess(message, values = {}) {\n\n\t\tif (!message) {\n\t\t\treturn [];\n\t\t}\n\n\t\tlet blockStartIndex = message.indexOf('{');\n\t\tif (blockStartIndex !== -1) {\n\t\t\tlet blockEndIndex = findClosingBracket(message, blockStartIndex);\n\t\t\tif (blockEndIndex !== -1) {\n\t\t\t\tlet block = message.substring(blockStartIndex, blockEndIndex + 1);\n\t\t\t\tif (block) {\n\t\t\t\t\tlet result = [];\n\t\t\t\t\tlet head = message.substring(0, blockStartIndex);\n\t\t\t\t\tif (head) {\n\t\t\t\t\t\tresult.push(head);\n\t\t\t\t\t}\n\t\t\t\t\tlet [key, type, format] = splitFormattedArgument(block);\n\t\t\t\t\tlet body = values[key];\n\t\t\t\t\tif (body === null || body === undefined) {\n\t\t\t\t\t\tbody = '';\n\t\t\t\t\t}\n\t\t\t\t\tlet typeHandler = type && this.typeHandlers[type];\n\t\t\t\t\tresult.push(typeHandler ?\n\t\t\t\t\t\ttypeHandler(body, format, this.locale, values, this.process.bind(this)) :\n\t\t\t\t\t\tbody);\n\t\t\t\t\tlet tail = message.substring(blockEndIndex + 1);\n\t\t\t\t\tif (tail) {\n\t\t\t\t\t\tresult.push(this.process(tail, values));\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new Error(`Unbalanced curly braces in string: \"${message}\"`);\n\t\t\t}\n\t\t}\n\t\treturn [message];\n\t}\n}\n","/*\n * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {parseCases} from './utilities.js';\n\nlet pluralFormatter;\n\nlet keyCounter = 0;\n\n// All the special keywords that can be used in `plural` blocks for the various branches\nconst ONE = 'one';\nconst OTHER = 'other';\n\n/**\n * @private\n * @param {string} caseBody\n * @param {number} value\n * @return {{caseBody: string, numberValues: object}}\n */\nfunction replaceNumberSign(caseBody, value) {\n\tlet i = 0;\n\tlet output = '';\n\tlet numBraces = 0;\n\tconst numberValues = {};\n\n\twhile (i < caseBody.length) {\n\t\tif (caseBody[i] === '#' && !numBraces) {\n\t\t\tlet keyParam = `__hashToken${keyCounter++}`;\n\t\t\toutput += `{${keyParam}, number}`;\n\t\t\tnumberValues[keyParam] = value;\n\t\t}\n\t\telse {\n\t\t\toutput += caseBody[i];\n\t\t}\n\n\t\tif (caseBody[i] === '{') {\n\t\t\tnumBraces++;\n\t\t}\n\t\telse if (caseBody[i] === '}') {\n\t\t\tnumBraces--;\n\t\t}\n\n\t\ti++;\n\t}\n\n\treturn {\n\t\tcaseBody: output,\n\t\tnumberValues\n\t};\n}\n\n/**\n * Handler for `plural` statements within ICU message syntax strings. Returns\n * a formatted string for the branch that closely matches the current value.\n *\n * See https://formatjs.io/docs/core-concepts/icu-syntax#plural-format for more\n * details on how the `plural` statement works.\n *\n * @param {string} value\n * @param {string} matches\n * @param {string} locale\n * @param {import('./MessageFormatter.js').FormatValues} values\n * @param {import('./MessageFormatter.js').ProcessFunction} process\n * @return {any | any[]}\n */\nexport default function pluralTypeHandler(value, matches, locale, values, process) {\n\tconst {args, cases} = parseCases(matches);\n\n\tlet intValue = parseInt(value);\n\n\targs.forEach((arg) => {\n\t\tif (arg.startsWith('offset:')) {\n\t\t\tintValue -= parseInt(arg.slice('offset:'.length));\n\t\t}\n\t});\n\n\tconst keywordPossibilities = [];\n\n\tif ('PluralRules' in Intl) {\n\t\t// Effectively memoize because instantiation of `Int.*` objects is expensive.\n\t\tif (pluralFormatter === undefined || pluralFormatter.resolvedOptions().locale !== locale) {\n\t\t\tpluralFormatter = new Intl.PluralRules(locale);\n\t\t}\n\n\t\tconst pluralKeyword = pluralFormatter.select(intValue);\n\n\t\t// Other is always added last with least priority, so we don't want to add it here.\n\t\tif (pluralKeyword !== OTHER) {\n\t\t\tkeywordPossibilities.push(pluralKeyword);\n\t\t}\n\t}\n\tif (intValue === 1) {\n\t\tkeywordPossibilities.push(ONE);\n\t}\n\tkeywordPossibilities.push(`=${intValue}`, OTHER);\n\n\tfor (let i = 0; i < keywordPossibilities.length; i++) {\n\t\tconst keyword = keywordPossibilities[i];\n\t\tif (keyword in cases) {\n\t\t\tconst {caseBody, numberValues} = replaceNumberSign(cases[keyword], intValue);\n\t\t\treturn process(caseBody, {\n\t\t\t\t...values,\n\t\t\t\t...numberValues\n\t\t\t});\n\t\t}\n\t}\n\n\treturn value;\n}\n","/*\n * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {parseCases} from './utilities.js';\n\nconst OTHER = 'other';\n\n/**\n * Handler for `select` statements within ICU message syntax strings. Returns\n * a formatted string for the branch that closely matches the current value.\n *\n * See https://formatjs.io/docs/core-concepts/icu-syntax#select-format for more\n * details on how the `select` statement works.\n *\n * @param {string} value\n * @param {string} matches\n * @param {string} locale\n * @param {import('./MessageFormatter.js').FormatValues} values\n * @param {import('./MessageFormatter.js').ProcessFunction} process\n * @return {any | any[]}\n */\nexport default function selectTypeHandler(value, matches, locale, values, process) {\n\tconst {cases} = parseCases(matches);\n\n\tif (value in cases) {\n\t\treturn process(cases[value], values);\n\t}\n\telse if (OTHER in cases) {\n\t\treturn process(cases[OTHER], values);\n\t}\n\n\treturn value;\n}\n"],"names":["memoize","OTHER"],"mappings":"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"}
@@ -1,16 +1,3 @@
1
- export type ParseCasesResult = {
2
- /**
3
- * A list of prepended arguments.
4
- */
5
- args: string[];
6
- /**
7
- * A map of all cases.
8
- */
9
- cases: Record<string, string>;
10
- };
11
- export type FormatValues = Record<string, any>;
12
- export type ProcessFunction = (message: string, values?: FormatValues) => any[];
13
- export type TypeHandler = (value: any, matches: string, locale: string, values: FormatValues, process: ProcessFunction) => any | any[];
14
1
  /**
15
2
  * @typedef {Record<string,any>} FormatValues
16
3
  */
@@ -41,7 +28,7 @@ export type TypeHandler = (value: any, matches: string, locale: string, values:
41
28
  *
42
29
  * @author Emanuel Rabina
43
30
  */
44
- export class MessageFormatter {
31
+ declare class MessageFormatter {
45
32
  /**
46
33
  * Creates a new formatter that can work using any of the custom type handlers
47
34
  * you register.
@@ -79,38 +66,10 @@ export class MessageFormatter {
79
66
  */
80
67
  process(message: string, values?: FormatValues): any[];
81
68
  }
82
- /**
83
- * Finds the index of the matching closing curly bracket, including through
84
- * strings that could have nested brackets.
85
- *
86
- * @param {string} string
87
- * @param {number} fromIndex
88
- * @return {number}
89
- * The index of the matching closing bracket, or -1 if no closing bracket
90
- * could be found.
91
- */
92
- export function findClosingBracket(string: string, fromIndex: number): number;
93
- /**
94
- * @typedef ParseCasesResult
95
- * @property {string[]} args
96
- * A list of prepended arguments.
97
- * @property {Record<string,string>} cases
98
- * A map of all cases.
99
- */
100
- /**
101
- * Most branch-based type handlers are based around "cases". For example,
102
- * `select` and `plural` compare compare a value to "case keys" to choose a
103
- * subtranslation.
104
- *
105
- * This util splits "matches" portions provided to the aforementioned handlers
106
- * into case strings, and extracts any prepended arguments (for example,
107
- * `plural` supports an `offset:n` argument used for populating the magic `#`
108
- * variable).
109
- *
110
- * @param {string} string
111
- * @return {ParseCasesResult}
112
- */
113
- export function parseCases(string?: string): ParseCasesResult;
69
+ type FormatValues = Record<string, any>;
70
+ type ProcessFunction = (message: string, values?: FormatValues) => any[];
71
+ type TypeHandler = (value: any, matches: string, locale: string, values: FormatValues, process: ProcessFunction) => any | any[];
72
+
114
73
  /**
115
74
  * Handler for `plural` statements within ICU message syntax strings. Returns
116
75
  * a formatted string for the branch that closely matches the current value.
@@ -125,7 +84,8 @@ export function parseCases(string?: string): ParseCasesResult;
125
84
  * @param {import('./MessageFormatter.js').ProcessFunction} process
126
85
  * @return {any | any[]}
127
86
  */
128
- export function pluralTypeHandler(value: string, matches: string, locale: string, values: any, process: any): any | any[];
87
+ declare function pluralTypeHandler(value: string, matches: string, locale: string, values: FormatValues, process: ProcessFunction): any | any[];
88
+
129
89
  /**
130
90
  * Handler for `select` statements within ICU message syntax strings. Returns
131
91
  * a formatted string for the branch that closely matches the current value.
@@ -140,7 +100,40 @@ export function pluralTypeHandler(value: string, matches: string, locale: string
140
100
  * @param {import('./MessageFormatter.js').ProcessFunction} process
141
101
  * @return {any | any[]}
142
102
  */
143
- export function selectTypeHandler(value: string, matches: string, locale: string, values: any, process: any): any | any[];
103
+ declare function selectTypeHandler(value: string, matches: string, locale: string, values: FormatValues, process: ProcessFunction): any | any[];
104
+
105
+ /**
106
+ * @typedef ParseCasesResult
107
+ * @property {string[]} args
108
+ * A list of prepended arguments.
109
+ * @property {Record<string,string>} cases
110
+ * A map of all cases.
111
+ */
112
+ /**
113
+ * Most branch-based type handlers are based around "cases". For example,
114
+ * `select` and `plural` compare compare a value to "case keys" to choose a
115
+ * subtranslation.
116
+ *
117
+ * This util splits "matches" portions provided to the aforementioned handlers
118
+ * into case strings, and extracts any prepended arguments (for example,
119
+ * `plural` supports an `offset:n` argument used for populating the magic `#`
120
+ * variable).
121
+ *
122
+ * @param {string} string
123
+ * @return {ParseCasesResult}
124
+ */
125
+ declare function parseCases(string?: string): ParseCasesResult;
126
+ /**
127
+ * Finds the index of the matching closing curly bracket, including through
128
+ * strings that could have nested brackets.
129
+ *
130
+ * @param {string} string
131
+ * @param {number} fromIndex
132
+ * @return {number}
133
+ * The index of the matching closing bracket, or -1 if no closing bracket
134
+ * could be found.
135
+ */
136
+ declare function findClosingBracket(string: string, fromIndex: number): number;
144
137
  /**
145
138
  * Split a `{key, type, format}` block into those 3 parts, taking into account
146
139
  * nested message syntax that can exist in the `format` part.
@@ -150,4 +143,16 @@ export function selectTypeHandler(value: string, matches: string, locale: string
150
143
  * An array with `key`, `type`, and `format` items in that order, if present
151
144
  * in the formatted argument block.
152
145
  */
153
- export function splitFormattedArgument(block: string): string[];
146
+ declare function splitFormattedArgument(block: string): string[];
147
+ type ParseCasesResult = {
148
+ /**
149
+ * A list of prepended arguments.
150
+ */
151
+ args: string[];
152
+ /**
153
+ * A map of all cases.
154
+ */
155
+ cases: Record<string, string>;
156
+ };
157
+
158
+ export { MessageFormatter, findClosingBracket, parseCases, pluralTypeHandler, selectTypeHandler, splitFormattedArgument };