@qualifyze/airtable-formulator
Version:
Airtable Formula Manipulator
65 lines • 3.04 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.reduceModifiers = exports.isModifierNode = void 0;
const primitives_1 = require("./primitives");
const expression_1 = require("./expression");
function isModifierNodeMember(node) {
return (0, primitives_1.isSpace)(node) || (0, primitives_1.isUnaryOperator)(node) || (0, expression_1.isExpressionNode)(node);
}
function isModifierNode(node) {
const { operator, operand } = node;
return ((0, primitives_1.isGroupNode)(node) &&
node.members.every(isModifierNodeMember) &&
node.type === "modifier" &&
(0, primitives_1.isNode)(operator) &&
(0, primitives_1.isUnaryOperator)(operator) &&
(0, primitives_1.isNode)(operand) &&
(0, expression_1.isExpressionNode)(operand));
}
exports.isModifierNode = isModifierNode;
function createModifier(nodes) {
const modifier = (0, primitives_1.createGroup)("modifier", nodes);
const [operator, operand, invalid] = (0, primitives_1.filterMeaningfulNodes)(nodes);
if (!operator || !(0, primitives_1.isOperator)(operator)) {
throw new Error((0, primitives_1.createNodeErrorMessage)(modifier, `Modifier must have an operator, but encountered ${operator.type} instead`));
}
if (!operand || !(0, expression_1.isExpressionNode)(operand)) {
throw new Error((0, primitives_1.createNodeErrorMessage)(modifier, `Modifier must have an operand expression, but encountered ${operand.type} instead`));
}
if (invalid) {
throw new Error((0, primitives_1.createNodeErrorMessage)(modifier, `Modifier must have exactly 2 members, but encountered an extra ${invalid.type} instead`));
}
return {
...modifier,
operator,
operand,
};
}
const reduceModifiers = ([...nodes]) => {
const meaningfulNodes = (0, primitives_1.filterMeaningfulNodes)(nodes);
const operators = meaningfulNodes.filter(primitives_1.isUnaryOperator);
const nodeGroups = operators
.map((operator) => {
const operatorIndex = meaningfulNodes.indexOf(operator);
const before = meaningfulNodes[operatorIndex - 1];
const after = meaningfulNodes[operatorIndex + 1];
return { before, operator, after };
})
.filter(({ before, after }) => {
return ((!before || (0, primitives_1.isOperator)(before)) && after && (0, expression_1.isExpressionNode)(after));
})
.map(({ operator, after: operand }) => {
const operatorIndex = nodes.indexOf(operator);
const expressionIndex = nodes.indexOf(operand);
return nodes.slice(operatorIndex, expressionIndex + 1);
})
.filter((nodes) => nodes.every(isModifierNodeMember));
nodeGroups.forEach((members) => {
const modifier = createModifier(members);
const index = nodes.indexOf(modifier.operator);
nodes.splice(index, members.length, modifier);
});
return nodes;
};
exports.reduceModifiers = reduceModifiers;
//# sourceMappingURL=modifier.js.map