@rebasepro/types 0.8.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.
Files changed (78) hide show
  1. package/README.md +10 -10
  2. package/dist/controllers/auth.d.ts +1 -1
  3. package/dist/controllers/client.d.ts +184 -6
  4. package/dist/controllers/collection_registry.d.ts +3 -3
  5. package/dist/controllers/customization_controller.d.ts +1 -1
  6. package/dist/controllers/data.d.ts +267 -35
  7. package/dist/controllers/data_driver.d.ts +50 -37
  8. package/dist/controllers/index.d.ts +1 -1
  9. package/dist/controllers/local_config_persistence.d.ts +4 -4
  10. package/dist/controllers/navigation.d.ts +2 -2
  11. package/dist/controllers/registry.d.ts +17 -4
  12. package/dist/controllers/{side_entity_controller.d.ts → side_panel_controller.d.ts} +7 -7
  13. package/dist/controllers/storage.d.ts +39 -0
  14. package/dist/errors.d.ts +64 -0
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.es.js +142 -15
  17. package/dist/index.es.js.map +1 -1
  18. package/dist/index.umd.js +150 -17
  19. package/dist/index.umd.js.map +1 -1
  20. package/dist/rebase_context.d.ts +8 -4
  21. package/dist/types/auth_adapter.d.ts +4 -1
  22. package/dist/types/backend.d.ts +26 -26
  23. package/dist/types/builders.d.ts +2 -2
  24. package/dist/types/collections.d.ts +62 -63
  25. package/dist/types/component_overrides.d.ts +61 -3
  26. package/dist/types/cron.d.ts +10 -1
  27. package/dist/types/data_source.d.ts +15 -2
  28. package/dist/types/database_adapter.d.ts +4 -3
  29. package/dist/types/entities.d.ts +7 -7
  30. package/dist/types/entity_actions.d.ts +7 -7
  31. package/dist/types/entity_callbacks.d.ts +39 -39
  32. package/dist/types/entity_views.d.ts +3 -3
  33. package/dist/types/filter-operators.d.ts +62 -17
  34. package/dist/types/modify_collections.d.ts +2 -2
  35. package/dist/types/plugins.d.ts +9 -9
  36. package/dist/types/policy.d.ts +64 -10
  37. package/dist/types/properties.d.ts +41 -9
  38. package/dist/types/relations.d.ts +3 -3
  39. package/dist/types/slots.d.ts +14 -14
  40. package/dist/types/websockets.d.ts +12 -13
  41. package/dist/users/user.d.ts +21 -9
  42. package/package.json +1 -1
  43. package/src/controllers/auth.tsx +1 -1
  44. package/src/controllers/client.ts +214 -6
  45. package/src/controllers/collection_registry.ts +3 -3
  46. package/src/controllers/customization_controller.tsx +1 -1
  47. package/src/controllers/data.ts +290 -39
  48. package/src/controllers/data_driver.ts +49 -40
  49. package/src/controllers/index.ts +1 -1
  50. package/src/controllers/local_config_persistence.tsx +4 -4
  51. package/src/controllers/navigation.ts +2 -2
  52. package/src/controllers/registry.ts +18 -4
  53. package/src/controllers/{side_entity_controller.tsx → side_panel_controller.tsx} +7 -7
  54. package/src/controllers/storage.ts +60 -1
  55. package/src/errors.ts +80 -0
  56. package/src/index.ts +1 -0
  57. package/src/rebase_context.tsx +8 -4
  58. package/src/types/auth_adapter.ts +4 -1
  59. package/src/types/backend.ts +36 -36
  60. package/src/types/builders.ts +2 -2
  61. package/src/types/collections.ts +78 -79
  62. package/src/types/component_overrides.ts +72 -5
  63. package/src/types/cron.ts +10 -1
  64. package/src/types/data_source.ts +24 -2
  65. package/src/types/database_adapter.ts +4 -3
  66. package/src/types/entities.ts +7 -7
  67. package/src/types/entity_actions.tsx +7 -7
  68. package/src/types/entity_callbacks.ts +42 -42
  69. package/src/types/entity_views.tsx +3 -3
  70. package/src/types/filter-operators.ts +96 -23
  71. package/src/types/modify_collections.tsx +2 -2
  72. package/src/types/plugins.tsx +9 -9
  73. package/src/types/policy.ts +64 -8
  74. package/src/types/properties.ts +44 -9
  75. package/src/types/relations.ts +3 -3
  76. package/src/types/slots.tsx +14 -14
  77. package/src/types/websockets.ts +12 -14
  78. package/src/users/user.ts +22 -9
@@ -21,7 +21,7 @@
21
21
  */
22
22
 
23
23
  import type { DataDriver } from "../controllers/data_driver";
24
- import type { EntityCollection } from "./collections";
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: unknown,
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: EntityCollection[];
118
+ collections: CollectionConfig[];
118
119
  /** The shared collection registry to register into. */
119
120
  collectionRegistry: CollectionRegistryInterface;
120
121
  }
@@ -5,7 +5,7 @@
5
5
  export type EntityStatus = "new" | "existing" | "copy";
6
6
 
7
7
  /**
8
- * Representation of an entity fetched from the driver
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 an EntityReference
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 an entity in a different path.
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 an entity.
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 an entity in a different path
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?: Entity;
170
+ readonly data?: Record<string, unknown>;
171
171
 
172
- constructor(id: string | number, path: string, data?: Entity) {
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 { EntityCollection, SelectionController } from "./collections";
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 { SideEntityController } from "../controllers/side_entity_controller";
7
+ import type { SidePanelController } from "../controllers/side_panel_controller";
8
8
 
9
9
  /**
10
- * An entity action is a custom action that can be performed on an entity.
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?: EntityCollection<M>;
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
- sideEntityController?: SideEntityController;
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 an entity or navigating from a form)
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 an entity is deleted or created.
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 { EntityCollection } from "./collections";
2
- import type { Entity, EntityStatus, EntityValues } from "./entities";
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 `initBackend({ callbacks })`. Fires on **every** data path — REST API,
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 EntityCallbacks<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> = {
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: EntityAfterReadProps<M, USER>)
29
- : Promise<Entity<M>> | Entity<M>;
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 snackbar gets displayed.
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: EntityBeforeSaveProps<M, USER>)
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: EntityAfterSaveProps<M, USER>)
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: EntityAfterSaveErrorProps<M, USER>)
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 snackbar gets displayed.
61
+ * HTTP error response is returned to the client.
62
62
  *
63
63
  * @param props
64
64
  */
65
- beforeDelete?(props: EntityBeforeDeleteProps<M, USER>): Promise<boolean | void> | boolean | void;
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: EntityAfterDeleteProps<M, USER>): Promise<void> | void;
72
+ afterDelete?(props: AfterDeleteProps<M, USER>): Promise<void> | void;
73
73
 
74
74
  }
75
75
 
76
76
  /**
77
- * Parameters passed to hooks when an entity is fetched
77
+ * Parameters passed to hooks when a entity is fetched
78
78
  * @group Models
79
79
  */
80
- export interface EntityAfterReadProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
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: EntityCollection<M>;
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 entity
94
+ * Fetched row (flat — `{ id, ...columns }`)
95
95
  */
96
- entity: Entity<M>
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 an entity is saved
105
+ * Parameters passed to hooks before a entity is saved
106
106
  * @group Models
107
107
  */
108
- export type EntityBeforeSaveProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> =
109
- Omit<EntityAfterSaveProps<M, USER>, "entityId">
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
- entityId?: string | number;
111
+ id?: string | number;
112
112
  }
113
113
  /**
114
- * Parameters passed to hooks before an entity is saved
114
+ * Parameters passed to hooks before a entity is saved
115
115
  * @group Models
116
116
  */
117
- export type EntityAfterSaveErrorProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> =
118
- Omit<EntityAfterSaveProps<M, USER>, "entityId">
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
- entityId?: string | number;
120
+ id?: string | number;
121
121
  }
122
122
 
123
123
  /**
124
- * Parameters passed to hooks when an entity is saved
124
+ * Parameters passed to hooks when a entity is saved
125
125
  * @group Models
126
126
  */
127
- export interface EntityAfterSaveProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
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: EntityCollection<M>;
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
- entityId: string | number;
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 an entity is deleted
167
+ * Parameters passed to hooks when a entity is deleted
168
168
  * @group Models
169
169
  */
170
- export interface EntityBeforeDeleteProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
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: EntityCollection<M>;
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
- entityId: string | number;
185
+ id: string | number;
186
186
 
187
187
  /**
188
- * Deleted entity
188
+ * Deleted row (flat — `{ id, ...columns }`)
189
189
  */
190
- entity: Entity<M>;
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 an entity is deleted
199
+ * Parameters passed to hooks after a entity is deleted
200
200
  * @group Models
201
201
  */
202
- export interface EntityAfterDeleteProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
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: EntityCollection<M>;
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
- entityId: string | number;
217
+ id: string | number;
218
218
 
219
219
  /**
220
- * Deleted entity
220
+ * Deleted row (flat — `{ id, ...columns }`)
221
221
  */
222
- entity: Entity<M>;
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 { EntityCollection } from "./collections";
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?: EntityCollection<M>;
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: EntityCollection<M>;
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 │ 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
- * └──────────────────┴───────────────┴──────────────────────────┘
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?: [Key, "asc" | "desc"];
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
- /** All canonical operator strings for runtime validation. */
148
- const CANONICAL_OPS: ReadonlySet<string> = new Set<WhereFilterOp>([
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
@@ -1,6 +1,6 @@
1
- import { EntityCollection } from "./collections";
1
+ import { CollectionConfig } from "./collections";
2
2
 
3
3
  export type ModifyCollectionProps = {
4
- collection: EntityCollection,
4
+ collection: CollectionConfig,
5
5
  parentPaths: string[],
6
6
  };
@@ -1,6 +1,6 @@
1
1
  import React, { PropsWithChildren } from "react";
2
2
 
3
- import type { EntityCollection, CollectionActionsProps, EntityTableController, SelectionController } from "./collections";
3
+ import type { CollectionConfig, CollectionActionsProps, EntityTableController, SelectionController } from "./collections";
4
4
  import type { EntityStatus } from "./entities";
5
5
  import type { InferPropertyType, Property } from "./properties";
6
6
  import type { FormContext } from "./entity_views";
@@ -181,19 +181,19 @@ export interface PluginHooks {
181
181
  /**
182
182
  * Modify a single collection before it is rendered (synchronous).
183
183
  */
184
- modifyCollection?: (collection: EntityCollection) => EntityCollection;
184
+ modifyCollection?: (collection: CollectionConfig) => CollectionConfig;
185
185
 
186
186
  /**
187
187
  * Async version of modifyCollection — supports fetching remote config.
188
188
  * Runs during navigation resolution. If provided alongside `modifyCollection`,
189
189
  * the sync version runs first, then the async version.
190
190
  */
191
- modifyCollectionAsync?: (collection: EntityCollection) => Promise<EntityCollection>;
191
+ modifyCollectionAsync?: (collection: CollectionConfig) => Promise<CollectionConfig>;
192
192
 
193
193
  /**
194
194
  * Modify, add or remove collections.
195
195
  */
196
- injectCollections?: (collections: EntityCollection[]) => EntityCollection[];
196
+ injectCollections?: (collections: CollectionConfig[]) => CollectionConfig[];
197
197
 
198
198
  /**
199
199
  * Callback called when columns are reordered via drag and drop.
@@ -202,7 +202,7 @@ export interface PluginHooks {
202
202
  fullPath: string;
203
203
  parentCollectionSlugs: string[];
204
204
  parentEntityIds: string[];
205
- collection: EntityCollection;
205
+ collection: CollectionConfig;
206
206
  newPropertiesOrder: string[];
207
207
  }) => void;
208
208
 
@@ -213,7 +213,7 @@ export interface PluginHooks {
213
213
  fullPath: string;
214
214
  parentCollectionSlugs: string[];
215
215
  parentEntityIds: string[];
216
- collection: EntityCollection;
216
+ collection: CollectionConfig;
217
217
  kanbanColumnProperty: string;
218
218
  newColumnsOrder: string[];
219
219
  }) => void;
@@ -291,7 +291,7 @@ export interface FieldBuilderConfig {
291
291
  * Props passed to home page collection card action components.
292
292
  * @group Models
293
293
  */
294
- export interface PluginHomePageActionsProps<EP extends object = object, M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User, EC extends EntityCollection<M> = EntityCollection<M>> {
294
+ export interface PluginHomePageActionsProps<EP extends object = object, M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User, EC extends CollectionConfig<M> = CollectionConfig<M>> {
295
295
  slug: string;
296
296
  collection: EC;
297
297
  context: RebaseContext<USER>;
@@ -301,7 +301,7 @@ export interface PluginHomePageActionsProps<EP extends object = object, M extend
301
301
  * Props passed to form action components in entity edit/form views.
302
302
  * @group Models
303
303
  */
304
- export interface PluginFormActionProps<USER extends User = User, EC extends EntityCollection = EntityCollection> {
304
+ export interface PluginFormActionProps<USER extends User = User, EC extends CollectionConfig = CollectionConfig> {
305
305
  entityId?: string | number;
306
306
  path: string;
307
307
  parentCollectionSlugs: string[];
@@ -318,7 +318,7 @@ export interface PluginFormActionProps<USER extends User = User, EC extends Enti
318
318
  * Parameters passed to the field builder wrap function.
319
319
  * @group Models
320
320
  */
321
- export type PluginFieldBuilderParams<M extends Record<string, unknown> = Record<string, unknown>, EC extends EntityCollection<M> = EntityCollection<M>> = {
321
+ export type PluginFieldBuilderParams<M extends Record<string, unknown> = Record<string, unknown>, EC extends CollectionConfig<M> = CollectionConfig<M>> = {
322
322
  fieldConfigId: string;
323
323
  propertyKey: string;
324
324
  property: Property;