@rsc-kit/press 0.0.0-stage → 0.30.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -2
- package/dist/admin/actions.d.ts +30 -0
- package/dist/admin/actions.js +171 -0
- package/dist/admin/actions.js.map +1 -0
- package/dist/admin/index.d.ts +5 -0
- package/dist/admin/index.js +2 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/panel.d.ts +96 -0
- package/dist/admin/panel.js +354 -0
- package/dist/admin/panel.js.map +1 -0
- package/dist/admin/registry.d.ts +58 -0
- package/dist/admin/registry.js +90 -0
- package/dist/admin/registry.js.map +1 -0
- package/dist/admin/theme.d.ts +251 -0
- package/dist/admin/theme.js +2 -0
- package/dist/admin/theme.js.map +1 -0
- package/dist/admin/url.d.ts +24 -0
- package/dist/admin/url.js +45 -0
- package/dist/admin/url.js.map +1 -0
- package/dist/blocks.d.ts +46 -0
- package/dist/blocks.js +33 -0
- package/dist/blocks.js.map +1 -0
- package/dist/forms/actions.d.ts +7 -0
- package/dist/forms/actions.js +26 -0
- package/dist/forms/actions.js.map +1 -0
- package/dist/forms/form.d.ts +42 -0
- package/dist/forms/form.js +44 -0
- package/dist/forms/form.js.map +1 -0
- package/dist/forms/honeypot.d.ts +2 -0
- package/dist/forms/honeypot.js +3 -0
- package/dist/forms/honeypot.js.map +1 -0
- package/dist/forms/index.d.ts +3 -0
- package/dist/forms/index.js +2 -0
- package/dist/forms/index.js.map +1 -0
- package/dist/forms/registry.d.ts +10 -0
- package/dist/forms/registry.js +17 -0
- package/dist/forms/registry.js.map +1 -0
- package/dist/forms/theme.d.ts +29 -0
- package/dist/forms/theme.js +2 -0
- package/dist/forms/theme.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/installable.d.ts +173 -0
- package/dist/installable.js +490 -0
- package/dist/installable.js.map +1 -0
- package/dist/memory.d.ts +7 -0
- package/dist/memory.js +50 -0
- package/dist/memory.js.map +1 -0
- package/dist/pages/index.d.ts +2 -0
- package/dist/pages/index.js +2 -0
- package/dist/pages/index.js.map +1 -0
- package/dist/pages/pages.d.ts +78 -0
- package/dist/pages/pages.js +183 -0
- package/dist/pages/pages.js.map +1 -0
- package/dist/plugin.d.ts +51 -0
- package/dist/plugin.js +20 -0
- package/dist/plugin.js.map +1 -0
- package/dist/resource.d.ts +320 -0
- package/dist/resource.js +415 -0
- package/dist/resource.js.map +1 -0
- package/dist/shadcn/breadcrumbs.d.ts +6 -0
- package/dist/shadcn/breadcrumbs.js +21 -0
- package/dist/shadcn/breadcrumbs.js.map +1 -0
- package/dist/shadcn/components/ui/alert-dialog.d.ts +18 -0
- package/dist/shadcn/components/ui/alert-dialog.js +44 -0
- package/dist/shadcn/components/ui/alert-dialog.js.map +1 -0
- package/dist/shadcn/components/ui/avatar.d.ts +11 -0
- package/dist/shadcn/components/ui/avatar.js +25 -0
- package/dist/shadcn/components/ui/avatar.js.map +1 -0
- package/dist/shadcn/components/ui/badge.d.ts +7 -0
- package/dist/shadcn/components/ui/badge.js +34 -0
- package/dist/shadcn/components/ui/badge.js.map +1 -0
- package/dist/shadcn/components/ui/breadcrumb.d.ts +10 -0
- package/dist/shadcn/components/ui/breadcrumb.js +38 -0
- package/dist/shadcn/components/ui/breadcrumb.js.map +1 -0
- package/dist/shadcn/components/ui/button.d.ts +8 -0
- package/dist/shadcn/components/ui/button.js +35 -0
- package/dist/shadcn/components/ui/button.js.map +1 -0
- package/dist/shadcn/components/ui/card.d.ts +11 -0
- package/dist/shadcn/components/ui/card.js +26 -0
- package/dist/shadcn/components/ui/card.js.map +1 -0
- package/dist/shadcn/components/ui/checkbox.d.ts +3 -0
- package/dist/shadcn/components/ui/checkbox.js +10 -0
- package/dist/shadcn/components/ui/checkbox.js.map +1 -0
- package/dist/shadcn/components/ui/dropdown-menu.d.ts +29 -0
- package/dist/shadcn/components/ui/dropdown-menu.js +53 -0
- package/dist/shadcn/components/ui/dropdown-menu.js.map +1 -0
- package/dist/shadcn/components/ui/field.d.ts +24 -0
- package/dist/shadcn/components/ui/field.js +69 -0
- package/dist/shadcn/components/ui/field.js.map +1 -0
- package/dist/shadcn/components/ui/input.d.ts +3 -0
- package/dist/shadcn/components/ui/input.js +9 -0
- package/dist/shadcn/components/ui/input.js.map +1 -0
- package/dist/shadcn/components/ui/label.d.ts +3 -0
- package/dist/shadcn/components/ui/label.js +9 -0
- package/dist/shadcn/components/ui/label.js.map +1 -0
- package/dist/shadcn/components/ui/select.d.ts +15 -0
- package/dist/shadcn/components/ui/select.js +36 -0
- package/dist/shadcn/components/ui/select.js.map +1 -0
- package/dist/shadcn/components/ui/separator.d.ts +3 -0
- package/dist/shadcn/components/ui/separator.js +9 -0
- package/dist/shadcn/components/ui/separator.js.map +1 -0
- package/dist/shadcn/components/ui/sheet.d.ts +14 -0
- package/dist/shadcn/components/ui/sheet.js +39 -0
- package/dist/shadcn/components/ui/sheet.js.map +1 -0
- package/dist/shadcn/components/ui/sidebar.d.ts +63 -0
- package/dist/shadcn/components/ui/sidebar.js +257 -0
- package/dist/shadcn/components/ui/sidebar.js.map +1 -0
- package/dist/shadcn/components/ui/skeleton.d.ts +2 -0
- package/dist/shadcn/components/ui/skeleton.js +7 -0
- package/dist/shadcn/components/ui/skeleton.js.map +1 -0
- package/dist/shadcn/components/ui/sonner.d.ts +3 -0
- package/dist/shadcn/components/ui/sonner.js +38 -0
- package/dist/shadcn/components/ui/sonner.js.map +1 -0
- package/dist/shadcn/components/ui/switch.d.ts +5 -0
- package/dist/shadcn/components/ui/switch.js +9 -0
- package/dist/shadcn/components/ui/switch.js.map +1 -0
- package/dist/shadcn/components/ui/table.d.ts +10 -0
- package/dist/shadcn/components/ui/table.js +30 -0
- package/dist/shadcn/components/ui/table.js.map +1 -0
- package/dist/shadcn/components/ui/textarea.d.ts +3 -0
- package/dist/shadcn/components/ui/textarea.js +8 -0
- package/dist/shadcn/components/ui/textarea.js.map +1 -0
- package/dist/shadcn/components/ui/tooltip.d.ts +6 -0
- package/dist/shadcn/components/ui/tooltip.js +18 -0
- package/dist/shadcn/components/ui/tooltip.js.map +1 -0
- package/dist/shadcn/data-table.d.ts +12 -0
- package/dist/shadcn/data-table.js +195 -0
- package/dist/shadcn/data-table.js.map +1 -0
- package/dist/shadcn/fields.d.ts +20 -0
- package/dist/shadcn/fields.js +179 -0
- package/dist/shadcn/fields.js.map +1 -0
- package/dist/shadcn/flash-toasts.d.ts +2 -0
- package/dist/shadcn/flash-toasts.js +11 -0
- package/dist/shadcn/flash-toasts.js.map +1 -0
- package/dist/shadcn/hooks/use-mobile.d.ts +1 -0
- package/dist/shadcn/hooks/use-mobile.js +16 -0
- package/dist/shadcn/hooks/use-mobile.js.map +1 -0
- package/dist/shadcn/index.d.ts +10 -0
- package/dist/shadcn/index.js +31 -0
- package/dist/shadcn/index.js.map +1 -0
- package/dist/shadcn/mode-toggle.d.ts +7 -0
- package/dist/shadcn/mode-toggle.js +52 -0
- package/dist/shadcn/mode-toggle.js.map +1 -0
- package/dist/shadcn/nav.d.ts +5 -0
- package/dist/shadcn/nav.js +19 -0
- package/dist/shadcn/nav.js.map +1 -0
- package/dist/shadcn/pages.d.ts +15 -0
- package/dist/shadcn/pages.js +59 -0
- package/dist/shadcn/pages.js.map +1 -0
- package/dist/shadcn/plugin-forms.d.ts +16 -0
- package/dist/shadcn/plugin-forms.js +25 -0
- package/dist/shadcn/plugin-forms.js.map +1 -0
- package/dist/shadcn/public-form.d.ts +8 -0
- package/dist/shadcn/public-form.js +26 -0
- package/dist/shadcn/public-form.js.map +1 -0
- package/dist/shadcn/resource-form.d.ts +19 -0
- package/dist/shadcn/resource-form.js +30 -0
- package/dist/shadcn/resource-form.js.map +1 -0
- package/dist/shadcn/styles.css +12 -0
- package/dist/shadcn/tenant-switcher.d.ts +3 -0
- package/dist/shadcn/tenant-switcher.js +17 -0
- package/dist/shadcn/tenant-switcher.js.map +1 -0
- package/dist/shadcn/theme-script.d.ts +7 -0
- package/dist/shadcn/theme-script.js +10 -0
- package/dist/shadcn/theme-script.js.map +1 -0
- package/dist/shadcn/user-menu.d.ts +3 -0
- package/dist/shadcn/user-menu.js +23 -0
- package/dist/shadcn/user-menu.js.map +1 -0
- package/dist/signing.d.ts +43 -0
- package/dist/signing.js +82 -0
- package/dist/signing.js.map +1 -0
- package/dist/tenant.d.ts +12 -0
- package/dist/tenant.js +29 -0
- package/dist/tenant.js.map +1 -0
- package/dist/uploads.d.ts +32 -0
- package/dist/uploads.js +28 -0
- package/dist/uploads.js.map +1 -0
- package/package.json +74 -4
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A resource, described once: what its table shows, what its form takes, and
|
|
3
|
+
* where its rows come from. The panel renders every page from this - nothing
|
|
4
|
+
* per resource is written as a page.
|
|
5
|
+
*
|
|
6
|
+
* The form is a schema, not a list of widgets: the same object validates the
|
|
7
|
+
* save on the server and is read for the fields it has, so a field cannot be
|
|
8
|
+
* on the form and missing from the check, or the other way round. Any
|
|
9
|
+
* Standard Schema validates; one that also describes itself as JSON Schema
|
|
10
|
+
* (Standard JSON Schema - zod 4.2+, and others as they add it) gives its
|
|
11
|
+
* fields too, and any other says them in `fields`.
|
|
12
|
+
*/
|
|
13
|
+
import type { ComponentType, ReactNode } from 'react';
|
|
14
|
+
import type { StandardSchemaV1 } from '@rsc-kit/core/standardSchema';
|
|
15
|
+
import type { Storage } from './uploads.js';
|
|
16
|
+
/** What the form validates with: any Standard Schema - zod, valibot, arktype, effect. */
|
|
17
|
+
export type FormSchema = StandardSchemaV1<any, Record<string, unknown>>;
|
|
18
|
+
/** What a schema's save hands the data source. */
|
|
19
|
+
export type ValuesOf<Schema extends FormSchema> = NonNullable<Schema['~standard']['types']>['output'];
|
|
20
|
+
export type Format = 'text' | 'money' | 'badge' | 'boolean' | 'date' | 'relation';
|
|
21
|
+
export interface Column {
|
|
22
|
+
key: string;
|
|
23
|
+
label: string;
|
|
24
|
+
format: Format;
|
|
25
|
+
sortable: boolean;
|
|
26
|
+
searchable: boolean;
|
|
27
|
+
/** Shown until the visitor hides it from the Columns menu. */
|
|
28
|
+
visible: boolean;
|
|
29
|
+
/** Draws the cell instead of the format. Runs on the server, so it may be async and read anything. */
|
|
30
|
+
cell?: (value: any, row: any) => ReactNode | Promise<ReactNode>;
|
|
31
|
+
/** For a relation column: the resource whose row the value names, shown by its title. */
|
|
32
|
+
relation?: string;
|
|
33
|
+
}
|
|
34
|
+
/** A column, chained: text('name').searchable().sortable(). */
|
|
35
|
+
export declare class ColumnBuilder {
|
|
36
|
+
#private;
|
|
37
|
+
constructor(column: Column);
|
|
38
|
+
sortable(): this;
|
|
39
|
+
searchable(): this;
|
|
40
|
+
label(label: string): this;
|
|
41
|
+
/** In the Columns menu, unticked until the visitor shows it. */
|
|
42
|
+
hidden(): this;
|
|
43
|
+
/** Draw the cell yourself: .cell((value, row) => <Avatar src={row.photo} />). */
|
|
44
|
+
cell(render: NonNullable<Column['cell']>): this;
|
|
45
|
+
build(): Column;
|
|
46
|
+
}
|
|
47
|
+
/** The column helpers, typed to the row so a misspelt key fails the typecheck. */
|
|
48
|
+
export interface Columns<Row> {
|
|
49
|
+
text(key: keyof Row & string): ColumnBuilder;
|
|
50
|
+
money(key: keyof Row & string): ColumnBuilder;
|
|
51
|
+
badge(key: keyof Row & string): ColumnBuilder;
|
|
52
|
+
boolean(key: keyof Row & string): ColumnBuilder;
|
|
53
|
+
date(key: keyof Row & string): ColumnBuilder;
|
|
54
|
+
/**
|
|
55
|
+
* A belongsTo: the value is another resource's key, shown as that row's
|
|
56
|
+
* title - col.relation('categoryId', 'categories') shows "Lighting", not 3.
|
|
57
|
+
*/
|
|
58
|
+
relation(key: keyof Row & string, resource: string): ColumnBuilder;
|
|
59
|
+
}
|
|
60
|
+
export type FieldType = 'text' | 'textarea' | 'number' | 'select' | 'toggle' | 'email' | 'date' | 'blocks' | 'file' | 'image';
|
|
61
|
+
/** A kind of block a blocks field offers, as the form needs it: plain data. */
|
|
62
|
+
export interface BlockSpec {
|
|
63
|
+
name: string;
|
|
64
|
+
label: string;
|
|
65
|
+
fields: Field[];
|
|
66
|
+
}
|
|
67
|
+
/** One choice of a select: what is saved, and what the visitor reads. */
|
|
68
|
+
export interface Option {
|
|
69
|
+
value: string;
|
|
70
|
+
label: string;
|
|
71
|
+
}
|
|
72
|
+
/** What the form renders. Plain data: it crosses to the client component. */
|
|
73
|
+
export interface Field {
|
|
74
|
+
name: string;
|
|
75
|
+
label: string;
|
|
76
|
+
type: FieldType;
|
|
77
|
+
required: boolean;
|
|
78
|
+
options?: Option[];
|
|
79
|
+
/**
|
|
80
|
+
* A belongsTo: the options are another resource's rows, its key saved and
|
|
81
|
+
* its title shown, read when the form is drawn and scoped to the tenant.
|
|
82
|
+
*/
|
|
83
|
+
relation?: string;
|
|
84
|
+
/** A select whose schema wants a number: its value is converted, as a number field's is. */
|
|
85
|
+
numeric?: boolean;
|
|
86
|
+
/** Help under the control. */
|
|
87
|
+
description?: string;
|
|
88
|
+
/**
|
|
89
|
+
* What the browser checks before a submit, from the schema: the native
|
|
90
|
+
* constraints, so a mistake is caught without a round trip and without the
|
|
91
|
+
* schema in the browser. A courtesy only - the server validates every save.
|
|
92
|
+
*/
|
|
93
|
+
min?: number;
|
|
94
|
+
max?: number;
|
|
95
|
+
minLength?: number;
|
|
96
|
+
maxLength?: number;
|
|
97
|
+
/** Whole-value, as the pattern attribute matches. */
|
|
98
|
+
pattern?: string;
|
|
99
|
+
step?: number | 'any';
|
|
100
|
+
/**
|
|
101
|
+
* A blocks field's kinds of block. Its value is a list of { type, data },
|
|
102
|
+
* each block's data checked by its own schema; in a form, block i's field
|
|
103
|
+
* is named `name.i.field`, which is also where its errors are.
|
|
104
|
+
*/
|
|
105
|
+
blocks?: BlockSpec[];
|
|
106
|
+
/**
|
|
107
|
+
* A file or image field's types, as the accept attribute says them:
|
|
108
|
+
* `image/*`, `application/pdf`, `.csv`. Checked by the browser when the
|
|
109
|
+
* file is chosen and by the server when it arrives.
|
|
110
|
+
*/
|
|
111
|
+
accept?: string;
|
|
112
|
+
/** A file or image field's largest file, in bytes. */
|
|
113
|
+
maxSize?: number;
|
|
114
|
+
/** The schema allows null: a file field that is emptied saves null, so the source clears it. */
|
|
115
|
+
nullable?: boolean;
|
|
116
|
+
}
|
|
117
|
+
export interface Filter {
|
|
118
|
+
key: string;
|
|
119
|
+
label: string;
|
|
120
|
+
options: Option[];
|
|
121
|
+
}
|
|
122
|
+
export interface ListQuery {
|
|
123
|
+
q?: string;
|
|
124
|
+
sort?: string;
|
|
125
|
+
dir: 'asc' | 'desc';
|
|
126
|
+
page: number;
|
|
127
|
+
/**
|
|
128
|
+
* Null asks for every row: a resource whose table works in the browser
|
|
129
|
+
* (mode: 'client') is loaded whole, and searched, sorted and paged there.
|
|
130
|
+
*/
|
|
131
|
+
perPage: number | null;
|
|
132
|
+
/** Only the resource's declared filters, each with a value. */
|
|
133
|
+
filters: Record<string, string>;
|
|
134
|
+
/** The columns marked searchable: what q is matched against. */
|
|
135
|
+
searchable: string[];
|
|
136
|
+
}
|
|
137
|
+
/** Whoever's records these are, in a panel with tenants. */
|
|
138
|
+
export interface Tenant {
|
|
139
|
+
id: string;
|
|
140
|
+
name: string;
|
|
141
|
+
/** A second line under the name in the switcher: a plan, a role. */
|
|
142
|
+
description?: string;
|
|
143
|
+
/** An image url for the switcher. Without one the first letter is shown. */
|
|
144
|
+
avatar?: string;
|
|
145
|
+
}
|
|
146
|
+
/** What every call to a data source is told besides its arguments. */
|
|
147
|
+
export interface SourceContext {
|
|
148
|
+
/** The tenant the visitor is working in, or null in a panel without tenants. */
|
|
149
|
+
tenant: Tenant | null;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Where a resource's rows live: five functions, and nothing about how. A
|
|
153
|
+
* database (Drizzle, Prisma, SQL), a REST or GraphQL API, a Laravel app through
|
|
154
|
+
* rpc(), a file, memory - the panel calls these and never anything else.
|
|
155
|
+
*
|
|
156
|
+
* In a panel with tenants, a source answers only for context.tenant. find()
|
|
157
|
+
* returning null for another tenant's record is what makes its url a 404.
|
|
158
|
+
*/
|
|
159
|
+
export interface DataSource<Row, Values> {
|
|
160
|
+
list(query: ListQuery, context: SourceContext): Promise<{
|
|
161
|
+
rows: Row[];
|
|
162
|
+
total: number;
|
|
163
|
+
}>;
|
|
164
|
+
find(id: string, context: SourceContext): Promise<Row | null>;
|
|
165
|
+
create(values: Values, context: SourceContext): Promise<Row>;
|
|
166
|
+
update(id: string, values: Values, context: SourceContext): Promise<Row>;
|
|
167
|
+
delete(id: string, context: SourceContext): Promise<void>;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Where a table's search, filters, sort and paging happen.
|
|
171
|
+
*
|
|
172
|
+
* 'server' each change is a request; the source is asked for one page.
|
|
173
|
+
* For a table that grows: orders, users, an API with millions.
|
|
174
|
+
* 'client' the source is asked once for every row (perPage: null) and the
|
|
175
|
+
* browser does the rest, with no request per keystroke. For a
|
|
176
|
+
* table that stays small: categories, settings, team members.
|
|
177
|
+
*/
|
|
178
|
+
export type TableMode = 'server' | 'client';
|
|
179
|
+
/**
|
|
180
|
+
* Something done to the rows ticked in the table: publish, archive, export.
|
|
181
|
+
* `run` is given the rows themselves, each found by the source as the
|
|
182
|
+
* visitor - an id the browser sent that is not theirs never reaches it.
|
|
183
|
+
*/
|
|
184
|
+
export interface BulkAction<Row = any> {
|
|
185
|
+
/** Identifies it in the call; 'delete' is the panel's own. */
|
|
186
|
+
name: string;
|
|
187
|
+
label: string;
|
|
188
|
+
/** Asked about first, as a delete is. */
|
|
189
|
+
destructive?: boolean;
|
|
190
|
+
/** What happened to the rows, for the toast: 'published' says "3 products published.", as Delete says "deleted". */
|
|
191
|
+
done?: string;
|
|
192
|
+
/** Returns its own words for the toast, or leaves them to `done`. */
|
|
193
|
+
run: (rows: Row[], context: SourceContext) => void | string | Promise<void | string>;
|
|
194
|
+
}
|
|
195
|
+
export interface Resource<Row = any, Schema extends FormSchema = FormSchema> {
|
|
196
|
+
name: string;
|
|
197
|
+
label: string;
|
|
198
|
+
singular: string;
|
|
199
|
+
key: keyof Row & string;
|
|
200
|
+
title: keyof Row & string;
|
|
201
|
+
source: DataSource<Row, ValuesOf<Schema>>;
|
|
202
|
+
columns: Column[];
|
|
203
|
+
filters: Filter[];
|
|
204
|
+
schema: Schema;
|
|
205
|
+
fields: Field[];
|
|
206
|
+
perPage: number;
|
|
207
|
+
mode: TableMode;
|
|
208
|
+
/** Listed and searched, never created, edited or deleted from the panel. */
|
|
209
|
+
readOnly: boolean;
|
|
210
|
+
bulkActions: BulkAction<Row>[];
|
|
211
|
+
/** The sidebar's icon: a lucide icon, or any component. */
|
|
212
|
+
icon?: ComponentType<{
|
|
213
|
+
className?: string;
|
|
214
|
+
}>;
|
|
215
|
+
description?: string;
|
|
216
|
+
}
|
|
217
|
+
export interface ResourceDefinition<Row, Schema extends FormSchema> {
|
|
218
|
+
/** The url segment: /admin/products. */
|
|
219
|
+
name: string;
|
|
220
|
+
label?: string;
|
|
221
|
+
singular?: string;
|
|
222
|
+
/** The field that identifies a row in the url. */
|
|
223
|
+
key: keyof Row & string;
|
|
224
|
+
/** The field an edit page's heading shows. */
|
|
225
|
+
title: keyof Row & string;
|
|
226
|
+
source: DataSource<Row, ValuesOf<Schema>>;
|
|
227
|
+
table: (col: Columns<Row>) => ColumnBuilder[];
|
|
228
|
+
/** Enum fields of the form, offered as a select above the table. */
|
|
229
|
+
filters?: (keyof Row & string)[];
|
|
230
|
+
/** Any Standard Schema of an object: z.object(), v.object(), type({...}). */
|
|
231
|
+
form: Schema;
|
|
232
|
+
/**
|
|
233
|
+
* What the schema cannot say: a long string is a textarea, a label, help.
|
|
234
|
+
* The whole list, for a schema that does not describe itself as JSON
|
|
235
|
+
* Schema - a field missing here is then missing from the form.
|
|
236
|
+
*/
|
|
237
|
+
fields?: Partial<Record<keyof ValuesOf<Schema> & string, FieldOverride>>;
|
|
238
|
+
perPage?: number;
|
|
239
|
+
/** Where search, filters, sort and paging happen. 'server' unless said. */
|
|
240
|
+
mode?: TableMode;
|
|
241
|
+
/** Listed and searched, never created, edited or deleted from the panel: a log, a feed, a plugin's own records. */
|
|
242
|
+
readOnly?: boolean;
|
|
243
|
+
/** Offered when rows are ticked, beside the panel's own Delete. */
|
|
244
|
+
bulkActions?: BulkAction<Row>[];
|
|
245
|
+
/** The sidebar's icon: import { Package } from 'lucide-react'. */
|
|
246
|
+
icon?: ComponentType<{
|
|
247
|
+
className?: string;
|
|
248
|
+
}>;
|
|
249
|
+
/** Under the page's heading. */
|
|
250
|
+
description?: string;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Two calls so the row is named and the schema is inferred:
|
|
254
|
+
* defineResource<Product>()({ ... }).
|
|
255
|
+
*/
|
|
256
|
+
export declare function defineResource<Row>(): <Schema extends FormSchema>(definition: ResourceDefinition<Row, Schema>) => Resource<Row, Schema>;
|
|
257
|
+
/** A field as the app says it, over what the schema said. */
|
|
258
|
+
export type FieldOverride = Partial<Pick<Field, 'type' | 'label' | 'description' | 'required' | 'relation'>> & {
|
|
259
|
+
/** A bare value is labelled by humanizing it: 'in_stock' reads "In stock". */
|
|
260
|
+
options?: (string | Option)[];
|
|
261
|
+
/** The kinds a blocks field offers: { type: 'blocks', blocks: [hero, features] }. */
|
|
262
|
+
blocks?: BlockLike[];
|
|
263
|
+
/** Where a file or image field keeps what is uploaded. Required for one. */
|
|
264
|
+
storage?: Storage;
|
|
265
|
+
/** A file or image field's types. An image field takes PNG, JPEG, WebP, GIF and AVIF unless it says. */
|
|
266
|
+
accept?: string;
|
|
267
|
+
/** A file or image field's largest file, in bytes. */
|
|
268
|
+
maxSize?: number;
|
|
269
|
+
};
|
|
270
|
+
/** What a blocks field needs of a block: its name, label, fields and schema. */
|
|
271
|
+
interface BlockLike {
|
|
272
|
+
name: string;
|
|
273
|
+
label: string;
|
|
274
|
+
fields: Field[];
|
|
275
|
+
schema: FormSchema;
|
|
276
|
+
}
|
|
277
|
+
type Overrides = Record<string, FieldOverride | undefined>;
|
|
278
|
+
/**
|
|
279
|
+
* The fields a schema describes: the type of each property, whether it is
|
|
280
|
+
* required, an enum's options. From its JSON Schema when it has one; from
|
|
281
|
+
* `overrides` alone when it does not, which must then list every field.
|
|
282
|
+
*/
|
|
283
|
+
export declare function fieldsOf(schema: FormSchema, overrides?: Overrides): Field[];
|
|
284
|
+
/**
|
|
285
|
+
* A submitted form's values as the schema expects them, by its fields: a
|
|
286
|
+
* resource's, a public form's, a block's. A checkbox that is off is not in
|
|
287
|
+
* FormData at all, so a toggle is whether its name arrived; an empty optional
|
|
288
|
+
* field is left out rather than sent as "".
|
|
289
|
+
*/
|
|
290
|
+
export declare function valuesFrom(target: {
|
|
291
|
+
fields: Field[];
|
|
292
|
+
}, form: FormData): Record<string, unknown>;
|
|
293
|
+
export type Parsed<Values> = {
|
|
294
|
+
ok: true;
|
|
295
|
+
values: Values;
|
|
296
|
+
} | {
|
|
297
|
+
ok: false;
|
|
298
|
+
errors: Record<string, string[]>;
|
|
299
|
+
};
|
|
300
|
+
export interface ParseOptions {
|
|
301
|
+
/** The record being edited, as it was: the values a file field may keep without uploading again. */
|
|
302
|
+
current?: Record<string, unknown> | null;
|
|
303
|
+
/** Handed to storage with each upload. */
|
|
304
|
+
tenant?: Tenant | null;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* A submitted form checked against its schema, with each refusal under its
|
|
308
|
+
* field. Uploads are kept last: the form is checked with them still files,
|
|
309
|
+
* and only when nothing else is wrong is each one stored and the form
|
|
310
|
+
* checked again with what storage answered - so a refused save leaves no
|
|
311
|
+
* file behind.
|
|
312
|
+
*/
|
|
313
|
+
export declare function parse<Schema extends FormSchema>(target: {
|
|
314
|
+
schema: Schema;
|
|
315
|
+
fields: Field[];
|
|
316
|
+
}, form: FormData, options?: ParseOptions): Promise<Parsed<ValuesOf<Schema>>>;
|
|
317
|
+
export declare function humanize(key: string): string;
|
|
318
|
+
/** What a bulk action's toast says: "3 products published." with `done`, else "Publish: 3 products.". */
|
|
319
|
+
export declare function bulkToast(bulk: Pick<BulkAction, 'label' | 'done'>, count: number, noun: string): string;
|
|
320
|
+
export {};
|