@rsql/emitter
Version:
RSQL Emitter
108 lines (103 loc) • 3.36 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var ast = require("@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 === "" ||
ast.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 (ast.isLogicOperator(node.operator, ast.AND)) {
if (ast.isLogicNode(node.left, ast.OR)) {
left = "(" + left + ")";
}
if (ast.isLogicNode(node.right, ast.OR)) {
right = "(" + right + ")";
}
}
// for verbose operator add space before and after operator
var operator =
node.operator === ast.AND_VERBOSE || node.operator === ast.OR_VERBOSE ? " " + node.operator + " " : node.operator;
return "" + left + operator + right;
}
function emitWithoutOptionsValidation(expression, options) {
if (ast.isComparisonNode(expression)) {
return emitComparison(expression, options);
} else if (ast.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);
}
exports.emit = emit;