@deway-ai/web-sdk 0.43.0 → 0.45.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/loader.es.js +48 -30
- package/dist/loader.umd.js +1 -1
- package/package.json +1 -1
package/dist/loader.es.js
CHANGED
|
@@ -45,9 +45,27 @@ class S {
|
|
|
45
45
|
getPromptSuggestions() {
|
|
46
46
|
return this.loadConfig()?.promptSuggestions;
|
|
47
47
|
}
|
|
48
|
+
getWelcomeTitle() {
|
|
49
|
+
return this.loadConfig()?.welcomeTitle ?? "How can I help you today?";
|
|
50
|
+
}
|
|
51
|
+
getWelcomeSubtitle() {
|
|
52
|
+
return this.loadConfig()?.welcomeSubtitle ?? "I'm ready to help you navigate, learn, and get things done.";
|
|
53
|
+
}
|
|
48
54
|
getBookmarkAppearanceMode() {
|
|
49
55
|
return this.loadConfig()?.bookmarkAppearanceMode ?? "bookmark";
|
|
50
56
|
}
|
|
57
|
+
getTenantTheme() {
|
|
58
|
+
return this.loadConfig()?.tenantTheme ?? null;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get the theme override for a specific mode
|
|
62
|
+
* @param mode - "light" or "dark"
|
|
63
|
+
* @returns ThemeOverride for the specified mode, or null if not available
|
|
64
|
+
*/
|
|
65
|
+
getTenantThemeForMode(e) {
|
|
66
|
+
const t = this.getTenantTheme();
|
|
67
|
+
return t ? e === "dark" ? t.dark : t.light : null;
|
|
68
|
+
}
|
|
51
69
|
}
|
|
52
70
|
class s {
|
|
53
71
|
static CACHE_KEY = "deway-sdk-cache";
|
|
@@ -57,7 +75,7 @@ class s {
|
|
|
57
75
|
async cacheSDK(e, t, i, n) {
|
|
58
76
|
try {
|
|
59
77
|
const d = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readwrite").objectStore(s.STORE_NAME);
|
|
60
|
-
await new Promise((
|
|
78
|
+
await new Promise((h, m) => {
|
|
61
79
|
const l = d.put({
|
|
62
80
|
id: "latest",
|
|
63
81
|
code: e,
|
|
@@ -66,27 +84,27 @@ class s {
|
|
|
66
84
|
signature: n,
|
|
67
85
|
timestamp: Date.now()
|
|
68
86
|
});
|
|
69
|
-
l.onsuccess = () =>
|
|
87
|
+
l.onsuccess = () => h(l.result), l.onerror = () => m(l.error);
|
|
70
88
|
});
|
|
71
89
|
} catch {
|
|
72
90
|
try {
|
|
73
|
-
const
|
|
91
|
+
const a = JSON.stringify({
|
|
74
92
|
code: e,
|
|
75
93
|
version: t,
|
|
76
94
|
checksum: i,
|
|
77
95
|
signature: n,
|
|
78
96
|
timestamp: Date.now()
|
|
79
97
|
});
|
|
80
|
-
localStorage.setItem(s.CACHE_KEY,
|
|
98
|
+
localStorage.setItem(s.CACHE_KEY, a);
|
|
81
99
|
} catch {
|
|
82
100
|
}
|
|
83
101
|
}
|
|
84
102
|
}
|
|
85
103
|
async getCachedSDK() {
|
|
86
104
|
try {
|
|
87
|
-
const i = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readonly").objectStore(s.STORE_NAME), n = await new Promise((
|
|
105
|
+
const i = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readonly").objectStore(s.STORE_NAME), n = await new Promise((o, a) => {
|
|
88
106
|
const d = i.get("latest");
|
|
89
|
-
d.onsuccess = () =>
|
|
107
|
+
d.onsuccess = () => o(d.result || null), d.onerror = () => a(d.error);
|
|
90
108
|
});
|
|
91
109
|
if (n)
|
|
92
110
|
return n;
|
|
@@ -104,15 +122,15 @@ class s {
|
|
|
104
122
|
return new Promise((e, t) => {
|
|
105
123
|
const i = indexedDB.open(s.DB_NAME, s.DB_VERSION);
|
|
106
124
|
i.onerror = () => t(i.error), i.onsuccess = () => e(i.result), i.onupgradeneeded = (n) => {
|
|
107
|
-
const
|
|
108
|
-
|
|
125
|
+
const o = n.target.result;
|
|
126
|
+
o.objectStoreNames.contains(s.STORE_NAME) || o.createObjectStore(s.STORE_NAME, { keyPath: "id" });
|
|
109
127
|
};
|
|
110
128
|
});
|
|
111
129
|
}
|
|
112
130
|
}
|
|
113
131
|
async function C(r) {
|
|
114
132
|
const t = new TextEncoder().encode(r), i = await crypto.subtle.digest("SHA-256", t);
|
|
115
|
-
return Array.from(new Uint8Array(i)).map((
|
|
133
|
+
return Array.from(new Uint8Array(i)).map((o) => o.toString(16).padStart(2, "0")).join("");
|
|
116
134
|
}
|
|
117
135
|
function w(r) {
|
|
118
136
|
const e = atob(r), t = new Uint8Array(e.length);
|
|
@@ -128,8 +146,8 @@ function E(r) {
|
|
|
128
146
|
}
|
|
129
147
|
async function D(r, e, t) {
|
|
130
148
|
try {
|
|
131
|
-
const i = w(r), n = E(e),
|
|
132
|
-
return await crypto.subtle.verify("Ed25519",
|
|
149
|
+
const i = w(r), n = E(e), o = w(t), a = await crypto.subtle.importKey("raw", i, { name: "Ed25519" }, !1, ["verify"]);
|
|
150
|
+
return await crypto.subtle.verify("Ed25519", a, o, n);
|
|
133
151
|
} catch {
|
|
134
152
|
return !1;
|
|
135
153
|
}
|
|
@@ -148,7 +166,7 @@ class b {
|
|
|
148
166
|
}
|
|
149
167
|
async fetchSDK(e, t, i) {
|
|
150
168
|
try {
|
|
151
|
-
const n = this.cleanApiEndpoint(t),
|
|
169
|
+
const n = this.cleanApiEndpoint(t), o = await fetch(`${n}/sdk-serve/sdk/v0`, {
|
|
152
170
|
method: "GET",
|
|
153
171
|
headers: {
|
|
154
172
|
Accept: "application/javascript",
|
|
@@ -156,16 +174,16 @@ class b {
|
|
|
156
174
|
Origin: window?.location?.origin || ""
|
|
157
175
|
}
|
|
158
176
|
});
|
|
159
|
-
return
|
|
177
|
+
return o.ok ? this.handleSuccessfulFetch(o, i) : null;
|
|
160
178
|
} catch {
|
|
161
179
|
return null;
|
|
162
180
|
}
|
|
163
181
|
}
|
|
164
182
|
async handleSuccessfulFetch(e, t) {
|
|
165
|
-
const i = e.headers.get("x-sdk-checksum"), n = e.headers.get("x-sdk-version"),
|
|
166
|
-
if (!n || !
|
|
183
|
+
const i = e.headers.get("x-sdk-checksum"), n = e.headers.get("x-sdk-version"), o = e.headers.get("x-sdk-signature"), a = await e.text();
|
|
184
|
+
if (!n || !a || !i)
|
|
167
185
|
throw Object.fromEntries(e.headers.entries()), new Error("Invalid SDK response: missing version, code, or checksum");
|
|
168
|
-
return await A(
|
|
186
|
+
return await A(a, i, o, t), { code: a, version: n, checksum: i, signature: o || "" };
|
|
169
187
|
}
|
|
170
188
|
}
|
|
171
189
|
class g {
|
|
@@ -282,13 +300,13 @@ class K {
|
|
|
282
300
|
const i = document.createElement("script");
|
|
283
301
|
i.textContent = e, i.type = "text/javascript";
|
|
284
302
|
let n = !1;
|
|
285
|
-
const
|
|
286
|
-
n || (n = !0, this.cleanupScript(i), t(
|
|
303
|
+
const o = (a) => {
|
|
304
|
+
n || (n = !0, this.cleanupScript(i), t(a));
|
|
287
305
|
};
|
|
288
306
|
i.onerror = () => {
|
|
289
|
-
|
|
290
|
-
}, i.onload = () =>
|
|
291
|
-
!n && this.verifySDKLoaded() ?
|
|
307
|
+
o(!1);
|
|
308
|
+
}, i.onload = () => o(!0), document.head.appendChild(i), setTimeout(() => {
|
|
309
|
+
!n && this.verifySDKLoaded() ? o(!0) : n || o(!1);
|
|
292
310
|
}, 100);
|
|
293
311
|
} catch {
|
|
294
312
|
t(!1);
|
|
@@ -320,7 +338,7 @@ class k {
|
|
|
320
338
|
}
|
|
321
339
|
}
|
|
322
340
|
}
|
|
323
|
-
const
|
|
341
|
+
const f = {
|
|
324
342
|
apiEndpoint: "https://service.deway.app",
|
|
325
343
|
publicKey: "9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY="
|
|
326
344
|
};
|
|
@@ -350,11 +368,11 @@ class I {
|
|
|
350
368
|
if (!this.configValidator.validateConfig(i))
|
|
351
369
|
return;
|
|
352
370
|
this.isLoading = !0;
|
|
353
|
-
const n = i.apiEndpoint ||
|
|
354
|
-
if (!
|
|
371
|
+
const n = i.apiEndpoint || f.apiEndpoint, o = i.publicKey || f.publicKey, [a, d] = await Promise.all([this.fetchOrLoadSDK(i.appKey, n, o), this.fetchRemoteConfigWithCache(i, n)]);
|
|
372
|
+
if (!a)
|
|
355
373
|
return;
|
|
356
|
-
const
|
|
357
|
-
if (!await this.scriptExecutor.executeSDK(
|
|
374
|
+
const h = t ? e : this.createInitializationPayload(d, i);
|
|
375
|
+
if (!await this.scriptExecutor.executeSDK(a.code) || !this.initializeSDK(h))
|
|
358
376
|
return;
|
|
359
377
|
this.commandQueue.replayQueuedCommands(), this.isLoaded = !0;
|
|
360
378
|
} finally {
|
|
@@ -391,7 +409,7 @@ class I {
|
|
|
391
409
|
return {
|
|
392
410
|
localConfig: t,
|
|
393
411
|
remoteConfig: e?.config ?? null,
|
|
394
|
-
defaults:
|
|
412
|
+
defaults: f
|
|
395
413
|
};
|
|
396
414
|
}
|
|
397
415
|
async fetchOrLoadSDK(e, t, i) {
|
|
@@ -465,7 +483,7 @@ class I {
|
|
|
465
483
|
return typeof window < "u" && "Deway" in window && !!window.Deway;
|
|
466
484
|
}
|
|
467
485
|
}
|
|
468
|
-
const c = new I(),
|
|
486
|
+
const c = new I(), T = {
|
|
469
487
|
init: (r) => c.init(r),
|
|
470
488
|
identify: (r) => c.identify(r),
|
|
471
489
|
reportEvent: (r, e) => c.reportEvent(r, e),
|
|
@@ -476,7 +494,7 @@ const c = new I(), x = {
|
|
|
476
494
|
isInitialized: () => c.isInitialized(),
|
|
477
495
|
destroy: () => c.destroy()
|
|
478
496
|
};
|
|
479
|
-
typeof window < "u" && (window.Deway =
|
|
497
|
+
typeof window < "u" && (window.Deway = T);
|
|
480
498
|
export {
|
|
481
|
-
|
|
499
|
+
T as default
|
|
482
500
|
};
|
package/dist/loader.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(l,u){typeof exports=="object"&&typeof module<"u"?module.exports=u():typeof define=="function"&&define.amd?define(u):(l=typeof globalThis<"u"?globalThis:l||self,l.Deway=u())})(this,(function(){"use strict";const l="deway-sdk-config",u=["Understanding intent","Reading web page","Browsing the docs","Enriching context","Validating understanding","Crafting response"];class C{saveConfig(e){if(window?.localStorage)try{const t=JSON.stringify(e);window.localStorage.setItem(l,t)}catch{}}loadConfig(){if(window?.localStorage)try{const e=window.localStorage.getItem(l);return e?JSON.parse(e):null}catch{return null}return null}getExcludedVendors(){return this.loadConfig()?.excludedVendors??[]}getAssistantName(){return this.loadConfig()?.assistantName??"Assistant"}getAiDisclaimer(){return this.loadConfig()?.aiDisclaimer}getThinkingMessages(){return this.loadConfig()?.thinkingMessages??u}getTalkToHumanBtnTxt(){return this.loadConfig()?.talkToHumanBtnTxt??"talk to Support"}getHumanHandoffUrl(){return this.loadConfig()?.humanHandoffUrl}getFeatureFlags(){return this.loadConfig()?.featureFlags??{}}getFeatureFlag(e){return this.getFeatureFlags()[e]??!1}getPromptSuggestions(){return this.loadConfig()?.promptSuggestions}getBookmarkAppearanceMode(){return this.loadConfig()?.bookmarkAppearanceMode??"bookmark"}}class s{static CACHE_KEY="deway-sdk-cache";static DB_NAME="DewaySdk";static DB_VERSION=1;static STORE_NAME="sdk";async cacheSDK(e,t,i,n){try{const d=(await this.openIndexedDB()).transaction([s.STORE_NAME],"readwrite").objectStore(s.STORE_NAME);await new Promise((g,S)=>{const f=d.put({id:"latest",code:e,version:t,checksum:i,signature:n,timestamp:Date.now()});f.onsuccess=()=>g(f.result),f.onerror=()=>S(f.error)})}catch{try{const a=JSON.stringify({code:e,version:t,checksum:i,signature:n,timestamp:Date.now()});localStorage.setItem(s.CACHE_KEY,a)}catch{}}}async getCachedSDK(){try{const i=(await this.openIndexedDB()).transaction([s.STORE_NAME],"readonly").objectStore(s.STORE_NAME),n=await new Promise((o,a)=>{const d=i.get("latest");d.onsuccess=()=>o(d.result||null),d.onerror=()=>a(d.error)});if(n)return n}catch{}try{const e=localStorage.getItem(s.CACHE_KEY);if(e)return JSON.parse(e)}catch{}return null}openIndexedDB(){return new Promise((e,t)=>{const i=indexedDB.open(s.DB_NAME,s.DB_VERSION);i.onerror=()=>t(i.error),i.onsuccess=()=>e(i.result),i.onupgradeneeded=n=>{const o=n.target.result;o.objectStoreNames.contains(s.STORE_NAME)||o.createObjectStore(s.STORE_NAME,{keyPath:"id"})}})}}async function E(r){const t=new TextEncoder().encode(r),i=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(i)).map(o=>o.toString(16).padStart(2,"0")).join("")}function w(r){const e=atob(r),t=new Uint8Array(e.length);for(let i=0;i<e.length;i++)t[i]=e.charCodeAt(i);return t}function D(r){const e=new Uint8Array(r.length/2);for(let t=0;t<r.length;t+=2)e[t/2]=Number.parseInt(r.substr(t,2),16);return e}async function A(r,e,t){try{const i=w(r),n=D(e),o=w(t),a=await crypto.subtle.importKey("raw",i,{name:"Ed25519"},!1,["verify"]);return await crypto.subtle.verify("Ed25519",a,o,n)}catch{return!1}}async function b(r,e,t,i){if(!e||!t)throw new Error("SDK verification failed: Missing security headers");if(await E(r)!==e)throw new Error("SDK verification failed: Checksum mismatch - content tampered");if(!await A(i,e,t))throw new Error("SDK verification failed: Invalid signature - content tampered")}class v{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchSDK(e,t,i){try{const n=this.cleanApiEndpoint(t),o=await fetch(`${n}/sdk-serve/sdk/v0`,{method:"GET",headers:{Accept:"application/javascript","deway-app-key":e,Origin:window?.location?.origin||""}});return o.ok?this.handleSuccessfulFetch(o,i):null}catch{return null}}async handleSuccessfulFetch(e,t){const i=e.headers.get("x-sdk-checksum"),n=e.headers.get("x-sdk-version"),o=e.headers.get("x-sdk-signature"),a=await e.text();if(!n||!a||!i)throw Object.fromEntries(e.headers.entries()),new Error("Invalid SDK response: missing version, code, or checksum");return await b(a,i,o,t),{code:a,version:n,checksum:i,signature:o||""}}}class m{static MAX_QUEUE_SIZE=50;commandQueue=[];queueCommand(e,...t){this.commandQueue.length>=m.MAX_QUEUE_SIZE&&this.commandQueue.shift(),this.commandQueue.push({method:e,args:t})}replayQueuedCommands(){if(this.commandQueue.length===0)return;const e=[...this.commandQueue];if(this.commandQueue=[],!!this.isSDKAvailable())for(const t of e)this.replayCommand(t)}clearQueue(){this.commandQueue=[]}isSDKAvailable(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}replayCommand(e){try{const t=window.Deway,i=t?.[e.method];typeof i=="function"&&i.apply(t,e.args)}catch{}}}class h{static CACHE_KEY="deway-remote-config-cache";async cacheRemoteConfig(e,t){try{const i={config:e,ttl_seconds:t,timestamp:Date.now()};localStorage.setItem(h.CACHE_KEY,JSON.stringify(i))}catch{}}async getCachedRemoteConfig(){try{const e=localStorage.getItem(h.CACHE_KEY);return e?JSON.parse(e):null}catch{return null}}isCacheValid(e,t){const i=Date.now(),n=e+t*1e3;return i<n}}class K{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchRemoteConfig(e,t){try{const i=this.cleanApiEndpoint(t),n=await fetch(`${i}/sdk-remote-config-serve/`,{method:"GET",headers:{Accept:"application/json","deway-app-key":e,Origin:window?.location?.origin||""}});return n.ok?await n.json():null}catch{return null}}}class k{async executeSDK(e){return new Promise(t=>{try{if(!this.isDocumentReady()){t(!1);return}const i=document.createElement("script");i.textContent=e,i.type="text/javascript";let n=!1;const o=a=>{n||(n=!0,this.cleanupScript(i),t(a))};i.onerror=()=>{o(!1)},i.onload=()=>o(!0),document.head.appendChild(i),setTimeout(()=>{!n&&this.verifySDKLoaded()?o(!0):n||o(!1)},100)}catch{t(!1)}})}isDocumentReady(){return typeof document<"u"&&document.head!=null}verifySDKLoaded(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}cleanupScript(e){try{e.parentNode&&e.parentNode.removeChild(e)}catch{}}}class I{validateConfig(e){return!(!e||!e.appKey||e.appKey.trim().length===0||e.apiEndpoint!==void 0&&!this.isValidUrl(e.apiEndpoint)||e.publicKey!==void 0&&e.publicKey.trim().length===0)}isValidUrl(e){try{return new URL(e),!0}catch{return!1}}}const y={apiEndpoint:"https://service.deway.app",publicKey:"9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY="};class x{isLoaded=!1;isLoading=!1;cacheManager;scriptExecutor;commandQueue;sdkFetcher;configValidator;remoteConfigFetcher;remoteConfigCache;sdkConfigStore;constructor(){this.cacheManager=new s,this.scriptExecutor=new k,this.commandQueue=new m,this.sdkFetcher=new v,this.configValidator=new I,this.sdkConfigStore=new C,this.remoteConfigFetcher=new K,this.remoteConfigCache=new h}init(e){this.performInit(e).catch(t=>{})}async performInit(e){try{if(!this.canInitialize())return;const t=this.isInitializationPayload(e),i=t?e.localConfig:e;if(!this.configValidator.validateConfig(i))return;this.isLoading=!0;const n=i.apiEndpoint||y.apiEndpoint,o=i.publicKey||y.publicKey,[a,d]=await Promise.all([this.fetchOrLoadSDK(i.appKey,n,o),this.fetchRemoteConfigWithCache(i,n)]);if(!a)return;const g=t?e:this.createInitializationPayload(d,i);if(!await this.scriptExecutor.executeSDK(a.code)||!this.initializeSDK(g))return;this.commandQueue.replayQueuedCommands(),this.isLoaded=!0}finally{this.isLoading=!1}}isInitializationPayload(e){return"localConfig"in e&&"remoteConfig"in e&&"defaults"in e}canInitialize(){return!(this.isLoaded||this.isLoading)}async fetchRemoteConfigWithCache(e,t){this.sdkConfigStore.saveConfig(e);const i=await this.remoteConfigFetcher.fetchRemoteConfig(e.appKey,t);if(i)return await this.remoteConfigCache.cacheRemoteConfig(i.config,i.ttl_seconds),i;const n=await this.remoteConfigCache.getCachedRemoteConfig();return n?{config:n.config,ttl_seconds:n.ttl_seconds}:null}createInitializationPayload(e,t){return{localConfig:t,remoteConfig:e?.config??null,defaults:y}}async fetchOrLoadSDK(e,t,i){const n=await this.sdkFetcher.fetchSDK(e,t,i);return n?(await this.cacheManager.cacheSDK(n.code,n.version,n.checksum,n.signature),n):this.loadFromCache()}async loadFromCache(){const e=await this.cacheManager.getCachedSDK();return e?{code:e.code,version:e.version}:null}initializeSDK(e){if(!this.isSDKAvailable())return!1;try{return window.Deway?.init(e),!0}catch{return!1}}identify(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.identify(e):this.commandQueue.queueCommand("identify",e)}catch{}}reportEvent(e,t){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.reportEvent(e,t):this.commandQueue.queueCommand("reportEvent",e,t)}catch{}}setUserProfile(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.setUserProfile(e):this.commandQueue.queueCommand("setUserProfile",e)}catch{}}show(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.show(e):this.commandQueue.queueCommand("show",e)}catch{}}hide(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.hide():this.commandQueue.queueCommand("hide")}catch{}}isVisible(){try{return this.isLoaded&&this.isSDKAvailable()?window.Deway?.isVisible()??!1:!1}catch{return!1}}isInitialized(){try{return this.isLoaded&&this.isSDKAvailable()?window.Deway?.isInitialized()??!1:!1}catch{return!1}}destroy(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.destroy():this.commandQueue.queueCommand("destroy"),this.commandQueue.clearQueue()}catch{}}isSDKAvailable(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}}const c=new x,p={init:r=>c.init(r),identify:r=>c.identify(r),reportEvent:(r,e)=>c.reportEvent(r,e),setUserProfile:r=>c.setUserProfile(r),show:r=>c.show(r),hide:()=>c.hide(),isVisible:()=>c.isVisible(),isInitialized:()=>c.isInitialized(),destroy:()=>c.destroy()};return typeof window<"u"&&(window.Deway=p),p}));
|
|
1
|
+
(function(l,u){typeof exports=="object"&&typeof module<"u"?module.exports=u():typeof define=="function"&&define.amd?define(u):(l=typeof globalThis<"u"?globalThis:l||self,l.Deway=u())})(this,(function(){"use strict";const l="deway-sdk-config",u=["Understanding intent","Reading web page","Browsing the docs","Enriching context","Validating understanding","Crafting response"];class C{saveConfig(e){if(window?.localStorage)try{const t=JSON.stringify(e);window.localStorage.setItem(l,t)}catch{}}loadConfig(){if(window?.localStorage)try{const e=window.localStorage.getItem(l);return e?JSON.parse(e):null}catch{return null}return null}getExcludedVendors(){return this.loadConfig()?.excludedVendors??[]}getAssistantName(){return this.loadConfig()?.assistantName??"Assistant"}getAiDisclaimer(){return this.loadConfig()?.aiDisclaimer}getThinkingMessages(){return this.loadConfig()?.thinkingMessages??u}getTalkToHumanBtnTxt(){return this.loadConfig()?.talkToHumanBtnTxt??"talk to Support"}getHumanHandoffUrl(){return this.loadConfig()?.humanHandoffUrl}getFeatureFlags(){return this.loadConfig()?.featureFlags??{}}getFeatureFlag(e){return this.getFeatureFlags()[e]??!1}getPromptSuggestions(){return this.loadConfig()?.promptSuggestions}getWelcomeTitle(){return this.loadConfig()?.welcomeTitle??"How can I help you today?"}getWelcomeSubtitle(){return this.loadConfig()?.welcomeSubtitle??"I'm ready to help you navigate, learn, and get things done."}getBookmarkAppearanceMode(){return this.loadConfig()?.bookmarkAppearanceMode??"bookmark"}getTenantTheme(){return this.loadConfig()?.tenantTheme??null}getTenantThemeForMode(e){const t=this.getTenantTheme();return t?e==="dark"?t.dark:t.light:null}}class s{static CACHE_KEY="deway-sdk-cache";static DB_NAME="DewaySdk";static DB_VERSION=1;static STORE_NAME="sdk";async cacheSDK(e,t,i,n){try{const d=(await this.openIndexedDB()).transaction([s.STORE_NAME],"readwrite").objectStore(s.STORE_NAME);await new Promise((y,S)=>{const f=d.put({id:"latest",code:e,version:t,checksum:i,signature:n,timestamp:Date.now()});f.onsuccess=()=>y(f.result),f.onerror=()=>S(f.error)})}catch{try{const a=JSON.stringify({code:e,version:t,checksum:i,signature:n,timestamp:Date.now()});localStorage.setItem(s.CACHE_KEY,a)}catch{}}}async getCachedSDK(){try{const i=(await this.openIndexedDB()).transaction([s.STORE_NAME],"readonly").objectStore(s.STORE_NAME),n=await new Promise((o,a)=>{const d=i.get("latest");d.onsuccess=()=>o(d.result||null),d.onerror=()=>a(d.error)});if(n)return n}catch{}try{const e=localStorage.getItem(s.CACHE_KEY);if(e)return JSON.parse(e)}catch{}return null}openIndexedDB(){return new Promise((e,t)=>{const i=indexedDB.open(s.DB_NAME,s.DB_VERSION);i.onerror=()=>t(i.error),i.onsuccess=()=>e(i.result),i.onupgradeneeded=n=>{const o=n.target.result;o.objectStoreNames.contains(s.STORE_NAME)||o.createObjectStore(s.STORE_NAME,{keyPath:"id"})}})}}async function E(r){const t=new TextEncoder().encode(r),i=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(i)).map(o=>o.toString(16).padStart(2,"0")).join("")}function w(r){const e=atob(r),t=new Uint8Array(e.length);for(let i=0;i<e.length;i++)t[i]=e.charCodeAt(i);return t}function D(r){const e=new Uint8Array(r.length/2);for(let t=0;t<r.length;t+=2)e[t/2]=Number.parseInt(r.substr(t,2),16);return e}async function A(r,e,t){try{const i=w(r),n=D(e),o=w(t),a=await crypto.subtle.importKey("raw",i,{name:"Ed25519"},!1,["verify"]);return await crypto.subtle.verify("Ed25519",a,o,n)}catch{return!1}}async function b(r,e,t,i){if(!e||!t)throw new Error("SDK verification failed: Missing security headers");if(await E(r)!==e)throw new Error("SDK verification failed: Checksum mismatch - content tampered");if(!await A(i,e,t))throw new Error("SDK verification failed: Invalid signature - content tampered")}class v{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchSDK(e,t,i){try{const n=this.cleanApiEndpoint(t),o=await fetch(`${n}/sdk-serve/sdk/v0`,{method:"GET",headers:{Accept:"application/javascript","deway-app-key":e,Origin:window?.location?.origin||""}});return o.ok?this.handleSuccessfulFetch(o,i):null}catch{return null}}async handleSuccessfulFetch(e,t){const i=e.headers.get("x-sdk-checksum"),n=e.headers.get("x-sdk-version"),o=e.headers.get("x-sdk-signature"),a=await e.text();if(!n||!a||!i)throw Object.fromEntries(e.headers.entries()),new Error("Invalid SDK response: missing version, code, or checksum");return await b(a,i,o,t),{code:a,version:n,checksum:i,signature:o||""}}}class g{static MAX_QUEUE_SIZE=50;commandQueue=[];queueCommand(e,...t){this.commandQueue.length>=g.MAX_QUEUE_SIZE&&this.commandQueue.shift(),this.commandQueue.push({method:e,args:t})}replayQueuedCommands(){if(this.commandQueue.length===0)return;const e=[...this.commandQueue];if(this.commandQueue=[],!!this.isSDKAvailable())for(const t of e)this.replayCommand(t)}clearQueue(){this.commandQueue=[]}isSDKAvailable(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}replayCommand(e){try{const t=window.Deway,i=t?.[e.method];typeof i=="function"&&i.apply(t,e.args)}catch{}}}class h{static CACHE_KEY="deway-remote-config-cache";async cacheRemoteConfig(e,t){try{const i={config:e,ttl_seconds:t,timestamp:Date.now()};localStorage.setItem(h.CACHE_KEY,JSON.stringify(i))}catch{}}async getCachedRemoteConfig(){try{const e=localStorage.getItem(h.CACHE_KEY);return e?JSON.parse(e):null}catch{return null}}isCacheValid(e,t){const i=Date.now(),n=e+t*1e3;return i<n}}class K{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchRemoteConfig(e,t){try{const i=this.cleanApiEndpoint(t),n=await fetch(`${i}/sdk-remote-config-serve/`,{method:"GET",headers:{Accept:"application/json","deway-app-key":e,Origin:window?.location?.origin||""}});return n.ok?await n.json():null}catch{return null}}}class k{async executeSDK(e){return new Promise(t=>{try{if(!this.isDocumentReady()){t(!1);return}const i=document.createElement("script");i.textContent=e,i.type="text/javascript";let n=!1;const o=a=>{n||(n=!0,this.cleanupScript(i),t(a))};i.onerror=()=>{o(!1)},i.onload=()=>o(!0),document.head.appendChild(i),setTimeout(()=>{!n&&this.verifySDKLoaded()?o(!0):n||o(!1)},100)}catch{t(!1)}})}isDocumentReady(){return typeof document<"u"&&document.head!=null}verifySDKLoaded(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}cleanupScript(e){try{e.parentNode&&e.parentNode.removeChild(e)}catch{}}}class T{validateConfig(e){return!(!e||!e.appKey||e.appKey.trim().length===0||e.apiEndpoint!==void 0&&!this.isValidUrl(e.apiEndpoint)||e.publicKey!==void 0&&e.publicKey.trim().length===0)}isValidUrl(e){try{return new URL(e),!0}catch{return!1}}}const m={apiEndpoint:"https://service.deway.app",publicKey:"9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY="};class I{isLoaded=!1;isLoading=!1;cacheManager;scriptExecutor;commandQueue;sdkFetcher;configValidator;remoteConfigFetcher;remoteConfigCache;sdkConfigStore;constructor(){this.cacheManager=new s,this.scriptExecutor=new k,this.commandQueue=new g,this.sdkFetcher=new v,this.configValidator=new T,this.sdkConfigStore=new C,this.remoteConfigFetcher=new K,this.remoteConfigCache=new h}init(e){this.performInit(e).catch(t=>{})}async performInit(e){try{if(!this.canInitialize())return;const t=this.isInitializationPayload(e),i=t?e.localConfig:e;if(!this.configValidator.validateConfig(i))return;this.isLoading=!0;const n=i.apiEndpoint||m.apiEndpoint,o=i.publicKey||m.publicKey,[a,d]=await Promise.all([this.fetchOrLoadSDK(i.appKey,n,o),this.fetchRemoteConfigWithCache(i,n)]);if(!a)return;const y=t?e:this.createInitializationPayload(d,i);if(!await this.scriptExecutor.executeSDK(a.code)||!this.initializeSDK(y))return;this.commandQueue.replayQueuedCommands(),this.isLoaded=!0}finally{this.isLoading=!1}}isInitializationPayload(e){return"localConfig"in e&&"remoteConfig"in e&&"defaults"in e}canInitialize(){return!(this.isLoaded||this.isLoading)}async fetchRemoteConfigWithCache(e,t){this.sdkConfigStore.saveConfig(e);const i=await this.remoteConfigFetcher.fetchRemoteConfig(e.appKey,t);if(i)return await this.remoteConfigCache.cacheRemoteConfig(i.config,i.ttl_seconds),i;const n=await this.remoteConfigCache.getCachedRemoteConfig();return n?{config:n.config,ttl_seconds:n.ttl_seconds}:null}createInitializationPayload(e,t){return{localConfig:t,remoteConfig:e?.config??null,defaults:m}}async fetchOrLoadSDK(e,t,i){const n=await this.sdkFetcher.fetchSDK(e,t,i);return n?(await this.cacheManager.cacheSDK(n.code,n.version,n.checksum,n.signature),n):this.loadFromCache()}async loadFromCache(){const e=await this.cacheManager.getCachedSDK();return e?{code:e.code,version:e.version}:null}initializeSDK(e){if(!this.isSDKAvailable())return!1;try{return window.Deway?.init(e),!0}catch{return!1}}identify(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.identify(e):this.commandQueue.queueCommand("identify",e)}catch{}}reportEvent(e,t){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.reportEvent(e,t):this.commandQueue.queueCommand("reportEvent",e,t)}catch{}}setUserProfile(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.setUserProfile(e):this.commandQueue.queueCommand("setUserProfile",e)}catch{}}show(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.show(e):this.commandQueue.queueCommand("show",e)}catch{}}hide(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.hide():this.commandQueue.queueCommand("hide")}catch{}}isVisible(){try{return this.isLoaded&&this.isSDKAvailable()?window.Deway?.isVisible()??!1:!1}catch{return!1}}isInitialized(){try{return this.isLoaded&&this.isSDKAvailable()?window.Deway?.isInitialized()??!1:!1}catch{return!1}}destroy(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.destroy():this.commandQueue.queueCommand("destroy"),this.commandQueue.clearQueue()}catch{}}isSDKAvailable(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}}const c=new I,p={init:r=>c.init(r),identify:r=>c.identify(r),reportEvent:(r,e)=>c.reportEvent(r,e),setUserProfile:r=>c.setUserProfile(r),show:r=>c.show(r),hide:()=>c.hide(),isVisible:()=>c.isVisible(),isInitialized:()=>c.isInitialized(),destroy:()=>c.destroy()};return typeof window<"u"&&(window.Deway=p),p}));
|