@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.
Files changed (88) hide show
  1. package/README.md +13 -13
  2. package/dist/controllers/auth.d.ts +7 -1
  3. package/dist/controllers/client.d.ts +204 -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 +309 -35
  7. package/dist/controllers/data_driver.d.ts +92 -37
  8. package/dist/controllers/email.d.ts +2 -2
  9. package/dist/controllers/index.d.ts +1 -1
  10. package/dist/controllers/local_config_persistence.d.ts +4 -4
  11. package/dist/controllers/navigation.d.ts +2 -2
  12. package/dist/controllers/registry.d.ts +21 -8
  13. package/dist/controllers/{side_entity_controller.d.ts → side_panel_controller.d.ts} +7 -7
  14. package/dist/controllers/storage.d.ts +39 -0
  15. package/dist/errors.d.ts +64 -0
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.es.js +160 -15
  18. package/dist/index.es.js.map +1 -1
  19. package/dist/rebase_context.d.ts +8 -4
  20. package/dist/types/auth_adapter.d.ts +29 -4
  21. package/dist/types/backend.d.ts +33 -26
  22. package/dist/types/backup.d.ts +20 -0
  23. package/dist/types/builders.d.ts +2 -2
  24. package/dist/types/collections.d.ts +84 -75
  25. package/dist/types/component_overrides.d.ts +61 -3
  26. package/dist/types/cron.d.ts +11 -2
  27. package/dist/types/data_source.d.ts +15 -2
  28. package/dist/types/database_adapter.d.ts +21 -4
  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/index.d.ts +1 -0
  35. package/dist/types/modify_collections.d.ts +2 -2
  36. package/dist/types/plugins.d.ts +9 -9
  37. package/dist/types/policy.d.ts +111 -11
  38. package/dist/types/properties.d.ts +54 -9
  39. package/dist/types/relations.d.ts +3 -3
  40. package/dist/types/slots.d.ts +14 -14
  41. package/dist/types/translations.d.ts +5 -1
  42. package/dist/types/user_management_delegate.d.ts +8 -2
  43. package/dist/types/websockets.d.ts +46 -13
  44. package/dist/users/user.d.ts +21 -9
  45. package/package.json +5 -6
  46. package/src/controllers/auth.tsx +7 -1
  47. package/src/controllers/client.ts +235 -7
  48. package/src/controllers/collection_registry.ts +3 -3
  49. package/src/controllers/customization_controller.tsx +1 -1
  50. package/src/controllers/data.ts +330 -39
  51. package/src/controllers/data_driver.ts +93 -40
  52. package/src/controllers/email.ts +2 -2
  53. package/src/controllers/index.ts +1 -1
  54. package/src/controllers/local_config_persistence.tsx +4 -4
  55. package/src/controllers/navigation.ts +2 -2
  56. package/src/controllers/registry.ts +22 -8
  57. package/src/controllers/{side_entity_controller.tsx → side_panel_controller.tsx} +7 -7
  58. package/src/controllers/storage.ts +60 -1
  59. package/src/errors.ts +80 -0
  60. package/src/index.ts +1 -0
  61. package/src/rebase_context.tsx +8 -4
  62. package/src/types/auth_adapter.ts +29 -4
  63. package/src/types/backend.ts +44 -36
  64. package/src/types/backup.ts +26 -0
  65. package/src/types/builders.ts +2 -2
  66. package/src/types/collections.ts +101 -91
  67. package/src/types/component_overrides.ts +72 -5
  68. package/src/types/cron.ts +11 -2
  69. package/src/types/data_source.ts +24 -2
  70. package/src/types/database_adapter.ts +19 -4
  71. package/src/types/entities.ts +7 -7
  72. package/src/types/entity_actions.tsx +7 -7
  73. package/src/types/entity_callbacks.ts +42 -42
  74. package/src/types/entity_views.tsx +3 -3
  75. package/src/types/filter-operators.ts +96 -23
  76. package/src/types/index.ts +1 -0
  77. package/src/types/modify_collections.tsx +2 -2
  78. package/src/types/plugins.tsx +9 -9
  79. package/src/types/policy.ts +114 -9
  80. package/src/types/properties.ts +58 -9
  81. package/src/types/relations.ts +3 -3
  82. package/src/types/slots.tsx +14 -14
  83. package/src/types/translations.ts +5 -1
  84. package/src/types/user_management_delegate.ts +8 -2
  85. package/src/types/websockets.ts +43 -14
  86. package/src/users/user.ts +22 -9
  87. package/dist/index.umd.js +0 -458
  88. package/dist/index.umd.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import React, { Dispatch, SetStateAction } from "react";
2
2
  import type { Entity, EntityStatus, EntityValues } from "./entities";
3
- import type { EntityCallbacks } from "./entity_callbacks";
3
+ import type { CollectionCallbacks } from "./entity_callbacks";
4
4
 
5
5
  import type { EnumValues, Properties, PostgresProperties, FirebaseProperties, MongoProperties } from "./properties";
6
6
  import type { ExportConfig } from "./export_import";
@@ -13,17 +13,17 @@ import type { EntityAction } from "./entity_actions";
13
13
  import type { PolicyExpression } from "./policy";
14
14
  import type { ComponentRef } from "./component_ref";
15
15
  import type { CollectionComponentOverrideMap } from "./component_overrides";
16
- import type { WhereFilterOp, FilterValues, FilterPreset } from "./filter-operators";
16
+ import type { WhereFilterOp, FilterValues, FilterPreset, OrderByTuple } from "./filter-operators";
17
17
 
18
18
  /**
19
19
  * Base interface containing all driver-agnostic collection properties.
20
- * Use {@link PostgresCollection} or {@link FirebaseCollection} for
21
- * driver-specific type safety, or {@link EntityCollection} when you
20
+ * Use {@link PostgresCollectionConfig} or {@link FirebaseCollectionConfig} for
21
+ * driver-specific type safety, or {@link CollectionConfig} when you
22
22
  * need to handle any collection regardless of backend.
23
23
  *
24
24
  * @group Models
25
25
  */
26
- export interface BaseEntityCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
26
+ export interface BaseCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
27
27
 
28
28
  /**
29
29
  * You can set an alias that will be used internally instead of the collection name.
@@ -56,14 +56,14 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
56
56
  *
57
57
  * Custom drivers can set this directly to expose child collections to the UI.
58
58
  */
59
- childCollections?: () => EntityCollection<Record<string, unknown>>[];
59
+ childCollections?: () => CollectionConfig<Record<string, unknown>>[];
60
60
 
61
61
 
62
62
  /**
63
63
  * The data source this collection belongs to — the routing key shared by
64
64
  * the frontend router and the backend driver registry. It points at a
65
65
  * {@link DataSourceDefinition} registered on `<Rebase dataSources>` (front)
66
- * and `initRebase({ dataSources })` (back).
66
+ * and `initializeRebaseBackend({ dataSources })` (back).
67
67
  *
68
68
  * If not specified, the default data source `"(default)"` is used, which
69
69
  * for a standard Rebase app is the server-mediated Postgres backend.
@@ -81,8 +81,8 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
81
81
  * The database engine backing this collection (`"postgres"`, `"firestore"`,
82
82
  * `"mongodb"`, or a custom id).
83
83
  *
84
- * On concrete collection types ({@link PostgresCollection},
85
- * {@link FirebaseCollection}, {@link MongoDBCollection}) this is a literal
84
+ * On concrete collection types ({@link PostgresCollectionConfig},
85
+ * {@link FirebaseCollectionConfig}, {@link MongoDBCollectionConfig}) this is a literal
86
86
  * discriminant. On the base type it is optional and gets stamped
87
87
  * automatically during collection normalization from the registered
88
88
  * {@link DataSourceDefinition}.
@@ -103,7 +103,7 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
103
103
  databaseId?: string;
104
104
 
105
105
  /**
106
- * Set of properties that compose an entity
106
+ * Set of properties that compose a entity
107
107
  */
108
108
  properties: Properties;
109
109
 
@@ -145,13 +145,13 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
145
145
  readonly titleProperty?: Extract<keyof M, string> | (string & {});
146
146
 
147
147
  /**
148
- * When editing an entity, you can choose to open the entity in a side dialog
148
+ * When editing a entity, you can choose to open the entity in a side dialog
149
149
  * or in a full screen dialog. Defaults to `full_screen`.
150
150
  */
151
151
  openEntityMode?: "side_panel" | "full_screen" | "split" | "dialog";
152
152
 
153
153
  /**
154
- * Controls what happens when a user clicks on an entity in the collection view.
154
+ * Controls what happens when a user clicks on a entity in the collection view.
155
155
  * - `"edit"` (default): Opens the entity in the edit form.
156
156
  * - `"view"`: Opens a read-only detail view with an "Edit" button.
157
157
  */
@@ -179,24 +179,23 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
179
179
  auth?: boolean | AuthCollectionConfig;
180
180
 
181
181
  /**
182
- * Opt out of the framework's default Row Level Security policies for
183
- * authentication collections.
182
+ * Opt out of the framework's default Row Level Security policies.
184
183
  *
185
- * When a collection has `auth` enabled, the schema generator automatically
186
- * injects an admin-only write policy (INSERT/UPDATE/DELETE require the
187
- * `admin` role, or the trusted server context) for any write operation that
188
- * the collection does not already cover with an explicit `securityRules`
189
- * entry. This makes privileged columns such as `roles` safe by default a
190
- * non-admin cannot modify the user row through the data API regardless of
191
- * which code path issues the write.
184
+ * The schema generator automatically injects, for every collection, a
185
+ * baseline SELECT policy granting the trusted server context and the
186
+ * `admin` role read access (reads run under a restricted role, so RLS
187
+ * default-denies without it). For auth collections it additionally injects
188
+ * a self-read policy (`id = auth.uid()`) and an admin-only write gate
189
+ * (INSERT/UPDATE/DELETE require the `admin` role or the trusted server
190
+ * context), making privileged columns such as `roles` safe by default.
192
191
  *
193
- * Defining your own write rule for an operation overrides the default for
194
- * that operation. Set this flag to `true` to remove the default policies
192
+ * Author-defined `securityRules` are permissive and broaden access on top
193
+ * of these defaults. Set this flag to `true` to remove the defaults
195
194
  * entirely and take full responsibility for the collection's RLS.
196
195
  *
197
196
  * @default false
198
197
  */
199
- disableDefaultAuthPolicies?: boolean;
198
+ disableDefaultPolicies?: boolean;
200
199
 
201
200
 
202
201
  /**
@@ -204,19 +203,18 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
204
203
  * If you are specifying your collection as code, the order is the same as the
205
204
  * one you define in `properties`. Additional columns are added at the
206
205
  * end of the list, if the order is not specified.
206
+ *
207
207
  * You can use this prop to hide some properties from the table view.
208
208
  * Note that if you set this prop, other ways to hide fields, like
209
209
  * `hidden` in the property definition, will be ignored.
210
210
  * `propertiesOrder` has precedence over `hidden`.
211
- * - For properties use the property key.
212
- * - For additional fields use the field key.
213
- * - If you have subcollections, you get a column for each subcollection,
214
- * with the path (or alias) as the subcollection, prefixed with
215
- * `subcollection:`. e.g. `subcollection:orders`.
216
- * You can use this prop to hide some properties from the table view.
217
- * Note that if you set this prop, other ways to hide fields, like
218
- * `hidden` in the property definition,will be ignored.
219
- * `propertiesOrder` has precedence over `hidden`.
211
+ *
212
+ * Supported entry formats:
213
+ * - For properties, use the property key.
214
+ * - For additional fields, use the field key.
215
+ * - Child collections (Firestore subcollections, or Postgres relations
216
+ * with `many` cardinality) each get a column with id
217
+ * `subcollection:<slug>`, e.g. `subcollection:orders`.
220
218
  */
221
219
  propertiesOrder?: (Extract<keyof M, string> | (string & {}) | string | `subcollection:${string}`)[];
222
220
 
@@ -233,11 +231,11 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
233
231
  selectionEnabled?: boolean;
234
232
 
235
233
  /**
236
- * This interface defines all the callbacks that can be used when an entity
234
+ * This interface defines all the callbacks that can be used when a entity
237
235
  * is being created, updated or deleted.
238
236
  * Useful for adding your own logic or blocking the execution of the operation.
239
237
  */
240
- readonly callbacks?: EntityCallbacks<M, USER>;
238
+ readonly callbacks?: CollectionCallbacks<M, USER>;
241
239
 
242
240
  /**
243
241
  * Pass your own selection controller if you want to control selected
@@ -287,7 +285,7 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
287
285
  * applied in the collection.
288
286
  * e.g. `sort: ["order", "asc"]`
289
287
  */
290
- readonly sort?: [Extract<keyof M, string> | (string & {}), "asc" | "desc"];
288
+ readonly sort?: OrderByTuple<Extract<keyof M, string> | (string & {})>;
291
289
 
292
290
  /**
293
291
  * You can add additional fields to the collection view by implementing
@@ -318,7 +316,7 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
318
316
 
319
317
  /**
320
318
  * If you want to open custom views or subcollections by default when opening the edit
321
- * view of an entity, you can specify the path to the view here.
319
+ * view of a entity, you can specify the path to the view here.
322
320
  * The path is relative to the current collection. For example if you have a collection
323
321
  * that has a custom view as well as a subcollection that refers to another entity, you can
324
322
  * either specify the path to the custom view or the path to the subcollection.
@@ -362,7 +360,7 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
362
360
  metadata?: Record<string, unknown>;
363
361
 
364
362
  /**
365
- * Width of the side dialog (in pixels) when opening an entity in this collection.
363
+ * Width of the side dialog (in pixels) when opening a entity in this collection.
366
364
  */
367
365
  sideDialogWidth?: number | string;
368
366
 
@@ -384,12 +382,24 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
384
382
  */
385
383
  history?: boolean;
386
384
 
385
+ /**
386
+ * Whether a write naming a field this collection does not declare is
387
+ * rejected with a 400. Defaults to `true`.
388
+ *
389
+ * Set to `false` to let unknown keys through to the database, which is what
390
+ * happened before this existed: a typo reached the INSERT and came back as
391
+ * a Postgres error about a column, or — where a column really does exist
392
+ * that the config never declared, populated by a trigger or a default —
393
+ * quietly worked. The second case is the reason for the escape hatch.
394
+ */
395
+ strictWrites?: boolean;
396
+
387
397
  /**
388
398
  * Should local changes be backed up in local storage, to prevent data loss on
389
399
  * accidental navigations.
390
- * - `manual_apply`: When the user navigates back to an entity with local changes,
400
+ * - `manual_apply`: When the user navigates back to a entity with local changes,
391
401
  * they will be prompted to restore the changes.
392
- * - `auto_apply`: When the user navigates back to an entity with local changes,
402
+ * - `auto_apply`: When the user navigates back to a entity with local changes,
393
403
  * the changes will be automatically applied.
394
404
  * - `false`: Local changes will not be backed up.
395
405
  * Defaults to `manual_apply`.
@@ -458,7 +468,7 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
458
468
  * Security rules for this collection (Row Level Security).
459
469
  * When defined, the backend enforces access control policies.
460
470
  */
461
- securityRules?: SecurityRule[];
471
+ securityRules?: readonly SecurityRule[];
462
472
 
463
473
  /**
464
474
  * Collection-scoped component overrides. These take precedence over
@@ -471,7 +481,7 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
471
481
  *
472
482
  * @example
473
483
  * ```tsx
474
- * const productsCollection: PostgresCollection = {
484
+ * const productsCollection: PostgresCollectionConfig = {
475
485
  * name: "Products",
476
486
  * slug: "products",
477
487
  * table: "products",
@@ -492,13 +502,13 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
492
502
  * A collection backed by PostgreSQL (or any SQL database).
493
503
  * Adds support for SQL-style relations (JOINs) and Row Level Security.
494
504
  *
495
- * Use this type instead of {@link EntityCollection} when you want
505
+ * Use this type instead of {@link CollectionConfig} when you want
496
506
  * compile-time safety that only SQL-relevant fields appear.
497
507
  *
498
508
  * @group Models
499
509
  */
500
- export interface PostgresCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>
501
- extends BaseEntityCollection<M, USER> {
510
+ export interface PostgresCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>
511
+ extends BaseCollectionConfig<M, USER> {
502
512
  properties: PostgresProperties;
503
513
 
504
514
  /**
@@ -526,7 +536,7 @@ export interface PostgresCollection<M extends Record<string, unknown> = Record<s
526
536
  relations?: Relation[];
527
537
 
528
538
  /**
529
- * Security rules for this collection (Supabase-style Row Level Security).
539
+ * Security rules for this collection (PostgreSQL Row Level Security).
530
540
  * When defined, the schema generator will enable RLS on the table and
531
541
  * create the corresponding PostgreSQL policies.
532
542
  *
@@ -540,27 +550,27 @@ export interface PostgresCollection<M extends Record<string, unknown> = Record<s
540
550
  * - `auth.roles()` — comma-separated app role IDs
541
551
  * - `auth.jwt()` — full JWT claims as JSONB
542
552
  */
543
- securityRules?: SecurityRule[];
553
+ securityRules?: readonly SecurityRule[];
544
554
  }
545
555
 
546
556
  /**
547
557
  * A collection backed by Firebase / Firestore.
548
558
  * Adds support for subcollections (nested document collections).
549
559
  *
550
- * Use this type instead of {@link EntityCollection} when you want
560
+ * Use this type instead of {@link CollectionConfig} when you want
551
561
  * compile-time safety that only Firestore-relevant fields appear.
552
562
  *
553
563
  * @group Models
554
564
  */
555
- export interface FirebaseCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>
556
- extends BaseEntityCollection<M, USER> {
565
+ export interface FirebaseCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>
566
+ extends BaseCollectionConfig<M, USER> {
557
567
  /**
558
568
  * The database engine for this collection. Must be set to `"firestore"`.
559
569
  */
560
570
  engine: "firestore";
561
571
 
562
572
  /**
563
- * Set of properties that compose an entity.
573
+ * Set of properties that compose a entity.
564
574
  * Firestore collections support `reference` properties but not `relation`.
565
575
  */
566
576
  properties: FirebaseProperties;
@@ -572,7 +582,7 @@ export interface FirebaseCollection<M extends Record<string, unknown> = Record<s
572
582
  *
573
583
  * @example
574
584
  * ```typescript
575
- * const fsCustomer: FirebaseCollection = {
585
+ * const fsCustomer: FirebaseCollectionConfig = {
576
586
  * slug: "fs_customer", // URL: /c/fs_customer
577
587
  * path: "customer", // Firestore path: customer
578
588
  * name: "Customers (Firestore)",
@@ -586,21 +596,21 @@ export interface FirebaseCollection<M extends Record<string, unknown> = Record<s
586
596
  /**
587
597
  * You can add subcollections to your entity in the same way you define the root
588
598
  * collections. The collections added here will be displayed when opening
589
- * the side dialog of an entity.
599
+ * the side dialog of a entity.
590
600
  */
591
- subcollections?: () => EntityCollection<Record<string, unknown>>[];
601
+ subcollections?: () => CollectionConfig<Record<string, unknown>>[];
592
602
  }
593
603
 
594
604
  /**
595
605
  * A collection backed by MongoDB.
596
606
  *
597
- * Use this type instead of {@link EntityCollection} when you want
607
+ * Use this type instead of {@link CollectionConfig} when you want
598
608
  * compile-time safety that only MongoDB-relevant fields appear.
599
609
  *
600
610
  * @group Models
601
611
  */
602
- export interface MongoDBCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>
603
- extends BaseEntityCollection<M, USER> {
612
+ export interface MongoDBCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>
613
+ extends BaseCollectionConfig<M, USER> {
604
614
 
605
615
  /**
606
616
  * The database engine for this collection. Must be set to `"mongodb"`.
@@ -608,7 +618,7 @@ export interface MongoDBCollection<M extends Record<string, unknown> = Record<st
608
618
  engine: "mongodb";
609
619
 
610
620
  /**
611
- * Set of properties that compose an entity.
621
+ * Set of properties that compose a entity.
612
622
  * MongoDB collections support `reference` properties but not `relation`.
613
623
  */
614
624
  properties: MongoProperties;
@@ -620,7 +630,7 @@ export interface MongoDBCollection<M extends Record<string, unknown> = Record<st
620
630
  *
621
631
  * @example
622
632
  * ```typescript
623
- * const mongoCustomer: MongoDBCollection = {
633
+ * const mongoCustomer: MongoDBCollectionConfig = {
624
634
  * slug: "mongo_customer", // URL: /c/mongo_customer
625
635
  * path: "customer", // MongoDB collection: customer
626
636
  * name: "Customers (MongoDB)",
@@ -634,25 +644,25 @@ export interface MongoDBCollection<M extends Record<string, unknown> = Record<st
634
644
 
635
645
  /**
636
646
  * A collection backed by any data source.
637
- * This is a discriminated union — use {@link PostgresCollection},
638
- * {@link FirebaseCollection}, or {@link MongoDBCollection} for
647
+ * This is a discriminated union — use {@link PostgresCollectionConfig},
648
+ * {@link FirebaseCollectionConfig}, or {@link MongoDBCollectionConfig} for
639
649
  * driver-specific type safety.
640
650
  *
641
651
  * @group Models
642
652
  */
643
- export type EntityCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> =
644
- | PostgresCollection<M, USER>
645
- | FirebaseCollection<M, USER>
646
- | MongoDBCollection<M, USER>;
653
+ export type CollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> =
654
+ | PostgresCollectionConfig<M, USER>
655
+ | FirebaseCollectionConfig<M, USER>
656
+ | MongoDBCollectionConfig<M, USER>;
647
657
 
648
658
  /**
649
659
  * Type guard for PostgreSQL collections.
650
660
  * Returns true if the collection uses the Postgres engine (or the default engine).
651
661
  * @group Models
652
662
  */
653
- export function isPostgresCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(
654
- collection: EntityCollection<M, USER>
655
- ): collection is PostgresCollection<M, USER> {
663
+ export function isPostgresCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(
664
+ collection: CollectionConfig<M, USER>
665
+ ): collection is PostgresCollectionConfig<M, USER> {
656
666
  return !collection.engine || collection.engine === "postgres";
657
667
  }
658
668
 
@@ -660,9 +670,9 @@ export function isPostgresCollection<M extends Record<string, unknown> = Record<
660
670
  * Type guard for Firebase / Firestore collections.
661
671
  * @group Models
662
672
  */
663
- export function isFirebaseCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(
664
- collection: EntityCollection<M, USER>
665
- ): collection is FirebaseCollection<M, USER> {
673
+ export function isFirebaseCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(
674
+ collection: CollectionConfig<M, USER>
675
+ ): collection is FirebaseCollectionConfig<M, USER> {
666
676
  return collection.engine === "firestore";
667
677
  }
668
678
 
@@ -670,9 +680,9 @@ export function isFirebaseCollection<M extends Record<string, unknown> = Record<
670
680
  * Type guard for MongoDB collections.
671
681
  * @group Models
672
682
  */
673
- export function isMongoDBCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(
674
- collection: EntityCollection<M, USER>
675
- ): collection is MongoDBCollection<M, USER> {
683
+ export function isMongoDBCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(
684
+ collection: CollectionConfig<M, USER>
685
+ ): collection is MongoDBCollectionConfig<M, USER> {
676
686
  return collection.engine === "mongodb";
677
687
  }
678
688
 
@@ -682,12 +692,12 @@ export function isMongoDBCollection<M extends Record<string, unknown> = Record<s
682
692
  * otherwise falls back to `slug`.
683
693
  */
684
694
  export function getCollectionDataPath<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(
685
- collection: EntityCollection<M, USER>
695
+ collection: CollectionConfig<M, USER>
686
696
  ): string {
687
- if (isFirebaseCollection(collection) && collection.path) {
697
+ if (isFirebaseCollectionConfig(collection) && collection.path) {
688
698
  return collection.path;
689
699
  }
690
- if (isMongoDBCollection(collection) && collection.path) {
700
+ if (isMongoDBCollectionConfig(collection) && collection.path) {
691
701
  return collection.path;
692
702
  }
693
703
  return collection.slug;
@@ -704,9 +714,9 @@ export function getCollectionDataPath<M extends Record<string, unknown> = Record
704
714
  * @group Models
705
715
  */
706
716
  export function getDeclaredSubcollections<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(
707
- collection: EntityCollection<M, USER>
708
- ): (() => EntityCollection<Record<string, unknown>>[]) | undefined {
709
- return (collection as FirebaseCollection<M, USER>).subcollections;
717
+ collection: CollectionConfig<M, USER>
718
+ ): (() => CollectionConfig<Record<string, unknown>>[]) | undefined {
719
+ return (collection as FirebaseCollectionConfig<M, USER>).subcollections;
710
720
  }
711
721
 
712
722
 
@@ -741,7 +751,7 @@ export type ViewMode = "list" | "table" | "cards" | "kanban";
741
751
  *
742
752
  * @group Models
743
753
  */
744
- export interface CollectionActionsProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User, EC extends EntityCollection<M> = EntityCollection<M>> {
754
+ export interface CollectionActionsProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User, EC extends CollectionConfig<M> = CollectionConfig<M>> {
745
755
  /**
746
756
  * Full collection path of this entity. This is the full path, like
747
757
  * `users/1234/addresses`
@@ -807,7 +817,7 @@ export interface CollectionActionsProps<M extends Record<string, unknown> = Reco
807
817
 
808
818
  /**
809
819
  * Use this controller to retrieve the selected entities or modify them in
810
- * an {@link EntityCollection}
820
+ * an {@link CollectionConfig}
811
821
  * @group Models
812
822
  */
813
823
  export interface SelectionController<M extends Record<string, unknown> = Record<string, unknown>> {
@@ -894,16 +904,16 @@ export interface AdditionalFieldDelegate<M extends Record<string, unknown> = Rec
894
904
  }
895
905
 
896
906
 
897
- export type InferCollectionType<S extends EntityCollection> = S extends EntityCollection<infer M> ? M : never;
907
+ export type InferCollectionConfigType<S extends CollectionConfig> = S extends CollectionConfig<infer M> ? M : never;
898
908
 
899
909
  /**
900
- * Used in the {@link EntityCollection#defaultSelectedView} to define the default
910
+ * Used in the {@link CollectionConfig#defaultSelectedView} to define the default
901
911
  * @group Models
902
912
  */
903
913
  export type DefaultSelectedViewBuilder = (params: DefaultSelectedViewParams) => string | undefined;
904
914
 
905
915
  /**
906
- * Used in the {@link EntityCollection#defaultSelectedView} to define the default
916
+ * Used in the {@link CollectionConfig#defaultSelectedView} to define the default
907
917
  * @group Models
908
918
  */
909
919
  export type DefaultSelectedViewParams = {
@@ -961,7 +971,7 @@ export type SecurityOperation = "select" | "insert" | "update" | "delete" | "all
961
971
  /**
962
972
  * Flexible Row Level Security rule for a collection.
963
973
  *
964
- * Inspired by Supabase's approach to PostgreSQL RLS. Rules can range from
974
+ * Built on PostgreSQL Row Level Security. Rules can range from
965
975
  * simple convenience shortcuts to fully custom SQL expressions, giving you the
966
976
  * full power of PostgreSQL Row Level Security.
967
977
  *
@@ -974,7 +984,7 @@ export type SecurityOperation = "select" | "insert" | "update" | "delete" | "all
974
984
  *
975
985
  * **How rules combine:** PostgreSQL evaluates all matching policies for an
976
986
  * operation. Permissive rules are OR'd together (any one passing is enough).
977
- * Restrictive rules are AND'd (all must pass). This mirrors Supabase behavior.
987
+ * Restrictive rules are AND'd (all must pass). This is standard PostgreSQL RLS behavior.
978
988
  *
979
989
  * **Mutual exclusivity:** `ownerField`, `access`, structured `condition`, and
980
990
  * raw SQL (`using`/`withCheck`) cannot be combined. The type system enforces
@@ -1041,7 +1051,7 @@ export interface SecurityRuleBase {
1041
1051
  * // Equivalent to operation: "all"
1042
1052
  * { operations: ["all"], ownerField: "user_id" }
1043
1053
  */
1044
- operations?: SecurityOperation[];
1054
+ operations?: readonly SecurityOperation[];
1045
1055
 
1046
1056
  /**
1047
1057
  * Whether this policy is `"permissive"` (default) or `"restrictive"`.
@@ -1051,7 +1061,7 @@ export interface SecurityRuleBase {
1051
1061
  * - **restrictive**: Restrictive policies are AND'd with all permissive
1052
1062
  * policies — they act as additional gates that *must* also pass.
1053
1063
  *
1054
- * This is the same model as PostgreSQL / Supabase.
1064
+ * This is the standard PostgreSQL RLS model.
1055
1065
  *
1056
1066
  * @default "permissive"
1057
1067
  */
@@ -1084,7 +1094,7 @@ export interface SecurityRuleBase {
1084
1094
  * // Admins have unfiltered read access to all rows
1085
1095
  * { operation: "select", roles: ["admin"], using: "true" }
1086
1096
  */
1087
- roles?: string[];
1097
+ roles?: readonly string[];
1088
1098
 
1089
1099
  // ── Advanced: native PostgreSQL role targeting ───────────────────────
1090
1100
 
@@ -1109,7 +1119,7 @@ export interface SecurityRuleBase {
1109
1119
  * // Only apply this policy when connected as `app_role`
1110
1120
  * { operation: "select", access: "public", pgRoles: ["app_role"] }
1111
1121
  */
1112
- pgRoles?: string[];
1122
+ pgRoles?: readonly string[];
1113
1123
  }
1114
1124
 
1115
1125
  /**
@@ -1,4 +1,6 @@
1
1
  import type React from "react";
2
+ import type { Property } from "./properties";
3
+ import type { WhereFilterOp } from "./filter-operators";
2
4
 
3
5
  // ── Scoped component name unions ──────────────────────────────────────
4
6
 
@@ -43,13 +45,14 @@ export type CollectionComponentName =
43
45
  | "Collection.Card"
44
46
  | "Collection.EmptyState"
45
47
  | "Collection.Actions"
48
+ | "Collection.FilterField"
46
49
 
47
50
  // ── Entity / Form ──
48
51
  | "Entity.Form"
49
- | "Entity.FormActions"
50
- | "Entity.DetailView"
52
+ | "EditView.FormActions"
53
+ | "DetailView"
51
54
  | "Entity.SidePanel"
52
- | "Entity.Preview"
55
+ | "EntityPreview"
53
56
  | "Entity.MissingReference";
54
57
 
55
58
  /**
@@ -58,6 +61,70 @@ export type CollectionComponentName =
58
61
  */
59
62
  export type OverridableComponentName = AppComponentName | CollectionComponentName;
60
63
 
64
+ /**
65
+ * Props received by a filter field component — whether it is a built-in
66
+ * per-type field, a property-level replacement (`property.ui.Filter`), or a
67
+ * `"Collection.FilterField"` override.
68
+ *
69
+ * The `operators` list is **already resolved**: it is the intersection of the
70
+ * engine's {@link DataSourceCapabilities.filterOperators}, the property-type
71
+ * defaults, and any `property.ui.filterOperators` narrowing. A custom field
72
+ * should only offer operators from this list — anything else may throw at
73
+ * query time on engines that cannot execute it.
74
+ *
75
+ * @example
76
+ * ```tsx
77
+ * function MyStatusFilter({ value, setValue, operators }: FilterFieldBindingProps) {
78
+ * return (
79
+ * <select
80
+ * value={value?.[1] as string ?? ""}
81
+ * onChange={e => setValue(e.target.value ? ["==", e.target.value] : undefined)}>
82
+ * <option value="">Any</option>
83
+ * <option value="active">Active</option>
84
+ * <option value="archived">Archived</option>
85
+ * </select>
86
+ * );
87
+ * }
88
+ * ```
89
+ *
90
+ * @group Component Overrides
91
+ */
92
+ export interface FilterFieldBindingProps {
93
+ /** Key of the property being filtered (the column id). */
94
+ propertyKey: string;
95
+
96
+ /**
97
+ * The resolved property. For array properties this is the **item**
98
+ * property (`property.of`), with `isArray` set to true.
99
+ */
100
+ property: Property;
101
+
102
+ /** True when the underlying property is an array of `property`. */
103
+ isArray: boolean;
104
+
105
+ /**
106
+ * Operators this field may offer, already narrowed by engine
107
+ * capabilities, property-type defaults, and `property.ui.filterOperators`.
108
+ */
109
+ operators: readonly WhereFilterOp[];
110
+
111
+ /** Current filter condition for this property, if any. */
112
+ value?: [WhereFilterOp, unknown];
113
+
114
+ /** Set (or clear, with `undefined`) the filter condition. */
115
+ setValue: (value?: [WhereFilterOp, unknown]) => void;
116
+
117
+ /** Display title for the field (usually the property name). */
118
+ title?: string;
119
+
120
+ /**
121
+ * Coordination flags used by fields that open their own dialogs
122
+ * (e.g. the reference picker hides the parent filters dialog).
123
+ */
124
+ hidden?: boolean;
125
+ setHidden?: (hidden: boolean) => void;
126
+ }
127
+
61
128
  // ── Override entry ────────────────────────────────────────────────────
62
129
 
63
130
  /**
@@ -89,7 +156,7 @@ export type OverridableComponentName = AppComponentName | CollectionComponentNam
89
156
  *
90
157
  * @group Component Overrides
91
158
  */
92
- export interface ComponentOverride<P = any> {
159
+ export interface ComponentOverride<P = Record<string, unknown>> {
93
160
  /**
94
161
  * The replacement component. Receives the same props as the built-in
95
162
  * component it replaces.
@@ -161,7 +228,7 @@ export type CollectionComponentOverrideMap = {
161
228
  * "HomePage": { Component: MyDashboard },
162
229
  *
163
230
  * // Collection defaults: apply to ALL collections
164
- * "Entity.FormActions": {
231
+ * "EditView.FormActions": {
165
232
  * Component: MyFormActions,
166
233
  * wrap: true
167
234
  * },
package/src/types/cron.ts CHANGED
@@ -4,7 +4,7 @@ import type { RebaseClient } from "../controllers/client";
4
4
  * Cron Job type definitions for Rebase.
5
5
  *
6
6
  * These types define the shape of cron job definitions, their runtime
7
- * status, and execution log entries — used across server-core, client,
7
+ * status, and execution log entries — used across server, client,
8
8
  * and studio packages.
9
9
  */
10
10
 
@@ -60,7 +60,16 @@ export interface CronJobContext {
60
60
  /** A simple logger scoped to this job run. */
61
61
  log: (...args: unknown[]) => void;
62
62
 
63
- /** The RebaseClient instance to interact with the database. */
63
+ /**
64
+ * The server-side {@link RebaseClient}. This is the **same singleton**
65
+ * exposed as `rebase` (imported from `@rebasepro/server`) and as
66
+ * `context` in collection callbacks — it is only named `client` here.
67
+ *
68
+ * Its data plane (`client.data`) runs with **admin privileges and bypasses
69
+ * RLS** (`{ uid: "service", roles: ["admin"] }`). There is no per-request
70
+ * user in a cron, so treat every query as fully trusted and scope your own
71
+ * filters explicitly.
72
+ */
64
73
  client: RebaseClient;
65
74
  }
66
75