@rebasepro/types 0.5.0 → 0.6.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/dist/controllers/client.d.ts +79 -32
- package/dist/controllers/customization_controller.d.ts +10 -9
- package/dist/index.es.js +249 -197
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +294 -224
- package/dist/index.umd.js.map +1 -1
- package/dist/rebase_context.d.ts +0 -16
- package/dist/types/auth_adapter.d.ts +59 -4
- package/dist/types/backend_hooks.d.ts +0 -63
- package/dist/types/breadcrumbs.d.ts +26 -0
- package/dist/types/collections.d.ts +141 -0
- package/dist/types/component_overrides.d.ts +138 -0
- package/dist/types/entity_views.d.ts +9 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/plugins.d.ts +0 -5
- package/dist/types/translations.d.ts +3 -0
- package/dist/types/user_management_delegate.d.ts +0 -70
- package/package.json +10 -10
- package/src/controllers/client.ts +85 -33
- package/src/controllers/customization_controller.tsx +11 -11
- package/src/rebase_context.tsx +0 -16
- package/src/types/auth_adapter.ts +70 -4
- package/src/types/backend_hooks.ts +0 -55
- package/src/types/breadcrumbs.ts +27 -0
- package/src/types/collections.ts +150 -1
- package/src/types/component_overrides.ts +177 -0
- package/src/types/database_adapter.ts +1 -1
- package/src/types/entity_views.tsx +10 -1
- package/src/types/index.ts +2 -0
- package/src/types/plugins.tsx +1 -5
- package/src/types/translations.ts +3 -0
- package/src/types/user_management_delegate.ts +0 -77
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { User } from "../users";
|
|
2
2
|
import type { RebaseData } from "./data";
|
|
3
3
|
import type { EmailService } from "./email";
|
|
4
|
+
import type { StorageSource } from "./storage";
|
|
5
|
+
import type { CronJobStatus, CronJobLogEntry } from "../types/cron";
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Event type for authentication state changes
|
|
@@ -17,8 +19,6 @@ export interface RebaseSession {
|
|
|
17
19
|
user: User;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
import type { StorageSource } from "./storage";
|
|
21
|
-
|
|
22
22
|
/**
|
|
23
23
|
* Unified Authentication Client Interface
|
|
24
24
|
* Pure functional SDK interface, decoupled from UI and React hooks
|
|
@@ -50,6 +50,8 @@ export interface AuthClient {
|
|
|
50
50
|
refreshSession(): Promise<RebaseSession>;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
// ─── Admin API ───────────────────────────────────────────────────────────────
|
|
54
|
+
|
|
53
55
|
/**
|
|
54
56
|
* User record as returned by the Admin API.
|
|
55
57
|
* @group Admin
|
|
@@ -87,9 +89,62 @@ export interface AdminAPI {
|
|
|
87
89
|
bootstrap(): Promise<{ success: boolean; message: string; user: { uid: string; roles: string[] } }>;
|
|
88
90
|
}
|
|
89
91
|
|
|
92
|
+
// ─── Cron API ────────────────────────────────────────────────────────────────
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Client-side Cron job management interface.
|
|
96
|
+
* @group Cron
|
|
97
|
+
*/
|
|
98
|
+
export interface CronAPI {
|
|
99
|
+
listJobs(): Promise<{ jobs: CronJobStatus[] }>;
|
|
100
|
+
getJob(jobId: string): Promise<{ job: CronJobStatus }>;
|
|
101
|
+
triggerJob(jobId: string): Promise<{ log: CronJobLogEntry; job: CronJobStatus }>;
|
|
102
|
+
getJobLogs(jobId: string, options?: { limit?: number }): Promise<{ logs: CronJobLogEntry[] }>;
|
|
103
|
+
toggleJob(jobId: string, enabled: boolean): Promise<{ job: CronJobStatus }>;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// ─── Functions API ───────────────────────────────────────────────────────────
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Options for invoking a custom backend function.
|
|
110
|
+
* @group Functions
|
|
111
|
+
*/
|
|
112
|
+
export interface FunctionInvokeOptions {
|
|
113
|
+
/** HTTP method — defaults to `"POST"`. */
|
|
114
|
+
method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
115
|
+
/** Sub-path appended after the function name. */
|
|
116
|
+
path?: string;
|
|
117
|
+
/** Extra headers merged into the request. */
|
|
118
|
+
headers?: Record<string, string>;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Client interface for invoking custom backend functions.
|
|
123
|
+
* @group Functions
|
|
124
|
+
*/
|
|
125
|
+
export interface FunctionsAPI {
|
|
126
|
+
/**
|
|
127
|
+
* Invoke a custom backend function by name.
|
|
128
|
+
*
|
|
129
|
+
* @typeParam T - Expected shape of the response payload.
|
|
130
|
+
* @param name - Function name (filename without extension, e.g. `"extract-job"`).
|
|
131
|
+
* @param payload - Optional JSON-serialisable body sent as POST.
|
|
132
|
+
* @param options - Optional overrides (method, sub-path, headers).
|
|
133
|
+
*/
|
|
134
|
+
invoke<T = unknown>(name: string, payload?: unknown, options?: FunctionInvokeOptions): Promise<T>;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ─── RebaseClient ────────────────────────────────────────────────────────────
|
|
138
|
+
|
|
90
139
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
140
|
+
* The single, canonical Rebase client interface.
|
|
141
|
+
*
|
|
142
|
+
* Used everywhere: the server-side `rebase` singleton, the SDK's
|
|
143
|
+
* `createRebaseClient()`, React context, cron job context, etc.
|
|
144
|
+
*
|
|
145
|
+
* Core fields (`data`, `auth`) are always present. Everything else
|
|
146
|
+
* is optional — which capabilities are populated depends on the
|
|
147
|
+
* runtime environment and adapter.
|
|
93
148
|
*/
|
|
94
149
|
export interface RebaseClient<DB = unknown> {
|
|
95
150
|
/** Unified Data access layer */
|
|
@@ -103,47 +158,44 @@ export interface RebaseClient<DB = unknown> {
|
|
|
103
158
|
|
|
104
159
|
/**
|
|
105
160
|
* Server-side email service.
|
|
106
|
-
*
|
|
107
|
-
* Available when SMTP (or a custom `sendEmail` function) is configured
|
|
108
|
-
* in the backend auth config. `undefined` when email is not configured.
|
|
109
|
-
*
|
|
110
|
-
* > **Note:** This is only available on the server-side `rebase` singleton.
|
|
111
|
-
* > The client-side SDK does not include an email service.
|
|
161
|
+
* Available when SMTP or a custom `sendEmail` function is configured.
|
|
112
162
|
*/
|
|
113
163
|
email?: EmailService;
|
|
114
164
|
|
|
115
165
|
/** Admin API for user management */
|
|
116
166
|
admin?: AdminAPI;
|
|
117
167
|
|
|
118
|
-
/**
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
168
|
+
/** Cron job management API */
|
|
169
|
+
cron?: CronAPI;
|
|
170
|
+
|
|
171
|
+
/** Custom backend functions API */
|
|
172
|
+
functions?: FunctionsAPI;
|
|
173
|
+
|
|
174
|
+
/** Base HTTP URL of the backend server */
|
|
123
175
|
baseUrl?: string;
|
|
124
176
|
|
|
125
|
-
/**
|
|
126
|
-
* WebSocket client for realtime subscriptions and admin capabilities.
|
|
127
|
-
* Exposed by the SDK client (`@rebasepro/client`). The shape is intentionally
|
|
128
|
-
* left as `unknown` in the base interface — callers should narrow via feature
|
|
129
|
-
* detection (e.g. `typeof ws.executeSql === "function"`).
|
|
130
|
-
*/
|
|
177
|
+
/** WebSocket client for realtime subscriptions */
|
|
131
178
|
ws?: unknown;
|
|
132
179
|
|
|
180
|
+
/** Set the auth token for subsequent requests */
|
|
181
|
+
setToken?(token: string | null): void;
|
|
182
|
+
|
|
183
|
+
/** Set a function that lazily resolves the auth token */
|
|
184
|
+
setAuthTokenGetter?(getter: () => Promise<string | null>): void;
|
|
185
|
+
|
|
186
|
+
/** Set handler called when a request returns 401 */
|
|
187
|
+
setOnUnauthorized?(handler: () => Promise<boolean>): void;
|
|
188
|
+
|
|
189
|
+
/** Resolve the current auth token */
|
|
190
|
+
resolveToken?(): Promise<string | null>;
|
|
191
|
+
|
|
192
|
+
/** Make a raw HTTP call to the backend */
|
|
193
|
+
call?<T = unknown>(endpoint: string, payload?: unknown): Promise<T>;
|
|
194
|
+
|
|
133
195
|
/**
|
|
134
196
|
* Execute raw SQL against the database.
|
|
135
|
-
*
|
|
136
|
-
* Only available server-side when the backend uses a SQL database
|
|
137
|
-
* (PostgreSQL, MySQL, etc.). `undefined` for document databases
|
|
138
|
-
* (MongoDB, Firestore) and on the client-side SDK.
|
|
139
|
-
*
|
|
140
|
-
* @example
|
|
141
|
-
* ```typescript
|
|
142
|
-
* // In a cron job or custom function:
|
|
143
|
-
* if (ctx.client.sql) {
|
|
144
|
-
* const rows = await ctx.client.sql("SELECT count(*) FROM orders");
|
|
145
|
-
* }
|
|
146
|
-
* ```
|
|
197
|
+
* Only available server-side with a SQL database.
|
|
147
198
|
*/
|
|
148
199
|
sql?(query: string, options?: { database?: string; role?: string }): Promise<Record<string, unknown>[]>;
|
|
149
200
|
}
|
|
201
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
2
|
import type { EntityLinkBuilder } from "../types/entity_link_builder";
|
|
3
3
|
import type { Locale } from "../types/locales";
|
|
4
4
|
import type { EntityAction } from "../types/entity_actions";
|
|
@@ -6,6 +6,7 @@ import type { EntityCustomView } from "../types/entity_views";
|
|
|
6
6
|
import type { RebasePlugin } from "../types/plugins";
|
|
7
7
|
import type { PropertyConfig } from "../types/property_config";
|
|
8
8
|
import type { SlotContribution } from "../types/slots";
|
|
9
|
+
import type { ComponentOverrideMap } from "../types/component_overrides";
|
|
9
10
|
|
|
10
11
|
export type CustomizationController = {
|
|
11
12
|
|
|
@@ -59,14 +60,13 @@ export type CustomizationController = {
|
|
|
59
60
|
*/
|
|
60
61
|
propertyConfigs: Record<string, PropertyConfig>;
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
};
|
|
63
|
+
/**
|
|
64
|
+
* Global component overrides. Keys are component names from
|
|
65
|
+
* {@link OverridableComponentName}. Values replace the default
|
|
66
|
+
* implementation everywhere in the app.
|
|
67
|
+
*
|
|
68
|
+
* Collection-scoped overrides (set on individual collections)
|
|
69
|
+
* take precedence over global overrides.
|
|
70
|
+
*/
|
|
71
|
+
components?: ComponentOverrideMap;
|
|
72
72
|
}
|
package/src/rebase_context.tsx
CHANGED
|
@@ -7,7 +7,6 @@ import type { RebaseClient } from "./controllers/client";
|
|
|
7
7
|
|
|
8
8
|
import type { RebaseData } from "./controllers/data";
|
|
9
9
|
import type { User } from "./users";
|
|
10
|
-
import type { UserManagementDelegate } from "./types/user_management_delegate";
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
/**
|
|
@@ -112,21 +111,6 @@ export type RebaseContext<USER extends User = User, AuthControllerType extends A
|
|
|
112
111
|
*/
|
|
113
112
|
analyticsController?: AnalyticsController;
|
|
114
113
|
|
|
115
|
-
/**
|
|
116
|
-
* This section is used to manage users in the CMS.
|
|
117
|
-
* It is used to show user information in various places of the CMS,
|
|
118
|
-
* for example, to show who created or modified an entity,
|
|
119
|
-
* or to assign ownership of an entity.
|
|
120
|
-
*
|
|
121
|
-
* In the base CMS, this information is not used for access control.
|
|
122
|
-
* You can pass your own implementation of this section, to populate
|
|
123
|
-
* the dropdown of users when assigning ownership of an entity,
|
|
124
|
-
* or to show more information about the user.
|
|
125
|
-
*
|
|
126
|
-
* If you are using the Rebase user management plugin, this
|
|
127
|
-
* section will be implemented automatically.
|
|
128
|
-
*/
|
|
129
|
-
userManagement?: UserManagementDelegate<USER>;
|
|
130
114
|
|
|
131
115
|
/**
|
|
132
116
|
* Administrative database operations (SQL, schema discovery).
|
|
@@ -183,6 +183,41 @@ export interface UserManagementAdapter {
|
|
|
183
183
|
setUserRoles(userId: string, roleIds: string[]): Promise<void>;
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
// ─── User Creation Lifecycle ─────────────────────────────────────────────────
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Result of `AuthAdapter.prepareUserCreation()`.
|
|
190
|
+
*
|
|
191
|
+
* Contains the processed values ready for persistence and metadata
|
|
192
|
+
* needed by the finalization step.
|
|
193
|
+
*
|
|
194
|
+
* @group Auth
|
|
195
|
+
*/
|
|
196
|
+
export interface UserCreationPrepareResult {
|
|
197
|
+
/** Processed values to persist (passwordHash instead of raw password, etc.). */
|
|
198
|
+
values: Record<string, unknown>;
|
|
199
|
+
/** Cleartext password for post-save processing (email or admin display). */
|
|
200
|
+
clearPassword?: string;
|
|
201
|
+
/** Whether the hook already handled the invitation (email, etc.). */
|
|
202
|
+
hookHandledEmail: boolean;
|
|
203
|
+
/** Whether an invitation was sent (only relevant when hookHandledEmail is true). */
|
|
204
|
+
invitationSent: boolean;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Result of `AuthAdapter.finalizeUserCreation()`.
|
|
209
|
+
*
|
|
210
|
+
* Returned to the REST API for inclusion in the response.
|
|
211
|
+
*
|
|
212
|
+
* @group Auth
|
|
213
|
+
*/
|
|
214
|
+
export interface UserCreationFinalizeResult {
|
|
215
|
+
/** If set, returned to the admin in the API response. */
|
|
216
|
+
temporaryPassword?: string;
|
|
217
|
+
/** Whether an invitation email was sent. */
|
|
218
|
+
invitationSent: boolean;
|
|
219
|
+
}
|
|
220
|
+
|
|
186
221
|
// ─── Auth Adapter ────────────────────────────────────────────────────────────
|
|
187
222
|
|
|
188
223
|
/**
|
|
@@ -270,10 +305,7 @@ export interface AuthAdapter {
|
|
|
270
305
|
createAuthRoutes?(): Hono<any, any, any> | undefined;
|
|
271
306
|
|
|
272
307
|
/**
|
|
273
|
-
* Mount admin routes for
|
|
274
|
-
*
|
|
275
|
-
* Same typing rationale as `createAuthRoutes` — the sub-app env is
|
|
276
|
-
* unconstrained to support arbitrary adapter implementations.
|
|
308
|
+
* Mount admin routes (e.g. password reset for users).
|
|
277
309
|
*
|
|
278
310
|
* @returns A Hono sub-app with admin routes, or `undefined` to skip.
|
|
279
311
|
*/
|
|
@@ -304,6 +336,40 @@ export interface AuthAdapter {
|
|
|
304
336
|
*/
|
|
305
337
|
destroy?(): Promise<void>;
|
|
306
338
|
|
|
339
|
+
// ── Collection User Creation (for auth collections) ───────────────
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Prepare values for creating a user via the auth collection's REST API.
|
|
343
|
+
*
|
|
344
|
+
* Called on POST to a collection with `auth: true`. Handles password
|
|
345
|
+
* hashing, email normalization, and any collection/backend-level hooks.
|
|
346
|
+
*
|
|
347
|
+
* If not implemented, the collection saves values as-is (no password hashing).
|
|
348
|
+
*
|
|
349
|
+
* @param values - Raw request body from the client.
|
|
350
|
+
* @param collectionAuth - The parsed `AuthCollectionConfig` from the collection (if `auth` is an object).
|
|
351
|
+
* @returns Processed values ready for `driver.saveEntity()`, plus metadata for the post-save step.
|
|
352
|
+
*/
|
|
353
|
+
prepareUserCreation?(
|
|
354
|
+
values: Record<string, unknown>,
|
|
355
|
+
collectionAuth?: unknown
|
|
356
|
+
): Promise<UserCreationPrepareResult>;
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Finalize a user creation after the entity has been persisted.
|
|
360
|
+
*
|
|
361
|
+
* Handles post-save work: sending invitation emails, generating
|
|
362
|
+
* password-reset tokens, or falling back to returning a temporary password.
|
|
363
|
+
*
|
|
364
|
+
* @param entity - The persisted entity (id + values).
|
|
365
|
+
* @param clearPassword - The cleartext password from the prepare step (if any).
|
|
366
|
+
* @returns Metadata for the API response (temporary password, invitation status).
|
|
367
|
+
*/
|
|
368
|
+
finalizeUserCreation?(
|
|
369
|
+
entity: { id: string; values: Record<string, unknown> },
|
|
370
|
+
clearPassword?: string
|
|
371
|
+
): Promise<UserCreationFinalizeResult>;
|
|
372
|
+
|
|
307
373
|
// ── Service Key (optional) ──────────────────────────────────────────
|
|
308
374
|
|
|
309
375
|
/**
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { AdminUser } from "../controllers/client";
|
|
2
1
|
|
|
3
2
|
/**
|
|
4
3
|
* Context passed to every backend hook.
|
|
@@ -12,49 +11,6 @@ export interface BackendHookContext {
|
|
|
12
11
|
method: "GET" | "POST" | "PUT" | "DELETE";
|
|
13
12
|
}
|
|
14
13
|
|
|
15
|
-
/**
|
|
16
|
-
* Hooks for intercepting Admin User data at the API boundary.
|
|
17
|
-
*
|
|
18
|
-
* These hooks run on the server after the database operation completes
|
|
19
|
-
* but before the response is sent to the client.
|
|
20
|
-
*
|
|
21
|
-
* @group Backend Hooks
|
|
22
|
-
*/
|
|
23
|
-
export interface UserHooks {
|
|
24
|
-
/**
|
|
25
|
-
* Transform a user record after it's read from the database,
|
|
26
|
-
* before it's returned to the client.
|
|
27
|
-
*
|
|
28
|
-
* Return the modified user, or `null` to filter it out entirely
|
|
29
|
-
* (the user won't appear in listings or individual fetches).
|
|
30
|
-
*/
|
|
31
|
-
afterRead?(user: AdminUser, context: BackendHookContext): AdminUser | null | Promise<AdminUser | null>;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Transform user data before it's written to the database.
|
|
35
|
-
* Runs on POST (create) and PUT (update).
|
|
36
|
-
*
|
|
37
|
-
* Return the (possibly modified) data to proceed with the save.
|
|
38
|
-
* Throw an error to abort the operation.
|
|
39
|
-
*/
|
|
40
|
-
beforeSave?(data: { email?: string; displayName?: string; roles?: string[] }, context: BackendHookContext): { email?: string; displayName?: string; roles?: string[] } | Promise<{ email?: string; displayName?: string; roles?: string[] }>;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Called after a user is successfully created or updated.
|
|
44
|
-
* Useful for side-effects like sending notifications.
|
|
45
|
-
*/
|
|
46
|
-
afterSave?(user: AdminUser, context: BackendHookContext): void | Promise<void>;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Called before a user is deleted. Throw to prevent deletion.
|
|
50
|
-
*/
|
|
51
|
-
beforeDelete?(userId: string, context: BackendHookContext): void | Promise<void>;
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Called after a user is successfully deleted.
|
|
55
|
-
*/
|
|
56
|
-
afterDelete?(userId: string, context: BackendHookContext): void | Promise<void>;
|
|
57
|
-
}
|
|
58
14
|
|
|
59
15
|
/**
|
|
60
16
|
* Hooks for intercepting collection entity data at the REST API boundary.
|
|
@@ -130,9 +86,6 @@ export interface DataHooks {
|
|
|
130
86
|
* These hooks run server-side after database operations complete and before
|
|
131
87
|
* API responses are sent.
|
|
132
88
|
*
|
|
133
|
-
* - `users` — intercept admin user management endpoints
|
|
134
|
-
* - `data` — intercept ALL collection entity data flowing through the REST API
|
|
135
|
-
*
|
|
136
89
|
* `data` hooks complement per-collection `EntityCallbacks`. Entity callbacks
|
|
137
90
|
* run inside the DataDriver (close to the DB); data hooks run at the HTTP
|
|
138
91
|
* boundary (close to the client). Use data hooks for cross-cutting concerns
|
|
@@ -149,12 +102,6 @@ export interface DataHooks {
|
|
|
149
102
|
* }
|
|
150
103
|
* return entity;
|
|
151
104
|
* }
|
|
152
|
-
* },
|
|
153
|
-
* users: {
|
|
154
|
-
* afterRead(user, ctx) {
|
|
155
|
-
* if (user.email.endsWith("@system.internal")) return null;
|
|
156
|
-
* return user;
|
|
157
|
-
* }
|
|
158
105
|
* }
|
|
159
106
|
* };
|
|
160
107
|
* ```
|
|
@@ -162,8 +109,6 @@ export interface DataHooks {
|
|
|
162
109
|
* @group Backend Hooks
|
|
163
110
|
*/
|
|
164
111
|
export interface BackendHooks {
|
|
165
|
-
/** Hooks for intercepting user management data */
|
|
166
|
-
users?: UserHooks;
|
|
167
112
|
/** Hooks for intercepting ALL collection entity data via the REST API */
|
|
168
113
|
data?: DataHooks;
|
|
169
114
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface BreadcrumbEntry {
|
|
2
|
+
title: string;
|
|
3
|
+
url: string;
|
|
4
|
+
/**
|
|
5
|
+
* Optional entity count for collection breadcrumbs.
|
|
6
|
+
* - undefined: not applicable (e.g., entity breadcrumb, custom view)
|
|
7
|
+
* - null: loading
|
|
8
|
+
* - number: loaded count
|
|
9
|
+
*/
|
|
10
|
+
count?: number | null;
|
|
11
|
+
/**
|
|
12
|
+
* Unique identifier for this breadcrumb (e.g., collection path).
|
|
13
|
+
* Used to update count without replacing entire breadcrumb array.
|
|
14
|
+
*/
|
|
15
|
+
id?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface BreadcrumbsController {
|
|
19
|
+
breadcrumbs: BreadcrumbEntry[];
|
|
20
|
+
set: (props: {
|
|
21
|
+
breadcrumbs: BreadcrumbEntry[];
|
|
22
|
+
}) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Update the count for a specific breadcrumb by ID.
|
|
25
|
+
*/
|
|
26
|
+
updateCount: (id: string, count: number | null | undefined) => void;
|
|
27
|
+
}
|
package/src/types/collections.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { Relation } from "./relations";
|
|
|
11
11
|
import type { EntityCustomView, FormViewConfig } from "./entity_views";
|
|
12
12
|
import type { EntityAction } from "./entity_actions";
|
|
13
13
|
import type { ComponentRef } from "./component_ref";
|
|
14
|
+
import type { CollectionComponentOverrideMap } from "./component_overrides";
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Base interface containing all driver-agnostic collection properties.
|
|
@@ -158,6 +159,11 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
158
159
|
*/
|
|
159
160
|
disableDefaultActions?: ("edit" | "copy" | "delete")[];
|
|
160
161
|
|
|
162
|
+
/**
|
|
163
|
+
* Mark this collection as an authentication collection.
|
|
164
|
+
* When true, this collection is used for user management, login, password hashing, and invitation flows.
|
|
165
|
+
*/
|
|
166
|
+
auth?: boolean | AuthCollectionConfig;
|
|
161
167
|
|
|
162
168
|
|
|
163
169
|
/**
|
|
@@ -418,6 +424,31 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
418
424
|
* When defined, the backend enforces access control policies.
|
|
419
425
|
*/
|
|
420
426
|
securityRules?: SecurityRule[];
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Collection-scoped component overrides. These take precedence over
|
|
430
|
+
* global overrides set on `<Rebase>`, but only within this collection's
|
|
431
|
+
* views (entity form, detail view, table, empty state, etc.).
|
|
432
|
+
*
|
|
433
|
+
* Only collection-scoped components (like `Entity.Form`, `Collection.EmptyState`,
|
|
434
|
+
* `Collection.Card`, etc.) can be overridden here. App-level components
|
|
435
|
+
* (like `Shell.AppBar`, `HomePage`) can only be overridden at the `<Rebase>` level.
|
|
436
|
+
*
|
|
437
|
+
* @example
|
|
438
|
+
* ```tsx
|
|
439
|
+
* const productsCollection: PostgresCollection = {
|
|
440
|
+
* name: "Products",
|
|
441
|
+
* slug: "products",
|
|
442
|
+
* table: "products",
|
|
443
|
+
* components: {
|
|
444
|
+
* "Entity.Form": { Component: ProductCustomForm },
|
|
445
|
+
* "Collection.Card": { Component: ProductCard },
|
|
446
|
+
* },
|
|
447
|
+
* properties: { ... }
|
|
448
|
+
* };
|
|
449
|
+
* ```
|
|
450
|
+
*/
|
|
451
|
+
components?: CollectionComponentOverrideMap;
|
|
421
452
|
}
|
|
422
453
|
|
|
423
454
|
// ── Driver-specific collection types ──────────────────────────────────
|
|
@@ -742,7 +773,6 @@ export interface FilterPreset<Key extends string = string> {
|
|
|
742
773
|
}
|
|
743
774
|
|
|
744
775
|
|
|
745
|
-
|
|
746
776
|
/**
|
|
747
777
|
* Used to indicate valid filter combinations (e.g. created in Firestore)
|
|
748
778
|
* If the user selects a specific filter/sort combination, the CMS checks if it's
|
|
@@ -1120,3 +1150,122 @@ export interface RolesOnlySecurityRule extends SecurityRuleBase {
|
|
|
1120
1150
|
using?: never;
|
|
1121
1151
|
withCheck?: never;
|
|
1122
1152
|
}
|
|
1153
|
+
|
|
1154
|
+
/**
|
|
1155
|
+
* Configuration for authentication collections.
|
|
1156
|
+
*
|
|
1157
|
+
* Controls what happens when admins create users, reset passwords,
|
|
1158
|
+
* and which entity actions are auto-injected.
|
|
1159
|
+
*
|
|
1160
|
+
* Use `auth: true` as sugar for `{ enabled: true }` with all defaults.
|
|
1161
|
+
*
|
|
1162
|
+
* @example Override user creation
|
|
1163
|
+
* ```ts
|
|
1164
|
+
* auth: {
|
|
1165
|
+
* enabled: true,
|
|
1166
|
+
* onCreateUser: async (values, ctx) => {
|
|
1167
|
+
* const hash = await ctx.hashPassword("welcome123");
|
|
1168
|
+
* return {
|
|
1169
|
+
* values: { ...values, passwordHash: hash, emailVerified: true },
|
|
1170
|
+
* temporaryPassword: "welcome123",
|
|
1171
|
+
* };
|
|
1172
|
+
* },
|
|
1173
|
+
* }
|
|
1174
|
+
* ```
|
|
1175
|
+
*
|
|
1176
|
+
* @example Disable the reset-password entity action
|
|
1177
|
+
* ```ts
|
|
1178
|
+
* auth: {
|
|
1179
|
+
* enabled: true,
|
|
1180
|
+
* actions: { resetPassword: false },
|
|
1181
|
+
* }
|
|
1182
|
+
* ```
|
|
1183
|
+
*
|
|
1184
|
+
* @group Models
|
|
1185
|
+
*/
|
|
1186
|
+
export interface AuthCollectionConfig {
|
|
1187
|
+
/** Set to true to mark this collection as the authentication collection. */
|
|
1188
|
+
enabled: boolean;
|
|
1189
|
+
|
|
1190
|
+
/**
|
|
1191
|
+
* Called when an admin creates a user via the collection REST API.
|
|
1192
|
+
*
|
|
1193
|
+
* Default: generate password → hash → normalize email → save →
|
|
1194
|
+
* send invitation email (or return temp password if no email configured).
|
|
1195
|
+
*
|
|
1196
|
+
* Override to implement custom invitation flows, LDAP sync, etc.
|
|
1197
|
+
*/
|
|
1198
|
+
onCreateUser?: (
|
|
1199
|
+
values: Record<string, unknown>,
|
|
1200
|
+
ctx: AuthCollectionContext
|
|
1201
|
+
) => Promise<AuthCollectionCreateResult>;
|
|
1202
|
+
|
|
1203
|
+
/**
|
|
1204
|
+
* Called when an admin resets a user's password via the admin panel.
|
|
1205
|
+
*
|
|
1206
|
+
* Default: generate reset token → send email (or generate + return temp password).
|
|
1207
|
+
* Override for custom reset flows.
|
|
1208
|
+
*/
|
|
1209
|
+
onResetPassword?: (
|
|
1210
|
+
userId: string,
|
|
1211
|
+
ctx: AuthCollectionContext
|
|
1212
|
+
) => Promise<AuthCollectionResetResult>;
|
|
1213
|
+
|
|
1214
|
+
/**
|
|
1215
|
+
* Control which auth-specific entity actions are auto-injected.
|
|
1216
|
+
*
|
|
1217
|
+
* Default: `{ resetPassword: true }` — the framework auto-injects
|
|
1218
|
+
* the built-in `resetPasswordAction` into the collection's entity actions.
|
|
1219
|
+
*
|
|
1220
|
+
* Set to `false` to disable, or pass a custom `EntityAction` to replace the UI.
|
|
1221
|
+
*/
|
|
1222
|
+
actions?: {
|
|
1223
|
+
resetPassword?: boolean | EntityAction;
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
/**
|
|
1228
|
+
* Context provided to collection-level auth hooks.
|
|
1229
|
+
*
|
|
1230
|
+
* This is a simplified facade over the server internals —
|
|
1231
|
+
* it exposes only what's needed for custom auth flows without
|
|
1232
|
+
* coupling collection config to internal interfaces.
|
|
1233
|
+
*
|
|
1234
|
+
* @group Models
|
|
1235
|
+
*/
|
|
1236
|
+
export interface AuthCollectionContext {
|
|
1237
|
+
/** Hash a password using the configured algorithm (scrypt by default). */
|
|
1238
|
+
hashPassword: (password: string) => Promise<string>;
|
|
1239
|
+
/** Send an email. Only available when email service is configured. */
|
|
1240
|
+
sendEmail?: (options: { to: string; subject: string; html: string; text?: string }) => Promise<void>;
|
|
1241
|
+
/** Whether the email service is configured and available. */
|
|
1242
|
+
emailConfigured: boolean;
|
|
1243
|
+
/** The app name from email config (for templates). */
|
|
1244
|
+
appName: string;
|
|
1245
|
+
/** The base URL for password reset links. */
|
|
1246
|
+
resetPasswordUrl: string;
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
/**
|
|
1250
|
+
* Result of a collection-level `onCreateUser` hook.
|
|
1251
|
+
* @group Models
|
|
1252
|
+
*/
|
|
1253
|
+
export interface AuthCollectionCreateResult {
|
|
1254
|
+
/** Processed values to persist (must include passwordHash, NOT raw password). */
|
|
1255
|
+
values: Record<string, unknown>;
|
|
1256
|
+
/** If set, shown to the admin in the creation result dialog. */
|
|
1257
|
+
temporaryPassword?: string;
|
|
1258
|
+
/** Whether an invitation email was sent. */
|
|
1259
|
+
invitationSent?: boolean;
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
/**
|
|
1263
|
+
* Result of a collection-level `onResetPassword` hook.
|
|
1264
|
+
* @group Models
|
|
1265
|
+
*/
|
|
1266
|
+
export interface AuthCollectionResetResult {
|
|
1267
|
+
/** If set, shown to the admin. */
|
|
1268
|
+
temporaryPassword?: string;
|
|
1269
|
+
/** Whether a reset email was sent. */
|
|
1270
|
+
invitationSent?: boolean;
|
|
1271
|
+
}
|