Skip to main content

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:

  • config is optional. Top-level fields (like expression or groupBy) are merged into config if 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)

  1. Parentheses
  2. Unary ! and unary -
  3. * and /
  4. + and -
  5. Comparisons (==, !=, >, >=, <, <=)
  6. &&
  7. ||

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 group
  • count() - number of rows in the group
  • count(expr) - number of rows where expr is truthy
  • avg(expr) - numeric average of all rows in the group
  • any(expr) - true if any row makes expr truthy
  • all(expr) - true if all rows make expr truthy

Function names are case-insensitive.


Truthiness and Coercion

  • null is false
  • Numbers: 0 is 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

  • groupBy splits 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",
},
}