@fluentui/react-charts 9.3.12 → 9.3.14
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/CHANGELOG.md +25 -2
- package/dist/index.d.ts +859 -0
- package/lib/VegaDeclarativeChart.js +1 -0
- package/lib/VegaDeclarativeChart.js.map +1 -0
- package/lib/components/LineChart/LineChart.js +47 -7
- package/lib/components/LineChart/LineChart.js.map +1 -1
- package/lib/components/ScatterChart/ScatterChart.js +12 -12
- package/lib/components/ScatterChart/ScatterChart.js.map +1 -1
- package/lib/components/VegaDeclarativeChart/VegaDeclarativeChart.js +405 -0
- package/lib/components/VegaDeclarativeChart/VegaDeclarativeChart.js.map +1 -0
- package/lib/components/VegaDeclarativeChart/VegaDeclarativeChartHooks.js +20 -0
- package/lib/components/VegaDeclarativeChart/VegaDeclarativeChartHooks.js.map +1 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteColorAdapter.js +415 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteColorAdapter.js.map +1 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteExpressionEvaluator.js +537 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteExpressionEvaluator.js.map +1 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteSchemaAdapter.js +3279 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteSchemaAdapter.js.map +1 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteTypes.js +28 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteTypes.js.map +1 -0
- package/lib/components/VegaDeclarativeChart/index.js +1 -0
- package/lib/components/VegaDeclarativeChart/index.js.map +1 -0
- package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js +5 -2
- package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/utilities/utilities.js +41 -0
- package/lib/utilities/utilities.js.map +1 -1
- package/lib-commonjs/VegaDeclarativeChart.js +6 -0
- package/lib-commonjs/VegaDeclarativeChart.js.map +1 -0
- package/lib-commonjs/components/LineChart/LineChart.js +46 -6
- package/lib-commonjs/components/LineChart/LineChart.js.map +1 -1
- package/lib-commonjs/components/ScatterChart/ScatterChart.js +11 -11
- package/lib-commonjs/components/ScatterChart/ScatterChart.js.map +1 -1
- package/lib-commonjs/components/VegaDeclarativeChart/VegaDeclarativeChart.js +274 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaDeclarativeChart.js.map +1 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaDeclarativeChartHooks.js +35 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaDeclarativeChartHooks.js.map +1 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteColorAdapter.js +412 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteColorAdapter.js.map +1 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteExpressionEvaluator.js +533 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteExpressionEvaluator.js.map +1 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteSchemaAdapter.js +3214 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteSchemaAdapter.js.map +1 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteTypes.js +31 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteTypes.js.map +1 -0
- package/lib-commonjs/components/VegaDeclarativeChart/index.js +6 -0
- package/lib-commonjs/components/VegaDeclarativeChart/index.js.map +1 -0
- package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js +4 -1
- package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
- package/lib-commonjs/index.js +1 -0
- package/lib-commonjs/index.js.map +1 -1
- package/lib-commonjs/utilities/utilities.js +33 -0
- package/lib-commonjs/utilities/utilities.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe expression evaluator for Vega-Lite expressions.
|
|
3
|
+
*
|
|
4
|
+
* Recursive-descent parser that only supports the safe subset of the
|
|
5
|
+
* Vega-Lite expression language:
|
|
6
|
+
* - Property access: datum.field, datum['field'] (own properties only)
|
|
7
|
+
* - Arithmetic: +, -, *, /, %
|
|
8
|
+
* - Comparison: ==, ===, !=, !==, <, >, <=, >=
|
|
9
|
+
* - Logical: &&, ||, !
|
|
10
|
+
* - Ternary: condition ? trueVal : falseVal
|
|
11
|
+
* - Literals: numbers, strings, booleans, null
|
|
12
|
+
* - Safe built-in functions: isValid, isDate, isNumber, isNaN, isFinite,
|
|
13
|
+
* abs, ceil, floor, round, sqrt, log, exp, pow, min, max, length,
|
|
14
|
+
* toNumber, toString, toBoolean
|
|
15
|
+
* - Constants: PI, E, SQRT2, LN2, LN10, NaN, Infinity
|
|
16
|
+
*
|
|
17
|
+
* Everything else (assignment, arbitrary function calls, global access) is rejected.
|
|
18
|
+
*
|
|
19
|
+
* @see https://vega.github.io/vega/docs/expressions/
|
|
20
|
+
*/ // ---------------------------------------------------------------------------
|
|
21
|
+
// Token types
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
"use strict";
|
|
24
|
+
Object.defineProperty(exports, "__esModule", {
|
|
25
|
+
value: true
|
|
26
|
+
});
|
|
27
|
+
Object.defineProperty(exports, "safeEvaluateExpression", {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
get: function() {
|
|
30
|
+
return safeEvaluateExpression;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
const _define_property = require("@swc/helpers/_/_define_property");
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// Own-property check — only allow access to properties that exist directly
|
|
36
|
+
// on the object (not inherited from the prototype chain). This is an allowlist
|
|
37
|
+
// approach: constructor, __proto__, toString, valueOf, etc. are all inherited
|
|
38
|
+
// and thus blocked automatically without maintaining a blocklist.
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
const hasOwn = (obj, prop)=>obj !== null && obj !== undefined && typeof obj === 'object' && Object.prototype.hasOwnProperty.call(obj, prop);
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Whitelisted built-in functions (mirrors the Vega expression function set)
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
const SAFE_FUNCTIONS = {
|
|
45
|
+
isValid: (x)=>x !== null && x !== undefined && (typeof x !== 'number' || !isNaN(x)),
|
|
46
|
+
isDate: (x)=>x instanceof Date,
|
|
47
|
+
isNumber: (x)=>typeof x === 'number' && !isNaN(x),
|
|
48
|
+
isString: (x)=>typeof x === 'string',
|
|
49
|
+
isBoolean: (x)=>typeof x === 'boolean',
|
|
50
|
+
isArray: (x)=>Array.isArray(x),
|
|
51
|
+
isNaN: (x)=>isNaN(x),
|
|
52
|
+
isFinite: (x)=>Number.isFinite(x),
|
|
53
|
+
abs: (x)=>Math.abs(x),
|
|
54
|
+
ceil: (x)=>Math.ceil(x),
|
|
55
|
+
floor: (x)=>Math.floor(x),
|
|
56
|
+
round: (x)=>Math.round(x),
|
|
57
|
+
sqrt: (x)=>Math.sqrt(x),
|
|
58
|
+
log: (x)=>Math.log(x),
|
|
59
|
+
exp: (x)=>Math.exp(x),
|
|
60
|
+
pow: (x, y)=>x ** y,
|
|
61
|
+
min: (...args)=>Math.min(...args),
|
|
62
|
+
max: (...args)=>Math.max(...args),
|
|
63
|
+
length: (x)=>typeof x === 'string' || Array.isArray(x) ? x.length : 0,
|
|
64
|
+
toNumber: (x)=>Number(x),
|
|
65
|
+
toString: (x)=>String(x),
|
|
66
|
+
toBoolean: (x)=>Boolean(x)
|
|
67
|
+
};
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
// Whitelisted constants
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
const SAFE_CONSTANTS = {
|
|
72
|
+
PI: Math.PI,
|
|
73
|
+
E: Math.E,
|
|
74
|
+
SQRT2: Math.SQRT2,
|
|
75
|
+
LN2: Math.LN2,
|
|
76
|
+
LN10: Math.LN10,
|
|
77
|
+
NaN,
|
|
78
|
+
Infinity
|
|
79
|
+
};
|
|
80
|
+
// Set of all allowed top-level identifiers
|
|
81
|
+
const ALLOWED_IDENTIFIERS = new Set([
|
|
82
|
+
'datum',
|
|
83
|
+
...Object.keys(SAFE_FUNCTIONS),
|
|
84
|
+
...Object.keys(SAFE_CONSTANTS)
|
|
85
|
+
]);
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// Tokenizer
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
function tokenize(expr) {
|
|
90
|
+
const tokens = [];
|
|
91
|
+
let i = 0;
|
|
92
|
+
while(i < expr.length){
|
|
93
|
+
// Skip whitespace
|
|
94
|
+
if (/\s/.test(expr[i])) {
|
|
95
|
+
i++;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
// Numbers (including decimal and scientific notation)
|
|
99
|
+
if (/[0-9]/.test(expr[i]) || expr[i] === '.' && i + 1 < expr.length && /[0-9]/.test(expr[i + 1])) {
|
|
100
|
+
const start = i;
|
|
101
|
+
while(i < expr.length && /[0-9.]/.test(expr[i])){
|
|
102
|
+
i++;
|
|
103
|
+
}
|
|
104
|
+
if (i < expr.length && (expr[i] === 'e' || expr[i] === 'E')) {
|
|
105
|
+
i++;
|
|
106
|
+
if (i < expr.length && (expr[i] === '+' || expr[i] === '-')) {
|
|
107
|
+
i++;
|
|
108
|
+
}
|
|
109
|
+
while(i < expr.length && /[0-9]/.test(expr[i])){
|
|
110
|
+
i++;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
tokens.push({
|
|
114
|
+
type: 'number',
|
|
115
|
+
value: parseFloat(expr.slice(start, i)),
|
|
116
|
+
start
|
|
117
|
+
});
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
// Strings (single or double quoted)
|
|
121
|
+
if (expr[i] === '"' || expr[i] === "'") {
|
|
122
|
+
const quote = expr[i];
|
|
123
|
+
const start = i;
|
|
124
|
+
i++;
|
|
125
|
+
let str = '';
|
|
126
|
+
while(i < expr.length && expr[i] !== quote){
|
|
127
|
+
if (expr[i] === '\\') {
|
|
128
|
+
i++;
|
|
129
|
+
if (i < expr.length) {
|
|
130
|
+
switch(expr[i]){
|
|
131
|
+
case 'n':
|
|
132
|
+
str += '\n';
|
|
133
|
+
break;
|
|
134
|
+
case 't':
|
|
135
|
+
str += '\t';
|
|
136
|
+
break;
|
|
137
|
+
case '\\':
|
|
138
|
+
str += '\\';
|
|
139
|
+
break;
|
|
140
|
+
case "'":
|
|
141
|
+
str += "'";
|
|
142
|
+
break;
|
|
143
|
+
case '"':
|
|
144
|
+
str += '"';
|
|
145
|
+
break;
|
|
146
|
+
default:
|
|
147
|
+
str += expr[i];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
str += expr[i];
|
|
152
|
+
}
|
|
153
|
+
i++;
|
|
154
|
+
}
|
|
155
|
+
if (i < expr.length) {
|
|
156
|
+
i++; // Skip closing quote
|
|
157
|
+
}
|
|
158
|
+
tokens.push({
|
|
159
|
+
type: 'string',
|
|
160
|
+
value: str,
|
|
161
|
+
start
|
|
162
|
+
});
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
// Identifiers and keywords
|
|
166
|
+
if (/[a-zA-Z_$]/.test(expr[i])) {
|
|
167
|
+
const start = i;
|
|
168
|
+
while(i < expr.length && /[a-zA-Z0-9_$]/.test(expr[i])){
|
|
169
|
+
i++;
|
|
170
|
+
}
|
|
171
|
+
const word = expr.slice(start, i);
|
|
172
|
+
switch(word){
|
|
173
|
+
case 'true':
|
|
174
|
+
tokens.push({
|
|
175
|
+
type: 'boolean',
|
|
176
|
+
value: true,
|
|
177
|
+
start
|
|
178
|
+
});
|
|
179
|
+
break;
|
|
180
|
+
case 'false':
|
|
181
|
+
tokens.push({
|
|
182
|
+
type: 'boolean',
|
|
183
|
+
value: false,
|
|
184
|
+
start
|
|
185
|
+
});
|
|
186
|
+
break;
|
|
187
|
+
case 'null':
|
|
188
|
+
tokens.push({
|
|
189
|
+
type: 'null',
|
|
190
|
+
value: null,
|
|
191
|
+
start
|
|
192
|
+
});
|
|
193
|
+
break;
|
|
194
|
+
case 'undefined':
|
|
195
|
+
tokens.push({
|
|
196
|
+
type: 'null',
|
|
197
|
+
value: undefined,
|
|
198
|
+
start
|
|
199
|
+
});
|
|
200
|
+
break;
|
|
201
|
+
default:
|
|
202
|
+
tokens.push({
|
|
203
|
+
type: 'ident',
|
|
204
|
+
value: word,
|
|
205
|
+
start
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
// Multi-character operators
|
|
211
|
+
const start = i;
|
|
212
|
+
const three = expr.slice(i, i + 3);
|
|
213
|
+
const two = expr.slice(i, i + 2);
|
|
214
|
+
if (three === '===' || three === '!==') {
|
|
215
|
+
tokens.push({
|
|
216
|
+
type: three,
|
|
217
|
+
value: three,
|
|
218
|
+
start
|
|
219
|
+
});
|
|
220
|
+
i += 3;
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (two === '==' || two === '!=' || two === '<=' || two === '>=' || two === '&&' || two === '||') {
|
|
224
|
+
tokens.push({
|
|
225
|
+
type: two,
|
|
226
|
+
value: two,
|
|
227
|
+
start
|
|
228
|
+
});
|
|
229
|
+
i += 2;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
// Single-character operators and punctuation
|
|
233
|
+
const ch = expr[i];
|
|
234
|
+
if ('+-*/%<>!.()[],?:'.includes(ch)) {
|
|
235
|
+
tokens.push({
|
|
236
|
+
type: ch,
|
|
237
|
+
value: ch,
|
|
238
|
+
start
|
|
239
|
+
});
|
|
240
|
+
i++;
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
// Any other character is rejected
|
|
244
|
+
throw new Error(`Safe expression evaluator: unexpected character '${ch}' at position ${i}`);
|
|
245
|
+
}
|
|
246
|
+
tokens.push({
|
|
247
|
+
type: 'eof',
|
|
248
|
+
value: null,
|
|
249
|
+
start: i
|
|
250
|
+
});
|
|
251
|
+
return tokens;
|
|
252
|
+
}
|
|
253
|
+
// ---------------------------------------------------------------------------
|
|
254
|
+
// Recursive-descent parser & evaluator
|
|
255
|
+
//
|
|
256
|
+
// Grammar (precedence low→high):
|
|
257
|
+
// expr → ternary
|
|
258
|
+
// ternary → logicalOr ('?' expr ':' expr)?
|
|
259
|
+
// logicalOr → logicalAnd ('||' logicalAnd)*
|
|
260
|
+
// logicalAnd → equality ('&&' equality)*
|
|
261
|
+
// equality → comparison (('=='|'==='|'!='|'!==') comparison)*
|
|
262
|
+
// comparison → additive (('<'|'>'|'<='|'>=') additive)*
|
|
263
|
+
// additive → multiplicative (('+'|'-') multiplicative)*
|
|
264
|
+
// multiplicative → unary (('*'|'/'|'%') unary)*
|
|
265
|
+
// unary → ('!'|'-'|'+') unary | postfix
|
|
266
|
+
// postfix → primary ('.' ident | '[' expr ']' | '(' args ')')*
|
|
267
|
+
// primary → number | string | boolean | null | ident | '(' expr ')'
|
|
268
|
+
// ---------------------------------------------------------------------------
|
|
269
|
+
class ExpressionParser {
|
|
270
|
+
parse() {
|
|
271
|
+
const result = this._parseExpression();
|
|
272
|
+
if (this._peek().type !== 'eof') {
|
|
273
|
+
throw new Error(`Safe expression evaluator: unexpected token '${this._peek().type}' at position ${this._peek().start}`);
|
|
274
|
+
}
|
|
275
|
+
return result;
|
|
276
|
+
}
|
|
277
|
+
_peek() {
|
|
278
|
+
return this.tokens[this.pos];
|
|
279
|
+
}
|
|
280
|
+
_advance() {
|
|
281
|
+
const token = this.tokens[this.pos];
|
|
282
|
+
this.pos++;
|
|
283
|
+
return token;
|
|
284
|
+
}
|
|
285
|
+
_expect(type) {
|
|
286
|
+
const token = this._peek();
|
|
287
|
+
if (token.type !== type) {
|
|
288
|
+
throw new Error(`Safe expression evaluator: expected '${type}' but got '${token.type}' at position ${token.start}`);
|
|
289
|
+
}
|
|
290
|
+
return this._advance();
|
|
291
|
+
}
|
|
292
|
+
_parseExpression() {
|
|
293
|
+
return this._parseTernary();
|
|
294
|
+
}
|
|
295
|
+
_parseTernary() {
|
|
296
|
+
const condition = this._parseOr();
|
|
297
|
+
if (this._peek().type === '?') {
|
|
298
|
+
this._advance();
|
|
299
|
+
const trueVal = this._parseExpression();
|
|
300
|
+
this._expect(':');
|
|
301
|
+
const falseVal = this._parseExpression();
|
|
302
|
+
return condition ? trueVal : falseVal;
|
|
303
|
+
}
|
|
304
|
+
return condition;
|
|
305
|
+
}
|
|
306
|
+
_parseOr() {
|
|
307
|
+
let left = this._parseAnd();
|
|
308
|
+
while(this._peek().type === '||'){
|
|
309
|
+
this._advance();
|
|
310
|
+
const right = this._parseAnd();
|
|
311
|
+
left = left || right;
|
|
312
|
+
}
|
|
313
|
+
return left;
|
|
314
|
+
}
|
|
315
|
+
_parseAnd() {
|
|
316
|
+
let left = this._parseEquality();
|
|
317
|
+
while(this._peek().type === '&&'){
|
|
318
|
+
this._advance();
|
|
319
|
+
const right = this._parseEquality();
|
|
320
|
+
left = left && right;
|
|
321
|
+
}
|
|
322
|
+
return left;
|
|
323
|
+
}
|
|
324
|
+
_parseEquality() {
|
|
325
|
+
let left = this._parseComparison();
|
|
326
|
+
while([
|
|
327
|
+
'==',
|
|
328
|
+
'===',
|
|
329
|
+
'!=',
|
|
330
|
+
'!=='
|
|
331
|
+
].includes(this._peek().type)){
|
|
332
|
+
const op = this._advance().type;
|
|
333
|
+
const right = this._parseComparison();
|
|
334
|
+
switch(op){
|
|
335
|
+
case '==':
|
|
336
|
+
// eslint-disable-next-line eqeqeq
|
|
337
|
+
left = left == right;
|
|
338
|
+
break;
|
|
339
|
+
case '===':
|
|
340
|
+
left = left === right;
|
|
341
|
+
break;
|
|
342
|
+
case '!=':
|
|
343
|
+
// eslint-disable-next-line eqeqeq
|
|
344
|
+
left = left != right;
|
|
345
|
+
break;
|
|
346
|
+
case '!==':
|
|
347
|
+
left = left !== right;
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return left;
|
|
352
|
+
}
|
|
353
|
+
_parseComparison() {
|
|
354
|
+
let left = this._parseAdditive();
|
|
355
|
+
while([
|
|
356
|
+
'<',
|
|
357
|
+
'>',
|
|
358
|
+
'<=',
|
|
359
|
+
'>='
|
|
360
|
+
].includes(this._peek().type)){
|
|
361
|
+
const op = this._advance().type;
|
|
362
|
+
const right = this._parseAdditive();
|
|
363
|
+
switch(op){
|
|
364
|
+
case '<':
|
|
365
|
+
left = left < right;
|
|
366
|
+
break;
|
|
367
|
+
case '>':
|
|
368
|
+
left = left > right;
|
|
369
|
+
break;
|
|
370
|
+
case '<=':
|
|
371
|
+
left = left <= right;
|
|
372
|
+
break;
|
|
373
|
+
case '>=':
|
|
374
|
+
left = left >= right;
|
|
375
|
+
break;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return left;
|
|
379
|
+
}
|
|
380
|
+
_parseAdditive() {
|
|
381
|
+
let left = this._parseMultiplicative();
|
|
382
|
+
while([
|
|
383
|
+
'+',
|
|
384
|
+
'-'
|
|
385
|
+
].includes(this._peek().type)){
|
|
386
|
+
const op = this._advance().type;
|
|
387
|
+
const right = this._parseMultiplicative();
|
|
388
|
+
if (op === '+') {
|
|
389
|
+
left = typeof left === 'string' || typeof right === 'string' ? String(left) + String(right) : left + right;
|
|
390
|
+
} else {
|
|
391
|
+
left = left - right;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return left;
|
|
395
|
+
}
|
|
396
|
+
_parseMultiplicative() {
|
|
397
|
+
let left = this._parseUnary();
|
|
398
|
+
while([
|
|
399
|
+
'*',
|
|
400
|
+
'/',
|
|
401
|
+
'%'
|
|
402
|
+
].includes(this._peek().type)){
|
|
403
|
+
const op = this._advance().type;
|
|
404
|
+
const right = this._parseUnary();
|
|
405
|
+
switch(op){
|
|
406
|
+
case '*':
|
|
407
|
+
left = left * right;
|
|
408
|
+
break;
|
|
409
|
+
case '/':
|
|
410
|
+
left = left / right;
|
|
411
|
+
break;
|
|
412
|
+
case '%':
|
|
413
|
+
left = left % right;
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
return left;
|
|
418
|
+
}
|
|
419
|
+
_parseUnary() {
|
|
420
|
+
if (this._peek().type === '!') {
|
|
421
|
+
this._advance();
|
|
422
|
+
return !this._parseUnary();
|
|
423
|
+
}
|
|
424
|
+
if (this._peek().type === '-') {
|
|
425
|
+
this._advance();
|
|
426
|
+
return -this._parseUnary();
|
|
427
|
+
}
|
|
428
|
+
if (this._peek().type === '+') {
|
|
429
|
+
this._advance();
|
|
430
|
+
return +this._parseUnary();
|
|
431
|
+
}
|
|
432
|
+
return this._parsePostfix();
|
|
433
|
+
}
|
|
434
|
+
_parsePostfix() {
|
|
435
|
+
let value = this._parsePrimary();
|
|
436
|
+
while(true){
|
|
437
|
+
if (this._peek().type === '.') {
|
|
438
|
+
// Property access: obj.prop — only own properties allowed
|
|
439
|
+
this._advance();
|
|
440
|
+
const prop = this._expect('ident');
|
|
441
|
+
const propName = prop.value;
|
|
442
|
+
if (hasOwn(value, propName)) {
|
|
443
|
+
value = value[propName];
|
|
444
|
+
} else {
|
|
445
|
+
value = undefined;
|
|
446
|
+
}
|
|
447
|
+
} else if (this._peek().type === '[') {
|
|
448
|
+
// Bracket access: obj['prop'] or obj[expr] — only own properties allowed
|
|
449
|
+
this._advance();
|
|
450
|
+
const index = this._parseExpression();
|
|
451
|
+
this._expect(']');
|
|
452
|
+
const key = String(index);
|
|
453
|
+
if (hasOwn(value, key)) {
|
|
454
|
+
value = value[key];
|
|
455
|
+
} else {
|
|
456
|
+
value = undefined;
|
|
457
|
+
}
|
|
458
|
+
} else if (this._peek().type === '(') {
|
|
459
|
+
// Function call — only safe built-in functions are callable
|
|
460
|
+
if (typeof value !== 'function') {
|
|
461
|
+
throw new Error('Safe expression evaluator: function calls are only allowed for built-in functions');
|
|
462
|
+
}
|
|
463
|
+
this._advance();
|
|
464
|
+
const args = [];
|
|
465
|
+
if (this._peek().type !== ')') {
|
|
466
|
+
args.push(this._parseExpression());
|
|
467
|
+
while(this._peek().type === ','){
|
|
468
|
+
this._advance();
|
|
469
|
+
args.push(this._parseExpression());
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
this._expect(')');
|
|
473
|
+
value = value(...args);
|
|
474
|
+
} else {
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return value;
|
|
479
|
+
}
|
|
480
|
+
_parsePrimary() {
|
|
481
|
+
const token = this._peek();
|
|
482
|
+
switch(token.type){
|
|
483
|
+
case 'number':
|
|
484
|
+
case 'string':
|
|
485
|
+
case 'boolean':
|
|
486
|
+
case 'null':
|
|
487
|
+
this._advance();
|
|
488
|
+
return token.value;
|
|
489
|
+
case 'ident':
|
|
490
|
+
{
|
|
491
|
+
const name = token.value;
|
|
492
|
+
if (!ALLOWED_IDENTIFIERS.has(name)) {
|
|
493
|
+
throw new Error(`Safe expression evaluator: unknown identifier '${name}'`);
|
|
494
|
+
}
|
|
495
|
+
this._advance();
|
|
496
|
+
if (name === 'datum') {
|
|
497
|
+
return this.context.datum;
|
|
498
|
+
}
|
|
499
|
+
if (name in SAFE_FUNCTIONS) {
|
|
500
|
+
return SAFE_FUNCTIONS[name];
|
|
501
|
+
}
|
|
502
|
+
if (name in SAFE_CONSTANTS) {
|
|
503
|
+
return SAFE_CONSTANTS[name];
|
|
504
|
+
}
|
|
505
|
+
return undefined;
|
|
506
|
+
}
|
|
507
|
+
case '(':
|
|
508
|
+
{
|
|
509
|
+
this._advance();
|
|
510
|
+
const result = this._parseExpression();
|
|
511
|
+
this._expect(')');
|
|
512
|
+
return result;
|
|
513
|
+
}
|
|
514
|
+
default:
|
|
515
|
+
throw new Error(`Safe expression evaluator: unexpected token '${token.type}' at position ${token.start}`);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
constructor(tokens, context){
|
|
519
|
+
(0, _define_property._)(this, "tokens", void 0);
|
|
520
|
+
(0, _define_property._)(this, "pos", void 0);
|
|
521
|
+
(0, _define_property._)(this, "context", void 0);
|
|
522
|
+
this.tokens = tokens;
|
|
523
|
+
this.pos = 0;
|
|
524
|
+
this.context = context;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
function safeEvaluateExpression(expr, datum) {
|
|
528
|
+
const tokens = tokenize(expr);
|
|
529
|
+
const parser = new ExpressionParser(tokens, {
|
|
530
|
+
datum
|
|
531
|
+
});
|
|
532
|
+
return parser.parse();
|
|
533
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/VegaDeclarativeChart/VegaLiteExpressionEvaluator.ts"],"sourcesContent":["/**\n * Safe expression evaluator for Vega-Lite expressions.\n *\n * Recursive-descent parser that only supports the safe subset of the\n * Vega-Lite expression language:\n * - Property access: datum.field, datum['field'] (own properties only)\n * - Arithmetic: +, -, *, /, %\n * - Comparison: ==, ===, !=, !==, <, >, <=, >=\n * - Logical: &&, ||, !\n * - Ternary: condition ? trueVal : falseVal\n * - Literals: numbers, strings, booleans, null\n * - Safe built-in functions: isValid, isDate, isNumber, isNaN, isFinite,\n * abs, ceil, floor, round, sqrt, log, exp, pow, min, max, length,\n * toNumber, toString, toBoolean\n * - Constants: PI, E, SQRT2, LN2, LN10, NaN, Infinity\n *\n * Everything else (assignment, arbitrary function calls, global access) is rejected.\n *\n * @see https://vega.github.io/vega/docs/expressions/\n */\n\n// ---------------------------------------------------------------------------\n// Token types\n// ---------------------------------------------------------------------------\ninterface Token {\n type: string;\n value: unknown;\n start: number;\n}\n\n// ---------------------------------------------------------------------------\n// Own-property check — only allow access to properties that exist directly\n// on the object (not inherited from the prototype chain). This is an allowlist\n// approach: constructor, __proto__, toString, valueOf, etc. are all inherited\n// and thus blocked automatically without maintaining a blocklist.\n// ---------------------------------------------------------------------------\nconst hasOwn = (obj: unknown, prop: string): boolean =>\n obj !== null && obj !== undefined && typeof obj === 'object' && Object.prototype.hasOwnProperty.call(obj, prop);\n\n// ---------------------------------------------------------------------------\n// Whitelisted built-in functions (mirrors the Vega expression function set)\n// ---------------------------------------------------------------------------\nconst SAFE_FUNCTIONS: Record<string, (...args: unknown[]) => unknown> = {\n isValid: (x: unknown) => x !== null && x !== undefined && (typeof x !== 'number' || !isNaN(x as number)),\n isDate: (x: unknown) => x instanceof Date,\n isNumber: (x: unknown) => typeof x === 'number' && !isNaN(x as number),\n isString: (x: unknown) => typeof x === 'string',\n isBoolean: (x: unknown) => typeof x === 'boolean',\n isArray: (x: unknown) => Array.isArray(x),\n isNaN: (x: unknown) => isNaN(x as number),\n isFinite: (x: unknown) => Number.isFinite(x),\n abs: (x: unknown) => Math.abs(x as number),\n ceil: (x: unknown) => Math.ceil(x as number),\n floor: (x: unknown) => Math.floor(x as number),\n round: (x: unknown) => Math.round(x as number),\n sqrt: (x: unknown) => Math.sqrt(x as number),\n log: (x: unknown) => Math.log(x as number),\n exp: (x: unknown) => Math.exp(x as number),\n pow: (x: unknown, y: unknown) => (x as number) ** (y as number),\n min: (...args: unknown[]) => Math.min(...(args as number[])),\n max: (...args: unknown[]) => Math.max(...(args as number[])),\n length: (x: unknown) => (typeof x === 'string' || Array.isArray(x) ? (x as string | unknown[]).length : 0),\n toNumber: (x: unknown) => Number(x),\n toString: (x: unknown) => String(x),\n toBoolean: (x: unknown) => Boolean(x),\n};\n\n// ---------------------------------------------------------------------------\n// Whitelisted constants\n// ---------------------------------------------------------------------------\nconst SAFE_CONSTANTS: Record<string, unknown> = {\n PI: Math.PI,\n E: Math.E,\n SQRT2: Math.SQRT2,\n LN2: Math.LN2,\n LN10: Math.LN10,\n NaN,\n Infinity,\n};\n\n// Set of all allowed top-level identifiers\nconst ALLOWED_IDENTIFIERS = new Set(['datum', ...Object.keys(SAFE_FUNCTIONS), ...Object.keys(SAFE_CONSTANTS)]);\n\n// ---------------------------------------------------------------------------\n// Tokenizer\n// ---------------------------------------------------------------------------\nfunction tokenize(expr: string): Token[] {\n const tokens: Token[] = [];\n let i = 0;\n\n while (i < expr.length) {\n // Skip whitespace\n if (/\\s/.test(expr[i])) {\n i++;\n continue;\n }\n\n // Numbers (including decimal and scientific notation)\n if (/[0-9]/.test(expr[i]) || (expr[i] === '.' && i + 1 < expr.length && /[0-9]/.test(expr[i + 1]))) {\n const start = i;\n while (i < expr.length && /[0-9.]/.test(expr[i])) {\n i++;\n }\n if (i < expr.length && (expr[i] === 'e' || expr[i] === 'E')) {\n i++;\n if (i < expr.length && (expr[i] === '+' || expr[i] === '-')) {\n i++;\n }\n while (i < expr.length && /[0-9]/.test(expr[i])) {\n i++;\n }\n }\n tokens.push({ type: 'number', value: parseFloat(expr.slice(start, i)), start });\n continue;\n }\n\n // Strings (single or double quoted)\n if (expr[i] === '\"' || expr[i] === \"'\") {\n const quote = expr[i];\n const start = i;\n i++;\n let str = '';\n while (i < expr.length && expr[i] !== quote) {\n if (expr[i] === '\\\\') {\n i++;\n if (i < expr.length) {\n switch (expr[i]) {\n case 'n':\n str += '\\n';\n break;\n case 't':\n str += '\\t';\n break;\n case '\\\\':\n str += '\\\\';\n break;\n case \"'\":\n str += \"'\";\n break;\n case '\"':\n str += '\"';\n break;\n default:\n str += expr[i];\n }\n }\n } else {\n str += expr[i];\n }\n i++;\n }\n if (i < expr.length) {\n i++; // Skip closing quote\n }\n tokens.push({ type: 'string', value: str, start });\n continue;\n }\n\n // Identifiers and keywords\n if (/[a-zA-Z_$]/.test(expr[i])) {\n const start = i;\n while (i < expr.length && /[a-zA-Z0-9_$]/.test(expr[i])) {\n i++;\n }\n const word = expr.slice(start, i);\n switch (word) {\n case 'true':\n tokens.push({ type: 'boolean', value: true, start });\n break;\n case 'false':\n tokens.push({ type: 'boolean', value: false, start });\n break;\n case 'null':\n tokens.push({ type: 'null', value: null, start });\n break;\n case 'undefined':\n tokens.push({ type: 'null', value: undefined, start });\n break;\n default:\n tokens.push({ type: 'ident', value: word, start });\n }\n continue;\n }\n\n // Multi-character operators\n const start = i;\n const three = expr.slice(i, i + 3);\n const two = expr.slice(i, i + 2);\n\n if (three === '===' || three === '!==') {\n tokens.push({ type: three, value: three, start });\n i += 3;\n continue;\n }\n if (two === '==' || two === '!=' || two === '<=' || two === '>=' || two === '&&' || two === '||') {\n tokens.push({ type: two, value: two, start });\n i += 2;\n continue;\n }\n\n // Single-character operators and punctuation\n const ch = expr[i];\n if ('+-*/%<>!.()[],?:'.includes(ch)) {\n tokens.push({ type: ch, value: ch, start });\n i++;\n continue;\n }\n\n // Any other character is rejected\n throw new Error(`Safe expression evaluator: unexpected character '${ch}' at position ${i}`);\n }\n\n tokens.push({ type: 'eof', value: null, start: i });\n return tokens;\n}\n\n// ---------------------------------------------------------------------------\n// Recursive-descent parser & evaluator\n//\n// Grammar (precedence low→high):\n// expr → ternary\n// ternary → logicalOr ('?' expr ':' expr)?\n// logicalOr → logicalAnd ('||' logicalAnd)*\n// logicalAnd → equality ('&&' equality)*\n// equality → comparison (('=='|'==='|'!='|'!==') comparison)*\n// comparison → additive (('<'|'>'|'<='|'>=') additive)*\n// additive → multiplicative (('+'|'-') multiplicative)*\n// multiplicative → unary (('*'|'/'|'%') unary)*\n// unary → ('!'|'-'|'+') unary | postfix\n// postfix → primary ('.' ident | '[' expr ']' | '(' args ')')*\n// primary → number | string | boolean | null | ident | '(' expr ')'\n// ---------------------------------------------------------------------------\nclass ExpressionParser {\n private tokens: Token[];\n private pos: number;\n private context: Record<string, unknown>;\n\n constructor(tokens: Token[], context: Record<string, unknown>) {\n this.tokens = tokens;\n this.pos = 0;\n this.context = context;\n }\n\n public parse(): unknown {\n const result = this._parseExpression();\n if (this._peek().type !== 'eof') {\n throw new Error(\n `Safe expression evaluator: unexpected token '${this._peek().type}' at position ${this._peek().start}`,\n );\n }\n return result;\n }\n\n private _peek(): Token {\n return this.tokens[this.pos];\n }\n\n private _advance(): Token {\n const token = this.tokens[this.pos];\n this.pos++;\n return token;\n }\n\n private _expect(type: string): Token {\n const token = this._peek();\n if (token.type !== type) {\n throw new Error(\n `Safe expression evaluator: expected '${type}' but got '${token.type}' at position ${token.start}`,\n );\n }\n return this._advance();\n }\n\n private _parseExpression(): unknown {\n return this._parseTernary();\n }\n\n private _parseTernary(): unknown {\n const condition = this._parseOr();\n if (this._peek().type === '?') {\n this._advance();\n const trueVal = this._parseExpression();\n this._expect(':');\n const falseVal = this._parseExpression();\n return condition ? trueVal : falseVal;\n }\n return condition;\n }\n\n private _parseOr(): unknown {\n let left = this._parseAnd();\n while (this._peek().type === '||') {\n this._advance();\n const right = this._parseAnd();\n left = left || right;\n }\n return left;\n }\n\n private _parseAnd(): unknown {\n let left = this._parseEquality();\n while (this._peek().type === '&&') {\n this._advance();\n const right = this._parseEquality();\n left = left && right;\n }\n return left;\n }\n\n private _parseEquality(): unknown {\n let left = this._parseComparison();\n while (['==', '===', '!=', '!=='].includes(this._peek().type)) {\n const op = this._advance().type;\n const right = this._parseComparison();\n switch (op) {\n case '==':\n // eslint-disable-next-line eqeqeq\n left = left == right;\n break;\n case '===':\n left = left === right;\n break;\n case '!=':\n // eslint-disable-next-line eqeqeq\n left = left != right;\n break;\n case '!==':\n left = left !== right;\n break;\n }\n }\n return left;\n }\n\n private _parseComparison(): unknown {\n let left = this._parseAdditive();\n while (['<', '>', '<=', '>='].includes(this._peek().type)) {\n const op = this._advance().type;\n const right = this._parseAdditive();\n switch (op) {\n case '<':\n left = (left as number) < (right as number);\n break;\n case '>':\n left = (left as number) > (right as number);\n break;\n case '<=':\n left = (left as number) <= (right as number);\n break;\n case '>=':\n left = (left as number) >= (right as number);\n break;\n }\n }\n return left;\n }\n\n private _parseAdditive(): unknown {\n let left = this._parseMultiplicative();\n while (['+', '-'].includes(this._peek().type)) {\n const op = this._advance().type;\n const right = this._parseMultiplicative();\n if (op === '+') {\n left =\n typeof left === 'string' || typeof right === 'string'\n ? String(left) + String(right)\n : (left as number) + (right as number);\n } else {\n left = (left as number) - (right as number);\n }\n }\n return left;\n }\n\n private _parseMultiplicative(): unknown {\n let left = this._parseUnary();\n while (['*', '/', '%'].includes(this._peek().type)) {\n const op = this._advance().type;\n const right = this._parseUnary();\n switch (op) {\n case '*':\n left = (left as number) * (right as number);\n break;\n case '/':\n left = (left as number) / (right as number);\n break;\n case '%':\n left = (left as number) % (right as number);\n break;\n }\n }\n return left;\n }\n\n private _parseUnary(): unknown {\n if (this._peek().type === '!') {\n this._advance();\n return !this._parseUnary();\n }\n if (this._peek().type === '-') {\n this._advance();\n return -(this._parseUnary() as number);\n }\n if (this._peek().type === '+') {\n this._advance();\n return +(this._parseUnary() as number);\n }\n return this._parsePostfix();\n }\n\n private _parsePostfix(): unknown {\n let value = this._parsePrimary();\n\n while (true) {\n if (this._peek().type === '.') {\n // Property access: obj.prop — only own properties allowed\n this._advance();\n const prop = this._expect('ident');\n const propName = prop.value as string;\n\n if (hasOwn(value, propName)) {\n value = (value as Record<string, unknown>)[propName];\n } else {\n value = undefined;\n }\n } else if (this._peek().type === '[') {\n // Bracket access: obj['prop'] or obj[expr] — only own properties allowed\n this._advance();\n const index = this._parseExpression();\n this._expect(']');\n\n const key = String(index);\n if (hasOwn(value, key)) {\n value = (value as Record<string, unknown>)[key];\n } else {\n value = undefined;\n }\n } else if (this._peek().type === '(') {\n // Function call — only safe built-in functions are callable\n if (typeof value !== 'function') {\n throw new Error('Safe expression evaluator: function calls are only allowed for built-in functions');\n }\n this._advance();\n const args: unknown[] = [];\n if (this._peek().type !== ')') {\n args.push(this._parseExpression());\n while (this._peek().type === ',') {\n this._advance();\n args.push(this._parseExpression());\n }\n }\n this._expect(')');\n value = (value as (...a: unknown[]) => unknown)(...args);\n } else {\n break;\n }\n }\n\n return value;\n }\n\n private _parsePrimary(): unknown {\n const token = this._peek();\n\n switch (token.type) {\n case 'number':\n case 'string':\n case 'boolean':\n case 'null':\n this._advance();\n return token.value;\n\n case 'ident': {\n const name = token.value as string;\n if (!ALLOWED_IDENTIFIERS.has(name)) {\n throw new Error(`Safe expression evaluator: unknown identifier '${name}'`);\n }\n this._advance();\n if (name === 'datum') {\n return this.context.datum;\n }\n if (name in SAFE_FUNCTIONS) {\n return SAFE_FUNCTIONS[name];\n }\n if (name in SAFE_CONSTANTS) {\n return SAFE_CONSTANTS[name];\n }\n return undefined;\n }\n\n case '(': {\n this._advance();\n const result = this._parseExpression();\n this._expect(')');\n return result;\n }\n\n default:\n throw new Error(`Safe expression evaluator: unexpected token '${token.type}' at position ${token.start}`);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Safely evaluates a Vega-Lite expression string against a datum object.\n *\n * Only allows property access, arithmetic, comparison, logical operators,\n * ternary expressions, literals, and a whitelist of built-in functions.\n * Rejects assignment, arbitrary function calls, and global object access.\n *\n * @param expr - The Vega-Lite expression string to evaluate\n * @param datum - The data row object (accessible as `datum` in the expression)\n * @returns The result of evaluating the expression\n * @throws Error if the expression contains disallowed constructs\n */\nexport function safeEvaluateExpression(expr: string, datum: Record<string, unknown>): unknown {\n const tokens = tokenize(expr);\n const parser = new ExpressionParser(tokens, { datum });\n return parser.parse();\n}\n"],"names":["hasOwn","obj","prop","undefined","Object","prototype","hasOwnProperty","call","SAFE_FUNCTIONS","isValid","x","isNaN","isDate","Date","isNumber","isString","isBoolean","isArray","Array","isFinite","Number","abs","Math","ceil","floor","round","sqrt","log","exp","pow","y","min","args","max","length","toNumber","toString","String","toBoolean","Boolean","SAFE_CONSTANTS","PI","E","SQRT2","LN2","LN10","NaN","Infinity","ALLOWED_IDENTIFIERS","Set","keys","tokenize","expr","tokens","i","test","start","push","type","value","parseFloat","slice","quote","str","word","three","two","ch","includes","Error","ExpressionParser","parse","result","_parseExpression","_peek","pos","_advance","token","_expect","_parseTernary","condition","_parseOr","trueVal","falseVal","left","_parseAnd","right","_parseEquality","_parseComparison","op","_parseAdditive","_parseMultiplicative","_parseUnary","_parsePostfix","_parsePrimary","propName","index","key","name","has","context","datum","constructor","safeEvaluateExpression","parser"],"mappings":"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"}
|