Global API
Complete reference for global() builder methods.
global(name)
Creates a new global builder. Globals are singleton records (one row per global) used for site settings, configuration, and other single-instance data.
import { global } from "#questpie/factories";
const siteSettings = global("siteSettings")
.fields(({ f }) => ({
siteName: f.text(255).required(),
tagline: f.text(255).localized(),
logo: f.upload(),
maintenanceMode: f.boolean().default(false),
socialLinks: f.object(),
}))
.options({ timestamps: true })
.hooks({
afterChange: async ({ data, kv }) => {
await kv.delete("site-settings-cache");
},
})
.access({
read: true,
update: ({ session }) => session?.user?.role === "admin",
});Builder Methods
All methods are chainable and return a new builder instance.
| Method | Description |
|---|---|
.fields() | Define data fields using the field builder |
.options() | Configure timestamps, versioning, scoped mode |
.hooks() | Attach lifecycle hooks |
.access() | Set access control rules |
.set() | Generic extension point for plugins |
With @questpie/admin installed:
| Method | Description |
|---|---|
.admin() | Admin UI metadata (label, icon) |
.form() | Configure the form view |
.fields(callback)
Define global fields using the field builder. Works identically to collection fields.
.fields(({ f }) => ({
siteName: f.text(255).required(),
description: f.textarea().localized(),
logo: f.upload(),
theme: f.select([
{ value: "light", label: "Light" },
{ value: "dark", label: "Dark" },
{ value: "system", label: "System" },
]).default("system"),
analytics: f.object(),
})).options(config)
Configure global-level options.
.options({
timestamps: true, // Adds createdAt, updatedAt (default: true)
versioning: true, // Creates a versions table for history
scoped: true, // Scope globals by scope_id (multi-tenant)
})When scoped is enabled, the global stores one row per scope instead of a single global row.
Versioning with Workflow
Like collections, globals support versioning with optional publishing workflow:
.options({
versioning: {
enabled: true,
workflow: {
stages: ["draft", "published"],
initialStage: "draft",
},
},
}).hooks(config)
Attach lifecycle hooks. Globals support the same hook types as collections.
.hooks({
beforeChange: ({ data }) => {
if (data.siteName) {
data.siteName = data.siteName.trim();
}
},
afterChange: async ({ data, kv }) => {
// Invalidate cache when settings change
await kv.delete("site-settings-cache");
},
}).access(config)
Set access control rules. Globals support read and update operations (no create/delete since they are singletons).
.access({
read: true,
transition: ({ session }) => session?.user?.role === "editor",
update: ({ session }) => session?.user?.role === "admin",
})transition controls workflow stage transitions. If it is omitted, workflow transitions fall back to the update rule.
.set(key, value)
Generic extension point for plugins to attach metadata.
.set("admin", { icon: { type: "icon", props: { name: "ph:gear" } } })Admin Extension Methods
.admin(callback)
Set admin UI metadata for the global.
.admin(({ c }) => ({
label: { en: "Site Settings" },
icon: c.icon("ph:gear"),
})).form(callback)
Configure the admin form view.
.form(({ v, f }) => v.globalForm({
fields: [
f.siteName,
f.tagline,
{
type: "section",
label: "Appearance",
fields: [f.logo, f.theme],
},
],
}))Server API
Read and update globals through the runtime API:
// Read the global value
const settings = await globals.siteSettings.get();
console.log(settings.siteName);
// Update the global
await globals.siteSettings.update({
siteName: "New Site Name",
maintenanceMode: true,
});With localized fields, pass a locale:
const settings = await globals.siteSettings.get({ locale: "sk" });
await globals.siteSettings.update({ tagline: "Novy slogan" }, { locale: "sk" });Client API
Access globals from the client using the typed API client:
const settings = await client.globals.siteSettings.get();
await client.globals.siteSettings.update({ siteName: "Updated" });With workflow enabled, get() and update() accept stage:
const published = await client.globals.siteSettings.get({
stage: "published",
});
await client.globals.siteSettings.update(
{ announcement: "Launching soon" },
{ stage: "draft" },
);Workflow Transition API
Use transitionStage() to move a global to a target workflow stage without mutating the working row:
await globals.siteSettings.transitionStage({
stage: "published",
});The client SDK supports the same call, including scheduled transitions:
await client.globals.siteSettings.transitionStage({
stage: "published",
scheduledAt: new Date("2026-05-01T09:00:00Z"),
});Transition validation matches collections: the target stage must exist, the transition graph must allow the move, access.transition must pass or fall back to access.update, and transition hooks run around the version snapshot.
Type Inference
Globals provide type inference through $infer:
type SettingsSelect = typeof siteSettings.$infer.select;
type SettingsInsert = typeof siteSettings.$infer.insert;
type SettingsUpdate = typeof siteSettings.$infer.update;