@digifi/jexl-functions
Version:
Package with available JEXL functions
283 lines (282 loc) • 14.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const module_1 = require("../utils/module");
const errors_1 = require("../errors");
const MAX_CRITERIA_COUNT = 30;
const MAX_TABLE_ARRAY_LENGTH = 3000;
exports.default = (0, module_1.createModule)(({ coerceToNumber, coerceNullishValueToArray, validateArrayLikeValueMaxSize, validateTextLength, validateCriteria, evalCriteriaParseResult, parseCriteriaExpression, }) => {
const TABLESUM = (table, columnName) => {
validateTableAndColumnData(table, columnName);
const coercedValue = coerceNullishValueToArray(table);
return coercedValue.reduce((sum, tableRow) => {
return sum + coerceToNumber(tableRow[columnName]);
}, 0);
};
const TABLESUMIF = (table, columnName, criteriaColumn, criteria) => {
return TABLESUMIFS(table, columnName, criteriaColumn, criteria);
};
const TABLESUMIFS = (table, columnName, ...criteriaData) => {
validateTableAndColumnData(table, columnName);
const parsedCriteriaData = getParsedMultipleCriteriaResult(criteriaData);
const coercedValue = coerceNullishValueToArray(table);
return coercedValue.reduce((sum, tableRow) => {
const evaluationResult = parsedCriteriaData.every(({ parsedCriteria, criteriaColumn }) => evalCriteriaParseResult(parsedCriteria, tableRow[criteriaColumn]));
return sum + (evaluationResult ? coerceToNumber(tableRow[columnName]) : 0);
}, 0);
};
const TABLESUMIFSOR = (table, columnName, ...criteriaData) => {
validateTableAndColumnData(table, columnName);
const parsedCriteriaData = getParsedMultipleCriteriaResult(criteriaData);
const coercedValue = coerceNullishValueToArray(table);
return coercedValue.reduce((sum, tableRow) => {
const evaluationResult = parsedCriteriaData.some(({ parsedCriteria, criteriaColumn }) => evalCriteriaParseResult(parsedCriteria, tableRow[criteriaColumn]));
return sum + (evaluationResult ? coerceToNumber(tableRow[columnName]) : 0);
}, 0);
};
const TABLECOUNT = (table, columnName) => {
validateTableAndColumnData(table, columnName);
const coercedValue = coerceNullishValueToArray(table);
return coercedValue.reduce((count, tableRow) => {
return count + (tableRow[columnName] !== undefined && tableRow[columnName] !== null ? 1 : 0);
}, 0);
};
const TABLECOUNTIF = (table, columnName, criteriaColumn, criteria) => {
return TABLECOUNTIFS(table, columnName, criteriaColumn, criteria);
};
const TABLECOUNTIFS = (table, columnName, ...criteriaData) => {
validateTableAndColumnData(table, columnName);
const parsedCriteriaData = getParsedMultipleCriteriaResult(criteriaData);
const coercedValue = coerceNullishValueToArray(table);
return coercedValue.reduce((count, tableRow) => {
const evaluationResult = parsedCriteriaData.every(({ parsedCriteria, criteriaColumn }) => evalCriteriaParseResult(parsedCriteria, tableRow[criteriaColumn]));
return count + (evaluationResult && tableRow[columnName] !== undefined && tableRow[columnName] !== null ? 1 : 0);
}, 0);
};
const TABLECOUNTIFSOR = (table, columnName, ...criteriaData) => {
validateTableAndColumnData(table, columnName);
const parsedCriteriaData = getParsedMultipleCriteriaResult(criteriaData);
const coercedValue = coerceNullishValueToArray(table);
return coercedValue.reduce((count, tableRow) => {
const evaluationResult = parsedCriteriaData.some(({ parsedCriteria, criteriaColumn }) => evalCriteriaParseResult(parsedCriteria, tableRow[criteriaColumn]));
return count + (evaluationResult && tableRow[columnName] !== undefined && tableRow[columnName] !== null ? 1 : 0);
}, 0);
};
const TABLEMAX = (table, columnName) => {
validateTableAndColumnData(table, columnName);
const coercedValue = coerceNullishValueToArray(table);
return Math.max(...extractValidNumbersFromTable(coercedValue, columnName));
};
const TABLEMAXIF = (table, columnName, criteriaColumn, criteria) => {
return TABLEMAXIFS(table, columnName, criteriaColumn, criteria);
};
const TABLEMAXIFS = (table, columnName, ...criteriaData) => {
validateTableAndColumnData(table, columnName);
const parsedCriteriaData = getParsedMultipleCriteriaResult(criteriaData);
const coercedValue = coerceNullishValueToArray(table);
return Math.max(...extractValidNumbersFromTableWithAllPassingCriteria(coercedValue, columnName, parsedCriteriaData));
};
const TABLEMAXIFSOR = (table, columnName, ...criteriaData) => {
validateTableAndColumnData(table, columnName);
const parsedCriteriaData = getParsedMultipleCriteriaResult(criteriaData);
const coercedValue = coerceNullishValueToArray(table);
return Math.max(...extractValidNumbersFromTableWithSomePassingCriteria(coercedValue, columnName, parsedCriteriaData));
};
const TABLEMIN = (table, columnName) => {
validateTableAndColumnData(table, columnName);
const coercedValue = coerceNullishValueToArray(table);
return Math.min(...extractValidNumbersFromTable(coercedValue, columnName));
};
const TABLEMINIF = (table, columnName, criteriaColumn, criteria) => {
return TABLEMINIFS(table, columnName, criteriaColumn, criteria);
};
const TABLEMINIFS = (table, columnName, ...criteriaData) => {
validateTableAndColumnData(table, columnName);
const parsedCriteriaData = getParsedMultipleCriteriaResult(criteriaData);
const coercedValue = coerceNullishValueToArray(table);
return Math.min(...extractValidNumbersFromTableWithAllPassingCriteria(coercedValue, columnName, parsedCriteriaData));
};
const TABLEMINIFSOR = (table, columnName, ...criteriaData) => {
validateTableAndColumnData(table, columnName);
const parsedCriteriaData = getParsedMultipleCriteriaResult(criteriaData);
const coercedValue = coerceNullishValueToArray(table);
return Math.min(...extractValidNumbersFromTableWithSomePassingCriteria(coercedValue, columnName, parsedCriteriaData));
};
const TABLEAVG = (table, columnName) => {
return TABLESUM(table, columnName) / TABLECOUNT(table, columnName);
};
const TABLEAVGIF = (table, columnName, criteriaColumn, criteria) => {
return TABLEAVGIFS(table, columnName, criteriaColumn, criteria);
};
const TABLEAVGIFS = (table, columnName, ...criteriaData) => {
return TABLESUMIFS(table, columnName, ...criteriaData) / TABLECOUNTIFS(table, columnName, ...criteriaData);
};
const TABLEAVGIFSOR = (table, columnName, ...criteriaData) => {
return TABLESUMIFSOR(table, columnName, ...criteriaData) / TABLECOUNTIFSOR(table, columnName, ...criteriaData);
};
const TABLEFILTERROWSIF = (table, criteriaColumn, criteria) => {
return TABLEFILTERROWSIFS(table, criteriaColumn, criteria);
};
const TABLEFILTERROWSIFS = (table, ...criteriaData) => {
validateTableData(table);
const parsedCriteriaData = getParsedMultipleCriteriaResult(criteriaData);
const coercedValue = coerceNullishValueToArray(table);
return coercedValue.filter((tableRow) => parsedCriteriaData.every(({ parsedCriteria, criteriaColumn }) => evalCriteriaParseResult(parsedCriteria, tableRow[criteriaColumn])));
};
const TABLEFILTERROWSIFSOR = (table, ...criteriaData) => {
validateTableData(table);
const parsedCriteriaData = getParsedMultipleCriteriaResult(criteriaData);
const coercedValue = coerceNullishValueToArray(table);
return coercedValue.filter((tableRow) => parsedCriteriaData.some(({ parsedCriteria, criteriaColumn }) => evalCriteriaParseResult(parsedCriteria, tableRow[criteriaColumn])));
};
const TABLEMATCHESCONDITIONS = (table, ...criteriaData) => {
validateTableData(table);
const parsedCriteriaData = getParsedMultipleCriteriaResult(criteriaData);
const coercedValue = coerceNullishValueToArray(table);
return coercedValue.every((tableRow) => parsedCriteriaData.every(({ parsedCriteria, criteriaColumn }) => evalCriteriaParseResult(parsedCriteria, tableRow[criteriaColumn])));
};
const TABLECONCATROWS = (table, rowsToAdd) => {
validateTableData(table);
validateRowsToAddData(rowsToAdd);
const coercedTableValue = coerceNullishValueToArray(table);
const coercedRowsValue = coerceNullishValueToArray(rowsToAdd);
const combinedTable = coercedTableValue.concat(coercedRowsValue);
validateArrayLikeValueMaxSize(combinedTable, MAX_TABLE_ARRAY_LENGTH);
return combinedTable;
};
/**
* @deprecated Invalid function name. Use TABLECONCATROWS instead.
*/
const TABLECONTCATROWS = (table, rowsToAdd) => {
validateTableData(table);
validateRowsToAddData(rowsToAdd);
const coercedTableValue = coerceNullishValueToArray(table);
const coercedRowsValue = coerceNullishValueToArray(rowsToAdd);
const combinedTable = coercedTableValue.concat(coercedRowsValue);
validateArrayLikeValueMaxSize(combinedTable, MAX_TABLE_ARRAY_LENGTH);
return combinedTable;
};
const getParsedMultipleCriteriaResult = (criteriaData) => {
validateMultipleCriteriaData(criteriaData);
return criteriaData.reduce((accumulator, item, index) => {
if (index % 2 !== 1) {
return accumulator;
}
validateCriteriaData(criteriaData[index - 1], item);
accumulator.push({
parsedCriteria: parseCriteriaExpression(item),
criteriaColumn: criteriaData[index - 1],
});
return accumulator;
}, []);
};
const validateTableData = (table, message = 'Table variable should be an array.') => {
if (table === null || table === undefined) {
return;
}
if (!Array.isArray(table)) {
throw new errors_1.JexlFunctionExecutionError(message);
}
validateArrayLikeValueMaxSize(table, MAX_TABLE_ARRAY_LENGTH);
};
const validateColumnData = (column) => {
if (typeof column !== 'string') {
throw new errors_1.JexlFunctionExecutionError('Column name should be a string.');
}
if (!column.length) {
throw new errors_1.JexlFunctionExecutionError('Column name cannot be empty.');
}
};
const validateTableAndColumnData = (table, column) => {
validateTableData(table);
validateColumnData(column);
};
const validateRowsToAddData = (rowsToAdd) => {
validateTableData(rowsToAdd, 'Added rows should be an array.');
const coercedRowsValue = coerceNullishValueToArray(rowsToAdd);
if (coercedRowsValue.some((row) => !(typeof row === 'object' && row !== null))) {
throw new errors_1.JexlFunctionExecutionError('Added rows should be objects.');
}
};
const validateCriteriaData = (criteriaColumn, criteria) => {
if (typeof criteriaColumn !== 'string') {
throw new errors_1.JexlFunctionExecutionError('Criteria column name should be a string.');
}
if (!criteriaColumn.length) {
throw new errors_1.JexlFunctionExecutionError('Criteria column name cannot be empty.');
}
validateTextLength(criteriaColumn);
validateCriteria(criteria);
};
const validateMultipleCriteriaData = (criteriaData) => {
if (!criteriaData.length) {
throw new errors_1.JexlFunctionExecutionError('There should be at least one logical criteria.');
}
if (criteriaData.length % 2 !== 0) {
throw new errors_1.JexlFunctionExecutionError('Each criteria should have a column name and a criteria expression.');
}
validateArrayLikeValueMaxSize(criteriaData, MAX_CRITERIA_COUNT * 2); // a criteria consists of a column name and logical expression
};
const extractValidNumbersFromTable = (table, columnName) => {
const coercedTableValue = coerceNullishValueToArray(table);
return coercedTableValue.reduce((accumulator, tableRow) => {
if (tableRow[columnName] !== undefined && tableRow[columnName] !== null) {
accumulator.push(coerceToNumber(tableRow[columnName]));
}
return accumulator;
}, []);
};
const extractValidNumbersFromTableWithAllPassingCriteria = (table, columnName, parsedCriteriaData) => {
const coercedTableValue = coerceNullishValueToArray(table);
return coercedTableValue.reduce((accumulator, tableRow) => {
if (tableRow[columnName] === undefined || tableRow[columnName] === null) {
return accumulator;
}
const evaluationResult = parsedCriteriaData.every(({ parsedCriteria, criteriaColumn }) => evalCriteriaParseResult(parsedCriteria, tableRow[criteriaColumn]));
if (evaluationResult) {
accumulator.push(coerceToNumber(tableRow[columnName]));
}
return accumulator;
}, []);
};
const extractValidNumbersFromTableWithSomePassingCriteria = (table, columnName, parsedCriteriaData) => {
const coercedTableValue = coerceNullishValueToArray(table);
return coercedTableValue.reduce((accumulator, tableRow) => {
if (tableRow[columnName] === undefined || tableRow[columnName] === null) {
return accumulator;
}
const evaluationResult = parsedCriteriaData.some(({ parsedCriteria, criteriaColumn }) => evalCriteriaParseResult(parsedCriteria, tableRow[criteriaColumn]));
if (evaluationResult) {
accumulator.push(coerceToNumber(tableRow[columnName]));
}
return accumulator;
}, []);
};
return {
TABLESUM,
TABLESUMIF,
TABLESUMIFS,
TABLESUMIFSOR,
TABLECOUNT,
TABLECOUNTIF,
TABLECOUNTIFS,
TABLECOUNTIFSOR,
TABLEMAX,
TABLEMAXIF,
TABLEMAXIFS,
TABLEMAXIFSOR,
TABLEMIN,
TABLEMINIF,
TABLEMINIFS,
TABLEMINIFSOR,
TABLEAVG,
TABLEAVGIF,
TABLEAVGIFS,
TABLEAVGIFSOR,
TABLEFILTERROWSIF,
TABLEFILTERROWSIFS,
TABLEFILTERROWSIFSOR,
TABLEMATCHESCONDITIONS,
TABLECONCATROWS,
TABLECONTCATROWS,
};
});