@qualifyze/airtable-formulator
Version:
Airtable Formula Manipulator
84 lines • 4.17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.reduceArgumentLists = exports.isArgumentListNode = exports.isArgumentListGroup = void 0;
const utils_1 = require("./utils");
const primitives_1 = require("./primitives");
const expression_1 = require("./expression");
const function_reference_1 = require("./function-reference");
function isArgumentListMember(node) {
return (0, primitives_1.isArgumentSeparator)(node) || (0, expression_1.isExpressionNode)(node) || (0, primitives_1.isSpace)(node);
}
function isArgumentListGroup(node, type) {
return (node.type === type &&
(0, primitives_1.isEnclosedWithParenthesis)(node) &&
node.members.every(isArgumentListMember));
}
exports.isArgumentListGroup = isArgumentListGroup;
function isArgumentListNode(node) {
const { args } = node;
return (isArgumentListGroup(node, "argumentList") &&
Array.isArray(args) &&
args.every(expression_1.isExpressionNode));
}
exports.isArgumentListNode = isArgumentListNode;
function sliceDelimitedExpression(nodes, start, end) {
const [expression, invalid] = (0, primitives_1.filterMeaningfulNodes)(nodes.slice(start, end));
if (invalid) {
throw new Error((0, primitives_1.createNodeErrorMessage)(invalid, `Expected a single expression, but got an extra ${invalid.type}`));
}
if (expression && !(0, expression_1.isExpressionNode)(expression)) {
throw new Error((0, primitives_1.createNodeErrorMessage)(expression, `Expected an expression, but got ${expression.type}`));
}
return expression;
}
function getDelimitedExpressions(nodes) {
const separators = nodes.filter(primitives_1.isArgumentSeparator);
const expressions = [];
const index = separators.reduce((index, separator) => {
const separatorIndex = nodes.indexOf(separator);
const expression = sliceDelimitedExpression(nodes, index, separatorIndex);
if (expression) {
expressions.push(expression);
}
else {
throw new Error((0, primitives_1.createNodeErrorMessage)(separator, `Expected an expression before the argument separator`));
}
return separatorIndex + 1;
}, 0);
const lastExpression = sliceDelimitedExpression(nodes, index);
if (lastExpression) {
expressions.push(lastExpression);
}
return expressions;
}
function createArgumentList(group) {
if (!(0, utils_1.checkArray)(group.members, isArgumentListMember)) {
throw new Error((0, primitives_1.createNodeErrorMessage)(group, `Expected all members of an argument list to be argument list members, but got ${group.members
.map((member) => member.type)
.join(", ")} instead`));
}
return {
...(0, primitives_1.createEnclosedGroup)("argumentList", group.members, group.opener, group.closer),
args: getDelimitedExpressions(group.members),
};
}
const reduceArgumentLists = ([...nodes]) => {
const meaningfulNodes = (0, primitives_1.filterMeaningfulNodes)(nodes);
const candidates = meaningfulNodes.filter((node) => isArgumentListGroup(node, "group"));
candidates.forEach((candidate) => {
const previousNode = meaningfulNodes[meaningfulNodes.indexOf(candidate) - 1];
if ((previousNode && (0, primitives_1.isReference)(previousNode)) ||
(0, primitives_1.filterMeaningfulNodes)(candidate.members).length === 0 ||
candidate.members.some(primitives_1.isArgumentSeparator)) {
// There must be a previous node, and this node must be a reference
if (!previousNode ||
(!(0, primitives_1.isReference)(previousNode) && !(0, function_reference_1.isFunctionReference)(previousNode))) {
throw new Error((0, primitives_1.createNodeErrorMessage)(candidate, `Expected an argument list to be preceded by a reference, but got ${previousNode?.type} instead`));
}
nodes.splice(nodes.indexOf(candidate), 1, createArgumentList(candidate));
}
});
return nodes;
};
exports.reduceArgumentLists = reduceArgumentLists;
//# sourceMappingURL=argument-list.js.map