Menu

API Reference

View as Markdown

@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

Values#

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 (columns: { readonly [Key in keyof Columns]: Columns[Key] & { readonly [kovoAnnotationColumnIdentity]: { readonly colum… 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) KovoTableExtraConfig<Columns> 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#

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 Parameters<T> extends [unknown] ? T : never The direct one-parameter helper candidate.
summary KovoAnalyzerFunctionSummary The private-scope projection the analyzer must independently verify.
(returns) T 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#

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 DrizzleUpdateResult | Promise<DrizzleUpdateResult> A promise that resolves to a Drizzle update result (or the raw result).
(returns) Promise<CasResult> A CasResult: { ok: true } on success, { ok: false, conflict: true } on stale-version conflict.

Copyable example

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#

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#

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#

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#

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#

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

Signature

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

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#

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#

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#

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

Signature

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

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#

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#

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#

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#

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#

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#

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#

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

Signature

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

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#

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

Signature

ts
interface KovoViewExtraConfigAnnotation {
  view: KovoViewAnnotation;
}

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#

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

Signature

ts
type CasResult = CasConflict | CasSuccess;

CasSuccess#

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

Signature

ts
interface CasSuccess {
  readonly ok: true;
}

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#

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#

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#

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#

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#

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';
}