@intlify/core-base 11.4.6 → 11.4.8

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,5 +1,5 @@
1
1
  /*!
2
- * core-base v11.4.6
2
+ * core-base v11.4.8
3
3
  * (c) 2026 kazuya kawaguchi
4
4
  * Released under the MIT License.
5
5
  */
@@ -747,7 +747,7 @@ function getWarnMessage(code, ...args) {
747
747
  * Intlify core-base version
748
748
  * @internal
749
749
  */
750
- const VERSION = '11.4.6';
750
+ const VERSION = '11.4.8';
751
751
  const NOT_REOSLVED = -1;
752
752
  const DEFAULT_LOCALE = 'en-US';
753
753
  const MISSING_RESOLVE_VALUE = '';
@@ -997,6 +997,88 @@ function isImplicitFallback(targetLocale, locales) {
997
997
  }
998
998
  /* eslint-enable @typescript-eslint/no-explicit-any */
999
999
 
1000
+ function resolveFormatLocale(context, key, locale, formats, missingWarn, fallbackWarn, type) {
1001
+ const { fallbackLocale, localeFallbacker, onWarn } = context;
1002
+ const locales = localeFallbacker(context, // eslint-disable-line @typescript-eslint/no-explicit-any
1003
+ fallbackLocale, locale);
1004
+ let from = locale;
1005
+ for (let i = 0; i < locales.length; i++) {
1006
+ const targetLocale = locales[i];
1007
+ if (locale !== targetLocale &&
1008
+ isTranslateFallbackWarn(fallbackWarn, key)) {
1009
+ onWarn(getWarnMessage(type === 'datetime format'
1010
+ ? CoreWarnCodes.FALLBACK_TO_DATE_FORMAT
1011
+ : CoreWarnCodes.FALLBACK_TO_NUMBER_FORMAT, {
1012
+ key,
1013
+ target: targetLocale
1014
+ }));
1015
+ }
1016
+ if (locale !== targetLocale) {
1017
+ const emitter = context.__v_emitter;
1018
+ if (emitter) {
1019
+ emitter.emit('fallback', {
1020
+ type,
1021
+ key,
1022
+ from,
1023
+ to: targetLocale,
1024
+ groupId: `${type}:${key}`
1025
+ });
1026
+ }
1027
+ }
1028
+ const format = (formats[targetLocale] || {})[key];
1029
+ if (shared.isPlainObject(format) && shared.isString(targetLocale)) {
1030
+ return targetLocale;
1031
+ }
1032
+ handleMissing(context, key, targetLocale, missingWarn, type);
1033
+ from = targetLocale;
1034
+ }
1035
+ return null;
1036
+ }
1037
+ function getFormatterCacheKey(locale, key, overrides) {
1038
+ let id = `${locale}__${key}`;
1039
+ if (shared.isPlainObject(overrides) && !shared.isEmptyObject(overrides)) {
1040
+ id = `${id}__${JSON.stringify(overrides)}`;
1041
+ }
1042
+ return id;
1043
+ }
1044
+ function clearFormatCache(formatters, locale, format) {
1045
+ for (const key in format) {
1046
+ const prefix = `${locale}__${key}`;
1047
+ for (const id of formatters.keys()) {
1048
+ if (id === prefix || id.startsWith(`${prefix}__`)) {
1049
+ formatters.delete(id);
1050
+ }
1051
+ }
1052
+ }
1053
+ }
1054
+ function parseFormatArgs(args, options, initialOverrides, optionsKeys) {
1055
+ const [, arg2, arg3, arg4] = args;
1056
+ let overrides = initialOverrides;
1057
+ if (shared.isString(arg2)) {
1058
+ options.key = arg2;
1059
+ }
1060
+ else if (shared.isPlainObject(arg2)) {
1061
+ Object.keys(arg2).forEach(key => {
1062
+ if (optionsKeys.includes(key)) {
1063
+ overrides[key] = arg2[key];
1064
+ }
1065
+ else {
1066
+ options[key] = arg2[key];
1067
+ }
1068
+ });
1069
+ }
1070
+ if (shared.isString(arg3)) {
1071
+ options.locale = arg3;
1072
+ }
1073
+ else if (shared.isPlainObject(arg3)) {
1074
+ overrides = arg3;
1075
+ }
1076
+ if (shared.isPlainObject(arg4)) {
1077
+ overrides = arg4;
1078
+ }
1079
+ return overrides;
1080
+ }
1081
+
1000
1082
  const intlDefined = typeof Intl !== 'undefined';
1001
1083
  const Availabilities = {
1002
1084
  dateTimeFormat: intlDefined && typeof Intl.DateTimeFormat !== 'undefined',
@@ -1005,7 +1087,7 @@ const Availabilities = {
1005
1087
 
1006
1088
  // implementation of `datetime` function
1007
1089
  function datetime(context, ...args) {
1008
- const { datetimeFormats, unresolving, fallbackLocale, onWarn, localeFallbacker } = context;
1090
+ const { datetimeFormats, unresolving, onWarn } = context;
1009
1091
  const { __datetimeFormatters } = context;
1010
1092
  if (!Availabilities.dateTimeFormat) {
1011
1093
  onWarn(getWarnMessage(CoreWarnCodes.CANNOT_FORMAT_DATE));
@@ -1028,57 +1110,16 @@ function datetime(context, ...args) {
1028
1110
  : context.fallbackWarn;
1029
1111
  const part = !!options.part;
1030
1112
  const locale = getLocale(context, options);
1031
- const locales = localeFallbacker(context, // eslint-disable-line @typescript-eslint/no-explicit-any
1032
- fallbackLocale, locale);
1033
1113
  if (!shared.isString(key) || key === '') {
1034
1114
  const formatter = new Intl.DateTimeFormat(locale.replace(/!/g, ''), overrides);
1035
1115
  return !part ? formatter.format(value) : formatter.formatToParts(value);
1036
1116
  }
1037
- // resolve format
1038
- let datetimeFormat = {};
1039
- let targetLocale;
1040
- let format = null;
1041
- let from = locale;
1042
- let to = null;
1043
- const type = 'datetime format';
1044
- for (let i = 0; i < locales.length; i++) {
1045
- targetLocale = to = locales[i];
1046
- if (locale !== targetLocale &&
1047
- isTranslateFallbackWarn(fallbackWarn, key)) {
1048
- onWarn(getWarnMessage(CoreWarnCodes.FALLBACK_TO_DATE_FORMAT, {
1049
- key,
1050
- target: targetLocale
1051
- }));
1052
- }
1053
- // for vue-devtools timeline event
1054
- if (locale !== targetLocale) {
1055
- const emitter = context.__v_emitter;
1056
- if (emitter) {
1057
- emitter.emit('fallback', {
1058
- type,
1059
- key,
1060
- from,
1061
- to,
1062
- groupId: `${type}:${key}`
1063
- });
1064
- }
1065
- }
1066
- datetimeFormat =
1067
- datetimeFormats[targetLocale] || {};
1068
- format = datetimeFormat[key];
1069
- if (shared.isPlainObject(format))
1070
- break;
1071
- handleMissing(context, key, targetLocale, missingWarn, type); // eslint-disable-line @typescript-eslint/no-explicit-any
1072
- from = to;
1073
- }
1074
- // checking format and target locale
1075
- if (!shared.isPlainObject(format) || !shared.isString(targetLocale)) {
1117
+ const targetLocale = resolveFormatLocale(context, key, locale, datetimeFormats, missingWarn, fallbackWarn, 'datetime format');
1118
+ if (!shared.isString(targetLocale)) {
1076
1119
  return unresolving ? NOT_REOSLVED : key;
1077
1120
  }
1078
- let id = `${targetLocale}__${key}`;
1079
- if (!shared.isEmptyObject(overrides)) {
1080
- id = `${id}__${JSON.stringify(overrides)}`;
1081
- }
1121
+ const format = datetimeFormats[targetLocale][key];
1122
+ const id = getFormatterCacheKey(targetLocale, key, overrides);
1082
1123
  let formatter = __datetimeFormatters.get(id);
1083
1124
  if (!formatter) {
1084
1125
  formatter = new Intl.DateTimeFormat(targetLocale, shared.assign({}, format, overrides));
@@ -1111,9 +1152,9 @@ const DATETIME_FORMAT_OPTIONS_KEYS = [
1111
1152
  ];
1112
1153
  /** @internal */
1113
1154
  function parseDateTimeArgs(...args) {
1114
- const [arg1, arg2, arg3, arg4] = args;
1155
+ const [arg1] = args;
1115
1156
  const options = shared.create();
1116
- let overrides = shared.create();
1157
+ const initialOverrides = shared.create();
1117
1158
  let value;
1118
1159
  if (shared.isString(arg1)) {
1119
1160
  // Only allow ISO strings - other date formats are often supported,
@@ -1150,45 +1191,18 @@ function parseDateTimeArgs(...args) {
1150
1191
  else {
1151
1192
  throw createCoreError(CoreErrorCodes.INVALID_ARGUMENT);
1152
1193
  }
1153
- if (shared.isString(arg2)) {
1154
- options.key = arg2;
1155
- }
1156
- else if (shared.isPlainObject(arg2)) {
1157
- Object.keys(arg2).forEach(key => {
1158
- if (DATETIME_FORMAT_OPTIONS_KEYS.includes(key)) {
1159
- overrides[key] = arg2[key];
1160
- }
1161
- else {
1162
- options[key] = arg2[key];
1163
- }
1164
- });
1165
- }
1166
- if (shared.isString(arg3)) {
1167
- options.locale = arg3;
1168
- }
1169
- else if (shared.isPlainObject(arg3)) {
1170
- overrides = arg3;
1171
- }
1172
- if (shared.isPlainObject(arg4)) {
1173
- overrides = arg4;
1174
- }
1194
+ const overrides = parseFormatArgs(args, options, initialOverrides, DATETIME_FORMAT_OPTIONS_KEYS);
1175
1195
  return [options.key || '', value, options, overrides];
1176
1196
  }
1177
1197
  /** @internal */
1178
1198
  function clearDateTimeFormat(ctx, locale, format) {
1179
1199
  const context = ctx;
1180
- for (const key in format) {
1181
- const id = `${locale}__${key}`;
1182
- if (!context.__datetimeFormatters.has(id)) {
1183
- continue;
1184
- }
1185
- context.__datetimeFormatters.delete(id);
1186
- }
1200
+ clearFormatCache(context.__datetimeFormatters, locale, format);
1187
1201
  }
1188
1202
 
1189
1203
  // implementation of `number` function
1190
1204
  function number(context, ...args) {
1191
- const { numberFormats, unresolving, fallbackLocale, onWarn, localeFallbacker } = context;
1205
+ const { numberFormats, unresolving, onWarn } = context;
1192
1206
  const { __numberFormatters } = context;
1193
1207
  if (!Availabilities.numberFormat) {
1194
1208
  onWarn(getWarnMessage(CoreWarnCodes.CANNOT_FORMAT_NUMBER));
@@ -1211,57 +1225,16 @@ function number(context, ...args) {
1211
1225
  : context.fallbackWarn;
1212
1226
  const part = !!options.part;
1213
1227
  const locale = getLocale(context, options);
1214
- const locales = localeFallbacker(context, // eslint-disable-line @typescript-eslint/no-explicit-any
1215
- fallbackLocale, locale);
1216
1228
  if (!shared.isString(key) || key === '') {
1217
1229
  const formatter = new Intl.NumberFormat(locale.replace(/!/g, ''), overrides);
1218
1230
  return !part ? formatter.format(value) : formatter.formatToParts(value);
1219
1231
  }
1220
- // resolve format
1221
- let numberFormat = {};
1222
- let targetLocale;
1223
- let format = null;
1224
- let from = locale;
1225
- let to = null;
1226
- const type = 'number format';
1227
- for (let i = 0; i < locales.length; i++) {
1228
- targetLocale = to = locales[i];
1229
- if (locale !== targetLocale &&
1230
- isTranslateFallbackWarn(fallbackWarn, key)) {
1231
- onWarn(getWarnMessage(CoreWarnCodes.FALLBACK_TO_NUMBER_FORMAT, {
1232
- key,
1233
- target: targetLocale
1234
- }));
1235
- }
1236
- // for vue-devtools timeline event
1237
- if (locale !== targetLocale) {
1238
- const emitter = context.__v_emitter;
1239
- if (emitter) {
1240
- emitter.emit('fallback', {
1241
- type,
1242
- key,
1243
- from,
1244
- to,
1245
- groupId: `${type}:${key}`
1246
- });
1247
- }
1248
- }
1249
- numberFormat =
1250
- numberFormats[targetLocale] || {};
1251
- format = numberFormat[key];
1252
- if (shared.isPlainObject(format))
1253
- break;
1254
- handleMissing(context, key, targetLocale, missingWarn, type); // eslint-disable-line @typescript-eslint/no-explicit-any
1255
- from = to;
1256
- }
1257
- // checking format and target locale
1258
- if (!shared.isPlainObject(format) || !shared.isString(targetLocale)) {
1232
+ const targetLocale = resolveFormatLocale(context, key, locale, numberFormats, missingWarn, fallbackWarn, 'number format');
1233
+ if (!shared.isString(targetLocale)) {
1259
1234
  return unresolving ? NOT_REOSLVED : key;
1260
1235
  }
1261
- let id = `${targetLocale}__${key}`;
1262
- if (!shared.isEmptyObject(overrides)) {
1263
- id = `${id}__${JSON.stringify(overrides)}`;
1264
- }
1236
+ const format = numberFormats[targetLocale][key];
1237
+ const id = getFormatterCacheKey(targetLocale, key, overrides);
1265
1238
  let formatter = __numberFormatters.get(id);
1266
1239
  if (!formatter) {
1267
1240
  formatter = new Intl.NumberFormat(targetLocale, shared.assign({}, format, overrides));
@@ -1294,47 +1267,20 @@ const NUMBER_FORMAT_OPTIONS_KEYS = [
1294
1267
  ];
1295
1268
  /** @internal */
1296
1269
  function parseNumberArgs(...args) {
1297
- const [arg1, arg2, arg3, arg4] = args;
1270
+ const [arg1] = args;
1298
1271
  const options = shared.create();
1299
- let overrides = shared.create();
1272
+ const initialOverrides = shared.create();
1300
1273
  if (!shared.isNumber(arg1)) {
1301
1274
  throw createCoreError(CoreErrorCodes.INVALID_ARGUMENT);
1302
1275
  }
1303
1276
  const value = arg1;
1304
- if (shared.isString(arg2)) {
1305
- options.key = arg2;
1306
- }
1307
- else if (shared.isPlainObject(arg2)) {
1308
- Object.keys(arg2).forEach(key => {
1309
- if (NUMBER_FORMAT_OPTIONS_KEYS.includes(key)) {
1310
- overrides[key] = arg2[key];
1311
- }
1312
- else {
1313
- options[key] = arg2[key];
1314
- }
1315
- });
1316
- }
1317
- if (shared.isString(arg3)) {
1318
- options.locale = arg3;
1319
- }
1320
- else if (shared.isPlainObject(arg3)) {
1321
- overrides = arg3;
1322
- }
1323
- if (shared.isPlainObject(arg4)) {
1324
- overrides = arg4;
1325
- }
1277
+ const overrides = parseFormatArgs(args, options, initialOverrides, NUMBER_FORMAT_OPTIONS_KEYS);
1326
1278
  return [options.key || '', value, options, overrides];
1327
1279
  }
1328
1280
  /** @internal */
1329
1281
  function clearNumberFormat(ctx, locale, format) {
1330
1282
  const context = ctx;
1331
- for (const key in format) {
1332
- const id = `${locale}__${key}`;
1333
- if (!context.__numberFormatters.has(id)) {
1334
- continue;
1335
- }
1336
- context.__numberFormatters.delete(id);
1337
- }
1283
+ clearFormatCache(context.__numberFormatters, locale, format);
1338
1284
  }
1339
1285
 
1340
1286
  const DEFAULT_MODIFIER = (str) => str;