@gooddata/sdk-ui-pluggable-host 11.40.0-alpha.3 → 11.40.0-alpha.4

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.
@@ -1,12 +1,16 @@
1
1
  // (C) 2026 GoodData Corporation
2
2
  import { isExternalPluggableApplicationRegistryItem, isLocalPluggableApplicationRegistryItem, isRemotePluggableApplicationRegistryItem, } from "@gooddata/sdk-model";
3
3
  const WORKSPACE_PATH_PATTERN = /^\/workspace\/(?<workspaceId>[^/]+)(?:\/|$)/;
4
+ function stripEmbedPrefix(pathname) {
5
+ return pathname.startsWith("/embedded/") ? pathname.slice("/embedded".length) : pathname;
6
+ }
4
7
  /**
5
8
  * Returns the application scope for the given URL path, or undefined if the path
6
9
  * does not match a known scope.
7
10
  */
8
11
  export function getApplicationScopeFromPath(path) {
9
- const isPathMatching = (definitionPath) => path === definitionPath || path.startsWith(definitionPath + "/");
12
+ const stripped = stripEmbedPrefix(path);
13
+ const isPathMatching = (definitionPath) => stripped === definitionPath || stripped.startsWith(definitionPath + "/");
10
14
  if (isPathMatching("/organization")) {
11
15
  return "organization";
12
16
  }
@@ -20,7 +24,7 @@ export function getApplicationScopeFromPath(path) {
20
24
  * does not contain a workspace id.
21
25
  */
22
26
  export function getWorkspaceIdFromPath(pathname) {
23
- return WORKSPACE_PATH_PATTERN.exec(pathname ?? "")?.groups?.["workspaceId"];
27
+ return WORKSPACE_PATH_PATTERN.exec(stripEmbedPrefix(pathname ?? ""))?.groups?.["workspaceId"];
24
28
  }
25
29
  function ensureLeadingSlash(path) {
26
30
  return path.startsWith("/") ? path : `/${path}`;
@@ -79,7 +83,7 @@ export function isInternalAppRouteActive(app, ctx, pathname) {
79
83
  return false;
80
84
  }
81
85
  const basePath = normalizePath(getApplicationHref(app, ctx, pathname));
82
- const normalizedPathname = normalizePath(pathname);
86
+ const normalizedPathname = normalizePath(stripEmbedPrefix(pathname));
83
87
  return normalizedPathname === basePath || normalizedPathname.startsWith(`${basePath}/`);
84
88
  }
85
89
  export function getActiveInternalApplication(apps, ctx, pathname) {
@@ -45,6 +45,6 @@ export async function loadPlatformContext(options = {}) {
45
45
  whiteLabeling: bootstrap.whiteLabeling,
46
46
  pantherTier: bootstrap.pantherTier,
47
47
  theme: bootstrap.theme,
48
- embeddingMode: "none",
48
+ embeddingMode: window.location.pathname.startsWith("/embedded/") ? "iframe" : "none",
49
49
  };
50
50
  }
@@ -10,7 +10,7 @@ export interface IPlatformContextErrorResult {
10
10
  state: "error";
11
11
  error: string;
12
12
  }
13
- type RoutePlatformContextFields = "currentWorkspaceId" | "currentApplicationScope" | "workspacePermissions" | "workspaceSettings" | "settings" | "preferredLocale";
13
+ type RoutePlatformContextFields = "currentWorkspaceId" | "currentApplicationScope" | "workspacePermissions" | "workspaceSettings" | "colorPalette" | "settings" | "preferredLocale";
14
14
  export type IRoutePlatformContext = Pick<IPlatformContext, RoutePlatformContextFields>;
15
15
  export type IBackendPlatformContext = Omit<IPlatformContext, RoutePlatformContextFields>;
16
16
  export type IPlatformContextLoadResult<TContext> = IPlatformContextLoadingResult | IPlatformContextReadyResult<TContext> | IPlatformContextErrorResult;
@@ -6,8 +6,11 @@ import { isProduction } from "../lib/isProduction.js";
6
6
  import { getApplicationScopeFromPath, getWorkspaceIdFromPath } from "../loader/routing.js";
7
7
  import { getBackend } from "./backend.js";
8
8
  import { HostApplicationDisabledError, loadPlatformContext, } from "./loadPlatformContext.js";
9
+ import { useWorkspaceColorPalette } from "./useWorkspaceColorPalette.js";
9
10
  import { useWorkspacePermissions } from "./useWorkspacePermissions.js";
10
11
  import { useWorkspaceSettings } from "./useWorkspaceSettings.js";
12
+ import { useWorkspaceTheme } from "./useWorkspaceTheme.js";
13
+ import { shouldWaitForInjectedApiToken, waitForInjectedApiToken } from "./waitForInjectedApiToken.js";
11
14
  function redirectToAppRoot() {
12
15
  const rootUrl = new URL("/", window.location.origin).toString();
13
16
  window.location.assign(rootUrl);
@@ -28,6 +31,8 @@ export function useLoadPlatformContext() {
28
31
  const backend = backendContext.state === "ready" ? getBackend() : undefined;
29
32
  const workspacePermissionsState = useWorkspacePermissions(backend, workspaceId);
30
33
  const workspaceSettingsState = useWorkspaceSettings(backend, workspaceId);
34
+ const workspaceColorPaletteState = useWorkspaceColorPalette(backend, workspaceId);
35
+ const workspaceThemeState = useWorkspaceTheme(backend, workspaceId);
31
36
  return useMemo(() => {
32
37
  if (backendContext.state !== "ready") {
33
38
  return backendContext;
@@ -47,6 +52,11 @@ export function useLoadPlatformContext() {
47
52
  }
48
53
  const workspacePermissions = workspacePermissionsState.state === "ready" ? workspacePermissionsState.permissions : undefined;
49
54
  const workspaceSettings = workspaceSettingsState.state === "ready" ? workspaceSettingsState.settings : undefined;
55
+ const colorPalette = workspaceColorPaletteState.state === "ready"
56
+ ? workspaceColorPaletteState.colorPalette
57
+ : undefined;
58
+ const workspaceTheme = workspaceThemeState.state === "ready" ? workspaceThemeState.theme : undefined;
59
+ const effectiveTheme = workspaceTheme ?? backendContext.ctx.theme;
50
60
  const settings = workspaceSettings ?? backendContext.ctx.userSettings;
51
61
  const preferredLocale = isLocale(settings.locale) ? settings.locale : undefined;
52
62
  const routeCtx = {
@@ -54,11 +64,20 @@ export function useLoadPlatformContext() {
54
64
  currentWorkspaceId: workspaceId,
55
65
  workspacePermissions,
56
66
  workspaceSettings,
67
+ colorPalette,
57
68
  settings,
58
69
  preferredLocale,
59
70
  };
60
- return { state: "ready", ctx: { ...backendContext.ctx, ...routeCtx } };
61
- }, [backendContext, applicationScope, workspaceId, workspacePermissionsState, workspaceSettingsState]);
71
+ return { state: "ready", ctx: { ...backendContext.ctx, ...routeCtx, theme: effectiveTheme } };
72
+ }, [
73
+ backendContext,
74
+ applicationScope,
75
+ workspaceId,
76
+ workspacePermissionsState,
77
+ workspaceSettingsState,
78
+ workspaceColorPaletteState,
79
+ workspaceThemeState,
80
+ ]);
62
81
  }
63
82
  class BackendPlatformContextProviderClass {
64
83
  _loadingStateMemo = { state: "loading" };
@@ -87,6 +106,9 @@ class BackendPlatformContextProviderClass {
87
106
  }
88
107
  this._abortController = new AbortController();
89
108
  try {
109
+ if (shouldWaitForInjectedApiToken()) {
110
+ await waitForInjectedApiToken(this._abortController.signal);
111
+ }
90
112
  const ctx = await loadPlatformContext({
91
113
  signal: this._abortController.signal,
92
114
  callbacks: this._callbacks,
@@ -0,0 +1,17 @@
1
+ import { type IAnalyticalBackend } from "@gooddata/sdk-backend-spi";
2
+ import { type IColorPalette } from "@gooddata/sdk-model";
3
+ type WorkspaceColorPaletteState = {
4
+ state: "idle";
5
+ } | {
6
+ state: "loading";
7
+ } | {
8
+ state: "ready";
9
+ colorPalette: IColorPalette | undefined;
10
+ } | {
11
+ state: "forbidden";
12
+ } | {
13
+ state: "error";
14
+ error: string;
15
+ };
16
+ export declare function useWorkspaceColorPalette(backend: IAnalyticalBackend | undefined, workspaceId: string | undefined): WorkspaceColorPaletteState;
17
+ export {};
@@ -0,0 +1,37 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { useEffect, useState } from "react";
3
+ import { UnexpectedResponseError } from "@gooddata/sdk-backend-spi";
4
+ export function useWorkspaceColorPalette(backend, workspaceId) {
5
+ const [paletteState, setPaletteState] = useState({ state: "idle" });
6
+ useEffect(() => {
7
+ if (!backend || !workspaceId) {
8
+ setPaletteState((prev) => (prev.state === "idle" ? prev : { state: "idle" }));
9
+ return;
10
+ }
11
+ let cancelled = false;
12
+ setPaletteState({ state: "loading" });
13
+ backend
14
+ .workspace(workspaceId)
15
+ .styling()
16
+ .getColorPalette()
17
+ .then((colorPalette) => {
18
+ if (!cancelled) {
19
+ setPaletteState({ state: "ready", colorPalette });
20
+ }
21
+ })
22
+ .catch((e) => {
23
+ if (cancelled)
24
+ return;
25
+ if (e instanceof UnexpectedResponseError && (e.httpStatus === 403 || e.httpStatus === 404)) {
26
+ setPaletteState({ state: "forbidden" });
27
+ return;
28
+ }
29
+ const error = e instanceof Error ? e.message : "Unknown error loading workspace color palette.";
30
+ setPaletteState({ state: "error", error });
31
+ });
32
+ return () => {
33
+ cancelled = true;
34
+ };
35
+ }, [backend, workspaceId]);
36
+ return paletteState;
37
+ }
@@ -0,0 +1,17 @@
1
+ import { type IAnalyticalBackend } from "@gooddata/sdk-backend-spi";
2
+ import { type ITheme } from "@gooddata/sdk-model";
3
+ type WorkspaceThemeState = {
4
+ state: "idle";
5
+ } | {
6
+ state: "loading";
7
+ } | {
8
+ state: "ready";
9
+ theme: ITheme | undefined;
10
+ } | {
11
+ state: "forbidden";
12
+ } | {
13
+ state: "error";
14
+ error: string;
15
+ };
16
+ export declare function useWorkspaceTheme(backend: IAnalyticalBackend | undefined, workspaceId: string | undefined): WorkspaceThemeState;
17
+ export {};
@@ -0,0 +1,37 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { useEffect, useState } from "react";
3
+ import { UnexpectedResponseError } from "@gooddata/sdk-backend-spi";
4
+ export function useWorkspaceTheme(backend, workspaceId) {
5
+ const [themeState, setThemeState] = useState({ state: "idle" });
6
+ useEffect(() => {
7
+ if (!backend || !workspaceId) {
8
+ setThemeState((prev) => (prev.state === "idle" ? prev : { state: "idle" }));
9
+ return;
10
+ }
11
+ let cancelled = false;
12
+ setThemeState({ state: "loading" });
13
+ backend
14
+ .workspace(workspaceId)
15
+ .styling()
16
+ .getTheme()
17
+ .then((theme) => {
18
+ if (!cancelled) {
19
+ setThemeState({ state: "ready", theme });
20
+ }
21
+ })
22
+ .catch((e) => {
23
+ if (cancelled)
24
+ return;
25
+ if (e instanceof UnexpectedResponseError && (e.httpStatus === 403 || e.httpStatus === 404)) {
26
+ setThemeState({ state: "forbidden" });
27
+ return;
28
+ }
29
+ const error = e instanceof Error ? e.message : "Unknown error loading workspace theme.";
30
+ setThemeState({ state: "error", error });
31
+ });
32
+ return () => {
33
+ cancelled = true;
34
+ };
35
+ }, [backend, workspaceId]);
36
+ return themeState;
37
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Tells the host whether the iframe URL asks for postMessage-based auth injection.
3
+ *
4
+ * When this returns true, the host MUST defer `backend.bootstrap()` until a
5
+ * `SetApiToken` postMessage from the parent has been applied via `setApiToken`
6
+ * / `setJwt`. The flag may live in either `window.location.search` (modern
7
+ * pluggable URLs) or in the hash query (legacy AD iframe URLs).
8
+ */
9
+ export declare function shouldWaitForInjectedApiToken(): boolean;
10
+ /**
11
+ * Performs the pre-bootstrap auth handshake AD has historically owned, but
12
+ * lifted to the host so that pluggable AD can keep the customer-side wire
13
+ * contract unchanged.
14
+ *
15
+ * Sequence:
16
+ * 1. Configure messagingUtils to accept only `SetApiToken` from the
17
+ * "analyticalDesigner" product.
18
+ * 2. Register a one-shot listener for that command.
19
+ * 3. Emit `listeningForApiToken` to the parent frame.
20
+ * 4. Await the parent's `SetApiToken`, apply it to the host backend, then
21
+ * tear the listener down so AD can register its full command set when it
22
+ * mounts.
23
+ *
24
+ * Resolves once a valid token has been applied. Rejects if `signal` aborts.
25
+ */
26
+ export declare function waitForInjectedApiToken(signal?: AbortSignal): Promise<void>;
@@ -0,0 +1,104 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { GdcAdCommandType as GdcAdCommandTypeValues, GdcAdEventType, GdcProductName, isAdSetApiTokenCommandData, } from "@gooddata/sdk-embedding";
3
+ import { messagingUtils } from "@gooddata/sdk-embedding/internal";
4
+ import { setApiToken, setJwt } from "./backend.js";
5
+ const API_TOKEN_AUTHENTICATION_PARAM = "apiTokenAuthentication";
6
+ const EMBEDDED_PATH_PREFIX = "/embedded/";
7
+ function hasFlagInQuery(query) {
8
+ return new URLSearchParams(query).get(API_TOKEN_AUTHENTICATION_PARAM) === "true";
9
+ }
10
+ // Extracts the query portion from a hash like "#/<route>?<query>". Standalone AD
11
+ // uses hash-based routing and the legacy iframe URL keeps the flag inside the
12
+ // hash, so the host has to look there as well as in `window.location.search`.
13
+ function getHashQuery(hash) {
14
+ const idx = hash.indexOf("?");
15
+ return idx >= 0 ? hash.slice(idx + 1) : "";
16
+ }
17
+ /**
18
+ * Tells the host whether the iframe URL asks for postMessage-based auth injection.
19
+ *
20
+ * When this returns true, the host MUST defer `backend.bootstrap()` until a
21
+ * `SetApiToken` postMessage from the parent has been applied via `setApiToken`
22
+ * / `setJwt`. The flag may live in either `window.location.search` (modern
23
+ * pluggable URLs) or in the hash query (legacy AD iframe URLs).
24
+ */
25
+ export function shouldWaitForInjectedApiToken() {
26
+ if (!window.location.pathname.startsWith(EMBEDDED_PATH_PREFIX)) {
27
+ return false;
28
+ }
29
+ return (hasFlagInQuery(window.location.search.replace(/^\?/, "")) ||
30
+ hasFlagInQuery(getHashQuery(window.location.hash)));
31
+ }
32
+ /**
33
+ * Performs the pre-bootstrap auth handshake AD has historically owned, but
34
+ * lifted to the host so that pluggable AD can keep the customer-side wire
35
+ * contract unchanged.
36
+ *
37
+ * Sequence:
38
+ * 1. Configure messagingUtils to accept only `SetApiToken` from the
39
+ * "analyticalDesigner" product.
40
+ * 2. Register a one-shot listener for that command.
41
+ * 3. Emit `listeningForApiToken` to the parent frame.
42
+ * 4. Await the parent's `SetApiToken`, apply it to the host backend, then
43
+ * tear the listener down so AD can register its full command set when it
44
+ * mounts.
45
+ *
46
+ * Resolves once a valid token has been applied. Rejects if `signal` aborts.
47
+ */
48
+ export async function waitForInjectedApiToken(signal) {
49
+ return new Promise((resolve, reject) => {
50
+ let listener;
51
+ const cleanup = () => {
52
+ if (listener) {
53
+ messagingUtils.removeListener(listener);
54
+ listener = undefined;
55
+ }
56
+ signal?.removeEventListener("abort", onAbort);
57
+ };
58
+ const onAbort = () => {
59
+ cleanup();
60
+ reject(new DOMException("Aborted", "AbortError"));
61
+ };
62
+ if (signal?.aborted) {
63
+ onAbort();
64
+ return;
65
+ }
66
+ signal?.addEventListener("abort", onAbort, { once: true });
67
+ listener = (command) => {
68
+ if (!isAdSetApiTokenCommandData(command.data)) {
69
+ return false;
70
+ }
71
+ const payload = command.data.gdc.event.data;
72
+ if (!payload) {
73
+ return false;
74
+ }
75
+ const token = payload.token;
76
+ const tokenType = payload.type ?? "gooddata";
77
+ if (typeof token !== "string" || token.length === 0) {
78
+ return false;
79
+ }
80
+ if (tokenType === "jwt" && !/^[\w-]+\.[\w-]+\.[\w-]+$/.test(token)) {
81
+ return false;
82
+ }
83
+ try {
84
+ if (tokenType === "jwt") {
85
+ setJwt(token, payload.secondsBeforeTokenExpirationToEmitReminder ?? 60);
86
+ }
87
+ else {
88
+ setApiToken(token);
89
+ }
90
+ }
91
+ catch (e) {
92
+ cleanup();
93
+ reject(e);
94
+ return true;
95
+ }
96
+ cleanup();
97
+ resolve();
98
+ return true;
99
+ };
100
+ messagingUtils.setConfig(GdcProductName.ANALYTICAL_DESIGNER, [GdcAdCommandTypeValues.SetApiToken]);
101
+ messagingUtils.addListener(listener);
102
+ messagingUtils.postEvent(GdcProductName.ANALYTICAL_DESIGNER, GdcAdEventType.ListeningForApiToken, {});
103
+ });
104
+ }
@@ -106,10 +106,11 @@ export function HostChrome({ ctx, resolvedApplications, pathname, onNavigate, on
106
106
  const headerColor = ctx.theme?.header?.backgroundColor ?? defaultHeaderTheme.backgroundColor;
107
107
  const headerTextColor = ctx.theme?.header?.color ?? defaultHeaderTheme.color;
108
108
  const activeColor = ctx.theme?.header?.activeColor ?? defaultHeaderTheme.activeColor;
109
- return (_jsx(HostIntlProvider, { locale: locale, additionalMessages: appMessages, children: _jsx(BackendProvider, { backend: getBackend(), children: _jsx(ToastsCenterContextProvider, { children: _jsxs("div", { className: b(), children: [
110
- _jsx("div", { className: e("header"), onMouseOver: handleHeaderMouseOver, children: _jsx(AppHeader, { logoUrl: ctx.whiteLabeling?.logoUrl || defaultLogoUrl, logoHref: "/organization" // switch the host scope to organization, the first org app will be chosen
109
+ const isEmbedded = ctx.embeddingMode === "iframe";
110
+ return (_jsx(HostIntlProvider, { locale: locale, additionalMessages: appMessages, children: _jsx(BackendProvider, { backend: getBackend(), children: _jsx(ToastsCenterContextProvider, { children: _jsxs("div", { className: b(), children: [isEmbedded ? null : (_jsx("div", { className: e("header"), onMouseOver: handleHeaderMouseOver, children: _jsx(AppHeader, { logoUrl: ctx.whiteLabeling?.logoUrl || defaultLogoUrl, logoHref: "/organization" // switch the host scope to organization, the first org app will be chosen
111
111
  , logoTitle: logoTitle, headerColor: headerColor, headerTextColor: headerTextColor, activeColor: activeColor, userName: userName, organizationName: ctx.organization?.title, isAccessibilityCompliant: true, workspacePicker: workspacePicker, menuItemsGroups: menuItemsGroups, helpMenuItems: helpMenuItems, accountMenuItems: accountMenuItems, onMenuItemClick: handleMenuItemClick, showUpsellButton: pricing.isTrial, onUpsellButtonClick: pricing.onUpsellButtonClick, expiredDate: pricing.isTrial ? pricing.expiredDate : undefined, search: search.element, showChatItem: chat.showChatItem, onChatItemClick: chat.open, notificationsPanel: ctx.userSettings.enableInPlatformNotifications
112
- ? ({ isMobile, closeNotificationsOverlay }) => (_jsx(AppHeaderNotifications, { locale: locale, isMobile: isMobile, closeNotificationsOverlay: closeNotificationsOverlay, useAsOfDateParam: ctx.userSettings.enableExecutionTimestamp ?? false, enableExportToDocumentStorage: ctx.userSettings.enableExportToDocumentStorage ?? false }))
113
- : undefined }) }), _jsx("main", { className: e("content"), children: children }), chat.element, pricing.element, _jsx(HostNotificationDispatcher, { notification: notification })
112
+ ? ({ isMobile, closeNotificationsOverlay }) => (_jsx(AppHeaderNotifications, { locale: locale, isMobile: isMobile, closeNotificationsOverlay: closeNotificationsOverlay, useAsOfDateParam: ctx.userSettings.enableExecutionTimestamp ?? false, enableExportToDocumentStorage: ctx.userSettings.enableExportToDocumentStorage ??
113
+ false }))
114
+ : undefined }) })), _jsx("main", { className: e("content"), children: children }), chat.element, pricing.element, _jsx(HostNotificationDispatcher, { notification: notification })
114
115
  ] }) }) }) }));
115
116
  }
@@ -17,7 +17,8 @@ export function PluggableApplicationRenderer({ app, ctx, pathname, onHeaderChang
17
17
  const containerRef = useRef(null);
18
18
  const mountHandleRef = useRef(undefined);
19
19
  const [viewState, setViewState] = useState({ state: "loading" });
20
- const appBasePath = getApplicationHref(app, ctx, pathname);
20
+ const baseHref = getApplicationHref(app, ctx, pathname);
21
+ const appBasePath = ctx.embeddingMode === "iframe" ? `/embedded${baseHref}` : baseHref;
21
22
  const lifecycle = getAppLifecycleCallbacks();
22
23
  const onTelemetryEvent = useMemo(() => lifecycle?.createTelemetryCallbacks?.(app.id), [lifecycle, app.id]);
23
24
  // onEvent is intentionally stable (empty deps) — pluggable apps capture it at mount time
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gooddata/sdk-ui-pluggable-host",
3
- "version": "11.40.0-alpha.3",
3
+ "version": "11.40.0-alpha.4",
4
4
  "description": "GoodData SDK runtime for hosting pluggable applications — registry, loader, routing, platform context, default UI chrome",
5
5
  "license": "MIT",
6
6
  "author": "GoodData Corporation",
@@ -29,19 +29,20 @@
29
29
  "dependencies": {
30
30
  "@module-federation/runtime": "2.3.1",
31
31
  "lodash-es": "^4.17.23",
32
- "@gooddata/sdk-backend-base": "11.40.0-alpha.3",
33
- "@gooddata/sdk-backend-spi": "11.40.0-alpha.3",
34
- "@gooddata/sdk-backend-tiger": "11.40.0-alpha.3",
35
- "@gooddata/sdk-model": "11.40.0-alpha.3",
36
- "@gooddata/sdk-pluggable-application-model": "11.40.0-alpha.3",
37
- "@gooddata/sdk-ui-application-header": "11.40.0-alpha.3",
38
- "@gooddata/sdk-ui": "11.40.0-alpha.3",
39
- "@gooddata/sdk-ui-ext": "11.40.0-alpha.3",
40
- "@gooddata/sdk-ui-gen-ai": "11.40.0-alpha.3",
41
- "@gooddata/sdk-ui-kit": "11.40.0-alpha.3",
42
- "@gooddata/sdk-ui-semantic-search": "11.40.0-alpha.3",
43
- "@gooddata/sdk-ui-theme-provider": "11.40.0-alpha.3",
44
- "@gooddata/util": "11.40.0-alpha.3"
32
+ "@gooddata/sdk-backend-base": "11.40.0-alpha.4",
33
+ "@gooddata/sdk-backend-spi": "11.40.0-alpha.4",
34
+ "@gooddata/sdk-backend-tiger": "11.40.0-alpha.4",
35
+ "@gooddata/sdk-embedding": "11.40.0-alpha.4",
36
+ "@gooddata/sdk-model": "11.40.0-alpha.4",
37
+ "@gooddata/sdk-pluggable-application-model": "11.40.0-alpha.4",
38
+ "@gooddata/sdk-ui": "11.40.0-alpha.4",
39
+ "@gooddata/sdk-ui-application-header": "11.40.0-alpha.4",
40
+ "@gooddata/sdk-ui-ext": "11.40.0-alpha.4",
41
+ "@gooddata/sdk-ui-gen-ai": "11.40.0-alpha.4",
42
+ "@gooddata/sdk-ui-kit": "11.40.0-alpha.4",
43
+ "@gooddata/sdk-ui-semantic-search": "11.40.0-alpha.4",
44
+ "@gooddata/sdk-ui-theme-provider": "11.40.0-alpha.4",
45
+ "@gooddata/util": "11.40.0-alpha.4"
45
46
  },
46
47
  "devDependencies": {
47
48
  "@microsoft/api-documenter": "^7.17.0",
@@ -55,7 +56,7 @@
55
56
  "@typescript-eslint/eslint-plugin": "8.58.0",
56
57
  "@typescript-eslint/parser": "8.58.0",
57
58
  "@typescript/native-preview": "7.0.0-dev.20260202.1",
58
- "@vitest/coverage-v8": "4.1.0",
59
+ "@vitest/coverage-v8": "4.1.8",
59
60
  "@vitest/eslint-plugin": "1.6.6",
60
61
  "eslint": "^9.39.2",
61
62
  "eslint-import-resolver-typescript": "4.4.4",
@@ -70,22 +71,22 @@
70
71
  "happy-dom": "18.0.1",
71
72
  "jiti": "2.6.1",
72
73
  "npm-run-all": "^4.1.5",
73
- "oxfmt": "0.45.0",
74
- "oxlint": "^1.43.0",
75
- "oxlint-tsgolint": "0.11.4",
74
+ "oxfmt": "0.52.0",
75
+ "oxlint": "1.51.0",
76
+ "oxlint-tsgolint": "0.15.0",
76
77
  "react": "19.1.1",
77
78
  "react-dom": "19.1.1",
78
79
  "react-intl": "7.1.11",
79
80
  "react-router": "7.13.1",
80
- "rolldown": "1.0.0-rc.9",
81
+ "rolldown": "1.0.3",
81
82
  "sass": "1.70.0",
82
83
  "tslib": "2.8.1",
83
84
  "typescript": "5.9.3",
84
- "vite": "8.0.0",
85
- "vitest": "4.1.0",
85
+ "vite": "8.0.16",
86
+ "vitest": "4.1.8",
86
87
  "vitest-dom": "0.1.1",
87
- "@gooddata/eslint-config": "11.40.0-alpha.3",
88
- "@gooddata/oxlint-config": "11.40.0-alpha.3"
88
+ "@gooddata/eslint-config": "11.40.0-alpha.4",
89
+ "@gooddata/oxlint-config": "11.40.0-alpha.4"
89
90
  },
90
91
  "peerDependencies": {
91
92
  "react": ">=18.3.1",