@syntrologie/adapt-chatbot 2.29.0 → 2.30.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/AdaptiveChatBarMountable.d.ts.map +1 -1
- package/dist/ChatAssistantLit.d.ts +5 -3
- package/dist/ChatAssistantLit.d.ts.map +1 -1
- package/dist/ChatAssistantLit.js +1 -1
- package/dist/ChatTransport.d.ts.map +1 -1
- package/dist/{chunk-ZXV4GXMO.js → chunk-A3TIGA4G.js} +5 -12
- package/dist/{chunk-ZXV4GXMO.js.map → chunk-A3TIGA4G.js.map} +2 -2
- package/dist/editorToken.d.ts +23 -0
- package/dist/editorToken.d.ts.map +1 -0
- package/dist/elements/fetcher.d.ts +8 -5
- package/dist/elements/fetcher.d.ts.map +1 -1
- package/dist/runtime.js +35 -15
- package/dist/runtime.js.map +3 -3
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Editor-session token for draft template verification.
|
|
3
|
+
*
|
|
4
|
+
* In editor mode the backend can verify submitted uiTemplates against the
|
|
5
|
+
* SERVER-SIDE draft of the plan an editor token is bound to (runtime-backend
|
|
6
|
+
* `config_verify/draft.py`) instead of requiring a released GrowthBook
|
|
7
|
+
* config. The chat surfaces attach the token as `X-Syntro-Editor-Token` on
|
|
8
|
+
* the /templates boot publish and every /stream turn; outside editor mode
|
|
9
|
+
* no header is sent and the release-only contract stands.
|
|
10
|
+
*
|
|
11
|
+
* Token source, in order:
|
|
12
|
+
* 1. The page's `editor_source` URL param — the same base64url payload the
|
|
13
|
+
* editor-sdk boots from ({token, api_base}). Read lazily per request so
|
|
14
|
+
* there is no load-order dependency on the editor bundle.
|
|
15
|
+
* 2. `window.__SYNTRO_EDITOR_PARAMS__` — the editor-sdk's injected params,
|
|
16
|
+
* which survive SPA navigations that drop the query string.
|
|
17
|
+
*
|
|
18
|
+
* This is deliberately NOT a workspace-auth channel (that is `runtime.token`,
|
|
19
|
+
* BUG-1785360157). The editor token is an ADDITIVE capability the server
|
|
20
|
+
* validates independently; sending a stale/invalid one is harmless.
|
|
21
|
+
*/
|
|
22
|
+
export declare function readEditorToken(): string | undefined;
|
|
23
|
+
//# sourceMappingURL=editorToken.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editorToken.d.ts","sourceRoot":"","sources":["../src/editorToken.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,SAAS,CAoBpD"}
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
* `packages/runtime-sdk/src/overlays/fetcher.ts` for the sibling pattern
|
|
6
6
|
* — no shared HTTP client, no axios, no fetch wrapper).
|
|
7
7
|
*
|
|
8
|
-
* Auth: forwards the SDK token from
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* Auth: forwards the caller-supplied SDK token (from the runtime handle,
|
|
9
|
+
* the single source `Syntro.init` populates — BUG-1785360157: never a
|
|
10
|
+
* window global) as a Bearer header, plus the runtime's visitor ids
|
|
11
|
+
* (`X-Distinct-Id` / `X-Syntro-Session`) so the backend rehydrates
|
|
12
|
+
* mounts under the same session-keyed Redis state the chat persisted to.
|
|
12
13
|
*
|
|
13
14
|
* 404 contract: the backend returns 404 only when the workspace's SDK
|
|
14
15
|
* token doesn't resolve to a workspace. The SDK treats 404 as
|
|
@@ -22,7 +23,9 @@ export interface FetchMountedElementsOptions {
|
|
|
22
23
|
* `/api/adaptive/mounted_elements`). Tests + multi-environment
|
|
23
24
|
* deploys use this. */
|
|
24
25
|
endpoint?: string;
|
|
25
|
-
/** SDK token
|
|
26
|
+
/** SDK token from the runtime handle (`runtime.token`). Absent →
|
|
27
|
+
* unauthenticated request; the backend 401s and the caller's null
|
|
28
|
+
* contract kicks in. No window-global fallback (BUG-1785360157). */
|
|
26
29
|
token?: string;
|
|
27
30
|
/** Custom fetch implementation — used by tests to mock the network. */
|
|
28
31
|
fetchImpl?: typeof fetch;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../src/elements/fetcher.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../src/elements/fetcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAIvD,MAAM,WAAW,2BAA2B;IAC1C;;4BAEwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;yEAEqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,oDAAoD;IACpD,MAAM,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CA2DzC"}
|
package/dist/runtime.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
decodeMutationEnvelope,
|
|
10
10
|
fetchMountedElements,
|
|
11
11
|
renderFallbackHtml
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-A3TIGA4G.js";
|
|
13
13
|
import {
|
|
14
14
|
pickPersona
|
|
15
15
|
} from "./chunk-FXHYE6FY.js";
|
|
@@ -361,13 +361,31 @@ var ChatSession = class {
|
|
|
361
361
|
};
|
|
362
362
|
var chatSession = new ChatSession();
|
|
363
363
|
|
|
364
|
+
// src/editorToken.ts
|
|
365
|
+
function readEditorToken() {
|
|
366
|
+
if (typeof window === "undefined") return void 0;
|
|
367
|
+
try {
|
|
368
|
+
const raw = new URLSearchParams(window.location.search).get("editor_source");
|
|
369
|
+
if (raw) {
|
|
370
|
+
const b64 = raw.replace(/-/g, "+").replace(/_/g, "/");
|
|
371
|
+
const parsed = JSON.parse(atob(b64));
|
|
372
|
+
if (typeof parsed.token === "string" && parsed.token.length > 0) return parsed.token;
|
|
373
|
+
}
|
|
374
|
+
} catch {
|
|
375
|
+
}
|
|
376
|
+
try {
|
|
377
|
+
const params = window.__SYNTRO_EDITOR_PARAMS__;
|
|
378
|
+
if (typeof params?.token === "string" && params.token.length > 0) return params.token;
|
|
379
|
+
} catch {
|
|
380
|
+
}
|
|
381
|
+
return void 0;
|
|
382
|
+
}
|
|
383
|
+
|
|
364
384
|
// src/ChatTransport.ts
|
|
365
385
|
var SESSION_READ_DEADLINE_MS = 6e4;
|
|
366
386
|
var FALLBACK_DEBOUNCE_MS = 1500;
|
|
367
|
-
function
|
|
368
|
-
|
|
369
|
-
const cfg = window.__SYNTRO_CONFIG__;
|
|
370
|
-
const token = cfg?.token;
|
|
387
|
+
function readRuntimeToken(runtime2) {
|
|
388
|
+
const token = runtime2?.token;
|
|
371
389
|
return typeof token === "string" && token.length > 0 ? token : void 0;
|
|
372
390
|
}
|
|
373
391
|
function debug(...args) {
|
|
@@ -649,7 +667,7 @@ var ChatTransport = class {
|
|
|
649
667
|
const baseUrl = this._config.backendUrl.replace(/\/$/, "");
|
|
650
668
|
const url = `${baseUrl}/api/adaptive/session`;
|
|
651
669
|
const headers = {};
|
|
652
|
-
const token =
|
|
670
|
+
const token = readRuntimeToken(this._config?.runtime);
|
|
653
671
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
654
672
|
const cft = await this._acquireTurnstileWithChallenge();
|
|
655
673
|
if (cft) headers["CF-Turnstile-Token"] = cft;
|
|
@@ -932,11 +950,13 @@ var ChatTransport = class {
|
|
|
932
950
|
if (this._config === null) return false;
|
|
933
951
|
const baseUrl = this._config.backendUrl.replace(/\/$/, "");
|
|
934
952
|
const streamUrl = `${baseUrl}/api/adaptive/stream`;
|
|
935
|
-
const token =
|
|
953
|
+
const token = readRuntimeToken(this._config?.runtime);
|
|
936
954
|
const buildHeaders = () => {
|
|
937
955
|
const h = {};
|
|
938
956
|
if (token) h.Authorization = `Bearer ${token}`;
|
|
939
957
|
if (cft) h["CF-Turnstile-Token"] = cft;
|
|
958
|
+
const editorToken = readEditorToken();
|
|
959
|
+
if (editorToken) h["X-Syntro-Editor-Token"] = editorToken;
|
|
940
960
|
const lidSlot = this._pendingLidSlot ?? this._config?.activeLidSlot;
|
|
941
961
|
if (typeof lidSlot === "string" && lidSlot.length > 0) {
|
|
942
962
|
h["X-Active-Lid-Slot"] = lidSlot;
|
|
@@ -1814,7 +1834,7 @@ function hydrateOnce(runtime2, backendUrl) {
|
|
|
1814
1834
|
const store = getOrCreateElementStore(runtime2);
|
|
1815
1835
|
const trimmed = backendUrl.replace(/\/$/, "");
|
|
1816
1836
|
const endpoint = trimmed ? `${trimmed}/api/adaptive/mounted_elements` : "/api/adaptive/mounted_elements";
|
|
1817
|
-
fetchMountedElements({ endpoint }).then((response) => {
|
|
1837
|
+
fetchMountedElements({ endpoint, token: runtime2.token }).then((response) => {
|
|
1818
1838
|
if (!response) return;
|
|
1819
1839
|
void store.hydrate(response.mounted_elements);
|
|
1820
1840
|
});
|
|
@@ -1866,7 +1886,7 @@ function wireNudgeSurface(runtime2, backendUrl) {
|
|
|
1866
1886
|
const store = getOrCreateElementStore(runtime2);
|
|
1867
1887
|
const trimmed = backendUrl.replace(/\/$/, "");
|
|
1868
1888
|
const endpoint = trimmed ? `${trimmed}/api/adaptive/mounted_elements` : "/api/adaptive/mounted_elements";
|
|
1869
|
-
void fetchMountedElements({ endpoint }).then((response) => {
|
|
1889
|
+
void fetchMountedElements({ endpoint, token: runtime2.token }).then((response) => {
|
|
1870
1890
|
if (!response) return;
|
|
1871
1891
|
void store.hydrate(response.mounted_elements);
|
|
1872
1892
|
});
|
|
@@ -1905,7 +1925,7 @@ function configureTransportIfPossible(cfg) {
|
|
|
1905
1925
|
const elementsActive = cfg.elementsEnabled === true && cfg.uiTemplates != null;
|
|
1906
1926
|
refreshTemplateWidgetMap(elementsActive ? cfg.uiTemplates : void 0);
|
|
1907
1927
|
const forwardedProps = elementsActive ? { elementsEnabled: true, uiTemplates: cfg.uiTemplates } : void 0;
|
|
1908
|
-
if (elementsActive) publishTemplatesIfPossible(backendUrl, cfg.uiTemplates);
|
|
1928
|
+
if (elementsActive) publishTemplatesIfPossible(backendUrl, cfg.uiTemplates, cfg.runtime?.token);
|
|
1909
1929
|
const runtime2 = cfg.runtime;
|
|
1910
1930
|
const onElementMutation = elementsActive ? (mutations) => {
|
|
1911
1931
|
void getOrCreateElementStore(runtime2).apply(mutations);
|
|
@@ -1929,14 +1949,14 @@ function configureTransportIfPossible(cfg) {
|
|
|
1929
1949
|
startObserverIfPossible(cfg);
|
|
1930
1950
|
}
|
|
1931
1951
|
var _templatesPublished = false;
|
|
1932
|
-
function publishTemplatesIfPossible(backendUrl, uiTemplates) {
|
|
1952
|
+
function publishTemplatesIfPossible(backendUrl, uiTemplates, token) {
|
|
1933
1953
|
if (_templatesPublished || typeof window === "undefined") return;
|
|
1934
1954
|
if (!uiTemplates || typeof uiTemplates !== "object") return;
|
|
1935
1955
|
_templatesPublished = true;
|
|
1936
|
-
const cfg = window.__SYNTRO_CONFIG__;
|
|
1937
|
-
const token = typeof cfg?.token === "string" && cfg.token.length > 0 ? cfg.token : void 0;
|
|
1938
1956
|
const headers = { "Content-Type": "application/json" };
|
|
1939
1957
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
1958
|
+
const editorToken = readEditorToken();
|
|
1959
|
+
if (editorToken) headers["X-Syntro-Editor-Token"] = editorToken;
|
|
1940
1960
|
const trimmed = backendUrl.replace(/\/$/, "");
|
|
1941
1961
|
void fetch(`${trimmed}/api/adaptive/templates`, {
|
|
1942
1962
|
method: "POST",
|
|
@@ -1992,8 +2012,8 @@ function startObserverIfPossible(cfg) {
|
|
|
1992
2012
|
const getDistinctId = () => runtimeId("getDistinctId");
|
|
1993
2013
|
const getSessionId = () => runtimeId("getSessionId");
|
|
1994
2014
|
const token = () => {
|
|
1995
|
-
const
|
|
1996
|
-
return typeof
|
|
2015
|
+
const t = runtimeRef.token;
|
|
2016
|
+
return typeof t === "string" ? t : "";
|
|
1997
2017
|
};
|
|
1998
2018
|
const enrich = buildObserverEnrich(runtimeRef);
|
|
1999
2019
|
const handle = startObserver({ url, token, getDistinctId, getSessionId, enrich });
|