@qontinui/ui-bridge 0.9.1 → 0.10.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/index.js +36 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +36 -7
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +31 -0
- package/dist/react/index.d.ts +31 -0
- package/dist/react/index.js +36 -7
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +36 -7
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react/index.d.mts
CHANGED
|
@@ -1616,6 +1616,29 @@ interface UseCommandRelayOptions {
|
|
|
1616
1616
|
* build-time defaults baked into a static config).
|
|
1617
1617
|
*/
|
|
1618
1618
|
version?: string;
|
|
1619
|
+
/**
|
|
1620
|
+
* Optional hook that returns the current session token (the raw token
|
|
1621
|
+
* value, WITHOUT a `Bearer ` prefix). When supplied and returns a
|
|
1622
|
+
* non-empty string, the SDK:
|
|
1623
|
+
*
|
|
1624
|
+
* - attaches `Authorization: Bearer <value>` to outbound
|
|
1625
|
+
* `POST {basePath}/commands` and `POST {basePath}/heartbeat`;
|
|
1626
|
+
* - appends a `_auth=<value>` query parameter to the SSE URL
|
|
1627
|
+
* `GET {basePath}/commands/stream` (EventSource cannot set custom
|
|
1628
|
+
* headers per the WhatWG spec).
|
|
1629
|
+
*
|
|
1630
|
+
* Called fresh on every outbound request — implementations should read
|
|
1631
|
+
* the token from a live source (e.g. `sessionStorage`) so a token
|
|
1632
|
+
* rotation is picked up without remounting the listener. Returning
|
|
1633
|
+
* `null` / `undefined` / empty string means "no auth this call" and
|
|
1634
|
+
* the transport falls back to legacy unauth'd / cookie-based behavior
|
|
1635
|
+
* (matching the SDK's pre-`authHeader` shape).
|
|
1636
|
+
*
|
|
1637
|
+
* Required to authenticate against any relay endpoint that enforces a
|
|
1638
|
+
* session-bound auth gate (e.g. qontinui-web's
|
|
1639
|
+
* `UI_BRIDGE_REQUIRE_AUTH=1` mode).
|
|
1640
|
+
*/
|
|
1641
|
+
authHeader?: () => string | null | undefined;
|
|
1619
1642
|
}
|
|
1620
1643
|
/**
|
|
1621
1644
|
* Hook that connects the browser to the server's command relay.
|
|
@@ -1660,6 +1683,14 @@ interface CommandRelayListenerProps {
|
|
|
1660
1683
|
* defaults baked into the static config.
|
|
1661
1684
|
*/
|
|
1662
1685
|
version?: string;
|
|
1686
|
+
/**
|
|
1687
|
+
* Optional hook returning the current session token (raw value, no
|
|
1688
|
+
* `Bearer ` prefix). When supplied, the SDK attaches
|
|
1689
|
+
* `Authorization: Bearer <value>` to outbound `POST /commands` and
|
|
1690
|
+
* `POST /heartbeat` and appends `_auth=<value>` to the SSE URL.
|
|
1691
|
+
* See `UseCommandRelayOptions.authHeader` for the full contract.
|
|
1692
|
+
*/
|
|
1693
|
+
authHeader?: () => string | null | undefined;
|
|
1663
1694
|
}
|
|
1664
1695
|
declare function CommandRelayListener(props: CommandRelayListenerProps): null;
|
|
1665
1696
|
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1616,6 +1616,29 @@ interface UseCommandRelayOptions {
|
|
|
1616
1616
|
* build-time defaults baked into a static config).
|
|
1617
1617
|
*/
|
|
1618
1618
|
version?: string;
|
|
1619
|
+
/**
|
|
1620
|
+
* Optional hook that returns the current session token (the raw token
|
|
1621
|
+
* value, WITHOUT a `Bearer ` prefix). When supplied and returns a
|
|
1622
|
+
* non-empty string, the SDK:
|
|
1623
|
+
*
|
|
1624
|
+
* - attaches `Authorization: Bearer <value>` to outbound
|
|
1625
|
+
* `POST {basePath}/commands` and `POST {basePath}/heartbeat`;
|
|
1626
|
+
* - appends a `_auth=<value>` query parameter to the SSE URL
|
|
1627
|
+
* `GET {basePath}/commands/stream` (EventSource cannot set custom
|
|
1628
|
+
* headers per the WhatWG spec).
|
|
1629
|
+
*
|
|
1630
|
+
* Called fresh on every outbound request — implementations should read
|
|
1631
|
+
* the token from a live source (e.g. `sessionStorage`) so a token
|
|
1632
|
+
* rotation is picked up without remounting the listener. Returning
|
|
1633
|
+
* `null` / `undefined` / empty string means "no auth this call" and
|
|
1634
|
+
* the transport falls back to legacy unauth'd / cookie-based behavior
|
|
1635
|
+
* (matching the SDK's pre-`authHeader` shape).
|
|
1636
|
+
*
|
|
1637
|
+
* Required to authenticate against any relay endpoint that enforces a
|
|
1638
|
+
* session-bound auth gate (e.g. qontinui-web's
|
|
1639
|
+
* `UI_BRIDGE_REQUIRE_AUTH=1` mode).
|
|
1640
|
+
*/
|
|
1641
|
+
authHeader?: () => string | null | undefined;
|
|
1619
1642
|
}
|
|
1620
1643
|
/**
|
|
1621
1644
|
* Hook that connects the browser to the server's command relay.
|
|
@@ -1660,6 +1683,14 @@ interface CommandRelayListenerProps {
|
|
|
1660
1683
|
* defaults baked into the static config.
|
|
1661
1684
|
*/
|
|
1662
1685
|
version?: string;
|
|
1686
|
+
/**
|
|
1687
|
+
* Optional hook returning the current session token (raw value, no
|
|
1688
|
+
* `Bearer ` prefix). When supplied, the SDK attaches
|
|
1689
|
+
* `Authorization: Bearer <value>` to outbound `POST /commands` and
|
|
1690
|
+
* `POST /heartbeat` and appends `_auth=<value>` to the SSE URL.
|
|
1691
|
+
* See `UseCommandRelayOptions.authHeader` for the full contract.
|
|
1692
|
+
*/
|
|
1693
|
+
authHeader?: () => string | null | undefined;
|
|
1663
1694
|
}
|
|
1664
1695
|
declare function CommandRelayListener(props: CommandRelayListenerProps): null;
|
|
1665
1696
|
|
package/dist/react/index.js
CHANGED
|
@@ -24948,7 +24948,7 @@ function exposeProviderOnWindow(internals) {
|
|
|
24948
24948
|
if (typeof window === "undefined") return;
|
|
24949
24949
|
const w = window;
|
|
24950
24950
|
const root = w.__UI_BRIDGE__ ?? (w.__UI_BRIDGE__ = {});
|
|
24951
|
-
root.version = "0.
|
|
24951
|
+
root.version = "0.10.0";
|
|
24952
24952
|
root.specs = { getGlobalSpecStore };
|
|
24953
24953
|
root.registry = internals.registry;
|
|
24954
24954
|
root.browserCapture = internals.browserCapture;
|
|
@@ -32911,10 +32911,39 @@ function safeJsonStringify(value) {
|
|
|
32911
32911
|
});
|
|
32912
32912
|
}
|
|
32913
32913
|
var HEARTBEAT_INTERVAL_MS = 1e4;
|
|
32914
|
+
function resolveAuthToken(authHeader) {
|
|
32915
|
+
if (!authHeader) return null;
|
|
32916
|
+
try {
|
|
32917
|
+
const value = authHeader();
|
|
32918
|
+
if (typeof value !== "string") return null;
|
|
32919
|
+
const trimmed = value.trim();
|
|
32920
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
32921
|
+
} catch {
|
|
32922
|
+
return null;
|
|
32923
|
+
}
|
|
32924
|
+
}
|
|
32925
|
+
function transportHeaders(authHeader) {
|
|
32926
|
+
const headers = {
|
|
32927
|
+
"Content-Type": "application/json"
|
|
32928
|
+
};
|
|
32929
|
+
const token = resolveAuthToken(authHeader);
|
|
32930
|
+
if (token) {
|
|
32931
|
+
headers.Authorization = `Bearer ${token}`;
|
|
32932
|
+
}
|
|
32933
|
+
return headers;
|
|
32934
|
+
}
|
|
32935
|
+
function appendAuthQuery(url, authHeader) {
|
|
32936
|
+
const token = resolveAuthToken(authHeader);
|
|
32937
|
+
if (!token) return url;
|
|
32938
|
+
const sep = url.includes("?") ? "&" : "?";
|
|
32939
|
+
return `${url}${sep}_auth=${encodeURIComponent(token)}`;
|
|
32940
|
+
}
|
|
32914
32941
|
function useCommandRelay(options) {
|
|
32915
32942
|
const enabled = options?.enabled ?? true;
|
|
32916
32943
|
const basePath = options?.basePath ?? "/api/ui-bridge";
|
|
32917
32944
|
const heartbeatIntervalMs = options?.heartbeatInterval ?? HEARTBEAT_INTERVAL_MS;
|
|
32945
|
+
const authHeaderRef = react.useRef(void 0);
|
|
32946
|
+
authHeaderRef.current = options?.authHeader;
|
|
32918
32947
|
const uiBridge = useUIBridge();
|
|
32919
32948
|
const context = useUIBridgeOptional();
|
|
32920
32949
|
const bridge2 = react.useMemo(
|
|
@@ -32970,7 +32999,7 @@ function useCommandRelay(options) {
|
|
|
32970
32999
|
try {
|
|
32971
33000
|
await fetch(`${basePath}/commands`, {
|
|
32972
33001
|
method: "POST",
|
|
32973
|
-
headers:
|
|
33002
|
+
headers: transportHeaders(authHeaderRef.current),
|
|
32974
33003
|
body: safeJsonStringify({
|
|
32975
33004
|
commandId,
|
|
32976
33005
|
success: ok,
|
|
@@ -33036,9 +33065,8 @@ function useCommandRelay(options) {
|
|
|
33036
33065
|
let isMounted = true;
|
|
33037
33066
|
const connect = () => {
|
|
33038
33067
|
if (!isMounted) return;
|
|
33039
|
-
const
|
|
33040
|
-
|
|
33041
|
-
);
|
|
33068
|
+
const baseUrl = `${basePath}/commands/stream${tabId ? `?tabId=${encodeURIComponent(tabId)}` : ""}`;
|
|
33069
|
+
const es = new EventSource(appendAuthQuery(baseUrl, authHeaderRef.current));
|
|
33042
33070
|
eventSourceRef.current = es;
|
|
33043
33071
|
es.onmessage = (event) => {
|
|
33044
33072
|
try {
|
|
@@ -33125,7 +33153,7 @@ function useCommandRelay(options) {
|
|
|
33125
33153
|
if (heartbeatVersion !== void 0) body.version = heartbeatVersion;
|
|
33126
33154
|
const resp = await fetch(`${basePath}/heartbeat`, {
|
|
33127
33155
|
method: "POST",
|
|
33128
|
-
headers:
|
|
33156
|
+
headers: transportHeaders(authHeaderRef.current),
|
|
33129
33157
|
body: JSON.stringify(body)
|
|
33130
33158
|
});
|
|
33131
33159
|
if (resp.ok) {
|
|
@@ -33256,7 +33284,8 @@ function CommandRelayListener(props) {
|
|
|
33256
33284
|
appType: props.appType,
|
|
33257
33285
|
framework: props.framework,
|
|
33258
33286
|
capabilities: props.capabilities,
|
|
33259
|
-
version: props.version
|
|
33287
|
+
version: props.version,
|
|
33288
|
+
authHeader: props.authHeader
|
|
33260
33289
|
};
|
|
33261
33290
|
useCommandRelay(options);
|
|
33262
33291
|
return null;
|