Skip to content

Codegen + migrate CLI

The SDK ships three CLIs:

CLIWhat it does
vb-typesPull the live admin’s collection schema → emit Schema for typed Vaultbase usage
vb-flagsPull the live admin’s flag definitions → emit a typed-keys module
vb-migrateSync collection schemas across environments (dev → staging → prod)

All three accept --url <baseUrl> + --token <admin-jwt>.

Terminal window
bunx vb-types \
--url https://admin.example.com \
--token $ADMIN_TOKEN \
--out src/vaultbase.gen.ts

Output:

// vaultbase.gen.ts (generated)
export interface Post {
id: string;
title: string;
body?: string;
author: string; // relation → User
created: number;
updated: number;
}
export interface PostCreate { title: string; body?: string; author: string }
export interface PostUpdate { title?: string; body?: string; author?: string }
export interface Schema {
posts: { record: Post; create: PostCreate; update: PostUpdate };
users: { record: User; create: UserCreate; update: UserUpdate };
// …
}

Use it:

import { Vaultbase } from "@vaultbase/sdk";
import type { Schema } from "./vaultbase.gen";
const vb = new Vaultbase<Schema>({ baseUrl: "..." });
await vb.collection("posts").create({
title: "hi", // ✓
fakeField: 1, // ✗ TS error
});
const list = await vb.collection("posts").list();
list.data[0]?.title; // ← string, inferred

Re-run the CLI after every schema change. Wire it into your build:

package.json
{
"scripts": {
"codegen:vb": "vb-types --url $VB_URL --token $VB_TOKEN --out src/vaultbase.gen.ts",
"build": "bun codegen:vb && bun build src/index.ts"
}
}
Terminal window
bunx vb-flags \
--url https://admin.example.com \
--token $ADMIN_TOKEN \
> src/flags.gen.ts

Generates a TS module that augments @vaultbase/sdk so flag reads are typed by key + variation:

import "./flags.gen";
vb.flags.isEnabled("new-checkout"); // ✓
vb.flags.getString("homepage-variant", "A"); // ↑ "A" | "B" | "C" inferred
vb.flags.isEnabled("typo"); // ✗ TS error

See Feature flags for usage.

Move schema (collections + fields + rules) between environments without hand-editing JSON.

Terminal window
# 1. Pull a snapshot from prod
bunx vb-migrate pull \
--url https://prod.example.com \
--token $PROD_TOKEN \
--out prod-snapshot.json
# 2. Diff against staging — what would change?
bunx vb-migrate diff \
--url https://staging.example.com \
--token $STAGING_TOKEN \
--in prod-snapshot.json
# → list of create/update/delete operations
# 3. Apply (additive — won't delete, won't change existing fields)
bunx vb-migrate apply \
--url https://staging.example.com \
--token $STAGING_TOKEN \
--in prod-snapshot.json \
--mode additive
# 4. Or full sync (destructive — adds/updates AND removes)
bunx vb-migrate apply --mode sync --in prod-snapshot.json --url ...

The same operations are available as functions:

import {
pullSnapshot,
diffSnapshot,
applySnapshot,
} from "@vaultbase/sdk/migrate";
const snap = await pullSnapshot({
url: "https://prod.example.com",
adminToken: process.env.PROD_TOKEN!,
});
const diff = await diffSnapshot(snap, {
url: "https://staging.example.com",
adminToken: process.env.STAGING_TOKEN!,
});
if (diff.length > 0) {
await applySnapshot(snap, {
url: "https://staging.example.com",
adminToken: process.env.STAGING_TOKEN!,
mode: "additive",
});
}

Use this in CI to fail builds when staging drifts from prod.

prod-snapshot.json:

{
"version": 1,
"createdAt": 1730000000,
"source": "https://prod.example.com",
"collections": [
{
"name": "posts",
"type": "base",
"fields": [ ],
"view_rule": "@request.auth.id != ''",
"create_rule": "",
"update_rule": "owner = @request.auth.id",
"delete_rule": "owner = @request.auth.id"
},
]
}

Versioned on disk so future SDK upgrades can read older snapshots.

.github/workflows/db-sync.yml
- name: Pull prod snapshot
run: bunx vb-migrate pull --url $PROD_URL --token $PROD_TOKEN --out snap.json
- name: Verify staging matches prod
run: |
DIFF=$(bunx vb-migrate diff --in snap.json --url $STAGING_URL --token $STAGING_TOKEN)
if [ -n "$DIFF" ]; then
echo "Staging drift detected:"
echo "$DIFF"
exit 1
fi