Use this file to discover all available pages before exploring further.
SchemaBuilder is the fluent configuration object returned by
createSchemaBuilder. You chain its methods to
register profiles, access-control policies, Koa-style middleware, relation
metadata, logging, and telemetry before finalising the configuration with
.build(). Most methods mutate and return this; .profiles() and .table()
return a new SchemaBuilder with updated type parameters.
Registers the set of valid profile names for this builder. Profiles represent
the roles or personas that will be passed to repository methods at runtime
(e.g. "admin", "public", "user"). Calling this method creates a new
SchemaBuilder whose TProfiles type parameter is narrowed to the provided
literal tuple, giving compile-time checks on .policies() profile keys and
repository call sites.
A const tuple of string literals that name each valid profile.
Must include "default" if you rely on the default fallback profile.
const builder = createSchemaBuilder(db, [usersTable, postsTable] as const) .profiles(["default", "public", "admin", "user"] as const);
Pass the array with as const so TypeScript infers the individual string
literals rather than string[]. Without it, policy profile keys lose their
narrowed type.
Subscribes a handler to a telemetry event emitted by the Castor runtime.
Returns this for chaining. All registered handlers fire asynchronously after
each operation completes.
policies( policy: GlobalPolicyDefinition<TSchemaContext<TDb, TTables, TMetadata>, TProfiles[number]>): this
Registers a global fallback policy that applies to every table that does
not have its own table-specific policy. The function receives the current
ExecutionContext, the name of the table being queried, and the active
profiles array.
Registers a policy scoped to a single named table. Takes precedence over the
global policy for that table. PolicyDefinition can be either a static
profile map or a single async function.
Either a profile map (an object keyed by profile names, each value being
a UnifiedPolicyConfig or an async function returning one) or a single
async function(ctx, activeProfiles) => UnifiedPolicyConfig.
You can register both a global policy and table-specific policies in the same
builder. Table-specific policies always win for their own table; the global
policy handles everything else.
use(middleware: Middleware, config?: MiddlewareConfig<TTables>): this
Registers a Koa-style middleware that intercepts every repository operation
before it reaches the RBAC layer and the database. Middleware runs in
registration order. Each function receives an ExecutionContext and a next
callback; you must call and await next() to continue the pipeline.
Limit this middleware to specific actions ("create", "read",
"update", "softDelete", "restore", "hardDelete"). If omitted,
the middleware runs for all actions.
// Runs for every table and every actionbuilder.use(async (ctx, next) => { console.log(`[${ctx.action}] → ${ctx.tableName}`); const result = await next(); console.log(`[${ctx.action}] ← ${ctx.tableName} done`); return result;});// Scoped to the "users" table, "create" and "update" actions onlybuilder.use( async (ctx, next) => { ctx.metadata.requestedAt = Date.now(); return next(); }, { tables: "users", actions: ["create", "update"] },);
Registers relation definitions and soft-delete configuration for a
table. Returns a new SchemaBuilder whose TMetadata type parameter is
extended with the supplied config, giving downstream methods full type
information about which tables have soft-delete enabled.
Configures the internal Castor logger. By default the logger is set to
"WARN". Call this method to increase verbosity during development or to
reduce it in production.
Controls what happens when the RBAC engine trims an unauthorized field from a
query clause. By default (false), trimming is silent — the field is removed
and execution continues. When set to true, any unauthorized field causes an
error to be thrown immediately instead.
false (default): Silently drop unauthorized fields and continue.
true: Throw an error when any unauthorized field is encountered during
query trimming.
// Strict field-level enforcement — throw instead of silently trimbuilder.withThrowError(true);
Enabling withThrowError(true) changes the silent-trim behaviour described
in the RBAC documentation. Callers will receive thrown errors for any field
that does not appear in their active policy’s allow-lists, so ensure all
client queries only request permitted fields before enabling this in
production.
Replaces the built-in random trace-ID generator with a custom function. The
generator is called once per repository operation and its return value is
attached to ExecutionEventPayload.traceId and MutationEventPayload.traceId.
A synchronous or asynchronous function that returns a string used as the
trace ID for each operation:
type TraceIdGenerator = () => string | Promise<string>;
import { randomUUID } from "crypto";// Use Node's built-in UUID generator as the trace ID sourcebuilder.withTraceIdGenerator(() => randomUUID());// Or propagate an incoming HTTP request's trace ID via AsyncLocalStoragebuilder.withTraceIdGenerator(() => requestContext.get("traceId") ?? randomUUID());
Finalises all registered configuration and returns a CastorInstance. Call
.build() once, after all chained configuration is complete, and export the
result for use across your application.Returns a CastorInstance with the following shape:
Factory function that creates a fully typed, middleware-and-policy-wrapped
Repository for the named table. Only tables registered via .table() are
accepted by the type system.