Lint DSL Reference
The lint DSL is a deterministic expression language used by rules with type dsl (aliases: expression, rule). It evaluates against row values and optional group contexts in WASM.
Rule Shape
const rule = {
id: "end_after_start",
type: "dsl",
severity: "error",
config: {
expression: "end_date >= start_date",
groupBy: ["accountId"],
message: "End date must be on or after start date",
},
};
Notes:
configis optional. Top-level fields (likeexpressionorgroupBy) are merged intoconfigif not present there.- Identifiers are case-sensitive and must match column names.
Expression Syntax
Literals
- Numbers:
42,3.14 - Strings:
'text',"text"(supports\\escapes) - Booleans:
true,false - Null:
null
Identifiers
- Pattern:
[A-Za-z_][A-Za-z0-9_.]* - Dots are allowed and treated as part of the field name.
Operators
- Arithmetic:
+,-,*,/ - Comparison:
==,!=,>,>=,<,<= - Logical:
&&,||,! - Grouping:
()
Precedence (Highest to Lowest)
- Parentheses
- Unary
!and unary- *and/+and-- Comparisons (
==,!=,>,>=,<,<=) &&||
Functions
Functions operate on the current group. If groupBy is omitted, the group is the full dataset.
sum(expr)- numeric sum of all rows in the groupcount()- number of rows in the groupcount(expr)- number of rows whereexpris truthyavg(expr)- numeric average of all rows in the groupany(expr)- true if any row makesexprtruthyall(expr)- true if all rows makeexprtruthy
Function names are case-insensitive.
Truthiness and Coercion
nullis false- Numbers:
0is false, non-zero is true - Strings: empty is false, non-empty is true
- Booleans: as-is
- Arithmetic operators accept numbers, booleans, and numeric strings. Other values throw evaluation errors.
- Comparisons between mixed types fall back to string comparison of both values.
Grouping Behavior
groupBysplits rows by key. Missing values map to an empty string in the group key.- Aggregate functions evaluate within the group only.
Examples
Row-level rule
{
id: "active_adults",
type: "dsl",
severity: "error",
config: {
expression: "status == 'active' && age >= 18",
},
}
Group constraint rule
{
id: "one_primary",
type: "group_constraint",
severity: "warning",
config: {
groupBy: ["accountId"],
condition: "sum(isPrimary) <= 1",
},
}
Grouped DSL rule with custom message
{
id: "limit_spend",
type: "dsl",
severity: "error",
config: {
groupBy: ["accountId"],
expression: "sum(amount) <= 10000",
message: "Account exceeds spend limit",
},
}