@rebasepro/types 0.8.0 → 0.9.1-canary.09aaf62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -13
- package/dist/controllers/auth.d.ts +7 -1
- package/dist/controllers/client.d.ts +204 -6
- package/dist/controllers/collection_registry.d.ts +3 -3
- package/dist/controllers/customization_controller.d.ts +1 -1
- package/dist/controllers/data.d.ts +309 -35
- package/dist/controllers/data_driver.d.ts +92 -37
- package/dist/controllers/email.d.ts +2 -2
- package/dist/controllers/index.d.ts +1 -1
- package/dist/controllers/local_config_persistence.d.ts +4 -4
- package/dist/controllers/navigation.d.ts +2 -2
- package/dist/controllers/registry.d.ts +21 -8
- package/dist/controllers/{side_entity_controller.d.ts → side_panel_controller.d.ts} +7 -7
- package/dist/controllers/storage.d.ts +39 -0
- package/dist/errors.d.ts +64 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +160 -15
- package/dist/index.es.js.map +1 -1
- package/dist/rebase_context.d.ts +8 -4
- package/dist/types/auth_adapter.d.ts +29 -4
- package/dist/types/backend.d.ts +33 -26
- package/dist/types/backup.d.ts +20 -0
- package/dist/types/builders.d.ts +2 -2
- package/dist/types/collections.d.ts +84 -75
- package/dist/types/component_overrides.d.ts +61 -3
- package/dist/types/cron.d.ts +11 -2
- package/dist/types/data_source.d.ts +15 -2
- package/dist/types/database_adapter.d.ts +21 -4
- package/dist/types/entities.d.ts +7 -7
- package/dist/types/entity_actions.d.ts +7 -7
- package/dist/types/entity_callbacks.d.ts +39 -39
- package/dist/types/entity_views.d.ts +3 -3
- package/dist/types/filter-operators.d.ts +62 -17
- package/dist/types/index.d.ts +1 -0
- package/dist/types/modify_collections.d.ts +2 -2
- package/dist/types/plugins.d.ts +9 -9
- package/dist/types/policy.d.ts +111 -11
- package/dist/types/properties.d.ts +54 -9
- package/dist/types/relations.d.ts +3 -3
- package/dist/types/slots.d.ts +14 -14
- package/dist/types/translations.d.ts +5 -1
- package/dist/types/user_management_delegate.d.ts +8 -2
- package/dist/types/websockets.d.ts +46 -13
- package/dist/users/user.d.ts +21 -9
- package/package.json +5 -6
- package/src/controllers/auth.tsx +7 -1
- package/src/controllers/client.ts +235 -7
- package/src/controllers/collection_registry.ts +3 -3
- package/src/controllers/customization_controller.tsx +1 -1
- package/src/controllers/data.ts +330 -39
- package/src/controllers/data_driver.ts +93 -40
- package/src/controllers/email.ts +2 -2
- package/src/controllers/index.ts +1 -1
- package/src/controllers/local_config_persistence.tsx +4 -4
- package/src/controllers/navigation.ts +2 -2
- package/src/controllers/registry.ts +22 -8
- package/src/controllers/{side_entity_controller.tsx → side_panel_controller.tsx} +7 -7
- package/src/controllers/storage.ts +60 -1
- package/src/errors.ts +80 -0
- package/src/index.ts +1 -0
- package/src/rebase_context.tsx +8 -4
- package/src/types/auth_adapter.ts +29 -4
- package/src/types/backend.ts +44 -36
- package/src/types/backup.ts +26 -0
- package/src/types/builders.ts +2 -2
- package/src/types/collections.ts +101 -91
- package/src/types/component_overrides.ts +72 -5
- package/src/types/cron.ts +11 -2
- package/src/types/data_source.ts +24 -2
- package/src/types/database_adapter.ts +19 -4
- package/src/types/entities.ts +7 -7
- package/src/types/entity_actions.tsx +7 -7
- package/src/types/entity_callbacks.ts +42 -42
- package/src/types/entity_views.tsx +3 -3
- package/src/types/filter-operators.ts +96 -23
- package/src/types/index.ts +1 -0
- package/src/types/modify_collections.tsx +2 -2
- package/src/types/plugins.tsx +9 -9
- package/src/types/policy.ts +114 -9
- package/src/types/properties.ts +58 -9
- package/src/types/relations.ts +3 -3
- package/src/types/slots.tsx +14 -14
- package/src/types/translations.ts +5 -1
- package/src/types/user_management_delegate.ts +8 -2
- package/src/types/websockets.ts +43 -14
- package/src/users/user.ts +22 -9
- package/dist/index.umd.js +0 -458
- package/dist/index.umd.js.map +0 -1
package/src/types/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
|
*/
|
|
@@ -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
|
|
183
|
-
* authentication collections.
|
|
182
|
+
* Opt out of the framework's default Row Level Security policies.
|
|
184
183
|
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
* `admin` role
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
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
|
-
*
|
|
194
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
212
|
-
*
|
|
213
|
-
* -
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
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
|
|
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?:
|
|
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?:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
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
|
|
501
|
-
extends
|
|
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 (
|
|
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
|
|
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
|
|
556
|
-
extends
|
|
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
|
|
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:
|
|
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
|
|
599
|
+
* the side dialog of a entity.
|
|
590
600
|
*/
|
|
591
|
-
subcollections?: () =>
|
|
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
|
|
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
|
|
603
|
-
extends
|
|
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
|
|
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:
|
|
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
|
|
638
|
-
* {@link
|
|
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
|
|
644
|
-
|
|
|
645
|
-
|
|
|
646
|
-
|
|
|
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
|
|
654
|
-
collection:
|
|
655
|
-
): collection is
|
|
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
|
|
664
|
-
collection:
|
|
665
|
-
): collection is
|
|
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
|
|
674
|
-
collection:
|
|
675
|
-
): collection is
|
|
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:
|
|
695
|
+
collection: CollectionConfig<M, USER>
|
|
686
696
|
): string {
|
|
687
|
-
if (
|
|
697
|
+
if (isFirebaseCollectionConfig(collection) && collection.path) {
|
|
688
698
|
return collection.path;
|
|
689
699
|
}
|
|
690
|
-
if (
|
|
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:
|
|
708
|
-
): (() =>
|
|
709
|
-
return (collection as
|
|
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
|
|
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
|
|
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
|
|
907
|
+
export type InferCollectionConfigType<S extends CollectionConfig> = S extends CollectionConfig<infer M> ? M : never;
|
|
898
908
|
|
|
899
909
|
/**
|
|
900
|
-
* Used in the {@link
|
|
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
|
|
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
|
-
*
|
|
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
|
|
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
|
|
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
|
-
| "
|
|
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
|
@@ -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
|
|
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
|
-
/**
|
|
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
|
|