definePermissions
Call Signature
Section titled “Call Signature”definePermissions<
TRoles>(config):Permissions<TRoles>
Defined in: packages/permissions/src/define-permissions.ts:206
Creates a permission configuration that can be shared between server-side
enforcement (@cfast/db) and client-side introspection (@cfast/actions).
Supports four calling styles:
-
Direct:
definePermissions(config)— when no custom user type and no schema map is needed. -
Curried (user only):
definePermissions<MyUser>()(config)— types theuserparameter insidewhereclauses. String subjects are still accepted but are not compile-time or runtime validated against a schema; they are stored as opaque strings and matched bygetTableName. -
Curried (user + schema types only, no runtime schema):
definePermissions<MyUser, typeof schema>()(config)— constrains string subjects to"jsKey" | "sql_name"at compile time, but at runtime still stores strings opaquely. Prefer style (4) when you can. -
Curried with runtime schema (RECOMMENDED):
definePermissions<MyUser, typeof schema>({ schema })(config)— walks the schema at startup and resolves every string-form subject to the exact Drizzle table reference the schema uses. This is the only form that lets string-form grants work with Drizzle relationalwithqueries, because Drizzle identifies tables by reference, not name (see issues #146, #175, #177).- Unknown strings throw PermissionRegistrationError at startup (fast, loud failure instead of silently matching nothing).
- Both the JS key (
"documentVersions") and the SQL table name ("document_versions") resolve to the same table reference. - Object-form subjects still work unchanged.
Type Parameters
Section titled “Type Parameters”TRoles
Section titled “TRoles”TRoles extends readonly string[]
Parameters
Section titled “Parameters”config
Section titled “config”PermissionsConfig<TRoles>
Returns
Section titled “Returns”Permissions<TRoles>
A Permissions object, or a function that takes a config and returns one.
Example
Section titled “Example”import { definePermissions, grant } from "@cfast/permissions";import { eq } from "drizzle-orm";import * as schema from "./schema";const { posts, comments } = schema;
// Style 1 — direct, accepts table objectsconst permissions = definePermissions({ roles: ["anonymous", "user", "admin"] as const, grants: { anonymous: [ grant("read", posts, { where: (p) => eq(p.published, true) }), ], user: [grant("read", posts), grant("create", posts)], admin: [grant("manage", "all")], },});
// Style 4 — recommended: runtime-resolved string subjectstype AuthUser = { id: string };const perms = definePermissions<AuthUser, typeof schema>({ schema })({ roles: ["user", "admin"] as const, grants: (grant) => ({ user: [ grant("read", "posts"), // JS key — resolves grant("create", "post_versions"), // SQL name — also resolves grant("update", posts, { // object form still works where: (p, u) => eq(p.authorId, u.id), }), // grant("read", "unknownTable"), // throws at startup ], admin: [grant("manage", "all")], }),});Call Signature
Section titled “Call Signature”definePermissions<
TUser,TTables>(options): <TRoles>(config) =>Permissions<TRoles>
Defined in: packages/permissions/src/define-permissions.ts:210
Creates a permission configuration that can be shared between server-side
enforcement (@cfast/db) and client-side introspection (@cfast/actions).
Supports four calling styles:
-
Direct:
definePermissions(config)— when no custom user type and no schema map is needed. -
Curried (user only):
definePermissions<MyUser>()(config)— types theuserparameter insidewhereclauses. String subjects are still accepted but are not compile-time or runtime validated against a schema; they are stored as opaque strings and matched bygetTableName. -
Curried (user + schema types only, no runtime schema):
definePermissions<MyUser, typeof schema>()(config)— constrains string subjects to"jsKey" | "sql_name"at compile time, but at runtime still stores strings opaquely. Prefer style (4) when you can. -
Curried with runtime schema (RECOMMENDED):
definePermissions<MyUser, typeof schema>({ schema })(config)— walks the schema at startup and resolves every string-form subject to the exact Drizzle table reference the schema uses. This is the only form that lets string-form grants work with Drizzle relationalwithqueries, because Drizzle identifies tables by reference, not name (see issues #146, #175, #177).- Unknown strings throw PermissionRegistrationError at startup (fast, loud failure instead of silently matching nothing).
- Both the JS key (
"documentVersions") and the SQL table name ("document_versions") resolve to the same table reference. - Object-form subjects still work unchanged.
Type Parameters
Section titled “Type Parameters”TUser
TTables
Section titled “TTables”TTables extends SchemaMap
Parameters
Section titled “Parameters”options
Section titled “options”schema
Section titled “schema”TTables
Returns
Section titled “Returns”A Permissions object, or a function that takes a config and returns one.
<
TRoles>(config):Permissions<TRoles>
Type Parameters
Section titled “Type Parameters”TRoles
Section titled “TRoles”TRoles extends readonly string[]
Parameters
Section titled “Parameters”config
Section titled “config”PermissionsConfig<TRoles, TUser, TTables>
Returns
Section titled “Returns”Permissions<TRoles>
Example
Section titled “Example”import { definePermissions, grant } from "@cfast/permissions";import { eq } from "drizzle-orm";import * as schema from "./schema";const { posts, comments } = schema;
// Style 1 — direct, accepts table objectsconst permissions = definePermissions({ roles: ["anonymous", "user", "admin"] as const, grants: { anonymous: [ grant("read", posts, { where: (p) => eq(p.published, true) }), ], user: [grant("read", posts), grant("create", posts)], admin: [grant("manage", "all")], },});
// Style 4 — recommended: runtime-resolved string subjectstype AuthUser = { id: string };const perms = definePermissions<AuthUser, typeof schema>({ schema })({ roles: ["user", "admin"] as const, grants: (grant) => ({ user: [ grant("read", "posts"), // JS key — resolves grant("create", "post_versions"), // SQL name — also resolves grant("update", posts, { // object form still works where: (p, u) => eq(p.authorId, u.id), }), // grant("read", "unknownTable"), // throws at startup ], admin: [grant("manage", "all")], }),});Call Signature
Section titled “Call Signature”definePermissions<
TUser,TTables>(): <TRoles>(config) =>Permissions<TRoles>
Defined in: packages/permissions/src/define-permissions.ts:219
Creates a permission configuration that can be shared between server-side
enforcement (@cfast/db) and client-side introspection (@cfast/actions).
Supports four calling styles:
-
Direct:
definePermissions(config)— when no custom user type and no schema map is needed. -
Curried (user only):
definePermissions<MyUser>()(config)— types theuserparameter insidewhereclauses. String subjects are still accepted but are not compile-time or runtime validated against a schema; they are stored as opaque strings and matched bygetTableName. -
Curried (user + schema types only, no runtime schema):
definePermissions<MyUser, typeof schema>()(config)— constrains string subjects to"jsKey" | "sql_name"at compile time, but at runtime still stores strings opaquely. Prefer style (4) when you can. -
Curried with runtime schema (RECOMMENDED):
definePermissions<MyUser, typeof schema>({ schema })(config)— walks the schema at startup and resolves every string-form subject to the exact Drizzle table reference the schema uses. This is the only form that lets string-form grants work with Drizzle relationalwithqueries, because Drizzle identifies tables by reference, not name (see issues #146, #175, #177).- Unknown strings throw PermissionRegistrationError at startup (fast, loud failure instead of silently matching nothing).
- Both the JS key (
"documentVersions") and the SQL table name ("document_versions") resolve to the same table reference. - Object-form subjects still work unchanged.
Type Parameters
Section titled “Type Parameters”TUser
TTables
Section titled “TTables”TTables extends SchemaMap = SchemaMap
Returns
Section titled “Returns”A Permissions object, or a function that takes a config and returns one.
<
TRoles>(config):Permissions<TRoles>
Type Parameters
Section titled “Type Parameters”TRoles
Section titled “TRoles”TRoles extends readonly string[]
Parameters
Section titled “Parameters”config
Section titled “config”PermissionsConfig<TRoles, TUser, TTables>
Returns
Section titled “Returns”Permissions<TRoles>
Example
Section titled “Example”import { definePermissions, grant } from "@cfast/permissions";import { eq } from "drizzle-orm";import * as schema from "./schema";const { posts, comments } = schema;
// Style 1 — direct, accepts table objectsconst permissions = definePermissions({ roles: ["anonymous", "user", "admin"] as const, grants: { anonymous: [ grant("read", posts, { where: (p) => eq(p.published, true) }), ], user: [grant("read", posts), grant("create", posts)], admin: [grant("manage", "all")], },});
// Style 4 — recommended: runtime-resolved string subjectstype AuthUser = { id: string };const perms = definePermissions<AuthUser, typeof schema>({ schema })({ roles: ["user", "admin"] as const, grants: (grant) => ({ user: [ grant("read", "posts"), // JS key — resolves grant("create", "post_versions"), // SQL name — also resolves grant("update", posts, { // object form still works where: (p, u) => eq(p.authorId, u.id), }), // grant("read", "unknownTable"), // throws at startup ], admin: [grant("manage", "all")], }),});