@rebasepro/server-postgresql 0.2.3 → 0.2.5
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/default-collections.d.ts +9 -0
- package/dist/common/src/collections/index.d.ts +1 -0
- package/dist/common/src/util/permissions.d.ts +1 -0
- package/dist/index.es.js +1075 -470
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1071 -466
- package/dist/index.umd.js.map +1 -1
- package/dist/server-postgresql/src/PostgresBackendDriver.d.ts +3 -1
- package/dist/server-postgresql/src/PostgresBootstrapper.d.ts +1 -0
- package/dist/server-postgresql/src/auth/services.d.ts +48 -31
- package/dist/server-postgresql/src/connection.d.ts +25 -0
- package/dist/server-postgresql/src/schema/auth-schema.d.ts +2135 -41
- package/dist/server-postgresql/src/services/EntityFetchService.d.ts +4 -0
- package/dist/server-postgresql/src/services/EntityPersistService.d.ts +4 -0
- package/dist/server-postgresql/src/services/entityService.d.ts +6 -0
- package/dist/server-postgresql/src/services/realtimeService.d.ts +20 -0
- package/dist/server-postgresql/src/utils/drizzle-conditions.d.ts +18 -0
- package/dist/types/src/controllers/auth.d.ts +4 -26
- package/dist/types/src/controllers/client.d.ts +25 -43
- package/dist/types/src/controllers/collection_registry.d.ts +1 -1
- package/dist/types/src/controllers/data.d.ts +4 -0
- package/dist/types/src/controllers/data_driver.d.ts +23 -0
- package/dist/types/src/controllers/registry.d.ts +5 -4
- package/dist/types/src/rebase_context.d.ts +1 -1
- package/dist/types/src/types/auth_adapter.d.ts +5 -60
- package/dist/types/src/types/backend.d.ts +2 -2
- package/dist/types/src/types/backend_hooks.d.ts +2 -17
- package/dist/types/src/types/collections.d.ts +0 -4
- package/dist/types/src/types/component_ref.d.ts +1 -1
- package/dist/types/src/types/cron.d.ts +1 -1
- package/dist/types/src/types/entity_views.d.ts +1 -0
- package/dist/types/src/types/export_import.d.ts +1 -1
- package/dist/types/src/types/formex.d.ts +2 -2
- package/dist/types/src/types/properties.d.ts +9 -7
- package/dist/types/src/types/translations.d.ts +28 -12
- package/dist/types/src/types/user_management_delegate.d.ts +22 -57
- package/dist/types/src/users/index.d.ts +0 -1
- package/dist/types/src/users/user.d.ts +0 -1
- package/package.json +6 -6
- package/src/PostgresBackendDriver.ts +14 -2
- package/src/PostgresBootstrapper.ts +30 -20
- package/src/auth/ensure-tables.ts +116 -103
- package/src/auth/services.ts +347 -177
- package/src/connection.ts +77 -0
- package/src/data-transformer.ts +2 -2
- package/src/schema/auth-schema.ts +85 -75
- package/src/schema/doctor.ts +44 -3
- package/src/schema/generate-drizzle-schema-logic.ts +33 -3
- package/src/schema/generate-drizzle-schema.ts +6 -6
- package/src/schema/introspect-db-logic.ts +7 -0
- package/src/services/EntityFetchService.ts +69 -10
- package/src/services/EntityPersistService.ts +9 -0
- package/src/services/entityService.ts +9 -0
- package/src/services/realtimeService.ts +214 -2
- package/src/utils/drizzle-conditions.ts +74 -2
- package/src/websocket.ts +10 -2
- package/test/auth-services.test.ts +10 -166
- package/test/doctor.test.ts +6 -2
- package/test/drizzle-conditions.test.ts +168 -0
- package/vite.config.ts +1 -1
- package/dist/server-postgresql/src/schema/default-collections.d.ts +0 -2
- package/dist/types/src/users/roles.d.ts +0 -22
- package/src/schema/default-collections.ts +0 -69
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SQL } from "drizzle-orm";
|
|
2
2
|
import { PgTable } from "drizzle-orm/pg-core";
|
|
3
3
|
import { Entity, FilterValues } from "@rebasepro/types";
|
|
4
|
+
import type { VectorSearchParams } from "@rebasepro/types";
|
|
4
5
|
import { RelationService } from "./RelationService";
|
|
5
6
|
import { DrizzleClient } from "../interfaces";
|
|
6
7
|
import { PostgresCollectionRegistry } from "../collections/PostgresCollectionRegistry";
|
|
@@ -102,6 +103,7 @@ export declare class EntityFetchService {
|
|
|
102
103
|
startAfter?: Record<string, unknown>;
|
|
103
104
|
searchString?: string;
|
|
104
105
|
databaseId?: string;
|
|
106
|
+
vectorSearch?: VectorSearchParams;
|
|
105
107
|
}): Promise<Entity<M>[]>;
|
|
106
108
|
/**
|
|
107
109
|
* Fallback path used when db.query is unavailable.
|
|
@@ -123,6 +125,7 @@ export declare class EntityFetchService {
|
|
|
123
125
|
startAfter?: Record<string, unknown>;
|
|
124
126
|
searchString?: string;
|
|
125
127
|
databaseId?: string;
|
|
128
|
+
vectorSearch?: VectorSearchParams;
|
|
126
129
|
}): Promise<Entity<M>[]>;
|
|
127
130
|
/**
|
|
128
131
|
* Search entities by text
|
|
@@ -175,6 +178,7 @@ export declare class EntityFetchService {
|
|
|
175
178
|
startAfter?: Record<string, unknown>;
|
|
176
179
|
searchString?: string;
|
|
177
180
|
databaseId?: string;
|
|
181
|
+
vectorSearch?: VectorSearchParams;
|
|
178
182
|
}, include?: string[]): Promise<Record<string, unknown>[]>;
|
|
179
183
|
/**
|
|
180
184
|
* Fetch a single entity with optional relation includes for REST API.
|
|
@@ -17,6 +17,10 @@ export declare class EntityPersistService {
|
|
|
17
17
|
* Delete an entity by ID
|
|
18
18
|
*/
|
|
19
19
|
deleteEntity(collectionPath: string, entityId: string | number, _databaseId?: string): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Delete all entities from a collection
|
|
22
|
+
*/
|
|
23
|
+
deleteAll(collectionPath: string, _databaseId?: string): Promise<void>;
|
|
20
24
|
/**
|
|
21
25
|
* Save an entity (create or update)
|
|
22
26
|
*/
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Entity, FilterValues } from "@rebasepro/types";
|
|
2
|
+
import type { VectorSearchParams } from "@rebasepro/types";
|
|
2
3
|
import { EntityFetchService } from "./EntityFetchService";
|
|
3
4
|
import { EntityPersistService } from "./EntityPersistService";
|
|
4
5
|
import { RelationService } from "./RelationService";
|
|
@@ -42,6 +43,7 @@ export declare class EntityService implements EntityRepository {
|
|
|
42
43
|
startAfter?: Record<string, unknown>;
|
|
43
44
|
searchString?: string;
|
|
44
45
|
databaseId?: string;
|
|
46
|
+
vectorSearch?: VectorSearchParams;
|
|
45
47
|
}): Promise<Entity<M>[]>;
|
|
46
48
|
/**
|
|
47
49
|
* Search entities by text
|
|
@@ -85,6 +87,10 @@ export declare class EntityService implements EntityRepository {
|
|
|
85
87
|
* Delete an entity by ID
|
|
86
88
|
*/
|
|
87
89
|
deleteEntity(collectionPath: string, entityId: string | number, databaseId?: string): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Delete all entities from a collection
|
|
92
|
+
*/
|
|
93
|
+
deleteAll(collectionPath: string, databaseId?: string): Promise<void>;
|
|
88
94
|
/**
|
|
89
95
|
* Execute raw SQL
|
|
90
96
|
*/
|
|
@@ -22,6 +22,10 @@ export declare class RealtimeService extends EventEmitter implements RealtimePro
|
|
|
22
22
|
private db;
|
|
23
23
|
private registry;
|
|
24
24
|
private clients;
|
|
25
|
+
private channels;
|
|
26
|
+
private presence;
|
|
27
|
+
private presenceInterval?;
|
|
28
|
+
private static readonly PRESENCE_TIMEOUT_MS;
|
|
25
29
|
private entityService;
|
|
26
30
|
private _subscriptions;
|
|
27
31
|
private subscriptionCallbacks;
|
|
@@ -152,6 +156,22 @@ export declare class RealtimeService extends EventEmitter implements RealtimePro
|
|
|
152
156
|
* Returns ["posts", "posts/70"] for the example above
|
|
153
157
|
*/
|
|
154
158
|
private getParentPaths;
|
|
159
|
+
/** Join a broadcast channel */
|
|
160
|
+
joinChannel(clientId: string, channel: string): void;
|
|
161
|
+
/** Leave a broadcast channel */
|
|
162
|
+
leaveChannel(clientId: string, channel: string): void;
|
|
163
|
+
/** Broadcast a message to all clients in a channel except sender */
|
|
164
|
+
broadcastToChannel(clientId: string, channel: string, event: string, payload: unknown): void;
|
|
165
|
+
/** Track presence in a channel */
|
|
166
|
+
trackPresence(clientId: string, channel: string, state: Record<string, unknown>): void;
|
|
167
|
+
/** Remove presence from a channel */
|
|
168
|
+
removePresence(clientId: string, channel: string): void;
|
|
169
|
+
/** Send full presence state to a specific client */
|
|
170
|
+
sendPresenceState(clientId: string, channel: string): void;
|
|
171
|
+
/** Broadcast presence diff (joins/leaves) to channel */
|
|
172
|
+
private broadcastPresenceDiff;
|
|
173
|
+
/** Periodic cleanup for stale presences */
|
|
174
|
+
private ensurePresenceCleanup;
|
|
155
175
|
/**
|
|
156
176
|
* Gracefully tear down all realtime resources.
|
|
157
177
|
*
|
|
@@ -108,6 +108,24 @@ export declare class DrizzleConditionBuilder {
|
|
|
108
108
|
* Find the corresponding junction table for an inverse many-to-many relation
|
|
109
109
|
*/
|
|
110
110
|
private static findCorrespondingJunctionTable;
|
|
111
|
+
/**
|
|
112
|
+
* Build vector similarity search expressions for pgvector.
|
|
113
|
+
*
|
|
114
|
+
* Returns:
|
|
115
|
+
* - `orderBy`: SQL expression to ORDER BY distance (ascending = closest first)
|
|
116
|
+
* - `filter`: optional WHERE clause for distance threshold
|
|
117
|
+
* - `distanceSelect`: SQL expression for selecting the distance as `_distance`
|
|
118
|
+
*/
|
|
119
|
+
static buildVectorSearchConditions(table: PgTable<any>, vectorSearch: {
|
|
120
|
+
property: string;
|
|
121
|
+
vector: number[];
|
|
122
|
+
distance?: "cosine" | "l2" | "inner_product";
|
|
123
|
+
threshold?: number;
|
|
124
|
+
}): {
|
|
125
|
+
orderBy: SQL;
|
|
126
|
+
filter?: SQL;
|
|
127
|
+
distanceSelect: SQL;
|
|
128
|
+
};
|
|
111
129
|
}
|
|
112
130
|
/**
|
|
113
131
|
* Alias for DrizzleConditionBuilder for consistent naming with other database implementations.
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Role, User } from "../users";
|
|
3
|
-
import { RebaseData } from "./data";
|
|
1
|
+
import type { User } from "../users";
|
|
4
2
|
/**
|
|
5
3
|
* Capabilities advertised by an auth provider.
|
|
6
4
|
* UI components use this to show/hide features dynamically
|
|
@@ -64,7 +62,7 @@ export type AuthController<USER extends User = User, ExtraData = unknown> = {
|
|
|
64
62
|
extra: ExtraData;
|
|
65
63
|
setExtra: (extra: ExtraData) => void;
|
|
66
64
|
setUser?(user: USER | null): void;
|
|
67
|
-
setUserRoles?(roles:
|
|
65
|
+
setUserRoles?(roles: string[]): void;
|
|
68
66
|
/**
|
|
69
67
|
* Capabilities advertised by the auth provider.
|
|
70
68
|
* UI components use this to feature-detect what the backend supports.
|
|
@@ -89,6 +87,8 @@ export interface AuthControllerExtended<USER extends User = User, ExtraData = un
|
|
|
89
87
|
code: string;
|
|
90
88
|
redirectUri: string;
|
|
91
89
|
}) => Promise<void>;
|
|
90
|
+
/** Generic OAuth login — works with any provider. Posts payload to /auth/{providerId}. */
|
|
91
|
+
oauthLogin?: (providerId: string, payload: Record<string, unknown>) => Promise<void>;
|
|
92
92
|
/** Register a new user */
|
|
93
93
|
register?(email: string, password: string, displayName?: string): Promise<void>;
|
|
94
94
|
/** Skip login (for anonymous access if enabled) */
|
|
@@ -102,25 +102,3 @@ export interface AuthControllerExtended<USER extends User = User, ExtraData = un
|
|
|
102
102
|
/** Update user profile */
|
|
103
103
|
updateProfile?(displayName?: string, photoURL?: string): Promise<USER>;
|
|
104
104
|
}
|
|
105
|
-
/**
|
|
106
|
-
* Implement this function to allow access to specific users.
|
|
107
|
-
* @group Hooks and utilities
|
|
108
|
-
*/
|
|
109
|
-
export type Authenticator<USER extends User = User> = (props: {
|
|
110
|
-
/**
|
|
111
|
-
* Logged-in user or null
|
|
112
|
-
*/
|
|
113
|
-
user: USER | null;
|
|
114
|
-
/**
|
|
115
|
-
* AuthController
|
|
116
|
-
*/
|
|
117
|
-
authController: AuthController<USER>;
|
|
118
|
-
/**
|
|
119
|
-
* Unified data access API
|
|
120
|
-
*/
|
|
121
|
-
data: RebaseData;
|
|
122
|
-
/**
|
|
123
|
-
* Used storage implementation
|
|
124
|
-
*/
|
|
125
|
-
storageSource: StorageSource;
|
|
126
|
-
}) => boolean | Promise<boolean>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { User } from "../users";
|
|
2
|
-
import { RebaseData } from "./data";
|
|
3
|
-
import { EmailService } from "./email";
|
|
1
|
+
import type { User } from "../users";
|
|
2
|
+
import type { RebaseData } from "./data";
|
|
3
|
+
import type { EmailService } from "./email";
|
|
4
4
|
/**
|
|
5
5
|
* Event type for authentication state changes
|
|
6
6
|
*/
|
|
@@ -14,7 +14,7 @@ export interface RebaseSession {
|
|
|
14
14
|
expiresAt: number;
|
|
15
15
|
user: User;
|
|
16
16
|
}
|
|
17
|
-
import { StorageSource } from "./storage";
|
|
17
|
+
import type { StorageSource } from "./storage";
|
|
18
18
|
/**
|
|
19
19
|
* Unified Authentication Client Interface
|
|
20
20
|
* Pure functional SDK interface, decoupled from UI and React hooks
|
|
@@ -56,20 +56,9 @@ export interface AdminUser {
|
|
|
56
56
|
createdAt: string;
|
|
57
57
|
updatedAt: string;
|
|
58
58
|
}
|
|
59
|
-
/**
|
|
60
|
-
* Role record as returned by the Admin API.
|
|
61
|
-
* @group Admin
|
|
62
|
-
*/
|
|
63
|
-
export interface AdminRole {
|
|
64
|
-
id: string;
|
|
65
|
-
name: string;
|
|
66
|
-
isAdmin: boolean;
|
|
67
|
-
defaultPermissions: Record<string, unknown> | null;
|
|
68
|
-
config: Record<string, unknown> | null;
|
|
69
|
-
}
|
|
70
59
|
/**
|
|
71
60
|
* Client-side Admin API interface.
|
|
72
|
-
* Provides user
|
|
61
|
+
* Provides user management operations.
|
|
73
62
|
* @group Admin
|
|
74
63
|
*/
|
|
75
64
|
export interface AdminAPI {
|
|
@@ -112,32 +101,6 @@ export interface AdminAPI {
|
|
|
112
101
|
deleteUser(userId: string): Promise<{
|
|
113
102
|
success: boolean;
|
|
114
103
|
}>;
|
|
115
|
-
listRoles(): Promise<{
|
|
116
|
-
roles: AdminRole[];
|
|
117
|
-
}>;
|
|
118
|
-
getRole(roleId: string): Promise<{
|
|
119
|
-
role: AdminRole;
|
|
120
|
-
}>;
|
|
121
|
-
createRole(data: {
|
|
122
|
-
id: string;
|
|
123
|
-
name: string;
|
|
124
|
-
isAdmin?: boolean;
|
|
125
|
-
defaultPermissions?: Record<string, unknown>;
|
|
126
|
-
config?: Record<string, unknown>;
|
|
127
|
-
}): Promise<{
|
|
128
|
-
role: AdminRole;
|
|
129
|
-
}>;
|
|
130
|
-
updateRole(roleId: string, data: {
|
|
131
|
-
name?: string;
|
|
132
|
-
isAdmin?: boolean;
|
|
133
|
-
defaultPermissions?: Record<string, unknown>;
|
|
134
|
-
config?: Record<string, unknown>;
|
|
135
|
-
}): Promise<{
|
|
136
|
-
role: AdminRole;
|
|
137
|
-
}>;
|
|
138
|
-
deleteRole(roleId: string): Promise<{
|
|
139
|
-
success: boolean;
|
|
140
|
-
}>;
|
|
141
104
|
bootstrap(): Promise<{
|
|
142
105
|
success: boolean;
|
|
143
106
|
message: string;
|
|
@@ -168,7 +131,7 @@ export interface RebaseClient<DB = unknown> {
|
|
|
168
131
|
* > The client-side SDK does not include an email service.
|
|
169
132
|
*/
|
|
170
133
|
email?: EmailService;
|
|
171
|
-
/** Admin API for user
|
|
134
|
+
/** Admin API for user management */
|
|
172
135
|
admin?: AdminAPI;
|
|
173
136
|
/**
|
|
174
137
|
* The base HTTP URL of the backend server.
|
|
@@ -183,4 +146,23 @@ export interface RebaseClient<DB = unknown> {
|
|
|
183
146
|
* detection (e.g. `typeof ws.executeSql === "function"`).
|
|
184
147
|
*/
|
|
185
148
|
ws?: unknown;
|
|
149
|
+
/**
|
|
150
|
+
* Execute raw SQL against the database.
|
|
151
|
+
*
|
|
152
|
+
* Only available server-side when the backend uses a SQL database
|
|
153
|
+
* (PostgreSQL, MySQL, etc.). `undefined` for document databases
|
|
154
|
+
* (MongoDB, Firestore) and on the client-side SDK.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* // In a cron job or custom function:
|
|
159
|
+
* if (ctx.client.sql) {
|
|
160
|
+
* const rows = await ctx.client.sql("SELECT count(*) FROM orders");
|
|
161
|
+
* }
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
sql?(query: string, options?: {
|
|
165
|
+
database?: string;
|
|
166
|
+
role?: string;
|
|
167
|
+
}): Promise<Record<string, unknown>[]>;
|
|
186
168
|
}
|
|
@@ -4,7 +4,7 @@ import type { EntityReference } from "../types/entities";
|
|
|
4
4
|
* Controller that provides access to the registered entity collections.
|
|
5
5
|
* @group Models
|
|
6
6
|
*/
|
|
7
|
-
export type CollectionRegistryController<DB = Record<string, unknown>, EC extends EntityCollection = EntityCollection
|
|
7
|
+
export type CollectionRegistryController<DB = Record<string, unknown>, EC extends EntityCollection = EntityCollection> = {
|
|
8
8
|
/**
|
|
9
9
|
* List of the mapped collections in the CMS.
|
|
10
10
|
* Each entry relates to a collection in the root database.
|
|
@@ -125,6 +125,10 @@ export interface CollectionAccessor<M extends Record<string, unknown> = Record<s
|
|
|
125
125
|
* Delete a record by ID.
|
|
126
126
|
*/
|
|
127
127
|
delete(id: string | number): Promise<void>;
|
|
128
|
+
/**
|
|
129
|
+
* Delete all records in this collection.
|
|
130
|
+
*/
|
|
131
|
+
deleteAll?(): Promise<void>;
|
|
128
132
|
/**
|
|
129
133
|
* Subscribe to a collection for real-time updates.
|
|
130
134
|
* Optional method, may not be supported by all implementations (like stateless HTTP clients).
|
|
@@ -17,6 +17,21 @@ export type ListenEntityProps<M extends Record<string, unknown> = Record<string,
|
|
|
17
17
|
onUpdate: (entity: Entity<M> | null) => void;
|
|
18
18
|
onError?: (error: Error) => void;
|
|
19
19
|
};
|
|
20
|
+
/**
|
|
21
|
+
* Configuration for vector similarity search queries.
|
|
22
|
+
* Vector search applies an ORDER BY distance expression and optionally
|
|
23
|
+
* filters results by a distance threshold.
|
|
24
|
+
*/
|
|
25
|
+
export interface VectorSearchParams {
|
|
26
|
+
/** Property name containing the vector column */
|
|
27
|
+
property: string;
|
|
28
|
+
/** Query vector to compare against */
|
|
29
|
+
vector: number[];
|
|
30
|
+
/** Distance function (default: "cosine") */
|
|
31
|
+
distance?: "cosine" | "l2" | "inner_product";
|
|
32
|
+
/** Only return results within this distance threshold */
|
|
33
|
+
threshold?: number;
|
|
34
|
+
}
|
|
20
35
|
/**
|
|
21
36
|
* @internal
|
|
22
37
|
*/
|
|
@@ -30,6 +45,8 @@ export interface FetchCollectionProps<M extends Record<string, unknown> = Record
|
|
|
30
45
|
orderBy?: string;
|
|
31
46
|
searchString?: string;
|
|
32
47
|
order?: "desc" | "asc";
|
|
48
|
+
/** Vector similarity search configuration */
|
|
49
|
+
vectorSearch?: VectorSearchParams;
|
|
33
50
|
}
|
|
34
51
|
/**
|
|
35
52
|
* @internal
|
|
@@ -112,6 +129,11 @@ export interface DataDriver {
|
|
|
112
129
|
* @return was the whole deletion flow successful
|
|
113
130
|
*/
|
|
114
131
|
deleteEntity<M extends Record<string, unknown> = Record<string, unknown>>(props: DeleteEntityProps<M>): Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* Delete all entities from a collection.
|
|
134
|
+
* @param path Collection path
|
|
135
|
+
*/
|
|
136
|
+
deleteAll?(path: string): Promise<void>;
|
|
115
137
|
/**
|
|
116
138
|
* Check if the given property is unique in the given collection
|
|
117
139
|
* @param path Collection path
|
|
@@ -187,6 +209,7 @@ export interface RestFetchService {
|
|
|
187
209
|
startAfter?: Record<string, unknown>;
|
|
188
210
|
searchString?: string;
|
|
189
211
|
databaseId?: string;
|
|
212
|
+
vectorSearch?: VectorSearchParams;
|
|
190
213
|
}, include?: string[]): Promise<Record<string, unknown>[]>;
|
|
191
214
|
/**
|
|
192
215
|
* Fetch a single flattened entity with optional relation includes.
|
|
@@ -4,6 +4,7 @@ import type { EntityCollectionsBuilder } from "../types/builders";
|
|
|
4
4
|
import type { EntityCustomView } from "../types/entity_views";
|
|
5
5
|
import type { EntityAction } from "../types/entity_actions";
|
|
6
6
|
import type { AppView, NavigationGroupMapping } from "./navigation";
|
|
7
|
+
import type { RebasePlugin } from "../types/plugins";
|
|
7
8
|
/**
|
|
8
9
|
* Options to enable the built-in collection editor.
|
|
9
10
|
* When provided to `<RebaseCMS>`, the editor is auto-wired as a native feature.
|
|
@@ -19,12 +20,12 @@ export interface CollectionEditorOptions {
|
|
|
19
20
|
/** Suggested base paths shown when creating new collections. */
|
|
20
21
|
pathSuggestions?: string[];
|
|
21
22
|
}
|
|
22
|
-
export interface RebaseCMSConfig<EC extends EntityCollection =
|
|
23
|
+
export interface RebaseCMSConfig<EC extends EntityCollection = EntityCollection> {
|
|
23
24
|
collections?: EC[] | EntityCollectionsBuilder<EC>;
|
|
24
25
|
homePage?: ReactNode;
|
|
25
|
-
entityViews?: EntityCustomView
|
|
26
|
+
entityViews?: EntityCustomView[];
|
|
26
27
|
entityActions?: EntityAction[];
|
|
27
|
-
plugins?:
|
|
28
|
+
plugins?: RebasePlugin[];
|
|
28
29
|
/**
|
|
29
30
|
* Centralized configuration for how collections and views are grouped
|
|
30
31
|
* in the navigation sidebar and home page.
|
|
@@ -42,7 +43,7 @@ export interface RebaseCMSConfig<EC extends EntityCollection = any> {
|
|
|
42
43
|
collectionEditor?: boolean | CollectionEditorOptions;
|
|
43
44
|
}
|
|
44
45
|
export interface RebaseStudioConfig {
|
|
45
|
-
tools?: ("sql" | "js" | "rls" | "schema" | "storage" | "cron" | "schema-visualizer" | "branches" | "api")[];
|
|
46
|
+
tools?: ("sql" | "js" | "rls" | "schema" | "storage" | "cron" | "schema-visualizer" | "branches" | "api" | "logs")[];
|
|
46
47
|
homePage?: ReactNode;
|
|
47
48
|
devViews?: AppView[];
|
|
48
49
|
}
|
|
@@ -28,7 +28,7 @@ export type RebaseCallContext<USER extends User = User> = {
|
|
|
28
28
|
* const { client } = props.context;
|
|
29
29
|
* const result = await client.functions.invoke('extract-job', { url });
|
|
30
30
|
*/
|
|
31
|
-
client: RebaseClient
|
|
31
|
+
client: RebaseClient;
|
|
32
32
|
/**
|
|
33
33
|
* Unified data access — `context.data.products.create(...)`.
|
|
34
34
|
* Access any collection as a dynamic property.
|
|
@@ -133,7 +133,7 @@ export interface AuthUserData {
|
|
|
133
133
|
displayName?: string | null;
|
|
134
134
|
photoUrl?: string | null;
|
|
135
135
|
emailVerified?: boolean;
|
|
136
|
-
metadata?: Record<string,
|
|
136
|
+
metadata?: Record<string, unknown>;
|
|
137
137
|
createdAt?: Date;
|
|
138
138
|
updatedAt?: Date;
|
|
139
139
|
}
|
|
@@ -146,41 +146,7 @@ export interface AuthCreateUserData {
|
|
|
146
146
|
password?: string;
|
|
147
147
|
displayName?: string;
|
|
148
148
|
photoUrl?: string;
|
|
149
|
-
metadata?: Record<string,
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Role data exposed by the auth adapter.
|
|
153
|
-
* @group Auth
|
|
154
|
-
*/
|
|
155
|
-
export interface AuthRoleData {
|
|
156
|
-
id: string;
|
|
157
|
-
name: string;
|
|
158
|
-
isAdmin: boolean;
|
|
159
|
-
defaultPermissions?: {
|
|
160
|
-
read?: boolean;
|
|
161
|
-
create?: boolean;
|
|
162
|
-
edit?: boolean;
|
|
163
|
-
delete?: boolean;
|
|
164
|
-
} | null;
|
|
165
|
-
collectionPermissions?: Record<string, {
|
|
166
|
-
read?: boolean;
|
|
167
|
-
create?: boolean;
|
|
168
|
-
edit?: boolean;
|
|
169
|
-
delete?: boolean;
|
|
170
|
-
}> | null;
|
|
171
|
-
config?: Record<string, unknown> | null;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Data for creating a role.
|
|
175
|
-
* @group Auth
|
|
176
|
-
*/
|
|
177
|
-
export interface AuthCreateRoleData {
|
|
178
|
-
id: string;
|
|
179
|
-
name: string;
|
|
180
|
-
isAdmin?: boolean;
|
|
181
|
-
defaultPermissions?: AuthRoleData["defaultPermissions"];
|
|
182
|
-
collectionPermissions?: AuthRoleData["collectionPermissions"];
|
|
183
|
-
config?: AuthRoleData["config"];
|
|
149
|
+
metadata?: Record<string, unknown>;
|
|
184
150
|
}
|
|
185
151
|
/**
|
|
186
152
|
* User management operations for the admin panel.
|
|
@@ -195,23 +161,9 @@ export interface UserManagementAdapter {
|
|
|
195
161
|
createUser(data: AuthCreateUserData): Promise<AuthUserData>;
|
|
196
162
|
updateUser(id: string, data: Partial<AuthCreateUserData>): Promise<AuthUserData | null>;
|
|
197
163
|
deleteUser(id: string): Promise<void>;
|
|
198
|
-
getUserRoles(userId: string): Promise<
|
|
164
|
+
getUserRoles(userId: string): Promise<string[]>;
|
|
199
165
|
setUserRoles(userId: string, roleIds: string[]): Promise<void>;
|
|
200
166
|
}
|
|
201
|
-
/**
|
|
202
|
-
* Role management operations for the admin panel.
|
|
203
|
-
*
|
|
204
|
-
* Optional — if not provided by the adapter, role management is disabled.
|
|
205
|
-
*
|
|
206
|
-
* @group Auth
|
|
207
|
-
*/
|
|
208
|
-
export interface RoleManagementAdapter {
|
|
209
|
-
listRoles(): Promise<AuthRoleData[]>;
|
|
210
|
-
getRoleById(id: string): Promise<AuthRoleData | null>;
|
|
211
|
-
createRole(data: AuthCreateRoleData): Promise<AuthRoleData>;
|
|
212
|
-
updateRole(id: string, data: Partial<AuthRoleData>): Promise<AuthRoleData | null>;
|
|
213
|
-
deleteRole(id: string): Promise<void>;
|
|
214
|
-
}
|
|
215
167
|
/**
|
|
216
168
|
* Pluggable authentication adapter for Rebase.
|
|
217
169
|
*
|
|
@@ -219,7 +171,7 @@ export interface RoleManagementAdapter {
|
|
|
219
171
|
* database layer. Each auth adapter knows how to:
|
|
220
172
|
*
|
|
221
173
|
* 1. Verify incoming HTTP requests (`verifyRequest`)
|
|
222
|
-
* 2. Optionally manage users
|
|
174
|
+
* 2. Optionally manage users (for the admin panel)
|
|
223
175
|
* 3. Optionally mount auth-specific routes (login, register, etc.)
|
|
224
176
|
* 4. Advertise its capabilities so the frontend can adapt
|
|
225
177
|
*
|
|
@@ -271,11 +223,6 @@ export interface AuthAdapter {
|
|
|
271
223
|
* Optional — if not provided, user management UI is hidden.
|
|
272
224
|
*/
|
|
273
225
|
userManagement?: UserManagementAdapter;
|
|
274
|
-
/**
|
|
275
|
-
* Role CRUD for the admin panel.
|
|
276
|
-
* Optional — if not provided, role management is disabled.
|
|
277
|
-
*/
|
|
278
|
-
roleManagement?: RoleManagementAdapter;
|
|
279
226
|
/**
|
|
280
227
|
* Mount adapter-specific auth routes (login, register, refresh, etc.).
|
|
281
228
|
*
|
|
@@ -291,7 +238,7 @@ export interface AuthAdapter {
|
|
|
291
238
|
*/
|
|
292
239
|
createAuthRoutes?(): Hono<any, any, any> | undefined;
|
|
293
240
|
/**
|
|
294
|
-
* Mount admin routes for user
|
|
241
|
+
* Mount admin routes for user management.
|
|
295
242
|
*
|
|
296
243
|
* Same typing rationale as `createAuthRoutes` — the sub-app env is
|
|
297
244
|
* unconstrained to support arbitrary adapter implementations.
|
|
@@ -347,8 +294,6 @@ export interface CustomAuthAdapterOptions {
|
|
|
347
294
|
verifyToken?: (token: string) => Promise<AuthenticatedUser | null>;
|
|
348
295
|
/** Optional user management for the admin panel. */
|
|
349
296
|
userManagement?: UserManagementAdapter;
|
|
350
|
-
/** Optional role management for the admin panel. */
|
|
351
|
-
roleManagement?: RoleManagementAdapter;
|
|
352
297
|
/** Static service key for server-to-server auth. */
|
|
353
298
|
serviceKey?: string;
|
|
354
299
|
/** Override default capabilities. */
|
|
@@ -527,8 +527,8 @@ export interface InitializedDriver {
|
|
|
527
527
|
export interface BootstrappedAuth {
|
|
528
528
|
/** User management service. */
|
|
529
529
|
userService: unknown;
|
|
530
|
-
/** Role management service. */
|
|
531
|
-
roleService
|
|
530
|
+
/** Role management service (optional, roles are now simple strings). */
|
|
531
|
+
roleService?: unknown;
|
|
532
532
|
/** Email service (optional). */
|
|
533
533
|
emailService?: unknown;
|
|
534
534
|
/** Combined Auth Repository for unified token and user management. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AdminUser
|
|
1
|
+
import type { AdminUser } from "../controllers/client";
|
|
2
2
|
/**
|
|
3
3
|
* Context passed to every backend hook.
|
|
4
4
|
* Provides information about the request that triggered the hook.
|
|
@@ -64,19 +64,6 @@ export interface UserHooks {
|
|
|
64
64
|
*/
|
|
65
65
|
afterDelete?(userId: string, context: BackendHookContext): void | Promise<void>;
|
|
66
66
|
}
|
|
67
|
-
/**
|
|
68
|
-
* Hooks for intercepting Admin Role data at the API boundary.
|
|
69
|
-
* @group Backend Hooks
|
|
70
|
-
*/
|
|
71
|
-
export interface RoleHooks {
|
|
72
|
-
/**
|
|
73
|
-
* Transform a role record after it's read from the database,
|
|
74
|
-
* before it's returned to the client.
|
|
75
|
-
*
|
|
76
|
-
* Return the modified role, or `null` to filter it out entirely.
|
|
77
|
-
*/
|
|
78
|
-
afterRead?(role: AdminRole, context: BackendHookContext): AdminRole | null | Promise<AdminRole | null>;
|
|
79
|
-
}
|
|
80
67
|
/**
|
|
81
68
|
* Hooks for intercepting collection entity data at the REST API boundary.
|
|
82
69
|
*
|
|
@@ -146,7 +133,7 @@ export interface DataHooks {
|
|
|
146
133
|
* These hooks run server-side after database operations complete and before
|
|
147
134
|
* API responses are sent.
|
|
148
135
|
*
|
|
149
|
-
* - `users`
|
|
136
|
+
* - `users` — intercept admin user management endpoints
|
|
150
137
|
* - `data` — intercept ALL collection entity data flowing through the REST API
|
|
151
138
|
*
|
|
152
139
|
* `data` hooks complement per-collection `EntityCallbacks`. Entity callbacks
|
|
@@ -180,8 +167,6 @@ export interface DataHooks {
|
|
|
180
167
|
export interface BackendHooks {
|
|
181
168
|
/** Hooks for intercepting user management data */
|
|
182
169
|
users?: UserHooks;
|
|
183
|
-
/** Hooks for intercepting role management data */
|
|
184
|
-
roles?: RoleHooks;
|
|
185
170
|
/** Hooks for intercepting ALL collection entity data via the REST API */
|
|
186
171
|
data?: DataHooks;
|
|
187
172
|
}
|
|
@@ -589,10 +589,6 @@ export interface FilterPreset<Key extends string = string> {
|
|
|
589
589
|
*/
|
|
590
590
|
sort?: [Key, "asc" | "desc"];
|
|
591
591
|
}
|
|
592
|
-
/**
|
|
593
|
-
* @deprecated Use {@link FilterPreset} instead.
|
|
594
|
-
*/
|
|
595
|
-
export type QuickFilter<Key extends string = string> = FilterPreset<Key>;
|
|
596
592
|
/**
|
|
597
593
|
* Used to indicate valid filter combinations (e.g. created in Firestore)
|
|
598
594
|
* If the user selects a specific filter/sort combination, the CMS checks if it's
|
|
@@ -37,7 +37,7 @@ export interface LazyComponentRef<P = unknown> {
|
|
|
37
37
|
*
|
|
38
38
|
* @group Types
|
|
39
39
|
*/
|
|
40
|
-
export type ComponentRef<P =
|
|
40
|
+
export type ComponentRef<P = any> = React.ComponentType<P> | LazyComponentRef<P> | (() => Promise<{
|
|
41
41
|
default: React.ComponentType<P>;
|
|
42
42
|
}>) | string;
|
|
43
43
|
/**
|
|
@@ -44,7 +44,7 @@ export interface CronJobContext {
|
|
|
44
44
|
/** A simple logger scoped to this job run. */
|
|
45
45
|
log: (...args: unknown[]) => void;
|
|
46
46
|
/** The RebaseClient instance to interact with the database. */
|
|
47
|
-
client: RebaseClient
|
|
47
|
+
client: RebaseClient;
|
|
48
48
|
}
|
|
49
49
|
export type CronJobRunState = "idle" | "running" | "success" | "error" | "disabled";
|
|
50
50
|
/**
|
|
@@ -50,6 +50,7 @@ export interface FormContext<M extends Record<string, unknown> = Record<string,
|
|
|
50
50
|
export type EntityCustomView<M extends Record<string, unknown> = Record<string, unknown>> = {
|
|
51
51
|
key: string;
|
|
52
52
|
name: string;
|
|
53
|
+
icon?: string | React.ReactNode;
|
|
53
54
|
tabComponent?: React.ReactNode;
|
|
54
55
|
includeActions?: boolean | "bottom";
|
|
55
56
|
Builder?: ComponentRef<EntityCustomViewParams<M>>;
|
|
@@ -15,7 +15,7 @@ export interface ExportConfig<USER extends User = User> {
|
|
|
15
15
|
export interface ExportMappingFunction<USER extends User = User> {
|
|
16
16
|
key: string;
|
|
17
17
|
builder: ({ entity, context }: {
|
|
18
|
-
entity: Entity
|
|
18
|
+
entity: Entity;
|
|
19
19
|
context: RebaseContext<USER>;
|
|
20
20
|
}) => Promise<string> | string;
|
|
21
21
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { FormEvent } from "react";
|
|
2
|
-
export type FormexController<T =
|
|
2
|
+
export type FormexController<T = unknown> = {
|
|
3
3
|
values: T;
|
|
4
4
|
initialValues: T;
|
|
5
5
|
setValues: (values: T) => void;
|
|
@@ -32,7 +32,7 @@ export type FormexController<T = any> = {
|
|
|
32
32
|
canUndo: boolean;
|
|
33
33
|
canRedo: boolean;
|
|
34
34
|
};
|
|
35
|
-
export type FormexResetProps<T =
|
|
35
|
+
export type FormexResetProps<T = unknown> = {
|
|
36
36
|
values?: T;
|
|
37
37
|
submitCount?: number;
|
|
38
38
|
errors?: Record<string, string>;
|