@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.
- package/dist/translator.js +20 -7
- package/package.json +1 -1
package/dist/translator.js
CHANGED
|
@@ -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,
|
|
110
|
-
*
|
|
111
|
-
*
|
|
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
|
|
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
|
|
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 }) =>
|
|
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
|