rules-machine
rules-machine copied to clipboard
Support functions in input context
This is still failing with both of the following:
import { ruleFactory } from '@elite-libs/rules-machine';
const things = [
{
name: "ABC"
},
{
name: "DEF"
},
{
name: "123"
}
];
const thingRules = ([
{
if: 'isConditional(thing.name) == false', then: 'keep = false'
},
{
return: "keep"
}
]);
const filterWithRules = ruleFactory(thingRules)
function isFiltered(thing: Record<string, string>): boolean {
const result = filterWithRules({
thing,
isConditional: (value:string) => value.endsWith('C'),
keep: true
});
return result;
}
console.dir(things.filter(isFiltered));
import { ruleFactory } from '@elite-libs/rules-machine';
const things = [
{
name: "ABC"
},
{
name: "DEF"
},
{
name: "123"
}
];
const thingRules = ([
{
if: 'isConditional(thing.name)', then: 'keep = false'
},
{
return: "keep"
}
]);
const filterWithRules = ruleFactory(thingRules)
function isFiltered(thing: Record<string, string>): boolean {
const result = filterWithRules({
thing,
isConditional: (value:string) => value.endsWith('C'),
keep: true
});
return result;
}
console.dir(things.filter(isFiltered));
Link to Repl: https://replit.com/@dara-rockwell/DearPortlyEmulator#index.ts
Found what may be the source of the problem:
import { ruleFactory } from '@elite-libs/rules-machine';
const things = [
{
rateCode: "Z2H",
provider: "Marriott",
shouldKeep: false
},
{
rateCode: "C13",
provider: "This is a Marriott Hotel",
shouldKeep: false
},
];
const thingRules = ([
{
if: 'stringContains(LOWER(thing.provider), "marriott")',
then: "keep = false"
},
{
return: "keep"
}
]);
const filterWithRules = ruleFactory(thingRules, { trace: true })
function isFiltered(thing: Record<string, string>): boolean {
const result = filterWithRules({
thing,
stringContains: (value: string, search: string): boolean => value.includes(search),
keep: true
});
console.dir(result.trace)
return result;
}
console.dir(things.filter(isFiltered));
According to the trace, it appears that stringContains is stripped out of the evaluated string:
{
operation: 'expression',
rule: 'stringContains(LOWER(thing.provider), "marriott")',
result: [ 'this is a marriott hotel', 'marriott' ],
stepRow: 0,
stepCount: 1
},
{
operation: 'if',
rule: 'stringContains(LOWER(thing.provider), "marriott")',
result: true,
currentState: '{"thing":{"rateCode":"C13","provider":"This is a Marriott Hotel","shouldKeep":false},"keep":true}',
stepRow: 0,
stepCount: 1
},
I base this presumption on how it is evaluated if I strip the function name out manually:
{
operation: 'expression',
rule: '(LOWER(thing.provider), "marriott")',
result: [ 'this is a marriott hotel', 'marriott' ],
stepRow: 0,
stepCount: 1
},
{
operation: 'if',
rule: '(LOWER(thing.provider), "marriott")',
result: true,
currentState: '{"thing":{"rateCode":"C13","provider":"This is a Marriott Hotel","shouldKeep":false},"keep":true}',
stepRow: 0,
stepCount: 1
},
@chhatch @justsml
@chhatch @justsml Replit for the above example:
https://replit.com/@dara-rockwell/Rules-Machine-Custom-Functions#index.ts
Good spotting @dara-rockwell.
It looks like there is a function safe list thing going on. Which reminds me, I need to put a lot more thought into this - the security 🙀 issues could be many.