twing
Version:
First-class Twig engine for Node.js
275 lines (274 loc) • 12.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.executeBinaryNodeSynchronously = exports.executeBinaryNode = void 0;
const compare_1 = require("../../helpers/compare");
const concatenate_1 = require("../../helpers/concatenate");
const map_like_1 = require("../../helpers/map-like");
const is_in_1 = require("../../helpers/is-in");
const parse_regular_expression_1 = require("../../helpers/parse-regular-expression");
const create_range_1 = require("../../helpers/create-range");
const runtime_1 = require("../../error/runtime");
const executeBinaryNode = async (node, executionContext) => {
const { left, right } = node.children;
const { nodeExecutor: execute, template } = executionContext;
switch (node.type) {
case "add": {
return await execute(left, executionContext) + await execute(right, executionContext);
}
case "and": {
return !!(await execute(left, executionContext) && await execute(right, executionContext));
}
case "bitwise_and": {
return await execute(left, executionContext) & await execute(right, executionContext);
}
case "bitwise_or": {
return await execute(left, executionContext) | await execute(right, executionContext);
}
case "bitwise_xor": {
return await execute(left, executionContext) ^ await execute(right, executionContext);
}
case "concatenate": {
const leftValue = await execute(left, executionContext);
const rightValue = await execute(right, executionContext);
return (0, concatenate_1.concatenate)(leftValue, rightValue);
}
case "divide": {
return await execute(left, executionContext) / await execute(right, executionContext);
}
case "divide_and_floor": {
return Math.floor(await execute(left, executionContext) / await execute(right, executionContext));
}
case "ends_with": {
const leftValue = await execute(left, executionContext);
if (typeof leftValue !== "string") {
return false;
}
const rightValue = await execute(right, executionContext);
if (typeof rightValue !== "string") {
return false;
}
return rightValue.length < 1 || leftValue.endsWith(rightValue);
}
case "has_every": {
const leftValue = await execute(left, executionContext);
const rightValue = await execute(right, executionContext);
if (typeof rightValue !== "function") {
return Promise.resolve(true);
}
if (!(0, map_like_1.isAMapLike)(leftValue) && !Array.isArray(leftValue)) {
return Promise.resolve(true);
}
return (0, map_like_1.every)(leftValue, rightValue);
}
case "has_some": {
const leftValue = await execute(left, executionContext);
const rightValue = await execute(right, executionContext);
if (typeof rightValue !== "function") {
return Promise.resolve(false);
}
if (!(0, map_like_1.isAMapLike)(leftValue) && !Array.isArray(leftValue)) {
return Promise.resolve(false);
}
return (0, map_like_1.some)(leftValue, rightValue);
}
case "is_equal_to": {
const leftValue = await execute(left, executionContext);
const rightValue = await execute(right, executionContext);
return (0, compare_1.compare)(leftValue, rightValue);
}
case "is_greater_than": {
return await execute(left, executionContext) > await execute(right, executionContext);
}
case "is_greater_than_or_equal_to": {
return await execute(left, executionContext) >= await execute(right, executionContext);
}
case "is_in": {
return (0, is_in_1.isIn)(await execute(left, executionContext), await execute(right, executionContext));
}
case "is_less_than": {
return await execute(left, executionContext) < await execute(right, executionContext);
}
case "is_less_than_or_equal_to": {
return await execute(left, executionContext) <= await execute(right, executionContext);
}
case "is_not_equal_to": {
return Promise.resolve(!(0, compare_1.compare)(await execute(left, executionContext), await execute(right, executionContext)));
}
case "is_not_in": {
return Promise.resolve(!(0, is_in_1.isIn)(await execute(left, executionContext), await execute(right, executionContext)));
}
case "matches": {
return (0, parse_regular_expression_1.parseRegularExpression)(await execute(right, executionContext)).test(await execute(left, executionContext));
}
case "modulo": {
return await execute(left, executionContext) % await execute(right, executionContext);
}
case "multiply": {
return await execute(left, executionContext) * await execute(right, executionContext);
}
case "or": {
return !!(await execute(left, executionContext) || await execute(right, executionContext));
}
case "power": {
return Math.pow(await execute(left, executionContext), await execute(right, executionContext));
}
case "range": {
const leftValue = await execute(left, executionContext);
const rightValue = await execute(right, executionContext);
return (0, create_range_1.createRange)(leftValue, rightValue, 1);
}
case "spaceship": {
const leftValue = await execute(left, executionContext);
const rightValue = await execute(right, executionContext);
return (0, compare_1.compare)(leftValue, rightValue) ? 0 : (leftValue < rightValue ? -1 : 1);
}
case "starts_with": {
const leftValue = await execute(left, executionContext);
if (typeof leftValue !== "string") {
return false;
}
const rightValue = await execute(right, executionContext);
if (typeof rightValue !== "string") {
return false;
}
return rightValue.length < 1 || leftValue.startsWith(rightValue);
}
case "subtract": {
return await execute(left, executionContext) - await execute(right, executionContext);
}
}
return Promise.reject((0, runtime_1.createRuntimeError)(`Unrecognized binary node of type "${node.type}"`, node, template.source));
};
exports.executeBinaryNode = executeBinaryNode;
const executeBinaryNodeSynchronously = (node, executionContext) => {
const { left, right } = node.children;
const { nodeExecutor: execute, template } = executionContext;
switch (node.type) {
case "add": {
return execute(left, executionContext) + execute(right, executionContext);
}
case "and": {
return !!(execute(left, executionContext) && execute(right, executionContext));
}
case "bitwise_and": {
return execute(left, executionContext) & execute(right, executionContext);
}
case "bitwise_or": {
return execute(left, executionContext) | execute(right, executionContext);
}
case "bitwise_xor": {
return execute(left, executionContext) ^ execute(right, executionContext);
}
case "concatenate": {
const leftValue = execute(left, executionContext);
const rightValue = execute(right, executionContext);
return (0, concatenate_1.concatenate)(leftValue, rightValue);
}
case "divide": {
return execute(left, executionContext) / execute(right, executionContext);
}
case "divide_and_floor": {
return Math.floor(execute(left, executionContext) / execute(right, executionContext));
}
case "ends_with": {
const leftValue = execute(left, executionContext);
if (typeof leftValue !== "string") {
return false;
}
const rightValue = execute(right, executionContext);
if (typeof rightValue !== "string") {
return false;
}
return rightValue.length < 1 || leftValue.endsWith(rightValue);
}
case "has_every": {
const leftValue = execute(left, executionContext);
const rightValue = execute(right, executionContext);
if (typeof rightValue !== "function") {
return true;
}
if (!(0, map_like_1.isAMapLike)(leftValue) && !Array.isArray(leftValue)) {
return true;
}
return (0, map_like_1.everySynchronously)(leftValue, rightValue);
}
case "has_some": {
const leftValue = execute(left, executionContext);
const rightValue = execute(right, executionContext);
if (typeof rightValue !== "function") {
return false;
}
if (!(0, map_like_1.isAMapLike)(leftValue) && !Array.isArray(leftValue)) {
return false;
}
return (0, map_like_1.someSynchronously)(leftValue, rightValue);
}
case "is_equal_to": {
const leftValue = execute(left, executionContext);
const rightValue = execute(right, executionContext);
return (0, compare_1.compare)(leftValue, rightValue);
}
case "is_greater_than": {
return execute(left, executionContext) > execute(right, executionContext);
}
case "is_greater_than_or_equal_to": {
return execute(left, executionContext) >= execute(right, executionContext);
}
case "is_in": {
return (0, is_in_1.isIn)(execute(left, executionContext), execute(right, executionContext));
}
case "is_less_than": {
return execute(left, executionContext) < execute(right, executionContext);
}
case "is_less_than_or_equal_to": {
return execute(left, executionContext) <= execute(right, executionContext);
}
case "is_not_equal_to": {
return !(0, compare_1.compare)(execute(left, executionContext), execute(right, executionContext));
}
case "is_not_in": {
return !(0, is_in_1.isIn)(execute(left, executionContext), execute(right, executionContext));
}
case "matches": {
return (0, parse_regular_expression_1.parseRegularExpression)(execute(right, executionContext)).test(execute(left, executionContext));
}
case "modulo": {
return execute(left, executionContext) % execute(right, executionContext);
}
case "multiply": {
return execute(left, executionContext) * execute(right, executionContext);
}
case "or": {
return !!(execute(left, executionContext) || execute(right, executionContext));
}
case "power": {
return Math.pow(execute(left, executionContext), execute(right, executionContext));
}
case "range": {
const leftValue = execute(left, executionContext);
const rightValue = execute(right, executionContext);
return (0, create_range_1.createRange)(leftValue, rightValue, 1);
}
case "spaceship": {
const leftValue = execute(left, executionContext);
const rightValue = execute(right, executionContext);
return (0, compare_1.compare)(leftValue, rightValue) ? 0 : (leftValue < rightValue ? -1 : 1);
}
case "starts_with": {
const leftValue = execute(left, executionContext);
if (typeof leftValue !== "string") {
return false;
}
const rightValue = execute(right, executionContext);
if (typeof rightValue !== "string") {
return false;
}
return rightValue.length < 1 || leftValue.startsWith(rightValue);
}
case "subtract": {
return execute(left, executionContext) - execute(right, executionContext);
}
}
throw (0, runtime_1.createRuntimeError)(`Unrecognized binary node of type "${node.type}"`, node, template.source);
};
exports.executeBinaryNodeSynchronously = executeBinaryNodeSynchronously;