parseCEL does not work well as parseJsonLogic
i-am-choco opened this issue · 1 comments
React Query Builder version
v6.5.5
Platform
No response
Description
Hi, I am new to using react-querybuilder.
Due to project requirements, there arises a scenario where field
configurations need to be dynamically created.
And I found that parseCEL
does not work well as parseJsonLogic
.
Reproduction
The query would be like this
const query = {
"id": "f2cf2612-288a-4ecc-be8f-07f7d755bb7b",
"combinator": "and",
"rules": [
{
"id": "7ce77daf-4c35-4c14-890b-bbf8cb5b1986",
"field": "be321f6d-8eba-4dc4-b783-2cda07b424f4",
"operator": "contains",
"valueSource": "value",
"value": "a"
}
]
}
And I would use formatQuery to get which fomart I want.
However, I found the results between parseCEL(formatQuery(query, "cel"))
and parseJsonLogic(formatQuery(query, "jsonlogic"))
are different.
const resultCEL = parseCEL(formatQuery(query, "cel"));
// actual
// {
// "rules": [],
// "combinator": "and"
// }
// expected
//{
// "combinator": "and",
// "rules": [
// {
// "field": "be321f6d-8eba-4dc4-b783-2cda07b424f4",
// "operator": "contains",
// "value": "a"
// }
// ]
// }
const resultsJsonLogic = parseJsonLogic(formatQuery(query, "jsonlogic"));
// actual
//{
// "combinator": "and",
// "rules": [
// {
// "field": "be321f6d-8eba-4dc4-b783-2cda07b424f4",
// "operator": "contains",
// "value": "a"
// }
// ]
// }
Expected behavior
parseCEL
will work well as parseJsonLogic
Additional information
After debugging the problem, I found that replacing all '-' within the 'field' resolved the problem.
This isn't an issue with parseCEL
so much as a limitation of CEL syntax. According to the CEL grammar spec, there is no way to bracket identifiers to allow characters outside the regex [_a-zA-Z][_a-zA-Z0-9]*
.
For the SQL-based exports, we have the quoteFieldNamesWith
option which allows you to bracket field names like `fieldName` = 'value'
or [fieldName] = 'value'
. The option has no effect on the CEL export because it would produce an invalid expression, which is also why parseCEL
won't recognize it as valid syntax.
I would suggest using transformQuery
to do something like this:
// Export
formatQuery(
transformQuery(
{ combinator: 'and', rules: [{ field: 'x-y-z', operator: '=', value: 'v' }] },
{ ruleProcessor: r => ({ ...r, field: r.field.replaceAll('-', '_') }) }
),
'cel'
);
// -> `x_y_z == "v"`
// Import
transformQuery(parseCEL(`x_y_z == "v"`), {
ruleProcessor: r => ({ ...r, field: r.field.replaceAll('_', '-') }),
});
// -> {"combinator":"and","rules":[{"field":"x-y-z","operator":"=","value":"v"}]}