QUESTPIE
Reference

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.

MethodDescription
.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:

MethodDescription
.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(["light", "dark", "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,
  update: ({ session }) => session?.user?.role === "admin",
})

.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" });

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;

On this page