@rebasepro/types 0.5.0 → 0.6.1
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,4 +1,3 @@
|
|
|
1
|
-
import type { AdminUser } from "../controllers/client";
|
|
2
1
|
/**
|
|
3
2
|
* Context passed to every backend hook.
|
|
4
3
|
* Provides information about the request that triggered the hook.
|
|
@@ -13,57 +12,6 @@ export interface BackendHookContext {
|
|
|
13
12
|
/** The HTTP method of the request */
|
|
14
13
|
method: "GET" | "POST" | "PUT" | "DELETE";
|
|
15
14
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Hooks for intercepting Admin User data at the API boundary.
|
|
18
|
-
*
|
|
19
|
-
* These hooks run on the server after the database operation completes
|
|
20
|
-
* but before the response is sent to the client.
|
|
21
|
-
*
|
|
22
|
-
* @group Backend Hooks
|
|
23
|
-
*/
|
|
24
|
-
export interface UserHooks {
|
|
25
|
-
/**
|
|
26
|
-
* Transform a user record after it's read from the database,
|
|
27
|
-
* before it's returned to the client.
|
|
28
|
-
*
|
|
29
|
-
* Return the modified user, or `null` to filter it out entirely
|
|
30
|
-
* (the user won't appear in listings or individual fetches).
|
|
31
|
-
*/
|
|
32
|
-
afterRead?(user: AdminUser, context: BackendHookContext): AdminUser | null | Promise<AdminUser | null>;
|
|
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: {
|
|
41
|
-
email?: string;
|
|
42
|
-
displayName?: string;
|
|
43
|
-
roles?: string[];
|
|
44
|
-
}, context: BackendHookContext): {
|
|
45
|
-
email?: string;
|
|
46
|
-
displayName?: string;
|
|
47
|
-
roles?: string[];
|
|
48
|
-
} | Promise<{
|
|
49
|
-
email?: string;
|
|
50
|
-
displayName?: string;
|
|
51
|
-
roles?: string[];
|
|
52
|
-
}>;
|
|
53
|
-
/**
|
|
54
|
-
* Called after a user is successfully created or updated.
|
|
55
|
-
* Useful for side-effects like sending notifications.
|
|
56
|
-
*/
|
|
57
|
-
afterSave?(user: AdminUser, context: BackendHookContext): void | Promise<void>;
|
|
58
|
-
/**
|
|
59
|
-
* Called before a user is deleted. Throw to prevent deletion.
|
|
60
|
-
*/
|
|
61
|
-
beforeDelete?(userId: string, context: BackendHookContext): void | Promise<void>;
|
|
62
|
-
/**
|
|
63
|
-
* Called after a user is successfully deleted.
|
|
64
|
-
*/
|
|
65
|
-
afterDelete?(userId: string, context: BackendHookContext): void | Promise<void>;
|
|
66
|
-
}
|
|
67
15
|
/**
|
|
68
16
|
* Hooks for intercepting collection entity data at the REST API boundary.
|
|
69
17
|
*
|
|
@@ -133,9 +81,6 @@ export interface DataHooks {
|
|
|
133
81
|
* These hooks run server-side after database operations complete and before
|
|
134
82
|
* API responses are sent.
|
|
135
83
|
*
|
|
136
|
-
* - `users` — intercept admin user management endpoints
|
|
137
|
-
* - `data` — intercept ALL collection entity data flowing through the REST API
|
|
138
|
-
*
|
|
139
84
|
* `data` hooks complement per-collection `EntityCallbacks`. Entity callbacks
|
|
140
85
|
* run inside the DataDriver (close to the DB); data hooks run at the HTTP
|
|
141
86
|
* boundary (close to the client). Use data hooks for cross-cutting concerns
|
|
@@ -152,12 +97,6 @@ export interface DataHooks {
|
|
|
152
97
|
* }
|
|
153
98
|
* return entity;
|
|
154
99
|
* }
|
|
155
|
-
* },
|
|
156
|
-
* users: {
|
|
157
|
-
* afterRead(user, ctx) {
|
|
158
|
-
* if (user.email.endsWith("@system.internal")) return null;
|
|
159
|
-
* return user;
|
|
160
|
-
* }
|
|
161
100
|
* }
|
|
162
101
|
* };
|
|
163
102
|
* ```
|
|
@@ -165,8 +104,6 @@ export interface DataHooks {
|
|
|
165
104
|
* @group Backend Hooks
|
|
166
105
|
*/
|
|
167
106
|
export interface BackendHooks {
|
|
168
|
-
/** Hooks for intercepting user management data */
|
|
169
|
-
users?: UserHooks;
|
|
170
107
|
/** Hooks for intercepting ALL collection entity data via the REST API */
|
|
171
108
|
data?: DataHooks;
|
|
172
109
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
+
export interface BreadcrumbsController {
|
|
18
|
+
breadcrumbs: BreadcrumbEntry[];
|
|
19
|
+
set: (props: {
|
|
20
|
+
breadcrumbs: BreadcrumbEntry[];
|
|
21
|
+
}) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Update the count for a specific breadcrumb by ID.
|
|
24
|
+
*/
|
|
25
|
+
updateCount: (id: string, count: number | null | undefined) => void;
|
|
26
|
+
}
|
|
@@ -10,6 +10,7 @@ import type { Relation } from "./relations";
|
|
|
10
10
|
import type { EntityCustomView, FormViewConfig } from "./entity_views";
|
|
11
11
|
import type { EntityAction } from "./entity_actions";
|
|
12
12
|
import type { ComponentRef } from "./component_ref";
|
|
13
|
+
import type { CollectionComponentOverrideMap } from "./component_overrides";
|
|
13
14
|
/**
|
|
14
15
|
* Base interface containing all driver-agnostic collection properties.
|
|
15
16
|
* Use {@link PostgresCollection} or {@link FirebaseCollection} for
|
|
@@ -136,6 +137,11 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
136
137
|
* Prevent default actions from being displayed or executed on this collection.
|
|
137
138
|
*/
|
|
138
139
|
disableDefaultActions?: ("edit" | "copy" | "delete")[];
|
|
140
|
+
/**
|
|
141
|
+
* Mark this collection as an authentication collection.
|
|
142
|
+
* When true, this collection is used for user management, login, password hashing, and invitation flows.
|
|
143
|
+
*/
|
|
144
|
+
auth?: boolean | AuthCollectionConfig;
|
|
139
145
|
/**
|
|
140
146
|
* Order in which the properties are displayed.
|
|
141
147
|
* If you are specifying your collection as code, the order is the same as the
|
|
@@ -360,6 +366,30 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
|
|
|
360
366
|
* When defined, the backend enforces access control policies.
|
|
361
367
|
*/
|
|
362
368
|
securityRules?: SecurityRule[];
|
|
369
|
+
/**
|
|
370
|
+
* Collection-scoped component overrides. These take precedence over
|
|
371
|
+
* global overrides set on `<Rebase>`, but only within this collection's
|
|
372
|
+
* views (entity form, detail view, table, empty state, etc.).
|
|
373
|
+
*
|
|
374
|
+
* Only collection-scoped components (like `Entity.Form`, `Collection.EmptyState`,
|
|
375
|
+
* `Collection.Card`, etc.) can be overridden here. App-level components
|
|
376
|
+
* (like `Shell.AppBar`, `HomePage`) can only be overridden at the `<Rebase>` level.
|
|
377
|
+
*
|
|
378
|
+
* @example
|
|
379
|
+
* ```tsx
|
|
380
|
+
* const productsCollection: PostgresCollection = {
|
|
381
|
+
* name: "Products",
|
|
382
|
+
* slug: "products",
|
|
383
|
+
* table: "products",
|
|
384
|
+
* components: {
|
|
385
|
+
* "Entity.Form": { Component: ProductCustomForm },
|
|
386
|
+
* "Collection.Card": { Component: ProductCard },
|
|
387
|
+
* },
|
|
388
|
+
* properties: { ... }
|
|
389
|
+
* };
|
|
390
|
+
* ```
|
|
391
|
+
*/
|
|
392
|
+
components?: CollectionComponentOverrideMap;
|
|
363
393
|
}
|
|
364
394
|
/**
|
|
365
395
|
* A collection backed by PostgreSQL (or any SQL database).
|
|
@@ -959,3 +989,114 @@ export interface RolesOnlySecurityRule extends SecurityRuleBase {
|
|
|
959
989
|
using?: never;
|
|
960
990
|
withCheck?: never;
|
|
961
991
|
}
|
|
992
|
+
/**
|
|
993
|
+
* Configuration for authentication collections.
|
|
994
|
+
*
|
|
995
|
+
* Controls what happens when admins create users, reset passwords,
|
|
996
|
+
* and which entity actions are auto-injected.
|
|
997
|
+
*
|
|
998
|
+
* Use `auth: true` as sugar for `{ enabled: true }` with all defaults.
|
|
999
|
+
*
|
|
1000
|
+
* @example Override user creation
|
|
1001
|
+
* ```ts
|
|
1002
|
+
* auth: {
|
|
1003
|
+
* enabled: true,
|
|
1004
|
+
* onCreateUser: async (values, ctx) => {
|
|
1005
|
+
* const hash = await ctx.hashPassword("welcome123");
|
|
1006
|
+
* return {
|
|
1007
|
+
* values: { ...values, passwordHash: hash, emailVerified: true },
|
|
1008
|
+
* temporaryPassword: "welcome123",
|
|
1009
|
+
* };
|
|
1010
|
+
* },
|
|
1011
|
+
* }
|
|
1012
|
+
* ```
|
|
1013
|
+
*
|
|
1014
|
+
* @example Disable the reset-password entity action
|
|
1015
|
+
* ```ts
|
|
1016
|
+
* auth: {
|
|
1017
|
+
* enabled: true,
|
|
1018
|
+
* actions: { resetPassword: false },
|
|
1019
|
+
* }
|
|
1020
|
+
* ```
|
|
1021
|
+
*
|
|
1022
|
+
* @group Models
|
|
1023
|
+
*/
|
|
1024
|
+
export interface AuthCollectionConfig {
|
|
1025
|
+
/** Set to true to mark this collection as the authentication collection. */
|
|
1026
|
+
enabled: boolean;
|
|
1027
|
+
/**
|
|
1028
|
+
* Called when an admin creates a user via the collection REST API.
|
|
1029
|
+
*
|
|
1030
|
+
* Default: generate password → hash → normalize email → save →
|
|
1031
|
+
* send invitation email (or return temp password if no email configured).
|
|
1032
|
+
*
|
|
1033
|
+
* Override to implement custom invitation flows, LDAP sync, etc.
|
|
1034
|
+
*/
|
|
1035
|
+
onCreateUser?: (values: Record<string, unknown>, ctx: AuthCollectionContext) => Promise<AuthCollectionCreateResult>;
|
|
1036
|
+
/**
|
|
1037
|
+
* Called when an admin resets a user's password via the admin panel.
|
|
1038
|
+
*
|
|
1039
|
+
* Default: generate reset token → send email (or generate + return temp password).
|
|
1040
|
+
* Override for custom reset flows.
|
|
1041
|
+
*/
|
|
1042
|
+
onResetPassword?: (userId: string, ctx: AuthCollectionContext) => Promise<AuthCollectionResetResult>;
|
|
1043
|
+
/**
|
|
1044
|
+
* Control which auth-specific entity actions are auto-injected.
|
|
1045
|
+
*
|
|
1046
|
+
* Default: `{ resetPassword: true }` — the framework auto-injects
|
|
1047
|
+
* the built-in `resetPasswordAction` into the collection's entity actions.
|
|
1048
|
+
*
|
|
1049
|
+
* Set to `false` to disable, or pass a custom `EntityAction` to replace the UI.
|
|
1050
|
+
*/
|
|
1051
|
+
actions?: {
|
|
1052
|
+
resetPassword?: boolean | EntityAction;
|
|
1053
|
+
};
|
|
1054
|
+
}
|
|
1055
|
+
/**
|
|
1056
|
+
* Context provided to collection-level auth hooks.
|
|
1057
|
+
*
|
|
1058
|
+
* This is a simplified facade over the server internals —
|
|
1059
|
+
* it exposes only what's needed for custom auth flows without
|
|
1060
|
+
* coupling collection config to internal interfaces.
|
|
1061
|
+
*
|
|
1062
|
+
* @group Models
|
|
1063
|
+
*/
|
|
1064
|
+
export interface AuthCollectionContext {
|
|
1065
|
+
/** Hash a password using the configured algorithm (scrypt by default). */
|
|
1066
|
+
hashPassword: (password: string) => Promise<string>;
|
|
1067
|
+
/** Send an email. Only available when email service is configured. */
|
|
1068
|
+
sendEmail?: (options: {
|
|
1069
|
+
to: string;
|
|
1070
|
+
subject: string;
|
|
1071
|
+
html: string;
|
|
1072
|
+
text?: string;
|
|
1073
|
+
}) => Promise<void>;
|
|
1074
|
+
/** Whether the email service is configured and available. */
|
|
1075
|
+
emailConfigured: boolean;
|
|
1076
|
+
/** The app name from email config (for templates). */
|
|
1077
|
+
appName: string;
|
|
1078
|
+
/** The base URL for password reset links. */
|
|
1079
|
+
resetPasswordUrl: string;
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Result of a collection-level `onCreateUser` hook.
|
|
1083
|
+
* @group Models
|
|
1084
|
+
*/
|
|
1085
|
+
export interface AuthCollectionCreateResult {
|
|
1086
|
+
/** Processed values to persist (must include passwordHash, NOT raw password). */
|
|
1087
|
+
values: Record<string, unknown>;
|
|
1088
|
+
/** If set, shown to the admin in the creation result dialog. */
|
|
1089
|
+
temporaryPassword?: string;
|
|
1090
|
+
/** Whether an invitation email was sent. */
|
|
1091
|
+
invitationSent?: boolean;
|
|
1092
|
+
}
|
|
1093
|
+
/**
|
|
1094
|
+
* Result of a collection-level `onResetPassword` hook.
|
|
1095
|
+
* @group Models
|
|
1096
|
+
*/
|
|
1097
|
+
export interface AuthCollectionResetResult {
|
|
1098
|
+
/** If set, shown to the admin. */
|
|
1099
|
+
temporaryPassword?: string;
|
|
1100
|
+
/** Whether a reset email was sent. */
|
|
1101
|
+
invitationSent?: boolean;
|
|
1102
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Components that can only be overridden at the **app level** via the
|
|
4
|
+
* `components` prop on `<Rebase>`.
|
|
5
|
+
*
|
|
6
|
+
* These are shell-level / global components that exist outside of any
|
|
7
|
+
* specific collection context.
|
|
8
|
+
*
|
|
9
|
+
* @group Component Overrides
|
|
10
|
+
*/
|
|
11
|
+
export type AppComponentName = "Shell.AppBar" | "Shell.Drawer" | "Shell.DrawerNavigationItem" | "Shell.DrawerNavigationGroup" | "HomePage" | "HomePage.CollectionCard" | "Auth.LoginView";
|
|
12
|
+
/**
|
|
13
|
+
* Components that can be overridden at the **collection level**
|
|
14
|
+
* (on an individual collection definition) or at the **app level**
|
|
15
|
+
* (as a default for all collections).
|
|
16
|
+
*
|
|
17
|
+
* When set at the app level, these act as defaults. When set on a
|
|
18
|
+
* specific collection, they override the app-level default for that
|
|
19
|
+
* collection only.
|
|
20
|
+
*
|
|
21
|
+
* @group Component Overrides
|
|
22
|
+
*/
|
|
23
|
+
export type CollectionComponentName = "Collection.View" | "Collection.Table" | "Collection.Card" | "Collection.EmptyState" | "Collection.Actions" | "Entity.Form" | "Entity.FormActions" | "Entity.DetailView" | "Entity.SidePanel" | "Entity.Preview" | "Entity.MissingReference";
|
|
24
|
+
/**
|
|
25
|
+
* All overridable component names across all scopes.
|
|
26
|
+
* @group Component Overrides
|
|
27
|
+
*/
|
|
28
|
+
export type OverridableComponentName = AppComponentName | CollectionComponentName;
|
|
29
|
+
/**
|
|
30
|
+
* A single component override entry.
|
|
31
|
+
*
|
|
32
|
+
* - **Eject mode** (default): Your component fully replaces the built-in one.
|
|
33
|
+
* It receives the same props as the original.
|
|
34
|
+
*
|
|
35
|
+
* - **Wrap mode** (`wrap: true`): Your component wraps the original. The
|
|
36
|
+
* built-in component is passed as `OriginalComponent` in props, so you can
|
|
37
|
+
* render it inside your custom layout/logic.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```tsx
|
|
41
|
+
* // Eject — full replacement
|
|
42
|
+
* { Component: MyCustomAppBar }
|
|
43
|
+
*
|
|
44
|
+
* // Wrap — augment the original
|
|
45
|
+
* {
|
|
46
|
+
* Component: ({ OriginalComponent, ...props }) => (
|
|
47
|
+
* <div>
|
|
48
|
+
* <MyBanner />
|
|
49
|
+
* <OriginalComponent {...props} />
|
|
50
|
+
* </div>
|
|
51
|
+
* ),
|
|
52
|
+
* wrap: true
|
|
53
|
+
* }
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* @group Component Overrides
|
|
57
|
+
*/
|
|
58
|
+
export interface ComponentOverride<P = any> {
|
|
59
|
+
/**
|
|
60
|
+
* The replacement component. Receives the same props as the built-in
|
|
61
|
+
* component it replaces.
|
|
62
|
+
*
|
|
63
|
+
* When `wrap` is true, an additional `OriginalComponent` prop is injected
|
|
64
|
+
* containing the default component, allowing you to render it within
|
|
65
|
+
* your custom wrapper.
|
|
66
|
+
*/
|
|
67
|
+
Component: React.ComponentType<P>;
|
|
68
|
+
/**
|
|
69
|
+
* When true, the original default component is injected as the
|
|
70
|
+
* `OriginalComponent` prop into your Component, enabling the
|
|
71
|
+
* wrapping pattern (similar to Docusaurus's `--wrap` swizzle mode).
|
|
72
|
+
*
|
|
73
|
+
* When false or omitted, your component fully replaces the default
|
|
74
|
+
* (similar to Docusaurus's `--eject` swizzle mode).
|
|
75
|
+
*
|
|
76
|
+
* @default false
|
|
77
|
+
*/
|
|
78
|
+
wrap?: boolean;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Collection-scoped overrides. Only collection-level components
|
|
82
|
+
* can be overridden here.
|
|
83
|
+
*
|
|
84
|
+
* Set on a collection's `components` field to customize
|
|
85
|
+
* components for that specific collection.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```tsx
|
|
89
|
+
* const productsCollection = {
|
|
90
|
+
* name: "Products",
|
|
91
|
+
* slug: "products",
|
|
92
|
+
* components: {
|
|
93
|
+
* "Entity.Form": { Component: ProductForm },
|
|
94
|
+
* "Collection.EmptyState": { Component: ProductsEmptyState },
|
|
95
|
+
* "Collection.Card": { Component: ProductCard },
|
|
96
|
+
* }
|
|
97
|
+
* };
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* @group Component Overrides
|
|
101
|
+
*/
|
|
102
|
+
export type CollectionComponentOverrideMap = {
|
|
103
|
+
[K in CollectionComponentName]?: ComponentOverride;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* App-level overrides. Includes both app-only components (Shell, HomePage, Auth)
|
|
107
|
+
* and collection-level components (as defaults for all collections).
|
|
108
|
+
*
|
|
109
|
+
* Pass this to the `components` prop on `<Rebase>`.
|
|
110
|
+
*
|
|
111
|
+
* Collection-level components set here act as **defaults** — they apply to all
|
|
112
|
+
* collections unless a specific collection overrides them in its own
|
|
113
|
+
* `components`.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```tsx
|
|
117
|
+
* <Rebase
|
|
118
|
+
* client={client}
|
|
119
|
+
* components={{
|
|
120
|
+
* // App-level: only available here
|
|
121
|
+
* "Shell.AppBar": { Component: MyAppBar },
|
|
122
|
+
* "HomePage": { Component: MyDashboard },
|
|
123
|
+
*
|
|
124
|
+
* // Collection defaults: apply to ALL collections
|
|
125
|
+
* "Entity.FormActions": {
|
|
126
|
+
* Component: MyFormActions,
|
|
127
|
+
* wrap: true
|
|
128
|
+
* },
|
|
129
|
+
* "Collection.EmptyState": { Component: MyEmptyState },
|
|
130
|
+
* }}
|
|
131
|
+
* />
|
|
132
|
+
* ```
|
|
133
|
+
*
|
|
134
|
+
* @group Component Overrides
|
|
135
|
+
*/
|
|
136
|
+
export type ComponentOverrideMap = {
|
|
137
|
+
[K in OverridableComponentName]?: ComponentOverride;
|
|
138
|
+
};
|
|
@@ -17,9 +17,17 @@ export interface FormContext<M extends Record<string, unknown> = Record<string,
|
|
|
17
17
|
*/
|
|
18
18
|
setFieldValue: (key: string, value: unknown, shouldValidate?: boolean) => void;
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* Quietly persist the entity to the database without any UI feedback
|
|
21
|
+
* (no validation, no snackbar, no form reset).
|
|
22
|
+
* Use this for programmatic/background saves from custom views.
|
|
21
23
|
*/
|
|
22
24
|
save: (values: M) => void;
|
|
25
|
+
/**
|
|
26
|
+
* Submit the form — validates, saves, resets the form, and shows
|
|
27
|
+
* a success snackbar. This is what the Save button calls.
|
|
28
|
+
* Use this from custom views when you want the full "user saved" experience.
|
|
29
|
+
*/
|
|
30
|
+
submit: () => void;
|
|
23
31
|
/**
|
|
24
32
|
* Collection of the entity being modified
|
|
25
33
|
*/
|
package/dist/types/index.d.ts
CHANGED
package/dist/types/plugins.d.ts
CHANGED
|
@@ -5,7 +5,6 @@ import type { InferPropertyType, Property } from "./properties";
|
|
|
5
5
|
import type { FormContext } from "./entity_views";
|
|
6
6
|
import type { RebaseContext } from "../rebase_context";
|
|
7
7
|
import type { NavigationGroupMapping, AppView } from "../controllers/navigation";
|
|
8
|
-
import type { UserManagementDelegate } from "./user_management_delegate";
|
|
9
8
|
import type { User } from "../users";
|
|
10
9
|
import type { SlotContribution } from "./slots";
|
|
11
10
|
/**
|
|
@@ -101,10 +100,6 @@ export interface RebasePlugin {
|
|
|
101
100
|
* Views to be automatically added to the navigation.
|
|
102
101
|
*/
|
|
103
102
|
views?: AppView[];
|
|
104
|
-
/**
|
|
105
|
-
* User management delegate from this plugin.
|
|
106
|
-
*/
|
|
107
|
-
userManagement?: UserManagementDelegate;
|
|
108
103
|
/**
|
|
109
104
|
* Optional lifecycle hooks. Called by the Rebase runtime
|
|
110
105
|
* at appropriate points in the app lifecycle.
|
|
@@ -112,6 +112,9 @@ export interface RebaseTranslations {
|
|
|
112
112
|
/** Aria label for the user menu trigger in the drawer footer */
|
|
113
113
|
user_menu?: string;
|
|
114
114
|
error: string;
|
|
115
|
+
error_loading_data?: string;
|
|
116
|
+
error_check_server_logs?: string;
|
|
117
|
+
error_technical_details?: string;
|
|
115
118
|
error_uploading_file: string;
|
|
116
119
|
error_deleting: string;
|
|
117
120
|
error_before_delete: string;
|
|
@@ -14,73 +14,3 @@ export interface UserCreationResult<USER extends User = User> {
|
|
|
14
14
|
*/
|
|
15
15
|
temporaryPassword?: string;
|
|
16
16
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Delegate to manage auth-specific user operations.
|
|
19
|
-
*
|
|
20
|
-
* This interface allows the CMS to be agnostic of the underlying
|
|
21
|
-
* authentication provider or backend. User/role CRUD is now handled
|
|
22
|
-
* by the collection system; this delegate only exposes auth-specific
|
|
23
|
-
* operations (password hashing, invitations, bootstrap).
|
|
24
|
-
*
|
|
25
|
-
* @group Models
|
|
26
|
-
*/
|
|
27
|
-
export interface UserManagementDelegate<USER extends User = User> {
|
|
28
|
-
/**
|
|
29
|
-
* Are auth-related operations currently loading?
|
|
30
|
-
*/
|
|
31
|
-
loading: boolean;
|
|
32
|
-
/**
|
|
33
|
-
* In-memory list of users (used for client-side filtering fallback).
|
|
34
|
-
*/
|
|
35
|
-
users?: USER[];
|
|
36
|
-
/**
|
|
37
|
-
* Error from fetching the users list, if any.
|
|
38
|
-
*/
|
|
39
|
-
usersError?: Error;
|
|
40
|
-
/**
|
|
41
|
-
* Look up a single user by UID from the in-memory cache.
|
|
42
|
-
*/
|
|
43
|
-
getUser?: (uid: string) => USER | null;
|
|
44
|
-
/**
|
|
45
|
-
* Server-side user search with pagination.
|
|
46
|
-
*/
|
|
47
|
-
searchUsers?: (params: {
|
|
48
|
-
search?: string;
|
|
49
|
-
limit?: number;
|
|
50
|
-
offset?: number;
|
|
51
|
-
}) => Promise<{
|
|
52
|
-
users: USER[];
|
|
53
|
-
total: number;
|
|
54
|
-
}>;
|
|
55
|
-
/**
|
|
56
|
-
* Create a new user with invitation/password generation support.
|
|
57
|
-
* Returns additional info about how the credentials were delivered.
|
|
58
|
-
*/
|
|
59
|
-
createUser?: (user: USER) => Promise<UserCreationResult<USER>>;
|
|
60
|
-
/**
|
|
61
|
-
* Reset the password for an existing user.
|
|
62
|
-
* Returns a temporary password if no email service is configured,
|
|
63
|
-
* or a flag indicating an email invitation was sent.
|
|
64
|
-
*/
|
|
65
|
-
resetPassword?: (user: USER) => Promise<UserCreationResult<USER>>;
|
|
66
|
-
/**
|
|
67
|
-
* Is the currently logged in user an admin?
|
|
68
|
-
*/
|
|
69
|
-
isAdmin?: boolean;
|
|
70
|
-
/**
|
|
71
|
-
* Optionally define roles for a given user. This is useful when the roles
|
|
72
|
-
* are coming from a separate provider than the one issuing the tokens.
|
|
73
|
-
*/
|
|
74
|
-
defineRolesFor?: (user: USER) => Promise<string[] | undefined> | string[] | undefined;
|
|
75
|
-
/**
|
|
76
|
-
* Whether any admin users exist. Used by the bootstrap banner to decide
|
|
77
|
-
* whether to prompt. Populated via a lightweight check (e.g. `limit=1`
|
|
78
|
-
* query) instead of loading all users.
|
|
79
|
-
*/
|
|
80
|
-
hasAdminUsers?: boolean;
|
|
81
|
-
/**
|
|
82
|
-
* Optional function to bootstrap an admin user.
|
|
83
|
-
* Often used when the database is empty.
|
|
84
|
-
*/
|
|
85
|
-
bootstrapAdmin?: () => Promise<void>;
|
|
86
|
-
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebasepro/types",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.1",
|
|
5
5
|
"description": "Rebase type definitions — shared interfaces and controller types",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/rebaseco"
|
|
@@ -39,18 +39,18 @@
|
|
|
39
39
|
"./package.json": "./package.json"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@types/jest": "^
|
|
43
|
-
"@types/node": "^
|
|
42
|
+
"@types/jest": "^30.0.0",
|
|
43
|
+
"@types/node": "^25.9.3",
|
|
44
44
|
"@types/object-hash": "^3.0.6",
|
|
45
|
-
"@types/react": "^19.2.
|
|
45
|
+
"@types/react": "^19.2.17",
|
|
46
46
|
"@types/react-dom": "^19.2.3",
|
|
47
47
|
"@types/react-measure": "^2.0.12",
|
|
48
|
-
"@vitejs/plugin-react": "^
|
|
49
|
-
"hono": "^4.12.
|
|
50
|
-
"jest": "^
|
|
51
|
-
"ts-jest": "^29.4.
|
|
52
|
-
"typescript": "^
|
|
53
|
-
"vite": "^
|
|
48
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
49
|
+
"hono": "^4.12.25",
|
|
50
|
+
"jest": "^30.4.2",
|
|
51
|
+
"ts-jest": "^29.4.11",
|
|
52
|
+
"typescript": "^6.0.3",
|
|
53
|
+
"vite": "^8.0.16"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"hono": "^4.12.21"
|