@intlify/core-base 10.0.6 → 10.0.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.
- package/dist/core-base.cjs +92 -67
- package/dist/core-base.d.ts +12 -1
- package/dist/core-base.esm-browser.js +149 -86
- package/dist/core-base.esm-browser.prod.js +2 -2
- package/dist/core-base.global.js +142 -78
- package/dist/core-base.global.prod.js +2 -2
- package/dist/core-base.mjs +93 -69
- package/dist/core-base.prod.cjs +92 -67
- package/package.json +4 -4
package/dist/core-base.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* core-base v10.0.
|
|
2
|
+
* core-base v10.0.8
|
|
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
|
function format(ast) {
|
|
12
86
|
const msg = (ctx) => formatParts(ctx, ast);
|
|
13
87
|
return msg;
|
|
@@ -30,14 +104,6 @@ function formatParts(ctx, ast) {
|
|
|
30
104
|
return formatMessageParts(ctx, body);
|
|
31
105
|
}
|
|
32
106
|
}
|
|
33
|
-
const PROPS_BODY = ['b', 'body'];
|
|
34
|
-
function resolveBody(node) {
|
|
35
|
-
return resolveProps(node, PROPS_BODY);
|
|
36
|
-
}
|
|
37
|
-
const PROPS_CASES = ['c', 'cases'];
|
|
38
|
-
function resolveCases(node) {
|
|
39
|
-
return resolveProps(node, PROPS_CASES, []);
|
|
40
|
-
}
|
|
41
107
|
function formatMessageParts(ctx, node) {
|
|
42
108
|
const static_ = resolveStatic(node);
|
|
43
109
|
if (static_ != null) {
|
|
@@ -50,14 +116,6 @@ function formatMessageParts(ctx, node) {
|
|
|
50
116
|
return ctx.normalize(messages);
|
|
51
117
|
}
|
|
52
118
|
}
|
|
53
|
-
const PROPS_STATIC = ['s', 'static'];
|
|
54
|
-
function resolveStatic(node) {
|
|
55
|
-
return resolveProps(node, PROPS_STATIC);
|
|
56
|
-
}
|
|
57
|
-
const PROPS_ITEMS = ['i', 'items'];
|
|
58
|
-
function resolveItems(node) {
|
|
59
|
-
return resolveProps(node, PROPS_ITEMS, []);
|
|
60
|
-
}
|
|
61
119
|
function formatMessagePart(ctx, node) {
|
|
62
120
|
const type = resolveType(node);
|
|
63
121
|
switch (type) {
|
|
@@ -103,48 +161,6 @@ function formatMessagePart(ctx, node) {
|
|
|
103
161
|
throw new Error(`unhandled node on format message part: ${type}`);
|
|
104
162
|
}
|
|
105
163
|
}
|
|
106
|
-
const PROPS_TYPE = ['t', 'type'];
|
|
107
|
-
function resolveType(node) {
|
|
108
|
-
return resolveProps(node, PROPS_TYPE);
|
|
109
|
-
}
|
|
110
|
-
const PROPS_VALUE = ['v', 'value'];
|
|
111
|
-
function resolveValue$1(node, type) {
|
|
112
|
-
const resolved = resolveProps(node, PROPS_VALUE);
|
|
113
|
-
if (resolved) {
|
|
114
|
-
return resolved;
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
117
|
-
throw createUnhandleNodeError(type);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
const PROPS_MODIFIER = ['m', 'modifier'];
|
|
121
|
-
function resolveLinkedModifier(node) {
|
|
122
|
-
return resolveProps(node, PROPS_MODIFIER);
|
|
123
|
-
}
|
|
124
|
-
const PROPS_KEY = ['k', 'key'];
|
|
125
|
-
function resolveLinkedKey(node) {
|
|
126
|
-
const resolved = resolveProps(node, PROPS_KEY);
|
|
127
|
-
if (resolved) {
|
|
128
|
-
return resolved;
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
throw createUnhandleNodeError(6 /* NodeTypes.Linked */);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
function resolveProps(node, props, defaultValue) {
|
|
135
|
-
for (let i = 0; i < props.length; i++) {
|
|
136
|
-
const prop = props[i];
|
|
137
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
138
|
-
if (shared.hasOwn(node, prop) && node[prop] != null) {
|
|
139
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
140
|
-
return node[prop];
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return defaultValue;
|
|
144
|
-
}
|
|
145
|
-
function createUnhandleNodeError(type) {
|
|
146
|
-
return new Error(`unhandled node type: ${type}`);
|
|
147
|
-
}
|
|
148
164
|
|
|
149
165
|
const WARN_MESSAGE = `Detected HTML in '{source}' message. Recommend not using HTML messages to avoid XSS.`;
|
|
150
166
|
function checkHtmlMessage(source, warnHtmlMessage) {
|
|
@@ -157,11 +173,6 @@ let compileCache = shared.create();
|
|
|
157
173
|
function clearCompileCache() {
|
|
158
174
|
compileCache = shared.create();
|
|
159
175
|
}
|
|
160
|
-
function isMessageAST(val) {
|
|
161
|
-
return (shared.isObject(val) &&
|
|
162
|
-
resolveType(val) === 0 &&
|
|
163
|
-
(shared.hasOwn(val, 'b') || shared.hasOwn(val, 'body')));
|
|
164
|
-
}
|
|
165
176
|
function baseCompile(message, options = {}) {
|
|
166
177
|
// error detecting on compile
|
|
167
178
|
let detectError = false;
|
|
@@ -674,7 +685,16 @@ function resolveValue(obj, path) {
|
|
|
674
685
|
let last = obj;
|
|
675
686
|
let i = 0;
|
|
676
687
|
while (i < len) {
|
|
677
|
-
const
|
|
688
|
+
const key = hit[i];
|
|
689
|
+
/**
|
|
690
|
+
* NOTE:
|
|
691
|
+
* if `key` is intlify message format AST node key and `last` is intlify message format AST, skip it.
|
|
692
|
+
* because the AST node is not a key-value structure.
|
|
693
|
+
*/
|
|
694
|
+
if (AST_NODE_PROPS_KEYS.includes(key) && isMessageAST(last)) {
|
|
695
|
+
return null;
|
|
696
|
+
}
|
|
697
|
+
const val = last[key];
|
|
678
698
|
if (val === undefined) {
|
|
679
699
|
return null;
|
|
680
700
|
}
|
|
@@ -716,7 +736,7 @@ function getWarnMessage(code, ...args) {
|
|
|
716
736
|
* Intlify core-base version
|
|
717
737
|
* @internal
|
|
718
738
|
*/
|
|
719
|
-
const VERSION = '10.0.
|
|
739
|
+
const VERSION = '10.0.8';
|
|
720
740
|
const NOT_REOSLVED = -1;
|
|
721
741
|
const DEFAULT_LOCALE = 'en-US';
|
|
722
742
|
const MISSING_RESOLVE_VALUE = '';
|
|
@@ -1508,9 +1528,13 @@ function translate(context, ...args) {
|
|
|
1508
1528
|
const msgContext = createMessageContext(ctxOptions);
|
|
1509
1529
|
const messaged = evaluateMessage(context, msg, msgContext);
|
|
1510
1530
|
// if use post translation option, proceed it with handler
|
|
1511
|
-
|
|
1531
|
+
let ret = postTranslation
|
|
1512
1532
|
? postTranslation(messaged, key)
|
|
1513
1533
|
: messaged;
|
|
1534
|
+
// apply HTML sanitization for security
|
|
1535
|
+
if (escapeParameter && shared.isString(ret)) {
|
|
1536
|
+
ret = shared.sanitizeTranslatedHtml(ret);
|
|
1537
|
+
}
|
|
1514
1538
|
// NOTE: experimental !!
|
|
1515
1539
|
{
|
|
1516
1540
|
// prettier-ignore
|
|
@@ -1835,6 +1859,7 @@ function getMessageContextOptions(context, locale, message, options) {
|
|
|
1835
1859
|
|
|
1836
1860
|
exports.CompileErrorCodes = messageCompiler.CompileErrorCodes;
|
|
1837
1861
|
exports.createCompileError = messageCompiler.createCompileError;
|
|
1862
|
+
exports.AST_NODE_PROPS_KEYS = AST_NODE_PROPS_KEYS;
|
|
1838
1863
|
exports.CORE_ERROR_CODES_EXTEND_POINT = CORE_ERROR_CODES_EXTEND_POINT;
|
|
1839
1864
|
exports.CORE_WARN_CODES_EXTEND_POINT = CORE_WARN_CODES_EXTEND_POINT;
|
|
1840
1865
|
exports.CoreErrorCodes = CoreErrorCodes;
|
package/dist/core-base.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ declare type __ResourceFormatPath<T, Key extends keyof T> = Key extends string ?
|
|
|
13
13
|
|
|
14
14
|
export declare type __ResourcePath<T, Key extends keyof T> = Key extends string ? T[Key] extends Record<string, any> ? `${Key}.${__ResourcePath<T[Key], Exclude<keyof T[Key], keyof any[]>> & string}` | `${Key}.${Exclude<keyof T[Key], keyof any[]> & string}` : never : never;
|
|
15
15
|
|
|
16
|
+
export declare const AST_NODE_PROPS_KEYS: string[];
|
|
17
|
+
|
|
16
18
|
export declare function clearCompileCache(): void;
|
|
17
19
|
|
|
18
20
|
/* Excluded from this release type: clearDateTimeFormat */
|
|
@@ -1190,7 +1192,16 @@ export declare interface TranslateOptions<Locales = Locale> extends LocaleOption
|
|
|
1190
1192
|
fallbackWarn?: boolean;
|
|
1191
1193
|
/**
|
|
1192
1194
|
* @remarks
|
|
1193
|
-
* Whether
|
|
1195
|
+
* Whether to escape parameters for list or named interpolation values.
|
|
1196
|
+
* When enabled, this option:
|
|
1197
|
+
* - Escapes HTML special characters (`<`, `>`, `"`, `'`, `&`, `/`, `=`) in interpolation parameters
|
|
1198
|
+
* - Sanitizes the final translated HTML to prevent XSS attacks by:
|
|
1199
|
+
* - Escaping dangerous characters in HTML attribute values
|
|
1200
|
+
* - Neutralizing event handler attributes (onclick, onerror, etc.)
|
|
1201
|
+
* - Disabling javascript: URLs in href, src, action, formaction, and style attributes
|
|
1202
|
+
*
|
|
1203
|
+
* @defaultValue false
|
|
1204
|
+
* @see [HTML Message - Using the escapeParameter option](https://vue-i18n.intlify.dev/guide/essentials/syntax.html#using-the-escapeparameter-option)
|
|
1194
1205
|
*/
|
|
1195
1206
|
escapeParameter?: boolean;
|
|
1196
1207
|
/**
|
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* core-base v10.0.
|
|
2
|
+
* core-base v10.0.8
|
|
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, '&') // escape `&` first to avoid double escaping
|
|
58
76
|
.replace(/</g, '<')
|
|
59
77
|
.replace(/>/g, '>')
|
|
60
78
|
.replace(/"/g, '"')
|
|
61
|
-
.replace(/'/g, ''')
|
|
79
|
+
.replace(/'/g, ''')
|
|
80
|
+
.replace(/\//g, '/') // escape `/` to prevent closing tags or JavaScript URLs
|
|
81
|
+
.replace(/=/g, '='); // escape `=` to prevent attribute injection
|
|
82
|
+
}
|
|
83
|
+
function escapeAttributeValue(value) {
|
|
84
|
+
return value
|
|
85
|
+
.replace(/&(?![a-zA-Z0-9#]{2,6};)/g, '&') // escape unescaped `&`
|
|
86
|
+
.replace(/"/g, '"')
|
|
87
|
+
.replace(/'/g, ''')
|
|
88
|
+
.replace(/</g, '<')
|
|
89
|
+
.replace(/>/g, '>');
|
|
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, '$1on$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:');
|
|
116
|
+
});
|
|
117
|
+
return html;
|
|
62
118
|
}
|
|
63
119
|
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
64
120
|
function hasOwn(obj, key) {
|
|
@@ -130,23 +186,6 @@ function generateCodeFrame(source, start = 0, end = source.length) {
|
|
|
130
186
|
return res.join('\n');
|
|
131
187
|
}
|
|
132
188
|
|
|
133
|
-
function warn(msg, err) {
|
|
134
|
-
if (typeof console !== 'undefined') {
|
|
135
|
-
console.warn(`[intlify] ` + msg);
|
|
136
|
-
/* istanbul ignore if */
|
|
137
|
-
if (err) {
|
|
138
|
-
console.warn(err.stack);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
const hasWarned = {};
|
|
143
|
-
function warnOnce(msg) {
|
|
144
|
-
if (!hasWarned[msg]) {
|
|
145
|
-
hasWarned[msg] = true;
|
|
146
|
-
warn(msg);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
189
|
function createPosition(line, column, offset) {
|
|
151
190
|
return { line, column, offset };
|
|
152
191
|
}
|
|
@@ -1649,6 +1688,80 @@ function baseCompile$1(source, options = {}) {
|
|
|
1649
1688
|
}
|
|
1650
1689
|
}
|
|
1651
1690
|
|
|
1691
|
+
function isMessageAST(val) {
|
|
1692
|
+
return (isObject(val) &&
|
|
1693
|
+
resolveType(val) === 0 &&
|
|
1694
|
+
(hasOwn(val, 'b') || hasOwn(val, 'body')));
|
|
1695
|
+
}
|
|
1696
|
+
const PROPS_BODY = ['b', 'body'];
|
|
1697
|
+
function resolveBody(node) {
|
|
1698
|
+
return resolveProps(node, PROPS_BODY);
|
|
1699
|
+
}
|
|
1700
|
+
const PROPS_CASES = ['c', 'cases'];
|
|
1701
|
+
function resolveCases(node) {
|
|
1702
|
+
return resolveProps(node, PROPS_CASES, []);
|
|
1703
|
+
}
|
|
1704
|
+
const PROPS_STATIC = ['s', 'static'];
|
|
1705
|
+
function resolveStatic(node) {
|
|
1706
|
+
return resolveProps(node, PROPS_STATIC);
|
|
1707
|
+
}
|
|
1708
|
+
const PROPS_ITEMS = ['i', 'items'];
|
|
1709
|
+
function resolveItems(node) {
|
|
1710
|
+
return resolveProps(node, PROPS_ITEMS, []);
|
|
1711
|
+
}
|
|
1712
|
+
const PROPS_TYPE = ['t', 'type'];
|
|
1713
|
+
function resolveType(node) {
|
|
1714
|
+
return resolveProps(node, PROPS_TYPE);
|
|
1715
|
+
}
|
|
1716
|
+
const PROPS_VALUE = ['v', 'value'];
|
|
1717
|
+
function resolveValue$1(node, type) {
|
|
1718
|
+
const resolved = resolveProps(node, PROPS_VALUE);
|
|
1719
|
+
if (resolved != null) {
|
|
1720
|
+
return resolved;
|
|
1721
|
+
}
|
|
1722
|
+
else {
|
|
1723
|
+
throw createUnhandleNodeError(type);
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
const PROPS_MODIFIER = ['m', 'modifier'];
|
|
1727
|
+
function resolveLinkedModifier(node) {
|
|
1728
|
+
return resolveProps(node, PROPS_MODIFIER);
|
|
1729
|
+
}
|
|
1730
|
+
const PROPS_KEY = ['k', 'key'];
|
|
1731
|
+
function resolveLinkedKey(node) {
|
|
1732
|
+
const resolved = resolveProps(node, PROPS_KEY);
|
|
1733
|
+
if (resolved) {
|
|
1734
|
+
return resolved;
|
|
1735
|
+
}
|
|
1736
|
+
else {
|
|
1737
|
+
throw createUnhandleNodeError(6 /* NodeTypes.Linked */);
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
function resolveProps(node, props, defaultValue) {
|
|
1741
|
+
for (let i = 0; i < props.length; i++) {
|
|
1742
|
+
const prop = props[i];
|
|
1743
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1744
|
+
if (hasOwn(node, prop) && node[prop] != null) {
|
|
1745
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1746
|
+
return node[prop];
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
return defaultValue;
|
|
1750
|
+
}
|
|
1751
|
+
const AST_NODE_PROPS_KEYS = [
|
|
1752
|
+
...PROPS_BODY,
|
|
1753
|
+
...PROPS_CASES,
|
|
1754
|
+
...PROPS_STATIC,
|
|
1755
|
+
...PROPS_ITEMS,
|
|
1756
|
+
...PROPS_KEY,
|
|
1757
|
+
...PROPS_MODIFIER,
|
|
1758
|
+
...PROPS_VALUE,
|
|
1759
|
+
...PROPS_TYPE
|
|
1760
|
+
];
|
|
1761
|
+
function createUnhandleNodeError(type) {
|
|
1762
|
+
return new Error(`unhandled node type: ${type}`);
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1652
1765
|
function format(ast) {
|
|
1653
1766
|
const msg = (ctx) => formatParts(ctx, ast);
|
|
1654
1767
|
return msg;
|
|
@@ -1671,14 +1784,6 @@ function formatParts(ctx, ast) {
|
|
|
1671
1784
|
return formatMessageParts(ctx, body);
|
|
1672
1785
|
}
|
|
1673
1786
|
}
|
|
1674
|
-
const PROPS_BODY = ['b', 'body'];
|
|
1675
|
-
function resolveBody(node) {
|
|
1676
|
-
return resolveProps(node, PROPS_BODY);
|
|
1677
|
-
}
|
|
1678
|
-
const PROPS_CASES = ['c', 'cases'];
|
|
1679
|
-
function resolveCases(node) {
|
|
1680
|
-
return resolveProps(node, PROPS_CASES, []);
|
|
1681
|
-
}
|
|
1682
1787
|
function formatMessageParts(ctx, node) {
|
|
1683
1788
|
const static_ = resolveStatic(node);
|
|
1684
1789
|
if (static_ != null) {
|
|
@@ -1691,14 +1796,6 @@ function formatMessageParts(ctx, node) {
|
|
|
1691
1796
|
return ctx.normalize(messages);
|
|
1692
1797
|
}
|
|
1693
1798
|
}
|
|
1694
|
-
const PROPS_STATIC = ['s', 'static'];
|
|
1695
|
-
function resolveStatic(node) {
|
|
1696
|
-
return resolveProps(node, PROPS_STATIC);
|
|
1697
|
-
}
|
|
1698
|
-
const PROPS_ITEMS = ['i', 'items'];
|
|
1699
|
-
function resolveItems(node) {
|
|
1700
|
-
return resolveProps(node, PROPS_ITEMS, []);
|
|
1701
|
-
}
|
|
1702
1799
|
function formatMessagePart(ctx, node) {
|
|
1703
1800
|
const type = resolveType(node);
|
|
1704
1801
|
switch (type) {
|
|
@@ -1744,48 +1841,6 @@ function formatMessagePart(ctx, node) {
|
|
|
1744
1841
|
throw new Error(`unhandled node on format message part: ${type}`);
|
|
1745
1842
|
}
|
|
1746
1843
|
}
|
|
1747
|
-
const PROPS_TYPE = ['t', 'type'];
|
|
1748
|
-
function resolveType(node) {
|
|
1749
|
-
return resolveProps(node, PROPS_TYPE);
|
|
1750
|
-
}
|
|
1751
|
-
const PROPS_VALUE = ['v', 'value'];
|
|
1752
|
-
function resolveValue$1(node, type) {
|
|
1753
|
-
const resolved = resolveProps(node, PROPS_VALUE);
|
|
1754
|
-
if (resolved) {
|
|
1755
|
-
return resolved;
|
|
1756
|
-
}
|
|
1757
|
-
else {
|
|
1758
|
-
throw createUnhandleNodeError(type);
|
|
1759
|
-
}
|
|
1760
|
-
}
|
|
1761
|
-
const PROPS_MODIFIER = ['m', 'modifier'];
|
|
1762
|
-
function resolveLinkedModifier(node) {
|
|
1763
|
-
return resolveProps(node, PROPS_MODIFIER);
|
|
1764
|
-
}
|
|
1765
|
-
const PROPS_KEY = ['k', 'key'];
|
|
1766
|
-
function resolveLinkedKey(node) {
|
|
1767
|
-
const resolved = resolveProps(node, PROPS_KEY);
|
|
1768
|
-
if (resolved) {
|
|
1769
|
-
return resolved;
|
|
1770
|
-
}
|
|
1771
|
-
else {
|
|
1772
|
-
throw createUnhandleNodeError(6 /* NodeTypes.Linked */);
|
|
1773
|
-
}
|
|
1774
|
-
}
|
|
1775
|
-
function resolveProps(node, props, defaultValue) {
|
|
1776
|
-
for (let i = 0; i < props.length; i++) {
|
|
1777
|
-
const prop = props[i];
|
|
1778
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1779
|
-
if (hasOwn(node, prop) && node[prop] != null) {
|
|
1780
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1781
|
-
return node[prop];
|
|
1782
|
-
}
|
|
1783
|
-
}
|
|
1784
|
-
return defaultValue;
|
|
1785
|
-
}
|
|
1786
|
-
function createUnhandleNodeError(type) {
|
|
1787
|
-
return new Error(`unhandled node type: ${type}`);
|
|
1788
|
-
}
|
|
1789
1844
|
|
|
1790
1845
|
const WARN_MESSAGE = `Detected HTML in '{source}' message. Recommend not using HTML messages to avoid XSS.`;
|
|
1791
1846
|
function checkHtmlMessage(source, warnHtmlMessage) {
|
|
@@ -1798,11 +1853,6 @@ let compileCache = create();
|
|
|
1798
1853
|
function clearCompileCache() {
|
|
1799
1854
|
compileCache = create();
|
|
1800
1855
|
}
|
|
1801
|
-
function isMessageAST(val) {
|
|
1802
|
-
return (isObject(val) &&
|
|
1803
|
-
resolveType(val) === 0 &&
|
|
1804
|
-
(hasOwn(val, 'b') || hasOwn(val, 'body')));
|
|
1805
|
-
}
|
|
1806
1856
|
function baseCompile(message, options = {}) {
|
|
1807
1857
|
// error detecting on compile
|
|
1808
1858
|
let detectError = false;
|
|
@@ -2315,7 +2365,16 @@ function resolveValue(obj, path) {
|
|
|
2315
2365
|
let last = obj;
|
|
2316
2366
|
let i = 0;
|
|
2317
2367
|
while (i < len) {
|
|
2318
|
-
const
|
|
2368
|
+
const key = hit[i];
|
|
2369
|
+
/**
|
|
2370
|
+
* NOTE:
|
|
2371
|
+
* if `key` is intlify message format AST node key and `last` is intlify message format AST, skip it.
|
|
2372
|
+
* because the AST node is not a key-value structure.
|
|
2373
|
+
*/
|
|
2374
|
+
if (AST_NODE_PROPS_KEYS.includes(key) && isMessageAST(last)) {
|
|
2375
|
+
return null;
|
|
2376
|
+
}
|
|
2377
|
+
const val = last[key];
|
|
2319
2378
|
if (val === undefined) {
|
|
2320
2379
|
return null;
|
|
2321
2380
|
}
|
|
@@ -2357,7 +2416,7 @@ function getWarnMessage(code, ...args) {
|
|
|
2357
2416
|
* Intlify core-base version
|
|
2358
2417
|
* @internal
|
|
2359
2418
|
*/
|
|
2360
|
-
const VERSION = '10.0.
|
|
2419
|
+
const VERSION = '10.0.8';
|
|
2361
2420
|
const NOT_REOSLVED = -1;
|
|
2362
2421
|
const DEFAULT_LOCALE = 'en-US';
|
|
2363
2422
|
const MISSING_RESOLVE_VALUE = '';
|
|
@@ -3149,9 +3208,13 @@ function translate(context, ...args) {
|
|
|
3149
3208
|
const msgContext = createMessageContext(ctxOptions);
|
|
3150
3209
|
const messaged = evaluateMessage(context, msg, msgContext);
|
|
3151
3210
|
// if use post translation option, proceed it with handler
|
|
3152
|
-
|
|
3211
|
+
let ret = postTranslation
|
|
3153
3212
|
? postTranslation(messaged, key)
|
|
3154
3213
|
: messaged;
|
|
3214
|
+
// apply HTML sanitization for security
|
|
3215
|
+
if (escapeParameter && isString(ret)) {
|
|
3216
|
+
ret = sanitizeTranslatedHtml(ret);
|
|
3217
|
+
}
|
|
3155
3218
|
// NOTE: experimental !!
|
|
3156
3219
|
{
|
|
3157
3220
|
// prettier-ignore
|
|
@@ -3474,4 +3537,4 @@ function getMessageContextOptions(context, locale, message, options) {
|
|
|
3474
3537
|
return ctxOptions;
|
|
3475
3538
|
}
|
|
3476
3539
|
|
|
3477
|
-
export { CORE_ERROR_CODES_EXTEND_POINT, CORE_WARN_CODES_EXTEND_POINT, 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, 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 };
|
|
3540
|
+
export { AST_NODE_PROPS_KEYS, CORE_ERROR_CODES_EXTEND_POINT, CORE_WARN_CODES_EXTEND_POINT, 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, 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 };
|