Validation

Turns rules on for the schema. schema() does not run them.

validation is stored as you pass it. schema() does not read the rules. okm check does, and the engine does on the first validated call. Import okmodel/validate before that call, or a write that would validate is refused. The rules themselves are on the table.

Omitted and false are off. true is on. An object is on unless enabled is false. Omitting enabled inside an object leaves it on. Insert and update run the rules. A read does not. { validate: false } skips that call. onRead is stored. The write path does not read it.

style chooses where a rule may live. "inline" is .validate() on the column. "section" is the table validate section. Omitted, either place is accepted, and the same field in both is refused.

off

Omitted, rules stay off. false is the same.

off.ts
import { schema, table, t } from "okmodel/pg";
import { v } from "okmodel/validate";

const notes = table("notes", {
  id: t.identity(),
  title: t.text().validate([v.min(1, "title_required")]),
});

export default schema({
  tables: [notes],
});

false leaves them off as well.

disabled.ts
import { schema, table, t } from "okmodel/pg";
import { v } from "okmodel/validate";

const notes = table("notes", {
  id: t.identity(),
  title: t.text().validate([v.min(1, "title_required")]),
});

export default schema({
  tables: [notes],
  validation: false, 
});

on

true turns rules on. onRead stays false. style stays unset, so a column rule and a validate section may both exist, on different fields.

on.ts
import { schema, table, t } from "okmodel/pg";
import { v } from "okmodel/validate";

const notes = table("notes", {
  id: t.identity(),
  title: t.text().validate([v.min(1, "title_required")]), 
});

export default schema({
  tables: [notes],
  validation: true, 
});

object

enabled, onRead, and style are the keys. onRead: true is stored with the flag. A read still does not run the rules.

inline

"inline" keeps column rules and refuses a validate section, including $row.

inline.ts
import { schema, table, t } from "okmodel/pg";
import { v } from "okmodel/validate";

const notes = table("notes", {
  id: t.identity(),
  title: t.text().validate([v.trim(), v.min(1, "title_required")]),
});

export default schema({
  tables: [notes],
  validation: { enabled: true, onRead: false, style: "inline" }, 
});

section

"section" keeps the table validate section and refuses .validate() on a column.

section.ts
import { schema, table, t } from "okmodel/pg";
import { v } from "okmodel/validate";

const notes = table(
  "notes",
  {
    id: t.identity(),
    title: t.text(),
  },
  { validate: { title: [v.min(1, "title_required")] } },
);

export default schema({
  tables: [notes],
  validation: { style: "section" }, 
});

OKM1060

Anything other than a boolean or an object is schema() validation must be a boolean or { enabled, onRead, style }. Another style is validation.style must be inline or section. The same on a table is table() validation must be a boolean or { enabled, onRead, style }.

OKM1030

The same field in both places is Field notes.title is validated in two places. Keep the column rules or the validate section. "inline" with a validate section, including $row, is the same code. "section" with .validate() is the same code.

table

A table flag replaces enabled and keeps the schema's onRead and style. true turns that table on. false turns it off. An object can set its own onRead and style. Omitting either one keeps the schema value.

table.ts
import { schema, table, t } from "okmodel/pg";
import { v } from "okmodel/validate";

const notes = table("notes", {
  id: t.identity(),
  title: t.text().validate([v.min(1, "title_required")]),
});

const drafts = table(
  "drafts",
  {
    id: t.identity(),
    title: t.text(),
  },
  { validation: false }, 
);

export default schema({
  tables: [notes, drafts],
  validation: { enabled: true, style: "inline" },
});

together

insert.validate checks the row and returns it frozen. A later insert of that value skips the rules. insert.check returns the issues and does not throw.

together.ts
import { connect } from "okmodel/pg/postgresjs";
import { schema, table, t } from "okmodel/pg";
import { v } from "okmodel/validate";

const notes = table("notes", {
  id: t.identity(),
  title: t.varchar(200).validate([v.trim(), v.min(1, "title_required")]),
});

const app = schema({
  tables: [notes],
  validation: true, 
});

export async function add(url: string, title: string) {
  await using db = connect(url, { schema: app });
  const row = await db.notes.insert.validate({ title }); 
  return db.notes.insert(row);
}

OKM1201

A write that would validate, when okmodel/validate was not imported, is Validation is enabled but `okmodel/validate` was not imported.

OKM1200

A failed validate is Validation failed: title title_required. The message names the first field and its key. check returns the issues instead.