-
Notifications
You must be signed in to change notification settings - Fork 795
Open
Labels
Description
What Would You Like to See with the Gateway?
Add new operator to be able to compare the length of an array to a number
This can either be a simple equals, or use nested queries to be able to use other operators (lt, gt, ne, etc).
Context for your Request
Location of Operator Handling
The comparison operators like $eq and $in are all handled in src/services/conditionalRouter.ts.
enum Operator {
// Comparison Operators
Equal = '$eq',
NotEqual = '$ne',
GreaterThan = '$gt',
GreaterThanOrEqual = '$gte',
LessThan = '$lt',
LessThanOrEqual = '$lte',
In = '$in',
NotIn = '$nin',
Regex = '$regex',
// Logical Operators
And = '$and',
Or = '$or',
}The actual comparison logic is in the evaluateOperator method (lines 92-135):
private evaluateOperator(operator: string, value: any): boolean {
for (const [op, compareValue] of Object.entries(operator)) {
switch (op) {
case Operator.Equal:
if (value !== compareValue) return false;
break;
case Operator.NotEqual:
if (value === compareValue) return false;
break;
case Operator.GreaterThan:
if (!(parseFloat(value) > parseFloat(compareValue))) return false;
break;
case Operator.GreaterThanOrEqual:
if (!(parseFloat(value) >= parseFloat(compareValue))) return false;
break;
case Operator.LessThan:
if (!(parseFloat(value) < parseFloat(compareValue))) return false;
break;
case Operator.LessThanOrEqual:
if (!(parseFloat(value) <= parseFloat(compareValue))) return false;
break;
case Operator.In:
if (!Array.isArray(compareValue) || !compareValue.includes(value))
return false;
break;
case Operator.NotIn:
if (!Array.isArray(compareValue) || compareValue.includes(value))
return false;
break;
case Operator.Regex:
try {
const regex = new RegExp(compareValue);
return regex.test(value);
} catch (e) {
return false;
}
default:
throw new Error(
`Unsupported operator used in the query router: ${op}`
);
}
}
return true;
}Adding a $length Operator
Yes, you can easily add a $length operator! Here's how:
1. Add the operator to the enum (line 15-30):
enum Operator {
// Comparison Operators
Equal = '$eq',
NotEqual = '$ne',
GreaterThan = '$gt',
GreaterThanOrEqual = '$gte',
LessThan = '$lt',
LessThanOrEqual = '$lte',
In = '$in',
NotIn = '$nin',
Regex = '$regex',
Length = '$length', // ← Add this
// Logical Operators
And = '$and',
Or = '$or',
}2. Add the case to the switch statement (around line 121):
case Operator.Length:
// For arrays, check length against compareValue
if (!Array.isArray(value)) return false;
if (value.length !== compareValue) return false;
break;Or if you want more flexibility with comparison operators on length:
case Operator.Length:
if (!Array.isArray(value)) return false;
// compareValue could be a number or an object like {$gt: 5}
if (typeof compareValue === 'number') {
if (value.length !== compareValue) return false;
} else if (typeof compareValue === 'object') {
// Recursively evaluate the length with other operators
if (!this.evaluateOperator(compareValue, value.length)) return false;
}
break;Example Usage
With the simple version:
{
"query": { "params.messages": { "$length": 3 } },
"then": "target-name"
}With the advanced version (nested operators):
{
"query": { "params.messages": { "$length": { "$gt": 5 } } },
"then": "target-for-long-conversations"
}The code is very clean and straightforward to extend - just add your operator to the enum and the switch statement!
Your Twitter/LinkedIn
alex-williams-5aa36761