@rebasepro/client-postgresql 0.0.1-canary.4d4fb3e → 0.0.1-canary.ca2cb6e
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/client/src/admin.d.ts +94 -0
- package/dist/client/src/auth.d.ts +161 -0
- package/dist/client/src/collection.d.ts +19 -0
- package/dist/client/src/cron.d.ts +25 -0
- package/dist/client/src/index.d.ts +42 -0
- package/dist/client/src/query_builder.d.ts +53 -0
- package/dist/client/src/reviver.d.ts +1 -0
- package/dist/client/src/storage.d.ts +3 -0
- package/dist/client/src/transport.d.ts +33 -0
- package/dist/client/src/websocket.d.ts +99 -0
- package/dist/index.es.js +28 -17
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +28 -17
- package/dist/index.umd.js.map +1 -1
- 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/package.json +83 -86
- package/src/usePostgresClientDriver.ts +57 -29
- package/tsconfig.json +1 -0
- package/vite.config.ts +4 -4
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { Entity
|
|
1
|
+
import type { Entity } from "../types/entities";
|
|
2
|
+
import type { EntityCollection } from "../types/collections";
|
|
2
3
|
/**
|
|
3
4
|
* Props used to open a side dialog
|
|
4
5
|
* @group Hooks and utilities
|
|
5
6
|
*/
|
|
6
|
-
export interface EntitySidePanelProps<M extends Record<string,
|
|
7
|
+
export interface EntitySidePanelProps<M extends Record<string, unknown> = Record<string, unknown>> {
|
|
7
8
|
/**
|
|
8
9
|
* Absolute path of the entity
|
|
9
10
|
*/
|
|
@@ -43,7 +44,7 @@ export interface EntitySidePanelProps<M extends Record<string, any> = any> {
|
|
|
43
44
|
* @param params
|
|
44
45
|
*/
|
|
45
46
|
onUpdate?: (params: {
|
|
46
|
-
entity: Entity<
|
|
47
|
+
entity: Entity<M>;
|
|
47
48
|
}) => void;
|
|
48
49
|
/**
|
|
49
50
|
* Callback when the dialog is closed
|
|
@@ -56,7 +57,7 @@ export interface EntitySidePanelProps<M extends Record<string, any> = any> {
|
|
|
56
57
|
/**
|
|
57
58
|
* Override some form properties
|
|
58
59
|
*/
|
|
59
|
-
formProps?:
|
|
60
|
+
formProps?: Record<string, unknown>;
|
|
60
61
|
/**
|
|
61
62
|
* Allow the user to open the entity fullscreen
|
|
62
63
|
*/
|
|
@@ -80,10 +81,10 @@ export interface SideEntityController {
|
|
|
80
81
|
* (or a new one with that id).
|
|
81
82
|
* @param props
|
|
82
83
|
*/
|
|
83
|
-
open: <M extends Record<string,
|
|
84
|
+
open: <M extends Record<string, unknown> = Record<string, unknown>>(props: EntitySidePanelProps<M>) => void;
|
|
84
85
|
/**
|
|
85
86
|
* Replace the last open entity panel with the given one.
|
|
86
87
|
* @param props
|
|
87
88
|
*/
|
|
88
|
-
replace: <M extends Record<string,
|
|
89
|
+
replace: <M extends Record<string, unknown> = Record<string, unknown>>(props: EntitySidePanelProps<M>) => void;
|
|
89
90
|
}
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export interface UploadFileProps {
|
|
5
5
|
file: File;
|
|
6
|
-
|
|
7
|
-
path?: string;
|
|
6
|
+
key: string;
|
|
8
7
|
metadata?: Record<string, unknown>;
|
|
9
8
|
bucket?: string;
|
|
10
9
|
}
|
|
@@ -13,9 +12,9 @@ export interface UploadFileProps {
|
|
|
13
12
|
*/
|
|
14
13
|
export interface UploadFileResult {
|
|
15
14
|
/**
|
|
16
|
-
* Storage
|
|
15
|
+
* Storage key including the file name where the file was uploaded.
|
|
17
16
|
*/
|
|
18
|
-
|
|
17
|
+
key: string;
|
|
19
18
|
/**
|
|
20
19
|
* Bucket where the file was uploaded
|
|
21
20
|
*/
|
|
@@ -23,7 +22,7 @@ export interface UploadFileResult {
|
|
|
23
22
|
/**
|
|
24
23
|
* Fully qualified storage URL for the uploaded file.
|
|
25
24
|
*
|
|
26
|
-
* For example: `
|
|
25
|
+
* For example: `s3://my-bucket/path/to/file.png`.
|
|
27
26
|
*
|
|
28
27
|
* This is optional for backwards compatibility.
|
|
29
28
|
*/
|
|
@@ -74,39 +73,38 @@ export declare interface DownloadMetadata {
|
|
|
74
73
|
*/
|
|
75
74
|
export interface StorageSource {
|
|
76
75
|
/**
|
|
77
|
-
* Upload
|
|
76
|
+
* Upload an object, specifying a key
|
|
78
77
|
* @param file
|
|
79
|
-
* @param
|
|
80
|
-
* @param path
|
|
78
|
+
* @param key
|
|
81
79
|
* @param metadata
|
|
82
80
|
* @param bucket
|
|
83
81
|
*/
|
|
84
|
-
|
|
82
|
+
putObject: ({ file, key, metadata, bucket }: UploadFileProps) => Promise<UploadFileResult>;
|
|
85
83
|
/**
|
|
86
|
-
* Convert a storage
|
|
87
|
-
* @param
|
|
84
|
+
* Convert a storage key or URL into a download configuration (signed URL equivalent)
|
|
85
|
+
* @param keyOrUrl
|
|
88
86
|
* @param bucket
|
|
89
87
|
*/
|
|
90
|
-
|
|
88
|
+
getSignedUrl: (keyOrUrl: string, bucket?: string) => Promise<DownloadConfig>;
|
|
91
89
|
/**
|
|
92
|
-
* Get
|
|
93
|
-
* It returns null if the
|
|
94
|
-
* @param
|
|
90
|
+
* Get an object from a storage key.
|
|
91
|
+
* It returns null if the object does not exist.
|
|
92
|
+
* @param key
|
|
95
93
|
* @param bucket
|
|
96
94
|
*/
|
|
97
|
-
|
|
95
|
+
getObject: (key: string, bucket?: string) => Promise<File | null>;
|
|
98
96
|
/**
|
|
99
|
-
* Delete
|
|
100
|
-
* @param
|
|
97
|
+
* Delete an object.
|
|
98
|
+
* @param key
|
|
101
99
|
* @param bucket
|
|
102
100
|
*/
|
|
103
|
-
|
|
101
|
+
deleteObject: (key: string, bucket?: string) => Promise<void>;
|
|
104
102
|
/**
|
|
105
|
-
* List the contents of a
|
|
106
|
-
* @param
|
|
103
|
+
* List the contents of a prefix.
|
|
104
|
+
* @param prefix
|
|
107
105
|
* @param options
|
|
108
106
|
*/
|
|
109
|
-
|
|
107
|
+
listObjects: (prefix: string, options?: {
|
|
110
108
|
bucket?: string;
|
|
111
109
|
maxResults?: number;
|
|
112
110
|
pageToken?: string;
|
|
@@ -137,15 +135,15 @@ export declare interface StorageListResult {
|
|
|
137
135
|
nextPageToken?: string;
|
|
138
136
|
}
|
|
139
137
|
/**
|
|
140
|
-
* Represents a reference to
|
|
138
|
+
* Represents a reference to an S3-compatible storage object. Developers can
|
|
141
139
|
* upload, download, and delete objects, as well as get/set object metadata.
|
|
142
140
|
* @public
|
|
143
141
|
*/
|
|
144
142
|
export declare interface StorageReference {
|
|
145
143
|
/**
|
|
146
|
-
* Returns a
|
|
147
|
-
* `
|
|
148
|
-
* @returns The
|
|
144
|
+
* Returns a s3:// URL for this object in the form
|
|
145
|
+
* `s3://<bucket>/<path>/<to>/<object>`
|
|
146
|
+
* @returns The s3:// URL.
|
|
149
147
|
*/
|
|
150
148
|
toString(): string;
|
|
151
149
|
/**
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import { AnalyticsController
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import type { AnalyticsController } from "./controllers/analytics_controller";
|
|
2
|
+
import type { AuthController } from "./controllers/auth";
|
|
3
|
+
import type { StorageSource } from "./controllers/storage";
|
|
4
|
+
import type { UserConfigurationPersistence } from "./controllers/local_config_persistence";
|
|
5
|
+
import type { DatabaseAdmin } from "./types/backend";
|
|
6
|
+
import type { RebaseData } from "./controllers/data";
|
|
7
|
+
import type { User } from "./users";
|
|
8
|
+
import type { UserManagementDelegate } from "./types/user_management_delegate";
|
|
5
9
|
/**
|
|
6
10
|
* Context that is provided to entity callbacks (hooks).
|
|
7
11
|
* It contains only the dependencies that are available in both the frontend and the backend.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Entity
|
|
1
|
+
import type { Entity } from "./entities";
|
|
2
|
+
import type { EntityCollection, FilterValues, WhereFilterOp } from "./collections";
|
|
2
3
|
/**
|
|
3
4
|
* Abstract database connection interface.
|
|
4
5
|
* Represents a connection to any database system.
|
|
@@ -33,6 +34,7 @@ export interface FetchCollectionOptions<M extends Record<string, unknown> = Reco
|
|
|
33
34
|
orderBy?: string;
|
|
34
35
|
order?: "desc" | "asc";
|
|
35
36
|
limit?: number;
|
|
37
|
+
offset?: number;
|
|
36
38
|
startAfter?: unknown;
|
|
37
39
|
searchString?: string;
|
|
38
40
|
databaseId?: string;
|
|
@@ -54,6 +56,7 @@ export interface SearchOptions<M extends Record<string, unknown> = Record<string
|
|
|
54
56
|
*/
|
|
55
57
|
export interface CountOptions<M extends Record<string, unknown> = Record<string, unknown>> {
|
|
56
58
|
filter?: FilterValues<Extract<keyof M, string>>;
|
|
59
|
+
searchString?: string;
|
|
57
60
|
databaseId?: string;
|
|
58
61
|
}
|
|
59
62
|
/**
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { AuthController
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import type { AuthController } from "../controllers/auth";
|
|
2
|
+
import type { RebaseData } from "../controllers/data";
|
|
3
|
+
import type { User } from "../users";
|
|
4
|
+
import type { EntityCollection } from "./collections";
|
|
5
|
+
import type { AppView } from "../controllers/navigation";
|
|
5
6
|
export type EntityCollectionsBuilder<EC extends EntityCollection = EntityCollection> = (params: {
|
|
6
7
|
user: User | null;
|
|
7
8
|
authController: AuthController;
|
|
@@ -2,4 +2,4 @@ export type ColorScheme = {
|
|
|
2
2
|
color: string;
|
|
3
3
|
text: string;
|
|
4
4
|
};
|
|
5
|
-
export type ColorKey = "
|
|
5
|
+
export type ColorKey = "blue" | "cyan" | "teal" | "green" | "yellow" | "orange" | "red" | "pink" | "purple" | "gray" | "indigo" | "violet" | "fuchsia" | "rose" | "emerald";
|
|
@@ -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
|
+
}
|