UNPKG

@rsql/emitter

Version:
113 lines (110 loc) 3.35 kB
import { isComparisonNode, isLogicNode, ReservedChars, isLogicOperator, AND, OR, AND_VERBOSE, OR_VERBOSE, } from "@rsql/ast"; var DEFAULT_EMIT_OPTIONS = { preferredQuote: '"', optimizeQuotes: true, }; var NEEDS_ESCAPING = { '"': /"|\\/g, "'": /'|\\/g, }; function escapeQuotes(value, quote) { return value.replace(NEEDS_ESCAPING[quote], "\\$&"); } function countQuote(value, quote) { var count = 0; for (var i = 0; i < value.length; ++i) { if (value[i] === quote) { count++; } } return count; } function selectQuote(value, _a) { var _b = _a.preferredQuote, preferredQuote = _b === void 0 ? DEFAULT_EMIT_OPTIONS.preferredQuote : _b, _c = _a.optimizeQuotes, optimizeQuotes = _c === void 0 ? DEFAULT_EMIT_OPTIONS.optimizeQuotes : _c; if (optimizeQuotes) { var otherQuote = preferredQuote === '"' ? "'" : '"'; return countQuote(value, otherQuote) < countQuote(value, preferredQuote) ? otherQuote : preferredQuote; } else { return preferredQuote; } } function escapeValue(value, options) { if ( value === "" || ReservedChars.some(function (reservedChar) { return value.includes(reservedChar); }) ) { var quote = selectQuote(value, options); return "" + quote + escapeQuotes(value, quote) + quote; } return value; } function emitSelector(node) { return node.selector; } function emitValue(node, options) { return Array.isArray(node.value) ? "(" + node.value .map(function (value) { return escapeValue(value, options); }) .join(",") + ")" : escapeValue(node.value, options); } function emitComparison(node, options) { return "" + emitSelector(node.left) + node.operator + emitValue(node.right, options); } function emitLogic(node, options) { var left = emitWithoutOptionsValidation(node.left, options); var right = emitWithoutOptionsValidation(node.right, options); // handle operator precedence - as it's only the case for AND operator, we don't need a generic logic for that if (isLogicOperator(node.operator, AND)) { if (isLogicNode(node.left, OR)) { left = "(" + left + ")"; } if (isLogicNode(node.right, OR)) { right = "(" + right + ")"; } } // for verbose operator add space before and after operator var operator = node.operator === AND_VERBOSE || node.operator === OR_VERBOSE ? " " + node.operator + " " : node.operator; return "" + left + operator + right; } function emitWithoutOptionsValidation(expression, options) { if (isComparisonNode(expression)) { return emitComparison(expression, options); } else if (isLogicNode(expression)) { return emitLogic(expression, options); } throw new TypeError('The "expression" has to be a valid "ExpressionNode", ' + String(expression) + " passed."); } function emit(expression, options) { if (options === void 0) { options = {}; } if (options.preferredQuote !== undefined && options.preferredQuote !== '"' && options.preferredQuote !== "'") { throw new TypeError( 'Invalid "preferredQuote" option: ' + options.preferredQuote + ". Must be either \" (the ASCII double quote character) or ' (the ASCII single quote character)." ); } return emitWithoutOptionsValidation(expression, options); } export { emit };