@rebasepro/server-postgresql 0.0.1-canary.4d4fb3e → 0.0.1-canary.5584634
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/dist/common/src/collections/CollectionRegistry.d.ts +8 -0
- package/dist/common/src/util/entities.d.ts +22 -0
- package/dist/common/src/util/relations.d.ts +14 -4
- package/dist/common/src/util/resolutions.d.ts +1 -1
- package/dist/index.es.js +1254 -591
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1254 -591
- package/dist/index.umd.js.map +1 -1
- package/dist/server-postgresql/src/PostgresBackendDriver.d.ts +17 -29
- package/dist/server-postgresql/src/auth/services.d.ts +7 -3
- package/dist/server-postgresql/src/collections/PostgresCollectionRegistry.d.ts +1 -1
- package/dist/server-postgresql/src/connection.d.ts +34 -1
- package/dist/server-postgresql/src/data-transformer.d.ts +26 -4
- package/dist/server-postgresql/src/databasePoolManager.d.ts +2 -2
- package/dist/server-postgresql/src/schema/auth-schema.d.ts +139 -38
- package/dist/server-postgresql/src/schema/doctor-cli.d.ts +2 -0
- package/dist/server-postgresql/src/schema/doctor.d.ts +43 -0
- package/dist/server-postgresql/src/schema/generate-drizzle-schema-logic.d.ts +1 -1
- package/dist/server-postgresql/src/schema/introspect-db-logic.d.ts +82 -0
- package/dist/server-postgresql/src/schema/introspect-db.d.ts +1 -0
- package/dist/server-postgresql/src/schema/test-schema.d.ts +24 -0
- package/dist/server-postgresql/src/services/EntityFetchService.d.ts +22 -8
- package/dist/server-postgresql/src/services/EntityPersistService.d.ts +1 -1
- package/dist/server-postgresql/src/services/RelationService.d.ts +11 -5
- package/dist/server-postgresql/src/services/entity-helpers.d.ts +16 -2
- package/dist/server-postgresql/src/services/entityService.d.ts +8 -6
- package/dist/server-postgresql/src/services/realtimeService.d.ts +2 -0
- package/dist/server-postgresql/src/utils/drizzle-conditions.d.ts +2 -2
- package/dist/types/src/controllers/auth.d.ts +2 -0
- package/dist/types/src/controllers/client.d.ts +119 -7
- package/dist/types/src/controllers/collection_registry.d.ts +4 -3
- package/dist/types/src/controllers/customization_controller.d.ts +7 -1
- package/dist/types/src/controllers/data.d.ts +34 -7
- package/dist/types/src/controllers/data_driver.d.ts +20 -28
- package/dist/types/src/controllers/database_admin.d.ts +2 -2
- package/dist/types/src/controllers/email.d.ts +34 -0
- package/dist/types/src/controllers/index.d.ts +1 -0
- package/dist/types/src/controllers/local_config_persistence.d.ts +4 -4
- package/dist/types/src/controllers/navigation.d.ts +5 -5
- package/dist/types/src/controllers/registry.d.ts +6 -3
- package/dist/types/src/controllers/side_entity_controller.d.ts +7 -6
- package/dist/types/src/controllers/storage.d.ts +24 -26
- package/dist/types/src/rebase_context.d.ts +8 -4
- package/dist/types/src/types/backend.d.ts +4 -1
- package/dist/types/src/types/builders.d.ts +5 -4
- package/dist/types/src/types/chips.d.ts +1 -1
- package/dist/types/src/types/collections.d.ts +169 -125
- package/dist/types/src/types/cron.d.ts +102 -0
- package/dist/types/src/types/data_source.d.ts +1 -1
- package/dist/types/src/types/entity_actions.d.ts +8 -8
- package/dist/types/src/types/entity_callbacks.d.ts +15 -15
- package/dist/types/src/types/entity_link_builder.d.ts +1 -1
- package/dist/types/src/types/entity_overrides.d.ts +2 -1
- package/dist/types/src/types/entity_views.d.ts +8 -8
- package/dist/types/src/types/export_import.d.ts +3 -3
- package/dist/types/src/types/index.d.ts +1 -0
- package/dist/types/src/types/plugins.d.ts +72 -18
- package/dist/types/src/types/properties.d.ts +118 -33
- package/dist/types/src/types/relations.d.ts +1 -1
- package/dist/types/src/types/slots.d.ts +30 -6
- package/dist/types/src/types/translations.d.ts +44 -0
- package/dist/types/src/types/user_management_delegate.d.ts +1 -0
- package/drizzle-test/0000_woozy_junta.sql +6 -0
- package/drizzle-test/0001_youthful_arachne.sql +1 -0
- package/drizzle-test/0002_lively_dragon_lord.sql +2 -0
- package/drizzle-test/0003_mean_king_cobra.sql +2 -0
- package/drizzle-test/meta/0000_snapshot.json +47 -0
- package/drizzle-test/meta/0001_snapshot.json +48 -0
- package/drizzle-test/meta/0002_snapshot.json +38 -0
- package/drizzle-test/meta/0003_snapshot.json +48 -0
- package/drizzle-test/meta/_journal.json +34 -0
- package/drizzle-test-out/0000_tan_trauma.sql +6 -0
- package/drizzle-test-out/0001_rapid_drax.sql +1 -0
- package/drizzle-test-out/meta/0000_snapshot.json +44 -0
- package/drizzle-test-out/meta/0001_snapshot.json +54 -0
- package/drizzle-test-out/meta/_journal.json +20 -0
- package/drizzle.test.config.ts +10 -0
- package/package.json +89 -89
- package/scratch.ts +41 -0
- package/src/PostgresBackendDriver.ts +63 -79
- package/src/PostgresBootstrapper.ts +7 -8
- package/src/auth/ensure-tables.ts +158 -86
- package/src/auth/services.ts +109 -50
- package/src/cli.ts +317 -16
- package/src/collections/PostgresCollectionRegistry.ts +6 -6
- package/src/connection.ts +70 -48
- package/src/data-transformer.ts +155 -116
- package/src/databasePoolManager.ts +6 -5
- package/src/history/HistoryService.ts +3 -12
- package/src/interfaces.ts +3 -3
- package/src/schema/auth-schema.ts +26 -3
- package/src/schema/doctor-cli.ts +47 -0
- package/src/schema/doctor.ts +595 -0
- package/src/schema/generate-drizzle-schema-logic.ts +204 -57
- package/src/schema/generate-drizzle-schema.ts +6 -6
- package/src/schema/introspect-db-logic.ts +592 -0
- package/src/schema/introspect-db.ts +211 -0
- package/src/schema/test-schema.ts +11 -0
- package/src/services/BranchService.ts +5 -5
- package/src/services/EntityFetchService.ts +317 -188
- package/src/services/EntityPersistService.ts +15 -17
- package/src/services/RelationService.ts +299 -37
- package/src/services/entity-helpers.ts +39 -13
- package/src/services/entityService.ts +11 -9
- package/src/services/realtimeService.ts +58 -29
- package/src/utils/drizzle-conditions.ts +25 -24
- package/src/websocket.ts +52 -21
- package/test/auth-services.test.ts +131 -39
- package/test/batch-many-to-many-regression.test.ts +573 -0
- package/test/branchService.test.ts +22 -12
- package/test/data-transformer-hardening.test.ts +417 -0
- package/test/data-transformer.test.ts +175 -0
- package/test/doctor.test.ts +182 -0
- package/test/entityService.errors.test.ts +31 -16
- package/test/entityService.relations.test.ts +155 -59
- package/test/entityService.subcollection-search.test.ts +107 -57
- package/test/entityService.test.ts +105 -47
- package/test/generate-drizzle-schema.test.ts +262 -69
- package/test/historyService.test.ts +31 -16
- package/test/introspect-db-generation.test.ts +436 -0
- package/test/introspect-db-utils.test.ts +389 -0
- package/test/n-plus-one-regression.test.ts +314 -0
- package/test/postgresDataDriver.test.ts +260 -168
- package/test/realtimeService.test.ts +70 -39
- package/test/relation-pipeline-gaps.test.ts +637 -0
- package/test/relations.test.ts +492 -39
- package/test/unmapped-tables-safety.test.ts +345 -0
- package/test-drizzle-bug.ts +18 -0
- package/test-drizzle-out/0000_cultured_freak.sql +7 -0
- package/test-drizzle-out/0001_tiresome_professor_monster.sql +1 -0
- package/test-drizzle-out/meta/0000_snapshot.json +55 -0
- package/test-drizzle-out/meta/0001_snapshot.json +63 -0
- package/test-drizzle-out/meta/_journal.json +20 -0
- package/test-drizzle-prompt.sh +2 -0
- package/test-policy-prompt.sh +3 -0
- package/test-programmatic.ts +30 -0
- package/test-programmatic2.ts +59 -0
- package/test-schema-no-policies.ts +12 -0
- package/test_drizzle_mock.js +2 -2
- package/test_find_changed.mjs +3 -1
- package/test_hash.js +14 -0
- package/tsconfig.json +1 -1
- package/vite.config.ts +5 -5
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Entity, EntityStatus } from "./entities";
|
|
3
|
-
import { EntityCallbacks } from "./entity_callbacks";
|
|
4
|
-
import { Properties } from "./properties";
|
|
5
|
-
import { ExportConfig } from "./export_import";
|
|
6
|
-
import { EntityOverrides } from "./entity_overrides";
|
|
7
|
-
import { User } from "../users";
|
|
8
|
-
import { RebaseContext } from "../rebase_context";
|
|
9
|
-
import { Relation } from "./relations";
|
|
10
|
-
import { EntityCustomView } from "./entity_views";
|
|
11
|
-
import { EntityAction } from "./entity_actions";
|
|
2
|
+
import type { Entity, EntityStatus } from "./entities";
|
|
3
|
+
import type { EntityCallbacks } from "./entity_callbacks";
|
|
4
|
+
import type { Properties } from "./properties";
|
|
5
|
+
import type { ExportConfig } from "./export_import";
|
|
6
|
+
import type { EntityOverrides } from "./entity_overrides";
|
|
7
|
+
import type { User } from "../users";
|
|
8
|
+
import type { RebaseContext } from "../rebase_context";
|
|
9
|
+
import type { Relation } from "./relations";
|
|
10
|
+
import type { EntityCustomView } from "./entity_views";
|
|
11
|
+
import type { EntityAction } from "./entity_actions";
|
|
12
12
|
/**
|
|
13
13
|
* Base interface containing all driver-agnostic collection properties.
|
|
14
14
|
* Use {@link PostgresCollection} or {@link FirebaseCollection} for
|
|
@@ -98,6 +98,11 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
98
98
|
* Default preview properties displayed when this collection is referenced to.
|
|
99
99
|
*/
|
|
100
100
|
previewProperties?: string[];
|
|
101
|
+
/**
|
|
102
|
+
* Properties to display as columns in the list view.
|
|
103
|
+
* If not specified, the list view uses a smart default (Title, Status, Date).
|
|
104
|
+
*/
|
|
105
|
+
listProperties?: string[];
|
|
101
106
|
/**
|
|
102
107
|
* Title property of the entity. This is the property that will be used
|
|
103
108
|
* as the title in entity related views and references.
|
|
@@ -108,7 +113,7 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
108
113
|
* When editing an entity, you can choose to open the entity in a side dialog
|
|
109
114
|
* or in a full screen dialog. Defaults to `full_screen`.
|
|
110
115
|
*/
|
|
111
|
-
openEntityMode?: "side_panel" | "full_screen";
|
|
116
|
+
openEntityMode?: "side_panel" | "full_screen" | "split";
|
|
112
117
|
/**
|
|
113
118
|
* Order in which the properties are displayed.
|
|
114
119
|
* If you are specifying your collection as code, the order is the same as the
|
|
@@ -262,7 +267,7 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
262
267
|
localChangesBackup?: "manual_apply" | "auto_apply" | false;
|
|
263
268
|
/**
|
|
264
269
|
* Default view mode for displaying this collection.
|
|
265
|
-
* - "table": Display entities in a
|
|
270
|
+
* - "table": Display entities in a table with inline editing (default)
|
|
266
271
|
* - "cards": Display entities as a grid of cards with thumbnails
|
|
267
272
|
* - "kanban": Display entities in a Kanban board grouped by a property
|
|
268
273
|
* Defaults to "table".
|
|
@@ -283,9 +288,10 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
283
288
|
kanban?: KanbanConfig<M>;
|
|
284
289
|
/**
|
|
285
290
|
* Property key to use for ordering items.
|
|
286
|
-
* Must reference a
|
|
287
|
-
* this property will be updated
|
|
288
|
-
*
|
|
291
|
+
* Must reference a string/text property. When items are reordered,
|
|
292
|
+
* this property will be updated with lexicographic sort keys
|
|
293
|
+
* (e.g. "a0", "a1", "a0V") using string-based fractional indexing.
|
|
294
|
+
* Used by Kanban view for ordering within columns
|
|
289
295
|
* and can be used for general ordering purposes.
|
|
290
296
|
*/
|
|
291
297
|
readonly orderProperty?: Extract<keyof M, string> | (string & {});
|
|
@@ -317,11 +323,6 @@ export interface PostgresCollection<M extends Record<string, unknown> = Record<s
|
|
|
317
323
|
* The PostgreSQL table name for this collection.
|
|
318
324
|
*/
|
|
319
325
|
table: string;
|
|
320
|
-
/**
|
|
321
|
-
* Set by the backend when the resolved table name doesn't match
|
|
322
|
-
* an actual table in the database schema.
|
|
323
|
-
*/
|
|
324
|
-
isTableMissing?: boolean;
|
|
325
326
|
/**
|
|
326
327
|
* For SQL databases, you can define the relations between collections here.
|
|
327
328
|
* Relations describe JOINs, foreign keys, and junction tables.
|
|
@@ -365,14 +366,39 @@ export interface FirebaseCollection<M extends Record<string, unknown> = Record<s
|
|
|
365
366
|
*/
|
|
366
367
|
subcollections?: () => EntityCollection<Record<string, unknown>>[];
|
|
367
368
|
}
|
|
369
|
+
/**
|
|
370
|
+
* A collection backed by MongoDB.
|
|
371
|
+
*
|
|
372
|
+
* Use this type instead of {@link EntityCollection} when you want
|
|
373
|
+
* compile-time safety that only MongoDB-relevant fields appear.
|
|
374
|
+
*
|
|
375
|
+
* @group Models
|
|
376
|
+
*/
|
|
377
|
+
export interface MongoDBCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> extends BaseEntityCollection<M, USER> {
|
|
378
|
+
/**
|
|
379
|
+
* The driver for this collection. Must be set to `"mongodb"`.
|
|
380
|
+
*/
|
|
381
|
+
driver: "mongodb";
|
|
382
|
+
}
|
|
368
383
|
/**
|
|
369
384
|
* A collection backed by any data source.
|
|
370
|
-
* This is a discriminated union — use {@link PostgresCollection}
|
|
371
|
-
* {@link FirebaseCollection}
|
|
385
|
+
* This is a discriminated union — use {@link PostgresCollection},
|
|
386
|
+
* {@link FirebaseCollection}, or {@link MongoDBCollection} for
|
|
387
|
+
* driver-specific type safety.
|
|
372
388
|
*
|
|
373
389
|
* @group Models
|
|
374
390
|
*/
|
|
375
|
-
export type EntityCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> = PostgresCollection<M, USER> | FirebaseCollection<M, USER>;
|
|
391
|
+
export type EntityCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> = PostgresCollection<M, USER> | FirebaseCollection<M, USER> | MongoDBCollection<M, USER>;
|
|
392
|
+
/** An EntityCollection that supports SQL-style relations (e.g. Postgres). */
|
|
393
|
+
export type CollectionWithRelations<M extends Record<string, unknown> = Record<string, unknown>> = EntityCollection<M> & {
|
|
394
|
+
table?: string;
|
|
395
|
+
relations?: Relation[];
|
|
396
|
+
securityRules?: SecurityRule[];
|
|
397
|
+
};
|
|
398
|
+
/** An EntityCollection that supports subcollections (e.g. Firestore). */
|
|
399
|
+
export type CollectionWithSubcollections<M extends Record<string, unknown> = Record<string, unknown>> = EntityCollection<M> & {
|
|
400
|
+
subcollections?: () => EntityCollection<Record<string, unknown>>[];
|
|
401
|
+
};
|
|
376
402
|
/**
|
|
377
403
|
* Type guard for PostgreSQL collections.
|
|
378
404
|
* Returns true if the collection uses the Postgres driver (or the default driver).
|
|
@@ -384,6 +410,11 @@ export declare function isPostgresCollection<M extends Record<string, unknown> =
|
|
|
384
410
|
* @group Models
|
|
385
411
|
*/
|
|
386
412
|
export declare function isFirebaseCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(collection: EntityCollection<M, USER>): collection is FirebaseCollection<M, USER>;
|
|
413
|
+
/**
|
|
414
|
+
* Type guard for MongoDB collections.
|
|
415
|
+
* @group Models
|
|
416
|
+
*/
|
|
417
|
+
export declare function isMongoDBCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(collection: EntityCollection<M, USER>): collection is MongoDBCollection<M, USER>;
|
|
387
418
|
/**
|
|
388
419
|
* Configuration for Kanban board view mode.
|
|
389
420
|
* @group Collections
|
|
@@ -399,9 +430,13 @@ export interface KanbanConfig<M extends Record<string, unknown> = Record<string,
|
|
|
399
430
|
}
|
|
400
431
|
/**
|
|
401
432
|
* View mode for displaying a collection.
|
|
433
|
+
* - "list": Simple, clean list view — the classic CMS default
|
|
434
|
+
* - "table": Table with inline editing
|
|
435
|
+
* - "cards": Grid of visual cards with thumbnails
|
|
436
|
+
* - "kanban": Board view grouped by a property
|
|
402
437
|
* @group Collections
|
|
403
438
|
*/
|
|
404
|
-
export type ViewMode = "table" | "cards" | "kanban";
|
|
439
|
+
export type ViewMode = "list" | "table" | "cards" | "kanban";
|
|
405
440
|
/**
|
|
406
441
|
* Parameter passed to the `Actions` prop in the collection configuration.
|
|
407
442
|
* The component will receive this prop when it is rendered in the collection
|
|
@@ -610,9 +645,18 @@ export type SecurityOperation = "select" | "insert" | "update" | "delete" | "all
|
|
|
610
645
|
* operation. Permissive rules are OR'd together (any one passing is enough).
|
|
611
646
|
* Restrictive rules are AND'd (all must pass). This mirrors Supabase behavior.
|
|
612
647
|
*
|
|
648
|
+
* **Mutual exclusivity:** `ownerField`, `access`, and raw SQL (`using`/`withCheck`)
|
|
649
|
+
* cannot be combined. The type system enforces this — attempting to set
|
|
650
|
+
* conflicting fields will produce a compile-time error.
|
|
651
|
+
*
|
|
613
652
|
* @group Models
|
|
614
653
|
*/
|
|
615
|
-
export
|
|
654
|
+
export type SecurityRule = OwnerSecurityRule | PublicSecurityRule | RawSQLSecurityRule | RolesOnlySecurityRule;
|
|
655
|
+
/**
|
|
656
|
+
* Shared fields for all SecurityRule variants.
|
|
657
|
+
* @group Models
|
|
658
|
+
*/
|
|
659
|
+
export interface SecurityRuleBase {
|
|
616
660
|
/**
|
|
617
661
|
* Optional human-readable name for the policy.
|
|
618
662
|
* If not provided, one will be auto-generated from the table name and operation.
|
|
@@ -664,35 +708,6 @@ export interface SecurityRule {
|
|
|
664
708
|
* @default "permissive"
|
|
665
709
|
*/
|
|
666
710
|
mode?: "permissive" | "restrictive";
|
|
667
|
-
/**
|
|
668
|
-
* **Shortcut.** The property (column) that stores the owner's user ID.
|
|
669
|
-
* Generates a USING/WITH CHECK clause like:
|
|
670
|
-
* `<column> = auth.uid()`
|
|
671
|
-
*
|
|
672
|
-
* Cannot be combined with `using` / `withCheck` / `access`.
|
|
673
|
-
*
|
|
674
|
-
* @example
|
|
675
|
-
* { operation: "all", ownerField: "user_id" }
|
|
676
|
-
*/
|
|
677
|
-
ownerField?: string;
|
|
678
|
-
/**
|
|
679
|
-
* **Shortcut.** Grant unrestricted row access (no row filtering) for this operation.
|
|
680
|
-
* Generates `USING (true)`.
|
|
681
|
-
*
|
|
682
|
-
* This means "no row-level filter", NOT "anonymous/unauthenticated access".
|
|
683
|
-
* Authentication is still enforced at the API layer — this only controls which
|
|
684
|
-
* *rows* authenticated users can see.
|
|
685
|
-
*
|
|
686
|
-
* Typically used alone for genuinely public read endpoints, or combined with
|
|
687
|
-
* `roles` to give certain roles an unfiltered view of the table.
|
|
688
|
-
*
|
|
689
|
-
* Cannot be combined with `using` / `withCheck` / `ownerField`.
|
|
690
|
-
*
|
|
691
|
-
* @example
|
|
692
|
-
* // Public read (any authenticated user sees all rows)
|
|
693
|
-
* { operation: "select", access: "public" }
|
|
694
|
-
*/
|
|
695
|
-
access?: "public";
|
|
696
711
|
/**
|
|
697
712
|
* **Shortcut.** Restrict this rule to users that have one of these
|
|
698
713
|
* application-level roles.
|
|
@@ -716,77 +731,6 @@ export interface SecurityRule {
|
|
|
716
731
|
* { operation: "select", roles: ["admin"], using: "true" }
|
|
717
732
|
*/
|
|
718
733
|
roles?: string[];
|
|
719
|
-
/**
|
|
720
|
-
* Raw SQL expression for the `USING` clause.
|
|
721
|
-
* This controls which *existing* rows are visible / can be modified / deleted.
|
|
722
|
-
* Applied to SELECT, UPDATE, and DELETE.
|
|
723
|
-
*
|
|
724
|
-
* You can reference columns via `{column_name}` which will be resolved to
|
|
725
|
-
* `table.column_name` in the generated Drizzle code. You can also use any
|
|
726
|
-
* valid PostgreSQL expression.
|
|
727
|
-
*
|
|
728
|
-
* Cannot be combined with `ownerField` or `access`.
|
|
729
|
-
*
|
|
730
|
-
* @example
|
|
731
|
-
* // Rows published in the last 30 days are visible
|
|
732
|
-
* { operation: "select", using: "{published_at} > now() - interval '30 days'" }
|
|
733
|
-
*
|
|
734
|
-
* @example
|
|
735
|
-
* // Only the owner, or users with 'moderator' role
|
|
736
|
-
* {
|
|
737
|
-
* operation: "select",
|
|
738
|
-
* using: "{user_id} = auth.uid() OR auth.roles() ~ 'moderator'"
|
|
739
|
-
* }
|
|
740
|
-
*
|
|
741
|
-
* @example
|
|
742
|
-
* // Cross-table subquery: only if user belongs to the org
|
|
743
|
-
* {
|
|
744
|
-
* operation: "select",
|
|
745
|
-
* using: "EXISTS (SELECT 1 FROM org_members WHERE org_members.org_id = {org_id} AND org_members.user_id = auth.uid())"
|
|
746
|
-
* }
|
|
747
|
-
*/
|
|
748
|
-
using?: string;
|
|
749
|
-
/**
|
|
750
|
-
* Raw SQL expression for the `WITH CHECK` clause.
|
|
751
|
-
* This controls which *new/updated* row values are allowed.
|
|
752
|
-
* Applied to INSERT and UPDATE.
|
|
753
|
-
*
|
|
754
|
-
* Same syntax as `using` — use `{column_name}` to reference columns.
|
|
755
|
-
*
|
|
756
|
-
* **Important for UPDATE:** PostgreSQL evaluates two row states — the
|
|
757
|
-
* *existing* row (`USING`) and the *incoming new* row (`WITH CHECK`).
|
|
758
|
-
* If you only specify `using`, the same expression is used for both.
|
|
759
|
-
* For security-sensitive updates, always specify `withCheck` explicitly
|
|
760
|
-
* to constrain what the new row values can be.
|
|
761
|
-
*
|
|
762
|
-
* If not provided on INSERT/UPDATE policies, falls back to `using`
|
|
763
|
-
* (which matches PostgreSQL's own default behavior).
|
|
764
|
-
*
|
|
765
|
-
* Cannot be combined with `ownerField` or `access`.
|
|
766
|
-
*
|
|
767
|
-
* @example
|
|
768
|
-
* // Users can only insert rows where they are the owner
|
|
769
|
-
* { operation: "insert", withCheck: "{user_id} = auth.uid()" }
|
|
770
|
-
*
|
|
771
|
-
* @example
|
|
772
|
-
* // Prevent changing the status to 'archived' unless admin
|
|
773
|
-
* {
|
|
774
|
-
* operation: "update",
|
|
775
|
-
* using: "{user_id} = auth.uid()",
|
|
776
|
-
* withCheck: "{status} != 'archived' OR auth.roles() ~ 'admin'"
|
|
777
|
-
* }
|
|
778
|
-
*
|
|
779
|
-
* @example
|
|
780
|
-
* // Restrictive gate: prevent locking AND unlocking unless admin.
|
|
781
|
-
* // `using` checks the old row state, `withCheck` checks the new.
|
|
782
|
-
* {
|
|
783
|
-
* operation: "update",
|
|
784
|
-
* mode: "restrictive",
|
|
785
|
-
* using: "{is_locked} = false",
|
|
786
|
-
* withCheck: "{is_locked} = false"
|
|
787
|
-
* }
|
|
788
|
-
*/
|
|
789
|
-
withCheck?: string;
|
|
790
734
|
/**
|
|
791
735
|
* **Advanced.** Native PostgreSQL database roles the policy applies to.
|
|
792
736
|
*
|
|
@@ -810,3 +754,103 @@ export interface SecurityRule {
|
|
|
810
754
|
*/
|
|
811
755
|
pgRoles?: string[];
|
|
812
756
|
}
|
|
757
|
+
/**
|
|
758
|
+
* Security rule that grants access based on row ownership.
|
|
759
|
+
* Generates a USING/WITH CHECK clause like: `<column> = auth.uid()`
|
|
760
|
+
*
|
|
761
|
+
* Cannot be combined with `using`, `withCheck`, or `access`.
|
|
762
|
+
*
|
|
763
|
+
* @example
|
|
764
|
+
* { operation: "all", ownerField: "user_id" }
|
|
765
|
+
*
|
|
766
|
+
* @group Models
|
|
767
|
+
*/
|
|
768
|
+
export interface OwnerSecurityRule extends SecurityRuleBase {
|
|
769
|
+
/** The property (column) that stores the owner's user ID. */
|
|
770
|
+
ownerField: string;
|
|
771
|
+
access?: never;
|
|
772
|
+
using?: never;
|
|
773
|
+
withCheck?: never;
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Security rule that grants unrestricted row access (no row filtering).
|
|
777
|
+
* Generates `USING (true)`.
|
|
778
|
+
*
|
|
779
|
+
* This means "no row-level filter", NOT "anonymous/unauthenticated access".
|
|
780
|
+
* Authentication is still enforced at the API layer — this only controls which
|
|
781
|
+
* *rows* authenticated users can see.
|
|
782
|
+
*
|
|
783
|
+
* Cannot be combined with `using`, `withCheck`, or `ownerField`.
|
|
784
|
+
*
|
|
785
|
+
* @example
|
|
786
|
+
* // Public read (any authenticated user sees all rows)
|
|
787
|
+
* { operation: "select", access: "public" }
|
|
788
|
+
*
|
|
789
|
+
* @group Models
|
|
790
|
+
*/
|
|
791
|
+
export interface PublicSecurityRule extends SecurityRuleBase {
|
|
792
|
+
/** Grant unrestricted row access for this operation. */
|
|
793
|
+
access: "public";
|
|
794
|
+
ownerField?: never;
|
|
795
|
+
using?: never;
|
|
796
|
+
withCheck?: never;
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* Security rule using raw SQL expressions for full PostgreSQL RLS power.
|
|
800
|
+
*
|
|
801
|
+
* Cannot be combined with `ownerField` or `access`.
|
|
802
|
+
*
|
|
803
|
+
* You can reference columns via `{column_name}` which will be resolved to
|
|
804
|
+
* `table.column_name` in the generated Drizzle code.
|
|
805
|
+
*
|
|
806
|
+
* @example
|
|
807
|
+
* // Rows published in the last 30 days are visible
|
|
808
|
+
* { operation: "select", using: "{published_at} > now() - interval '30 days'" }
|
|
809
|
+
*
|
|
810
|
+
* @example
|
|
811
|
+
* // Only the owner, or users with 'moderator' role
|
|
812
|
+
* {
|
|
813
|
+
* operation: "select",
|
|
814
|
+
* using: "{user_id} = auth.uid() OR auth.roles() ~ 'moderator'"
|
|
815
|
+
* }
|
|
816
|
+
*
|
|
817
|
+
* @group Models
|
|
818
|
+
*/
|
|
819
|
+
export interface RawSQLSecurityRule extends SecurityRuleBase {
|
|
820
|
+
/**
|
|
821
|
+
* Raw SQL expression for the `USING` clause.
|
|
822
|
+
* This controls which *existing* rows are visible / can be modified / deleted.
|
|
823
|
+
* Applied to SELECT, UPDATE, and DELETE.
|
|
824
|
+
*/
|
|
825
|
+
using: string;
|
|
826
|
+
/**
|
|
827
|
+
* Raw SQL expression for the `WITH CHECK` clause.
|
|
828
|
+
* This controls which *new/updated* row values are allowed.
|
|
829
|
+
* Applied to INSERT and UPDATE.
|
|
830
|
+
*
|
|
831
|
+
* If not provided on INSERT/UPDATE policies, falls back to `using`
|
|
832
|
+
* (which matches PostgreSQL's own default behavior).
|
|
833
|
+
*/
|
|
834
|
+
withCheck?: string;
|
|
835
|
+
ownerField?: never;
|
|
836
|
+
access?: never;
|
|
837
|
+
}
|
|
838
|
+
/**
|
|
839
|
+
* Security rule that only filters by application roles, without any
|
|
840
|
+
* row-level condition (USING/WITH CHECK).
|
|
841
|
+
*
|
|
842
|
+
* Useful for simple "only admins can access this table" rules where
|
|
843
|
+
* no per-row filtering is needed.
|
|
844
|
+
*
|
|
845
|
+
* @example
|
|
846
|
+
* // Only admins can delete
|
|
847
|
+
* { operation: "delete", roles: ["admin"] }
|
|
848
|
+
*
|
|
849
|
+
* @group Models
|
|
850
|
+
*/
|
|
851
|
+
export interface RolesOnlySecurityRule extends SecurityRuleBase {
|
|
852
|
+
ownerField?: never;
|
|
853
|
+
access?: never;
|
|
854
|
+
using?: never;
|
|
855
|
+
withCheck?: never;
|
|
856
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cron Job type definitions for Rebase.
|
|
3
|
+
*
|
|
4
|
+
* These types define the shape of cron job definitions, their runtime
|
|
5
|
+
* status, and execution log entries — used across server-core, client,
|
|
6
|
+
* and studio packages.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* A cron job definition file exports this shape as its default export.
|
|
10
|
+
* See the example cron files in `app/backend/crons/` for usage.
|
|
11
|
+
*/
|
|
12
|
+
export interface CronJobDefinition {
|
|
13
|
+
schedule: string;
|
|
14
|
+
/** Human-readable name shown in the Studio UI. */
|
|
15
|
+
name: string;
|
|
16
|
+
/** Optional description shown in the Studio UI. */
|
|
17
|
+
description?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Whether the job is enabled at startup. Defaults to `true`.
|
|
20
|
+
* Can be toggled at runtime via the Admin API.
|
|
21
|
+
*/
|
|
22
|
+
enabled?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Maximum number of seconds the handler may run before being
|
|
25
|
+
* considered timed-out. Default: 300 (5 min).
|
|
26
|
+
*/
|
|
27
|
+
timeoutSeconds?: number;
|
|
28
|
+
/**
|
|
29
|
+
* The handler function executed on each tick.
|
|
30
|
+
* Receives a context object with the data driver and logger.
|
|
31
|
+
* May return arbitrary JSON-serialisable data stored in the log.
|
|
32
|
+
*/
|
|
33
|
+
handler: (ctx: CronJobContext) => Promise<unknown> | unknown;
|
|
34
|
+
}
|
|
35
|
+
import type { RebaseClient } from "../controllers/client";
|
|
36
|
+
/**
|
|
37
|
+
* Context passed to each cron handler invocation.
|
|
38
|
+
*/
|
|
39
|
+
export interface CronJobContext {
|
|
40
|
+
/** The job's unique ID (derived from filename). */
|
|
41
|
+
jobId: string;
|
|
42
|
+
/** The current scheduled tick timestamp. */
|
|
43
|
+
scheduledAt: Date;
|
|
44
|
+
/** A simple logger scoped to this job run. */
|
|
45
|
+
log: (...args: unknown[]) => void;
|
|
46
|
+
/** The RebaseClient instance to interact with the database. */
|
|
47
|
+
client: RebaseClient<any>;
|
|
48
|
+
}
|
|
49
|
+
export type CronJobRunState = "idle" | "running" | "success" | "error" | "disabled";
|
|
50
|
+
/**
|
|
51
|
+
* Full runtime information about a registered cron job.
|
|
52
|
+
*/
|
|
53
|
+
export interface CronJobStatus {
|
|
54
|
+
/** Unique identifier (derived from filename, e.g. "cleanup-sessions"). */
|
|
55
|
+
id: string;
|
|
56
|
+
/** Human-readable name from the definition. */
|
|
57
|
+
name: string;
|
|
58
|
+
/** Description from the definition. */
|
|
59
|
+
description?: string;
|
|
60
|
+
/** The cron schedule expression. */
|
|
61
|
+
schedule: string;
|
|
62
|
+
/** Whether the job is currently enabled. */
|
|
63
|
+
enabled: boolean;
|
|
64
|
+
/** Current run state. */
|
|
65
|
+
state: CronJobRunState;
|
|
66
|
+
/** ISO timestamp of the last execution start. */
|
|
67
|
+
lastRunAt?: string;
|
|
68
|
+
/** ISO timestamp of the next scheduled execution. */
|
|
69
|
+
nextRunAt?: string;
|
|
70
|
+
/** Duration of the last run in milliseconds. */
|
|
71
|
+
lastDurationMs?: number;
|
|
72
|
+
/** Error message from the last failed run. */
|
|
73
|
+
lastError?: string;
|
|
74
|
+
/** Total number of executions since server start. */
|
|
75
|
+
totalRuns: number;
|
|
76
|
+
/** Total number of failed executions since server start. */
|
|
77
|
+
totalFailures: number;
|
|
78
|
+
}
|
|
79
|
+
export type CronLogLevel = "info" | "error" | "warn";
|
|
80
|
+
/**
|
|
81
|
+
* A single execution log entry stored in the in-memory ring buffer.
|
|
82
|
+
*/
|
|
83
|
+
export interface CronJobLogEntry {
|
|
84
|
+
/** The job ID this log belongs to. */
|
|
85
|
+
jobId: string;
|
|
86
|
+
/** ISO timestamp when execution started. */
|
|
87
|
+
startedAt: string;
|
|
88
|
+
/** ISO timestamp when execution finished. */
|
|
89
|
+
finishedAt: string;
|
|
90
|
+
/** Duration in milliseconds. */
|
|
91
|
+
durationMs: number;
|
|
92
|
+
/** Whether this run succeeded. */
|
|
93
|
+
success: boolean;
|
|
94
|
+
/** Error message if the run failed. */
|
|
95
|
+
error?: string;
|
|
96
|
+
/** Arbitrary result data returned by the handler. */
|
|
97
|
+
result?: unknown;
|
|
98
|
+
/** Captured log lines. */
|
|
99
|
+
logs: string[];
|
|
100
|
+
/** Whether this was a manual trigger. */
|
|
101
|
+
manual?: boolean;
|
|
102
|
+
}
|
|
@@ -38,7 +38,7 @@ export interface DataSourceCapabilities {
|
|
|
38
38
|
* Useful when you only need to check capabilities without UI metadata.
|
|
39
39
|
* @group Models
|
|
40
40
|
*/
|
|
41
|
-
export type DataSourceFeatures =
|
|
41
|
+
export type DataSourceFeatures = Omit<DataSourceCapabilities, "key" | "label">;
|
|
42
42
|
/** @group Models */
|
|
43
43
|
export declare const POSTGRES_CAPABILITIES: DataSourceCapabilities;
|
|
44
44
|
/** @group Models */
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Entity } from "./entities";
|
|
3
|
-
import { EntityCollection, SelectionController } from "./collections";
|
|
4
|
-
import { FormContext } from "./entity_views";
|
|
5
|
-
import { User } from "../users";
|
|
6
|
-
import { RebaseContext } from "../rebase_context";
|
|
7
|
-
import { SideEntityController } from "../controllers";
|
|
2
|
+
import type { Entity } from "./entities";
|
|
3
|
+
import type { EntityCollection, SelectionController } from "./collections";
|
|
4
|
+
import type { FormContext } from "./entity_views";
|
|
5
|
+
import type { User } from "../users";
|
|
6
|
+
import type { RebaseContext } from "../rebase_context";
|
|
7
|
+
import type { SideEntityController } from "../controllers/side_entity_controller";
|
|
8
8
|
/**
|
|
9
9
|
* An entity action is a custom action that can be performed on an entity.
|
|
10
10
|
* They are displayed in the entity view and in the collection view.
|
|
@@ -55,7 +55,7 @@ export type EntityActionClickProps<M extends Record<string, unknown>, USER exten
|
|
|
55
55
|
entity?: Entity<M>;
|
|
56
56
|
context: RebaseContext<USER>;
|
|
57
57
|
path?: string;
|
|
58
|
-
collection?: EntityCollection<
|
|
58
|
+
collection?: EntityCollection<M>;
|
|
59
59
|
/**
|
|
60
60
|
* Optional form context, present if the action is being called from a form.
|
|
61
61
|
* This allows you to access the form state and methods, including modifying the form values.
|
|
@@ -72,7 +72,7 @@ export type EntityActionClickProps<M extends Record<string, unknown>, USER exten
|
|
|
72
72
|
/**
|
|
73
73
|
* If the action is rendered in the form, is it open in a side panel or full screen?
|
|
74
74
|
*/
|
|
75
|
-
openEntityMode: "side_panel" | "full_screen";
|
|
75
|
+
openEntityMode: "side_panel" | "full_screen" | "split";
|
|
76
76
|
/**
|
|
77
77
|
* Optional selection controller, present if the action is being called from a collection view
|
|
78
78
|
*/
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { EntityCollection } from "./collections";
|
|
2
|
-
import { Entity, EntityStatus, EntityValues } from "./entities";
|
|
3
|
-
import { User } from "../users";
|
|
4
|
-
import { RebaseCallContext } from "../rebase_context";
|
|
1
|
+
import type { EntityCollection } from "./collections";
|
|
2
|
+
import type { Entity, EntityStatus, EntityValues } from "./entities";
|
|
3
|
+
import type { User } from "../users";
|
|
4
|
+
import type { RebaseCallContext } from "../rebase_context";
|
|
5
5
|
/**
|
|
6
6
|
* This interface defines all the callbacks that can be used when an entity
|
|
7
7
|
* is being created, updated or deleted.
|
|
8
8
|
* Useful for adding your own logic or blocking the execution of the operation.
|
|
9
9
|
* @group Models
|
|
10
10
|
*/
|
|
11
|
-
export type EntityCallbacks<M extends Record<string,
|
|
11
|
+
export type EntityCallbacks<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> = {
|
|
12
12
|
/**
|
|
13
13
|
* Callback used after fetching data
|
|
14
14
|
* @param props
|
|
@@ -51,11 +51,11 @@ export type EntityCallbacks<M extends Record<string, any> = any, USER extends Us
|
|
|
51
51
|
* Parameters passed to hooks when an entity is fetched
|
|
52
52
|
* @group Models
|
|
53
53
|
*/
|
|
54
|
-
export interface EntityAfterReadProps<M extends Record<string,
|
|
54
|
+
export interface EntityAfterReadProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
|
|
55
55
|
/**
|
|
56
56
|
* Collection of the entity
|
|
57
57
|
*/
|
|
58
|
-
collection: EntityCollection<
|
|
58
|
+
collection: EntityCollection<M>;
|
|
59
59
|
/**
|
|
60
60
|
* Full path of the CMS where this collection is being fetched.
|
|
61
61
|
* Might contain unresolved aliases.
|
|
@@ -74,25 +74,25 @@ export interface EntityAfterReadProps<M extends Record<string, any> = any, USER
|
|
|
74
74
|
* Parameters passed to hooks before an entity is saved
|
|
75
75
|
* @group Models
|
|
76
76
|
*/
|
|
77
|
-
export type EntityBeforeSaveProps<M extends Record<string,
|
|
77
|
+
export type EntityBeforeSaveProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> = Omit<EntityAfterSaveProps<M, USER>, "entityId"> & {
|
|
78
78
|
entityId?: string | number;
|
|
79
79
|
};
|
|
80
80
|
/**
|
|
81
81
|
* Parameters passed to hooks before an entity is saved
|
|
82
82
|
* @group Models
|
|
83
83
|
*/
|
|
84
|
-
export type EntityAfterSaveErrorProps<M extends Record<string,
|
|
84
|
+
export type EntityAfterSaveErrorProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> = Omit<EntityAfterSaveProps<M, USER>, "entityId"> & {
|
|
85
85
|
entityId?: string | number;
|
|
86
86
|
};
|
|
87
87
|
/**
|
|
88
88
|
* Parameters passed to hooks when an entity is saved
|
|
89
89
|
* @group Models
|
|
90
90
|
*/
|
|
91
|
-
export interface EntityAfterSaveProps<M extends Record<string,
|
|
91
|
+
export interface EntityAfterSaveProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
|
|
92
92
|
/**
|
|
93
93
|
* Resolved collection of the entity
|
|
94
94
|
*/
|
|
95
|
-
collection: EntityCollection<
|
|
95
|
+
collection: EntityCollection<M>;
|
|
96
96
|
/**
|
|
97
97
|
* Full path of the CMS where this entity is being saved.
|
|
98
98
|
* Might contain unresolved aliases.
|
|
@@ -123,11 +123,11 @@ export interface EntityAfterSaveProps<M extends Record<string, any> = any, USER
|
|
|
123
123
|
* Parameters passed to hooks when an entity is deleted
|
|
124
124
|
* @group Models
|
|
125
125
|
*/
|
|
126
|
-
export interface EntityBeforeDeleteProps<M extends Record<string,
|
|
126
|
+
export interface EntityBeforeDeleteProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
|
|
127
127
|
/**
|
|
128
128
|
* collection of the entity being deleted
|
|
129
129
|
*/
|
|
130
|
-
collection: EntityCollection<
|
|
130
|
+
collection: EntityCollection<M>;
|
|
131
131
|
/**
|
|
132
132
|
* Path of the parent collection
|
|
133
133
|
*/
|
|
@@ -149,11 +149,11 @@ export interface EntityBeforeDeleteProps<M extends Record<string, any> = any, US
|
|
|
149
149
|
* Parameters passed to hooks after an entity is deleted
|
|
150
150
|
* @group Models
|
|
151
151
|
*/
|
|
152
|
-
export interface EntityAfterDeleteProps<M extends Record<string,
|
|
152
|
+
export interface EntityAfterDeleteProps<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
|
|
153
153
|
/**
|
|
154
154
|
* collection of the entity being deleted
|
|
155
155
|
*/
|
|
156
|
-
collection: EntityCollection<
|
|
156
|
+
collection: EntityCollection<M>;
|
|
157
157
|
/**
|
|
158
158
|
* Path of the parent collection
|
|
159
159
|
*/
|
|
@@ -2,6 +2,6 @@ import { Entity } from "./entities";
|
|
|
2
2
|
/**
|
|
3
3
|
* @group Models
|
|
4
4
|
*/
|
|
5
|
-
export type EntityLinkBuilder<M extends Record<string,
|
|
5
|
+
export type EntityLinkBuilder<M extends Record<string, unknown> = Record<string, unknown>> = ({ entity }: {
|
|
6
6
|
entity: Entity<M>;
|
|
7
7
|
}) => string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { DataDriver
|
|
1
|
+
import type { DataDriver } from "../controllers/data_driver";
|
|
2
|
+
import type { StorageSource } from "../controllers/storage";
|
|
2
3
|
export type EntityOverrides = {
|
|
3
4
|
/**
|
|
4
5
|
* Internal driver override for this collection.
|