UNPKG

@adaptabletools/adaptable-cjs

Version:

Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

195 lines (194 loc) 9.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.aggregatedBooleanExpressionFunctionNames = exports.aggregatedBooleanExpressionFunctions = void 0; const tslib_1 = require("tslib"); const parseInt_1 = tslib_1.__importDefault(require("lodash/parseInt")); const ExpressionEvaluationError_1 = require("../../parser/src/ExpressionEvaluationError"); const expressionFunctionUtils_1 = require("./expressionFunctionUtils"); const aggregatedScalarExpressionFunctions_1 = require("./aggregatedScalarExpressionFunctions"); const TypeExtensions_1 = require("../Extensions/TypeExtensions"); const SUPPORTED_AGGREGATION_FNS = [ 'SUM', 'MIN', 'MAX', 'AVG', 'COUNT', ]; const aggregationScalarOperandMap = { SUM: ['string', 'number'], MIN: ['string', 'number'], MAX: ['string', 'number'], AVG: ['string', 'number'], COUNT: ['string', 'number'], }; // 0. optional non-capturing block of empty spaces // 1. block containing a numeric value (any digits) (required) // 2. block containing a single 'K', 'M' or 'B' letter (optional) (case insensitive) const CRITERIA_REGEX = /^(?:\s*)(\d+)(K|M|B)?$/i; exports.aggregatedBooleanExpressionFunctions = { WHERE: { handler(args, context) { return (0, expressionFunctionUtils_1.handleWhereFunction)(args, context); }, isHiddenFromMenu: true, description: 'Splits 2 composed queries, allowing for a main query(lhs) to have a where clause query(rhs) defined', signatures: ['<main_query> WHERE <boolean_query>'], examples: ['<main_query> WHERE <boolean_query>', '<main_query> WHERE QUERY("abc")'], hasEagerEvaluation: true, category: 'conditional', }, SUM: aggregatedScalarExpressionFunctions_1.aggregatedScalarExpressionFunctions['SUM'], MIN: aggregatedScalarExpressionFunctions_1.aggregatedScalarExpressionFunctions['MIN'], MAX: aggregatedScalarExpressionFunctions_1.aggregatedScalarExpressionFunctions['MAX'], AVG: aggregatedScalarExpressionFunctions_1.aggregatedScalarExpressionFunctions['AVG'], WEIGHT: aggregatedScalarExpressionFunctions_1.aggregatedScalarExpressionFunctions['WEIGHT'], COUNT: aggregatedScalarExpressionFunctions_1.aggregatedScalarExpressionFunctions['COUNT'], GROUP_BY: aggregatedScalarExpressionFunctions_1.aggregatedScalarExpressionFunctions['GROUP_BY'], EQ: { handler(args, context) { return buildBooleanAggregationParameter(args, context, '=', (aggregatedValue, conditionValue) => aggregatedValue === conditionValue); }, isHiddenFromMenu: true, description: 'Evaluates if the aggregation result equals a numerical value defined either as a number or a string abbreviation for thousands(K), millions(M) or billions(B)', signatures: [ 'SUM() = number', `SUM() = '%number%(K|M|B)'`, 'EQ(a: SUM(), b: number)', `EQ(a: SUM(), b: '%number%(K|M|B)')`, ], examples: [`SUM([col1]) = '5M'`, 'EQ( SUM([col1]), 250000)'], category: 'comparison', }, NEQ: { handler(args, context) { return buildBooleanAggregationParameter(args, context, '!=', (aggregatedValue, conditionValue) => aggregatedValue !== conditionValue); }, isHiddenFromMenu: true, description: 'Evaluates if the aggregation result is NOT equal with a numerical value defined either as a number or a string abbreviation for thousands(K), millions(M) or billions(B)', signatures: [ 'SUM() != number', `SUM() != '%number%(K|M|B)'`, 'NEQ(a: SUM(), b: number)', `NEQ(a: SUM(), b: '%number%(K|M|B)')`, ], examples: [`SUM([col1]) != '5M'`, 'NEQ( SUM([col1]), 250000)'], category: 'comparison', }, LT: { handler(args, context) { return buildBooleanAggregationParameter(args, context, '<', (aggregatedValue, conditionValue) => aggregatedValue < conditionValue); }, isHiddenFromMenu: true, description: 'Evaluates if the aggregation result is less than a numerical value defined either as a number or a string abbreviation for thousands(K), millions(M) or billions(B)', signatures: [ 'SUM() < number', `SUM() < '%number%(K|M|B)'`, 'LT(a: SUM(), b: number)', `LT(a: SUM(), b: '%number%(K|M|B)')`, ], examples: [`SUM([col1]) < '5M'`, 'LT( SUM([col1]), 250000)'], category: 'comparison', }, LTE: { handler(args, context) { return buildBooleanAggregationParameter(args, context, '<=', (aggregatedValue, conditionValue) => aggregatedValue <= conditionValue); }, isHiddenFromMenu: true, description: 'Evaluates if the aggregation result is less than or equals a numerical value defined either as a number or a string abbreviation for thousands(K), millions(M) or billions(B)', signatures: [ 'SUM() <= number', `SUM() <= '%number%(K|M|B)'`, 'LTE(a: SUM(), b: number)', `LTE(a: SUM(), b: '%number%(K|M|B)')`, ], examples: [`SUM([col1]) <= '5M'`, 'LTE( SUM([col1]), 250000)'], category: 'comparison', }, GT: { handler(args, context) { return buildBooleanAggregationParameter(args, context, '>', (aggregatedValue, conditionValue) => aggregatedValue > conditionValue); }, isHiddenFromMenu: true, description: 'Evaluates if the aggregation result is greater than a numerical value defined either as a number or a string abbreviation for thousands(K), millions(M) or billions(B)', signatures: [ 'SUM() > number', `SUM() > '%number%(K|M|B)'`, 'GT(a: SUM(), b: number)', `GT(a: SUM(), b: '%number%(K|M|B)')`, ], examples: [`SUM([col1]) > '5M'`, 'GT( SUM([col1]), 250000)'], category: 'comparison', }, GTE: { handler(args, context) { return buildBooleanAggregationParameter(args, context, '>=', (aggregatedValue, conditionValue) => aggregatedValue >= conditionValue); }, isHiddenFromMenu: true, description: 'Evaluates if the aggregation result is greater than or equals a numerical value defined either as a number or a string abbreviation for thousands(K), millions(M) or billions(B)', signatures: [ 'SUM() >= number', `SUM() >= '%number%(K|M|B)'`, 'GTE(a: SUM(), b: number)', `GTE(a: SUM(), b: '%number%(K|M|B)')`, ], examples: [`SUM([col1]) >= '5M'`, 'GTE( SUM([col1]), 250000)'], category: 'comparison', }, COL: { handler(args, context) { return (0, expressionFunctionUtils_1.handleColumnFunction)(args, context); }, description: 'References a column by its unique identifier', signatures: ['[colName]', 'COL(name: string)'], examples: ['[col1]', "COL('col1')"], category: 'special', }, }; const buildBooleanAggregationParameter = (args, context, comparisonOperator, conditionFn) => { // LHS const aggregationOperand = extractScalarAggregationOperand(comparisonOperator, args[0]); // RHS const scalarOperand = extractScalarOperand(comparisonOperator, args[1], aggregationScalarOperandMap[aggregationOperand.name]); return { type: 'aggregationBoolean', name: aggregationOperand.name, scalarAggregation: aggregationOperand, conditionValue: scalarOperand, conditionFn, }; }; const extractScalarAggregationOperand = (consumingFunctionName, argument) => { const result = argument; if (result == undefined || result.type !== 'aggregationScalar' || !SUPPORTED_AGGREGATION_FNS.includes(result.name)) { throw new ExpressionEvaluationError_1.ExpressionEvaluationError(consumingFunctionName, `comparison operator expects as a left-hand operand an aggregation function of type '${SUPPORTED_AGGREGATION_FNS.join(' | ')}'`); } return result; }; const extractScalarOperand = (consumingFunctionName, value, allowedTypes) => { if (value == undefined || !allowedTypes.find((allowedType) => typeof value === allowedType)) { throw new ExpressionEvaluationError_1.ExpressionEvaluationError(consumingFunctionName, `comparison operator expects as a right-hand operand a scalar value of type '${allowedTypes.join(' | ')}'`); } if (typeof value === 'number') { return value; } // assertion is safe, we checked in the IF above const stringValue = value; const matchingResult = stringValue.match(CRITERIA_REGEX); const numericString = matchingResult?.[1]; const largeNumberUnit = matchingResult?.[2] ?? 'number'; if (!numericString) { throw new ExpressionEvaluationError_1.ExpressionEvaluationError('Numeric abbreviation', `"${stringValue}" is invalid, expecting a number with a suffix for thousands(K), millions(M) or billions(B)"`); } // unit -> number const numberUnitRatios = { number: 1, k: 1000, m: 1000000, b: 1000000000, }; // numeric value return (0, parseInt_1.default)(numericString) * numberUnitRatios[largeNumberUnit.toLowerCase()]; }; exports.aggregatedBooleanExpressionFunctionNames = (0, TypeExtensions_1.getTypedKeys)(exports.aggregatedBooleanExpressionFunctions);