@rebasepro/client-postgresql 0.0.1-canary.09e5ec5
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/LICENSE +6 -0
- package/README.md +106 -0
- 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/client-postgresql/src/index.d.ts +8 -0
- package/dist/client-postgresql/src/usePostgresClientDriver.d.ts +9 -0
- package/dist/index.es.js +165 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +168 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/types/src/controllers/analytics_controller.d.ts +7 -0
- package/dist/types/src/controllers/auth.d.ts +119 -0
- package/dist/types/src/controllers/client.d.ts +170 -0
- package/dist/types/src/controllers/collection_registry.d.ts +45 -0
- package/dist/types/src/controllers/customization_controller.d.ts +60 -0
- package/dist/types/src/controllers/data.d.ts +168 -0
- package/dist/types/src/controllers/data_driver.d.ts +160 -0
- package/dist/types/src/controllers/database_admin.d.ts +11 -0
- package/dist/types/src/controllers/dialogs_controller.d.ts +36 -0
- package/dist/types/src/controllers/effective_role.d.ts +4 -0
- package/dist/types/src/controllers/email.d.ts +34 -0
- package/dist/types/src/controllers/index.d.ts +18 -0
- package/dist/types/src/controllers/local_config_persistence.d.ts +20 -0
- package/dist/types/src/controllers/navigation.d.ts +213 -0
- package/dist/types/src/controllers/registry.d.ts +54 -0
- package/dist/types/src/controllers/side_dialogs_controller.d.ts +67 -0
- package/dist/types/src/controllers/side_entity_controller.d.ts +90 -0
- package/dist/types/src/controllers/snackbar.d.ts +24 -0
- package/dist/types/src/controllers/storage.d.ts +171 -0
- package/dist/types/src/index.d.ts +4 -0
- package/dist/types/src/rebase_context.d.ts +105 -0
- package/dist/types/src/types/backend.d.ts +536 -0
- package/dist/types/src/types/builders.d.ts +15 -0
- package/dist/types/src/types/chips.d.ts +5 -0
- package/dist/types/src/types/collections.d.ts +856 -0
- package/dist/types/src/types/cron.d.ts +102 -0
- package/dist/types/src/types/data_source.d.ts +64 -0
- package/dist/types/src/types/entities.d.ts +145 -0
- package/dist/types/src/types/entity_actions.d.ts +98 -0
- package/dist/types/src/types/entity_callbacks.d.ts +173 -0
- package/dist/types/src/types/entity_link_builder.d.ts +7 -0
- package/dist/types/src/types/entity_overrides.d.ts +10 -0
- package/dist/types/src/types/entity_views.d.ts +61 -0
- package/dist/types/src/types/export_import.d.ts +21 -0
- package/dist/types/src/types/index.d.ts +23 -0
- package/dist/types/src/types/locales.d.ts +4 -0
- package/dist/types/src/types/modify_collections.d.ts +5 -0
- package/dist/types/src/types/plugins.d.ts +279 -0
- package/dist/types/src/types/properties.d.ts +1176 -0
- package/dist/types/src/types/property_config.d.ts +70 -0
- package/dist/types/src/types/relations.d.ts +336 -0
- package/dist/types/src/types/slots.d.ts +252 -0
- package/dist/types/src/types/translations.d.ts +870 -0
- package/dist/types/src/types/user_management_delegate.d.ts +121 -0
- package/dist/types/src/types/websockets.d.ts +78 -0
- package/dist/types/src/users/index.d.ts +2 -0
- package/dist/types/src/users/roles.d.ts +22 -0
- package/dist/types/src/users/user.d.ts +46 -0
- package/package.json +87 -0
- package/src/index.ts +11 -0
- package/src/usePostgresClientDriver.ts +153 -0
- package/tsconfig.json +44 -0
- package/tsconfig.prod.json +20 -0
- package/vite.config.ts +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Source code in this repository is variously licensed under the Business Source
|
|
2
|
+
License 1.1 (BSL), Apache version 2.0 and the MIT license. A copy of each
|
|
3
|
+
license can be found in each one of the packages under the folder packages
|
|
4
|
+
under a file called License. Source code in a given file is licensed under the
|
|
5
|
+
BSL and the copyright belongs to Rebase Authors unless otherwise noted at the
|
|
6
|
+
beginning of the file.
|
package/README.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# @rebasepro/postgresql
|
|
2
|
+
|
|
3
|
+
PostgreSQL data source client for Rebase with real-time WebSocket connectivity.
|
|
4
|
+
|
|
5
|
+
This package provides a complete client-side implementation for connecting Rebase applications to PostgreSQL backends, featuring real-time synchronization via WebSockets.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @rebasepro/postgresql @rebasepro/core
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Basic Setup with React Hook
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { usePostgresDataSource } from "@rebasepro/postgresql";
|
|
19
|
+
import { Rebase } from "@rebasepro/core";
|
|
20
|
+
|
|
21
|
+
function App() {
|
|
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
|
+
});
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<Rebase
|
|
32
|
+
dataSource={dataSource}
|
|
33
|
+
collections={collections}
|
|
34
|
+
// ... other props
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Creating Data Source Directly
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { createPostgresDataSource } from "@rebasepro/postgresql";
|
|
44
|
+
|
|
45
|
+
const dataSource = createPostgresDataSource({
|
|
46
|
+
baseUrl: "http://localhost:3001",
|
|
47
|
+
websocketUrl: "ws://localhost:3001"
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Features
|
|
52
|
+
|
|
53
|
+
- **Real-time Synchronization**: WebSocket-based real-time updates for collections and entities
|
|
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
|
|
58
|
+
|
|
59
|
+
## API
|
|
60
|
+
|
|
61
|
+
### Configuration
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
interface PostgresDataSourceConfig {
|
|
65
|
+
baseUrl: string; // Backend server URL
|
|
66
|
+
websocketUrl?: string; // WebSocket URL (optional)
|
|
67
|
+
headers?: Record<string, string>; // Custom headers (optional)
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Methods
|
|
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
|
|
105
|
+
|
|
106
|
+
MIT
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Transport } from "./transport";
|
|
2
|
+
export interface AdminUser {
|
|
3
|
+
uid: string;
|
|
4
|
+
email: string;
|
|
5
|
+
displayName: string | null;
|
|
6
|
+
photoURL: string | null;
|
|
7
|
+
provider: string;
|
|
8
|
+
roles: string[];
|
|
9
|
+
createdAt: string;
|
|
10
|
+
updatedAt: string;
|
|
11
|
+
}
|
|
12
|
+
export interface RebaseRole {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
isAdmin: boolean;
|
|
16
|
+
defaultPermissions: Record<string, unknown> | null;
|
|
17
|
+
config: Record<string, unknown> | null;
|
|
18
|
+
}
|
|
19
|
+
export interface CreateAdminOptions {
|
|
20
|
+
adminPath?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function createAdmin(transport: Transport, options?: CreateAdminOptions): {
|
|
23
|
+
listUsers: () => Promise<{
|
|
24
|
+
users: AdminUser[];
|
|
25
|
+
}>;
|
|
26
|
+
listUsersPaginated: (options?: {
|
|
27
|
+
search?: string;
|
|
28
|
+
limit?: number;
|
|
29
|
+
offset?: number;
|
|
30
|
+
orderBy?: string;
|
|
31
|
+
orderDir?: "asc" | "desc";
|
|
32
|
+
}) => Promise<{
|
|
33
|
+
users: AdminUser[];
|
|
34
|
+
total: number;
|
|
35
|
+
limit: number;
|
|
36
|
+
offset: number;
|
|
37
|
+
}>;
|
|
38
|
+
getUser: (userId: string) => Promise<{
|
|
39
|
+
user: AdminUser;
|
|
40
|
+
}>;
|
|
41
|
+
createUser: (data: {
|
|
42
|
+
email: string;
|
|
43
|
+
displayName?: string;
|
|
44
|
+
password?: string;
|
|
45
|
+
roles?: string[];
|
|
46
|
+
}) => Promise<{
|
|
47
|
+
user: AdminUser;
|
|
48
|
+
}>;
|
|
49
|
+
updateUser: (userId: string, data: {
|
|
50
|
+
email?: string;
|
|
51
|
+
displayName?: string;
|
|
52
|
+
password?: string;
|
|
53
|
+
roles?: string[];
|
|
54
|
+
}) => Promise<{
|
|
55
|
+
user: AdminUser;
|
|
56
|
+
}>;
|
|
57
|
+
deleteUser: (userId: string) => Promise<{
|
|
58
|
+
success: boolean;
|
|
59
|
+
}>;
|
|
60
|
+
listRoles: () => Promise<{
|
|
61
|
+
roles: RebaseRole[];
|
|
62
|
+
}>;
|
|
63
|
+
getRole: (roleId: string) => Promise<{
|
|
64
|
+
role: RebaseRole;
|
|
65
|
+
}>;
|
|
66
|
+
createRole: (data: {
|
|
67
|
+
id: string;
|
|
68
|
+
name: string;
|
|
69
|
+
isAdmin?: boolean;
|
|
70
|
+
defaultPermissions?: Record<string, unknown>;
|
|
71
|
+
config?: Record<string, unknown>;
|
|
72
|
+
}) => Promise<{
|
|
73
|
+
role: RebaseRole;
|
|
74
|
+
}>;
|
|
75
|
+
updateRole: (roleId: string, data: {
|
|
76
|
+
name?: string;
|
|
77
|
+
isAdmin?: boolean;
|
|
78
|
+
defaultPermissions?: Record<string, unknown>;
|
|
79
|
+
config?: Record<string, unknown>;
|
|
80
|
+
}) => Promise<{
|
|
81
|
+
role: RebaseRole;
|
|
82
|
+
}>;
|
|
83
|
+
deleteRole: (roleId: string) => Promise<{
|
|
84
|
+
success: boolean;
|
|
85
|
+
}>;
|
|
86
|
+
bootstrap: () => Promise<{
|
|
87
|
+
success: boolean;
|
|
88
|
+
message: string;
|
|
89
|
+
user: {
|
|
90
|
+
uid: string;
|
|
91
|
+
roles: string[];
|
|
92
|
+
};
|
|
93
|
+
}>;
|
|
94
|
+
};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { Transport } from "./transport";
|
|
2
|
+
export interface RebaseUser {
|
|
3
|
+
uid: string;
|
|
4
|
+
email: string | null;
|
|
5
|
+
displayName: string | null;
|
|
6
|
+
photoURL: string | null;
|
|
7
|
+
emailVerified?: boolean;
|
|
8
|
+
roles?: string[];
|
|
9
|
+
providerId: string;
|
|
10
|
+
isAnonymous: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface RebaseTokens {
|
|
13
|
+
accessToken: string;
|
|
14
|
+
refreshToken: string;
|
|
15
|
+
accessTokenExpiresAt: number;
|
|
16
|
+
}
|
|
17
|
+
export interface RebaseSession {
|
|
18
|
+
accessToken: string;
|
|
19
|
+
refreshToken: string;
|
|
20
|
+
expiresAt: number;
|
|
21
|
+
user: RebaseUser;
|
|
22
|
+
}
|
|
23
|
+
export type AuthChangeEvent = "SIGNED_IN" | "SIGNED_OUT" | "TOKEN_REFRESHED" | "USER_UPDATED";
|
|
24
|
+
export interface AuthConfig {
|
|
25
|
+
needsSetup: boolean;
|
|
26
|
+
registrationEnabled: boolean;
|
|
27
|
+
googleEnabled: boolean;
|
|
28
|
+
emailServiceEnabled: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface AuthStorage {
|
|
31
|
+
getItem: (key: string) => string | null;
|
|
32
|
+
setItem: (key: string, value: string) => void;
|
|
33
|
+
removeItem: (key: string) => void;
|
|
34
|
+
}
|
|
35
|
+
export declare function createMemoryStorage(): AuthStorage;
|
|
36
|
+
export interface CreateAuthOptions {
|
|
37
|
+
storage?: AuthStorage;
|
|
38
|
+
authPath?: string;
|
|
39
|
+
autoRefresh?: boolean;
|
|
40
|
+
persistSession?: boolean;
|
|
41
|
+
}
|
|
42
|
+
export declare function createAuth(transport: Transport, options?: CreateAuthOptions): {
|
|
43
|
+
signInWithEmail: (email: string, password: string) => Promise<{
|
|
44
|
+
user: RebaseUser;
|
|
45
|
+
accessToken: string;
|
|
46
|
+
refreshToken: string;
|
|
47
|
+
}>;
|
|
48
|
+
signUp: (email: string, password: string, displayName?: string) => Promise<{
|
|
49
|
+
user: RebaseUser;
|
|
50
|
+
accessToken: string;
|
|
51
|
+
refreshToken: string;
|
|
52
|
+
}>;
|
|
53
|
+
signInWithGoogle: (idToken: string) => Promise<{
|
|
54
|
+
user: RebaseUser;
|
|
55
|
+
accessToken: string;
|
|
56
|
+
refreshToken: string;
|
|
57
|
+
}>;
|
|
58
|
+
signInWithLinkedin: (code: string, redirectUri: string) => Promise<{
|
|
59
|
+
user: RebaseUser;
|
|
60
|
+
accessToken: string;
|
|
61
|
+
refreshToken: string;
|
|
62
|
+
}>;
|
|
63
|
+
signInWithOAuth: (providerId: string, payload: Record<string, unknown>) => Promise<{
|
|
64
|
+
user: RebaseUser;
|
|
65
|
+
accessToken: string;
|
|
66
|
+
refreshToken: string;
|
|
67
|
+
}>;
|
|
68
|
+
signInWithGitHub: (code: string, redirectUri: string) => Promise<{
|
|
69
|
+
user: RebaseUser;
|
|
70
|
+
accessToken: string;
|
|
71
|
+
refreshToken: string;
|
|
72
|
+
}>;
|
|
73
|
+
signInWithMicrosoft: (code: string, redirectUri: string) => Promise<{
|
|
74
|
+
user: RebaseUser;
|
|
75
|
+
accessToken: string;
|
|
76
|
+
refreshToken: string;
|
|
77
|
+
}>;
|
|
78
|
+
signInWithApple: (code: string, redirectUri: string, user?: {
|
|
79
|
+
name?: {
|
|
80
|
+
firstName?: string;
|
|
81
|
+
lastName?: string;
|
|
82
|
+
};
|
|
83
|
+
email?: string;
|
|
84
|
+
}) => Promise<{
|
|
85
|
+
user: RebaseUser;
|
|
86
|
+
accessToken: string;
|
|
87
|
+
refreshToken: string;
|
|
88
|
+
}>;
|
|
89
|
+
signInWithFacebook: (code: string, redirectUri: string) => Promise<{
|
|
90
|
+
user: RebaseUser;
|
|
91
|
+
accessToken: string;
|
|
92
|
+
refreshToken: string;
|
|
93
|
+
}>;
|
|
94
|
+
signInWithTwitter: (code: string, redirectUri: string, codeVerifier: string) => Promise<{
|
|
95
|
+
user: RebaseUser;
|
|
96
|
+
accessToken: string;
|
|
97
|
+
refreshToken: string;
|
|
98
|
+
}>;
|
|
99
|
+
signInWithDiscord: (code: string, redirectUri: string) => Promise<{
|
|
100
|
+
user: RebaseUser;
|
|
101
|
+
accessToken: string;
|
|
102
|
+
refreshToken: string;
|
|
103
|
+
}>;
|
|
104
|
+
signInWithGitLab: (code: string, redirectUri: string) => Promise<{
|
|
105
|
+
user: RebaseUser;
|
|
106
|
+
accessToken: string;
|
|
107
|
+
refreshToken: string;
|
|
108
|
+
}>;
|
|
109
|
+
signInWithBitbucket: (code: string, redirectUri: string) => Promise<{
|
|
110
|
+
user: RebaseUser;
|
|
111
|
+
accessToken: string;
|
|
112
|
+
refreshToken: string;
|
|
113
|
+
}>;
|
|
114
|
+
signInWithSlack: (code: string, redirectUri: string) => Promise<{
|
|
115
|
+
user: RebaseUser;
|
|
116
|
+
accessToken: string;
|
|
117
|
+
refreshToken: string;
|
|
118
|
+
}>;
|
|
119
|
+
signInWithSpotify: (code: string, redirectUri: string) => Promise<{
|
|
120
|
+
user: RebaseUser;
|
|
121
|
+
accessToken: string;
|
|
122
|
+
refreshToken: string;
|
|
123
|
+
}>;
|
|
124
|
+
signOut: () => Promise<void>;
|
|
125
|
+
refreshSession: () => Promise<RebaseSession>;
|
|
126
|
+
getUser: () => Promise<RebaseUser>;
|
|
127
|
+
updateUser: (updates: {
|
|
128
|
+
displayName?: string;
|
|
129
|
+
photoURL?: string;
|
|
130
|
+
}) => Promise<RebaseUser>;
|
|
131
|
+
resetPasswordForEmail: (email: string) => Promise<{
|
|
132
|
+
success: boolean;
|
|
133
|
+
message: string;
|
|
134
|
+
}>;
|
|
135
|
+
resetPassword: (token: string, password: string) => Promise<{
|
|
136
|
+
success: boolean;
|
|
137
|
+
message: string;
|
|
138
|
+
}>;
|
|
139
|
+
changePassword: (oldPassword: string, newPassword: string) => Promise<{
|
|
140
|
+
success: boolean;
|
|
141
|
+
message: string;
|
|
142
|
+
}>;
|
|
143
|
+
sendVerificationEmail: () => Promise<{
|
|
144
|
+
success: boolean;
|
|
145
|
+
message: string;
|
|
146
|
+
}>;
|
|
147
|
+
verifyEmail: (token: string) => Promise<{
|
|
148
|
+
success: boolean;
|
|
149
|
+
message: string;
|
|
150
|
+
}>;
|
|
151
|
+
getSessions: () => Promise<Record<string, unknown>[]>;
|
|
152
|
+
revokeSession: (sessionId: string) => Promise<{
|
|
153
|
+
success: boolean;
|
|
154
|
+
}>;
|
|
155
|
+
revokeAllSessions: () => Promise<{
|
|
156
|
+
success: boolean;
|
|
157
|
+
}>;
|
|
158
|
+
getAuthConfig: () => Promise<AuthConfig>;
|
|
159
|
+
getSession: () => RebaseSession | null;
|
|
160
|
+
onAuthStateChange: (callback: (event: AuthChangeEvent, session: RebaseSession | null) => void) => () => boolean;
|
|
161
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Transport } from "./transport";
|
|
2
|
+
import { RebaseWebSocketClient } from "./websocket";
|
|
3
|
+
import { CollectionAccessor } from "@rebasepro/types";
|
|
4
|
+
import { FilterOperator, QueryBuilder } from "./query_builder";
|
|
5
|
+
/**
|
|
6
|
+
* CollectionClient extends `CollectionAccessor` from `@rebasepro/types` so that
|
|
7
|
+
* `client.data` can be passed directly to the core Rebase component.
|
|
8
|
+
*
|
|
9
|
+
* Additionally it exposes fluent query builder methods like `.where()`, `.orderBy()`.
|
|
10
|
+
*/
|
|
11
|
+
export interface CollectionClient<M extends Record<string, unknown> = Record<string, unknown>> extends CollectionAccessor<M> {
|
|
12
|
+
where(column: keyof M & string, operator: FilterOperator, value: unknown): QueryBuilder<M>;
|
|
13
|
+
orderBy(column: keyof M & string, ascending?: "asc" | "desc"): QueryBuilder<M>;
|
|
14
|
+
limit(count: number): QueryBuilder<M>;
|
|
15
|
+
offset(count: number): QueryBuilder<M>;
|
|
16
|
+
search(searchString: string): QueryBuilder<M>;
|
|
17
|
+
include(...relations: string[]): QueryBuilder<M>;
|
|
18
|
+
}
|
|
19
|
+
export declare function createCollectionClient<M extends Record<string, unknown> = Record<string, unknown>>(transport: Transport, slug: string, ws?: RebaseWebSocketClient): CollectionClient<M>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Transport } from "./transport";
|
|
2
|
+
import type { CronJobStatus, CronJobLogEntry } from "@rebasepro/types";
|
|
3
|
+
export interface CreateCronOptions {
|
|
4
|
+
cronPath?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function createCron(transport: Transport, options?: CreateCronOptions): {
|
|
7
|
+
listJobs: () => Promise<{
|
|
8
|
+
jobs: CronJobStatus[];
|
|
9
|
+
}>;
|
|
10
|
+
getJob: (jobId: string) => Promise<{
|
|
11
|
+
job: CronJobStatus;
|
|
12
|
+
}>;
|
|
13
|
+
triggerJob: (jobId: string) => Promise<{
|
|
14
|
+
log: CronJobLogEntry;
|
|
15
|
+
job: CronJobStatus;
|
|
16
|
+
}>;
|
|
17
|
+
getJobLogs: (jobId: string, options?: {
|
|
18
|
+
limit?: number;
|
|
19
|
+
}) => Promise<{
|
|
20
|
+
logs: CronJobLogEntry[];
|
|
21
|
+
}>;
|
|
22
|
+
toggleJob: (jobId: string, enabled: boolean) => Promise<{
|
|
23
|
+
job: CronJobStatus;
|
|
24
|
+
}>;
|
|
25
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { RebaseClientConfig } from "./transport";
|
|
2
|
+
import { createAuth, CreateAuthOptions } from "./auth";
|
|
3
|
+
import { createAdmin, CreateAdminOptions } from "./admin";
|
|
4
|
+
import { createCron, CreateCronOptions } from "./cron";
|
|
5
|
+
import { CollectionClient } from "./collection";
|
|
6
|
+
export * from "./transport";
|
|
7
|
+
export * from "./auth";
|
|
8
|
+
export * from "./admin";
|
|
9
|
+
export * from "./cron";
|
|
10
|
+
export * from "./collection";
|
|
11
|
+
export * from "./websocket";
|
|
12
|
+
export * from "./storage";
|
|
13
|
+
export * from "./reviver";
|
|
14
|
+
export interface CreateRebaseClientOptions extends RebaseClientConfig {
|
|
15
|
+
auth?: CreateAuthOptions;
|
|
16
|
+
admin?: CreateAdminOptions;
|
|
17
|
+
cron?: CreateCronOptions;
|
|
18
|
+
}
|
|
19
|
+
import { RebaseWebSocketClient } from "./websocket";
|
|
20
|
+
import { RebaseClient as BaseRebaseClient, RebaseData, StorageSource } from "@rebasepro/types";
|
|
21
|
+
export type RebaseClient<DB = Record<string, unknown>> = BaseRebaseClient<DB> & {
|
|
22
|
+
setToken: (token: string | null) => void;
|
|
23
|
+
setAuthTokenGetter: (getter: () => Promise<string | null>) => void;
|
|
24
|
+
setOnUnauthorized: (handler: () => Promise<boolean>) => void;
|
|
25
|
+
resolveToken: () => Promise<string | null>;
|
|
26
|
+
auth: ReturnType<typeof createAuth>;
|
|
27
|
+
admin: ReturnType<typeof createAdmin>;
|
|
28
|
+
cron: ReturnType<typeof createCron>;
|
|
29
|
+
ws?: RebaseWebSocketClient;
|
|
30
|
+
storage?: StorageSource;
|
|
31
|
+
call: <T = unknown>(endpoint: string, payload?: unknown) => Promise<T>;
|
|
32
|
+
data: RebaseData & {
|
|
33
|
+
collection<K extends keyof DB>(slug: Extract<K, string>): CollectionClient<DB[K] extends {
|
|
34
|
+
Row: infer R extends Record<string, unknown>;
|
|
35
|
+
} ? R : Record<string, unknown>>;
|
|
36
|
+
} & {
|
|
37
|
+
[K in keyof DB]: CollectionClient<DB[K] extends {
|
|
38
|
+
Row: infer R extends Record<string, unknown>;
|
|
39
|
+
} ? R : Record<string, unknown>>;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
export declare function createRebaseClient<DB = Record<string, unknown>>(options: CreateRebaseClientOptions): RebaseClient<DB>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { FindResponse } from "@rebasepro/types";
|
|
2
|
+
import { CollectionClient } from "./collection";
|
|
3
|
+
export type FilterOperator = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "nin" | "cs" | "csa" | "==" | "!=" | ">" | ">=" | "<" | "<=" | "array-contains" | "array-contains-any" | "not-in";
|
|
4
|
+
export declare class QueryBuilder<M extends Record<string, unknown> = Record<string, unknown>> {
|
|
5
|
+
private collection;
|
|
6
|
+
private params;
|
|
7
|
+
constructor(collection: CollectionClient<M>);
|
|
8
|
+
/**
|
|
9
|
+
* Add a filter condition to your query.
|
|
10
|
+
* @example
|
|
11
|
+
* client.collection('users').where('age', '>=', 18).find()
|
|
12
|
+
*/
|
|
13
|
+
where(column: keyof M & string, operator: FilterOperator, value: unknown): this;
|
|
14
|
+
/**
|
|
15
|
+
* Order the results by a specific column.
|
|
16
|
+
* @example
|
|
17
|
+
* client.collection('users').orderBy('createdAt', 'desc').find()
|
|
18
|
+
*/
|
|
19
|
+
orderBy(column: keyof M & string, ascending?: "asc" | "desc"): this;
|
|
20
|
+
/**
|
|
21
|
+
* Limit the number of results returned.
|
|
22
|
+
*/
|
|
23
|
+
limit(count: number): this;
|
|
24
|
+
/**
|
|
25
|
+
* Skip the first N results.
|
|
26
|
+
*/
|
|
27
|
+
offset(count: number): this;
|
|
28
|
+
/**
|
|
29
|
+
* Set a free-text search string if supported by the backend.
|
|
30
|
+
*/
|
|
31
|
+
search(searchString: string): this;
|
|
32
|
+
/**
|
|
33
|
+
* Include related entities in the response.
|
|
34
|
+
* Relations will be populated with full entity data instead of just IDs.
|
|
35
|
+
*
|
|
36
|
+
* @param relations - Relation names to include, or "*" for all.
|
|
37
|
+
* @example
|
|
38
|
+
* // Include specific relations
|
|
39
|
+
* client.data.posts.include("tags", "author").find()
|
|
40
|
+
*
|
|
41
|
+
* // Include all relations
|
|
42
|
+
* client.data.posts.include("*").find()
|
|
43
|
+
*/
|
|
44
|
+
include(...relations: string[]): this;
|
|
45
|
+
/**
|
|
46
|
+
* Execute the find query and return the results.
|
|
47
|
+
*/
|
|
48
|
+
find(): Promise<FindResponse<M>>;
|
|
49
|
+
/**
|
|
50
|
+
* Listen to realtime updates matching this query.
|
|
51
|
+
*/
|
|
52
|
+
listen(onUpdate: (data: FindResponse<M>) => void, onError?: (error: Error) => void): () => void;
|
|
53
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function rebaseReviver(_key: string, value: unknown): unknown;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { FindParams as TypesFindParams, FindResponse as TypesFindResponse } from "@rebasepro/types";
|
|
2
|
+
export interface RebaseClientConfig {
|
|
3
|
+
baseUrl?: string;
|
|
4
|
+
token?: string;
|
|
5
|
+
apiPath?: string;
|
|
6
|
+
fetch?: typeof globalThis.fetch;
|
|
7
|
+
onUnauthorized?: () => Promise<boolean>;
|
|
8
|
+
websocketUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Re-export from `@rebasepro/types` for backward compatibility.
|
|
12
|
+
*/
|
|
13
|
+
export type FindParams = TypesFindParams;
|
|
14
|
+
export type FindResponse<T> = TypesFindResponse<T extends Record<string, unknown> ? T : Record<string, unknown>>;
|
|
15
|
+
export declare class RebaseApiError extends Error {
|
|
16
|
+
status: number;
|
|
17
|
+
code?: string;
|
|
18
|
+
details?: unknown;
|
|
19
|
+
constructor(status: number, message: string, code?: string, details?: unknown);
|
|
20
|
+
}
|
|
21
|
+
export declare function buildQueryString(params?: FindParams): string;
|
|
22
|
+
export interface Transport {
|
|
23
|
+
request: <T = unknown>(path: string, init?: RequestInit) => Promise<T>;
|
|
24
|
+
setToken: (newToken: string | null) => void;
|
|
25
|
+
setAuthTokenGetter: (getter: () => Promise<string | null>) => void;
|
|
26
|
+
setOnUnauthorized: (handler: () => Promise<boolean>) => void;
|
|
27
|
+
readonly baseUrl: string;
|
|
28
|
+
readonly apiPath: string;
|
|
29
|
+
readonly fetchFn: typeof globalThis.fetch;
|
|
30
|
+
getHeaders: (init?: RequestInit) => Record<string, string>;
|
|
31
|
+
resolveToken: () => Promise<string | null>;
|
|
32
|
+
}
|
|
33
|
+
export declare function createTransport(config: RebaseClientConfig): Transport;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { DeleteEntityProps, Entity, EntityCollection, FetchCollectionProps, FetchEntityProps, SaveEntityProps, TableMetadata, BranchInfo } from "@rebasepro/types";
|
|
2
|
+
export interface RebaseWebSocketConfig {
|
|
3
|
+
websocketUrl: string;
|
|
4
|
+
/** Optional auth token getter for WebSocket authentication */
|
|
5
|
+
getAuthToken?: () => Promise<string>;
|
|
6
|
+
/** Optional WebSocket constructor to override globalThis.WebSocket (e.g. for Node environments) */
|
|
7
|
+
WebSocket?: typeof WebSocket;
|
|
8
|
+
}
|
|
9
|
+
export declare class ApiError extends Error {
|
|
10
|
+
code?: string;
|
|
11
|
+
error?: string;
|
|
12
|
+
constructor(message: string, error?: string, code?: string);
|
|
13
|
+
}
|
|
14
|
+
export declare class RebaseWebSocketClient {
|
|
15
|
+
private websocketUrl;
|
|
16
|
+
private ws;
|
|
17
|
+
getAuthToken?: () => Promise<string>;
|
|
18
|
+
private subscriptions;
|
|
19
|
+
private listeners;
|
|
20
|
+
on(event: "connect" | "disconnect" | "reconnect" | "error", cb: (...args: unknown[]) => void): () => boolean;
|
|
21
|
+
private emit;
|
|
22
|
+
private collectionSubscriptions;
|
|
23
|
+
private entitySubscriptions;
|
|
24
|
+
private backendToCollectionKey;
|
|
25
|
+
private backendToEntityKey;
|
|
26
|
+
private pendingRequests;
|
|
27
|
+
private reconnectAttempts;
|
|
28
|
+
private maxReconnectAttempts;
|
|
29
|
+
private isConnected;
|
|
30
|
+
private messageQueue;
|
|
31
|
+
private reconnectTimeout;
|
|
32
|
+
private isAuthenticated;
|
|
33
|
+
private authPromise;
|
|
34
|
+
private WebSocketConstructor;
|
|
35
|
+
constructor(config: RebaseWebSocketConfig);
|
|
36
|
+
/**
|
|
37
|
+
* Authenticate the WebSocket connection
|
|
38
|
+
*/
|
|
39
|
+
authenticate(token: string): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Set the auth token getter function
|
|
42
|
+
*/
|
|
43
|
+
setAuthTokenGetter(getAuthToken: () => Promise<string>): void;
|
|
44
|
+
disconnect(): void;
|
|
45
|
+
private initWebSocket;
|
|
46
|
+
private processMessageQueue;
|
|
47
|
+
private attemptReconnect;
|
|
48
|
+
private handleWebSocketMessage;
|
|
49
|
+
private ensureAuthenticated;
|
|
50
|
+
/**
|
|
51
|
+
* Force re-authentication (call after token refresh)
|
|
52
|
+
*/
|
|
53
|
+
reauthenticate(): Promise<void>;
|
|
54
|
+
private sendMessage;
|
|
55
|
+
private doSendMessage;
|
|
56
|
+
fetchCollection<M extends Record<string, unknown>>(props: FetchCollectionProps<M>): Promise<Entity<M>[]>;
|
|
57
|
+
fetchEntity<M extends Record<string, unknown>>(props: FetchEntityProps<M>): Promise<Entity<M> | undefined>;
|
|
58
|
+
saveEntity<M extends Record<string, unknown>>(props: SaveEntityProps<M>): Promise<Entity<M>>;
|
|
59
|
+
deleteEntity<M extends Record<string, unknown>>(props: DeleteEntityProps<M>): Promise<void>;
|
|
60
|
+
executeSql(sql: string, options?: {
|
|
61
|
+
database?: string;
|
|
62
|
+
role?: string;
|
|
63
|
+
}): Promise<Record<string, unknown>[]>;
|
|
64
|
+
fetchAvailableDatabases(): Promise<string[]>;
|
|
65
|
+
fetchAvailableRoles(): Promise<string[]>;
|
|
66
|
+
fetchCurrentDatabase(): Promise<string | undefined>;
|
|
67
|
+
checkUniqueField(path: string, name: string, value: unknown, entityId?: string, collection?: EntityCollection): Promise<boolean>;
|
|
68
|
+
countEntities<M extends Record<string, unknown>>(props: FetchCollectionProps<M>): Promise<number>;
|
|
69
|
+
fetchUnmappedTables(mappedPaths?: string[]): Promise<string[]>;
|
|
70
|
+
fetchTableMetadata(tableName: string): Promise<TableMetadata>;
|
|
71
|
+
createBranch(name: string, options?: {
|
|
72
|
+
source?: string;
|
|
73
|
+
}): Promise<BranchInfo>;
|
|
74
|
+
deleteBranch(name: string): Promise<void>;
|
|
75
|
+
listBranches(): Promise<BranchInfo[]>;
|
|
76
|
+
/**
|
|
77
|
+
* Recursively compare two values for structural equality.
|
|
78
|
+
* Handles primitives, null, undefined, Date, RegExp, arrays, and plain objects.
|
|
79
|
+
*/
|
|
80
|
+
private deepEqual;
|
|
81
|
+
private normalizeForComparison;
|
|
82
|
+
/**
|
|
83
|
+
* Merge incoming entities with cached data, preserving cached references
|
|
84
|
+
* for entities whose values haven't changed. This avoids unnecessary
|
|
85
|
+
* React re-renders when the server refetches all entities but most
|
|
86
|
+
* haven't actually changed.
|
|
87
|
+
*/
|
|
88
|
+
private mergeEntities;
|
|
89
|
+
listenCollection<M extends Record<string, unknown>>(props: FetchCollectionProps<M>, onUpdate: (entities: Entity[]) => void, onError?: (error: Error) => void): () => void;
|
|
90
|
+
listenEntity<M extends Record<string, unknown>>(props: FetchEntityProps<M>, onUpdate: (entity: Entity | null) => void, onError?: (error: Error) => void): () => void;
|
|
91
|
+
/**
|
|
92
|
+
* Re-send all active subscriptions to the backend after a reconnect.
|
|
93
|
+
* The server wipes subscription state when a client disconnects, so
|
|
94
|
+
* we need to re-register everything to resume receiving updates.
|
|
95
|
+
*/
|
|
96
|
+
private resubscribeAll;
|
|
97
|
+
private createCollectionSubscriptionKey;
|
|
98
|
+
private createEntitySubscriptionKey;
|
|
99
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rebasepro/client-postgresql
|
|
3
|
+
*
|
|
4
|
+
* PostgreSQL data source client for Rebase
|
|
5
|
+
* This package provides a WebSocket-based client for connecting Rebase applications
|
|
6
|
+
* to PostgreSQL backends with real-time synchronization capabilities.
|
|
7
|
+
*/
|
|
8
|
+
export * from "./usePostgresClientDriver";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DataDriver } from "@rebasepro/types";
|
|
2
|
+
import { RebaseWebSocketClient } from "@rebasepro/client";
|
|
3
|
+
export interface PostgresDataDriverConfig {
|
|
4
|
+
wsClient?: RebaseWebSocketClient;
|
|
5
|
+
}
|
|
6
|
+
export interface PostgresDataDriver extends DataDriver {
|
|
7
|
+
client?: RebaseWebSocketClient;
|
|
8
|
+
}
|
|
9
|
+
export declare function usePostgresClientDriver(config: PostgresDataDriverConfig): PostgresDataDriver;
|