Records
vb.collection("name") returns a typed accessor over a single
collection. Every method maps 1-1 to a server endpoint and returns the
same shape the REST API does.
Quick reference
Section titled “Quick reference”const posts = vb.collection<Post>("posts");
await posts.list({ filter: "published = true", sort: "-created", perPage: 50 });await posts.get("p1");await posts.create({ title: "hi", body: "<p>…</p>" });await posts.update("p1", { title: "renamed" });await posts.delete("p1");
for await (const r of posts.iterate({ filter: "published = true" })) { /* … */ }await vb.collection("posts").list({ page: 1, perPage: 30, filter: 'status = "live" && @request.auth.id = author', sort: "-created,title", expand: "author,tags", fields: "id,title,author.name", skipTotal: true, // skip COUNT(*) for huge tables});Returns:
{ data: T[]; page: number; perPage: number; totalItems: number; // -1 when skipTotal totalPages: number; // -1 when skipTotal}iterate — automatic pagination
Section titled “iterate — automatic pagination”for await (const post of vb.collection<Post>("posts").iterate({ filter: 'tags ?= "tutorial"', perPage: 100,})) { console.log(post.title);}Backed by repeated list calls until the server stops returning a
full page.
const post = await vb.collection<Post>("posts").get("p1");Returns 404 → throws VaultbaseError with kind: "not_found".
create
Section titled “create”const post = await vb.collection<Post>("posts").create({ title: "Hello", body: "<p>World</p>", author: "u_42",});// post.id is the freshly generated UUID; created/updated set by the server.Validation failures throw VaultbaseError with kind: "validation" and
a details: { fieldName: message } map. Match codes pre-1.0:
400→ bad request403→ rule denied404→ collection / parent record missing409→ unique violation, optimistic-concurrency mismatch422→ schema validation
update
Section titled “update”const updated = await vb.collection<Post>("posts").update("p1", { title: "Renamed",});PATCH semantics — only the fields you send are touched.
ETag/If-Match concurrency runs automatically (see Errors + ETags):
the SDK caches the ETag from prior reads and attaches If-Match on the
next mutation. Override with:
// Skip the precondition entirely:await posts.update("p1", { title: "x" }, { ifMatch: false });
// Use an explicit tag:await posts.update("p1", { title: "x" }, { ifMatch: "W/\"42\"" });If the server’s ETag has moved, the SDK throws VaultbaseError with
kind: "precondition_failed" and the current etag attached so you can
retry against the latest state.
delete
Section titled “delete”await vb.collection("posts").delete("p1");Same ifMatch semantics as update. Returns null on success.
Filter language
Section titled “Filter language”Filters live in the same expression language as collection rules. See
API rules for the full grammar. For ergonomic,
injection-safe construction use the vb.q tag:
const term = req.query.q;const filter = vb.q`title ~ ${term} && status = ${"live"} && deleted = ${false}`;// → 'title ~ "hello" && status = "live" && deleted = false'
await vb.collection("posts").list({ filter });| Interpolation | Encoded as |
|---|---|
string | "…" (escaped) |
number | bare; rejects NaN/Infinity |
boolean | true/false |
null | null |
Date | quoted ISO string |
Array | (…) comma-joined — pairs with ?= / ?~ |
field("name") | bare identifier (validated) |
vb.q ALWAYS quotes strings — to interpolate a column name use the
field() escape:
const sortable = vb.field("title");const filter = vb.q`${sortable} ~ ${"hello"}`;// → 'title ~ "hello"'Request-scoped options
Section titled “Request-scoped options”const ac = new AbortController();posts.list({ signal: ac.signal });ac.abort(); // → throws kind: "aborted"
posts.list({ requestKey: "search-suggest" });posts.list({ requestKey: "search-suggest" });// → first request is auto-cancelled when the second starts (defaultAutoCancel)Disable auto-cancel via requestKey: null per-call or
defaultAutoCancel: false at construction.
With codegen
Section titled “With codegen”When you generate the Schema type via vb-types, every collection
accessor becomes typed:
const vb = new Vaultbase<Schema>({ baseUrl: "..." });
await vb.collection("posts").create({ title: "hi", // ✓ body: "<p>…</p>", // ✓ fakeField: 1, // ✗ TS error});
const list = await vb.collection("posts").list({ filter: "published = true" });list.data[0].title; // string — inferred