@rebasepro/types 0.7.0 → 0.9.0
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 +10 -10
- package/dist/controllers/auth.d.ts +1 -1
- package/dist/controllers/client.d.ts +237 -7
- package/dist/controllers/collection_registry.d.ts +3 -3
- package/dist/controllers/customization_controller.d.ts +1 -1
- package/dist/controllers/data.d.ts +285 -81
- package/dist/controllers/data_driver.d.ts +50 -37
- package/dist/controllers/index.d.ts +1 -1
- package/dist/controllers/local_config_persistence.d.ts +4 -4
- package/dist/controllers/navigation.d.ts +2 -2
- package/dist/controllers/registry.d.ts +17 -6
- package/dist/controllers/{side_entity_controller.d.ts → side_panel_controller.d.ts} +7 -7
- package/dist/controllers/storage.d.ts +39 -0
- package/dist/errors.d.ts +64 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +290 -16
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +305 -18
- package/dist/index.umd.js.map +1 -1
- package/dist/rebase_context.d.ts +8 -4
- package/dist/types/auth_adapter.d.ts +9 -6
- package/dist/types/backend.d.ts +30 -26
- package/dist/types/builders.d.ts +2 -2
- package/dist/types/collections.d.ts +211 -136
- package/dist/types/component_overrides.d.ts +61 -3
- package/dist/types/cron.d.ts +10 -1
- package/dist/types/data_source.d.ts +18 -5
- package/dist/types/database_adapter.d.ts +4 -3
- package/dist/types/entities.d.ts +7 -7
- package/dist/types/entity_actions.d.ts +7 -7
- package/dist/types/entity_callbacks.d.ts +55 -43
- package/dist/types/entity_views.d.ts +3 -3
- package/dist/types/filter-operators.d.ts +153 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/modify_collections.d.ts +2 -2
- package/dist/types/plugins.d.ts +9 -9
- package/dist/types/policy.d.ts +191 -0
- package/dist/types/properties.d.ts +153 -43
- package/dist/types/property_config.d.ts +1 -1
- package/dist/types/relations.d.ts +3 -3
- package/dist/types/slots.d.ts +14 -14
- package/dist/types/storage_source.d.ts +83 -0
- package/dist/types/websockets.d.ts +12 -13
- package/dist/users/user.d.ts +21 -9
- package/package.json +1 -1
- package/src/controllers/auth.tsx +1 -1
- package/src/controllers/client.ts +275 -7
- package/src/controllers/collection_registry.ts +3 -3
- package/src/controllers/customization_controller.tsx +1 -1
- package/src/controllers/data.ts +309 -97
- package/src/controllers/data_driver.ts +49 -40
- package/src/controllers/index.ts +1 -1
- package/src/controllers/local_config_persistence.tsx +4 -4
- package/src/controllers/navigation.ts +2 -2
- package/src/controllers/registry.ts +18 -6
- package/src/controllers/{side_entity_controller.tsx → side_panel_controller.tsx} +7 -7
- package/src/controllers/storage.ts +60 -1
- package/src/errors.ts +80 -0
- package/src/index.ts +1 -0
- package/src/rebase_context.tsx +8 -4
- package/src/types/auth_adapter.ts +9 -6
- package/src/types/backend.ts +41 -36
- package/src/types/builders.ts +2 -2
- package/src/types/collections.ts +256 -172
- package/src/types/component_overrides.ts +72 -5
- package/src/types/cron.ts +10 -1
- package/src/types/data_source.ts +29 -7
- package/src/types/database_adapter.ts +4 -3
- package/src/types/entities.ts +7 -7
- package/src/types/entity_actions.tsx +7 -7
- package/src/types/entity_callbacks.ts +58 -47
- package/src/types/entity_views.tsx +3 -3
- package/src/types/filter-operators.ts +240 -0
- package/src/types/index.ts +3 -2
- package/src/types/modify_collections.tsx +2 -2
- package/src/types/plugins.tsx +9 -9
- package/src/types/policy.ts +229 -0
- package/src/types/properties.ts +164 -44
- package/src/types/property_config.tsx +0 -1
- package/src/types/relations.ts +3 -3
- package/src/types/slots.tsx +14 -14
- package/src/types/storage_source.ts +90 -0
- package/src/types/websockets.ts +12 -14
- package/src/users/user.ts +22 -9
- package/dist/types/backend_hooks.d.ts +0 -109
- package/dist/types/entity_overrides.d.ts +0 -10
- package/src/types/backend_hooks.ts +0 -114
- package/src/types/entity_overrides.tsx +0 -11
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type React from "react";
|
|
2
|
+
import type { Property } from "./properties";
|
|
3
|
+
import type { WhereFilterOp } from "./filter-operators";
|
|
2
4
|
|
|
3
5
|
// ── Scoped component name unions ──────────────────────────────────────
|
|
4
6
|
|
|
@@ -43,13 +45,14 @@ export type CollectionComponentName =
|
|
|
43
45
|
| "Collection.Card"
|
|
44
46
|
| "Collection.EmptyState"
|
|
45
47
|
| "Collection.Actions"
|
|
48
|
+
| "Collection.FilterField"
|
|
46
49
|
|
|
47
50
|
// ── Entity / Form ──
|
|
48
51
|
| "Entity.Form"
|
|
49
|
-
| "
|
|
50
|
-
| "
|
|
52
|
+
| "EditView.FormActions"
|
|
53
|
+
| "DetailView"
|
|
51
54
|
| "Entity.SidePanel"
|
|
52
|
-
| "
|
|
55
|
+
| "EntityPreview"
|
|
53
56
|
| "Entity.MissingReference";
|
|
54
57
|
|
|
55
58
|
/**
|
|
@@ -58,6 +61,70 @@ export type CollectionComponentName =
|
|
|
58
61
|
*/
|
|
59
62
|
export type OverridableComponentName = AppComponentName | CollectionComponentName;
|
|
60
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Props received by a filter field component — whether it is a built-in
|
|
66
|
+
* per-type field, a property-level replacement (`property.ui.Filter`), or a
|
|
67
|
+
* `"Collection.FilterField"` override.
|
|
68
|
+
*
|
|
69
|
+
* The `operators` list is **already resolved**: it is the intersection of the
|
|
70
|
+
* engine's {@link DataSourceCapabilities.filterOperators}, the property-type
|
|
71
|
+
* defaults, and any `property.ui.filterOperators` narrowing. A custom field
|
|
72
|
+
* should only offer operators from this list — anything else may throw at
|
|
73
|
+
* query time on engines that cannot execute it.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```tsx
|
|
77
|
+
* function MyStatusFilter({ value, setValue, operators }: FilterFieldBindingProps) {
|
|
78
|
+
* return (
|
|
79
|
+
* <select
|
|
80
|
+
* value={value?.[1] as string ?? ""}
|
|
81
|
+
* onChange={e => setValue(e.target.value ? ["==", e.target.value] : undefined)}>
|
|
82
|
+
* <option value="">Any</option>
|
|
83
|
+
* <option value="active">Active</option>
|
|
84
|
+
* <option value="archived">Archived</option>
|
|
85
|
+
* </select>
|
|
86
|
+
* );
|
|
87
|
+
* }
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* @group Component Overrides
|
|
91
|
+
*/
|
|
92
|
+
export interface FilterFieldBindingProps {
|
|
93
|
+
/** Key of the property being filtered (the column id). */
|
|
94
|
+
propertyKey: string;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* The resolved property. For array properties this is the **item**
|
|
98
|
+
* property (`property.of`), with `isArray` set to true.
|
|
99
|
+
*/
|
|
100
|
+
property: Property;
|
|
101
|
+
|
|
102
|
+
/** True when the underlying property is an array of `property`. */
|
|
103
|
+
isArray: boolean;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Operators this field may offer, already narrowed by engine
|
|
107
|
+
* capabilities, property-type defaults, and `property.ui.filterOperators`.
|
|
108
|
+
*/
|
|
109
|
+
operators: readonly WhereFilterOp[];
|
|
110
|
+
|
|
111
|
+
/** Current filter condition for this property, if any. */
|
|
112
|
+
value?: [WhereFilterOp, unknown];
|
|
113
|
+
|
|
114
|
+
/** Set (or clear, with `undefined`) the filter condition. */
|
|
115
|
+
setValue: (value?: [WhereFilterOp, unknown]) => void;
|
|
116
|
+
|
|
117
|
+
/** Display title for the field (usually the property name). */
|
|
118
|
+
title?: string;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Coordination flags used by fields that open their own dialogs
|
|
122
|
+
* (e.g. the reference picker hides the parent filters dialog).
|
|
123
|
+
*/
|
|
124
|
+
hidden?: boolean;
|
|
125
|
+
setHidden?: (hidden: boolean) => void;
|
|
126
|
+
}
|
|
127
|
+
|
|
61
128
|
// ── Override entry ────────────────────────────────────────────────────
|
|
62
129
|
|
|
63
130
|
/**
|
|
@@ -89,7 +156,7 @@ export type OverridableComponentName = AppComponentName | CollectionComponentNam
|
|
|
89
156
|
*
|
|
90
157
|
* @group Component Overrides
|
|
91
158
|
*/
|
|
92
|
-
export interface ComponentOverride<P =
|
|
159
|
+
export interface ComponentOverride<P = Record<string, unknown>> {
|
|
93
160
|
/**
|
|
94
161
|
* The replacement component. Receives the same props as the built-in
|
|
95
162
|
* component it replaces.
|
|
@@ -161,7 +228,7 @@ export type CollectionComponentOverrideMap = {
|
|
|
161
228
|
* "HomePage": { Component: MyDashboard },
|
|
162
229
|
*
|
|
163
230
|
* // Collection defaults: apply to ALL collections
|
|
164
|
-
* "
|
|
231
|
+
* "EditView.FormActions": {
|
|
165
232
|
* Component: MyFormActions,
|
|
166
233
|
* wrap: true
|
|
167
234
|
* },
|
package/src/types/cron.ts
CHANGED
|
@@ -60,7 +60,16 @@ export interface CronJobContext {
|
|
|
60
60
|
/** A simple logger scoped to this job run. */
|
|
61
61
|
log: (...args: unknown[]) => void;
|
|
62
62
|
|
|
63
|
-
/**
|
|
63
|
+
/**
|
|
64
|
+
* The server-side {@link RebaseClient}. This is the **same singleton**
|
|
65
|
+
* exposed as `rebase` (imported from `@rebasepro/server-core`) and as
|
|
66
|
+
* `context` in collection callbacks — it is only named `client` here.
|
|
67
|
+
*
|
|
68
|
+
* Its data plane (`client.data`) runs with **admin privileges and bypasses
|
|
69
|
+
* RLS** (`{ uid: "service", roles: ["admin"] }`). There is no per-request
|
|
70
|
+
* user in a cron, so treat every query as fully trusted and scope your own
|
|
71
|
+
* filters explicitly.
|
|
72
|
+
*/
|
|
64
73
|
client: RebaseClient;
|
|
65
74
|
}
|
|
66
75
|
|
package/src/types/data_source.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ALL_WHERE_FILTER_OPS, WhereFilterOp } from "./filter-operators";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Describes the capabilities and features supported by a data source (driver).
|
|
3
5
|
*
|
|
@@ -35,6 +37,17 @@ export interface DataSourceCapabilities {
|
|
|
35
37
|
/** Does this source support real-time listeners? */
|
|
36
38
|
supportsRealtime: boolean;
|
|
37
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Canonical filter operators this engine can execute.
|
|
42
|
+
*
|
|
43
|
+
* The admin UI intersects this set with the property-type defaults and
|
|
44
|
+
* any per-property narrowing (`property.ui.filterOperators`) to decide
|
|
45
|
+
* which operators to offer in filter fields — so an engine that cannot
|
|
46
|
+
* run `ilike` (e.g. Firestore) never shows a "Contains" filter that
|
|
47
|
+
* would throw at query time.
|
|
48
|
+
*/
|
|
49
|
+
filterOperators: readonly WhereFilterOp[];
|
|
50
|
+
|
|
38
51
|
// ── Admin capability flags ───────────────────────────────────────
|
|
39
52
|
/** Does this source support SQL admin operations (SQL editor, EXPLAIN, etc.)? */
|
|
40
53
|
supportsSQLAdmin: boolean;
|
|
@@ -102,9 +115,11 @@ export interface DataSourceDefinition {
|
|
|
102
115
|
engine: string;
|
|
103
116
|
|
|
104
117
|
/**
|
|
105
|
-
* How the frontend reaches this source.
|
|
118
|
+
* How the frontend reaches this source. Optional — when omitted it is
|
|
119
|
+
* inferred: `"direct"` if the definition carries a client-side driver,
|
|
120
|
+
* `"server"` otherwise.
|
|
106
121
|
*/
|
|
107
|
-
transport
|
|
122
|
+
transport?: DataSourceTransport;
|
|
108
123
|
|
|
109
124
|
/**
|
|
110
125
|
* The physical database/schema/Firestore-database within the engine.
|
|
@@ -149,6 +164,7 @@ export const POSTGRES_CAPABILITIES: DataSourceCapabilities = {
|
|
|
149
164
|
supportsReferences: false,
|
|
150
165
|
supportsColumnTypes: true,
|
|
151
166
|
supportsRealtime: true,
|
|
167
|
+
filterOperators: ALL_WHERE_FILTER_OPS,
|
|
152
168
|
supportsSQLAdmin: true,
|
|
153
169
|
supportsDocumentAdmin: false,
|
|
154
170
|
supportsSchemaAdmin: true
|
|
@@ -164,6 +180,10 @@ export const FIREBASE_CAPABILITIES: DataSourceCapabilities = {
|
|
|
164
180
|
supportsReferences: true,
|
|
165
181
|
supportsColumnTypes: false,
|
|
166
182
|
supportsRealtime: true,
|
|
183
|
+
// Firestore has no SQL pattern matching — the driver throws on the LIKE
|
|
184
|
+
// family, so the UI must never offer it.
|
|
185
|
+
filterOperators: ALL_WHERE_FILTER_OPS.filter(op =>
|
|
186
|
+
op !== "like" && op !== "ilike" && op !== "not-like" && op !== "not-ilike"),
|
|
167
187
|
supportsSQLAdmin: false,
|
|
168
188
|
supportsDocumentAdmin: false,
|
|
169
189
|
supportsSchemaAdmin: false
|
|
@@ -179,6 +199,7 @@ export const MONGODB_CAPABILITIES: DataSourceCapabilities = {
|
|
|
179
199
|
supportsReferences: true,
|
|
180
200
|
supportsColumnTypes: false,
|
|
181
201
|
supportsRealtime: false,
|
|
202
|
+
filterOperators: ALL_WHERE_FILTER_OPS,
|
|
182
203
|
supportsSQLAdmin: false,
|
|
183
204
|
supportsDocumentAdmin: true,
|
|
184
205
|
supportsSchemaAdmin: true
|
|
@@ -198,6 +219,7 @@ export const DEFAULT_CAPABILITIES: DataSourceCapabilities = {
|
|
|
198
219
|
supportsReferences: true,
|
|
199
220
|
supportsColumnTypes: true,
|
|
200
221
|
supportsRealtime: true,
|
|
222
|
+
filterOperators: ALL_WHERE_FILTER_OPS,
|
|
201
223
|
supportsSQLAdmin: true,
|
|
202
224
|
supportsDocumentAdmin: true,
|
|
203
225
|
supportsSchemaAdmin: true
|
|
@@ -211,13 +233,13 @@ const CAPABILITIES_REGISTRY: Record<string, DataSourceCapabilities> = {
|
|
|
211
233
|
};
|
|
212
234
|
|
|
213
235
|
/**
|
|
214
|
-
* Look up capabilities for a given
|
|
215
|
-
* If `
|
|
236
|
+
* Look up capabilities for a given engine key.
|
|
237
|
+
* If `engine` is undefined or not found, returns `DEFAULT_CAPABILITIES`.
|
|
216
238
|
* @group Models
|
|
217
239
|
*/
|
|
218
|
-
export function getDataSourceCapabilities(
|
|
219
|
-
if (!
|
|
220
|
-
return CAPABILITIES_REGISTRY[
|
|
240
|
+
export function getDataSourceCapabilities(engine?: string): DataSourceCapabilities {
|
|
241
|
+
if (!engine) return POSTGRES_CAPABILITIES; // postgres is the default engine
|
|
242
|
+
return CAPABILITIES_REGISTRY[engine] ?? DEFAULT_CAPABILITIES;
|
|
221
243
|
}
|
|
222
244
|
|
|
223
245
|
/**
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
import type { DataDriver } from "../controllers/data_driver";
|
|
24
|
-
import type {
|
|
24
|
+
import type { CollectionConfig } from "./collections";
|
|
25
25
|
import type {
|
|
26
26
|
CollectionRegistryInterface,
|
|
27
27
|
DatabaseAdmin,
|
|
@@ -29,6 +29,7 @@ import type {
|
|
|
29
29
|
RealtimeProvider,
|
|
30
30
|
BootstrappedAuth
|
|
31
31
|
} from "./backend";
|
|
32
|
+
import type { HistoryConfig } from "../controllers/client";
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
35
|
* A `DatabaseAdapter` provides data persistence for Rebase.
|
|
@@ -75,7 +76,7 @@ export interface DatabaseAdapter {
|
|
|
75
76
|
* Return `undefined` if the database does not support history.
|
|
76
77
|
*/
|
|
77
78
|
initializeHistory?(
|
|
78
|
-
config:
|
|
79
|
+
config: HistoryConfig,
|
|
79
80
|
driverResult: InitializedDriver,
|
|
80
81
|
): Promise<{ historyService: unknown } | undefined>;
|
|
81
82
|
|
|
@@ -114,7 +115,7 @@ export interface DatabaseAdapter {
|
|
|
114
115
|
*/
|
|
115
116
|
export interface DatabaseAdapterInitConfig {
|
|
116
117
|
/** Registered collection definitions. */
|
|
117
|
-
collections:
|
|
118
|
+
collections: CollectionConfig[];
|
|
118
119
|
/** The shared collection registry to register into. */
|
|
119
120
|
collectionRegistry: CollectionRegistryInterface;
|
|
120
121
|
}
|
package/src/types/entities.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
export type EntityStatus = "new" | "existing" | "copy";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Representation of
|
|
8
|
+
* Representation of a entity fetched from the driver
|
|
9
9
|
* @group Models
|
|
10
10
|
*/
|
|
11
11
|
export interface Entity<M extends Record<string, unknown> = Record<string, unknown>> {
|
|
@@ -47,7 +47,7 @@ export interface Entity<M extends Record<string, unknown> = Record<string, unkno
|
|
|
47
47
|
export type EntityValues<M extends Record<string, unknown>> = M;
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
|
-
* Props for creating
|
|
50
|
+
* Props for creating a EntityReference
|
|
51
51
|
*/
|
|
52
52
|
export interface EntityReferenceProps {
|
|
53
53
|
/** ID of the entity */
|
|
@@ -61,7 +61,7 @@ export interface EntityReferenceProps {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
|
-
* Class used to create a reference to
|
|
64
|
+
* Class used to create a reference to a entity in a different path.
|
|
65
65
|
*
|
|
66
66
|
* @example
|
|
67
67
|
* // Simple reference (most common case - single driver, single db)
|
|
@@ -99,7 +99,7 @@ export class EntityReference {
|
|
|
99
99
|
readonly databaseId?: string;
|
|
100
100
|
|
|
101
101
|
/**
|
|
102
|
-
* Create a reference to
|
|
102
|
+
* Create a reference to a entity.
|
|
103
103
|
*
|
|
104
104
|
* @example
|
|
105
105
|
* // Simple reference (most common case)
|
|
@@ -148,7 +148,7 @@ export class EntityReference {
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
/**
|
|
151
|
-
* Class used to create a reference to
|
|
151
|
+
* Class used to create a reference to a entity in a different path
|
|
152
152
|
*/
|
|
153
153
|
export class EntityRelation {
|
|
154
154
|
|
|
@@ -167,9 +167,9 @@ export class EntityRelation {
|
|
|
167
167
|
* Pre-fetched data payload to eliminate N+1 queries.
|
|
168
168
|
* When present, clients can use this directly instead of fetching.
|
|
169
169
|
*/
|
|
170
|
-
readonly data?:
|
|
170
|
+
readonly data?: Record<string, unknown>;
|
|
171
171
|
|
|
172
|
-
constructor(id: string | number, path: string, data?:
|
|
172
|
+
constructor(id: string | number, path: string, data?: Record<string, unknown>) {
|
|
173
173
|
this.id = id;
|
|
174
174
|
this.path = path;
|
|
175
175
|
this.data = data;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { Entity } from "./entities";
|
|
3
|
-
import type {
|
|
3
|
+
import type { CollectionConfig, SelectionController } from "./collections";
|
|
4
4
|
import type { FormContext } from "./entity_views";
|
|
5
5
|
import type { User } from "../users";
|
|
6
6
|
import type { RebaseContext } from "../rebase_context";
|
|
7
|
-
import type {
|
|
7
|
+
import type { SidePanelController } from "../controllers/side_panel_controller";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* A entity action is a custom action that can be performed on a entity.
|
|
11
11
|
* They are displayed in the entity view and in the collection view.
|
|
12
12
|
*/
|
|
13
13
|
export interface EntityAction<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
|
|
@@ -72,7 +72,7 @@ export type EntityActionClickProps<M extends Record<string, unknown>, USER exten
|
|
|
72
72
|
context?: RebaseContext<USER>;
|
|
73
73
|
|
|
74
74
|
path?: string;
|
|
75
|
-
collection?:
|
|
75
|
+
collection?: CollectionConfig<M>;
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
78
|
* Optional form context, present if the action is being called from a form.
|
|
@@ -83,7 +83,7 @@ export type EntityActionClickProps<M extends Record<string, unknown>, USER exten
|
|
|
83
83
|
/**
|
|
84
84
|
* Present if this actions is being called from a side dialog only
|
|
85
85
|
*/
|
|
86
|
-
|
|
86
|
+
sidePanelController?: SidePanelController;
|
|
87
87
|
|
|
88
88
|
/**
|
|
89
89
|
* Is the action being called from the collection view or from the entity form view?
|
|
@@ -113,12 +113,12 @@ export type EntityActionClickProps<M extends Record<string, unknown>, USER exten
|
|
|
113
113
|
unhighlightEntity?: (entity: Entity<Record<string, unknown>>) => void;
|
|
114
114
|
|
|
115
115
|
/**
|
|
116
|
-
* Optional function to navigate back (e.g. when deleting
|
|
116
|
+
* Optional function to navigate back (e.g. when deleting a entity or navigating from a form)
|
|
117
117
|
*/
|
|
118
118
|
navigateBack?: () => void;
|
|
119
119
|
|
|
120
120
|
/**
|
|
121
|
-
* Callback to be called when the collection changes, e.g. after
|
|
121
|
+
* Callback to be called when the collection changes, e.g. after a entity is deleted or created.
|
|
122
122
|
*/
|
|
123
123
|
onCollectionChange?: () => void;
|
|
124
124
|
|
|
@@ -1,76 +1,88 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { CollectionConfig } from "./collections";
|
|
2
|
+
import type { EntityStatus, EntityValues } from "./entities";
|
|
3
3
|
import type { User } from "../users";
|
|
4
4
|
import type { RebaseCallContext } from "../rebase_context";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* Lifecycle callbacks for entity CRUD operations.
|
|
8
|
+
*
|
|
9
|
+
* Register per-collection on the collection's `callbacks` field, or globally
|
|
10
|
+
* via `initializeRebaseBackend({ callbacks })`. Fires on **every** data path — REST API,
|
|
11
|
+
* WebSocket / realtime subscriptions, and server-side `rebase.data`.
|
|
12
|
+
*
|
|
13
|
+
* When both global and per-collection callbacks are registered, execution
|
|
14
|
+
* order is: **global → collection → property callbacks**.
|
|
15
|
+
*
|
|
10
16
|
* @group Models
|
|
11
17
|
*/
|
|
12
|
-
export type
|
|
18
|
+
export type CollectionCallbacks<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> = {
|
|
13
19
|
|
|
14
20
|
/**
|
|
15
|
-
* Callback used after fetching data
|
|
21
|
+
* Callback used after fetching data.
|
|
22
|
+
*
|
|
23
|
+
* Fires on every read path. Use this for security-critical redaction
|
|
24
|
+
* (PII masking, row filtering) — no read path bypasses it.
|
|
25
|
+
*
|
|
16
26
|
* @param props
|
|
17
27
|
*/
|
|
18
|
-
afterRead?(props:
|
|
19
|
-
: Promise<
|
|
28
|
+
afterRead?(props: AfterReadProps<M, USER>)
|
|
29
|
+
: Promise<Record<string, unknown>> | Record<string, unknown>;
|
|
20
30
|
|
|
21
31
|
|
|
22
32
|
/**
|
|
23
33
|
* Callback used before saving, you need to return the values that will get
|
|
24
34
|
* saved. If you throw an error in this method the process stops, and an
|
|
25
|
-
* error
|
|
35
|
+
* HTTP error response is returned to the client.
|
|
26
36
|
* This runs after schema validation.
|
|
37
|
+
*
|
|
27
38
|
* @param props
|
|
28
39
|
*/
|
|
29
|
-
beforeSave?(props:
|
|
40
|
+
beforeSave?(props: BeforeSaveProps<M, USER>)
|
|
30
41
|
: Promise<Partial<EntityValues<M>>> | Partial<EntityValues<M>>;
|
|
31
42
|
|
|
32
43
|
/**
|
|
33
|
-
* Callback used when save is successful
|
|
44
|
+
* Callback used when save is successful.
|
|
45
|
+
*
|
|
34
46
|
* @param props
|
|
35
47
|
*/
|
|
36
|
-
afterSave?(props:
|
|
48
|
+
afterSave?(props: AfterSaveProps<M, USER>)
|
|
37
49
|
: Promise<void> | void;
|
|
38
50
|
|
|
39
51
|
/**
|
|
40
52
|
* Callback used when saving fails
|
|
41
53
|
* @param props
|
|
42
54
|
*/
|
|
43
|
-
afterSaveError?(props:
|
|
55
|
+
afterSaveError?(props: AfterSaveErrorProps<M, USER>)
|
|
44
56
|
: Promise<void> | void;
|
|
45
57
|
|
|
46
58
|
/**
|
|
47
59
|
* Callback used before the entity is deleted.
|
|
48
60
|
* If you throw an error in this method the process stops, and an
|
|
49
|
-
* error
|
|
61
|
+
* HTTP error response is returned to the client.
|
|
50
62
|
*
|
|
51
63
|
* @param props
|
|
52
64
|
*/
|
|
53
|
-
beforeDelete?(props:
|
|
65
|
+
beforeDelete?(props: BeforeDeleteProps<M, USER>): Promise<boolean | void> | boolean | void;
|
|
54
66
|
|
|
55
67
|
/**
|
|
56
68
|
* Callback used after the entity is deleted.
|
|
57
69
|
*
|
|
58
70
|
* @param props
|
|
59
71
|
*/
|
|
60
|
-
afterDelete?(props:
|
|
72
|
+
afterDelete?(props: AfterDeleteProps<M, USER>): Promise<void> | void;
|
|
61
73
|
|
|
62
74
|
}
|
|
63
75
|
|
|
64
76
|
/**
|
|
65
|
-
* Parameters passed to hooks when
|
|
77
|
+
* Parameters passed to hooks when a entity is fetched
|
|
66
78
|
* @group Models
|
|
67
79
|
*/
|
|
68
|
-
export interface
|
|
80
|
+
export interface AfterReadProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
|
|
69
81
|
|
|
70
82
|
/**
|
|
71
83
|
* Collection of the entity
|
|
72
84
|
*/
|
|
73
|
-
collection:
|
|
85
|
+
collection: CollectionConfig<M>;
|
|
74
86
|
|
|
75
87
|
/**
|
|
76
88
|
* Full path of the CMS where this collection is being fetched.
|
|
@@ -79,9 +91,9 @@ export interface EntityAfterReadProps<M extends Record<string, unknown> = Record
|
|
|
79
91
|
path: string;
|
|
80
92
|
|
|
81
93
|
/**
|
|
82
|
-
* Fetched
|
|
94
|
+
* Fetched row (flat — `{ id, ...columns }`)
|
|
83
95
|
*/
|
|
84
|
-
|
|
96
|
+
row: Record<string, unknown>
|
|
85
97
|
|
|
86
98
|
/**
|
|
87
99
|
* Context of the app status
|
|
@@ -90,34 +102,34 @@ export interface EntityAfterReadProps<M extends Record<string, unknown> = Record
|
|
|
90
102
|
}
|
|
91
103
|
|
|
92
104
|
/**
|
|
93
|
-
* Parameters passed to hooks before
|
|
105
|
+
* Parameters passed to hooks before a entity is saved
|
|
94
106
|
* @group Models
|
|
95
107
|
*/
|
|
96
|
-
export type
|
|
97
|
-
Omit<
|
|
108
|
+
export type BeforeSaveProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> =
|
|
109
|
+
Omit<AfterSaveProps<M, USER>, "id">
|
|
98
110
|
& {
|
|
99
|
-
|
|
111
|
+
id?: string | number;
|
|
100
112
|
}
|
|
101
113
|
/**
|
|
102
|
-
* Parameters passed to hooks before
|
|
114
|
+
* Parameters passed to hooks before a entity is saved
|
|
103
115
|
* @group Models
|
|
104
116
|
*/
|
|
105
|
-
export type
|
|
106
|
-
Omit<
|
|
117
|
+
export type AfterSaveErrorProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> =
|
|
118
|
+
Omit<AfterSaveProps<M, USER>, "id">
|
|
107
119
|
& {
|
|
108
|
-
|
|
120
|
+
id?: string | number;
|
|
109
121
|
}
|
|
110
122
|
|
|
111
123
|
/**
|
|
112
|
-
* Parameters passed to hooks when
|
|
124
|
+
* Parameters passed to hooks when a entity is saved
|
|
113
125
|
* @group Models
|
|
114
126
|
*/
|
|
115
|
-
export interface
|
|
127
|
+
export interface AfterSaveProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
|
|
116
128
|
|
|
117
129
|
/**
|
|
118
130
|
* Resolved collection of the entity
|
|
119
131
|
*/
|
|
120
|
-
collection:
|
|
132
|
+
collection: CollectionConfig<M>;
|
|
121
133
|
|
|
122
134
|
/**
|
|
123
135
|
* Full path of the CMS where this entity is being saved.
|
|
@@ -128,7 +140,7 @@ export interface EntityAfterSaveProps<M extends Record<string, unknown> = Record
|
|
|
128
140
|
/**
|
|
129
141
|
* ID of the entity
|
|
130
142
|
*/
|
|
131
|
-
|
|
143
|
+
id: string | number;
|
|
132
144
|
|
|
133
145
|
/**
|
|
134
146
|
* Values being saved
|
|
@@ -152,15 +164,15 @@ export interface EntityAfterSaveProps<M extends Record<string, unknown> = Record
|
|
|
152
164
|
}
|
|
153
165
|
|
|
154
166
|
/**
|
|
155
|
-
* Parameters passed to hooks when
|
|
167
|
+
* Parameters passed to hooks when a entity is deleted
|
|
156
168
|
* @group Models
|
|
157
169
|
*/
|
|
158
|
-
export interface
|
|
170
|
+
export interface BeforeDeleteProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
|
|
159
171
|
|
|
160
172
|
/**
|
|
161
173
|
* collection of the entity being deleted
|
|
162
174
|
*/
|
|
163
|
-
collection:
|
|
175
|
+
collection: CollectionConfig<M>;
|
|
164
176
|
|
|
165
177
|
/**
|
|
166
178
|
* Path of the parent collection
|
|
@@ -170,12 +182,12 @@ export interface EntityBeforeDeleteProps<M extends Record<string, unknown> = Rec
|
|
|
170
182
|
/**
|
|
171
183
|
* Deleted entity id
|
|
172
184
|
*/
|
|
173
|
-
|
|
185
|
+
id: string | number;
|
|
174
186
|
|
|
175
187
|
/**
|
|
176
|
-
* Deleted
|
|
188
|
+
* Deleted row (flat — `{ id, ...columns }`)
|
|
177
189
|
*/
|
|
178
|
-
|
|
190
|
+
row: Record<string, unknown>;
|
|
179
191
|
|
|
180
192
|
/**
|
|
181
193
|
* Context of the app status
|
|
@@ -184,15 +196,15 @@ export interface EntityBeforeDeleteProps<M extends Record<string, unknown> = Rec
|
|
|
184
196
|
}
|
|
185
197
|
|
|
186
198
|
/**
|
|
187
|
-
* Parameters passed to hooks after
|
|
199
|
+
* Parameters passed to hooks after a entity is deleted
|
|
188
200
|
* @group Models
|
|
189
201
|
*/
|
|
190
|
-
export interface
|
|
202
|
+
export interface AfterDeleteProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
|
|
191
203
|
|
|
192
204
|
/**
|
|
193
205
|
* collection of the entity being deleted
|
|
194
206
|
*/
|
|
195
|
-
collection:
|
|
207
|
+
collection: CollectionConfig<M>;
|
|
196
208
|
|
|
197
209
|
/**
|
|
198
210
|
* Path of the parent collection
|
|
@@ -202,16 +214,15 @@ export interface EntityAfterDeleteProps<M extends Record<string, unknown> = Reco
|
|
|
202
214
|
/**
|
|
203
215
|
* Deleted entity id
|
|
204
216
|
*/
|
|
205
|
-
|
|
217
|
+
id: string | number;
|
|
206
218
|
|
|
207
219
|
/**
|
|
208
|
-
* Deleted
|
|
220
|
+
* Deleted row (flat — `{ id, ...columns }`)
|
|
209
221
|
*/
|
|
210
|
-
|
|
222
|
+
row: Record<string, unknown>;
|
|
211
223
|
|
|
212
224
|
/**
|
|
213
225
|
* Context of the app status
|
|
214
226
|
*/
|
|
215
227
|
context: RebaseCallContext<USER>;
|
|
216
228
|
}
|
|
217
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { Entity, EntityValues } from "./entities";
|
|
3
|
-
import type {
|
|
3
|
+
import type { CollectionConfig } from "./collections";
|
|
4
4
|
import type { FormexController } from "./formex";
|
|
5
5
|
import type { ComponentRef } from "./component_ref";
|
|
6
6
|
|
|
@@ -37,7 +37,7 @@ export interface FormContext<M extends Record<string, unknown> = Record<string,
|
|
|
37
37
|
/**
|
|
38
38
|
* Collection of the entity being modified
|
|
39
39
|
*/
|
|
40
|
-
collection?:
|
|
40
|
+
collection?: CollectionConfig<M>;
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* Entity id, it can be undefined if it's a new entity
|
|
@@ -105,7 +105,7 @@ export type FormViewConfig<M extends Record<string, unknown> = Record<string, un
|
|
|
105
105
|
};
|
|
106
106
|
|
|
107
107
|
export interface EntityCustomViewParams<M extends Record<string, unknown> = Record<string, unknown>> {
|
|
108
|
-
collection:
|
|
108
|
+
collection: CollectionConfig<M>;
|
|
109
109
|
entity?: Entity<M>;
|
|
110
110
|
modifiedValues?: EntityValues<M>;
|
|
111
111
|
formContext: FormContext<M>;
|