/**
* A small evaluator for GitHub-Actions-style `${{ }}` expressions: literals, context paths,
* comparison/logical operators and the common built-in functions.
*/
export type ExprValue = string | number | boolean | null | ExprValue[] | { [key: string]: ExprValue };
export type ExprContext = {
contexts: Record<string, ExprValue>;
jobStatus: "success" | "failure";
};
type Token =
| { type: "number"; value: number }
| { type: "string"; value: string }
| { type: "ident"; value: string }
| { type: "op"; value: string }
| { type: "punct"; value: string };
const OPERATORS = ["==", "!=", "<=", ">=", "&&", "||", "<", ">", "!"];
const PUNCTUATION = ["(", ")", "[", "]", ",", "."];
const IDENT_START = /[A-Za-z_]/;
const IDENT_PART = /[A-Za-z0-9_-]/;
const DIGIT = /[0-9]/;
const MAX_EXPRESSION_DEPTH = 64;
const MAX_EXPRESSION_LENGTH = 8 * 1024;
function tokenize(source: string): Token[] {
const tokens: Token[] = [];
let index = 0;
while (index < source.length) {
const char = source[index];
if (/\s/.test(char)) {
index++;
continue;
}
if (char === "'") {
let value = "";
index++;
while (index < source.length) {