@adrienlcp/i18n 0.1.1 → 0.1.2

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.
Files changed (2) hide show
  1. package/dist/translator.js +20 -7
  2. package/package.json +1 -1
@@ -106,9 +106,10 @@ const FORMATTED_COUNT = '{?}';
106
106
  * That is dictionary text rather than a caller's value, so the rule above is
107
107
  * untouched.
108
108
  *
109
- * A value of the wrong type, or one the message never asked for, leaves its
110
- * placeholder standing rather than throwing: one bad value costs one word, not
111
- * the whole sentence.
109
+ * A value of the wrong type, one the message never asked for, or one the
110
+ * locale cannot print — an invalid `Date`, an infinite count, a code that names
111
+ * no language — leaves its placeholder standing rather than throwing: one bad
112
+ * value costs one word, not the whole sentence.
112
113
  */
113
114
  const substitute = ({ expanding = [], formatters, message, options, values }) => message.replace(PLACEHOLDER, (placeholder, name, type) => {
114
115
  const value = values[name];
@@ -117,7 +118,7 @@ const substitute = ({ expanding = [], formatters, message, options, values }) =>
117
118
  }
118
119
  switch (type) {
119
120
  case 'date':
120
- return value instanceof Date
121
+ return isValidDate(value)
121
122
  ? formatters.date(options.date?.[name]).format(value)
122
123
  : placeholder;
123
124
  case 'displayname':
@@ -167,7 +168,7 @@ const substitute = ({ expanding = [], formatters, message, options, values }) =>
167
168
  })
168
169
  : placeholder;
169
170
  case 'relative':
170
- return typeof value === 'number'
171
+ return typeof value === 'number' && Number.isFinite(value)
171
172
  ? (relativeTime({
172
173
  count: value,
173
174
  formatters,
@@ -220,9 +221,21 @@ const pluralize = ({ count, formatters, forms }) => {
220
221
  /**
221
222
  * A message declaring `{x:displayname}` must declare the kind of name it wants,
222
223
  * so the options are never absent — but the runtime shape stays loose, and
223
- * `Intl.DisplayNames` throws without a `type`. Nothing rather than a crash.
224
+ * `Intl.DisplayNames` throws without a `type`, and on a string that is no code
225
+ * at all (`'not a language'`). Nothing rather than a crash.
224
226
  */
225
- const displayName = ({ formatters, of, options }) => options === undefined ? undefined : formatters.displayname(options).of(of);
227
+ const displayName = ({ formatters, of, options }) => {
228
+ if (options === undefined) {
229
+ return undefined;
230
+ }
231
+ try {
232
+ return formatters.displayname(options).of(of);
233
+ }
234
+ catch {
235
+ return undefined;
236
+ }
237
+ };
238
+ const isValidDate = (value) => value instanceof Date && !Number.isNaN(value.getTime());
226
239
  /** Same reasoning: the unit is declared with the message, or there is none. */
227
240
  const relativeTime = ({ count, formatters, unit }) => unit === undefined
228
241
  ? undefined
package/package.json CHANGED
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "sideEffects": false,
28
28
  "type": "module",
29
- "version": "0.1.1",
29
+ "version": "0.1.2",
30
30
  "scripts": {
31
31
  "build": "tsc -p tsconfig.build.json",
32
32
  "test": "vitest run",