@rebasepro/app 0.11.1-canary.gfd39654 → 0.12.1-canary.g181d0fe
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/auth/api.d.ts +3 -1
- package/dist/collections/filter-operator-resolution.d.ts +27 -2
- package/dist/components/LoginView/LoginView.d.ts +9 -1
- package/dist/components/RebaseAuth.d.ts +3 -3
- package/dist/core/Rebase.d.ts +1 -1
- package/dist/core/RebaseProps.d.ts +8 -11
- package/dist/hooks/ApiConfigContext.d.ts +36 -2
- package/dist/hooks/useBackendStorageSource.d.ts +6 -1
- package/dist/hooks/useBuildModeController.d.ts +1 -1
- package/dist/hooks/useCustomizationController.d.ts +1 -1
- package/dist/hooks/useNavigationBlocker.d.ts +1 -1
- package/dist/hooks/useRebaseRegistry.d.ts +4 -4
- package/dist/hooks/useStudioBridge.d.ts +37 -10
- package/dist/index.es.js +327 -147
- package/dist/index.es.js.map +1 -1
- package/package.json +29 -25
- package/src/auth/api.ts +8 -2
- package/src/collections/filter-operator-resolution.ts +40 -2
- package/src/collections/property_presentation.ts +9 -4
- package/src/collections/title-property.ts +2 -2
- package/src/components/Debug/UIReferenceView.tsx +8 -0
- package/src/components/LoginView/LoginView.tsx +61 -5
- package/src/components/NotFoundPage.tsx +1 -1
- package/src/components/RebaseAuth.tsx +3 -3
- package/src/components/common/useColumnsIds.tsx +1 -1
- package/src/components/common/useDataTableController.tsx +1 -1
- package/src/core/Rebase.tsx +7 -4
- package/src/core/RebaseProps.tsx +8 -10
- package/src/core/RebaseRouter.tsx +2 -1
- package/src/core/RebaseRoutes.tsx +1 -1
- package/src/hooks/ApiConfigContext.tsx +45 -3
- package/src/hooks/useAuthSubscription.ts +29 -3
- package/src/hooks/useBackendStorageSource.ts +8 -1
- package/src/hooks/useBuildModeController.tsx +1 -1
- package/src/hooks/useCustomizationController.tsx +1 -1
- package/src/hooks/useNavigationBlocker.tsx +1 -1
- package/src/hooks/useRebaseContext.tsx +1 -1
- package/src/hooks/useRebaseRegistry.tsx +9 -9
- package/src/hooks/useStudioBridge.tsx +60 -12
- package/src/index.ts +1 -1
- package/src/internal/useRestoreScroll.tsx +1 -1
- package/src/locales/de.ts +10 -9
- package/src/locales/en.ts +10 -9
- package/src/locales/es.ts +10 -9
- package/src/locales/fr.ts +10 -9
- package/src/locales/hi.ts +11 -10
- package/src/locales/it.ts +11 -10
- package/src/locales/pt.ts +10 -9
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Framework-agnostic runtime for data-driven admin panels — React hooks, provide
|
|
|
8
8
|
pnpm add @rebasepro/app
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
**Peer dependencies:** `react >= 19`, `react-dom >= 19
|
|
11
|
+
**Peer dependencies:** `react >= 19.2.7`, `react-dom >= 19.2.7`, `react-router ^8`
|
|
12
12
|
|
|
13
13
|
## What This Package Does
|
|
14
14
|
|
package/dist/auth/api.d.ts
CHANGED
|
@@ -59,7 +59,9 @@ export declare function createAuthConfigCache(): AuthConfigCache;
|
|
|
59
59
|
* Concurrent calls are deduplicated: only one network request is made
|
|
60
60
|
* and all callers share the same promise.
|
|
61
61
|
*/
|
|
62
|
-
export declare function fetchAuthConfig(apiUrl: string, cache: AuthConfigCache
|
|
62
|
+
export declare function fetchAuthConfig(apiUrl: string, cache: AuthConfigCache,
|
|
63
|
+
/** The backend's `basePath`; only needed if it is not the default. */
|
|
64
|
+
apiPath?: string): Promise<AuthConfigResponse>;
|
|
63
65
|
/**
|
|
64
66
|
* Clear the cached auth config (e.g. on logout or for testing).
|
|
65
67
|
*/
|
|
@@ -1,4 +1,28 @@
|
|
|
1
1
|
import { Property, WhereFilterOp } from "@rebasepro/types";
|
|
2
|
+
/**
|
|
3
|
+
* Whether a relation is one the collection's engine can compile into a
|
|
4
|
+
* `WHERE`.
|
|
5
|
+
*
|
|
6
|
+
* Which kinds those are is the *driver's* answer, not this function's, so it
|
|
7
|
+
* comes from {@link DataSourceCapabilities.filterableRelationKinds}. The admin
|
|
8
|
+
* is one UI over Postgres, MongoDB, Firestore and whatever a developer
|
|
9
|
+
* registers, and "a many-to-many compiles to an `EXISTS` over the junction" is
|
|
10
|
+
* a fact about the Postgres driver — true today, and not the sort of thing to
|
|
11
|
+
* assert on an engine's behalf.
|
|
12
|
+
*
|
|
13
|
+
* Offering an uncompilable filter is not a cosmetic bug. The Postgres driver
|
|
14
|
+
* used to drop a filter key it could not resolve, which *widened* the result
|
|
15
|
+
* set — filtering a many-to-many column returned every row instead of none.
|
|
16
|
+
* That now fails closed with a 400, which is correct for a real schema drift
|
|
17
|
+
* and wrong as the answer to a control the admin itself put on screen.
|
|
18
|
+
*
|
|
19
|
+
* A relation whose kind cannot be determined at all — no inline `relation`
|
|
20
|
+
* block and no stamped `resolvedRelation` — stays filterable. The server
|
|
21
|
+
* resolves relations before the config reaches the admin, so this is the
|
|
22
|
+
* hand-built-property case, and silently dropping a working filter there would
|
|
23
|
+
* be its own regression.
|
|
24
|
+
*/
|
|
25
|
+
export declare function isFilterableRelation(property: Property, engine?: string): boolean;
|
|
2
26
|
export interface ResolveFilterOperatorsParams {
|
|
3
27
|
/**
|
|
4
28
|
* The property to filter on. For array properties, pass the **item**
|
|
@@ -24,8 +48,9 @@ export interface ResolveFilterOperatorsParams {
|
|
|
24
48
|
* 2. what makes sense for the property type (e.g. no `>` on booleans);
|
|
25
49
|
* 3. the developer's optional narrowing — `property.admin.filterOperators`.
|
|
26
50
|
*
|
|
27
|
-
* Returns an empty array when the property is not filterable
|
|
28
|
-
*
|
|
51
|
+
* Returns an empty array when the property is not filterable — by type, by
|
|
52
|
+
* developer narrowing (`filterOperators: []`), or because it is a relation the
|
|
53
|
+
* query layer has no column for (see {@link isFilterableRelation}).
|
|
29
54
|
*
|
|
30
55
|
* @group Models
|
|
31
56
|
*/
|
|
@@ -104,10 +104,18 @@ export interface LoginViewProps {
|
|
|
104
104
|
* Pre-fill the password field (e.g. for demo or testing environments).
|
|
105
105
|
*/
|
|
106
106
|
defaultPassword?: string;
|
|
107
|
+
/**
|
|
108
|
+
* When set, the email/password forms render a "Join the newsletter"
|
|
109
|
+
* opt-in checkbox. Called with the address that just authenticated —
|
|
110
|
+
* sign-in or registration — if the box was ticked. Wire it to whatever
|
|
111
|
+
* stores the subscription; failures are the callback's problem, the
|
|
112
|
+
* login flow never waits on it.
|
|
113
|
+
*/
|
|
114
|
+
onNewsletterOptIn?: (email: string) => void;
|
|
107
115
|
}
|
|
108
116
|
/**
|
|
109
117
|
* Generic login view component that works with any AuthControllerExtended.
|
|
110
118
|
* Feature-detects capabilities to show/hide login methods.
|
|
111
119
|
* @group Core
|
|
112
120
|
*/
|
|
113
|
-
export declare function LoginView({ logo, authController, noUserComponent, disableSignupScreen, disabled, notAllowedError, googleClientId, githubClientId, linkedinClientId, title, subtitle, needsSetup, registrationEnabled, additionalComponent, topComponent, defaultEmail, defaultPassword }: LoginViewProps): React.JSX.Element;
|
|
121
|
+
export declare function LoginView({ logo, authController, noUserComponent, disableSignupScreen, disabled, notAllowedError, googleClientId, githubClientId, linkedinClientId, title, subtitle, needsSetup, registrationEnabled, additionalComponent, topComponent, defaultEmail, defaultPassword, onNewsletterOptIn }: LoginViewProps): React.JSX.Element;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RebaseAuthViewConfig } from "@rebasepro/admin-types";
|
|
2
2
|
/**
|
|
3
3
|
* Declarative component to configure authentication in Rebase.
|
|
4
4
|
* Renders nothing — purely registers config into the RebaseRegistry.
|
|
5
5
|
*
|
|
6
6
|
* This is a framework-level component that lives in core since
|
|
7
|
-
* authentication is cross-cutting (
|
|
7
|
+
* authentication is cross-cutting (admin, Studio, any app area).
|
|
8
8
|
* @group Core
|
|
9
9
|
*/
|
|
10
|
-
export declare function RebaseAuth({ loginView }:
|
|
10
|
+
export declare function RebaseAuth({ loginView }: RebaseAuthViewConfig): null;
|
package/dist/core/Rebase.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { RebaseProps } from "./RebaseProps";
|
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { User } from "@rebasepro/types";
|
|
4
4
|
/**
|
|
5
|
-
* If you are using independent components of the
|
|
5
|
+
* If you are using independent components of the admin
|
|
6
6
|
* you need to wrap them with this main component, so the internal hooks work.
|
|
7
7
|
*
|
|
8
8
|
* This is the main component of Rebase. It acts as the provider of all the
|
|
@@ -43,10 +43,8 @@ type DeepPartial<T> = T extends object ? {
|
|
|
43
43
|
* Controller to simulate different roles when dev mode is active.
|
|
44
44
|
* @group Models
|
|
45
45
|
*/
|
|
46
|
-
export
|
|
47
|
-
|
|
48
|
-
setEffectiveRole: (role: string | null) => void;
|
|
49
|
-
}
|
|
46
|
+
export type { EffectiveRoleController } from "@rebasepro/types";
|
|
47
|
+
import type { EffectiveRoleController } from "@rebasepro/types";
|
|
50
48
|
/**
|
|
51
49
|
* Props for the main {@link Rebase} component.
|
|
52
50
|
*
|
|
@@ -116,7 +114,7 @@ export type RebaseProps<USER extends User> = {
|
|
|
116
114
|
*/
|
|
117
115
|
basePath?: string;
|
|
118
116
|
/**
|
|
119
|
-
* Optional base path for the
|
|
117
|
+
* Optional base path for the admin collections.
|
|
120
118
|
* Defaults to "/c"
|
|
121
119
|
*/
|
|
122
120
|
baseCollectionPath?: string;
|
|
@@ -127,12 +125,12 @@ export type RebaseProps<USER extends User> = {
|
|
|
127
125
|
*/
|
|
128
126
|
apiUrl?: string;
|
|
129
127
|
/**
|
|
130
|
-
* Format of the dates in the
|
|
128
|
+
* Format of the dates in the admin.
|
|
131
129
|
* Defaults to 'MMMM dd, yyyy, HH:mm:ss'
|
|
132
130
|
*/
|
|
133
131
|
dateTimeFormat?: string;
|
|
134
132
|
/**
|
|
135
|
-
* Locale of the
|
|
133
|
+
* Locale of the admin, currently only affecting dates
|
|
136
134
|
*/
|
|
137
135
|
locale?: Locale;
|
|
138
136
|
/**
|
|
@@ -228,7 +226,7 @@ export type RebaseProps<USER extends User> = {
|
|
|
228
226
|
*/
|
|
229
227
|
userConfigPersistence?: UserConfigurationPersistence;
|
|
230
228
|
/**
|
|
231
|
-
* Callback used to get analytics events from the
|
|
229
|
+
* Callback used to get analytics events from the admin
|
|
232
230
|
*/
|
|
233
231
|
onAnalyticsEvent?: (event: AnalyticsEvent, data?: object) => void;
|
|
234
232
|
/**
|
|
@@ -237,11 +235,11 @@ export type RebaseProps<USER extends User> = {
|
|
|
237
235
|
*/
|
|
238
236
|
entityLinkBuilder?: EntityLinkBuilder;
|
|
239
237
|
/**
|
|
240
|
-
* Plugins loaded in the
|
|
238
|
+
* Plugins loaded in the admin
|
|
241
239
|
*/
|
|
242
240
|
plugins?: RebasePlugin[];
|
|
243
241
|
/**
|
|
244
|
-
* Extra slots for the
|
|
242
|
+
* Extra slots for the admin
|
|
245
243
|
*/
|
|
246
244
|
slots?: SlotContribution[];
|
|
247
245
|
/**
|
|
@@ -289,4 +287,3 @@ export type RebaseProps<USER extends User> = {
|
|
|
289
287
|
*/
|
|
290
288
|
components?: ComponentOverrideMap;
|
|
291
289
|
};
|
|
292
|
-
export {};
|
|
@@ -8,17 +8,51 @@ import React from "react";
|
|
|
8
8
|
*/
|
|
9
9
|
export interface ApiConfig {
|
|
10
10
|
apiUrl: string;
|
|
11
|
+
/**
|
|
12
|
+
* The path the backend mounts its API under, appended to {@link apiUrl}.
|
|
13
|
+
*
|
|
14
|
+
* `"/api"` by default, which is the server's default `basePath`. It is
|
|
15
|
+
* carried here because a good deal of UI builds request URLs by hand
|
|
16
|
+
* instead of going through the client's typed methods, and every one of
|
|
17
|
+
* those sites used to write `/api` as a literal — so a backend configured
|
|
18
|
+
* with any other `basePath` served an admin panel whose auth-provider
|
|
19
|
+
* discovery, storage browser, history panel, user picker and Studio tools
|
|
20
|
+
* all requested paths that did not exist.
|
|
21
|
+
*/
|
|
22
|
+
apiPath: string;
|
|
11
23
|
getAuthToken?: () => Promise<string | null>;
|
|
12
24
|
}
|
|
25
|
+
/** What the server uses when `basePath` is not configured. */
|
|
26
|
+
export declare const DEFAULT_API_PATH = "/api";
|
|
13
27
|
/**
|
|
14
28
|
* Read the API config from context. Returns `undefined` if no provider is present,
|
|
15
29
|
* allowing hooks to fall back to their own props.
|
|
16
30
|
*/
|
|
17
31
|
export declare function useApiConfig(): ApiConfig | undefined;
|
|
18
32
|
/**
|
|
19
|
-
*
|
|
33
|
+
* `apiUrl` and `apiPath` joined, with no trailing slash — the prefix to build a
|
|
34
|
+
* request URL from.
|
|
35
|
+
*
|
|
36
|
+
* Returns `undefined` when there is no provider, so a caller can keep its own
|
|
37
|
+
* fallback rather than silently requesting a relative path.
|
|
38
|
+
*/
|
|
39
|
+
export declare function useApiBase(): string | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* The same prefix, derived from a client rather than from context.
|
|
42
|
+
*
|
|
43
|
+
* For the code that holds a `RebaseClient` but sits outside (or above) an
|
|
44
|
+
* `ApiConfigProvider`. Returns `undefined` when the client has no base URL,
|
|
45
|
+
* which is the signal every caller already treats as "cannot build a request".
|
|
46
|
+
*/
|
|
47
|
+
export declare function apiBaseOf(client?: {
|
|
48
|
+
baseUrl?: string;
|
|
49
|
+
apiPath?: string;
|
|
50
|
+
}): string | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Provide API configuration (apiUrl, apiPath, getAuthToken) to the entire subtree.
|
|
20
53
|
* Typically rendered inside `<Rebase>` or at the app root.
|
|
21
54
|
*/
|
|
22
|
-
export declare function ApiConfigProvider({ apiUrl, getAuthToken, children }: ApiConfig & {
|
|
55
|
+
export declare function ApiConfigProvider({ apiUrl, apiPath, getAuthToken, children }: Omit<ApiConfig, "apiPath"> & {
|
|
56
|
+
apiPath?: string;
|
|
23
57
|
children: React.ReactNode;
|
|
24
58
|
}): React.JSX.Element;
|
|
@@ -7,6 +7,11 @@ export interface BackendStorageSourceProps {
|
|
|
7
7
|
* Backend API URL (e.g., 'http://localhost:3001')
|
|
8
8
|
*/
|
|
9
9
|
apiUrl: string;
|
|
10
|
+
/**
|
|
11
|
+
* The path the backend mounts its API under. Defaults to the server's own
|
|
12
|
+
* default; pass the backend's `basePath` if it was configured otherwise.
|
|
13
|
+
*/
|
|
14
|
+
apiPath?: string;
|
|
10
15
|
/**
|
|
11
16
|
* Function to get the current auth token
|
|
12
17
|
*/
|
|
@@ -27,4 +32,4 @@ export interface BackendStorageSourceProps {
|
|
|
27
32
|
* <Rebase storageSource={storageSource} ... />
|
|
28
33
|
* ```
|
|
29
34
|
*/
|
|
30
|
-
export declare function useBackendStorageSource({ apiUrl, getAuthToken }: BackendStorageSourceProps): StorageSource;
|
|
35
|
+
export declare function useBackendStorageSource({ apiUrl, apiPath, getAuthToken }: BackendStorageSourceProps): StorageSource;
|
|
@@ -2,7 +2,7 @@ import type { CustomizationController } from "@rebasepro/admin-types";
|
|
|
2
2
|
/**
|
|
3
3
|
* Use this hook to retrieve the customization controller.
|
|
4
4
|
* This hook includes all the customization options that can be used
|
|
5
|
-
* to customize the
|
|
5
|
+
* to customize the admin.
|
|
6
6
|
*
|
|
7
7
|
* You will likely not need to use this hook directly.
|
|
8
8
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type { RebaseRegistryController, RebaseAdminConfig, RebaseStudioConfig,
|
|
2
|
+
import type { RebaseRegistryController, RebaseAdminConfig, RebaseStudioConfig, RebaseAuthViewConfig } from "@rebasepro/admin-types";
|
|
3
3
|
/**
|
|
4
4
|
* Split into two contexts to prevent infinite re-render loops:
|
|
5
5
|
* - DispatchContext: stable register/unregister functions (never changes identity)
|
|
@@ -10,11 +10,11 @@ import type { RebaseRegistryController, RebaseAdminConfig, RebaseStudioConfig, R
|
|
|
10
10
|
* RebaseShell consumes state context to read the collected configs.
|
|
11
11
|
*/
|
|
12
12
|
interface RegistryDispatch {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
registerAdmin: (config: RebaseAdminConfig) => void;
|
|
14
|
+
unregisterAdmin: () => void;
|
|
15
15
|
registerStudio: (config: RebaseStudioConfig) => void;
|
|
16
16
|
unregisterStudio: () => void;
|
|
17
|
-
registerAuth: (config:
|
|
17
|
+
registerAuth: (config: RebaseAuthViewConfig) => void;
|
|
18
18
|
unregisterAuth: () => void;
|
|
19
19
|
}
|
|
20
20
|
export declare function RebaseRegistryProvider({ children }: {
|
|
@@ -3,9 +3,9 @@ import type { CollectionRegistryController } from "@rebasepro/types";
|
|
|
3
3
|
import type { SidePanelController, UrlController, NavigationStateController, BreadcrumbEntry, BreadcrumbsController } from "@rebasepro/admin-types";
|
|
4
4
|
export type { BreadcrumbEntry, BreadcrumbsController };
|
|
5
5
|
/**
|
|
6
|
-
* StudioBridge provides optional
|
|
7
|
-
* When
|
|
8
|
-
* When
|
|
6
|
+
* StudioBridge provides optional admin capabilities to Studio components.
|
|
7
|
+
* When the admin is present, a bridge provider injects real implementations.
|
|
8
|
+
* When the admin is absent, noop defaults ensure Studio works standalone.
|
|
9
9
|
*/
|
|
10
10
|
export interface StudioBridge {
|
|
11
11
|
collectionRegistry: CollectionRegistryController;
|
|
@@ -13,13 +13,38 @@ export interface StudioBridge {
|
|
|
13
13
|
urlController: UrlController;
|
|
14
14
|
navigationState: NavigationStateController;
|
|
15
15
|
breadcrumbs: BreadcrumbsController;
|
|
16
|
+
capabilities: StudioCapabilities;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* What the *host* of these tools can do, as opposed to what the backend can.
|
|
20
|
+
*
|
|
21
|
+
* Studio is mounted in two very different places. In a project's own admin
|
|
22
|
+
* panel it runs next to the collection source files and can edit them through
|
|
23
|
+
* the schema-editor routes. In the hosted console it runs against somebody
|
|
24
|
+
* else's deployed container: there is no source to edit — the container is
|
|
25
|
+
* rebuilt from the customer's repository on every deploy — and the routes that
|
|
26
|
+
* would edit it are not mounted at all, because the framework switches the
|
|
27
|
+
* schema editor off under `NODE_ENV=production`.
|
|
28
|
+
*
|
|
29
|
+
* Tools that would otherwise offer a write into the codebase read this to
|
|
30
|
+
* decide whether that write is even meaningful.
|
|
31
|
+
*/
|
|
32
|
+
export interface StudioCapabilities {
|
|
33
|
+
/**
|
|
34
|
+
* Whether the host has the project's collection source at hand and can
|
|
35
|
+
* write to it.
|
|
36
|
+
*
|
|
37
|
+
* Defaults to `true`, which is what an admin panel running beside its own
|
|
38
|
+
* `collectionsDir` has always assumed.
|
|
39
|
+
*/
|
|
40
|
+
codebase: boolean;
|
|
16
41
|
}
|
|
17
42
|
export declare const StudioBridgeContext: React.Context<StudioBridge>;
|
|
18
43
|
/**
|
|
19
|
-
* Provider that injects
|
|
44
|
+
* Provider that injects admin capabilities into Studio.
|
|
20
45
|
* Accepts partial overrides — any field not provided falls back to noop.
|
|
21
46
|
*
|
|
22
|
-
* Usage (in app wiring, when
|
|
47
|
+
* Usage (in app wiring, when the admin is present):
|
|
23
48
|
* ```tsx
|
|
24
49
|
* <StudioBridgeProvider value={{
|
|
25
50
|
* collectionRegistry: useCollectionRegistryController(),
|
|
@@ -36,16 +61,18 @@ export declare function StudioBridgeProvider({ value, children }: {
|
|
|
36
61
|
value: Partial<StudioBridge>;
|
|
37
62
|
children: React.ReactNode;
|
|
38
63
|
}): React.JSX.Element;
|
|
39
|
-
/** Collection registry — returns noop if
|
|
64
|
+
/** Collection registry — returns noop if the admin is not present. */
|
|
40
65
|
export declare function useStudioCollectionRegistry(): CollectionRegistryController;
|
|
41
|
-
/** Side panel controller — returns noop if
|
|
66
|
+
/** Side panel controller — returns noop if the admin is not present. */
|
|
42
67
|
export declare function useStudioSidePanelController(): SidePanelController;
|
|
43
|
-
/** URL controller — returns noop if
|
|
68
|
+
/** URL controller — returns noop if the admin is not present. */
|
|
44
69
|
export declare function useStudioUrlController(): UrlController;
|
|
45
|
-
/** Navigation state — returns noop if
|
|
70
|
+
/** Navigation state — returns noop if the admin is not present. */
|
|
46
71
|
export declare function useStudioNavigationState(): NavigationStateController;
|
|
47
|
-
/** Breadcrumbs controller — returns noop if
|
|
72
|
+
/** Breadcrumbs controller — returns noop if the admin is not present. */
|
|
48
73
|
export declare function useStudioBreadcrumbs(): BreadcrumbsController;
|
|
74
|
+
/** What the host can do — see {@link StudioCapabilities}. */
|
|
75
|
+
export declare function useStudioCapabilities(): StudioCapabilities;
|
|
49
76
|
/**
|
|
50
77
|
* Registry that controllers use to self-register their implementations
|
|
51
78
|
* into the Studio bridge. Each controller calls `register(key, value)`
|