@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,21 +1,11 @@
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
  */
6
6
  var IntlifyCoreBase = (function (exports) {
7
7
  'use strict';
8
8
 
9
- function warn(msg, err) {
10
- if (typeof console !== 'undefined') {
11
- console.warn(`[intlify] ` + msg);
12
- /* istanbul ignore if */
13
- if (err) {
14
- console.warn(err.stack);
15
- }
16
- }
17
- }
18
-
19
9
  /**
20
10
  * Original Utilities
21
11
  * written by kazuya kawaguchi
@@ -66,6 +56,86 @@ var IntlifyCoreBase = (function (exports) {
66
56
  const assign = Object.assign;
67
57
  const _create = Object.create;
68
58
  const create = (obj = null) => _create(obj);
59
+ const hasOwnProperty = Object.prototype.hasOwnProperty;
60
+ function hasOwn(obj, key) {
61
+ return hasOwnProperty.call(obj, key);
62
+ }
63
+ /* eslint-enable */
64
+ /**
65
+ * Useful Utilities By Evan you
66
+ * Modified by kazuya kawaguchi
67
+ * MIT License
68
+ * https://github.com/vuejs/vue-next/blob/master/packages/shared/src/index.ts
69
+ * https://github.com/vuejs/vue-next/blob/master/packages/shared/src/codeframe.ts
70
+ */
71
+ const isArray = Array.isArray;
72
+ const isFunction = (val) => typeof val === 'function';
73
+ const isString = (val) => typeof val === 'string';
74
+ const isBoolean = (val) => typeof val === 'boolean';
75
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
76
+ const isObject = (val) => val !== null && typeof val === 'object';
77
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
78
+ const isPromise = (val) => {
79
+ return isObject(val) && isFunction(val.then) && isFunction(val.catch);
80
+ };
81
+ const objectToString = Object.prototype.toString;
82
+ const toTypeString = (value) => objectToString.call(value);
83
+ const isPlainObject = (val) => toTypeString(val) === '[object Object]';
84
+ // for converting list and named values to displayed strings.
85
+ const toDisplayString = (val) => {
86
+ return val == null
87
+ ? ''
88
+ : isArray(val) || (isPlainObject(val) && val.toString === objectToString)
89
+ ? JSON.stringify(val, null, 2)
90
+ : String(val);
91
+ };
92
+ function join(items, separator = '') {
93
+ return items.reduce((str, item, index) => (index === 0 ? str + item : str + separator + item), '');
94
+ }
95
+ const RANGE = 2;
96
+ function generateCodeFrame(source, start = 0, end = source.length) {
97
+ const lines = source.split(/\r?\n/);
98
+ let count = 0;
99
+ const res = [];
100
+ for (let i = 0; i < lines.length; i++) {
101
+ count += lines[i].length + 1;
102
+ if (count >= start) {
103
+ for (let j = i - RANGE; j <= i + RANGE || end > count; j++) {
104
+ if (j < 0 || j >= lines.length)
105
+ continue;
106
+ const line = j + 1;
107
+ res.push(`${line}${' '.repeat(3 - String(line).length)}| ${lines[j]}`);
108
+ const lineLength = lines[j].length;
109
+ if (j === i) {
110
+ // push underline
111
+ const pad = start - (count - lineLength) + 1;
112
+ const length = Math.max(1, end > count ? lineLength - pad : end - start);
113
+ res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));
114
+ }
115
+ else if (j > i) {
116
+ if (end > count) {
117
+ const length = Math.max(Math.min(end - count, lineLength), 1);
118
+ res.push(` | ` + '^'.repeat(length));
119
+ }
120
+ count += lineLength + 1;
121
+ }
122
+ }
123
+ break;
124
+ }
125
+ }
126
+ return res.join('\n');
127
+ }
128
+
129
+ function warn(msg, err) {
130
+ if (typeof console !== 'undefined') {
131
+ console.warn(`[intlify] ` + msg);
132
+ /* istanbul ignore if */
133
+ if (err) {
134
+ console.warn(err.stack);
135
+ }
136
+ }
137
+ }
138
+
69
139
  function escapeHtml(rawText) {
70
140
  return rawText
71
141
  .replace(/&/g, '&amp;') // escape `&` first to avoid double escaping
@@ -78,16 +148,37 @@ var IntlifyCoreBase = (function (exports) {
78
148
  }
79
149
  function escapeAttributeValue(value) {
80
150
  return value
81
- .replace(/&(?![a-zA-Z0-9#]{2,6};)/g, '&amp;') // escape unescaped `&`
151
+ .replace(/&(?![a-z0-9#]{2,6};)/gi, '&amp;') // escape unescaped `&`
82
152
  .replace(/"/g, '&quot;')
83
153
  .replace(/'/g, '&apos;')
84
154
  .replace(/</g, '&lt;')
85
155
  .replace(/>/g, '&gt;');
86
156
  }
87
- const javascriptSchemePattern = /^\s*javascript\s*(?::|&#0*58;?|&#x0*3a;?|&colon;?)/i;
157
+ const javascriptSchemePattern = /^javascript:/i;
88
158
  const urlAttributePattern = /^(?:href|src|action|formaction)$/i;
159
+ const numericCharacterReferencePattern = /&#(?:x([0-9a-f]+)|(\d+));?/gi;
160
+ const namedWhitespaceCharacterReferencePattern = /&(?:Tab|NewLine);/g;
161
+ const colonCharacterReferencePattern = /&colon;?/gi;
162
+ // eslint-disable-next-line no-control-regex -- URL scheme normalization requires the full control range
163
+ const controlOrWhitespacePattern = /[\u0000-\u0020\u007f-\u009f]/g;
164
+ const eventHandlerPattern = /(?:^|[\s"'<>/])on\w+\s*=\s*["']?[^"'>]+["']?/i;
165
+ const eventHandlerAttributePattern = /(^|[\s"'<>/])on(\w+\s*=)/gi;
166
+ const unquotedUrlAttributePattern = /(^|[\s"'<>/])((?:href|src|action|formaction)\s*=\s*)([^\s"'=<>`]+)/gi;
167
+ function decodeNumericCharacterReference(match, hex, decimal) {
168
+ const digits = hex || decimal;
169
+ if (!digits) {
170
+ return match;
171
+ }
172
+ const codePoint = Number.parseInt(digits, hex ? 16 : 10);
173
+ return codePoint <= 0x7f ? String.fromCharCode(codePoint) : match;
174
+ }
89
175
  function hasJavascriptScheme(value) {
90
- return javascriptSchemePattern.test(value);
176
+ const normalized = value
177
+ .replace(numericCharacterReferencePattern, decodeNumericCharacterReference)
178
+ .replace(namedWhitespaceCharacterReferencePattern, '')
179
+ .replace(colonCharacterReferencePattern, ':')
180
+ .replace(controlOrWhitespacePattern, '');
181
+ return javascriptSchemePattern.test(normalized);
91
182
  }
92
183
  function sanitizeStyleValue(value) {
93
184
  const urlPattern = /url\s*\(/gi;
@@ -151,88 +242,18 @@ var IntlifyCoreBase = (function (exports) {
151
242
  // Process attributes with single quotes
152
243
  html = html.replace(/([\w:-]+)\s*=\s*'([^']*)'/g, (_, attrName, attrValue) => `${attrName}='${sanitizeAttributeValue(attrName, attrValue)}'`);
153
244
  // Detect and neutralize event handler attributes
154
- const eventHandlerPattern = /\s*on\w+\s*=\s*["']?[^"'>]+["']?/gi;
155
245
  if (eventHandlerPattern.test(html)) {
156
246
  {
157
247
  warn('Potentially dangerous event handlers detected in translation. ' +
158
248
  'Consider removing onclick, onerror, etc. from your translation messages.');
159
249
  }
160
250
  // Neutralize event handler attributes by escaping 'on'
161
- html = html.replace(/(\s+)(on)(\w+\s*=)/gi, '$1&#111;n$3');
251
+ html = html.replace(eventHandlerAttributePattern, '$1&#111;n$2');
162
252
  }
163
253
  // Disable javascript: URLs in unquoted attributes
164
- html = html.replace(/(\s+(?:href|src|action|formaction)\s*=\s*)([^\s"'=<>`]+)/gi, (match, prefix, attrValue) => hasJavascriptScheme(attrValue) ? `${prefix}about:blank` : match);
254
+ html = html.replace(unquotedUrlAttributePattern, (match, boundary, prefix, attrValue) => hasJavascriptScheme(attrValue) ? `${boundary}${prefix}about:blank` : match);
165
255
  return html;
166
256
  }
167
- const hasOwnProperty = Object.prototype.hasOwnProperty;
168
- function hasOwn(obj, key) {
169
- return hasOwnProperty.call(obj, key);
170
- }
171
- /* eslint-enable */
172
- /**
173
- * Useful Utilities By Evan you
174
- * Modified by kazuya kawaguchi
175
- * MIT License
176
- * https://github.com/vuejs/vue-next/blob/master/packages/shared/src/index.ts
177
- * https://github.com/vuejs/vue-next/blob/master/packages/shared/src/codeframe.ts
178
- */
179
- const isArray = Array.isArray;
180
- const isFunction = (val) => typeof val === 'function';
181
- const isString = (val) => typeof val === 'string';
182
- const isBoolean = (val) => typeof val === 'boolean';
183
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
184
- const isObject = (val) => val !== null && typeof val === 'object';
185
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
186
- const isPromise = (val) => {
187
- return isObject(val) && isFunction(val.then) && isFunction(val.catch);
188
- };
189
- const objectToString = Object.prototype.toString;
190
- const toTypeString = (value) => objectToString.call(value);
191
- const isPlainObject = (val) => toTypeString(val) === '[object Object]';
192
- // for converting list and named values to displayed strings.
193
- const toDisplayString = (val) => {
194
- return val == null
195
- ? ''
196
- : isArray(val) || (isPlainObject(val) && val.toString === objectToString)
197
- ? JSON.stringify(val, null, 2)
198
- : String(val);
199
- };
200
- function join(items, separator = '') {
201
- return items.reduce((str, item, index) => (index === 0 ? str + item : str + separator + item), '');
202
- }
203
- const RANGE = 2;
204
- function generateCodeFrame(source, start = 0, end = source.length) {
205
- const lines = source.split(/\r?\n/);
206
- let count = 0;
207
- const res = [];
208
- for (let i = 0; i < lines.length; i++) {
209
- count += lines[i].length + 1;
210
- if (count >= start) {
211
- for (let j = i - RANGE; j <= i + RANGE || end > count; j++) {
212
- if (j < 0 || j >= lines.length)
213
- continue;
214
- const line = j + 1;
215
- res.push(`${line}${' '.repeat(3 - String(line).length)}| ${lines[j]}`);
216
- const lineLength = lines[j].length;
217
- if (j === i) {
218
- // push underline
219
- const pad = start - (count - lineLength) + 1;
220
- const length = Math.max(1, end > count ? lineLength - pad : end - start);
221
- res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));
222
- }
223
- else if (j > i) {
224
- if (end > count) {
225
- const length = Math.max(Math.min(end - count, lineLength), 1);
226
- res.push(` | ` + '^'.repeat(length));
227
- }
228
- count += lineLength + 1;
229
- }
230
- }
231
- break;
232
- }
233
- }
234
- return res.join('\n');
235
- }
236
257
 
237
258
  function createPosition(line, column, offset) {
238
259
  return { line, column, offset };
@@ -2507,7 +2528,7 @@ var IntlifyCoreBase = (function (exports) {
2507
2528
  * Intlify core-base version
2508
2529
  * @internal
2509
2530
  */
2510
- const VERSION = '11.4.6';
2531
+ const VERSION = '11.4.8';
2511
2532
  const NOT_REOSLVED = -1;
2512
2533
  const DEFAULT_LOCALE = 'en-US';
2513
2534
  const MISSING_RESOLVE_VALUE = '';
@@ -2754,6 +2775,88 @@ var IntlifyCoreBase = (function (exports) {
2754
2775
  }
2755
2776
  /* eslint-enable @typescript-eslint/no-explicit-any */
2756
2777
 
2778
+ function resolveFormatLocale(context, key, locale, formats, missingWarn, fallbackWarn, type) {
2779
+ const { fallbackLocale, localeFallbacker, onWarn } = context;
2780
+ const locales = localeFallbacker(context, // eslint-disable-line @typescript-eslint/no-explicit-any
2781
+ fallbackLocale, locale);
2782
+ let from = locale;
2783
+ for (let i = 0; i < locales.length; i++) {
2784
+ const targetLocale = locales[i];
2785
+ if (locale !== targetLocale &&
2786
+ isTranslateFallbackWarn(fallbackWarn, key)) {
2787
+ onWarn(getWarnMessage(type === 'datetime format'
2788
+ ? CoreWarnCodes.FALLBACK_TO_DATE_FORMAT
2789
+ : CoreWarnCodes.FALLBACK_TO_NUMBER_FORMAT, {
2790
+ key,
2791
+ target: targetLocale
2792
+ }));
2793
+ }
2794
+ if (locale !== targetLocale) {
2795
+ const emitter = context.__v_emitter;
2796
+ if (emitter) {
2797
+ emitter.emit('fallback', {
2798
+ type,
2799
+ key,
2800
+ from,
2801
+ to: targetLocale,
2802
+ groupId: `${type}:${key}`
2803
+ });
2804
+ }
2805
+ }
2806
+ const format = (formats[targetLocale] || {})[key];
2807
+ if (isPlainObject(format) && isString(targetLocale)) {
2808
+ return targetLocale;
2809
+ }
2810
+ handleMissing(context, key, targetLocale, missingWarn, type);
2811
+ from = targetLocale;
2812
+ }
2813
+ return null;
2814
+ }
2815
+ function getFormatterCacheKey(locale, key, overrides) {
2816
+ let id = `${locale}__${key}`;
2817
+ if (isPlainObject(overrides) && !isEmptyObject(overrides)) {
2818
+ id = `${id}__${JSON.stringify(overrides)}`;
2819
+ }
2820
+ return id;
2821
+ }
2822
+ function clearFormatCache(formatters, locale, format) {
2823
+ for (const key in format) {
2824
+ const prefix = `${locale}__${key}`;
2825
+ for (const id of formatters.keys()) {
2826
+ if (id === prefix || id.startsWith(`${prefix}__`)) {
2827
+ formatters.delete(id);
2828
+ }
2829
+ }
2830
+ }
2831
+ }
2832
+ function parseFormatArgs(args, options, initialOverrides, optionsKeys) {
2833
+ const [, arg2, arg3, arg4] = args;
2834
+ let overrides = initialOverrides;
2835
+ if (isString(arg2)) {
2836
+ options.key = arg2;
2837
+ }
2838
+ else if (isPlainObject(arg2)) {
2839
+ Object.keys(arg2).forEach(key => {
2840
+ if (optionsKeys.includes(key)) {
2841
+ overrides[key] = arg2[key];
2842
+ }
2843
+ else {
2844
+ options[key] = arg2[key];
2845
+ }
2846
+ });
2847
+ }
2848
+ if (isString(arg3)) {
2849
+ options.locale = arg3;
2850
+ }
2851
+ else if (isPlainObject(arg3)) {
2852
+ overrides = arg3;
2853
+ }
2854
+ if (isPlainObject(arg4)) {
2855
+ overrides = arg4;
2856
+ }
2857
+ return overrides;
2858
+ }
2859
+
2757
2860
  const intlDefined = typeof Intl !== 'undefined';
2758
2861
  const Availabilities = {
2759
2862
  dateTimeFormat: intlDefined && typeof Intl.DateTimeFormat !== 'undefined',
@@ -2762,7 +2865,7 @@ var IntlifyCoreBase = (function (exports) {
2762
2865
 
2763
2866
  // implementation of `datetime` function
2764
2867
  function datetime(context, ...args) {
2765
- const { datetimeFormats, unresolving, fallbackLocale, onWarn, localeFallbacker } = context;
2868
+ const { datetimeFormats, unresolving, onWarn } = context;
2766
2869
  const { __datetimeFormatters } = context;
2767
2870
  if (!Availabilities.dateTimeFormat) {
2768
2871
  onWarn(getWarnMessage(CoreWarnCodes.CANNOT_FORMAT_DATE));
@@ -2785,57 +2888,16 @@ var IntlifyCoreBase = (function (exports) {
2785
2888
  : context.fallbackWarn;
2786
2889
  const part = !!options.part;
2787
2890
  const locale = getLocale(context, options);
2788
- const locales = localeFallbacker(context, // eslint-disable-line @typescript-eslint/no-explicit-any
2789
- fallbackLocale, locale);
2790
2891
  if (!isString(key) || key === '') {
2791
2892
  const formatter = new Intl.DateTimeFormat(locale.replace(/!/g, ''), overrides);
2792
2893
  return !part ? formatter.format(value) : formatter.formatToParts(value);
2793
2894
  }
2794
- // resolve format
2795
- let datetimeFormat = {};
2796
- let targetLocale;
2797
- let format = null;
2798
- let from = locale;
2799
- let to = null;
2800
- const type = 'datetime format';
2801
- for (let i = 0; i < locales.length; i++) {
2802
- targetLocale = to = locales[i];
2803
- if (locale !== targetLocale &&
2804
- isTranslateFallbackWarn(fallbackWarn, key)) {
2805
- onWarn(getWarnMessage(CoreWarnCodes.FALLBACK_TO_DATE_FORMAT, {
2806
- key,
2807
- target: targetLocale
2808
- }));
2809
- }
2810
- // for vue-devtools timeline event
2811
- if (locale !== targetLocale) {
2812
- const emitter = context.__v_emitter;
2813
- if (emitter) {
2814
- emitter.emit('fallback', {
2815
- type,
2816
- key,
2817
- from,
2818
- to,
2819
- groupId: `${type}:${key}`
2820
- });
2821
- }
2822
- }
2823
- datetimeFormat =
2824
- datetimeFormats[targetLocale] || {};
2825
- format = datetimeFormat[key];
2826
- if (isPlainObject(format))
2827
- break;
2828
- handleMissing(context, key, targetLocale, missingWarn, type); // eslint-disable-line @typescript-eslint/no-explicit-any
2829
- from = to;
2830
- }
2831
- // checking format and target locale
2832
- if (!isPlainObject(format) || !isString(targetLocale)) {
2895
+ const targetLocale = resolveFormatLocale(context, key, locale, datetimeFormats, missingWarn, fallbackWarn, 'datetime format');
2896
+ if (!isString(targetLocale)) {
2833
2897
  return unresolving ? NOT_REOSLVED : key;
2834
2898
  }
2835
- let id = `${targetLocale}__${key}`;
2836
- if (!isEmptyObject(overrides)) {
2837
- id = `${id}__${JSON.stringify(overrides)}`;
2838
- }
2899
+ const format = datetimeFormats[targetLocale][key];
2900
+ const id = getFormatterCacheKey(targetLocale, key, overrides);
2839
2901
  let formatter = __datetimeFormatters.get(id);
2840
2902
  if (!formatter) {
2841
2903
  formatter = new Intl.DateTimeFormat(targetLocale, assign({}, format, overrides));
@@ -2868,9 +2930,9 @@ var IntlifyCoreBase = (function (exports) {
2868
2930
  ];
2869
2931
  /** @internal */
2870
2932
  function parseDateTimeArgs(...args) {
2871
- const [arg1, arg2, arg3, arg4] = args;
2933
+ const [arg1] = args;
2872
2934
  const options = create();
2873
- let overrides = create();
2935
+ const initialOverrides = create();
2874
2936
  let value;
2875
2937
  if (isString(arg1)) {
2876
2938
  // Only allow ISO strings - other date formats are often supported,
@@ -2907,45 +2969,18 @@ var IntlifyCoreBase = (function (exports) {
2907
2969
  else {
2908
2970
  throw createCoreError(CoreErrorCodes.INVALID_ARGUMENT);
2909
2971
  }
2910
- if (isString(arg2)) {
2911
- options.key = arg2;
2912
- }
2913
- else if (isPlainObject(arg2)) {
2914
- Object.keys(arg2).forEach(key => {
2915
- if (DATETIME_FORMAT_OPTIONS_KEYS.includes(key)) {
2916
- overrides[key] = arg2[key];
2917
- }
2918
- else {
2919
- options[key] = arg2[key];
2920
- }
2921
- });
2922
- }
2923
- if (isString(arg3)) {
2924
- options.locale = arg3;
2925
- }
2926
- else if (isPlainObject(arg3)) {
2927
- overrides = arg3;
2928
- }
2929
- if (isPlainObject(arg4)) {
2930
- overrides = arg4;
2931
- }
2972
+ const overrides = parseFormatArgs(args, options, initialOverrides, DATETIME_FORMAT_OPTIONS_KEYS);
2932
2973
  return [options.key || '', value, options, overrides];
2933
2974
  }
2934
2975
  /** @internal */
2935
2976
  function clearDateTimeFormat(ctx, locale, format) {
2936
2977
  const context = ctx;
2937
- for (const key in format) {
2938
- const id = `${locale}__${key}`;
2939
- if (!context.__datetimeFormatters.has(id)) {
2940
- continue;
2941
- }
2942
- context.__datetimeFormatters.delete(id);
2943
- }
2978
+ clearFormatCache(context.__datetimeFormatters, locale, format);
2944
2979
  }
2945
2980
 
2946
2981
  // implementation of `number` function
2947
2982
  function number(context, ...args) {
2948
- const { numberFormats, unresolving, fallbackLocale, onWarn, localeFallbacker } = context;
2983
+ const { numberFormats, unresolving, onWarn } = context;
2949
2984
  const { __numberFormatters } = context;
2950
2985
  if (!Availabilities.numberFormat) {
2951
2986
  onWarn(getWarnMessage(CoreWarnCodes.CANNOT_FORMAT_NUMBER));
@@ -2968,57 +3003,16 @@ var IntlifyCoreBase = (function (exports) {
2968
3003
  : context.fallbackWarn;
2969
3004
  const part = !!options.part;
2970
3005
  const locale = getLocale(context, options);
2971
- const locales = localeFallbacker(context, // eslint-disable-line @typescript-eslint/no-explicit-any
2972
- fallbackLocale, locale);
2973
3006
  if (!isString(key) || key === '') {
2974
3007
  const formatter = new Intl.NumberFormat(locale.replace(/!/g, ''), overrides);
2975
3008
  return !part ? formatter.format(value) : formatter.formatToParts(value);
2976
3009
  }
2977
- // resolve format
2978
- let numberFormat = {};
2979
- let targetLocale;
2980
- let format = null;
2981
- let from = locale;
2982
- let to = null;
2983
- const type = 'number format';
2984
- for (let i = 0; i < locales.length; i++) {
2985
- targetLocale = to = locales[i];
2986
- if (locale !== targetLocale &&
2987
- isTranslateFallbackWarn(fallbackWarn, key)) {
2988
- onWarn(getWarnMessage(CoreWarnCodes.FALLBACK_TO_NUMBER_FORMAT, {
2989
- key,
2990
- target: targetLocale
2991
- }));
2992
- }
2993
- // for vue-devtools timeline event
2994
- if (locale !== targetLocale) {
2995
- const emitter = context.__v_emitter;
2996
- if (emitter) {
2997
- emitter.emit('fallback', {
2998
- type,
2999
- key,
3000
- from,
3001
- to,
3002
- groupId: `${type}:${key}`
3003
- });
3004
- }
3005
- }
3006
- numberFormat =
3007
- numberFormats[targetLocale] || {};
3008
- format = numberFormat[key];
3009
- if (isPlainObject(format))
3010
- break;
3011
- handleMissing(context, key, targetLocale, missingWarn, type); // eslint-disable-line @typescript-eslint/no-explicit-any
3012
- from = to;
3013
- }
3014
- // checking format and target locale
3015
- if (!isPlainObject(format) || !isString(targetLocale)) {
3010
+ const targetLocale = resolveFormatLocale(context, key, locale, numberFormats, missingWarn, fallbackWarn, 'number format');
3011
+ if (!isString(targetLocale)) {
3016
3012
  return unresolving ? NOT_REOSLVED : key;
3017
3013
  }
3018
- let id = `${targetLocale}__${key}`;
3019
- if (!isEmptyObject(overrides)) {
3020
- id = `${id}__${JSON.stringify(overrides)}`;
3021
- }
3014
+ const format = numberFormats[targetLocale][key];
3015
+ const id = getFormatterCacheKey(targetLocale, key, overrides);
3022
3016
  let formatter = __numberFormatters.get(id);
3023
3017
  if (!formatter) {
3024
3018
  formatter = new Intl.NumberFormat(targetLocale, assign({}, format, overrides));
@@ -3051,47 +3045,20 @@ var IntlifyCoreBase = (function (exports) {
3051
3045
  ];
3052
3046
  /** @internal */
3053
3047
  function parseNumberArgs(...args) {
3054
- const [arg1, arg2, arg3, arg4] = args;
3048
+ const [arg1] = args;
3055
3049
  const options = create();
3056
- let overrides = create();
3050
+ const initialOverrides = create();
3057
3051
  if (!isNumber(arg1)) {
3058
3052
  throw createCoreError(CoreErrorCodes.INVALID_ARGUMENT);
3059
3053
  }
3060
3054
  const value = arg1;
3061
- if (isString(arg2)) {
3062
- options.key = arg2;
3063
- }
3064
- else if (isPlainObject(arg2)) {
3065
- Object.keys(arg2).forEach(key => {
3066
- if (NUMBER_FORMAT_OPTIONS_KEYS.includes(key)) {
3067
- overrides[key] = arg2[key];
3068
- }
3069
- else {
3070
- options[key] = arg2[key];
3071
- }
3072
- });
3073
- }
3074
- if (isString(arg3)) {
3075
- options.locale = arg3;
3076
- }
3077
- else if (isPlainObject(arg3)) {
3078
- overrides = arg3;
3079
- }
3080
- if (isPlainObject(arg4)) {
3081
- overrides = arg4;
3082
- }
3055
+ const overrides = parseFormatArgs(args, options, initialOverrides, NUMBER_FORMAT_OPTIONS_KEYS);
3083
3056
  return [options.key || '', value, options, overrides];
3084
3057
  }
3085
3058
  /** @internal */
3086
3059
  function clearNumberFormat(ctx, locale, format) {
3087
3060
  const context = ctx;
3088
- for (const key in format) {
3089
- const id = `${locale}__${key}`;
3090
- if (!context.__numberFormatters.has(id)) {
3091
- continue;
3092
- }
3093
- context.__numberFormatters.delete(id);
3094
- }
3061
+ clearFormatCache(context.__numberFormatters, locale, format);
3095
3062
  }
3096
3063
 
3097
3064
  const DEFAULT_MODIFIER = (str) => str;