@intlify/core-base 9.14.3 → 9.14.5

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 v9.14.3
2
+ * core-base v9.14.5
3
3
  * (c) 2025 kazuya kawaguchi
4
4
  * Released under the MIT License.
5
5
  */
@@ -8,6 +8,80 @@
8
8
  var messageCompiler = require('@intlify/message-compiler');
9
9
  var shared = require('@intlify/shared');
10
10
 
11
+ function isMessageAST(val) {
12
+ return (shared.isObject(val) &&
13
+ resolveType(val) === 0 &&
14
+ (shared.hasOwn(val, 'b') || shared.hasOwn(val, 'body')));
15
+ }
16
+ const PROPS_BODY = ['b', 'body'];
17
+ function resolveBody(node) {
18
+ return resolveProps(node, PROPS_BODY);
19
+ }
20
+ const PROPS_CASES = ['c', 'cases'];
21
+ function resolveCases(node) {
22
+ return resolveProps(node, PROPS_CASES, []);
23
+ }
24
+ const PROPS_STATIC = ['s', 'static'];
25
+ function resolveStatic(node) {
26
+ return resolveProps(node, PROPS_STATIC);
27
+ }
28
+ const PROPS_ITEMS = ['i', 'items'];
29
+ function resolveItems(node) {
30
+ return resolveProps(node, PROPS_ITEMS, []);
31
+ }
32
+ const PROPS_TYPE = ['t', 'type'];
33
+ function resolveType(node) {
34
+ return resolveProps(node, PROPS_TYPE);
35
+ }
36
+ const PROPS_VALUE = ['v', 'value'];
37
+ function resolveValue$1(node, type) {
38
+ const resolved = resolveProps(node, PROPS_VALUE);
39
+ if (resolved != null) {
40
+ return resolved;
41
+ }
42
+ else {
43
+ throw createUnhandleNodeError(type);
44
+ }
45
+ }
46
+ const PROPS_MODIFIER = ['m', 'modifier'];
47
+ function resolveLinkedModifier(node) {
48
+ return resolveProps(node, PROPS_MODIFIER);
49
+ }
50
+ const PROPS_KEY = ['k', 'key'];
51
+ function resolveLinkedKey(node) {
52
+ const resolved = resolveProps(node, PROPS_KEY);
53
+ if (resolved) {
54
+ return resolved;
55
+ }
56
+ else {
57
+ throw createUnhandleNodeError(6 /* NodeTypes.Linked */);
58
+ }
59
+ }
60
+ function resolveProps(node, props, defaultValue) {
61
+ for (let i = 0; i < props.length; i++) {
62
+ const prop = props[i];
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
+ if (shared.hasOwn(node, prop) && node[prop] != null) {
65
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
+ return node[prop];
67
+ }
68
+ }
69
+ return defaultValue;
70
+ }
71
+ const AST_NODE_PROPS_KEYS = [
72
+ ...PROPS_BODY,
73
+ ...PROPS_CASES,
74
+ ...PROPS_STATIC,
75
+ ...PROPS_ITEMS,
76
+ ...PROPS_KEY,
77
+ ...PROPS_MODIFIER,
78
+ ...PROPS_VALUE,
79
+ ...PROPS_TYPE
80
+ ];
81
+ function createUnhandleNodeError(type) {
82
+ return new Error(`unhandled node type: ${type}`);
83
+ }
84
+
11
85
  const pathStateMachine = [];
12
86
  pathStateMachine[0 /* States.BEFORE_PATH */] = {
13
87
  ["w" /* PathCharTypes.WORKSPACE */]: [0 /* States.BEFORE_PATH */],
@@ -241,7 +315,7 @@ function resolveWithKeyValue(obj, path) {
241
315
  *
242
316
  * @VueI18nGeneral
243
317
  */
244
- function resolveValue$1(obj, path) {
318
+ function resolveValue(obj, path) {
245
319
  // check object
246
320
  if (!shared.isObject(obj)) {
247
321
  return null;
@@ -263,7 +337,16 @@ function resolveValue$1(obj, path) {
263
337
  let last = obj;
264
338
  let i = 0;
265
339
  while (i < len) {
266
- const val = last[hit[i]];
340
+ const key = hit[i];
341
+ /**
342
+ * NOTE:
343
+ * if `key` is intlify message format AST node key and `last` is intlify message format AST, skip it.
344
+ * because the AST node is not a key-value structure.
345
+ */
346
+ if (AST_NODE_PROPS_KEYS.includes(key) && isMessageAST(last)) {
347
+ return null;
348
+ }
349
+ const val = last[key];
267
350
  if (val === undefined) {
268
351
  return null;
269
352
  }
@@ -635,7 +718,7 @@ function appendItemToChain(chain, target, blocks) {
635
718
  * Intlify core-base version
636
719
  * @internal
637
720
  */
638
- const VERSION = '9.14.3';
721
+ const VERSION = '9.14.5';
639
722
  const NOT_REOSLVED = -1;
640
723
  const DEFAULT_LOCALE = 'en-US';
641
724
  const MISSING_RESOLVE_VALUE = '';
@@ -907,14 +990,6 @@ function formatParts(ctx, ast) {
907
990
  return formatMessageParts(ctx, body);
908
991
  }
909
992
  }
910
- const PROPS_BODY = ['b', 'body'];
911
- function resolveBody(node) {
912
- return resolveProps(node, PROPS_BODY);
913
- }
914
- const PROPS_CASES = ['c', 'cases'];
915
- function resolveCases(node) {
916
- return resolveProps(node, PROPS_CASES, []);
917
- }
918
993
  function formatMessageParts(ctx, node) {
919
994
  const static_ = resolveStatic(node);
920
995
  if (static_ != null) {
@@ -927,22 +1002,14 @@ function formatMessageParts(ctx, node) {
927
1002
  return ctx.normalize(messages);
928
1003
  }
929
1004
  }
930
- const PROPS_STATIC = ['s', 'static'];
931
- function resolveStatic(node) {
932
- return resolveProps(node, PROPS_STATIC);
933
- }
934
- const PROPS_ITEMS = ['i', 'items'];
935
- function resolveItems(node) {
936
- return resolveProps(node, PROPS_ITEMS, []);
937
- }
938
1005
  function formatMessagePart(ctx, node) {
939
1006
  const type = resolveType(node);
940
1007
  switch (type) {
941
1008
  case 3 /* NodeTypes.Text */: {
942
- return resolveValue(node, type);
1009
+ return resolveValue$1(node, type);
943
1010
  }
944
1011
  case 9 /* NodeTypes.Literal */: {
945
- return resolveValue(node, type);
1012
+ return resolveValue$1(node, type);
946
1013
  }
947
1014
  case 4 /* NodeTypes.Named */: {
948
1015
  const named = node;
@@ -971,57 +1038,15 @@ function formatMessagePart(ctx, node) {
971
1038
  return ctx.linked(formatMessagePart(ctx, key), modifier ? formatMessagePart(ctx, modifier) : undefined, ctx.type);
972
1039
  }
973
1040
  case 7 /* NodeTypes.LinkedKey */: {
974
- return resolveValue(node, type);
1041
+ return resolveValue$1(node, type);
975
1042
  }
976
1043
  case 8 /* NodeTypes.LinkedModifier */: {
977
- return resolveValue(node, type);
1044
+ return resolveValue$1(node, type);
978
1045
  }
979
1046
  default:
980
1047
  throw new Error(`unhandled node on format message part: ${type}`);
981
1048
  }
982
1049
  }
983
- const PROPS_TYPE = ['t', 'type'];
984
- function resolveType(node) {
985
- return resolveProps(node, PROPS_TYPE);
986
- }
987
- const PROPS_VALUE = ['v', 'value'];
988
- function resolveValue(node, type) {
989
- const resolved = resolveProps(node, PROPS_VALUE);
990
- if (resolved) {
991
- return resolved;
992
- }
993
- else {
994
- throw createUnhandleNodeError(type);
995
- }
996
- }
997
- const PROPS_MODIFIER = ['m', 'modifier'];
998
- function resolveLinkedModifier(node) {
999
- return resolveProps(node, PROPS_MODIFIER);
1000
- }
1001
- const PROPS_KEY = ['k', 'key'];
1002
- function resolveLinkedKey(node) {
1003
- const resolved = resolveProps(node, PROPS_KEY);
1004
- if (resolved) {
1005
- return resolved;
1006
- }
1007
- else {
1008
- throw createUnhandleNodeError(6 /* NodeTypes.Linked */);
1009
- }
1010
- }
1011
- function resolveProps(node, props, defaultValue) {
1012
- for (let i = 0; i < props.length; i++) {
1013
- const prop = props[i];
1014
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1015
- if (shared.hasOwn(node, prop) && node[prop] != null) {
1016
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1017
- return node[prop];
1018
- }
1019
- }
1020
- return defaultValue;
1021
- }
1022
- function createUnhandleNodeError(type) {
1023
- return new Error(`unhandled node type: ${type}`);
1024
- }
1025
1050
 
1026
1051
  const WARN_MESSAGE = `Detected HTML in '{source}' message. Recommend not using HTML messages to avoid XSS.`;
1027
1052
  function checkHtmlMessage(source, warnHtmlMessage) {
@@ -1042,11 +1067,6 @@ function onCompileWarn(_warn) {
1042
1067
  function clearCompileCache() {
1043
1068
  compileCache = shared.create();
1044
1069
  }
1045
- function isMessageAST(val) {
1046
- return (shared.isObject(val) &&
1047
- resolveType(val) === 0 &&
1048
- (shared.hasOwn(val, 'b') || shared.hasOwn(val, 'body')));
1049
- }
1050
1070
  function baseCompile(message, options = {}) {
1051
1071
  // error detecting on compile
1052
1072
  let detectError = false;
@@ -1231,9 +1251,13 @@ function translate(context, ...args) {
1231
1251
  const msgContext = createMessageContext(ctxOptions);
1232
1252
  const messaged = evaluateMessage(context, msg, msgContext);
1233
1253
  // if use post translation option, proceed it with handler
1234
- const ret = postTranslation
1254
+ let ret = postTranslation
1235
1255
  ? postTranslation(messaged, key)
1236
1256
  : messaged;
1257
+ // apply HTML sanitization for security
1258
+ if (escapeParameter && shared.isString(ret)) {
1259
+ ret = shared.sanitizeTranslatedHtml(ret);
1260
+ }
1237
1261
  // NOTE: experimental !!
1238
1262
  {
1239
1263
  // prettier-ignore
@@ -1879,6 +1903,7 @@ function clearNumberFormat(ctx, locale, format) {
1879
1903
 
1880
1904
  exports.CompileErrorCodes = messageCompiler.CompileErrorCodes;
1881
1905
  exports.createCompileError = messageCompiler.createCompileError;
1906
+ exports.AST_NODE_PROPS_KEYS = AST_NODE_PROPS_KEYS;
1882
1907
  exports.CoreErrorCodes = CoreErrorCodes;
1883
1908
  exports.CoreWarnCodes = CoreWarnCodes;
1884
1909
  exports.DATETIME_FORMAT_OPTIONS_KEYS = DATETIME_FORMAT_OPTIONS_KEYS;
@@ -1921,7 +1946,7 @@ exports.registerLocaleFallbacker = registerLocaleFallbacker;
1921
1946
  exports.registerMessageCompiler = registerMessageCompiler;
1922
1947
  exports.registerMessageResolver = registerMessageResolver;
1923
1948
  exports.resolveLocale = resolveLocale;
1924
- exports.resolveValue = resolveValue$1;
1949
+ exports.resolveValue = resolveValue;
1925
1950
  exports.resolveWithKeyValue = resolveWithKeyValue;
1926
1951
  exports.setAdditionalMeta = setAdditionalMeta;
1927
1952
  exports.setDevToolsHook = setDevToolsHook;
@@ -20,6 +20,8 @@ declare type AdditionalPayloads = {
20
20
  meta?: Record<string, unknown>;
21
21
  };
22
22
 
23
+ export declare const AST_NODE_PROPS_KEYS: string[];
24
+
23
25
  export declare function clearCompileCache(): void;
24
26
 
25
27
  /* Excluded from this release type: clearDateTimeFormat */
@@ -1180,7 +1182,16 @@ export declare interface TranslateOptions<Locales = Locale> extends LocaleOption
1180
1182
  fallbackWarn?: boolean;
1181
1183
  /**
1182
1184
  * @remarks
1183
- * Whether do escape parameter for list or named interpolation values
1185
+ * Whether to escape parameters for list or named interpolation values.
1186
+ * When enabled, this option:
1187
+ * - Escapes HTML special characters (`<`, `>`, `"`, `'`, `&`, `/`, `=`) in interpolation parameters
1188
+ * - Sanitizes the final translated HTML to prevent XSS attacks by:
1189
+ * - Escaping dangerous characters in HTML attribute values
1190
+ * - Neutralizing event handler attributes (onclick, onerror, etc.)
1191
+ * - Disabling javascript: URLs in href, src, action, formaction, and style attributes
1192
+ *
1193
+ * @defaultValue false
1194
+ * @see [HTML Message - Using the escapeParameter option](https://vue-i18n.intlify.dev/guide/essentials/syntax.html#using-the-escapeparameter-option)
1184
1195
  */
1185
1196
  escapeParameter?: boolean;
1186
1197
  /**
@@ -1,8 +1,25 @@
1
1
  /*!
2
- * core-base v9.14.3
2
+ * core-base v9.14.5
3
3
  * (c) 2025 kazuya kawaguchi
4
4
  * Released under the MIT License.
5
5
  */
6
+ function warn(msg, err) {
7
+ if (typeof console !== 'undefined') {
8
+ console.warn(`[intlify] ` + msg);
9
+ /* istanbul ignore if */
10
+ if (err) {
11
+ console.warn(err.stack);
12
+ }
13
+ }
14
+ }
15
+ const hasWarned = {};
16
+ function warnOnce(msg) {
17
+ if (!hasWarned[msg]) {
18
+ hasWarned[msg] = true;
19
+ warn(msg);
20
+ }
21
+ }
22
+
6
23
  /**
7
24
  * Original Utilities
8
25
  * written by kazuya kawaguchi
@@ -55,10 +72,49 @@ const _create = Object.create;
55
72
  const create = (obj = null) => _create(obj);
56
73
  function escapeHtml(rawText) {
57
74
  return rawText
75
+ .replace(/&/g, '&amp;') // escape `&` first to avoid double escaping
58
76
  .replace(/</g, '&lt;')
59
77
  .replace(/>/g, '&gt;')
60
78
  .replace(/"/g, '&quot;')
61
- .replace(/'/g, '&apos;');
79
+ .replace(/'/g, '&apos;')
80
+ .replace(/\//g, '&#x2F;') // escape `/` to prevent closing tags or JavaScript URLs
81
+ .replace(/=/g, '&#x3D;'); // escape `=` to prevent attribute injection
82
+ }
83
+ function escapeAttributeValue(value) {
84
+ return value
85
+ .replace(/&(?![a-zA-Z0-9#]{2,6};)/g, '&amp;') // escape unescaped `&`
86
+ .replace(/"/g, '&quot;')
87
+ .replace(/'/g, '&apos;')
88
+ .replace(/</g, '&lt;')
89
+ .replace(/>/g, '&gt;');
90
+ }
91
+ function sanitizeTranslatedHtml(html) {
92
+ // Escape dangerous characters in attribute values
93
+ // Process attributes with double quotes
94
+ html = html.replace(/(\w+)\s*=\s*"([^"]*)"/g, (_, attrName, attrValue) => `${attrName}="${escapeAttributeValue(attrValue)}"`);
95
+ // Process attributes with single quotes
96
+ html = html.replace(/(\w+)\s*=\s*'([^']*)'/g, (_, attrName, attrValue) => `${attrName}='${escapeAttributeValue(attrValue)}'`);
97
+ // Detect and neutralize event handler attributes
98
+ const eventHandlerPattern = /\s*on\w+\s*=\s*["']?[^"'>]+["']?/gi;
99
+ if (eventHandlerPattern.test(html)) {
100
+ {
101
+ warn('Potentially dangerous event handlers detected in translation. ' +
102
+ 'Consider removing onclick, onerror, etc. from your translation messages.');
103
+ }
104
+ // Neutralize event handler attributes by escaping 'on'
105
+ html = html.replace(/(\s+)(on)(\w+\s*=)/gi, '$1&#111;n$3');
106
+ }
107
+ // Disable javascript: URLs in various contexts
108
+ const javascriptUrlPattern = [
109
+ // In href, src, action, formaction attributes
110
+ /(\s+(?:href|src|action|formaction)\s*=\s*["']?)\s*javascript:/gi,
111
+ // In style attributes within url()
112
+ /(style\s*=\s*["'][^"']*url\s*\(\s*)javascript:/gi
113
+ ];
114
+ javascriptUrlPattern.forEach(pattern => {
115
+ html = html.replace(pattern, '$1javascript&#58;');
116
+ });
117
+ return html;
62
118
  }
63
119
  const hasOwnProperty = Object.prototype.hasOwnProperty;
64
120
  function hasOwn(obj, key) {
@@ -139,23 +195,6 @@ function incrementer(code) {
139
195
  return () => ++current;
140
196
  }
141
197
 
142
- function warn(msg, err) {
143
- if (typeof console !== 'undefined') {
144
- console.warn(`[intlify] ` + msg);
145
- /* istanbul ignore if */
146
- if (err) {
147
- console.warn(err.stack);
148
- }
149
- }
150
- }
151
- const hasWarned = {};
152
- function warnOnce(msg) {
153
- if (!hasWarned[msg]) {
154
- hasWarned[msg] = true;
155
- warn(msg);
156
- }
157
- }
158
-
159
198
  function createPosition(line, column, offset) {
160
199
  return { line, column, offset };
161
200
  }
@@ -1746,6 +1785,80 @@ function baseCompile$1(source, options = {}) {
1746
1785
  }
1747
1786
  }
1748
1787
 
1788
+ function isMessageAST(val) {
1789
+ return (isObject(val) &&
1790
+ resolveType(val) === 0 &&
1791
+ (hasOwn(val, 'b') || hasOwn(val, 'body')));
1792
+ }
1793
+ const PROPS_BODY = ['b', 'body'];
1794
+ function resolveBody(node) {
1795
+ return resolveProps(node, PROPS_BODY);
1796
+ }
1797
+ const PROPS_CASES = ['c', 'cases'];
1798
+ function resolveCases(node) {
1799
+ return resolveProps(node, PROPS_CASES, []);
1800
+ }
1801
+ const PROPS_STATIC = ['s', 'static'];
1802
+ function resolveStatic(node) {
1803
+ return resolveProps(node, PROPS_STATIC);
1804
+ }
1805
+ const PROPS_ITEMS = ['i', 'items'];
1806
+ function resolveItems(node) {
1807
+ return resolveProps(node, PROPS_ITEMS, []);
1808
+ }
1809
+ const PROPS_TYPE = ['t', 'type'];
1810
+ function resolveType(node) {
1811
+ return resolveProps(node, PROPS_TYPE);
1812
+ }
1813
+ const PROPS_VALUE = ['v', 'value'];
1814
+ function resolveValue$1(node, type) {
1815
+ const resolved = resolveProps(node, PROPS_VALUE);
1816
+ if (resolved != null) {
1817
+ return resolved;
1818
+ }
1819
+ else {
1820
+ throw createUnhandleNodeError(type);
1821
+ }
1822
+ }
1823
+ const PROPS_MODIFIER = ['m', 'modifier'];
1824
+ function resolveLinkedModifier(node) {
1825
+ return resolveProps(node, PROPS_MODIFIER);
1826
+ }
1827
+ const PROPS_KEY = ['k', 'key'];
1828
+ function resolveLinkedKey(node) {
1829
+ const resolved = resolveProps(node, PROPS_KEY);
1830
+ if (resolved) {
1831
+ return resolved;
1832
+ }
1833
+ else {
1834
+ throw createUnhandleNodeError(6 /* NodeTypes.Linked */);
1835
+ }
1836
+ }
1837
+ function resolveProps(node, props, defaultValue) {
1838
+ for (let i = 0; i < props.length; i++) {
1839
+ const prop = props[i];
1840
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1841
+ if (hasOwn(node, prop) && node[prop] != null) {
1842
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1843
+ return node[prop];
1844
+ }
1845
+ }
1846
+ return defaultValue;
1847
+ }
1848
+ const AST_NODE_PROPS_KEYS = [
1849
+ ...PROPS_BODY,
1850
+ ...PROPS_CASES,
1851
+ ...PROPS_STATIC,
1852
+ ...PROPS_ITEMS,
1853
+ ...PROPS_KEY,
1854
+ ...PROPS_MODIFIER,
1855
+ ...PROPS_VALUE,
1856
+ ...PROPS_TYPE
1857
+ ];
1858
+ function createUnhandleNodeError(type) {
1859
+ return new Error(`unhandled node type: ${type}`);
1860
+ }
1861
+
1749
1862
  const pathStateMachine = [];
1750
1863
  pathStateMachine[0 /* States.BEFORE_PATH */] = {
1751
1864
  ["w" /* PathCharTypes.WORKSPACE */]: [0 /* States.BEFORE_PATH */],
@@ -1979,7 +2092,7 @@ function resolveWithKeyValue(obj, path) {
1979
2092
  *
1980
2093
  * @VueI18nGeneral
1981
2094
  */
1982
- function resolveValue$1(obj, path) {
2095
+ function resolveValue(obj, path) {
1983
2096
  // check object
1984
2097
  if (!isObject(obj)) {
1985
2098
  return null;
@@ -2001,7 +2114,16 @@ function resolveValue$1(obj, path) {
2001
2114
  let last = obj;
2002
2115
  let i = 0;
2003
2116
  while (i < len) {
2004
- const val = last[hit[i]];
2117
+ const key = hit[i];
2118
+ /**
2119
+ * NOTE:
2120
+ * if `key` is intlify message format AST node key and `last` is intlify message format AST, skip it.
2121
+ * because the AST node is not a key-value structure.
2122
+ */
2123
+ if (AST_NODE_PROPS_KEYS.includes(key) && isMessageAST(last)) {
2124
+ return null;
2125
+ }
2126
+ const val = last[key];
2005
2127
  if (val === undefined) {
2006
2128
  return null;
2007
2129
  }
@@ -2373,7 +2495,7 @@ function appendItemToChain(chain, target, blocks) {
2373
2495
  * Intlify core-base version
2374
2496
  * @internal
2375
2497
  */
2376
- const VERSION = '9.14.3';
2498
+ const VERSION = '9.14.5';
2377
2499
  const NOT_REOSLVED = -1;
2378
2500
  const DEFAULT_LOCALE = 'en-US';
2379
2501
  const MISSING_RESOLVE_VALUE = '';
@@ -2645,14 +2767,6 @@ function formatParts(ctx, ast) {
2645
2767
  return formatMessageParts(ctx, body);
2646
2768
  }
2647
2769
  }
2648
- const PROPS_BODY = ['b', 'body'];
2649
- function resolveBody(node) {
2650
- return resolveProps(node, PROPS_BODY);
2651
- }
2652
- const PROPS_CASES = ['c', 'cases'];
2653
- function resolveCases(node) {
2654
- return resolveProps(node, PROPS_CASES, []);
2655
- }
2656
2770
  function formatMessageParts(ctx, node) {
2657
2771
  const static_ = resolveStatic(node);
2658
2772
  if (static_ != null) {
@@ -2665,22 +2779,14 @@ function formatMessageParts(ctx, node) {
2665
2779
  return ctx.normalize(messages);
2666
2780
  }
2667
2781
  }
2668
- const PROPS_STATIC = ['s', 'static'];
2669
- function resolveStatic(node) {
2670
- return resolveProps(node, PROPS_STATIC);
2671
- }
2672
- const PROPS_ITEMS = ['i', 'items'];
2673
- function resolveItems(node) {
2674
- return resolveProps(node, PROPS_ITEMS, []);
2675
- }
2676
2782
  function formatMessagePart(ctx, node) {
2677
2783
  const type = resolveType(node);
2678
2784
  switch (type) {
2679
2785
  case 3 /* NodeTypes.Text */: {
2680
- return resolveValue(node, type);
2786
+ return resolveValue$1(node, type);
2681
2787
  }
2682
2788
  case 9 /* NodeTypes.Literal */: {
2683
- return resolveValue(node, type);
2789
+ return resolveValue$1(node, type);
2684
2790
  }
2685
2791
  case 4 /* NodeTypes.Named */: {
2686
2792
  const named = node;
@@ -2709,57 +2815,15 @@ function formatMessagePart(ctx, node) {
2709
2815
  return ctx.linked(formatMessagePart(ctx, key), modifier ? formatMessagePart(ctx, modifier) : undefined, ctx.type);
2710
2816
  }
2711
2817
  case 7 /* NodeTypes.LinkedKey */: {
2712
- return resolveValue(node, type);
2818
+ return resolveValue$1(node, type);
2713
2819
  }
2714
2820
  case 8 /* NodeTypes.LinkedModifier */: {
2715
- return resolveValue(node, type);
2821
+ return resolveValue$1(node, type);
2716
2822
  }
2717
2823
  default:
2718
2824
  throw new Error(`unhandled node on format message part: ${type}`);
2719
2825
  }
2720
2826
  }
2721
- const PROPS_TYPE = ['t', 'type'];
2722
- function resolveType(node) {
2723
- return resolveProps(node, PROPS_TYPE);
2724
- }
2725
- const PROPS_VALUE = ['v', 'value'];
2726
- function resolveValue(node, type) {
2727
- const resolved = resolveProps(node, PROPS_VALUE);
2728
- if (resolved) {
2729
- return resolved;
2730
- }
2731
- else {
2732
- throw createUnhandleNodeError(type);
2733
- }
2734
- }
2735
- const PROPS_MODIFIER = ['m', 'modifier'];
2736
- function resolveLinkedModifier(node) {
2737
- return resolveProps(node, PROPS_MODIFIER);
2738
- }
2739
- const PROPS_KEY = ['k', 'key'];
2740
- function resolveLinkedKey(node) {
2741
- const resolved = resolveProps(node, PROPS_KEY);
2742
- if (resolved) {
2743
- return resolved;
2744
- }
2745
- else {
2746
- throw createUnhandleNodeError(6 /* NodeTypes.Linked */);
2747
- }
2748
- }
2749
- function resolveProps(node, props, defaultValue) {
2750
- for (let i = 0; i < props.length; i++) {
2751
- const prop = props[i];
2752
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
2753
- if (hasOwn(node, prop) && node[prop] != null) {
2754
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
2755
- return node[prop];
2756
- }
2757
- }
2758
- return defaultValue;
2759
- }
2760
- function createUnhandleNodeError(type) {
2761
- return new Error(`unhandled node type: ${type}`);
2762
- }
2763
2827
 
2764
2828
  const WARN_MESSAGE = `Detected HTML in '{source}' message. Recommend not using HTML messages to avoid XSS.`;
2765
2829
  function checkHtmlMessage(source, warnHtmlMessage) {
@@ -2780,11 +2844,6 @@ function onCompileWarn(_warn) {
2780
2844
  function clearCompileCache() {
2781
2845
  compileCache = create();
2782
2846
  }
2783
- function isMessageAST(val) {
2784
- return (isObject(val) &&
2785
- resolveType(val) === 0 &&
2786
- (hasOwn(val, 'b') || hasOwn(val, 'body')));
2787
- }
2788
2847
  function baseCompile(message, options = {}) {
2789
2848
  // error detecting on compile
2790
2849
  let detectError = false;
@@ -2969,9 +3028,13 @@ function translate(context, ...args) {
2969
3028
  const msgContext = createMessageContext(ctxOptions);
2970
3029
  const messaged = evaluateMessage(context, msg, msgContext);
2971
3030
  // if use post translation option, proceed it with handler
2972
- const ret = postTranslation
3031
+ let ret = postTranslation
2973
3032
  ? postTranslation(messaged, key)
2974
3033
  : messaged;
3034
+ // apply HTML sanitization for security
3035
+ if (escapeParameter && isString(ret)) {
3036
+ ret = sanitizeTranslatedHtml(ret);
3037
+ }
2975
3038
  // NOTE: experimental !!
2976
3039
  {
2977
3040
  // prettier-ignore
@@ -3615,4 +3678,4 @@ function clearNumberFormat(ctx, locale, format) {
3615
3678
  }
3616
3679
  }
3617
3680
 
3618
- export { CompileErrorCodes, CoreErrorCodes, CoreWarnCodes, DATETIME_FORMAT_OPTIONS_KEYS, DEFAULT_LOCALE, DEFAULT_MESSAGE_DATA_TYPE, MISSING_RESOLVE_VALUE, NOT_REOSLVED, NUMBER_FORMAT_OPTIONS_KEYS, VERSION, clearCompileCache, clearDateTimeFormat, clearNumberFormat, compile, compileToFunction, createCompileError, createCoreContext, createCoreError, createMessageContext, datetime, fallbackWithLocaleChain, fallbackWithSimple, getAdditionalMeta, getDevToolsHook, getFallbackContext, getLocale, getWarnMessage, handleMissing, initI18nDevTools, isAlmostSameLocale, isImplicitFallback, isMessageAST, isMessageFunction, isTranslateFallbackWarn, isTranslateMissingWarn, number, parse, parseDateTimeArgs, parseNumberArgs, parseTranslateArgs, registerLocaleFallbacker, registerMessageCompiler, registerMessageResolver, resolveLocale, resolveValue$1 as resolveValue, resolveWithKeyValue, setAdditionalMeta, setDevToolsHook, setFallbackContext, translate, translateDevTools, updateFallbackLocale };
3681
+ export { AST_NODE_PROPS_KEYS, CompileErrorCodes, CoreErrorCodes, CoreWarnCodes, DATETIME_FORMAT_OPTIONS_KEYS, DEFAULT_LOCALE, DEFAULT_MESSAGE_DATA_TYPE, MISSING_RESOLVE_VALUE, NOT_REOSLVED, NUMBER_FORMAT_OPTIONS_KEYS, VERSION, clearCompileCache, clearDateTimeFormat, clearNumberFormat, compile, compileToFunction, createCompileError, createCoreContext, createCoreError, createMessageContext, datetime, fallbackWithLocaleChain, fallbackWithSimple, getAdditionalMeta, getDevToolsHook, getFallbackContext, getLocale, getWarnMessage, handleMissing, initI18nDevTools, isAlmostSameLocale, isImplicitFallback, isMessageAST, isMessageFunction, isTranslateFallbackWarn, isTranslateMissingWarn, number, parse, parseDateTimeArgs, parseNumberArgs, parseTranslateArgs, registerLocaleFallbacker, registerMessageCompiler, registerMessageResolver, resolveLocale, resolveValue, resolveWithKeyValue, setAdditionalMeta, setDevToolsHook, setFallbackContext, translate, translateDevTools, updateFallbackLocale };