Skip to content

RowFilterSpec

Defined in: packages/contracts/src/config.ts:427

optional columns?: string[]

Defined in: packages/contracts/src/config.ts:447

Column projection for the shape URL (e.g. [“id”, “source_text”]).


optional customWhere?: (claims, params?) => string | SQL<unknown> | null

Defined in: packages/contracts/src/config.ts:445

The row filter: returns the Electric shape where for this request, or null to bypass filtering (e.g. admin access). Prefer returning a Drizzle SQL fragment built from the table’s columns: reference each column through c (a bare, rename-safe identifier) and embed request-derived values directly — they become bound $n params, never hand-escaped literals. Enum columns must be cast to text (${c(col)}::text = 'x') for Electric’s grammar, and subqueries must be self-contained (not correlated), since Electric needs plain column refs.

Returning a raw string is the escape hatch for a predicate Drizzle can’t express. SECURITY: a string is interpolated verbatim into the where — it is NOT escaped, so any request-derived value you embed must be escaped/validated (escapeSqlLiteral) inside this function, or it is a SQL-injection vector. Reach for the string form only when the Drizzle fragment cannot express it.

Must be pure. The proxy already calls this fresh on every shape request; the client also probes it with empty claims ({}) to detect claims-dependence (ADR-0039 — isClaimsDependentRowFilter). Do not memoize, mutate external state, or assume it runs once.

{[key: string]: unknown; roles?: string[]; } = ...

string[] = ...

string = ...

Record<string, unknown>

string | SQL<unknown> | null


optional revision?: string | number

Defined in: packages/contracts/src/config.ts:455

An opaque version tag for the part of this filter the fingerprint cannot see — the customWhere body (you cannot hash a closure; only its presence is fingerprinted). Bump this (any new string/number) whenever you change that logic so the fingerprint shifts and the local read cache rebuilds + the shape subscription resets. Leaving it unchanged after a customWhere authorization change would silently serve the stale shape.