UNPKG

@digifi/jexl-functions

Version:
283 lines (282 loc) 14.7 kB
"use strict"; 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, }; });