UNPKG

@rsql/ast

Version:

RSQL AST definitions and functions

324 lines (319 loc) 8.78 kB
var EQ = "=="; var NEQ = "!="; var LE = "<="; var GE = ">="; var LT = "<"; var GT = ">"; var IN = "=in="; var OUT = "=out="; var LE_VERBOSE = "=le="; var GE_VERBOSE = "=ge="; var LT_VERBOSE = "=lt="; var GT_VERBOSE = "=gt="; var CanonicalComparisonOperators = [EQ, NEQ, LE, GE, LT, GT, IN, OUT]; var VerboseComparisonOperators = [LE_VERBOSE, GE_VERBOSE, LT_VERBOSE, GT_VERBOSE]; var ComparisonOperators = [EQ, NEQ, LE, GE, LT, GT, IN, OUT, LE_VERBOSE, GE_VERBOSE, LT_VERBOSE, GT_VERBOSE]; function mapToCanonicalComparisonOperator(operator) { switch (operator) { case LE_VERBOSE: return LE; case LT_VERBOSE: return LT; case GE_VERBOSE: return GE; case GT_VERBOSE: return GT; default: return operator; } } var CUSTOM_OPERATOR_REGEXP = /^=[a-z]+=$/; function isCustomComparisonOperator(candidate) { return candidate.length > 2 && CUSTOM_OPERATOR_REGEXP.test(candidate); } function isComparisonOperator(candidate, operator) { switch (candidate) { case EQ: case NEQ: case LE: case GE: case LT: case GT: case IN: case OUT: case LE_VERBOSE: case GE_VERBOSE: case LT_VERBOSE: case GT_VERBOSE: return ( operator === undefined || mapToCanonicalComparisonOperator(candidate) === mapToCanonicalComparisonOperator(operator) ); default: if (isCustomComparisonOperator(candidate)) { return operator === undefined || candidate === operator; } else { return false; } } } var AND = ";"; var OR = ","; var AND_VERBOSE = "and"; var OR_VERBOSE = "or"; var CanonicalLogicOperators = [AND, OR]; var VerboseLogicOperators = [AND_VERBOSE, OR_VERBOSE]; var LogicOperators = [AND, OR, AND_VERBOSE, OR_VERBOSE]; function mapToCanonicalLogicOperator(operator) { switch (operator) { case AND_VERBOSE: return AND; case OR_VERBOSE: return OR; default: return operator; } } function isLogicOperator(candidate, operator) { switch (candidate) { case AND: case OR: case AND_VERBOSE: case OR_VERBOSE: return operator === undefined || mapToCanonicalLogicOperator(candidate) === mapToCanonicalLogicOperator(operator); default: return false; } } var ReservedChars = ['"', "'", "(", ")", ";", ",", "=", "!", "~", "<", ">", " ", "\n", "\t", "\r"]; var NodeType = { SELECTOR: "SELECTOR", VALUE: "VALUE", COMPARISON: "COMPARISON", LOGIC: "LOGIC", }; function createNamedNode(node, toString) { Object.defineProperty(node, "toString", { value: toString, enumerable: false, configurable: false, writable: false, }); return node; } function createSelectorNode(selector, skipChecks) { if (skipChecks === void 0) { skipChecks = false; } if (!skipChecks) { if (typeof selector !== "string") { throw new TypeError('The "selector" has to be a "string", "' + String(selector) + '" passed.'); } if (!selector || selector.length === 0) { throw new Error('The "selector" cannot be an empty string.'); } var reservedChar = ReservedChars.find(function (reservedChar) { return selector.indexOf(reservedChar) !== -1; }); if (reservedChar) { var position = selector.indexOf(reservedChar) + 1; throw new Error( 'The "selector" contains reserved character \'' + reservedChar + "' at position " + position + ' in "' + selector + '".' ); } } return createNamedNode( { type: NodeType.SELECTOR, selector: selector, }, function () { return 'SelectorNode("' + selector + '")'; } ); } function createValueNode(value, skipChecks) { if (skipChecks === void 0) { skipChecks = false; } if (!skipChecks) { if (typeof value !== "string" && !Array.isArray(value)) { throw new TypeError('The "value" has to be a "string | string[]", "' + String(value) + '" passed.'); } if (Array.isArray(value) && value.length === 0) { throw new Error('The "value" cannot be an empty array.'); } } return createNamedNode( { type: NodeType.VALUE, value: value, }, function () { return "ValueNode(" + JSON.stringify(value) + ")"; } ); } function createComparisonNode(selector, operator, value, skipChecks) { if (skipChecks === void 0) { skipChecks = false; } if (!skipChecks) { if (!isSelectorNode(selector)) { throw new TypeError('The "selector" has to be a "SelectorNode", "' + String(selector) + '" passed.'); } if (typeof operator !== "string") { throw new TypeError('The "operator" has to be a "SelectorNode", "' + String(operator) + '" passed.'); } if (!isComparisonOperator(operator)) { throw new TypeError('The "operator" has to be a valid "ComparisonOperator", ' + String(operator) + " passed."); } if (!isValueNode(value)) { throw new TypeError('The "value" has to be a "ValueNode", "' + String(value) + '" passed.'); } } return createNamedNode( { type: NodeType.COMPARISON, left: selector, operator: operator, right: value, }, function () { return "ComparisonNode(" + selector + "," + operator + "," + value + ")"; } ); } function createLogicNode(left, operator, right, skipChecks) { if (skipChecks === void 0) { skipChecks = false; } if (!skipChecks) { if (!isExpressionNode(left)) { throw new TypeError('The "left" has to be a "ExpressionNode", "' + String(left) + '" passed.'); } if (typeof operator !== "string") { throw new TypeError('The "operator" has to be a "string", "' + String(operator) + '" passed.'); } if (!isLogicOperator(operator)) { throw new TypeError('The "operator" has to be a valid "LogicOperator", ' + String(operator) + " passed."); } if (!isExpressionNode(right)) { throw new TypeError('The "right" has to be a "ExpressionNode", "' + String(right) + '" passed.'); } } return createNamedNode( { type: NodeType.LOGIC, left: left, operator: operator, right: right, }, function () { return "LogicNode(" + left + "," + operator + "," + right + ")"; } ); } function isNode(candidate) { return candidate !== undefined && candidate !== null && Object.prototype.hasOwnProperty.call(candidate, "type"); } function isSelectorNode(candidate) { return isNode(candidate) && candidate.type === NodeType.SELECTOR; } function isValueNode(candidate) { return isNode(candidate) && candidate.type === NodeType.VALUE; } function isComparisonNode(candidate, operator) { return ( isNode(candidate) && candidate.type === NodeType.COMPARISON && (operator === undefined || isComparisonOperator(candidate.operator, operator)) ); } function isLogicNode(candidate, operator) { return ( isNode(candidate) && candidate.type === NodeType.LOGIC && (operator === undefined || isLogicOperator(candidate.operator, operator)) ); } function isExpressionNode(candidate) { return isComparisonNode(candidate) || isLogicNode(candidate); } function getSelector(comparison) { if (!isComparisonNode(comparison)) { throw new TypeError('The "comparison" has to be a valid "ComparisonNode", ' + String(comparison) + " passed."); } return comparison.left.selector; } function getValue(comparison) { if (!isComparisonNode(comparison)) { throw new TypeError('The "comparison" has to be a valid "ComparisonNode", ' + String(comparison) + " passed."); } return comparison.right.value; } function getSingleValue(comparison) { var value = getValue(comparison); if (Array.isArray(value)) { throw new Error( 'The "comparison" passed to the "getSingleValue" function has to contain string value, but contains an array.' ); } return value; } function getMultiValue(comparison) { var value = getValue(comparison); if (typeof value === "string") { throw new Error( 'The "comparison" passed to the "getMultiValue" function has to contain array value, but contains a single string.' ); } return value; } export { AND, AND_VERBOSE, CanonicalComparisonOperators, CanonicalLogicOperators, ComparisonOperators, EQ, GE, GE_VERBOSE, GT, GT_VERBOSE, IN, LE, LE_VERBOSE, LT, LT_VERBOSE, LogicOperators, NEQ, OR, OR_VERBOSE, OUT, ReservedChars, VerboseComparisonOperators, VerboseLogicOperators, createComparisonNode, createLogicNode, createSelectorNode, createValueNode, getMultiValue, getSelector, getSingleValue, getValue, isComparisonNode, isComparisonOperator, isExpressionNode, isLogicNode, isLogicOperator, isNode, isSelectorNode, isValueNode, };