@brickkit/crud
CRUD actions for a resource, with access rules, filters, and hooks.
@brickkit/crud exports 17 names: 1 function, 5 interfaces, 11 types.
import { crud } from "@brickkit/crud";Functions
| Function | Description |
|---|---|
crud | A plugin that gives a resource its CRUD actions: list, get, create, update, delete, findOne, count, and exists, with validated input and output… |
crud
function crud<
const F extends Fields,
const O extends Operations = {},
>(
options: CrudOptions<F, O>,
): CrudPlugin<F, O>A plugin that gives a resource its CRUD actions: list, get, create,
update, delete, findOne, count, and exists, with validated input
and output, filters and sorting, and access rules. Install it with
resource.use(crud({ ... })). The actions are named <resource>.<operation>
and routed under /api/<resource>.
It denies by default: access is required. A column is hidden from reads,
writes, and filters until its fields entry allows it.
Parameters
| Name | Type | Description |
|---|---|---|
options | CrudOptions<F, O> | fields (per column: read, create, update, filter operators, and sort), access ("public", or { authorize, scope }), operations to switch some off, routes to move or disable routes, hooks around create, update, and delete, and defaultLimit and maxLimit for lists. |
Returns CrudPlugin<F, O> — The plugin, for resource.use, which returns the resource with its
actions attached so they can be called in-process.
Example
import { crud } from "@brickkit/crud";
export const page = pagesService
.resource({ name: "page", table: pages, id: pages.id })
.use(
crud({
access: "public",
fields: {
id: { read: true, filter: ["eq", "in"] },
title: { read: true, create: true, update: true, sort: true },
},
}),
);Source: packages/crud/src/index.ts:225
Interfaces
ColumnFieldPolicy
interface ColumnFieldPolicyProperties
| Name | Type | Description |
|---|---|---|
read? | boolean | |
create? | boolean | |
update? | boolean | |
filter? | readonly FilterOperator[] | |
sort? | boolean | |
schema? | TSchema | |
resolve? | never | |
scrub? | (args: { value: any; ctx: ActionContext; }) => unknown | Promise<unknown> |
Source: packages/crud/src/types.ts:26
CrudOptions
interface CrudOptions<F extends Fields = Fields, O extends Operations = Operations>Properties
| Name | Type | Description |
|---|---|---|
fields | F | |
operations? | O | |
routes? | PluginRoutes | |
defaultLimit? | number | |
maxLimit? | number | |
access | | "public" | { authorize?: (args: CrudAuthorizeArgs<F>) => boolean | Promise<boolean>; scope?: (args: { operation: Operation; ctx: ActionContext; }) => SQL | undefined | Promise<SQL | undefined>; } | |
hooks? | { beforeCreate?: (args: { data: Record<string, unknown>; ctx: ActionContext; error: ErrorBuilder<Record<string, never>>; }) => void | Promise<void>; afterCreate?: (args: { row: Record<string, unknown>; ctx: ActionContex… |
Source: packages/crud/src/types.ts:65
CrudTypes
interface CrudTypes<F, O>Properties
| Name | Type | Description |
|---|---|---|
readonly table | unknown | |
readonly context | unknown | |
readonly resource | unknown | |
readonly api | this["table"] extends Table ? CrudAPI<this["table"], this["context"], F, O, this["resource"] extends { config: { id: infer I extends Column } } ? GetColumnData<I, "raw"> : this["table"]["$inferSelect"][keyof this["table… |
Source: packages/crud/src/types.ts:394
DerivedFieldPolicy
interface DerivedFieldPolicyProperties
| Name | Type | Description |
|---|---|---|
read | true | |
schema | TSchema | |
resolve | (args: { rows: readonly Readonly<Record<string, unknown>>[]; ctx: ActionContext; }) => readonly unknown[] | Promise<readonly unknown[]> | One value per authorized parent row, in the same order. |
create? | false | |
update? | false | |
filter? | readonly [] | |
sort? | false | |
scrub? | ColumnFieldPolicy["scrub"] |
Source: packages/crud/src/types.ts:39
Query
interface Query<T extends Table, F, S extends readonly ReadKeys<T, F>[] | undefined = undefined, I extends readonly IncludeKeys<F>[] | undefined = undefined>Properties
| Name | Type | Description |
|---|---|---|
select? | S | |
include? | I | |
where? | Where<T, F> | |
orderBy? | readonly { field: Extract<Keys<F, "sort">, keyof Row<T>>; direction: "asc" | "desc"; }[] | |
limit? | number | |
offset? | number | |
includeTotal? | boolean |
Source: packages/crud/src/types.ts:179
Types
CrudAPI
type CrudAPI<T extends Table, C, F, O, ID = Row<T>[keyof Row<T>]> = [
O,
] extends [false]
? {}
: Pick<
AllAPI<T, C, F, ID>,
{ [K in Operation]: O extends Record<K, false> ? never : K }[Operation]
>;Source: packages/crud/src/types.ts:386
CrudAuthorizeArgs
type CrudAuthorizeArgs<F extends Fields = Fields> = {
[K in Operation]: {
operation: K;
input: CrudInputs<F>[K];
ctx: ActionContext;
};
}[Operation];Narrow operation and input together in an authorize callback.
Source: packages/crud/src/types.ts:242
CrudInputs
type CrudInputs<F extends Fields = Fields> = {
list: { [K in keyof AuthorizeQuery<F>]: AuthorizeQuery<F>[K] };
findOne: { [K in keyof AuthorizeQuery<F>]: AuthorizeQuery<F>[K] };
get: {
id: unknown;
select?: readonly Exclude<AuthorizeKeys<F, "read">, IncludeKeys<F>>[];
include?: readonly IncludeKeys<F>[];
};
create: AuthorizeWrite<F, "create">;
update: { id: unknown; data: AuthorizeWrite<F, "update"> };
delete: { id: unknown };
count: { where?: AuthorizeQuery<F>["where"] };
exists: { where?: AuthorizeQuery<F>["where"] };
};Validated authorization inputs, indexed by CRUD operation.
Properties
| Name | Type | Description |
|---|---|---|
list | { [K in keyof AuthorizeQuery<F>]: AuthorizeQuery<F>[K] } | |
findOne | { [K in keyof AuthorizeQuery<F>]: AuthorizeQuery<F>[K] } | |
get | { id: unknown; select?: readonly Exclude<AuthorizeKeys<F, "read">, IncludeKeys<F>>[]; include?: readonly IncludeKeys<F>[]; } | |
create | AuthorizeWrite<F, "create"> | |
update | { id: unknown; data: AuthorizeWrite<F, "update"> } | |
delete | { id: unknown } | |
count | { where?: AuthorizeQuery<F>["where"] } | |
exists | { where?: AuthorizeQuery<F>["where"] } |
Source: packages/crud/src/types.ts:227
CrudPlugin
type CrudPlugin<F extends Fields, O extends Operations> = ResourcePlugin<
any,
any,
object
> & { readonly types: CrudTypes<F, O> };Source: packages/crud/src/types.ts:410
FieldPolicy
type FieldPolicy = ColumnFieldPolicy | DerivedFieldPolicy;Source: packages/crud/src/types.ts:53
Fields
type Fields = Readonly<Record<string, FieldPolicy>>;Source: packages/crud/src/types.ts:54
FilterOperator
type FilterOperator =
| "eq"
| "ne"
| "in"
| "notIn"
| "gt"
| "gte"
| "lt"
| "lte"
| "between"
| "contains"
| "startsWith"
| "endsWith"
| "isNull"
| "isNotNull";Source: packages/crud/src/types.ts:11
Operation
type Operation =
| "list"
| "get"
| "create"
| "update"
| "delete"
| "findOne"
| "count"
| "exists";Source: packages/crud/src/types.ts:55
Operations
type Operations = false | Partial<Record<Operation, boolean>>;Source: packages/crud/src/types.ts:64
ReadRow
type ReadRow<T extends Table, F> = {
[K in ReadKeys<T, F>]: FieldValue<T, F, K>;
};Source: packages/crud/src/types.ts:140
Where
type Where<T extends Table, F> = FilterWhere<F, Row<T>>;Source: packages/crud/src/types.ts:178