---
title: "@kovojs/drizzle"
description: Concrete Drizzle table annotations, managed SQL constructors, and compare-and-set helpers.
order: 5
---

# @kovojs/drizzle

Generated from 1 public subpath — 31 exports, 31 documented. Do not edit by hand.

## `@kovojs/drizzle`

**Task:** Concrete Drizzle table annotations, managed SQL constructors, and compare-and-set helpers.

Source: [`packages/drizzle/src/runtime.ts`](https://github.com/kovojs/kovo/blob/main/packages/drizzle/src/runtime.ts)

### Values

#### `kovo` {#kovo}

Annotate a Drizzle table with the invalidation domain it belongs to, mark it
`exempt`, or declare a view/materialized-view backing domain. Used in a
relation's extra-config callback so the compiler can extract touch/read graph
facts from queries and writes — the Drizzle-blessed path to
schema-as-domain-registry (SPEC §10.1).

| Parameter | Type | Description |
| --- | --- | --- |
| `annotation` | <code>(columns: { readonly [Key in keyof Columns]: Columns[Key] &amp; { readonly [kovoAnnotationColumnIdentity]: { readonly colum…</code> | A callback receiving concrete Drizzle column identities for the table being annotated. The private identity witness makes typo and wrong-table references fail to typecheck; runtime and AST verification remain the security proof. It returns a `{ domain, key?, owner?, readOnly?, secret?, confidentialAtRest? }` binding (`owner` names the principal-owning column for the §10.3 IDOR audit and `readOnly` marks externally-owned/CMS-style content read by the app but not invalidated by Kovo mutations (SPEC §4.10), `secret` names confidential columns for the Phase 1 wire gate; `confidentialAtRest` names columns that require the authenticated-encryption write sink), `{ exempt: true }`, or `{ view: { of, refresh? } }` binding. |
| *(returns)* | <code><a href="#kovotableextraconfig">KovoTableExtraConfig</a>&lt;Columns&gt;</code> | A Drizzle extra-config callback carrying the Kovo annotation. |

**Copyable example**

```ts
import { kovo } from '@kovojs/drizzle';
import { pgTable, text } from 'drizzle-orm/pg-core';

export const carts = pgTable(
  'carts',
  { id: text('id').primaryKey() },
  kovo((columns) => ({ domain: 'cart', key: columns.id })),
);
```

**Signature**

```ts
function kovo<
  Columns extends Readonly<Record<string, AnyColumn>>,
  Parent extends Table = Table,
>(
  annotation: (columns: {
    readonly [Key in keyof Columns]: Columns[Key] & {
      readonly [kovoAnnotationColumnIdentity]: {
        readonly columns: Columns;
        readonly key: Key;
      };
    };
  }) => KovoTableAnnotation<Columns, Parent>,
): KovoTableExtraConfig<Columns>;
function kovo<Columns extends Readonly<Record<string, AnyColumn>>>(
  annotation: (columns: {
    readonly [Key in keyof Columns]: Columns[Key] & {
      readonly [kovoAnnotationColumnIdentity]: {
        readonly columns: Columns;
        readonly key: Key;
      };
    };
  }) => KovoViewExtraConfigAnnotation,
): KovoViewExtraConfig<Columns>;
```

#### `kovoAnalyzerSummary` {#kovoanalyzersummary}

Mark one direct same-file private-scope helper as a candidate for exact structural
verification. The helper argument must be the bare identifier of a function
declaration or a `const` initialized directly by an arrow or function expression.
Object properties, methods, imports, aliased marker targets, and mutable bindings
remain unknown.

The marker is not an author assertion and cannot grant a security verdict. The
analyzer independently inspects the helper body and accepts only a one-parameter,
one-return literal projection that exactly matches `kind` and `path` (SPEC §6.6).
The one-parameter TypeScript shape is an author-time guardrail, not the proof. The
runtime value is the original helper.

After the marker is proven, one direct immutable same-file
`const alias = provenHelper` may preserve its identity at an invocation. Property,
element, destructured/container, chained, imported, opaque, and mutable aliases do
not preserve provenance.

| Parameter | Type | Description |
| --- | --- | --- |
| `helper` | <code>Parameters&lt;T&gt; extends [unknown] ? T : never</code> | The direct one-parameter helper candidate. |
| `summary` | <code><a href="#kovoanalyzerfunctionsummary">KovoAnalyzerFunctionSummary</a></code> | The private-scope projection the analyzer must independently verify. |
| *(returns)* | <code>T</code> | The original helper, unchanged at runtime. |

**Copyable example**

```ts
import { kovoAnalyzerSummary } from '@kovojs/drizzle';

function requireSessionId(context: { request: { session: { id: string } } }) {
  return context.request.session.id;
}

kovoAnalyzerSummary(requireSessionId, { returns: { kind: 'session', path: 'id' } });
```

**Signature**

```ts
function kovoAnalyzerSummary<T extends (...args: never[]) => unknown>(
  helper: Parameters<T> extends [unknown] ? T : never,
  summary: KovoAnalyzerFunctionSummary,
): T;
```

#### `compareAndSet` {#compareandset}

Execute a Drizzle update whose `.where()` clause carries the version/CAS predicate,
and return a typed {@link CasResult}.

KV429 (SPEC §10.3/§11.1): pass the entire `.update(…).set(…).where(…)` expression
as the argument so the predicate is part of the atomic SQL statement. Zero rowsAffected
means the predicate did not match — the caller's version was stale → `CasConflict`.
One or more rows updated → `CasSuccess`.

| Parameter | Type | Description |
| --- | --- | --- |
| `update` | <code><a href="#drizzleupdateresult">DrizzleUpdateResult</a> &#124; Promise&lt;<a href="#drizzleupdateresult">DrizzleUpdateResult</a>&gt;</code> | A promise that resolves to a Drizzle update result (or the raw result). |
| *(returns)* | <code>Promise&lt;<a href="#casresult">CasResult</a>&gt;</code> | A `CasResult`: `{ ok: true }` on success, `{ ok: false, conflict: true }` on stale-version conflict. |

**Copyable example**

<!-- kovo-sample: illustrative reason="The compare-and-set expression depends on an app-local Drizzle schema, database handle, and mutation input." -->

```ts
// In a mutation handler with
// kovo((columns) => ({ atomic: columns.stock, version: columns.ver })):
const cas = await compareAndSet(
  db.update(products)
    .set({ stock: sql`${products.stock} - ${qty}`, ver: sql`${products.ver} + 1` })
    .where(and(eq(products.id, id), eq(products.ver, prevVer))),
);
if (!cas.ok) throw new StaleVersionError();
```

**Signature**

```ts
async function compareAndSet(
  update: DrizzleUpdateResult | Promise<DrizzleUpdateResult>,
): Promise<CasResult>;
```

#### `sql` {#sql}

Kovo-owned SQL tag. Scalar interpolations remain bound parameters through Drizzle's
serializer; Kovo stamps the resulting SQL object so managed DB guards can reject raw strings
while still accepting parameterized builders (SPEC §10.2/§10.3 SQL safety).

**Signature**

```ts
const sql = (<T = unknown>(strings: TemplateStringsArray, ...values: unknown[]) => {
  const stringSnapshot = snapshotSqlConstructorArray(strings, 'sql template strings');
  const valueSnapshot = snapshotSqlConstructorArray(values, 'sql template values');
  const args: unknown[] = [stringSnapshot];
  for (let index = 0; index < valueSnapshot.length; index += 1) {
    drizzleArrayAppend(args, valueSnapshot[index]);
  }
  const statement = invokeSqlConstructor<SQL<T>>(drizzleSql, undefined, args);
  return stampParameterizedSql(statement, mergeSqlSafetyMetadata(valueSnapshot), {
    kind: 'template',
    strings: stringSnapshot,
    values: valueSnapshot,
  });
}) as unknown as SqlTag;
```

#### `staticSql` {#staticsql}

Literal-only SQL text. Use this for static DDL or prepared statement text; interpolations are
intentionally rejected so dynamic values must flow through `sql` placeholders instead.

**Signature**

```ts
function staticSql<T = unknown>(
  strings: TemplateStringsArray,
  ...values: never[]
): KovoStaticSql<T>;
```

#### `trustedSql` {#trustedsql}

Audited raw-SQL escape hatch. This is the only Kovo brand that may execute a statement
containing `sql.raw(...)` chunks on managed DB handles.

**Signature**

```ts
function trustedSql<TResult = unknown, T extends SQL<TResult> = SQL<TResult>>(
  statement: T,
  options: { justification: string },
): T & KovoTrustedSql<TResult>;
```

### Supporting types

#### `KovoAnalyzerFunctionSummary` {#kovoanalyzerfunctionsummary}

A candidate marker for a private-scope helper. Security verdicts use only the
analyzer's exact structural proof. Object properties, methods, imports, aliased
marker targets, mutable bindings, multi-statement bodies, and mismatched projections
remain unknown regardless of this marker (SPEC §6.6).

**Signature**

```ts
type KovoAnalyzerFunctionSummary = {
  returns: { kind: KovoAnalyzerPrivateScopeKind; path: string };
};
```

#### `KovoAnalyzerPrivateScopeKind` {#kovoanalyzerprivatescopekind}

Private server-side provenance kinds used by exact local helper projections.

**Signature**

```ts
type KovoAnalyzerPrivateScopeKind = 'guard' | 'session' | 'tenant';
```

#### `KovoColumnRef` {#kovocolumnref}

One exact column from the table currently being annotated.

The private type witness is an author-time guardrail: only a property read from the `columns`
argument of the enclosing {@link kovo} callback inhabits this type. Runtime extraction still
verifies the concrete Drizzle table/column object identity and the compiler independently
resolves the same source expression (SPEC §10.1).

**Signature**

```ts
type KovoColumnRef<
  Columns extends Readonly<Record<string, AnyColumn>> = Readonly<Record<string, AnyColumn>>,
> = {
  readonly [Key in keyof Columns]: Columns[Key] & {
    readonly [kovoAnnotationColumnIdentity]: {
      readonly columns: Columns;
      readonly key: Key;
    };
  };
}[keyof Columns];
```

#### `KovoConfidentialAtRestColumnAnnotation` {#kovoconfidentialatrestcolumnannotation}

Column-level at-rest confidentiality annotation consumed by the encrypted-write gate.

**Signature**

```ts
type KovoConfidentialAtRestColumnAnnotation<
  Columns extends Readonly<Record<string, AnyColumn>> = Readonly<Record<string, AnyColumn>>,
> = true | KovoColumnRef<Columns> | readonly KovoColumnRef<Columns>[];
```

#### `KovoConcurrencyColumnAnnotation` {#kovoconcurrencycolumnannotation}

Names columns whose single-row read-modify-write MUST fold the check and the act into
one statement — a compare-and-set / version guard in the `where()` (SPEC §10.3/§11.1,
the KV429 TOCTOU gate). A self-referential `set({ col: col ± x })` on such a column
whose `where()` carries no eq-predicate on that column (nor a declared version column)
is a lost-update race. `atomic` names the contended value column; `version` names an
optimistic-concurrency counter that, when guarded in the `where()`, discharges the gate.

**Signature**

```ts
type KovoConcurrencyColumnAnnotation<
  Columns extends Readonly<Record<string, AnyColumn>> = Readonly<Record<string, AnyColumn>>,
> = KovoColumnRef<Columns> | readonly KovoColumnRef<Columns>[];
```

#### `KovoDomainRef` {#kovodomainref}

A domain annotation can use explicit external vocabulary or a source-derived Kovo domain value.

**Signature**

```ts
type KovoDomainRef = string | { key: string };
```

#### `KovoDomainTableAnnotation` {#kovodomaintableannotation}

The domain-bearing form of a table annotation: its `domain`, optional `key` column, and optional principal `owner` column (SPEC §10.1).

**Signature**

```ts
interface KovoDomainTableAnnotation<
  Columns extends Readonly<Record<string, AnyColumn>> = Readonly<Record<string, AnyColumn>>,
  Parent extends Table = Table,
> {
  atomic?: KovoConcurrencyColumnAnnotation<Columns>;
  authzPolicy?: SQL<boolean> | string;
  confidentialAtRest?: KovoConfidentialAtRestColumnAnnotation<Columns>;
  domain: KovoDomainRef;
  fans?: readonly KovoFanAnnotation<Columns>[];
  governed?: KovoGovernedColumnAnnotation<Columns>;
  key?: KovoColumnRef<Columns> | readonly [KovoColumnRef<Columns>, ...KovoColumnRef<Columns>[]];
  owner?: KovoColumnRef<Columns>;
  ownerVia?: KovoOwnerViaAnnotation<Columns, Parent>;
  public?: true;
  readOnly?: true;
  reference?: true;
  secret?: KovoSecretColumnAnnotation<Columns>;
  version?: KovoConcurrencyColumnAnnotation<Columns>;
}
```

#### `KovoFanAnnotation` {#kovofanannotation}

A fan-out invalidation edge for a table's `fans`: when a write touches this table,
also invalidate the named `domain` reached `via` the given relation, optionally scoped
to a write `when` (`insert`/`update`/`delete`). The element type of `KovoTableAnnotation.fans`
and `KovoDomainTableAnnotation.fans` (SPEC §10.1 / KV413 declared engine-side-effect edges).

**Signature**

```ts
interface KovoFanAnnotation<
  Columns extends Readonly<Record<string, AnyColumn>> = Readonly<Record<string, AnyColumn>>,
> {
  domain: string;
  via: KovoColumnRef<Columns>;
  when?: 'delete' | 'insert' | 'update';
}
```

#### `KovoGovernedColumnAnnotation` {#kovogovernedcolumnannotation}

Names columns that may only be written from a server-derived value, never from
raw request input (SPEC §11.1, the §11.1 mass-assignment gate / KV438). The
primary `key` and the principal `owner` column are AUTO-governed; this annotation
governs the rest (`role`/`balance`/`isAdmin`/…). `true` would govern every column
(rarely wanted); the usual form is a column ref or list.

**Signature**

```ts
type KovoGovernedColumnAnnotation<
  Columns extends Readonly<Record<string, AnyColumn>> = Readonly<Record<string, AnyColumn>>,
> = true | KovoColumnRef<Columns> | readonly KovoColumnRef<Columns>[];
```

#### `KovoOwnerViaAnnotation` {#kovoownerviaannotation}

Declares ownership through one concrete parent-table relation (SPEC §10.1).

**Signature**

```ts
interface KovoOwnerViaAnnotation<
  Columns extends Readonly<Record<string, AnyColumn>> = Readonly<Record<string, AnyColumn>>,
  Parent extends Table = Table,
> {
  fk: KovoColumnRef<Columns>;
  parent: Parent;
  parentKey: Parent['_']['columns'][keyof Parent['_']['columns']];
}
```

#### `KovoSecretColumnAnnotation` {#kovosecretcolumnannotation}

Column-level confidentiality annotation consumed by the secret wire gate.

**Signature**

```ts
type KovoSecretColumnAnnotation<
  Columns extends Readonly<Record<string, AnyColumn>> = Readonly<Record<string, AnyColumn>>,
> = true | KovoColumnRef<Columns> | readonly KovoColumnRef<Columns>[];
```

#### `KovoTableAnnotation` {#kovotableannotation}

A Kovo annotation on a Drizzle table: a `domain` (with optional row `key` and principal `owner`), or an `exempt` marker.

**Signature**

```ts
type KovoTableAnnotation<
  Columns extends Readonly<Record<string, AnyColumn>> = Readonly<Record<string, AnyColumn>>,
  Parent extends Table = Table,
> =
  | {
      atomic?: KovoConcurrencyColumnAnnotation<Columns>;
      authzPolicy?: SQL<boolean> | string;
      confidentialAtRest?: KovoConfidentialAtRestColumnAnnotation<Columns>;
      domain: KovoDomainRef;
      fans?: readonly KovoFanAnnotation<Columns>[];
      governed?: KovoGovernedColumnAnnotation<Columns>;
      key?: KovoColumnRef<Columns> | readonly [KovoColumnRef<Columns>, ...KovoColumnRef<Columns>[]];
      owner?: KovoColumnRef<Columns>;
      ownerVia?: KovoOwnerViaAnnotation<Columns, Parent>;
      public?: true;
      readOnly?: true;
      reference?: true;
      secret?: KovoSecretColumnAnnotation<Columns>;
      version?: KovoConcurrencyColumnAnnotation<Columns>;
    }
  | {
      exempt: true;
    };
```

#### `KovoTableExtraConfig` {#kovotableextraconfig}

The opaque Drizzle extra-config callback returned by {@link kovo}.

**Signature**

```ts
type KovoTableExtraConfig<
  Columns extends Readonly<Record<string, AnyColumn>> = Readonly<Record<string, AnyColumn>>,
> = (self: Columns) => [];
```

#### `KovoViewAnnotation` {#kovoviewannotation}

Declares the backing invalidation domain and refresh mode for a Drizzle view relation.

**Signature**

```ts
interface KovoViewAnnotation {
  of: string;
  refresh?: 'async' | 'sync';
}
```

#### `KovoViewExtraConfig` {#kovoviewextraconfig}

The opaque extra-config callback returned for a view/materialized-view annotation.

**Signature**

```ts
type KovoViewExtraConfig<
  Columns extends Readonly<Record<string, AnyColumn>> = Readonly<Record<string, AnyColumn>>,
> = (self: Columns) => [];
```

#### `KovoViewExtraConfigAnnotation` {#kovoviewextraconfigannotation}

A Kovo annotation for a Drizzle view or materialized view declaration.

**Signature**

```ts
interface KovoViewExtraConfigAnnotation {
  view: KovoViewAnnotation;
}
```

#### `CasConflict` {#casconflict}

A CAS operation detected a stale-version conflict — 0 rows matched the predicate,
meaning the row was concurrently modified since the version was read (lost-update race,
SPEC §10.3/§11.1, KV429).

**Signature**

```ts
interface CasConflict {
  readonly conflict: true;
  readonly ok: false;
}
```

#### `CasResult` {#casresult}

The typed result of a {@link compareAndSet} call (SPEC §10.3/§11.1, KV429).

**Signature**

```ts
type CasResult = CasConflict | CasSuccess;
```

#### `CasSuccess` {#cassuccess}

A CAS operation succeeded — ≥1 row matched the version predicate and was updated.

**Signature**

```ts
interface CasSuccess {
  readonly ok: true;
}
```

#### `DrizzleUpdateResult` {#drizzleupdateresult}

A Drizzle result object that carries row-affected count in one of the standard shapes
returned by Drizzle adapters (pg: `rowCount`, sqlite: `changes`, or a generic
`rowsAffected`).

**Signature**

```ts
interface DrizzleUpdateResult {
  affectedRows?: number | null;
  changes?: number | null;
  rowCount?: number | null;
  rowsAffected?: number | null;
}
```

#### `KovoParameterizedSql` {#kovoparameterizedsql}

Kovo-branded parameterized SQL value accepted by framework-managed DB handles.

Produced by {@link sql}; scalar interpolations are bound parameters rather than SQL text.

**Signature**

```ts
interface KovoParameterizedSql<T = unknown> extends SQL<T> {
  readonly [kovoSqlIdentity]: 'parameterized';
}
```

#### `KovoStaticSql` {#kovostaticsql}

Kovo-branded literal SQL text accepted by framework-managed DB handles.

Produced by {@link staticSql}, {@link sql.identifier}, and {@link sql.allow}.

**Signature**

```ts
interface KovoStaticSql<T = unknown> extends SQL<T> {
  readonly [kovoSqlIdentity]: 'static';
}
```

#### `KovoTrustedSql` {#kovotrustedsql}

Kovo-branded audited raw SQL accepted by framework-managed DB handles.

Produced only by {@link trustedSql}; use it for reviewed raw-SQL escape hatches with a
source-visible justification.

**Signature**

```ts
interface KovoTrustedSql<T = unknown> extends SQL<T> {
  readonly [kovoSqlIdentity]: 'trusted';
}
```

#### `KovoSqlIdentifier` {#kovosqlidentifier}

Kovo-branded SQL identifier fragment accepted by framework-managed DB handles.

Produced by {@link sql.identifier}; dynamic values are grammar-checked and may be constrained
by an allowlist before the witness is minted.

**Signature**

```ts
interface KovoSqlIdentifier<T = unknown> extends KovoStaticSql<T> {
  readonly [kovoSqlFragmentIdentity]: 'identifier';
}
```

#### `KovoSqlKeyword` {#kovosqlkeyword}

Kovo-branded SQL keyword/clause fragment accepted by framework-managed DB handles.

Produced by {@link sql.allow}; the value must match the supplied static allowlist.

**Signature**

```ts
interface KovoSqlKeyword<T = unknown> extends KovoStaticSql<T> {
  readonly [kovoSqlFragmentIdentity]: 'keyword';
}
```

