@rebasepro/types 0.10.0 → 0.10.1-canary.0a881d4

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 (96) hide show
  1. package/dist/call_context.d.ts +51 -0
  2. package/dist/controllers/auth_state.d.ts +23 -0
  3. package/dist/controllers/client.d.ts +3 -1
  4. package/dist/controllers/collection_registry.d.ts +5 -1
  5. package/dist/controllers/data_driver.d.ts +31 -2
  6. package/dist/controllers/index.d.ts +1 -10
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.es.js +374 -1
  9. package/dist/index.es.js.map +1 -1
  10. package/dist/types/admin_block.d.ts +34 -0
  11. package/dist/types/backend.d.ts +30 -1
  12. package/dist/types/channel_bus.d.ts +192 -0
  13. package/dist/types/collection_contract.d.ts +43 -0
  14. package/dist/types/collections.d.ts +17 -789
  15. package/dist/types/component_ref.d.ts +39 -6
  16. package/dist/types/entity_callbacks.d.ts +1 -1
  17. package/dist/types/index.d.ts +7 -15
  18. package/dist/types/project_manifest.d.ts +336 -0
  19. package/dist/types/properties.d.ts +12 -157
  20. package/dist/types/schema_version.d.ts +18 -0
  21. package/dist/types/security_rules.d.ts +320 -0
  22. package/dist/types/storage_authorize.d.ts +74 -0
  23. package/package.json +3 -6
  24. package/src/call_context.ts +56 -0
  25. package/src/controllers/auth_state.ts +24 -0
  26. package/src/controllers/client.ts +3 -2
  27. package/src/controllers/collection_registry.ts +5 -1
  28. package/src/controllers/data_driver.ts +58 -2
  29. package/src/controllers/index.ts +1 -10
  30. package/src/index.ts +1 -1
  31. package/src/types/admin_block.ts +75 -0
  32. package/src/types/backend.ts +33 -1
  33. package/src/types/channel_bus.ts +202 -0
  34. package/src/types/collection_contract.ts +278 -0
  35. package/src/types/collections.ts +25 -848
  36. package/src/types/component_ref.ts +40 -6
  37. package/src/types/entity_callbacks.ts +1 -1
  38. package/src/types/index.ts +7 -15
  39. package/src/types/policy.ts +25 -11
  40. package/src/types/project_manifest.ts +362 -0
  41. package/src/types/properties.ts +11 -169
  42. package/src/types/schema_version.ts +112 -0
  43. package/src/types/security_rules.ts +344 -0
  44. package/src/types/storage_authorize.ts +77 -0
  45. package/dist/controllers/analytics_controller.d.ts +0 -7
  46. package/dist/controllers/auth.d.ts +0 -110
  47. package/dist/controllers/customization_controller.d.ts +0 -61
  48. package/dist/controllers/dialogs_controller.d.ts +0 -36
  49. package/dist/controllers/local_config_persistence.d.ts +0 -20
  50. package/dist/controllers/navigation.d.ts +0 -225
  51. package/dist/controllers/registry.d.ts +0 -80
  52. package/dist/controllers/side_dialogs_controller.d.ts +0 -67
  53. package/dist/controllers/side_panel_controller.d.ts +0 -97
  54. package/dist/controllers/snackbar.d.ts +0 -24
  55. package/dist/rebase_context.d.ts +0 -110
  56. package/dist/types/breadcrumbs.d.ts +0 -26
  57. package/dist/types/builders.d.ts +0 -15
  58. package/dist/types/component_overrides.d.ts +0 -196
  59. package/dist/types/entity_actions.d.ts +0 -104
  60. package/dist/types/entity_link_builder.d.ts +0 -7
  61. package/dist/types/entity_views.d.ts +0 -95
  62. package/dist/types/export_import.d.ts +0 -21
  63. package/dist/types/formex.d.ts +0 -40
  64. package/dist/types/locales.d.ts +0 -4
  65. package/dist/types/modify_collections.d.ts +0 -5
  66. package/dist/types/plugins.d.ts +0 -277
  67. package/dist/types/property_config.d.ts +0 -74
  68. package/dist/types/slots.d.ts +0 -262
  69. package/dist/types/translations.d.ts +0 -915
  70. package/dist/types/user_management_delegate.d.ts +0 -22
  71. package/src/controllers/analytics_controller.tsx +0 -57
  72. package/src/controllers/auth.tsx +0 -121
  73. package/src/controllers/customization_controller.tsx +0 -72
  74. package/src/controllers/dialogs_controller.tsx +0 -37
  75. package/src/controllers/local_config_persistence.tsx +0 -22
  76. package/src/controllers/navigation.ts +0 -267
  77. package/src/controllers/registry.ts +0 -95
  78. package/src/controllers/side_dialogs_controller.tsx +0 -82
  79. package/src/controllers/side_panel_controller.tsx +0 -112
  80. package/src/controllers/snackbar.ts +0 -29
  81. package/src/rebase_context.tsx +0 -130
  82. package/src/types/breadcrumbs.ts +0 -27
  83. package/src/types/builders.ts +0 -17
  84. package/src/types/component_overrides.ts +0 -244
  85. package/src/types/entity_actions.tsx +0 -125
  86. package/src/types/entity_link_builder.ts +0 -8
  87. package/src/types/entity_views.tsx +0 -114
  88. package/src/types/export_import.ts +0 -26
  89. package/src/types/formex.ts +0 -45
  90. package/src/types/locales.ts +0 -81
  91. package/src/types/modify_collections.tsx +0 -6
  92. package/src/types/plugins.tsx +0 -346
  93. package/src/types/property_config.tsx +0 -95
  94. package/src/types/slots.tsx +0 -307
  95. package/src/types/translations.ts +0 -1026
  96. package/src/types/user_management_delegate.ts +0 -23
@@ -1,17 +1,8 @@
1
- import React from "react";
2
- import type { Entity, EntityStatus } from "./entities";
3
1
  import type { CollectionCallbacks } from "./entity_callbacks";
4
2
  import type { Properties, PostgresProperties, FirebaseProperties, MongoProperties } from "./properties";
5
- import type { ExportConfig } from "./export_import";
6
3
  import type { User } from "../users";
7
- import type { RebaseContext } from "../rebase_context";
8
4
  import type { Relation } from "./relations";
9
- import type { EntityCustomView, FormViewConfig } from "./entity_views";
10
- import type { EntityAction } from "./entity_actions";
11
- import type { PolicyExpression } from "./policy";
12
- import type { ComponentRef } from "./component_ref";
13
- import type { CollectionComponentOverrideMap } from "./component_overrides";
14
- import type { FilterValues, FilterPreset, OrderByTuple } from "./filter-operators";
5
+ import type { SecurityRule } from "./security_rules";
15
6
  /**
16
7
  * Base interface containing all driver-agnostic collection properties.
17
8
  * Use {@link PostgresCollectionConfig} or {@link FirebaseCollectionConfig} for
@@ -93,61 +84,6 @@ export interface BaseCollectionConfig<M extends Record<string, unknown> = Record
93
84
  * Set of properties that compose a entity
94
85
  */
95
86
  properties: Properties;
96
- /**
97
- * Icon for the navigation sidebar or cards.
98
- */
99
- icon?: string | React.ReactNode;
100
- /**
101
- * Navigation group for this collection.
102
- * Collections sharing the same group name will be visually grouped
103
- * together in the drawer and home page. If not set, the collection
104
- * falls into the default "Views" group.
105
- */
106
- group?: string;
107
- /**
108
- * Array of entity views that this collection has.
109
- * Can be an array of `EntityCustomView` or a string representing the key of a global `EntityCustomView`.
110
- */
111
- entityViews?: (string | EntityCustomView<Record<string, unknown>>)[];
112
- /**
113
- * Default preview properties displayed when this collection is referenced to.
114
- */
115
- previewProperties?: string[];
116
- /**
117
- * Properties to display as columns in the list view.
118
- * If not specified, the list view uses a smart default (Title, Status, Date).
119
- */
120
- listProperties?: string[];
121
- /**
122
- * Title property of the entity. This is the property that will be used
123
- * as the title in entity related views and references.
124
- * If not specified, the first property simple text property will be used.
125
- */
126
- readonly titleProperty?: Extract<keyof M, string> | (string & {});
127
- /**
128
- * When editing a entity, you can choose to open the entity in a side dialog
129
- * or in a full screen dialog. Defaults to `full_screen`.
130
- */
131
- openEntityMode?: "side_panel" | "full_screen" | "split" | "dialog";
132
- /**
133
- * Controls what happens when a user clicks on a entity in the collection view.
134
- * - `"edit"` (default): Opens the entity in the edit form.
135
- * - `"view"`: Opens a read-only detail view with an "Edit" button.
136
- */
137
- defaultEntityAction?: "view" | "edit";
138
- /**
139
- * Replace the default entity form with a custom component.
140
- * The Builder receives the same props as entity view tabs
141
- * (entity, formContext, collection, etc.) and has full control over the UI.
142
- *
143
- * Works in both edit mode and read-only mode (when `defaultEntityAction`
144
- * is `"view"`). In read-only mode, `formContext.readOnly` will be `true`.
145
- */
146
- formView?: FormViewConfig;
147
- /**
148
- * Prevent default actions from being displayed or executed on this collection.
149
- */
150
- disableDefaultActions?: ("edit" | "copy" | "delete")[];
151
87
  /**
152
88
  * Mark this collection as an authentication collection.
153
89
  * When true, this collection is used for user management, login, password hashing, and invitation flows.
@@ -171,135 +107,12 @@ export interface BaseCollectionConfig<M extends Record<string, unknown> = Record
171
107
  * @default false
172
108
  */
173
109
  disableDefaultPolicies?: boolean;
174
- /**
175
- * Order in which the properties are displayed.
176
- * If you are specifying your collection as code, the order is the same as the
177
- * one you define in `properties`. Additional columns are added at the
178
- * end of the list, if the order is not specified.
179
- *
180
- * You can use this prop to hide some properties from the table view.
181
- * Note that if you set this prop, other ways to hide fields, like
182
- * `hidden` in the property definition, will be ignored.
183
- * `propertiesOrder` has precedence over `hidden`.
184
- *
185
- * Supported entry formats:
186
- * - For properties, use the property key.
187
- * - For additional fields, use the field key.
188
- * - Child collections (Firestore subcollections, or Postgres relations
189
- * with `many` cardinality) each get a column with id
190
- * `subcollection:<slug>`, e.g. `subcollection:orders`.
191
- */
192
- propertiesOrder?: (Extract<keyof M, string> | (string & {}) | string | `subcollection:${string}`)[];
193
- /**
194
- * If enabled, content is loaded in batches. If `false` all entities in the
195
- * collection are loaded. This means that when reaching the end of the
196
- * collection, the CMS will load more entities.
197
- * You can specify a number to specify the pagination size (50 by default)
198
- * Defaults to `true`
199
- */
200
- pagination?: boolean | number;
201
- selectionEnabled?: boolean;
202
110
  /**
203
111
  * This interface defines all the callbacks that can be used when a entity
204
112
  * is being created, updated or deleted.
205
113
  * Useful for adding your own logic or blocking the execution of the operation.
206
114
  */
207
115
  readonly callbacks?: CollectionCallbacks<M, USER>;
208
- /**
209
- * Pass your own selection controller if you want to control selected
210
- * entities externally.
211
- * @see useSelectionController
212
- */
213
- selectionController?: SelectionController<M>;
214
- /**
215
- * Force a filter in this view. If applied, the rest of the filters will
216
- * be disabled. Filters applied with this prop cannot be changed.
217
- * e.g. `fixedFilter: { age: [">", 18] }`
218
- * e.g. `fixedFilter: { related_user: ["==", new EntityReference("sdc43dsw2", "users")] }`
219
- */
220
- readonly fixedFilter?: FilterValues<Extract<keyof M, string> | (string & {})>;
221
- /**
222
- * Initial filters applied to the collection this collection is related to.
223
- * Defaults to none. Filters applied with this prop can be changed.
224
- * e.g. `defaultFilter: { age: [">", 18] }`
225
- * e.g. `defaultFilter: { related_user: ["==", new EntityReference("sdc43dsw2", "users")] }`
226
- */
227
- readonly defaultFilter?: FilterValues<Extract<keyof M, string> | (string & {})>;
228
- /**
229
- * Pre-defined filter presets that appear as quick-access options in the
230
- * collection toolbar. Each preset applies a set of filters (and
231
- * optionally a sort order) with a single click.
232
- *
233
- * ```ts
234
- * filterPresets: [
235
- * {
236
- * label: "Shipped this month",
237
- * filterValues: {
238
- * status: ["==", "shipped"],
239
- * order_date: [">=", new Date(Date.now() - 30 * 86400000)]
240
- * }
241
- * }
242
- * ]
243
- * ```
244
- */
245
- readonly filterPresets?: FilterPreset<Extract<keyof M, string> | (string & {})>[];
246
- /**
247
- * Default sort applied to this collection.
248
- * When setting this prop, entities will have a default order
249
- * applied in the collection.
250
- * e.g. `sort: ["order", "asc"]`
251
- */
252
- readonly sort?: OrderByTuple<Extract<keyof M, string> | (string & {})>;
253
- /**
254
- * You can add additional fields to the collection view by implementing
255
- * an additional field delegate.
256
- */
257
- readonly additionalFields?: AdditionalFieldDelegate<M, USER>[];
258
- /**
259
- * Default size of the rendered collection
260
- */
261
- defaultSize?: CollectionSize;
262
- /**
263
- * Can the elements in this collection be edited inline in the collection
264
- * view. Even when inline editing is disabled, entities can still be
265
- * edited in the side panel (subject to `securityRules`).
266
- */
267
- inlineEditing?: boolean;
268
- /**
269
- * Should this collection be hidden from the main navigation panel, if
270
- * it is at the root level, or in the entity side panel if it's a
271
- * subcollection.
272
- * It will still be accessible if you reach the specified path.
273
- * You can also use this collection as a reference target.
274
- */
275
- hideFromNavigation?: boolean;
276
- /**
277
- * If you want to open custom views or subcollections by default when opening the edit
278
- * view of a entity, you can specify the path to the view here.
279
- * The path is relative to the current collection. For example if you have a collection
280
- * that has a custom view as well as a subcollection that refers to another entity, you can
281
- * either specify the path to the custom view or the path to the subcollection.
282
- */
283
- defaultSelectedView?: string | DefaultSelectedViewBuilder;
284
- /**
285
- * Should the ID of this collection be hidden from the form view.
286
- */
287
- hideIdFromForm?: boolean;
288
- /**
289
- * Should the ID of this collection be hidden from the grid view.
290
- */
291
- hideIdFromCollection?: boolean;
292
- /**
293
- * If set to true, the form will be auto-saved when the user changes
294
- * the value of a field.
295
- * Defaults to false.
296
- * When a new entity is created, this property can be updated to generated a new ID
297
- */
298
- formAutoSave?: boolean;
299
- /**
300
- *
301
- */
302
- exportable?: boolean | ExportConfig<USER>;
303
116
  /**
304
117
  * User id of the owner of this collection. This is used only by plugins, or if you
305
118
  * are writing custom code
@@ -311,20 +124,6 @@ export interface BaseCollectionConfig<M extends Record<string, unknown> = Record
311
124
  * Used by domain apps to store custom per-collection config.
312
125
  */
313
126
  metadata?: Record<string, unknown>;
314
- /**
315
- * Width of the side dialog (in pixels) when opening a entity in this collection.
316
- */
317
- sideDialogWidth?: number | string;
318
- /**
319
- * If set to true, the default values of the properties will be applied
320
- * to the entity every time the entity is updated (not only when created).
321
- * Defaults to false.
322
- */
323
- alwaysApplyDefaultValues?: boolean;
324
- /**
325
- * If set to true, a tab including the JSON representation of the entity will be included.
326
- */
327
- includeJsonView?: boolean;
328
127
  /**
329
128
  * If set to true, changes to the entity will be saved in a subcollection.
330
129
  * This prop has no effect if the history plugin is not enabled
@@ -341,55 +140,6 @@ export interface BaseCollectionConfig<M extends Record<string, unknown> = Record
341
140
  * quietly worked. The second case is the reason for the escape hatch.
342
141
  */
343
142
  strictWrites?: boolean;
344
- /**
345
- * Should local changes be backed up in local storage, to prevent data loss on
346
- * accidental navigations.
347
- * - `manual_apply`: When the user navigates back to a entity with local changes,
348
- * they will be prompted to restore the changes.
349
- * - `auto_apply`: When the user navigates back to a entity with local changes,
350
- * the changes will be automatically applied.
351
- * - `false`: Local changes will not be backed up.
352
- * Defaults to `manual_apply`.
353
- */
354
- localChangesBackup?: "manual_apply" | "auto_apply" | false;
355
- /**
356
- * Default view mode for displaying this collection.
357
- * - "table": Display entities in a table with inline editing (default)
358
- * - "cards": Display entities as a grid of cards with thumbnails
359
- * - "kanban": Display entities in a Kanban board grouped by a property
360
- * Defaults to "table".
361
- */
362
- defaultViewMode?: ViewMode;
363
- /**
364
- * Which view modes are available for this collection.
365
- * Possible values: "table", "cards", "kanban".
366
- * Defaults to all three: ["table", "cards", "kanban"].
367
- * Note: "kanban" will only be available if the collection has at least
368
- * one string property with `enum` defined, regardless of this setting.
369
- */
370
- enabledViews?: ViewMode[];
371
- /**
372
- * Configuration for Kanban board view mode.
373
- * When set, the Kanban view mode becomes available.
374
- */
375
- kanban?: KanbanConfig<M>;
376
- /**
377
- * Property key to use for ordering items.
378
- * Must reference a string/text property. When items are reordered,
379
- * this property will be updated with lexicographic sort keys
380
- * (e.g. "a0", "a1", "a0V") using string-based fractional indexing.
381
- * Used by Kanban view for ordering within columns
382
- * and can be used for general ordering purposes.
383
- */
384
- readonly orderProperty?: Extract<keyof M, string> | (string & {});
385
- /**
386
- * Actions that can be performed on the entities in this collection.
387
- */
388
- entityActions?: EntityAction<M, USER>[];
389
- /**
390
- * Builder for the collection actions rendered in the toolbar
391
- */
392
- Actions?: ComponentRef<CollectionActionsProps>[];
393
143
  /**
394
144
  * The database table name for this collection.
395
145
  * Automatically set for PostgreSQL collections.
@@ -407,30 +157,6 @@ export interface BaseCollectionConfig<M extends Record<string, unknown> = Record
407
157
  * When defined, the backend enforces access control policies.
408
158
  */
409
159
  securityRules?: readonly SecurityRule[];
410
- /**
411
- * Collection-scoped component overrides. These take precedence over
412
- * global overrides set on `<Rebase>`, but only within this collection's
413
- * views (entity form, detail view, table, empty state, etc.).
414
- *
415
- * Only collection-scoped components (like `Entity.Form`, `Collection.EmptyState`,
416
- * `Collection.Card`, etc.) can be overridden here. App-level components
417
- * (like `Shell.AppBar`, `HomePage`) can only be overridden at the `<Rebase>` level.
418
- *
419
- * @example
420
- * ```tsx
421
- * const productsCollection: PostgresCollectionConfig = {
422
- * name: "Products",
423
- * slug: "products",
424
- * table: "products",
425
- * components: {
426
- * "Entity.Form": { Component: ProductCustomForm },
427
- * "Collection.Card": { Component: ProductCard },
428
- * },
429
- * properties: { ... }
430
- * };
431
- * ```
432
- */
433
- components?: CollectionComponentOverrideMap;
434
160
  }
435
161
  /**
436
162
  * A collection backed by PostgreSQL (or any SQL database).
@@ -571,19 +297,26 @@ export type CollectionConfig<M extends Record<string, unknown> = Record<string,
571
297
  /**
572
298
  * Type guard for PostgreSQL collections.
573
299
  * Returns true if the collection uses the Postgres engine (or the default engine).
300
+ *
301
+ * Generic over the *input* type, and narrows by intersection rather than
302
+ * replacement. Narrowing to a bare `PostgresCollectionConfig` discarded whatever
303
+ * the caller actually had — most visibly the admin panel's view model, whose
304
+ * flattened presentation fields vanished the moment a collection passed through
305
+ * one of these guards.
306
+ *
574
307
  * @group Models
575
308
  */
576
- export declare function isPostgresCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(collection: CollectionConfig<M, USER>): collection is PostgresCollectionConfig<M, USER>;
309
+ export declare function isPostgresCollectionConfig<C extends CollectionConfig<any, any>>(collection: C): collection is C & PostgresCollectionConfig<any, any>;
577
310
  /**
578
311
  * Type guard for Firebase / Firestore collections.
579
312
  * @group Models
580
313
  */
581
- export declare function isFirebaseCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(collection: CollectionConfig<M, USER>): collection is FirebaseCollectionConfig<M, USER>;
314
+ export declare function isFirebaseCollectionConfig<C extends CollectionConfig<any, any>>(collection: C): collection is C & FirebaseCollectionConfig<any, any>;
582
315
  /**
583
316
  * Type guard for MongoDB collections.
584
317
  * @group Models
585
318
  */
586
- export declare function isMongoDBCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(collection: CollectionConfig<M, USER>): collection is MongoDBCollectionConfig<M, USER>;
319
+ export declare function isMongoDBCollectionConfig<C extends CollectionConfig<any, any>>(collection: C): collection is C & MongoDBCollectionConfig<any, any>;
587
320
  /**
588
321
  * Returns the data path for a collection.
589
322
  * For Firestore or MongoDB collections with a `path`, returns that value;
@@ -601,518 +334,8 @@ export declare function getCollectionDataPath<M extends Record<string, unknown>
601
334
  * @group Models
602
335
  */
603
336
  export declare function getDeclaredSubcollections<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(collection: CollectionConfig<M, USER>): (() => CollectionConfig<Record<string, unknown>>[]) | undefined;
604
- /**
605
- * Configuration for Kanban board view mode.
606
- * @group Collections
607
- */
608
- export interface KanbanConfig<M extends Record<string, unknown> = Record<string, unknown>> {
609
- /**
610
- * Property key to use for Kanban board columns.
611
- * Must reference a string property with `enum` values defined.
612
- * Entities will be grouped into columns based on this property's value.
613
- * The column order is determined by the order of `enum` values in the property.
614
- */
615
- columnProperty: Extract<keyof M, string> | (string & {});
616
- }
617
- /**
618
- * View mode for displaying a collection.
619
- * - "list": Simple, clean list view — the classic CMS default
620
- * - "table": Table with inline editing
621
- * - "cards": Grid of visual cards with thumbnails
622
- * - "kanban": Board view grouped by a property
623
- * @group Collections
624
- */
625
- export type ViewMode = "list" | "table" | "cards" | "kanban";
626
- /**
627
- * Parameter passed to the `Actions` prop in the collection configuration.
628
- * The component will receive this prop when it is rendered in the collection
629
- * toolbar.
630
- *
631
- * @group Models
632
- */
633
- export interface CollectionActionsProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User, EC extends CollectionConfig<M> = CollectionConfig<M>> {
634
- /**
635
- * Full collection path of this entity. This is the full path, like
636
- * `users/1234/addresses`
637
- */
638
- path: string;
639
- /**
640
- * Path of the last collection, like `addresses`
641
- */
642
- relativePath: string;
643
- /**
644
- * Array of the parent path segments like `['users']`
645
- */
646
- parentCollectionSlugs: string[];
647
- parentEntityIds: string[];
648
- /**
649
- * The collection configuration
650
- */
651
- collection: EC;
652
- /**
653
- * Use this controller to get the selected entities and to update the
654
- * selected entities state.
655
- */
656
- selectionController: SelectionController<M>;
657
- /**
658
- * Use this controller to get the table controller and to update the
659
- * table controller state.
660
- */
661
- tableController: EntityTableController<M>;
662
- /**
663
- * Context of the app status
664
- */
665
- context: RebaseContext<USER>;
666
- /**
667
- * Count of the entities in this collection.
668
- * undefined means the count is still loading.
669
- */
670
- collectionEntitiesCount?: number;
671
- /**
672
- * Programmatically open the new-document form for this collection,
673
- * optionally pre-populating it with initial field values.
674
- * The form opens in the same mode configured for the collection
675
- * (side panel, full screen, or split).
676
- *
677
- * This is the primary hook for workflows that need to create a document
678
- * from external data — e.g. fetching content from a URL, importing from
679
- * a third-party API, or duplicating from another system.
680
- *
681
- * @example
682
- * // Inside a custom CollectionAction component:
683
- * openNewDocument({ title: "Fetched title", body: "..." });
684
- */
685
- openNewDocument: (defaultValues?: Record<string, unknown>) => void;
686
- }
687
- /**
688
- * Use this controller to retrieve the selected entities or modify them in
689
- * an {@link CollectionConfig}
690
- * @group Models
691
- */
692
- export interface SelectionController<M extends Record<string, unknown> = Record<string, unknown>> {
693
- selectedEntities: Entity<M>[];
694
- setSelectedEntities(entities: Entity<M>[]): void;
695
- setSelectedEntities(action: (prev: Entity<M>[]) => Entity<M>[]): void;
696
- isEntitySelected(entity: Entity<M>): boolean;
697
- toggleEntitySelection(entity: Entity<M>, newSelectedState?: boolean): void;
698
- }
699
337
  export type { WhereFilterOp, FilterValues, WireFilterValues, FilterPreset } from "./filter-operators";
700
- /**
701
- * Used to indicate valid filter combinations (e.g. created in Firestore)
702
- * If the user selects a specific filter/sort combination, the CMS checks if it's
703
- * valid, otherwise it reverts to the simpler valid case
704
- * @group Models
705
- */
706
- export type FilterCombination<Key extends string> = Partial<Record<Key, "asc" | "desc">>;
707
- /**
708
- * Sizes in which a collection can be rendered
709
- * @group Models
710
- */
711
- export type CollectionSize = "xs" | "s" | "m" | "l" | "xl";
712
- export type AdditionalFieldDelegateProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> = {
713
- entity: Entity<M>;
714
- context: RebaseContext<USER>;
715
- };
716
- /**
717
- * Use this interface for adding additional fields to entity collection views and forms.
718
- * @group Models
719
- */
720
- export interface AdditionalFieldDelegate<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
721
- /**
722
- * ID of this column. You can use this id in the `properties` field of the
723
- * collection in any order you want
724
- */
725
- key: string;
726
- /**
727
- * Header of this column
728
- */
729
- name: string;
730
- /**
731
- * Width of the generated column in pixels
732
- */
733
- width?: number;
734
- /**
735
- * Builder for the custom field
736
- */
737
- Builder?(props: {
738
- entity: Entity<M>;
739
- context: RebaseContext<USER>;
740
- }): React.ReactNode;
741
- /**
742
- * If this column needs to update dynamically based on other properties,
743
- * you can define an array of keys as strings with the
744
- * `dependencies` prop.
745
- * e.g. ["name", "surname"]
746
- * This is a performance optimization, if you don't define dependencies
747
- * it will be updated in every render.
748
- */
749
- dependencies?: NoInfer<Extract<keyof M, string>> | NoInfer<Extract<keyof M, string>>[] | (string & {}) | (string & {})[];
750
- /**
751
- * Use this prop to define the value of the column as a string or number.
752
- * This is the value that will be used for exporting the collection.
753
- * If `Builder` is defined, this prop will be ignored in the collection
754
- * view.
755
- * @param entity
756
- */
757
- value?(props: {
758
- entity: Entity<M>;
759
- context: RebaseContext;
760
- }): string | number | Promise<string | number> | undefined;
761
- }
762
338
  export type InferCollectionConfigType<S extends CollectionConfig> = S extends CollectionConfig<infer M> ? M : never;
763
- /**
764
- * Used in the {@link CollectionConfig#defaultSelectedView} to define the default
765
- * @group Models
766
- */
767
- export type DefaultSelectedViewBuilder = (params: DefaultSelectedViewParams) => string | undefined;
768
- /**
769
- * Used in the {@link CollectionConfig#defaultSelectedView} to define the default
770
- * @group Models
771
- */
772
- export type DefaultSelectedViewParams = {
773
- status?: EntityStatus;
774
- entityId?: string | number;
775
- };
776
- /**
777
- * You can use this controller to control the table view of a collection.
778
- */
779
- export type EntityTableController<M extends Record<string, unknown> = Record<string, unknown>> = {
780
- data: Entity<M>[];
781
- dataLoading: boolean;
782
- noMoreToLoad: boolean;
783
- dataLoadingError?: Error;
784
- filterValues?: FilterValues<Extract<keyof M, string> | (string & {})>;
785
- setFilterValues?: (filterValues: FilterValues<Extract<keyof M, string> | (string & {})>) => void;
786
- sortBy?: [Extract<keyof M, string> | (string & {}), "asc" | "desc"];
787
- setSortBy?: (sortBy?: [Extract<keyof M, string> | (string & {}), "asc" | "desc"]) => void;
788
- searchString?: string;
789
- setSearchString?: (searchString?: string) => void;
790
- clearFilter?: () => void;
791
- itemCount?: number;
792
- setItemCount?: (itemCount: number) => void;
793
- initialScroll?: number;
794
- onScroll?: (props: {
795
- scrollDirection: "forward" | "backward";
796
- scrollOffset: number;
797
- scrollUpdateWasRequested: boolean;
798
- }) => void;
799
- paginationEnabled?: boolean;
800
- pageSize?: number;
801
- checkFilterCombination?: (filterValues: FilterValues<string>, sortBy?: [string, "asc" | "desc"]) => boolean;
802
- popupCell?: SelectedCellProps<M>;
803
- setPopupCell?: (popupCell?: SelectedCellProps<M>) => void;
804
- onAddColumn?: (column: string) => void;
805
- };
806
- export type SelectedCellProps<M extends Record<string, unknown> = Record<string, unknown>> = {
807
- propertyKey: Extract<keyof M, string> | (string & {});
808
- cellRect: DOMRect;
809
- width: number;
810
- height: number;
811
- entityPath: string;
812
- entityId: string | number;
813
- };
814
- /**
815
- * SQL operation that a policy applies to.
816
- * @group Models
817
- */
818
- export type SecurityOperation = "select" | "insert" | "update" | "delete" | "all";
819
- /**
820
- * Flexible Row Level Security rule for a collection.
821
- *
822
- * Built on PostgreSQL Row Level Security. Rules can range from
823
- * simple convenience shortcuts to fully custom SQL expressions, giving you the
824
- * full power of PostgreSQL Row Level Security.
825
- *
826
- * The authenticated user's identity is available in raw SQL via:
827
- * - `auth.uid()` — the user's ID
828
- * - `auth.roles()` — comma-separated app role IDs
829
- * - `auth.jwt()` — full JWT claims as JSONB
830
- *
831
- * These are set automatically per-transaction by the backend.
832
- *
833
- * **How rules combine:** PostgreSQL evaluates all matching policies for an
834
- * operation. Permissive rules are OR'd together (any one passing is enough).
835
- * Restrictive rules are AND'd (all must pass). This is standard PostgreSQL RLS behavior.
836
- *
837
- * **Mutual exclusivity:** `ownerField`, `access`, structured `condition`, and
838
- * raw SQL (`using`/`withCheck`) cannot be combined. The type system enforces
839
- * this — attempting to set conflicting fields will produce a compile-time
840
- * error.
841
- *
842
- * **Which form to reach for:** prefer the structured {@link StructuredSecurityRule}
843
- * (`condition`/`check`) or the shortcuts (`ownerField`, `access`, `roles`). These
844
- * are engine-agnostic and evaluated identically by the database and the admin UI,
845
- * so the UI never shows an action the database will reject. Raw SQL
846
- * ({@link RawSQLSecurityRule}) keeps full PostgreSQL power but is Postgres-only
847
- * and server-authoritative (the UI cannot evaluate arbitrary SQL locally).
848
- *
849
- * @group Models
850
- */
851
- export type SecurityRule = OwnerSecurityRule | PublicSecurityRule | StructuredSecurityRule | RawSQLSecurityRule | RolesOnlySecurityRule;
852
- /**
853
- * Shared fields for all SecurityRule variants.
854
- * @group Models
855
- */
856
- export interface SecurityRuleBase {
857
- /**
858
- * Optional human-readable name for the policy.
859
- * If not provided, one will be auto-generated from the table name and operation.
860
- * Must be unique per table.
861
- *
862
- * When using `operations` (array), each generated policy will have the
863
- * operation name appended, e.g. `"owner_access_select"`, `"owner_access_update"`.
864
- */
865
- name?: string;
866
- /**
867
- * Which SQL operation this policy applies to.
868
- * Use this when the policy targets a single operation or all operations.
869
- *
870
- * For multiple specific operations, use `operations` (array) instead.
871
- * If neither is specified, defaults to `"all"`.
872
- *
873
- * @default "all"
874
- */
875
- operation?: SecurityOperation;
876
- /**
877
- * Array of SQL operations this policy applies to.
878
- * The compiler will generate one PostgreSQL policy per operation, sharing
879
- * the same configuration.
880
- *
881
- * This reduces boilerplate when the same rule applies to multiple (but not all)
882
- * operations.
883
- *
884
- * Takes precedence over `operation` (singular) if both are specified.
885
- *
886
- * @example
887
- * // Same rule for select and update
888
- * { operations: ["select", "update"], ownerField: "user_id" }
889
- *
890
- * @example
891
- * // Equivalent to operation: "all"
892
- * { operations: ["all"], ownerField: "user_id" }
893
- */
894
- operations?: readonly SecurityOperation[];
895
- /**
896
- * Whether this policy is `"permissive"` (default) or `"restrictive"`.
897
- *
898
- * - **permissive**: Multiple permissive policies for the same operation are
899
- * OR'd together — if *any* passes, access is granted.
900
- * - **restrictive**: Restrictive policies are AND'd with all permissive
901
- * policies — they act as additional gates that *must* also pass.
902
- *
903
- * This is the standard PostgreSQL RLS model.
904
- *
905
- * @default "permissive"
906
- */
907
- mode?: "permissive" | "restrictive";
908
- /**
909
- * **Shortcut.** Restrict this rule to users that have one of these
910
- * application-level roles.
911
- *
912
- * **Important:** These are NOT native PostgreSQL database roles — names
913
- * like `public`, `anon` or `authenticated` belong to {@link pgRoles} and
914
- * produce a condition no user can satisfy if used here. These are
915
- * application roles managed by Rebase, stored as an inline `roles TEXT[]`
916
- * column on the users table, and injected into each transaction as
917
- * `app.user_roles` — which `auth.roles()` reads.
918
- *
919
- * There is no roles registry: a role exists once it is assigned to a user.
920
- *
921
- * Generates a safe array-overlap condition — the user passes if they hold
922
- * *any* of the listed roles:
923
- * `string_to_array(auth.roles(), ',') && ARRAY['<role1>', '<role2>']`
924
- *
925
- * (Note: this is a true set intersection, NOT a regex/substring match, so
926
- * a role named `admin` never matches `nonadmin` or `superadmin`.)
927
- *
928
- * Can be combined with `ownerField`, `access`, `condition`, or raw
929
- * `using`/`withCheck`. When combined, the role check is AND'd with the
930
- * other condition.
931
- *
932
- * @example
933
- * // Only admins can delete
934
- * { operation: "delete", roles: ["admin"] }
935
- *
936
- * @example
937
- * // Admins have unfiltered read access to all rows
938
- * { operation: "select", roles: ["admin"], using: "true" }
939
- */
940
- roles?: readonly string[];
941
- /**
942
- * **Advanced.** Native PostgreSQL database roles the policy applies to.
943
- *
944
- * By default, all generated policies target the `public` role (i.e.
945
- * every database connection). This is correct for most setups where
946
- * a single database role is used for all connections.
947
- *
948
- * **Important:** These are NOT the same as the application-level
949
- * {@link roles} (admin, editor, viewer, etc.) — those are enforced in the
950
- * USING/WITH CHECK clauses via `auth.roles()`. This field controls the
951
- * PostgreSQL `TO` clause in `CREATE POLICY ... TO role_name`.
952
- *
953
- * Use this if you have dedicated PostgreSQL roles (e.g. `app_read`,
954
- * `app_write`) and want policies to target specific ones.
955
- *
956
- * @default ["public"]
957
- *
958
- * @example
959
- * // Only apply this policy when connected as `app_role`
960
- * { operation: "select", access: "public", pgRoles: ["app_role"] }
961
- */
962
- pgRoles?: readonly string[];
963
- }
964
- /**
965
- * Security rule that grants access based on row ownership.
966
- * Generates a USING/WITH CHECK clause like: `<column> = auth.uid()`
967
- *
968
- * Cannot be combined with `using`, `withCheck`, or `access`.
969
- *
970
- * @example
971
- * { operation: "all", ownerField: "user_id" }
972
- *
973
- * @group Models
974
- */
975
- export interface OwnerSecurityRule extends SecurityRuleBase {
976
- /** The property (column) that stores the owner's user ID. */
977
- ownerField: string;
978
- access?: never;
979
- using?: never;
980
- withCheck?: never;
981
- condition?: never;
982
- check?: never;
983
- }
984
- /**
985
- * Security rule that grants unrestricted row access (no row filtering).
986
- * Generates `USING (true)`.
987
- *
988
- * This means "no row-level filter", NOT "anonymous/unauthenticated access".
989
- * Authentication is still enforced at the API layer — this only controls which
990
- * *rows* authenticated users can see.
991
- *
992
- * Cannot be combined with `using`, `withCheck`, or `ownerField`.
993
- *
994
- * @example
995
- * // Public read (any authenticated user sees all rows)
996
- * { operation: "select", access: "public" }
997
- *
998
- * @group Models
999
- */
1000
- export interface PublicSecurityRule extends SecurityRuleBase {
1001
- /** Grant unrestricted row access for this operation. */
1002
- access: "public";
1003
- ownerField?: never;
1004
- using?: never;
1005
- withCheck?: never;
1006
- condition?: never;
1007
- check?: never;
1008
- }
1009
- /**
1010
- * Security rule expressed as a structured, engine-agnostic
1011
- * {@link PolicyExpression}. This is the **recommended** way to write a
1012
- * non-trivial condition: it compiles to PostgreSQL `USING`/`WITH CHECK` SQL
1013
- * *and* is evaluated identically by the admin UI, so the UI can never show an
1014
- * action the database will reject.
1015
- *
1016
- * Cannot be combined with `ownerField`, `access`, or raw `using`/`withCheck`.
1017
- *
1018
- * @example
1019
- * // Owner, or any user holding the `moderator` role
1020
- * {
1021
- * operation: "update",
1022
- * condition: policy.or(
1023
- * policy.compare(policy.field("user_id"), "eq", policy.authUid()),
1024
- * policy.rolesOverlap(["moderator"])
1025
- * )
1026
- * }
1027
- *
1028
- * @group Models
1029
- */
1030
- export interface StructuredSecurityRule extends SecurityRuleBase {
1031
- /**
1032
- * Structured condition for the `USING` clause — which *existing* rows are
1033
- * visible / can be modified / deleted (SELECT, UPDATE, DELETE).
1034
- */
1035
- condition: PolicyExpression;
1036
- /**
1037
- * Structured condition for the `WITH CHECK` clause — which *new/updated*
1038
- * row values are allowed (INSERT, UPDATE). Defaults to `condition` when
1039
- * omitted, mirroring PostgreSQL's own behavior.
1040
- */
1041
- check?: PolicyExpression;
1042
- ownerField?: never;
1043
- access?: never;
1044
- using?: never;
1045
- withCheck?: never;
1046
- }
1047
- /**
1048
- * Security rule using raw SQL expressions for full PostgreSQL RLS power.
1049
- *
1050
- * **Postgres-only and server-authoritative.** Arbitrary SQL cannot be
1051
- * evaluated by the admin UI, so a rule using this form is treated as *unknown*
1052
- * client-side (never silently allowed) and its effect on visible actions is
1053
- * reflected from the server. For conditions that should also drive the UI
1054
- * precisely, prefer the structured {@link StructuredSecurityRule}.
1055
- *
1056
- * Cannot be combined with `ownerField`, `access`, or structured `condition`.
1057
- *
1058
- * You can reference columns via `{column_name}` which will be resolved to
1059
- * `table.column_name` in the generated Drizzle code.
1060
- *
1061
- * @example
1062
- * // Rows published in the last 30 days are visible
1063
- * { operation: "select", using: "{published_at} > now() - interval '30 days'" }
1064
- *
1065
- * @example
1066
- * // Only the owner, or users with 'moderator' role
1067
- * {
1068
- * operation: "select",
1069
- * using: "{user_id} = auth.uid() OR auth.roles() ~ 'moderator'"
1070
- * }
1071
- *
1072
- * @group Models
1073
- */
1074
- export interface RawSQLSecurityRule extends SecurityRuleBase {
1075
- /**
1076
- * Raw SQL expression for the `USING` clause.
1077
- * This controls which *existing* rows are visible / can be modified / deleted.
1078
- * Applied to SELECT, UPDATE, and DELETE.
1079
- */
1080
- using: string;
1081
- /**
1082
- * Raw SQL expression for the `WITH CHECK` clause.
1083
- * This controls which *new/updated* row values are allowed.
1084
- * Applied to INSERT and UPDATE.
1085
- *
1086
- * If not provided on INSERT/UPDATE policies, falls back to `using`
1087
- * (which matches PostgreSQL's own default behavior).
1088
- */
1089
- withCheck?: string;
1090
- ownerField?: never;
1091
- access?: never;
1092
- condition?: never;
1093
- check?: never;
1094
- }
1095
- /**
1096
- * Security rule that only filters by application roles, without any
1097
- * row-level condition (USING/WITH CHECK).
1098
- *
1099
- * Useful for simple "only admins can access this table" rules where
1100
- * no per-row filtering is needed.
1101
- *
1102
- * @example
1103
- * // Only admins can delete
1104
- * { operation: "delete", roles: ["admin"] }
1105
- *
1106
- * @group Models
1107
- */
1108
- export interface RolesOnlySecurityRule extends SecurityRuleBase {
1109
- ownerField?: never;
1110
- access?: never;
1111
- using?: never;
1112
- withCheck?: never;
1113
- condition?: never;
1114
- check?: never;
1115
- }
1116
339
  /**
1117
340
  * Configuration for authentication collections.
1118
341
  *
@@ -1171,9 +394,14 @@ export interface AuthCollectionConfig {
1171
394
  * the built-in `resetPasswordAction` into the collection's entity actions.
1172
395
  *
1173
396
  * Set to `false` to disable, or pass a custom `EntityAction` to replace the UI.
397
+ *
398
+ * The object form is an `EntityAction` from `@rebasepro/admin-types`, typed
399
+ * here as `object` because it is a React component with admin controllers in
400
+ * its props and nothing on the server reads it — only whether the built-in
401
+ * action is injected, which is the boolean.
1174
402
  */
1175
403
  actions?: {
1176
- resetPassword?: boolean | EntityAction;
404
+ resetPassword?: boolean | object;
1177
405
  };
1178
406
  }
1179
407
  /**