@rebasepro/types 0.8.0 → 0.9.1-canary.09aaf62
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 +13 -13
- package/dist/controllers/auth.d.ts +7 -1
- package/dist/controllers/client.d.ts +204 -6
- package/dist/controllers/collection_registry.d.ts +3 -3
- package/dist/controllers/customization_controller.d.ts +1 -1
- package/dist/controllers/data.d.ts +309 -35
- package/dist/controllers/data_driver.d.ts +92 -37
- package/dist/controllers/email.d.ts +2 -2
- 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 +21 -8
- 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 +160 -15
- package/dist/index.es.js.map +1 -1
- package/dist/rebase_context.d.ts +8 -4
- package/dist/types/auth_adapter.d.ts +29 -4
- package/dist/types/backend.d.ts +33 -26
- package/dist/types/backup.d.ts +20 -0
- package/dist/types/builders.d.ts +2 -2
- package/dist/types/collections.d.ts +84 -75
- package/dist/types/component_overrides.d.ts +61 -3
- package/dist/types/cron.d.ts +11 -2
- package/dist/types/data_source.d.ts +15 -2
- package/dist/types/database_adapter.d.ts +21 -4
- package/dist/types/entities.d.ts +7 -7
- package/dist/types/entity_actions.d.ts +7 -7
- package/dist/types/entity_callbacks.d.ts +39 -39
- package/dist/types/entity_views.d.ts +3 -3
- package/dist/types/filter-operators.d.ts +62 -17
- package/dist/types/index.d.ts +1 -0
- package/dist/types/modify_collections.d.ts +2 -2
- package/dist/types/plugins.d.ts +9 -9
- package/dist/types/policy.d.ts +111 -11
- package/dist/types/properties.d.ts +54 -9
- package/dist/types/relations.d.ts +3 -3
- package/dist/types/slots.d.ts +14 -14
- package/dist/types/translations.d.ts +5 -1
- package/dist/types/user_management_delegate.d.ts +8 -2
- package/dist/types/websockets.d.ts +46 -13
- package/dist/users/user.d.ts +21 -9
- package/package.json +5 -6
- package/src/controllers/auth.tsx +7 -1
- package/src/controllers/client.ts +235 -7
- package/src/controllers/collection_registry.ts +3 -3
- package/src/controllers/customization_controller.tsx +1 -1
- package/src/controllers/data.ts +330 -39
- package/src/controllers/data_driver.ts +93 -40
- package/src/controllers/email.ts +2 -2
- 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 +22 -8
- 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 +29 -4
- package/src/types/backend.ts +44 -36
- package/src/types/backup.ts +26 -0
- package/src/types/builders.ts +2 -2
- package/src/types/collections.ts +101 -91
- package/src/types/component_overrides.ts +72 -5
- package/src/types/cron.ts +11 -2
- package/src/types/data_source.ts +24 -2
- package/src/types/database_adapter.ts +19 -4
- package/src/types/entities.ts +7 -7
- package/src/types/entity_actions.tsx +7 -7
- package/src/types/entity_callbacks.ts +42 -42
- package/src/types/entity_views.tsx +3 -3
- package/src/types/filter-operators.ts +96 -23
- package/src/types/index.ts +1 -0
- package/src/types/modify_collections.tsx +2 -2
- package/src/types/plugins.tsx +9 -9
- package/src/types/policy.ts +114 -9
- package/src/types/properties.ts +58 -9
- package/src/types/relations.ts +3 -3
- package/src/types/slots.tsx +14 -14
- package/src/types/translations.ts +5 -1
- package/src/types/user_management_delegate.ts +8 -2
- package/src/types/websockets.ts +43 -14
- package/src/users/user.ts +22 -9
- package/dist/index.umd.js +0 -458
- package/dist/index.umd.js.map +0 -1
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
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
11
|
* ```ts
|
|
12
|
-
* import { createPostgresAdapter } from "@rebasepro/server-
|
|
12
|
+
* import { createPostgresAdapter } from "@rebasepro/server-postgres";
|
|
13
13
|
*
|
|
14
14
|
* initializeRebaseBackend({
|
|
15
15
|
* database: createPostgresAdapter({ connection: db, schema }),
|
|
@@ -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,21 @@ 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;
|
|
121
|
+
/**
|
|
122
|
+
* How the server is being run — see `RebaseBackendConfig.mode`.
|
|
123
|
+
*
|
|
124
|
+
* In `"baas"` mode `collections` is empty by design: a driver that can
|
|
125
|
+
* describe its own schema should introspect the database and report the
|
|
126
|
+
* collections it found back on `InitializedDriver.collections`. Drivers
|
|
127
|
+
* that cannot introspect may ignore this.
|
|
128
|
+
*/
|
|
129
|
+
mode?: "cms" | "baas";
|
|
130
|
+
/**
|
|
131
|
+
* `baas`-mode options — see `RebaseBackendConfig.baas`. Drivers that
|
|
132
|
+
* introspect should honour `unprotectedTables`.
|
|
133
|
+
*/
|
|
134
|
+
baas?: { unprotectedTables?: "exclude" | "serve" };
|
|
120
135
|
}
|
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,5 +1,5 @@
|
|
|
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
|
|
|
@@ -7,7 +7,7 @@ import type { RebaseCallContext } from "../rebase_context";
|
|
|
7
7
|
* Lifecycle callbacks for entity CRUD operations.
|
|
8
8
|
*
|
|
9
9
|
* Register per-collection on the collection's `callbacks` field, or globally
|
|
10
|
-
* via `
|
|
10
|
+
* via `initializeRebaseBackend({ callbacks })`. Fires on **every** data path — REST API,
|
|
11
11
|
* WebSocket / realtime subscriptions, and server-side `rebase.data`.
|
|
12
12
|
*
|
|
13
13
|
* When both global and per-collection callbacks are registered, execution
|
|
@@ -15,7 +15,7 @@ import type { RebaseCallContext } from "../rebase_context";
|
|
|
15
15
|
*
|
|
16
16
|
* @group Models
|
|
17
17
|
*/
|
|
18
|
-
export type
|
|
18
|
+
export type CollectionCallbacks<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> = {
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Callback used after fetching data.
|
|
@@ -25,19 +25,19 @@ export type EntityCallbacks<M extends Record<string, unknown> = Record<string, u
|
|
|
25
25
|
*
|
|
26
26
|
* @param props
|
|
27
27
|
*/
|
|
28
|
-
afterRead?(props:
|
|
29
|
-
: Promise<
|
|
28
|
+
afterRead?(props: AfterReadProps<M, USER>)
|
|
29
|
+
: Promise<Record<string, unknown>> | Record<string, unknown>;
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Callback used before saving, you need to return the values that will get
|
|
34
34
|
* saved. If you throw an error in this method the process stops, and an
|
|
35
|
-
* error
|
|
35
|
+
* HTTP error response is returned to the client.
|
|
36
36
|
* This runs after schema validation.
|
|
37
37
|
*
|
|
38
38
|
* @param props
|
|
39
39
|
*/
|
|
40
|
-
beforeSave?(props:
|
|
40
|
+
beforeSave?(props: BeforeSaveProps<M, USER>)
|
|
41
41
|
: Promise<Partial<EntityValues<M>>> | Partial<EntityValues<M>>;
|
|
42
42
|
|
|
43
43
|
/**
|
|
@@ -45,44 +45,44 @@ export type EntityCallbacks<M extends Record<string, unknown> = Record<string, u
|
|
|
45
45
|
*
|
|
46
46
|
* @param props
|
|
47
47
|
*/
|
|
48
|
-
afterSave?(props:
|
|
48
|
+
afterSave?(props: AfterSaveProps<M, USER>)
|
|
49
49
|
: Promise<void> | void;
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* Callback used when saving fails
|
|
53
53
|
* @param props
|
|
54
54
|
*/
|
|
55
|
-
afterSaveError?(props:
|
|
55
|
+
afterSaveError?(props: AfterSaveErrorProps<M, USER>)
|
|
56
56
|
: Promise<void> | void;
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
59
|
* Callback used before the entity is deleted.
|
|
60
60
|
* If you throw an error in this method the process stops, and an
|
|
61
|
-
* error
|
|
61
|
+
* HTTP error response is returned to the client.
|
|
62
62
|
*
|
|
63
63
|
* @param props
|
|
64
64
|
*/
|
|
65
|
-
beforeDelete?(props:
|
|
65
|
+
beforeDelete?(props: BeforeDeleteProps<M, USER>): Promise<boolean | void> | boolean | void;
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
68
|
* Callback used after the entity is deleted.
|
|
69
69
|
*
|
|
70
70
|
* @param props
|
|
71
71
|
*/
|
|
72
|
-
afterDelete?(props:
|
|
72
|
+
afterDelete?(props: AfterDeleteProps<M, USER>): Promise<void> | void;
|
|
73
73
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
|
-
* Parameters passed to hooks when
|
|
77
|
+
* Parameters passed to hooks when a entity is fetched
|
|
78
78
|
* @group Models
|
|
79
79
|
*/
|
|
80
|
-
export interface
|
|
80
|
+
export interface AfterReadProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
83
|
* Collection of the entity
|
|
84
84
|
*/
|
|
85
|
-
collection:
|
|
85
|
+
collection: CollectionConfig<M>;
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
88
|
* Full path of the CMS where this collection is being fetched.
|
|
@@ -91,9 +91,9 @@ export interface EntityAfterReadProps<M extends Record<string, unknown> = Record
|
|
|
91
91
|
path: string;
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
|
-
* Fetched
|
|
94
|
+
* Fetched row (flat — the table's columns)
|
|
95
95
|
*/
|
|
96
|
-
|
|
96
|
+
row: Record<string, unknown>
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
99
|
* Context of the app status
|
|
@@ -102,34 +102,34 @@ export interface EntityAfterReadProps<M extends Record<string, unknown> = Record
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
/**
|
|
105
|
-
* Parameters passed to hooks before
|
|
105
|
+
* Parameters passed to hooks before a entity is saved
|
|
106
106
|
* @group Models
|
|
107
107
|
*/
|
|
108
|
-
export type
|
|
109
|
-
Omit<
|
|
108
|
+
export type BeforeSaveProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> =
|
|
109
|
+
Omit<AfterSaveProps<M, USER>, "id">
|
|
110
110
|
& {
|
|
111
|
-
|
|
111
|
+
id?: string | number;
|
|
112
112
|
}
|
|
113
113
|
/**
|
|
114
|
-
* Parameters passed to hooks before
|
|
114
|
+
* Parameters passed to hooks before a entity is saved
|
|
115
115
|
* @group Models
|
|
116
116
|
*/
|
|
117
|
-
export type
|
|
118
|
-
Omit<
|
|
117
|
+
export type AfterSaveErrorProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> =
|
|
118
|
+
Omit<AfterSaveProps<M, USER>, "id">
|
|
119
119
|
& {
|
|
120
|
-
|
|
120
|
+
id?: string | number;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
/**
|
|
124
|
-
* Parameters passed to hooks when
|
|
124
|
+
* Parameters passed to hooks when a entity is saved
|
|
125
125
|
* @group Models
|
|
126
126
|
*/
|
|
127
|
-
export interface
|
|
127
|
+
export interface AfterSaveProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
|
|
128
128
|
|
|
129
129
|
/**
|
|
130
130
|
* Resolved collection of the entity
|
|
131
131
|
*/
|
|
132
|
-
collection:
|
|
132
|
+
collection: CollectionConfig<M>;
|
|
133
133
|
|
|
134
134
|
/**
|
|
135
135
|
* Full path of the CMS where this entity is being saved.
|
|
@@ -140,7 +140,7 @@ export interface EntityAfterSaveProps<M extends Record<string, unknown> = Record
|
|
|
140
140
|
/**
|
|
141
141
|
* ID of the entity
|
|
142
142
|
*/
|
|
143
|
-
|
|
143
|
+
id: string | number;
|
|
144
144
|
|
|
145
145
|
/**
|
|
146
146
|
* Values being saved
|
|
@@ -164,15 +164,15 @@ export interface EntityAfterSaveProps<M extends Record<string, unknown> = Record
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
/**
|
|
167
|
-
* Parameters passed to hooks when
|
|
167
|
+
* Parameters passed to hooks when a entity is deleted
|
|
168
168
|
* @group Models
|
|
169
169
|
*/
|
|
170
|
-
export interface
|
|
170
|
+
export interface BeforeDeleteProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
|
|
171
171
|
|
|
172
172
|
/**
|
|
173
173
|
* collection of the entity being deleted
|
|
174
174
|
*/
|
|
175
|
-
collection:
|
|
175
|
+
collection: CollectionConfig<M>;
|
|
176
176
|
|
|
177
177
|
/**
|
|
178
178
|
* Path of the parent collection
|
|
@@ -182,12 +182,12 @@ export interface EntityBeforeDeleteProps<M extends Record<string, unknown> = Rec
|
|
|
182
182
|
/**
|
|
183
183
|
* Deleted entity id
|
|
184
184
|
*/
|
|
185
|
-
|
|
185
|
+
id: string | number;
|
|
186
186
|
|
|
187
187
|
/**
|
|
188
|
-
* Deleted
|
|
188
|
+
* Deleted row (flat — the table's columns)
|
|
189
189
|
*/
|
|
190
|
-
|
|
190
|
+
row: Record<string, unknown>;
|
|
191
191
|
|
|
192
192
|
/**
|
|
193
193
|
* Context of the app status
|
|
@@ -196,15 +196,15 @@ export interface EntityBeforeDeleteProps<M extends Record<string, unknown> = Rec
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
/**
|
|
199
|
-
* Parameters passed to hooks after
|
|
199
|
+
* Parameters passed to hooks after a entity is deleted
|
|
200
200
|
* @group Models
|
|
201
201
|
*/
|
|
202
|
-
export interface
|
|
202
|
+
export interface AfterDeleteProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
|
|
203
203
|
|
|
204
204
|
/**
|
|
205
205
|
* collection of the entity being deleted
|
|
206
206
|
*/
|
|
207
|
-
collection:
|
|
207
|
+
collection: CollectionConfig<M>;
|
|
208
208
|
|
|
209
209
|
/**
|
|
210
210
|
* Path of the parent collection
|
|
@@ -214,12 +214,12 @@ export interface EntityAfterDeleteProps<M extends Record<string, unknown> = Reco
|
|
|
214
214
|
/**
|
|
215
215
|
* Deleted entity id
|
|
216
216
|
*/
|
|
217
|
-
|
|
217
|
+
id: string | number;
|
|
218
218
|
|
|
219
219
|
/**
|
|
220
|
-
* Deleted
|
|
220
|
+
* Deleted row (flat — the table's columns)
|
|
221
221
|
*/
|
|
222
|
-
|
|
222
|
+
row: Record<string, unknown>;
|
|
223
223
|
|
|
224
224
|
/**
|
|
225
225
|
* Context of the app status
|
|
@@ -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>;
|
|
@@ -8,24 +8,50 @@
|
|
|
8
8
|
* HTTP wire boundary, handled by `serializeFilter` / `deserializeFilter`
|
|
9
9
|
* in `@rebasepro/common`.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
* │ Canonical
|
|
13
|
-
*
|
|
14
|
-
* │ "=="
|
|
15
|
-
* │ "!="
|
|
16
|
-
* │ ">"
|
|
17
|
-
* │ ">="
|
|
18
|
-
* │ "<"
|
|
19
|
-
* │ "<="
|
|
20
|
-
* │ "in"
|
|
21
|
-
* │ "not-in"
|
|
22
|
-
* │ "array-contains"
|
|
23
|
-
* │ "array-contains-any" │ "csa"
|
|
24
|
-
*
|
|
11
|
+
* ┌──────────────────────┬───────────────┬──────────────────────────────┐
|
|
12
|
+
* │ Canonical │ REST short │ Meaning │
|
|
13
|
+
* ├──────────────────────┼───────────────┼──────────────────────────────┤
|
|
14
|
+
* │ "==" │ "eq" │ Equal │
|
|
15
|
+
* │ "!=" │ "neq" │ Not equal │
|
|
16
|
+
* │ ">" │ "gt" │ Greater than │
|
|
17
|
+
* │ ">=" │ "gte" │ Greater than or equal │
|
|
18
|
+
* │ "<" │ "lt" │ Less than │
|
|
19
|
+
* │ "<=" │ "lte" │ Less than or equal │
|
|
20
|
+
* │ "in" │ "in" │ Value in list │
|
|
21
|
+
* │ "not-in" │ "nin" │ Value not in list │
|
|
22
|
+
* │ "array-contains" │ "cs" │ Array contains element │
|
|
23
|
+
* │ "array-contains-any" │ "csa" │ Array contains any of │
|
|
24
|
+
* │ "like" │ "like" │ SQL LIKE (case-sensitive) │
|
|
25
|
+
* │ "ilike" │ "ilike" │ SQL ILIKE (case-insensitive) │
|
|
26
|
+
* │ "not-like" │ "nlike" │ NOT LIKE (case-sensitive) │
|
|
27
|
+
* │ "not-ilike" │ "nilike" │ NOT ILIKE (case-insensitive) │
|
|
28
|
+
* │ "is-null" │ "isnull" │ Field IS NULL │
|
|
29
|
+
* │ "is-not-null" │ "notnull" │ Field IS NOT NULL │
|
|
30
|
+
* └──────────────────────┴───────────────┴──────────────────────────────┘
|
|
31
|
+
*
|
|
32
|
+
* Pattern matching (`like`/`ilike`) uses SQL wildcard syntax: `%` matches any
|
|
33
|
+
* sequence of characters, `_` matches a single character. On MongoDB these are
|
|
34
|
+
* translated to anchored regular expressions; Firestore has no native pattern
|
|
35
|
+
* matching and rejects these operators (use `searchString` instead).
|
|
25
36
|
*
|
|
26
37
|
* @module
|
|
27
38
|
*/
|
|
28
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Canonical sort representation: `[fieldName, direction]`.
|
|
42
|
+
*
|
|
43
|
+
* Used in `FindParams.orderBy`, `collection.sort`, and `FilterPreset.sort`.
|
|
44
|
+
* The colon-string form (`"field:direction"`) exists only at the HTTP wire
|
|
45
|
+
* boundary, handled by `serializeOrderBy` / `deserializeOrderBy` in
|
|
46
|
+
* `@rebasepro/common`.
|
|
47
|
+
*
|
|
48
|
+
* Design note: the natural extension for multi-column sort is
|
|
49
|
+
* `OrderByTuple[]` — not implemented yet (server consumes only the first).
|
|
50
|
+
*
|
|
51
|
+
* @group Models
|
|
52
|
+
*/
|
|
53
|
+
export type OrderByTuple<Key extends string = string> = [Key, "asc" | "desc"];
|
|
54
|
+
|
|
29
55
|
/**
|
|
30
56
|
* Canonical filter operators supported across all database backends.
|
|
31
57
|
* Each DB driver translates these to its native query format.
|
|
@@ -42,7 +68,13 @@ export type WhereFilterOp =
|
|
|
42
68
|
| "array-contains"
|
|
43
69
|
| "in"
|
|
44
70
|
| "not-in"
|
|
45
|
-
| "array-contains-any"
|
|
71
|
+
| "array-contains-any"
|
|
72
|
+
| "like"
|
|
73
|
+
| "ilike"
|
|
74
|
+
| "not-like"
|
|
75
|
+
| "not-ilike"
|
|
76
|
+
| "is-null"
|
|
77
|
+
| "is-not-null";
|
|
46
78
|
|
|
47
79
|
/**
|
|
48
80
|
* Used to define filters applied in collections.
|
|
@@ -61,6 +93,14 @@ export type WhereFilterOp =
|
|
|
61
93
|
* { role: ["in", ["admin", "editor"]] }
|
|
62
94
|
* { tags: ["array-contains", "featured"] }
|
|
63
95
|
*
|
|
96
|
+
* // Pattern matching (SQL wildcards: % and _)
|
|
97
|
+
* { name: ["ilike", "%john%"] }
|
|
98
|
+
* { slug: ["like", "post-%"] }
|
|
99
|
+
*
|
|
100
|
+
* // Null checks (the value is ignored; `null` is conventional)
|
|
101
|
+
* { deleted_at: ["is-null", null] }
|
|
102
|
+
* { published_at: ["is-not-null", null] }
|
|
103
|
+
*
|
|
64
104
|
* @group Models
|
|
65
105
|
*/
|
|
66
106
|
export type FilterValues<Key extends string> =
|
|
@@ -101,7 +141,7 @@ export interface FilterPreset<Key extends string = string> {
|
|
|
101
141
|
/**
|
|
102
142
|
* Optional sort override to apply alongside the filter values.
|
|
103
143
|
*/
|
|
104
|
-
sort?:
|
|
144
|
+
sort?: OrderByTuple<Key>;
|
|
105
145
|
}
|
|
106
146
|
|
|
107
147
|
/**
|
|
@@ -114,7 +154,10 @@ export type RestFilterOp =
|
|
|
114
154
|
| "gt" | "gte"
|
|
115
155
|
| "lt" | "lte"
|
|
116
156
|
| "in" | "nin"
|
|
117
|
-
| "cs" | "csa"
|
|
157
|
+
| "cs" | "csa"
|
|
158
|
+
| "like" | "ilike"
|
|
159
|
+
| "nlike" | "nilike"
|
|
160
|
+
| "isnull" | "notnull";
|
|
118
161
|
|
|
119
162
|
/** Maps canonical operators to their REST short-code equivalents. */
|
|
120
163
|
export const CANONICAL_TO_REST: Readonly<Record<WhereFilterOp, RestFilterOp>> = {
|
|
@@ -127,7 +170,13 @@ export const CANONICAL_TO_REST: Readonly<Record<WhereFilterOp, RestFilterOp>> =
|
|
|
127
170
|
"in": "in",
|
|
128
171
|
"not-in": "nin",
|
|
129
172
|
"array-contains": "cs",
|
|
130
|
-
"array-contains-any": "csa"
|
|
173
|
+
"array-contains-any": "csa",
|
|
174
|
+
"like": "like",
|
|
175
|
+
"ilike": "ilike",
|
|
176
|
+
"not-like": "nlike",
|
|
177
|
+
"not-ilike": "nilike",
|
|
178
|
+
"is-null": "isnull",
|
|
179
|
+
"is-not-null": "notnull"
|
|
131
180
|
};
|
|
132
181
|
|
|
133
182
|
/** Maps REST short-code operators to their canonical equivalents. */
|
|
@@ -141,15 +190,39 @@ export const REST_TO_CANONICAL: Readonly<Record<RestFilterOp, WhereFilterOp>> =
|
|
|
141
190
|
"in": "in",
|
|
142
191
|
"nin": "not-in",
|
|
143
192
|
"cs": "array-contains",
|
|
144
|
-
"csa": "array-contains-any"
|
|
193
|
+
"csa": "array-contains-any",
|
|
194
|
+
"like": "like",
|
|
195
|
+
"ilike": "ilike",
|
|
196
|
+
"nlike": "not-like",
|
|
197
|
+
"nilike": "not-ilike",
|
|
198
|
+
"isnull": "is-null",
|
|
199
|
+
"notnull": "is-not-null"
|
|
145
200
|
};
|
|
146
201
|
|
|
147
|
-
/**
|
|
148
|
-
|
|
202
|
+
/**
|
|
203
|
+
* Operators that test for null/not-null and therefore ignore their value.
|
|
204
|
+
* Codecs normalize the value of these conditions to `null`.
|
|
205
|
+
*/
|
|
206
|
+
export const NULL_OPS: ReadonlySet<WhereFilterOp> = new Set<WhereFilterOp>([
|
|
207
|
+
"is-null", "is-not-null"
|
|
208
|
+
]);
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Every canonical operator, in a stable order. Useful for engine capability
|
|
212
|
+
* declarations ({@link DataSourceCapabilities.filterOperators}) and for
|
|
213
|
+
* building operator subsets.
|
|
214
|
+
* @group Models
|
|
215
|
+
*/
|
|
216
|
+
export const ALL_WHERE_FILTER_OPS: readonly WhereFilterOp[] = [
|
|
149
217
|
"<", "<=", "==", "!=", ">=", ">",
|
|
150
218
|
"in", "not-in",
|
|
151
|
-
"array-contains", "array-contains-any"
|
|
152
|
-
|
|
219
|
+
"array-contains", "array-contains-any",
|
|
220
|
+
"like", "ilike", "not-like", "not-ilike",
|
|
221
|
+
"is-null", "is-not-null"
|
|
222
|
+
];
|
|
223
|
+
|
|
224
|
+
/** All canonical operator strings for runtime validation. */
|
|
225
|
+
const CANONICAL_OPS: ReadonlySet<string> = new Set<WhereFilterOp>(ALL_WHERE_FILTER_OPS);
|
|
153
226
|
|
|
154
227
|
/**
|
|
155
228
|
* Resolve any operator string (canonical or REST short-code) to its
|