bonsai-js 0.4.0 → 0.5.0
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 +22 -0
- package/README.md +17 -6
- package/dist/autocomplete/index.d.mts +1 -1
- package/dist/autocomplete/index.d.mts.map +1 -1
- package/dist/autocomplete/index.mjs +16 -55
- package/dist/autocomplete/index.mjs.map +1 -1
- package/dist/{errors-BONB6P_5.mjs → errors-CCZDd1gK.mjs} +1 -1
- package/dist/errors-CCZDd1gK.mjs.map +1 -0
- package/dist/{execution-context-B-5hQ92X.mjs → execution-context-b6FBfEdv.mjs} +147 -16
- package/dist/execution-context-b6FBfEdv.mjs.map +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +144 -81
- package/dist/index.mjs.map +1 -1
- package/dist/stdlib/index.d.mts +1 -1
- package/dist/stdlib/index.d.mts.map +1 -1
- package/dist/stdlib/index.mjs +43 -11
- package/dist/stdlib/index.mjs.map +1 -1
- package/dist/{types-C58c6SlH.d.mts → types-DkXfy5IJ.d.mts} +4 -2
- package/dist/types-DkXfy5IJ.d.mts.map +1 -0
- package/package.json +37 -11
- package/dist/errors-BONB6P_5.mjs.map +0 -1
- package/dist/execution-context-B-5hQ92X.mjs.map +0 -1
- package/dist/types-C58c6SlH.d.mts.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as ExpressionError, n as BonsaiSecurityError } from "./errors-
|
|
1
|
+
import { i as ExpressionError, n as BonsaiSecurityError } from "./errors-CCZDd1gK.mjs";
|
|
2
2
|
//#region src/lexer.ts
|
|
3
3
|
const KEYWORDS = new Map([
|
|
4
4
|
["true", {
|
|
@@ -38,6 +38,19 @@ function isAlphaNumeric(ch) {
|
|
|
38
38
|
function isHexDigit(ch) {
|
|
39
39
|
return isDigit(ch) || ch >= "a" && ch <= "f" || ch >= "A" && ch <= "F";
|
|
40
40
|
}
|
|
41
|
+
const NUMERIC_SEPARATOR_PATTERNS = {
|
|
42
|
+
hex: /^0[xX][0-9a-fA-F]+(?:_[0-9a-fA-F]+)*$/u,
|
|
43
|
+
bin: /^0[bB][01]+(?:_[01]+)*$/u,
|
|
44
|
+
oct: /^0[oO][0-7]+(?:_[0-7]+)*$/u,
|
|
45
|
+
dec: /^\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?$/u
|
|
46
|
+
};
|
|
47
|
+
function checkNumericSeparators(value, kind, source, start, end) {
|
|
48
|
+
if (!NUMERIC_SEPARATOR_PATTERNS[kind].test(value)) throw new ExpressionError(`Invalid numeric literal "${value}": "_" separators must sit between digits`, {
|
|
49
|
+
source,
|
|
50
|
+
start,
|
|
51
|
+
end
|
|
52
|
+
});
|
|
53
|
+
}
|
|
41
54
|
function tokenize(source) {
|
|
42
55
|
const tokens = [];
|
|
43
56
|
let i = 0;
|
|
@@ -51,35 +64,62 @@ function tokenize(source) {
|
|
|
51
64
|
const start = i;
|
|
52
65
|
if (ch === "0" && i + 1 < source.length && (source[i + 1] === "x" || source[i + 1] === "X")) {
|
|
53
66
|
i += 2;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
type: "Number",
|
|
57
|
-
value: source.slice(start, i),
|
|
67
|
+
if (i >= source.length || !isHexDigit(source[i])) throw new ExpressionError("Invalid hexadecimal literal: expected at least one digit after \"0x\"", {
|
|
68
|
+
source,
|
|
58
69
|
start,
|
|
59
70
|
end: i
|
|
60
71
|
});
|
|
72
|
+
while (i < source.length && (isHexDigit(source[i]) || source[i] === "_")) i++;
|
|
73
|
+
{
|
|
74
|
+
const value = source.slice(start, i);
|
|
75
|
+
checkNumericSeparators(value, "hex", source, start, i);
|
|
76
|
+
tokens.push({
|
|
77
|
+
type: "Number",
|
|
78
|
+
value,
|
|
79
|
+
start,
|
|
80
|
+
end: i
|
|
81
|
+
});
|
|
82
|
+
}
|
|
61
83
|
continue;
|
|
62
84
|
}
|
|
63
85
|
if (ch === "0" && i + 1 < source.length && (source[i + 1] === "b" || source[i + 1] === "B")) {
|
|
64
86
|
i += 2;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
type: "Number",
|
|
68
|
-
value: source.slice(start, i),
|
|
87
|
+
if (i >= source.length || source[i] !== "0" && source[i] !== "1") throw new ExpressionError("Invalid binary literal: expected at least one digit after \"0b\"", {
|
|
88
|
+
source,
|
|
69
89
|
start,
|
|
70
90
|
end: i
|
|
71
91
|
});
|
|
92
|
+
while (i < source.length && (source[i] === "0" || source[i] === "1" || source[i] === "_")) i++;
|
|
93
|
+
{
|
|
94
|
+
const value = source.slice(start, i);
|
|
95
|
+
checkNumericSeparators(value, "bin", source, start, i);
|
|
96
|
+
tokens.push({
|
|
97
|
+
type: "Number",
|
|
98
|
+
value,
|
|
99
|
+
start,
|
|
100
|
+
end: i
|
|
101
|
+
});
|
|
102
|
+
}
|
|
72
103
|
continue;
|
|
73
104
|
}
|
|
74
105
|
if (ch === "0" && i + 1 < source.length && (source[i + 1] === "o" || source[i + 1] === "O")) {
|
|
75
106
|
i += 2;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
type: "Number",
|
|
79
|
-
value: source.slice(start, i),
|
|
107
|
+
if (i >= source.length || source[i] < "0" || source[i] > "7") throw new ExpressionError("Invalid octal literal: expected at least one digit after \"0o\"", {
|
|
108
|
+
source,
|
|
80
109
|
start,
|
|
81
110
|
end: i
|
|
82
111
|
});
|
|
112
|
+
while (i < source.length && (source[i] >= "0" && source[i] <= "7" || source[i] === "_")) i++;
|
|
113
|
+
{
|
|
114
|
+
const value = source.slice(start, i);
|
|
115
|
+
checkNumericSeparators(value, "oct", source, start, i);
|
|
116
|
+
tokens.push({
|
|
117
|
+
type: "Number",
|
|
118
|
+
value,
|
|
119
|
+
start,
|
|
120
|
+
end: i
|
|
121
|
+
});
|
|
122
|
+
}
|
|
83
123
|
continue;
|
|
84
124
|
}
|
|
85
125
|
while (i < source.length && (isDigit(source[i]) || source[i] === "_")) i++;
|
|
@@ -90,11 +130,18 @@ function tokenize(source) {
|
|
|
90
130
|
if (i < source.length && (source[i] === "e" || source[i] === "E")) {
|
|
91
131
|
i++;
|
|
92
132
|
if (i < source.length && (source[i] === "+" || source[i] === "-")) i++;
|
|
133
|
+
if (i >= source.length || !isDigit(source[i])) throw new ExpressionError("Invalid number: exponent has no digits", {
|
|
134
|
+
source,
|
|
135
|
+
start,
|
|
136
|
+
end: i
|
|
137
|
+
});
|
|
93
138
|
while (i < source.length && (isDigit(source[i]) || source[i] === "_")) i++;
|
|
94
139
|
}
|
|
140
|
+
const value = source.slice(start, i);
|
|
141
|
+
checkNumericSeparators(value, "dec", source, start, i);
|
|
95
142
|
tokens.push({
|
|
96
143
|
type: "Number",
|
|
97
|
-
value
|
|
144
|
+
value,
|
|
98
145
|
start,
|
|
99
146
|
end: i
|
|
100
147
|
});
|
|
@@ -230,6 +277,24 @@ function tokenize(source) {
|
|
|
230
277
|
}
|
|
231
278
|
continue;
|
|
232
279
|
}
|
|
280
|
+
if (ic === "`") {
|
|
281
|
+
raw += ic;
|
|
282
|
+
i++;
|
|
283
|
+
while (i < source.length && source[i] !== "`") {
|
|
284
|
+
if (source[i] === "\\" && i + 1 < source.length) {
|
|
285
|
+
raw += source[i] + source[i + 1];
|
|
286
|
+
i += 2;
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
raw += source[i];
|
|
290
|
+
i++;
|
|
291
|
+
}
|
|
292
|
+
if (i < source.length) {
|
|
293
|
+
raw += source[i];
|
|
294
|
+
i++;
|
|
295
|
+
}
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
233
298
|
if (ic === "{") depth++;
|
|
234
299
|
else if (ic === "}") depth--;
|
|
235
300
|
if (depth > 0) raw += ic;
|
|
@@ -472,6 +537,66 @@ function tokenize(source) {
|
|
|
472
537
|
return tokens;
|
|
473
538
|
}
|
|
474
539
|
//#endregion
|
|
540
|
+
//#region src/safe-methods.ts
|
|
541
|
+
/** Method name -> the receiver types it is permitted on. */
|
|
542
|
+
const SAFE_METHODS = {
|
|
543
|
+
startsWith: ["string"],
|
|
544
|
+
endsWith: ["string"],
|
|
545
|
+
substring: ["string"],
|
|
546
|
+
charAt: ["string"],
|
|
547
|
+
charCodeAt: ["string"],
|
|
548
|
+
repeat: ["string"],
|
|
549
|
+
trim: ["string"],
|
|
550
|
+
trimStart: ["string"],
|
|
551
|
+
trimEnd: ["string"],
|
|
552
|
+
toLowerCase: ["string"],
|
|
553
|
+
toUpperCase: ["string"],
|
|
554
|
+
replace: ["string"],
|
|
555
|
+
replaceAll: ["string"],
|
|
556
|
+
padStart: ["string"],
|
|
557
|
+
padEnd: ["string"],
|
|
558
|
+
split: ["string"],
|
|
559
|
+
includes: ["string", "array"],
|
|
560
|
+
indexOf: ["string", "array"],
|
|
561
|
+
lastIndexOf: ["string", "array"],
|
|
562
|
+
slice: ["string", "array"],
|
|
563
|
+
at: ["string", "array"],
|
|
564
|
+
concat: ["string", "array"],
|
|
565
|
+
filter: ["array"],
|
|
566
|
+
map: ["array"],
|
|
567
|
+
find: ["array"],
|
|
568
|
+
findIndex: ["array"],
|
|
569
|
+
some: ["array"],
|
|
570
|
+
every: ["array"],
|
|
571
|
+
flatMap: ["array"],
|
|
572
|
+
join: ["array"],
|
|
573
|
+
flat: ["array"],
|
|
574
|
+
toReversed: ["array"],
|
|
575
|
+
toSorted: ["array"],
|
|
576
|
+
toSpliced: ["array"],
|
|
577
|
+
with: ["array"],
|
|
578
|
+
toFixed: ["number"],
|
|
579
|
+
toString: ["number", "string"]
|
|
580
|
+
};
|
|
581
|
+
/** Map a runtime value to its method-receiver type, or undefined if it has none. */
|
|
582
|
+
function receiverTypeOf(obj) {
|
|
583
|
+
const t = typeof obj;
|
|
584
|
+
if (t === "string") return "string";
|
|
585
|
+
if (t === "number") return "number";
|
|
586
|
+
if (Array.isArray(obj)) return "array";
|
|
587
|
+
}
|
|
588
|
+
/** Whether `method` is a safe built-in method for the runtime type of `obj`. */
|
|
589
|
+
function isMethodAllowedOn(obj, method) {
|
|
590
|
+
const receiver = receiverTypeOf(obj);
|
|
591
|
+
if (receiver === void 0) return false;
|
|
592
|
+
const allowed = SAFE_METHODS[method];
|
|
593
|
+
return allowed !== void 0 && allowed.includes(receiver);
|
|
594
|
+
}
|
|
595
|
+
/** All safe method names available on a given receiver type. */
|
|
596
|
+
function methodsForReceiverType(type) {
|
|
597
|
+
return Object.keys(SAFE_METHODS).filter((method) => SAFE_METHODS[method].includes(type));
|
|
598
|
+
}
|
|
599
|
+
//#endregion
|
|
475
600
|
//#region src/execution-context.ts
|
|
476
601
|
const BLOCKED_PROPERTIES = new Set([
|
|
477
602
|
"__proto__",
|
|
@@ -487,16 +612,19 @@ function isCanonicalIndex(key) {
|
|
|
487
612
|
const TIMEOUT_CHECK_INTERVAL = 1e3;
|
|
488
613
|
const DEFAULT_MAX_DEPTH = 100;
|
|
489
614
|
const DEFAULT_MAX_ARRAY_LENGTH = 1e5;
|
|
615
|
+
const DEFAULT_MAX_STRING_LENGTH = 1e5;
|
|
490
616
|
/** Immutable per-instance security configuration derived from BonsaiOptions. */
|
|
491
617
|
var SecurityPolicy = class {
|
|
492
618
|
maxDepth;
|
|
493
619
|
maxArrayLength;
|
|
620
|
+
maxStringLength;
|
|
494
621
|
timeout;
|
|
495
622
|
allowedProperties;
|
|
496
623
|
deniedProperties;
|
|
497
624
|
constructor(options = {}) {
|
|
498
625
|
this.maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
499
626
|
this.maxArrayLength = options.maxArrayLength ?? DEFAULT_MAX_ARRAY_LENGTH;
|
|
627
|
+
this.maxStringLength = options.maxStringLength ?? DEFAULT_MAX_STRING_LENGTH;
|
|
500
628
|
this.timeout = options.timeout ?? 0;
|
|
501
629
|
this.allowedProperties = options.allowedProperties ? new Set(options.allowedProperties) : void 0;
|
|
502
630
|
this.deniedProperties = options.deniedProperties ? new Set(options.deniedProperties) : void 0;
|
|
@@ -557,8 +685,11 @@ var ExecutionContext = class {
|
|
|
557
685
|
checkArrayLength(length) {
|
|
558
686
|
if (length > this.policy.maxArrayLength) throw new BonsaiSecurityError("MAX_ARRAY_LENGTH", `Array length (${length}) exceeds maximum (${this.policy.maxArrayLength})`);
|
|
559
687
|
}
|
|
688
|
+
checkStringLength(length) {
|
|
689
|
+
if (length > this.policy.maxStringLength) throw new BonsaiSecurityError("MAX_STRING_LENGTH", `String length (${length}) exceeds maximum (${this.policy.maxStringLength})`);
|
|
690
|
+
}
|
|
560
691
|
};
|
|
561
692
|
//#endregion
|
|
562
|
-
export {
|
|
693
|
+
export { methodsForReceiverType as a, isMethodAllowedOn as i, ExecutionContext as n, tokenize as o, SecurityPolicy as r, BLOCKED_PROPERTIES as t };
|
|
563
694
|
|
|
564
|
-
//# sourceMappingURL=execution-context-
|
|
695
|
+
//# sourceMappingURL=execution-context-b6FBfEdv.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-context-b6FBfEdv.mjs","names":[],"sources":["../src/lexer.ts","../src/safe-methods.ts","../src/execution-context.ts"],"sourcesContent":["import type { Token, PunctuationValue } from './types.js'\nimport { ExpressionError } from './errors.js'\n\nconst KEYWORDS = new Map<string, { type: Token['type']; value: string }>([\n ['true', { type: 'Boolean', value: 'true' }],\n ['false', { type: 'Boolean', value: 'false' }],\n ['null', { type: 'Null', value: 'null' }],\n ['undefined', { type: 'Undefined', value: 'undefined' }],\n ['in', { type: 'Operator', value: 'in' }],\n ['not', { type: 'Operator', value: 'not' }],\n])\n\nfunction isDigit(ch: string): boolean {\n return ch >= '0' && ch <= '9'\n}\n\nfunction isAlpha(ch: string): boolean {\n return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch === '_' || ch === '$'\n}\n\nfunction isAlphaNumeric(ch: string): boolean {\n return isAlpha(ch) || isDigit(ch)\n}\n\nfunction isHexDigit(ch: string): boolean {\n return isDigit(ch) || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')\n}\n\n// A numeric separator `_` is only legal between two digits of the same radix.\n// The digit-consuming loops below accept `_` freely, so validate the produced\n// literal here to reject leading, trailing, or doubled separators (`1_`,\n// `1__0`, `0xff_`), which JS rejects and which Number() would otherwise coerce\n// silently (e.g. Number('0xff_') === 255, Number('1_') === NaN).\nconst NUMERIC_SEPARATOR_PATTERNS = {\n hex: /^0[xX][0-9a-fA-F]+(?:_[0-9a-fA-F]+)*$/u,\n bin: /^0[bB][01]+(?:_[01]+)*$/u,\n oct: /^0[oO][0-7]+(?:_[0-7]+)*$/u,\n dec: /^\\d+(?:_\\d+)*(?:\\.\\d+(?:_\\d+)*)?(?:[eE][+-]?\\d+(?:_\\d+)*)?$/u,\n} as const\n\nfunction checkNumericSeparators(\n value: string,\n kind: keyof typeof NUMERIC_SEPARATOR_PATTERNS,\n source: string,\n start: number,\n end: number,\n): void {\n if (!NUMERIC_SEPARATOR_PATTERNS[kind].test(value)) {\n throw new ExpressionError(\n `Invalid numeric literal \"${value}\": \"_\" separators must sit between digits`,\n { source, start, end },\n )\n }\n}\n\nexport function tokenize(source: string): Token[] {\n const tokens: Token[] = []\n let i = 0\n\n while (i < source.length) {\n const ch = source[i]\n\n // Skip whitespace\n if (ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '\\r') {\n i++\n continue\n }\n\n // Numbers: decimal, hex, binary, octal, scientific, underscores\n if (isDigit(ch)) {\n const start = i\n\n // Hex: 0x...\n if (ch === '0' && i + 1 < source.length && (source[i + 1] === 'x' || source[i + 1] === 'X')) {\n i += 2\n if (i >= source.length || !isHexDigit(source[i])) {\n throw new ExpressionError('Invalid hexadecimal literal: expected at least one digit after \"0x\"', { source, start, end: i })\n }\n while (i < source.length && (isHexDigit(source[i]) || source[i] === '_')) i++\n {\n const value = source.slice(start, i)\n checkNumericSeparators(value, 'hex', source, start, i)\n tokens.push({ type: 'Number', value, start, end: i })\n }\n continue\n }\n\n // Binary: 0b...\n if (ch === '0' && i + 1 < source.length && (source[i + 1] === 'b' || source[i + 1] === 'B')) {\n i += 2\n if (i >= source.length || (source[i] !== '0' && source[i] !== '1')) {\n throw new ExpressionError('Invalid binary literal: expected at least one digit after \"0b\"', { source, start, end: i })\n }\n while (i < source.length && (source[i] === '0' || source[i] === '1' || source[i] === '_')) i++\n {\n const value = source.slice(start, i)\n checkNumericSeparators(value, 'bin', source, start, i)\n tokens.push({ type: 'Number', value, start, end: i })\n }\n continue\n }\n\n // Octal: 0o...\n if (ch === '0' && i + 1 < source.length && (source[i + 1] === 'o' || source[i + 1] === 'O')) {\n i += 2\n if (i >= source.length || source[i] < '0' || source[i] > '7') {\n throw new ExpressionError('Invalid octal literal: expected at least one digit after \"0o\"', { source, start, end: i })\n }\n while (i < source.length && ((source[i] >= '0' && source[i] <= '7') || source[i] === '_')) i++\n {\n const value = source.slice(start, i)\n checkNumericSeparators(value, 'oct', source, start, i)\n tokens.push({ type: 'Number', value, start, end: i })\n }\n continue\n }\n\n // Decimal (with optional underscore separators)\n while (i < source.length && (isDigit(source[i]) || source[i] === '_')) i++\n if (i < source.length && source[i] === '.' && i + 1 < source.length && isDigit(source[i + 1])) {\n i++ // skip '.'\n while (i < source.length && (isDigit(source[i]) || source[i] === '_')) i++\n }\n\n // Scientific notation: e/E followed by optional +/- and at least one digit\n if (i < source.length && (source[i] === 'e' || source[i] === 'E')) {\n i++\n if (i < source.length && (source[i] === '+' || source[i] === '-')) i++\n if (i >= source.length || !isDigit(source[i])) {\n throw new ExpressionError('Invalid number: exponent has no digits', { source, start, end: i })\n }\n while (i < source.length && (isDigit(source[i]) || source[i] === '_')) i++\n }\n\n const value = source.slice(start, i)\n checkNumericSeparators(value, 'dec', source, start, i)\n tokens.push({ type: 'Number', value, start, end: i })\n continue\n }\n\n // Strings\n if (ch === '\"' || ch === \"'\") {\n const quote = ch\n const start = i\n i++ // skip opening quote\n let value = ''\n while (i < source.length && source[i] !== quote) {\n if (source[i] === '\\\\') {\n i++\n const escaped = source[i]\n switch (escaped) {\n case 'n': value += '\\n'; break\n case 't': value += '\\t'; break\n case 'r': value += '\\r'; break\n case '\\\\': value += '\\\\'; break\n case '0': value += '\\0'; break\n case 'x': {\n const hex = source.slice(i + 1, i + 3)\n if (hex.length < 2 || !isHexDigit(hex[0]) || !isHexDigit(hex[1])) {\n throw new ExpressionError('Invalid \\\\x escape: expected 2 hex digits', { source, start, end: i + 3 })\n }\n value += String.fromCharCode(parseInt(hex, 16))\n i += 2\n break\n }\n case 'u': {\n if (i + 1 < source.length && source[i + 1] === '{') {\n const closeBrace = source.indexOf('}', i + 2)\n if (closeBrace === -1) {\n throw new ExpressionError('Invalid \\\\u{} escape: missing closing brace', { source, start, end: source.length })\n }\n const hex = source.slice(i + 2, closeBrace)\n if (hex.length === 0) {\n throw new ExpressionError('Invalid \\\\u{} escape: empty code point', { source, start, end: closeBrace + 1 })\n }\n for (const c of hex) {\n if (!isHexDigit(c)) {\n throw new ExpressionError(`Invalid \\\\u{} escape: non-hex digit \"${c}\"`, { source, start, end: closeBrace + 1 })\n }\n }\n const MAX_UNICODE_CODE_POINT = 0x10FFFF\n const codePoint = parseInt(hex, 16)\n if (codePoint > MAX_UNICODE_CODE_POINT) {\n throw new ExpressionError('Invalid \\\\u{} escape: code point out of range', { source, start, end: closeBrace + 1 })\n }\n value += String.fromCodePoint(codePoint)\n i = closeBrace\n } else {\n const UNICODE_ESCAPE_LEN = 4\n const hex = source.slice(i + 1, i + 1 + UNICODE_ESCAPE_LEN)\n if (hex.length < UNICODE_ESCAPE_LEN) {\n throw new ExpressionError('Invalid \\\\u escape: expected 4 hex digits', { source, start, end: i + 1 + UNICODE_ESCAPE_LEN })\n }\n for (const c of hex) {\n if (!isHexDigit(c)) {\n throw new ExpressionError('Invalid \\\\u escape: expected 4 hex digits', { source, start, end: i + 1 + UNICODE_ESCAPE_LEN })\n }\n }\n value += String.fromCharCode(parseInt(hex, 16))\n i += UNICODE_ESCAPE_LEN\n }\n break\n }\n default: value += escaped; break\n }\n } else {\n value += source[i]\n }\n i++\n }\n if (i >= source.length) {\n throw new ExpressionError('Unterminated string', { source, start, end: i })\n }\n i++ // skip closing quote\n tokens.push({ type: 'String', value, start, end: i })\n continue\n }\n\n // Template literals\n if (ch === '`') {\n const start = i\n i++ // skip opening backtick\n let raw = '`'\n while (i < source.length && source[i] !== '`') {\n if (source[i] === '$' && i + 1 < source.length && source[i + 1] === '{') {\n raw += '${'\n i += 2\n let depth = 1\n while (i < source.length && depth > 0) {\n const ic = source[i]\n // Skip string literals inside interpolations\n if (ic === '\"' || ic === \"'\") {\n raw += ic\n i++\n while (i < source.length && source[i] !== ic) {\n if (source[i] === '\\\\' && i + 1 < source.length) {\n raw += source[i] + source[i + 1]\n i += 2\n continue\n }\n raw += source[i]\n i++\n }\n if (i < source.length) {\n raw += source[i] // closing quote\n i++\n }\n continue\n }\n // Skip nested template literals so their raw braces (and the braces\n // of their own interpolations) do not throw off this brace count.\n // The nested template is preserved verbatim and re-parsed later.\n if (ic === '`') {\n raw += ic\n i++\n while (i < source.length && source[i] !== '`') {\n if (source[i] === '\\\\' && i + 1 < source.length) {\n raw += source[i] + source[i + 1]\n i += 2\n continue\n }\n raw += source[i]\n i++\n }\n if (i < source.length) {\n raw += source[i] // closing backtick\n i++\n }\n continue\n }\n if (ic === '{') depth++\n else if (ic === '}') depth--\n if (depth > 0) raw += ic\n i++\n }\n raw += '}'\n } else {\n raw += source[i]\n i++\n }\n }\n if (i >= source.length) {\n throw new ExpressionError('Unterminated template literal', { source, start, end: i })\n }\n raw += '`'\n i++ // skip closing backtick\n tokens.push({ type: 'TemplateLiteral', value: raw, start, end: i })\n continue\n }\n\n // Identifiers and keywords\n if (isAlpha(ch)) {\n const start = i\n while (i < source.length && isAlphaNumeric(source[i])) i++\n const value = source.slice(start, i)\n const kw = KEYWORDS.get(value)\n if (kw) {\n tokens.push({ type: kw.type, value: kw.value, start, end: i } as Token)\n } else {\n tokens.push({ type: 'Identifier', value, start, end: i })\n }\n continue\n }\n\n // Multi-character operators and punctuation\n const start = i\n\n // Spread operator ...\n if (ch === '.' && i + 2 < source.length && source[i + 1] === '.' && source[i + 2] === '.') {\n tokens.push({ type: 'Spread', value: '...', start, end: i + 3 })\n i += 3\n continue\n }\n\n // Dot (punctuation)\n if (ch === '.') {\n tokens.push({ type: 'Punctuation', value: '.', start, end: i + 1 })\n i++\n continue\n }\n\n // Pipe |> or logical ||\n if (ch === '|') {\n if (i + 1 < source.length && source[i + 1] === '>') {\n tokens.push({ type: 'Pipe', value: '|>', start, end: i + 2 })\n i += 2\n continue\n }\n if (i + 1 < source.length && source[i + 1] === '|') {\n tokens.push({ type: 'Operator', value: '||', start, end: i + 2 })\n i += 2\n continue\n }\n }\n\n // &&\n if (ch === '&' && i + 1 < source.length && source[i + 1] === '&') {\n tokens.push({ type: 'Operator', value: '&&', start, end: i + 2 })\n i += 2\n continue\n }\n\n // == !=\n if (ch === '=' && i + 1 < source.length && source[i + 1] === '=') {\n tokens.push({ type: 'Operator', value: '==', start, end: i + 2 })\n i += 2\n continue\n }\n if (ch === '!' && i + 1 < source.length && source[i + 1] === '=') {\n tokens.push({ type: 'Operator', value: '!=', start, end: i + 2 })\n i += 2\n continue\n }\n\n // ! (logical not) - must come after != check\n if (ch === '!') {\n tokens.push({ type: 'Operator', value: '!', start, end: i + 1 })\n i++\n continue\n }\n\n // <= >= < >\n if (ch === '<') {\n if (i + 1 < source.length && source[i + 1] === '=') {\n tokens.push({ type: 'Operator', value: '<=', start, end: i + 2 })\n i += 2\n continue\n }\n tokens.push({ type: 'Operator', value: '<', start, end: i + 1 })\n i++\n continue\n }\n if (ch === '>') {\n if (i + 1 < source.length && source[i + 1] === '=') {\n tokens.push({ type: 'Operator', value: '>=', start, end: i + 2 })\n i += 2\n continue\n }\n tokens.push({ type: 'Operator', value: '>', start, end: i + 1 })\n i++\n continue\n }\n\n // ** (exponentiation) — must come before single *\n if (ch === '*' && i + 1 < source.length && source[i + 1] === '*') {\n tokens.push({ type: 'Operator', value: '**', start, end: i + 2 })\n i += 2\n continue\n }\n\n // ?. (optional chaining) or ?? (nullish coalescing) or ? (ternary)\n if (ch === '?') {\n if (i + 1 < source.length && source[i + 1] === '.') {\n tokens.push({ type: 'OptionalChain', value: '?.', start, end: i + 2 })\n i += 2\n continue\n }\n if (i + 1 < source.length && source[i + 1] === '?') {\n tokens.push({ type: 'NullishCoalescing', value: '??', start, end: i + 2 })\n i += 2\n continue\n }\n tokens.push({ type: 'Punctuation', value: '?', start, end: i + 1 })\n i++\n continue\n }\n\n // Single-character operators\n if (ch === '+' || ch === '-' || ch === '*' || ch === '/' || ch === '%') {\n tokens.push({ type: 'Operator', value: ch, start, end: i + 1 })\n i++\n continue\n }\n\n // Punctuation\n if ('()[]{},:'.includes(ch)) {\n tokens.push({ type: 'Punctuation', value: ch as PunctuationValue, start, end: i + 1 })\n i++\n continue\n }\n\n throw new ExpressionError(`Unexpected character \"${ch}\"`, { source, start, end: i + 1 })\n }\n\n tokens.push({ type: 'EOF', value: '', start: i, end: i })\n return tokens\n}\n","/**\n * Single source of truth for the safe built-in method allowlist.\n *\n * Both the runtime enforcement (`isAllowedReceiver` in eval-ops.ts) and the\n * autocomplete catalog (`METHODS_BY_TYPE` in autocomplete/catalog.ts) derive\n * from this table, so a method can never be suggested but rejected (or vice\n * versa). Keep this list intentionally small and audited: every entry is a\n * non-mutating, callback-or-primitive method that is safe to call on untrusted\n * data. `tests/autocomplete/catalog-sync.test.ts` enforces that the two views\n * stay aligned.\n */\n\n/** Receiver types that have a method allowlist. */\nexport type MethodReceiverType = 'string' | 'array' | 'number'\n\n// `as const` keeps each entry precisely typed; the exported view below adds a\n// string index signature so methods can be looked up by an arbitrary name.\nconst SAFE_METHODS_TABLE = {\n // String-only\n startsWith: ['string'],\n endsWith: ['string'],\n substring: ['string'],\n charAt: ['string'],\n charCodeAt: ['string'],\n repeat: ['string'],\n trim: ['string'],\n trimStart: ['string'],\n trimEnd: ['string'],\n toLowerCase: ['string'],\n toUpperCase: ['string'],\n replace: ['string'],\n replaceAll: ['string'],\n padStart: ['string'],\n padEnd: ['string'],\n split: ['string'],\n // String + Array\n includes: ['string', 'array'],\n indexOf: ['string', 'array'],\n lastIndexOf: ['string', 'array'],\n slice: ['string', 'array'],\n at: ['string', 'array'],\n concat: ['string', 'array'],\n // Array-only (higher-order)\n filter: ['array'],\n map: ['array'],\n find: ['array'],\n findIndex: ['array'],\n some: ['array'],\n every: ['array'],\n flatMap: ['array'],\n // Array-only (non-callback, non-mutating)\n join: ['array'],\n flat: ['array'],\n toReversed: ['array'],\n toSorted: ['array'],\n toSpliced: ['array'],\n with: ['array'],\n // Number\n toFixed: ['number'],\n // Number + String\n toString: ['number', 'string'],\n} as const\n\n/** Method name -> the receiver types it is permitted on. */\nconst SAFE_METHODS: Readonly<Record<string, readonly MethodReceiverType[]>> = SAFE_METHODS_TABLE\n\n/** Map a runtime value to its method-receiver type, or undefined if it has none. */\nfunction receiverTypeOf(obj: unknown): MethodReceiverType | undefined {\n const t = typeof obj\n if (t === 'string') return 'string'\n if (t === 'number') return 'number'\n if (Array.isArray(obj)) return 'array'\n return undefined\n}\n\n/** Whether `method` is a safe built-in method for the runtime type of `obj`. */\nexport function isMethodAllowedOn(obj: unknown, method: string): boolean {\n const receiver = receiverTypeOf(obj)\n if (receiver === undefined) return false\n const allowed = SAFE_METHODS[method]\n return allowed !== undefined && allowed.includes(receiver)\n}\n\n/** All safe method names available on a given receiver type. */\nexport function methodsForReceiverType(type: MethodReceiverType): string[] {\n return Object.keys(SAFE_METHODS).filter(method => SAFE_METHODS[method].includes(type))\n}\n","import type { BonsaiOptions } from './types.js'\nimport { BonsaiSecurityError } from './errors.js'\n\n/**\n * Discriminates how a property name is being accessed so security checks can\n * apply different rules (e.g. root identifiers bypass allow/deny lists).\n */\nexport type AccessKind = 'identifier' | 'member' | 'method' | 'object-key'\n\nexport const BLOCKED_PROPERTIES: ReadonlySet<string> = new Set([\n '__proto__', 'constructor', 'prototype',\n])\n\nconst MAX_INDEX_DIGITS = 10\n\nfunction isCanonicalIndex(key: string): boolean {\n if (key.length === 0 || key.length > MAX_INDEX_DIGITS) return false\n const n = Number(key)\n return Number.isInteger(n) && n >= 0 && String(n) === key\n}\n\nconst TIMEOUT_CHECK_INTERVAL = 1000\nconst DEFAULT_MAX_DEPTH = 100\nconst DEFAULT_MAX_ARRAY_LENGTH = 100_000\nconst DEFAULT_MAX_STRING_LENGTH = 100_000\n\n/** Immutable per-instance security configuration derived from BonsaiOptions. */\nexport class SecurityPolicy {\n readonly maxDepth: number\n readonly maxArrayLength: number\n readonly maxStringLength: number\n readonly timeout: number\n readonly allowedProperties?: ReadonlySet<string>\n readonly deniedProperties?: ReadonlySet<string>\n\n constructor(options: BonsaiOptions = {}) {\n this.maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH\n this.maxArrayLength = options.maxArrayLength ?? DEFAULT_MAX_ARRAY_LENGTH\n this.maxStringLength = options.maxStringLength ?? DEFAULT_MAX_STRING_LENGTH\n this.timeout = options.timeout ?? 0\n this.allowedProperties = options.allowedProperties\n ? new Set(options.allowedProperties)\n : undefined\n this.deniedProperties = options.deniedProperties\n ? new Set(options.deniedProperties)\n : undefined\n }\n}\n\n/** Mutable per-evaluation state: tracks depth, step count, and deadline for a single evaluation. */\nexport class ExecutionContext {\n private stepCount = 0\n private depth = 0\n private deadline: number\n readonly policy: SecurityPolicy\n private readonly now: () => number\n\n constructor(policy: SecurityPolicy, now: () => number = Date.now) {\n this.policy = policy\n this.now = now\n this.deadline = policy.timeout ? now() + policy.timeout : 0\n }\n\n /** Reset mutable state for reuse. Avoids allocating a new instance per evaluation. */\n reset(): void {\n this.stepCount = 0\n this.depth = 0\n this.deadline = this.policy.timeout ? this.now() + this.policy.timeout : 0\n }\n\n step(): void {\n if (this.deadline) {\n this.stepCount++\n if (this.stepCount % TIMEOUT_CHECK_INTERVAL === 0) {\n this.checkTimeout()\n }\n }\n }\n\n checkTimeout(): void {\n if (this.deadline && this.now() >= this.deadline) {\n throw new BonsaiSecurityError(\n 'TIMEOUT',\n `Expression timeout: exceeded ${this.policy.timeout}ms`,\n )\n }\n }\n\n enterDepth(): void {\n if (++this.depth > this.policy.maxDepth) {\n throw new BonsaiSecurityError(\n 'MAX_DEPTH',\n `Maximum expression depth (${this.policy.maxDepth}) exceeded`,\n )\n }\n }\n\n exitDepth(): void {\n this.depth--\n }\n\n withDepth<T>(fn: () => T): T {\n this.enterDepth()\n try {\n return fn()\n } finally {\n this.exitDepth()\n }\n }\n\n checkNameAccess(key: string, kind: AccessKind): void {\n if (BLOCKED_PROPERTIES.has(key)) {\n throw new BonsaiSecurityError(\n 'BLOCKED_PROPERTY',\n `Blocked: access to \"${key}\" is not allowed`,\n )\n }\n\n if (kind === 'identifier' || kind === 'object-key') return\n\n if (isCanonicalIndex(key)) return\n\n if (this.policy.allowedProperties) {\n if (!this.policy.allowedProperties.has(key)) {\n throw new BonsaiSecurityError(\n 'PROPERTY_NOT_ALLOWED',\n `Blocked: \"${key}\" is not in allowed properties`,\n )\n }\n }\n\n if (this.policy.deniedProperties) {\n if (this.policy.deniedProperties.has(key)) {\n throw new BonsaiSecurityError(\n 'PROPERTY_DENIED',\n `Blocked: \"${key}\" is in denied properties`,\n )\n }\n }\n }\n\n checkArrayLength(length: number): void {\n if (length > this.policy.maxArrayLength) {\n throw new BonsaiSecurityError(\n 'MAX_ARRAY_LENGTH',\n `Array length (${length}) exceeds maximum (${this.policy.maxArrayLength})`,\n )\n }\n }\n\n checkStringLength(length: number): void {\n if (length > this.policy.maxStringLength) {\n throw new BonsaiSecurityError(\n 'MAX_STRING_LENGTH',\n `String length (${length}) exceeds maximum (${this.policy.maxStringLength})`,\n )\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as BonsaiPlugin, c as ExpressionReferences, d as PolicySnapshot, f as ResolveResult, g as ValidationResult, h as TransformFn, i as BonsaiOptions, l as FunctionFn, m as TokenType, n as BonsaiContext, o as CompiledExpression, p as Token, r as BonsaiInstance, s as ContextFunctionFn, t as ASTNode, u as InferredTypeName } from "./types-
|
|
1
|
+
import { a as BonsaiPlugin, c as ExpressionReferences, d as PolicySnapshot, f as ResolveResult, g as ValidationResult, h as TransformFn, i as BonsaiOptions, l as FunctionFn, m as TokenType, n as BonsaiContext, o as CompiledExpression, p as Token, r as BonsaiInstance, s as ContextFunctionFn, t as ASTNode, u as InferredTypeName } from "./types-DkXfy5IJ.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/errors.d.ts
|
|
4
4
|
interface ErrorLocation {
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/errors.ts","../src/lexer.ts","../src/parser.ts","../src/compiler.ts","../src/index.ts"],"mappings":";;;UAIiB,aAAA;EACf,MAAA;EACA,KAAA;EACA,GAAA;AAAA;;cAIW,eAAA,SAAwB,
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/errors.ts","../src/lexer.ts","../src/parser.ts","../src/compiler.ts","../src/index.ts"],"mappings":";;;UAIiB,aAAA;EACf,MAAA;EACA,KAAA;EACA,GAAA;AAAA;;cAIW,eAAA,SAAwB,KAAK;EAAA,SAC/B,UAAA;EAAA,SACA,KAAA;EAAA,SACA,GAAA;EAAA,SACA,MAAA;EAAA,SACA,UAAA;cAGP,OAAA,UACA,QAAA,EAAU,aAAA,EACV,UAAA;AAAA;;cAcS,eAAA,SAAwB,KAAK;EAAA,SAC/B,SAAA;EAAA,SACA,QAAA;EAAA,SACA,QAAA;EACT,QAAA,GAAW,aAAA;EACX,SAAA;cAEY,SAAA,UAAmB,QAAA,UAAkB,KAAA;AAAA;;cAetC,mBAAA,SAA4B,KAAK;EAAA,SACnC,IAAA;EACT,QAAA,GAAW,aAAA;EACX,SAAA;cAEY,IAAA,UAAc,OAAA;AAAA;;cAQf,oBAAA,SAA6B,KAAK;EAAA,SACpC,UAAA;EAAA,SACA,IAAA;EAAA,SACA,UAAA;EACT,QAAA,GAAW,aAAA;EACX,SAAA;cAEY,IAAA,uCAA2C,UAAA,UAAoB,UAAA;AAAA;;iBAmE7D,WAAA,CACd,OAAA,UACA,QAAA,EAAU,aAAa,EACvB,UAAA;AA1FF;AAAA,iBAuHgB,iBAAA,CAAkB,KAAc;;;iBCzHhC,QAAA,CAAS,MAAA,WAAiB,KAAK;;;iBCV/B,KAAA,CAAM,MAAA,UAAgB,MAAA,YAAa,OAAO;;;iBC3C1C,OAAA,CAAQ,GAAA,EAAK,OAAA,GAAU,OAAO;;;;;;;iBCmF9B,kBAAA,aAAA,CAAgC,UAAA,UAAoB,OAAA,GAAU,MAAA,oBAA0B,CAAC;AJ9EpG;AAIL;;;;;;;;;;;;;;;;AAUuB;AAcvB;;;;;AA5BK,iBI0GW,MAAA,cAAoB,aAAA,GAAgB,MAAA,kBAAA,CAClD,OAAA,GAAS,aAAA,GACR,cAAA,CAAe,IAAA"}
|