@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.
- package/README.md +10 -10
- package/dist/controllers/auth.d.ts +1 -1
- package/dist/controllers/client.d.ts +184 -6
- package/dist/controllers/collection_registry.d.ts +3 -3
- package/dist/controllers/customization_controller.d.ts +1 -1
- package/dist/controllers/data.d.ts +267 -35
- package/dist/controllers/data_driver.d.ts +50 -37
- package/dist/controllers/index.d.ts +1 -1
- package/dist/controllers/local_config_persistence.d.ts +4 -4
- package/dist/controllers/navigation.d.ts +2 -2
- package/dist/controllers/registry.d.ts +17 -4
- package/dist/controllers/{side_entity_controller.d.ts → side_panel_controller.d.ts} +7 -7
- package/dist/controllers/storage.d.ts +39 -0
- package/dist/errors.d.ts +64 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +142 -15
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +150 -17
- package/dist/index.umd.js.map +1 -1
- package/dist/rebase_context.d.ts +8 -4
- package/dist/types/auth_adapter.d.ts +4 -1
- package/dist/types/backend.d.ts +26 -26
- package/dist/types/builders.d.ts +2 -2
- package/dist/types/collections.d.ts +62 -63
- package/dist/types/component_overrides.d.ts +61 -3
- package/dist/types/cron.d.ts +10 -1
- package/dist/types/data_source.d.ts +15 -2
- package/dist/types/database_adapter.d.ts +4 -3
- package/dist/types/entities.d.ts +7 -7
- package/dist/types/entity_actions.d.ts +7 -7
- package/dist/types/entity_callbacks.d.ts +39 -39
- package/dist/types/entity_views.d.ts +3 -3
- package/dist/types/filter-operators.d.ts +62 -17
- package/dist/types/modify_collections.d.ts +2 -2
- package/dist/types/plugins.d.ts +9 -9
- package/dist/types/policy.d.ts +64 -10
- package/dist/types/properties.d.ts +41 -9
- package/dist/types/relations.d.ts +3 -3
- package/dist/types/slots.d.ts +14 -14
- package/dist/types/websockets.d.ts +12 -13
- package/dist/users/user.d.ts +21 -9
- package/package.json +1 -1
- package/src/controllers/auth.tsx +1 -1
- package/src/controllers/client.ts +214 -6
- package/src/controllers/collection_registry.ts +3 -3
- package/src/controllers/customization_controller.tsx +1 -1
- package/src/controllers/data.ts +290 -39
- package/src/controllers/data_driver.ts +49 -40
- package/src/controllers/index.ts +1 -1
- package/src/controllers/local_config_persistence.tsx +4 -4
- package/src/controllers/navigation.ts +2 -2
- package/src/controllers/registry.ts +18 -4
- package/src/controllers/{side_entity_controller.tsx → side_panel_controller.tsx} +7 -7
- package/src/controllers/storage.ts +60 -1
- package/src/errors.ts +80 -0
- package/src/index.ts +1 -0
- package/src/rebase_context.tsx +8 -4
- package/src/types/auth_adapter.ts +4 -1
- package/src/types/backend.ts +36 -36
- package/src/types/builders.ts +2 -2
- package/src/types/collections.ts +78 -79
- package/src/types/component_overrides.ts +72 -5
- package/src/types/cron.ts +10 -1
- package/src/types/data_source.ts +24 -2
- package/src/types/database_adapter.ts +4 -3
- package/src/types/entities.ts +7 -7
- package/src/types/entity_actions.tsx +7 -7
- package/src/types/entity_callbacks.ts +42 -42
- package/src/types/entity_views.tsx +3 -3
- package/src/types/filter-operators.ts +96 -23
- package/src/types/modify_collections.tsx +2 -2
- package/src/types/plugins.tsx +9 -9
- package/src/types/policy.ts +64 -8
- package/src/types/properties.ts +44 -9
- package/src/types/relations.ts +3 -3
- package/src/types/slots.tsx +14 -14
- package/src/types/websockets.ts +12 -14
- package/src/users/user.ts +22 -9
package/src/types/collections.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { Dispatch, SetStateAction } from "react";
|
|
2
2
|
import type { Entity, EntityStatus, EntityValues } from "./entities";
|
|
3
|
-
import type {
|
|
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
|
|
21
|
-
* driver-specific type safety, or {@link
|
|
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
|
|
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?: () =>
|
|
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 `
|
|
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
|
|
85
|
-
* {@link
|
|
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
|
|
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
|
|
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
|
|
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
|
*/
|
|
@@ -204,19 +204,18 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
204
204
|
* If you are specifying your collection as code, the order is the same as the
|
|
205
205
|
* one you define in `properties`. Additional columns are added at the
|
|
206
206
|
* end of the list, if the order is not specified.
|
|
207
|
+
*
|
|
207
208
|
* You can use this prop to hide some properties from the table view.
|
|
208
209
|
* Note that if you set this prop, other ways to hide fields, like
|
|
209
210
|
* `hidden` in the property definition, will be ignored.
|
|
210
211
|
* `propertiesOrder` has precedence over `hidden`.
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
* -
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
* `hidden` in the property definition,will be ignored.
|
|
219
|
-
* `propertiesOrder` has precedence over `hidden`.
|
|
212
|
+
*
|
|
213
|
+
* Supported entry formats:
|
|
214
|
+
* - For properties, use the property key.
|
|
215
|
+
* - For additional fields, use the field key.
|
|
216
|
+
* - Child collections (Firestore subcollections, or Postgres relations
|
|
217
|
+
* with `many` cardinality) each get a column with id
|
|
218
|
+
* `subcollection:<slug>`, e.g. `subcollection:orders`.
|
|
220
219
|
*/
|
|
221
220
|
propertiesOrder?: (Extract<keyof M, string> | (string & {}) | string | `subcollection:${string}`)[];
|
|
222
221
|
|
|
@@ -233,11 +232,11 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
233
232
|
selectionEnabled?: boolean;
|
|
234
233
|
|
|
235
234
|
/**
|
|
236
|
-
* This interface defines all the callbacks that can be used when
|
|
235
|
+
* This interface defines all the callbacks that can be used when a entity
|
|
237
236
|
* is being created, updated or deleted.
|
|
238
237
|
* Useful for adding your own logic or blocking the execution of the operation.
|
|
239
238
|
*/
|
|
240
|
-
readonly callbacks?:
|
|
239
|
+
readonly callbacks?: CollectionCallbacks<M, USER>;
|
|
241
240
|
|
|
242
241
|
/**
|
|
243
242
|
* Pass your own selection controller if you want to control selected
|
|
@@ -287,7 +286,7 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
287
286
|
* applied in the collection.
|
|
288
287
|
* e.g. `sort: ["order", "asc"]`
|
|
289
288
|
*/
|
|
290
|
-
readonly sort?:
|
|
289
|
+
readonly sort?: OrderByTuple<Extract<keyof M, string> | (string & {})>;
|
|
291
290
|
|
|
292
291
|
/**
|
|
293
292
|
* You can add additional fields to the collection view by implementing
|
|
@@ -318,7 +317,7 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
318
317
|
|
|
319
318
|
/**
|
|
320
319
|
* If you want to open custom views or subcollections by default when opening the edit
|
|
321
|
-
* view of
|
|
320
|
+
* view of a entity, you can specify the path to the view here.
|
|
322
321
|
* The path is relative to the current collection. For example if you have a collection
|
|
323
322
|
* that has a custom view as well as a subcollection that refers to another entity, you can
|
|
324
323
|
* either specify the path to the custom view or the path to the subcollection.
|
|
@@ -362,7 +361,7 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
362
361
|
metadata?: Record<string, unknown>;
|
|
363
362
|
|
|
364
363
|
/**
|
|
365
|
-
* Width of the side dialog (in pixels) when opening
|
|
364
|
+
* Width of the side dialog (in pixels) when opening a entity in this collection.
|
|
366
365
|
*/
|
|
367
366
|
sideDialogWidth?: number | string;
|
|
368
367
|
|
|
@@ -387,9 +386,9 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
387
386
|
/**
|
|
388
387
|
* Should local changes be backed up in local storage, to prevent data loss on
|
|
389
388
|
* accidental navigations.
|
|
390
|
-
* - `manual_apply`: When the user navigates back to
|
|
389
|
+
* - `manual_apply`: When the user navigates back to a entity with local changes,
|
|
391
390
|
* they will be prompted to restore the changes.
|
|
392
|
-
* - `auto_apply`: When the user navigates back to
|
|
391
|
+
* - `auto_apply`: When the user navigates back to a entity with local changes,
|
|
393
392
|
* the changes will be automatically applied.
|
|
394
393
|
* - `false`: Local changes will not be backed up.
|
|
395
394
|
* Defaults to `manual_apply`.
|
|
@@ -458,7 +457,7 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
458
457
|
* Security rules for this collection (Row Level Security).
|
|
459
458
|
* When defined, the backend enforces access control policies.
|
|
460
459
|
*/
|
|
461
|
-
securityRules?: SecurityRule[];
|
|
460
|
+
securityRules?: readonly SecurityRule[];
|
|
462
461
|
|
|
463
462
|
/**
|
|
464
463
|
* Collection-scoped component overrides. These take precedence over
|
|
@@ -471,7 +470,7 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
471
470
|
*
|
|
472
471
|
* @example
|
|
473
472
|
* ```tsx
|
|
474
|
-
* const productsCollection:
|
|
473
|
+
* const productsCollection: PostgresCollectionConfig = {
|
|
475
474
|
* name: "Products",
|
|
476
475
|
* slug: "products",
|
|
477
476
|
* table: "products",
|
|
@@ -492,13 +491,13 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
492
491
|
* A collection backed by PostgreSQL (or any SQL database).
|
|
493
492
|
* Adds support for SQL-style relations (JOINs) and Row Level Security.
|
|
494
493
|
*
|
|
495
|
-
* Use this type instead of {@link
|
|
494
|
+
* Use this type instead of {@link CollectionConfig} when you want
|
|
496
495
|
* compile-time safety that only SQL-relevant fields appear.
|
|
497
496
|
*
|
|
498
497
|
* @group Models
|
|
499
498
|
*/
|
|
500
|
-
export interface
|
|
501
|
-
extends
|
|
499
|
+
export interface PostgresCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>
|
|
500
|
+
extends BaseCollectionConfig<M, USER> {
|
|
502
501
|
properties: PostgresProperties;
|
|
503
502
|
|
|
504
503
|
/**
|
|
@@ -526,7 +525,7 @@ export interface PostgresCollection<M extends Record<string, unknown> = Record<s
|
|
|
526
525
|
relations?: Relation[];
|
|
527
526
|
|
|
528
527
|
/**
|
|
529
|
-
* Security rules for this collection (
|
|
528
|
+
* Security rules for this collection (PostgreSQL Row Level Security).
|
|
530
529
|
* When defined, the schema generator will enable RLS on the table and
|
|
531
530
|
* create the corresponding PostgreSQL policies.
|
|
532
531
|
*
|
|
@@ -540,27 +539,27 @@ export interface PostgresCollection<M extends Record<string, unknown> = Record<s
|
|
|
540
539
|
* - `auth.roles()` — comma-separated app role IDs
|
|
541
540
|
* - `auth.jwt()` — full JWT claims as JSONB
|
|
542
541
|
*/
|
|
543
|
-
securityRules?: SecurityRule[];
|
|
542
|
+
securityRules?: readonly SecurityRule[];
|
|
544
543
|
}
|
|
545
544
|
|
|
546
545
|
/**
|
|
547
546
|
* A collection backed by Firebase / Firestore.
|
|
548
547
|
* Adds support for subcollections (nested document collections).
|
|
549
548
|
*
|
|
550
|
-
* Use this type instead of {@link
|
|
549
|
+
* Use this type instead of {@link CollectionConfig} when you want
|
|
551
550
|
* compile-time safety that only Firestore-relevant fields appear.
|
|
552
551
|
*
|
|
553
552
|
* @group Models
|
|
554
553
|
*/
|
|
555
|
-
export interface
|
|
556
|
-
extends
|
|
554
|
+
export interface FirebaseCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>
|
|
555
|
+
extends BaseCollectionConfig<M, USER> {
|
|
557
556
|
/**
|
|
558
557
|
* The database engine for this collection. Must be set to `"firestore"`.
|
|
559
558
|
*/
|
|
560
559
|
engine: "firestore";
|
|
561
560
|
|
|
562
561
|
/**
|
|
563
|
-
* Set of properties that compose
|
|
562
|
+
* Set of properties that compose a entity.
|
|
564
563
|
* Firestore collections support `reference` properties but not `relation`.
|
|
565
564
|
*/
|
|
566
565
|
properties: FirebaseProperties;
|
|
@@ -572,7 +571,7 @@ export interface FirebaseCollection<M extends Record<string, unknown> = Record<s
|
|
|
572
571
|
*
|
|
573
572
|
* @example
|
|
574
573
|
* ```typescript
|
|
575
|
-
* const fsCustomer:
|
|
574
|
+
* const fsCustomer: FirebaseCollectionConfig = {
|
|
576
575
|
* slug: "fs_customer", // URL: /c/fs_customer
|
|
577
576
|
* path: "customer", // Firestore path: customer
|
|
578
577
|
* name: "Customers (Firestore)",
|
|
@@ -586,21 +585,21 @@ export interface FirebaseCollection<M extends Record<string, unknown> = Record<s
|
|
|
586
585
|
/**
|
|
587
586
|
* You can add subcollections to your entity in the same way you define the root
|
|
588
587
|
* collections. The collections added here will be displayed when opening
|
|
589
|
-
* the side dialog of
|
|
588
|
+
* the side dialog of a entity.
|
|
590
589
|
*/
|
|
591
|
-
subcollections?: () =>
|
|
590
|
+
subcollections?: () => CollectionConfig<Record<string, unknown>>[];
|
|
592
591
|
}
|
|
593
592
|
|
|
594
593
|
/**
|
|
595
594
|
* A collection backed by MongoDB.
|
|
596
595
|
*
|
|
597
|
-
* Use this type instead of {@link
|
|
596
|
+
* Use this type instead of {@link CollectionConfig} when you want
|
|
598
597
|
* compile-time safety that only MongoDB-relevant fields appear.
|
|
599
598
|
*
|
|
600
599
|
* @group Models
|
|
601
600
|
*/
|
|
602
|
-
export interface
|
|
603
|
-
extends
|
|
601
|
+
export interface MongoDBCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>
|
|
602
|
+
extends BaseCollectionConfig<M, USER> {
|
|
604
603
|
|
|
605
604
|
/**
|
|
606
605
|
* The database engine for this collection. Must be set to `"mongodb"`.
|
|
@@ -608,7 +607,7 @@ export interface MongoDBCollection<M extends Record<string, unknown> = Record<st
|
|
|
608
607
|
engine: "mongodb";
|
|
609
608
|
|
|
610
609
|
/**
|
|
611
|
-
* Set of properties that compose
|
|
610
|
+
* Set of properties that compose a entity.
|
|
612
611
|
* MongoDB collections support `reference` properties but not `relation`.
|
|
613
612
|
*/
|
|
614
613
|
properties: MongoProperties;
|
|
@@ -620,7 +619,7 @@ export interface MongoDBCollection<M extends Record<string, unknown> = Record<st
|
|
|
620
619
|
*
|
|
621
620
|
* @example
|
|
622
621
|
* ```typescript
|
|
623
|
-
* const mongoCustomer:
|
|
622
|
+
* const mongoCustomer: MongoDBCollectionConfig = {
|
|
624
623
|
* slug: "mongo_customer", // URL: /c/mongo_customer
|
|
625
624
|
* path: "customer", // MongoDB collection: customer
|
|
626
625
|
* name: "Customers (MongoDB)",
|
|
@@ -634,25 +633,25 @@ export interface MongoDBCollection<M extends Record<string, unknown> = Record<st
|
|
|
634
633
|
|
|
635
634
|
/**
|
|
636
635
|
* A collection backed by any data source.
|
|
637
|
-
* This is a discriminated union — use {@link
|
|
638
|
-
* {@link
|
|
636
|
+
* This is a discriminated union — use {@link PostgresCollectionConfig},
|
|
637
|
+
* {@link FirebaseCollectionConfig}, or {@link MongoDBCollectionConfig} for
|
|
639
638
|
* driver-specific type safety.
|
|
640
639
|
*
|
|
641
640
|
* @group Models
|
|
642
641
|
*/
|
|
643
|
-
export type
|
|
644
|
-
|
|
|
645
|
-
|
|
|
646
|
-
|
|
|
642
|
+
export type CollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> =
|
|
643
|
+
| PostgresCollectionConfig<M, USER>
|
|
644
|
+
| FirebaseCollectionConfig<M, USER>
|
|
645
|
+
| MongoDBCollectionConfig<M, USER>;
|
|
647
646
|
|
|
648
647
|
/**
|
|
649
648
|
* Type guard for PostgreSQL collections.
|
|
650
649
|
* Returns true if the collection uses the Postgres engine (or the default engine).
|
|
651
650
|
* @group Models
|
|
652
651
|
*/
|
|
653
|
-
export function
|
|
654
|
-
collection:
|
|
655
|
-
): collection is
|
|
652
|
+
export function isPostgresCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(
|
|
653
|
+
collection: CollectionConfig<M, USER>
|
|
654
|
+
): collection is PostgresCollectionConfig<M, USER> {
|
|
656
655
|
return !collection.engine || collection.engine === "postgres";
|
|
657
656
|
}
|
|
658
657
|
|
|
@@ -660,9 +659,9 @@ export function isPostgresCollection<M extends Record<string, unknown> = Record<
|
|
|
660
659
|
* Type guard for Firebase / Firestore collections.
|
|
661
660
|
* @group Models
|
|
662
661
|
*/
|
|
663
|
-
export function
|
|
664
|
-
collection:
|
|
665
|
-
): collection is
|
|
662
|
+
export function isFirebaseCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(
|
|
663
|
+
collection: CollectionConfig<M, USER>
|
|
664
|
+
): collection is FirebaseCollectionConfig<M, USER> {
|
|
666
665
|
return collection.engine === "firestore";
|
|
667
666
|
}
|
|
668
667
|
|
|
@@ -670,9 +669,9 @@ export function isFirebaseCollection<M extends Record<string, unknown> = Record<
|
|
|
670
669
|
* Type guard for MongoDB collections.
|
|
671
670
|
* @group Models
|
|
672
671
|
*/
|
|
673
|
-
export function
|
|
674
|
-
collection:
|
|
675
|
-
): collection is
|
|
672
|
+
export function isMongoDBCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(
|
|
673
|
+
collection: CollectionConfig<M, USER>
|
|
674
|
+
): collection is MongoDBCollectionConfig<M, USER> {
|
|
676
675
|
return collection.engine === "mongodb";
|
|
677
676
|
}
|
|
678
677
|
|
|
@@ -682,12 +681,12 @@ export function isMongoDBCollection<M extends Record<string, unknown> = Record<s
|
|
|
682
681
|
* otherwise falls back to `slug`.
|
|
683
682
|
*/
|
|
684
683
|
export function getCollectionDataPath<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(
|
|
685
|
-
collection:
|
|
684
|
+
collection: CollectionConfig<M, USER>
|
|
686
685
|
): string {
|
|
687
|
-
if (
|
|
686
|
+
if (isFirebaseCollectionConfig(collection) && collection.path) {
|
|
688
687
|
return collection.path;
|
|
689
688
|
}
|
|
690
|
-
if (
|
|
689
|
+
if (isMongoDBCollectionConfig(collection) && collection.path) {
|
|
691
690
|
return collection.path;
|
|
692
691
|
}
|
|
693
692
|
return collection.slug;
|
|
@@ -704,9 +703,9 @@ export function getCollectionDataPath<M extends Record<string, unknown> = Record
|
|
|
704
703
|
* @group Models
|
|
705
704
|
*/
|
|
706
705
|
export function getDeclaredSubcollections<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(
|
|
707
|
-
collection:
|
|
708
|
-
): (() =>
|
|
709
|
-
return (collection as
|
|
706
|
+
collection: CollectionConfig<M, USER>
|
|
707
|
+
): (() => CollectionConfig<Record<string, unknown>>[]) | undefined {
|
|
708
|
+
return (collection as FirebaseCollectionConfig<M, USER>).subcollections;
|
|
710
709
|
}
|
|
711
710
|
|
|
712
711
|
|
|
@@ -741,7 +740,7 @@ export type ViewMode = "list" | "table" | "cards" | "kanban";
|
|
|
741
740
|
*
|
|
742
741
|
* @group Models
|
|
743
742
|
*/
|
|
744
|
-
export interface CollectionActionsProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User, EC extends
|
|
743
|
+
export interface CollectionActionsProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User, EC extends CollectionConfig<M> = CollectionConfig<M>> {
|
|
745
744
|
/**
|
|
746
745
|
* Full collection path of this entity. This is the full path, like
|
|
747
746
|
* `users/1234/addresses`
|
|
@@ -807,7 +806,7 @@ export interface CollectionActionsProps<M extends Record<string, unknown> = Reco
|
|
|
807
806
|
|
|
808
807
|
/**
|
|
809
808
|
* Use this controller to retrieve the selected entities or modify them in
|
|
810
|
-
* an {@link
|
|
809
|
+
* an {@link CollectionConfig}
|
|
811
810
|
* @group Models
|
|
812
811
|
*/
|
|
813
812
|
export interface SelectionController<M extends Record<string, unknown> = Record<string, unknown>> {
|
|
@@ -894,16 +893,16 @@ export interface AdditionalFieldDelegate<M extends Record<string, unknown> = Rec
|
|
|
894
893
|
}
|
|
895
894
|
|
|
896
895
|
|
|
897
|
-
export type
|
|
896
|
+
export type InferCollectionConfigType<S extends CollectionConfig> = S extends CollectionConfig<infer M> ? M : never;
|
|
898
897
|
|
|
899
898
|
/**
|
|
900
|
-
* Used in the {@link
|
|
899
|
+
* Used in the {@link CollectionConfig#defaultSelectedView} to define the default
|
|
901
900
|
* @group Models
|
|
902
901
|
*/
|
|
903
902
|
export type DefaultSelectedViewBuilder = (params: DefaultSelectedViewParams) => string | undefined;
|
|
904
903
|
|
|
905
904
|
/**
|
|
906
|
-
* Used in the {@link
|
|
905
|
+
* Used in the {@link CollectionConfig#defaultSelectedView} to define the default
|
|
907
906
|
* @group Models
|
|
908
907
|
*/
|
|
909
908
|
export type DefaultSelectedViewParams = {
|
|
@@ -961,7 +960,7 @@ export type SecurityOperation = "select" | "insert" | "update" | "delete" | "all
|
|
|
961
960
|
/**
|
|
962
961
|
* Flexible Row Level Security rule for a collection.
|
|
963
962
|
*
|
|
964
|
-
*
|
|
963
|
+
* Built on PostgreSQL Row Level Security. Rules can range from
|
|
965
964
|
* simple convenience shortcuts to fully custom SQL expressions, giving you the
|
|
966
965
|
* full power of PostgreSQL Row Level Security.
|
|
967
966
|
*
|
|
@@ -974,7 +973,7 @@ export type SecurityOperation = "select" | "insert" | "update" | "delete" | "all
|
|
|
974
973
|
*
|
|
975
974
|
* **How rules combine:** PostgreSQL evaluates all matching policies for an
|
|
976
975
|
* operation. Permissive rules are OR'd together (any one passing is enough).
|
|
977
|
-
* Restrictive rules are AND'd (all must pass). This
|
|
976
|
+
* Restrictive rules are AND'd (all must pass). This is standard PostgreSQL RLS behavior.
|
|
978
977
|
*
|
|
979
978
|
* **Mutual exclusivity:** `ownerField`, `access`, structured `condition`, and
|
|
980
979
|
* raw SQL (`using`/`withCheck`) cannot be combined. The type system enforces
|
|
@@ -1041,7 +1040,7 @@ export interface SecurityRuleBase {
|
|
|
1041
1040
|
* // Equivalent to operation: "all"
|
|
1042
1041
|
* { operations: ["all"], ownerField: "user_id" }
|
|
1043
1042
|
*/
|
|
1044
|
-
operations?: SecurityOperation[];
|
|
1043
|
+
operations?: readonly SecurityOperation[];
|
|
1045
1044
|
|
|
1046
1045
|
/**
|
|
1047
1046
|
* Whether this policy is `"permissive"` (default) or `"restrictive"`.
|
|
@@ -1051,7 +1050,7 @@ export interface SecurityRuleBase {
|
|
|
1051
1050
|
* - **restrictive**: Restrictive policies are AND'd with all permissive
|
|
1052
1051
|
* policies — they act as additional gates that *must* also pass.
|
|
1053
1052
|
*
|
|
1054
|
-
* This is the
|
|
1053
|
+
* This is the standard PostgreSQL RLS model.
|
|
1055
1054
|
*
|
|
1056
1055
|
* @default "permissive"
|
|
1057
1056
|
*/
|
|
@@ -1084,7 +1083,7 @@ export interface SecurityRuleBase {
|
|
|
1084
1083
|
* // Admins have unfiltered read access to all rows
|
|
1085
1084
|
* { operation: "select", roles: ["admin"], using: "true" }
|
|
1086
1085
|
*/
|
|
1087
|
-
roles?: string[];
|
|
1086
|
+
roles?: readonly string[];
|
|
1088
1087
|
|
|
1089
1088
|
// ── Advanced: native PostgreSQL role targeting ───────────────────────
|
|
1090
1089
|
|
|
@@ -1109,7 +1108,7 @@ export interface SecurityRuleBase {
|
|
|
1109
1108
|
* // Only apply this policy when connected as `app_role`
|
|
1110
1109
|
* { operation: "select", access: "public", pgRoles: ["app_role"] }
|
|
1111
1110
|
*/
|
|
1112
|
-
pgRoles?: string[];
|
|
1111
|
+
pgRoles?: readonly string[];
|
|
1113
1112
|
}
|
|
1114
1113
|
|
|
1115
1114
|
/**
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type React from "react";
|
|
2
|
+
import type { Property } from "./properties";
|
|
3
|
+
import type { WhereFilterOp } from "./filter-operators";
|
|
2
4
|
|
|
3
5
|
// ── Scoped component name unions ──────────────────────────────────────
|
|
4
6
|
|
|
@@ -43,13 +45,14 @@ export type CollectionComponentName =
|
|
|
43
45
|
| "Collection.Card"
|
|
44
46
|
| "Collection.EmptyState"
|
|
45
47
|
| "Collection.Actions"
|
|
48
|
+
| "Collection.FilterField"
|
|
46
49
|
|
|
47
50
|
// ── Entity / Form ──
|
|
48
51
|
| "Entity.Form"
|
|
49
|
-
| "
|
|
50
|
-
| "
|
|
52
|
+
| "EditView.FormActions"
|
|
53
|
+
| "DetailView"
|
|
51
54
|
| "Entity.SidePanel"
|
|
52
|
-
| "
|
|
55
|
+
| "EntityPreview"
|
|
53
56
|
| "Entity.MissingReference";
|
|
54
57
|
|
|
55
58
|
/**
|
|
@@ -58,6 +61,70 @@ export type CollectionComponentName =
|
|
|
58
61
|
*/
|
|
59
62
|
export type OverridableComponentName = AppComponentName | CollectionComponentName;
|
|
60
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Props received by a filter field component — whether it is a built-in
|
|
66
|
+
* per-type field, a property-level replacement (`property.ui.Filter`), or a
|
|
67
|
+
* `"Collection.FilterField"` override.
|
|
68
|
+
*
|
|
69
|
+
* The `operators` list is **already resolved**: it is the intersection of the
|
|
70
|
+
* engine's {@link DataSourceCapabilities.filterOperators}, the property-type
|
|
71
|
+
* defaults, and any `property.ui.filterOperators` narrowing. A custom field
|
|
72
|
+
* should only offer operators from this list — anything else may throw at
|
|
73
|
+
* query time on engines that cannot execute it.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```tsx
|
|
77
|
+
* function MyStatusFilter({ value, setValue, operators }: FilterFieldBindingProps) {
|
|
78
|
+
* return (
|
|
79
|
+
* <select
|
|
80
|
+
* value={value?.[1] as string ?? ""}
|
|
81
|
+
* onChange={e => setValue(e.target.value ? ["==", e.target.value] : undefined)}>
|
|
82
|
+
* <option value="">Any</option>
|
|
83
|
+
* <option value="active">Active</option>
|
|
84
|
+
* <option value="archived">Archived</option>
|
|
85
|
+
* </select>
|
|
86
|
+
* );
|
|
87
|
+
* }
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* @group Component Overrides
|
|
91
|
+
*/
|
|
92
|
+
export interface FilterFieldBindingProps {
|
|
93
|
+
/** Key of the property being filtered (the column id). */
|
|
94
|
+
propertyKey: string;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* The resolved property. For array properties this is the **item**
|
|
98
|
+
* property (`property.of`), with `isArray` set to true.
|
|
99
|
+
*/
|
|
100
|
+
property: Property;
|
|
101
|
+
|
|
102
|
+
/** True when the underlying property is an array of `property`. */
|
|
103
|
+
isArray: boolean;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Operators this field may offer, already narrowed by engine
|
|
107
|
+
* capabilities, property-type defaults, and `property.ui.filterOperators`.
|
|
108
|
+
*/
|
|
109
|
+
operators: readonly WhereFilterOp[];
|
|
110
|
+
|
|
111
|
+
/** Current filter condition for this property, if any. */
|
|
112
|
+
value?: [WhereFilterOp, unknown];
|
|
113
|
+
|
|
114
|
+
/** Set (or clear, with `undefined`) the filter condition. */
|
|
115
|
+
setValue: (value?: [WhereFilterOp, unknown]) => void;
|
|
116
|
+
|
|
117
|
+
/** Display title for the field (usually the property name). */
|
|
118
|
+
title?: string;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Coordination flags used by fields that open their own dialogs
|
|
122
|
+
* (e.g. the reference picker hides the parent filters dialog).
|
|
123
|
+
*/
|
|
124
|
+
hidden?: boolean;
|
|
125
|
+
setHidden?: (hidden: boolean) => void;
|
|
126
|
+
}
|
|
127
|
+
|
|
61
128
|
// ── Override entry ────────────────────────────────────────────────────
|
|
62
129
|
|
|
63
130
|
/**
|
|
@@ -89,7 +156,7 @@ export type OverridableComponentName = AppComponentName | CollectionComponentNam
|
|
|
89
156
|
*
|
|
90
157
|
* @group Component Overrides
|
|
91
158
|
*/
|
|
92
|
-
export interface ComponentOverride<P =
|
|
159
|
+
export interface ComponentOverride<P = Record<string, unknown>> {
|
|
93
160
|
/**
|
|
94
161
|
* The replacement component. Receives the same props as the built-in
|
|
95
162
|
* component it replaces.
|
|
@@ -161,7 +228,7 @@ export type CollectionComponentOverrideMap = {
|
|
|
161
228
|
* "HomePage": { Component: MyDashboard },
|
|
162
229
|
*
|
|
163
230
|
* // Collection defaults: apply to ALL collections
|
|
164
|
-
* "
|
|
231
|
+
* "EditView.FormActions": {
|
|
165
232
|
* Component: MyFormActions,
|
|
166
233
|
* wrap: true
|
|
167
234
|
* },
|
package/src/types/cron.ts
CHANGED
|
@@ -60,7 +60,16 @@ export interface CronJobContext {
|
|
|
60
60
|
/** A simple logger scoped to this job run. */
|
|
61
61
|
log: (...args: unknown[]) => void;
|
|
62
62
|
|
|
63
|
-
/**
|
|
63
|
+
/**
|
|
64
|
+
* The server-side {@link RebaseClient}. This is the **same singleton**
|
|
65
|
+
* exposed as `rebase` (imported from `@rebasepro/server-core`) and as
|
|
66
|
+
* `context` in collection callbacks — it is only named `client` here.
|
|
67
|
+
*
|
|
68
|
+
* Its data plane (`client.data`) runs with **admin privileges and bypasses
|
|
69
|
+
* RLS** (`{ uid: "service", roles: ["admin"] }`). There is no per-request
|
|
70
|
+
* user in a cron, so treat every query as fully trusted and scope your own
|
|
71
|
+
* filters explicitly.
|
|
72
|
+
*/
|
|
64
73
|
client: RebaseClient;
|
|
65
74
|
}
|
|
66
75
|
|
package/src/types/data_source.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ALL_WHERE_FILTER_OPS, WhereFilterOp } from "./filter-operators";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Describes the capabilities and features supported by a data source (driver).
|
|
3
5
|
*
|
|
@@ -35,6 +37,17 @@ export interface DataSourceCapabilities {
|
|
|
35
37
|
/** Does this source support real-time listeners? */
|
|
36
38
|
supportsRealtime: boolean;
|
|
37
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Canonical filter operators this engine can execute.
|
|
42
|
+
*
|
|
43
|
+
* The admin UI intersects this set with the property-type defaults and
|
|
44
|
+
* any per-property narrowing (`property.ui.filterOperators`) to decide
|
|
45
|
+
* which operators to offer in filter fields — so an engine that cannot
|
|
46
|
+
* run `ilike` (e.g. Firestore) never shows a "Contains" filter that
|
|
47
|
+
* would throw at query time.
|
|
48
|
+
*/
|
|
49
|
+
filterOperators: readonly WhereFilterOp[];
|
|
50
|
+
|
|
38
51
|
// ── Admin capability flags ───────────────────────────────────────
|
|
39
52
|
/** Does this source support SQL admin operations (SQL editor, EXPLAIN, etc.)? */
|
|
40
53
|
supportsSQLAdmin: boolean;
|
|
@@ -102,9 +115,11 @@ export interface DataSourceDefinition {
|
|
|
102
115
|
engine: string;
|
|
103
116
|
|
|
104
117
|
/**
|
|
105
|
-
* How the frontend reaches this source.
|
|
118
|
+
* How the frontend reaches this source. Optional — when omitted it is
|
|
119
|
+
* inferred: `"direct"` if the definition carries a client-side driver,
|
|
120
|
+
* `"server"` otherwise.
|
|
106
121
|
*/
|
|
107
|
-
transport
|
|
122
|
+
transport?: DataSourceTransport;
|
|
108
123
|
|
|
109
124
|
/**
|
|
110
125
|
* The physical database/schema/Firestore-database within the engine.
|
|
@@ -149,6 +164,7 @@ export const POSTGRES_CAPABILITIES: DataSourceCapabilities = {
|
|
|
149
164
|
supportsReferences: false,
|
|
150
165
|
supportsColumnTypes: true,
|
|
151
166
|
supportsRealtime: true,
|
|
167
|
+
filterOperators: ALL_WHERE_FILTER_OPS,
|
|
152
168
|
supportsSQLAdmin: true,
|
|
153
169
|
supportsDocumentAdmin: false,
|
|
154
170
|
supportsSchemaAdmin: true
|
|
@@ -164,6 +180,10 @@ export const FIREBASE_CAPABILITIES: DataSourceCapabilities = {
|
|
|
164
180
|
supportsReferences: true,
|
|
165
181
|
supportsColumnTypes: false,
|
|
166
182
|
supportsRealtime: true,
|
|
183
|
+
// Firestore has no SQL pattern matching — the driver throws on the LIKE
|
|
184
|
+
// family, so the UI must never offer it.
|
|
185
|
+
filterOperators: ALL_WHERE_FILTER_OPS.filter(op =>
|
|
186
|
+
op !== "like" && op !== "ilike" && op !== "not-like" && op !== "not-ilike"),
|
|
167
187
|
supportsSQLAdmin: false,
|
|
168
188
|
supportsDocumentAdmin: false,
|
|
169
189
|
supportsSchemaAdmin: false
|
|
@@ -179,6 +199,7 @@ export const MONGODB_CAPABILITIES: DataSourceCapabilities = {
|
|
|
179
199
|
supportsReferences: true,
|
|
180
200
|
supportsColumnTypes: false,
|
|
181
201
|
supportsRealtime: false,
|
|
202
|
+
filterOperators: ALL_WHERE_FILTER_OPS,
|
|
182
203
|
supportsSQLAdmin: false,
|
|
183
204
|
supportsDocumentAdmin: true,
|
|
184
205
|
supportsSchemaAdmin: true
|
|
@@ -198,6 +219,7 @@ export const DEFAULT_CAPABILITIES: DataSourceCapabilities = {
|
|
|
198
219
|
supportsReferences: true,
|
|
199
220
|
supportsColumnTypes: true,
|
|
200
221
|
supportsRealtime: true,
|
|
222
|
+
filterOperators: ALL_WHERE_FILTER_OPS,
|
|
201
223
|
supportsSQLAdmin: true,
|
|
202
224
|
supportsDocumentAdmin: true,
|
|
203
225
|
supportsSchemaAdmin: true
|