@rebasepro/client-postgresql 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,106 +1,74 @@
|
|
|
1
|
-
# @rebasepro/postgresql
|
|
1
|
+
# @rebasepro/client-postgresql
|
|
2
2
|
|
|
3
|
-
PostgreSQL data source client for Rebase
|
|
4
|
-
|
|
5
|
-
This package provides a complete client-side implementation for connecting Rebase applications to PostgreSQL backends, featuring real-time synchronization via WebSockets.
|
|
3
|
+
PostgreSQL data source client for Rebase — connects the Rebase admin panel to a PostgreSQL backend via WebSocket.
|
|
6
4
|
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
9
7
|
```bash
|
|
10
|
-
|
|
8
|
+
pnpm add @rebasepro/client-postgresql
|
|
11
9
|
```
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
**Peer dependencies:** `react >= 19.0.0`, `react-dom >= 19.0.0`
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
## What This Package Does
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
import { usePostgresDataSource } from "@rebasepro/postgresql";
|
|
19
|
-
import { Rebase } from "@rebasepro/core";
|
|
15
|
+
This package provides a `DataDriver` implementation that bridges Rebase's data layer to a PostgreSQL backend through `@rebasepro/client`'s WebSocket client. It supports full CRUD, realtime collection/entity listeners, unique field validation, entity counting, and admin operations (SQL execution, branch management, table introspection).
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
const dataSource = usePostgresDataSource({
|
|
23
|
-
baseUrl: "http://localhost:3001",
|
|
24
|
-
websocketUrl: "ws://localhost:3001", // Optional, will be inferred from baseUrl
|
|
25
|
-
headers: { // Optional
|
|
26
|
-
"Authorization": "Bearer your-token"
|
|
27
|
-
}
|
|
28
|
-
});
|
|
17
|
+
## Key Exports
|
|
29
18
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
/>
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
```
|
|
19
|
+
| Export | Type | Description |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| `usePostgresClientDriver` | Hook | Creates a `PostgresDataDriver` from a `RebaseWebSocketClient` |
|
|
22
|
+
| `PostgresDataDriverConfig` | Type | Config object: `{ wsClient: RebaseWebSocketClient }` |
|
|
23
|
+
| `PostgresDataDriver` | Type | Extends `DataDriver` with a `client` reference and `admin` methods |
|
|
39
24
|
|
|
40
|
-
###
|
|
25
|
+
### `PostgresDataDriver` Methods
|
|
41
26
|
|
|
42
|
-
|
|
43
|
-
|
|
27
|
+
| Method | Description |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `fetchCollection(props)` | Fetch a list of entities with filtering, sorting, pagination, and search |
|
|
30
|
+
| `fetchEntity(props)` | Fetch a single entity by path and ID |
|
|
31
|
+
| `saveEntity(props)` | Create or update an entity |
|
|
32
|
+
| `deleteEntity(props)` | Delete an entity |
|
|
33
|
+
| `checkUniqueField(path, name, value, entityId?, collection?)` | Check if a field value is unique |
|
|
34
|
+
| `countEntities(props)` | Count entities matching filter criteria |
|
|
35
|
+
| `listenCollection(props)` | Subscribe to realtime collection updates. Returns an unsubscribe function |
|
|
36
|
+
| `listenEntity(props)` | Subscribe to realtime entity updates. Returns an unsubscribe function |
|
|
37
|
+
| `isFilterCombinationValid()` | Always returns `true` — PostgreSQL supports complex filter combinations |
|
|
44
38
|
|
|
45
|
-
|
|
46
|
-
baseUrl: "http://localhost:3001",
|
|
47
|
-
websocketUrl: "ws://localhost:3001"
|
|
48
|
-
});
|
|
49
|
-
```
|
|
39
|
+
### Admin Methods (`driver.admin`)
|
|
50
40
|
|
|
51
|
-
|
|
41
|
+
| Method | Description |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `executeSql(sql, options?)` | Execute raw SQL. Options: `{ database?, role? }` |
|
|
44
|
+
| `fetchAvailableDatabases()` | List available databases |
|
|
45
|
+
| `fetchAvailableRoles()` | List available roles |
|
|
46
|
+
| `fetchCurrentDatabase()` | Get the current database name |
|
|
47
|
+
| `fetchUnmappedTables(mappedPaths?)` | Find tables not yet mapped to collections |
|
|
48
|
+
| `fetchTableMetadata(tableName)` | Get column/constraint metadata for a table |
|
|
49
|
+
| `createBranch(name, options?)` | Create a database branch. Options: `{ source? }` |
|
|
50
|
+
| `deleteBranch(name)` | Delete a database branch |
|
|
51
|
+
| `listBranches()` | List all branches |
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
- **Automatic Reconnection**: Built-in reconnection logic with exponential backoff
|
|
55
|
-
- **Type Safety**: Full TypeScript support with Rebase core types
|
|
56
|
-
- **Error Handling**: Comprehensive error handling with custom error types
|
|
57
|
-
- **Connection Management**: Connection status monitoring and queue management
|
|
53
|
+
## Quick Start
|
|
58
54
|
|
|
59
|
-
|
|
55
|
+
```tsx
|
|
56
|
+
import { usePostgresClientDriver } from "@rebasepro/client-postgresql";
|
|
57
|
+
import { RebaseWebSocketClient } from "@rebasepro/client";
|
|
60
58
|
|
|
61
|
-
|
|
59
|
+
const wsClient = new RebaseWebSocketClient({ url: "ws://localhost:4100" });
|
|
62
60
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
function App() {
|
|
62
|
+
const driver = usePostgresClientDriver({ wsClient });
|
|
63
|
+
|
|
64
|
+
// Pass to your Rebase app as the data driver
|
|
65
|
+
return (
|
|
66
|
+
<Rebase driver={driver} /* ...other props */ />
|
|
67
|
+
);
|
|
68
68
|
}
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
The PostgreSQL data source implements all Rebase `DataSource` methods:
|
|
74
|
-
|
|
75
|
-
- `fetchCollection<M>(props): Promise<Entity<M>[]>`
|
|
76
|
-
- `fetchEntity<M>(props): Promise<Entity<M> | undefined>`
|
|
77
|
-
- `saveEntity<M>(props): Promise<Entity<M>>`
|
|
78
|
-
- `deleteEntity<M>(props): Promise<void>`
|
|
79
|
-
- `checkUniqueField(...): Promise<boolean>`
|
|
80
|
-
- `generateEntityId(...): string`
|
|
81
|
-
- `countEntities<M>(props): Promise<number>`
|
|
82
|
-
- `listenCollection<M>(props): () => void`
|
|
83
|
-
- `listenEntity<M>(props): () => void`
|
|
84
|
-
|
|
85
|
-
## Backend Requirements
|
|
86
|
-
|
|
87
|
-
This client expects a WebSocket-enabled backend that handles the following message types:
|
|
88
|
-
|
|
89
|
-
- `FETCH_COLLECTION`
|
|
90
|
-
- `FETCH_ENTITY`
|
|
91
|
-
- `SAVE_ENTITY`
|
|
92
|
-
- `DELETE_ENTITY`
|
|
93
|
-
- `CHECK_UNIQUE_FIELD`
|
|
94
|
-
- `GENERATE_ENTITY_ID`
|
|
95
|
-
- `COUNT_ENTITIES`
|
|
96
|
-
- `subscribe_collection`
|
|
97
|
-
- `subscribe_entity`
|
|
98
|
-
- `unsubscribe`
|
|
99
|
-
|
|
100
|
-
## Development
|
|
101
|
-
|
|
102
|
-
This package is part of the Rebase monorepo. For development instructions, see the main repository README.
|
|
103
|
-
|
|
104
|
-
## License
|
|
71
|
+
## Related Packages
|
|
105
72
|
|
|
106
|
-
|
|
73
|
+
- `@rebasepro/client` — Provides `RebaseWebSocketClient` used for communication
|
|
74
|
+
- `@rebasepro/types` — Shared types (`DataDriver`, `Entity`, `EntityCollection`, etc.)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Entity } from "./entities";
|
|
2
2
|
import type { EntityCollection, FilterValues, WhereFilterOp } from "./collections";
|
|
3
|
+
import type { AuthAdapter } from "./auth_adapter";
|
|
3
4
|
/**
|
|
4
5
|
* Abstract database connection interface.
|
|
5
6
|
* Represents a connection to any database system.
|
|
@@ -182,6 +183,24 @@ export interface RealtimeProvider {
|
|
|
182
183
|
* Notify all relevant subscribers of an entity update
|
|
183
184
|
*/
|
|
184
185
|
notifyEntityUpdate(path: string, entityId: string, entity: Entity | null, databaseId?: string): Promise<void>;
|
|
186
|
+
/**
|
|
187
|
+
* Called when the HTTP server is ready and listening.
|
|
188
|
+
* Useful for providers that need the server address for callbacks.
|
|
189
|
+
*/
|
|
190
|
+
onServerReady?(serverInfo: {
|
|
191
|
+
port: number;
|
|
192
|
+
hostname?: string;
|
|
193
|
+
}): void;
|
|
194
|
+
/**
|
|
195
|
+
* Gracefully shut down the realtime provider.
|
|
196
|
+
* Called during server shutdown to clean up resources.
|
|
197
|
+
*/
|
|
198
|
+
destroy?(): Promise<void>;
|
|
199
|
+
/**
|
|
200
|
+
* Stop the internal LISTEN client (e.g., PostgreSQL LISTEN/NOTIFY).
|
|
201
|
+
* Called during graceful shutdown before closing database connections.
|
|
202
|
+
*/
|
|
203
|
+
stopListening?(): Promise<void>;
|
|
185
204
|
}
|
|
186
205
|
/**
|
|
187
206
|
* Abstract collection registry interface.
|
|
@@ -464,6 +483,22 @@ export interface BackendBootstrapper {
|
|
|
464
483
|
* (e.g., `"postgres"`, `"mongodb"`, `"mysql"`).
|
|
465
484
|
*/
|
|
466
485
|
type: string;
|
|
486
|
+
/**
|
|
487
|
+
* Unique identifier for this bootstrapper instance.
|
|
488
|
+
* Used to register the driver in the driver registry.
|
|
489
|
+
* Defaults to `type` if not set.
|
|
490
|
+
*/
|
|
491
|
+
id?: string;
|
|
492
|
+
/**
|
|
493
|
+
* Whether this bootstrapper provides the default driver.
|
|
494
|
+
* When true, the coordinator uses this driver as the primary one.
|
|
495
|
+
*/
|
|
496
|
+
isDefault?: boolean;
|
|
497
|
+
/**
|
|
498
|
+
* Run database migrations for this driver.
|
|
499
|
+
* Called by the coordinator after all drivers are initialized.
|
|
500
|
+
*/
|
|
501
|
+
runMigrations?(config: unknown, driverResult: InitializedDriver): Promise<void>;
|
|
467
502
|
/**
|
|
468
503
|
* Create a DataDriver from the given config.
|
|
469
504
|
* This is the only **required** method.
|
|
@@ -498,7 +533,7 @@ export interface BackendBootstrapper {
|
|
|
498
533
|
/**
|
|
499
534
|
* Initialize WebSocket server for realtime operations.
|
|
500
535
|
*/
|
|
501
|
-
initializeWebsockets?(server: unknown, realtimeService: RealtimeProvider, driver: import("../controllers/data_driver").DataDriver, config?: unknown): Promise<void> | void;
|
|
536
|
+
initializeWebsockets?(server: unknown, realtimeService: RealtimeProvider, driver: import("../controllers/data_driver").DataDriver, config?: unknown, authAdapter?: AuthAdapter): Promise<void> | void;
|
|
502
537
|
}
|
|
503
538
|
/**
|
|
504
539
|
* Result of `BackendBootstrapper.initializeDriver()`.
|
|
@@ -343,6 +343,23 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
343
343
|
* Builder for the collection actions rendered in the toolbar
|
|
344
344
|
*/
|
|
345
345
|
Actions?: ComponentRef<CollectionActionsProps>[];
|
|
346
|
+
/**
|
|
347
|
+
* The database table name for this collection.
|
|
348
|
+
* Automatically set for PostgreSQL collections.
|
|
349
|
+
* For non-SQL backends, this may be undefined.
|
|
350
|
+
*/
|
|
351
|
+
table?: string;
|
|
352
|
+
/**
|
|
353
|
+
* Relations defined for this collection.
|
|
354
|
+
* Populated at normalization time from inline relation properties
|
|
355
|
+
* or explicit relation definitions.
|
|
356
|
+
*/
|
|
357
|
+
relations?: Relation[];
|
|
358
|
+
/**
|
|
359
|
+
* Security rules for this collection (Row Level Security).
|
|
360
|
+
* When defined, the backend enforces access control policies.
|
|
361
|
+
*/
|
|
362
|
+
securityRules?: SecurityRule[];
|
|
346
363
|
}
|
|
347
364
|
/**
|
|
348
365
|
* A collection backed by PostgreSQL (or any SQL database).
|
|
@@ -436,7 +453,10 @@ export interface MongoDBCollection<M extends Record<string, unknown> = Record<st
|
|
|
436
453
|
* @group Models
|
|
437
454
|
*/
|
|
438
455
|
export type EntityCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> = PostgresCollection<M, USER> | FirebaseCollection<M, USER> | MongoDBCollection<M, USER>;
|
|
439
|
-
/**
|
|
456
|
+
/**
|
|
457
|
+
* An EntityCollection that supports SQL-style relations (e.g. Postgres).
|
|
458
|
+
* @deprecated Use `EntityCollection` directly — `table`, `relations`, and `securityRules` are now on `BaseEntityCollection`.
|
|
459
|
+
*/
|
|
440
460
|
export type CollectionWithRelations<M extends Record<string, unknown> = Record<string, unknown>> = EntityCollection<M> & {
|
|
441
461
|
table?: string;
|
|
442
462
|
relations?: Relation[];
|
|
@@ -641,14 +641,6 @@ export interface MapProperty extends BaseProperty {
|
|
|
641
641
|
* Properties that are displayed when rendered as a preview
|
|
642
642
|
*/
|
|
643
643
|
previewProperties?: string[];
|
|
644
|
-
/**
|
|
645
|
-
* Allow the user to add only some keys in this map.
|
|
646
|
-
* By default, all properties of the map have the corresponding field in
|
|
647
|
-
* the form view. Setting this flag to true allows to pick only some.
|
|
648
|
-
* Useful for map that can have a lot of sub-properties that may not be
|
|
649
|
-
* needed
|
|
650
|
-
*/
|
|
651
|
-
pickOnlySomeKeys?: boolean;
|
|
652
644
|
/**
|
|
653
645
|
* Render this map as a key-value table that allows to use
|
|
654
646
|
* arbitrary keys. You don't need to define the properties in this case.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebasepro/client-postgresql",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"description": "PostgreSQL data source client for Rebase",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/rebaseco"
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
"./package.json": "./package.json"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@rebasepro/client": "0.
|
|
61
|
-
"@rebasepro/types": "0.
|
|
60
|
+
"@rebasepro/client": "0.5.0",
|
|
61
|
+
"@rebasepro/types": "0.5.0"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"react": ">=19.0.0",
|