@deway-ai/web-sdk 0.45.0 → 0.46.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 +108 -91
- package/dist/loader.umd.js +1 -1
- package/package.json +1 -1
package/dist/loader.es.js
CHANGED
|
@@ -30,11 +30,19 @@ class S {
|
|
|
30
30
|
getThinkingMessages() {
|
|
31
31
|
return this.loadConfig()?.thinkingMessages ?? p;
|
|
32
32
|
}
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Get the support handoff configuration
|
|
35
|
+
* @returns SupportHandoff config or null if not configured
|
|
36
|
+
*/
|
|
37
|
+
getSupportHandoff() {
|
|
38
|
+
return this.loadConfig()?.supportHandoff ?? null;
|
|
35
39
|
}
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Get the support handoff button text
|
|
42
|
+
* @returns Custom button text or default "talk to Support"
|
|
43
|
+
*/
|
|
44
|
+
getSupportHandoffButtonText() {
|
|
45
|
+
return this.getSupportHandoff()?.button_text ?? "talk to Support";
|
|
38
46
|
}
|
|
39
47
|
getFeatureFlags() {
|
|
40
48
|
return this.loadConfig()?.featureFlags ?? {};
|
|
@@ -66,33 +74,42 @@ class S {
|
|
|
66
74
|
const t = this.getTenantTheme();
|
|
67
75
|
return t ? e === "dark" ? t.dark : t.light : null;
|
|
68
76
|
}
|
|
77
|
+
getCustomIcons() {
|
|
78
|
+
return this.loadConfig()?.customIcons ?? null;
|
|
79
|
+
}
|
|
80
|
+
getBookmarkIconInlineSvg() {
|
|
81
|
+
return this.getCustomIcons()?.bookmark_icon_inline_svg ?? void 0;
|
|
82
|
+
}
|
|
83
|
+
getEmptyChatStateIconInlineSvg() {
|
|
84
|
+
return this.getCustomIcons()?.empty_chat_state_icon_inline_svg ?? void 0;
|
|
85
|
+
}
|
|
69
86
|
}
|
|
70
87
|
class s {
|
|
71
88
|
static CACHE_KEY = "deway-sdk-cache";
|
|
72
89
|
static DB_NAME = "DewaySdk";
|
|
73
90
|
static DB_VERSION = 1;
|
|
74
91
|
static STORE_NAME = "sdk";
|
|
75
|
-
async cacheSDK(e, t,
|
|
92
|
+
async cacheSDK(e, t, n, i) {
|
|
76
93
|
try {
|
|
77
94
|
const d = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readwrite").objectStore(s.STORE_NAME);
|
|
78
|
-
await new Promise((
|
|
95
|
+
await new Promise((f, m) => {
|
|
79
96
|
const l = d.put({
|
|
80
97
|
id: "latest",
|
|
81
98
|
code: e,
|
|
82
99
|
version: t,
|
|
83
|
-
checksum:
|
|
84
|
-
signature:
|
|
100
|
+
checksum: n,
|
|
101
|
+
signature: i,
|
|
85
102
|
timestamp: Date.now()
|
|
86
103
|
});
|
|
87
|
-
l.onsuccess = () =>
|
|
104
|
+
l.onsuccess = () => f(l.result), l.onerror = () => m(l.error);
|
|
88
105
|
});
|
|
89
106
|
} catch {
|
|
90
107
|
try {
|
|
91
108
|
const a = JSON.stringify({
|
|
92
109
|
code: e,
|
|
93
110
|
version: t,
|
|
94
|
-
checksum:
|
|
95
|
-
signature:
|
|
111
|
+
checksum: n,
|
|
112
|
+
signature: i,
|
|
96
113
|
timestamp: Date.now()
|
|
97
114
|
});
|
|
98
115
|
localStorage.setItem(s.CACHE_KEY, a);
|
|
@@ -102,12 +119,12 @@ class s {
|
|
|
102
119
|
}
|
|
103
120
|
async getCachedSDK() {
|
|
104
121
|
try {
|
|
105
|
-
const
|
|
106
|
-
const d =
|
|
107
|
-
d.onsuccess = () =>
|
|
122
|
+
const n = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readonly").objectStore(s.STORE_NAME), i = await new Promise((r, a) => {
|
|
123
|
+
const d = n.get("latest");
|
|
124
|
+
d.onsuccess = () => r(d.result || null), d.onerror = () => a(d.error);
|
|
108
125
|
});
|
|
109
|
-
if (
|
|
110
|
-
return
|
|
126
|
+
if (i)
|
|
127
|
+
return i;
|
|
111
128
|
} catch {
|
|
112
129
|
}
|
|
113
130
|
try {
|
|
@@ -120,53 +137,53 @@ class s {
|
|
|
120
137
|
}
|
|
121
138
|
openIndexedDB() {
|
|
122
139
|
return new Promise((e, t) => {
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
|
|
140
|
+
const n = indexedDB.open(s.DB_NAME, s.DB_VERSION);
|
|
141
|
+
n.onerror = () => t(n.error), n.onsuccess = () => e(n.result), n.onupgradeneeded = (i) => {
|
|
142
|
+
const r = i.target.result;
|
|
143
|
+
r.objectStoreNames.contains(s.STORE_NAME) || r.createObjectStore(s.STORE_NAME, { keyPath: "id" });
|
|
127
144
|
};
|
|
128
145
|
});
|
|
129
146
|
}
|
|
130
147
|
}
|
|
131
|
-
async function C(
|
|
132
|
-
const t = new TextEncoder().encode(
|
|
133
|
-
return Array.from(new Uint8Array(
|
|
148
|
+
async function C(o) {
|
|
149
|
+
const t = new TextEncoder().encode(o), n = await crypto.subtle.digest("SHA-256", t);
|
|
150
|
+
return Array.from(new Uint8Array(n)).map((r) => r.toString(16).padStart(2, "0")).join("");
|
|
134
151
|
}
|
|
135
|
-
function w(
|
|
136
|
-
const e = atob(
|
|
137
|
-
for (let
|
|
138
|
-
t[
|
|
152
|
+
function w(o) {
|
|
153
|
+
const e = atob(o), t = new Uint8Array(e.length);
|
|
154
|
+
for (let n = 0; n < e.length; n++)
|
|
155
|
+
t[n] = e.charCodeAt(n);
|
|
139
156
|
return t;
|
|
140
157
|
}
|
|
141
|
-
function E(
|
|
142
|
-
const e = new Uint8Array(
|
|
143
|
-
for (let t = 0; t <
|
|
144
|
-
e[t / 2] = Number.parseInt(
|
|
158
|
+
function E(o) {
|
|
159
|
+
const e = new Uint8Array(o.length / 2);
|
|
160
|
+
for (let t = 0; t < o.length; t += 2)
|
|
161
|
+
e[t / 2] = Number.parseInt(o.substr(t, 2), 16);
|
|
145
162
|
return e;
|
|
146
163
|
}
|
|
147
|
-
async function D(
|
|
164
|
+
async function D(o, e, t) {
|
|
148
165
|
try {
|
|
149
|
-
const
|
|
150
|
-
return await crypto.subtle.verify("Ed25519", a,
|
|
166
|
+
const n = w(o), i = E(e), r = w(t), a = await crypto.subtle.importKey("raw", n, { name: "Ed25519" }, !1, ["verify"]);
|
|
167
|
+
return await crypto.subtle.verify("Ed25519", a, r, i);
|
|
151
168
|
} catch {
|
|
152
169
|
return !1;
|
|
153
170
|
}
|
|
154
171
|
}
|
|
155
|
-
async function
|
|
172
|
+
async function v(o, e, t, n) {
|
|
156
173
|
if (!e || !t)
|
|
157
174
|
throw new Error("SDK verification failed: Missing security headers");
|
|
158
|
-
if (await C(
|
|
175
|
+
if (await C(o) !== e)
|
|
159
176
|
throw new Error("SDK verification failed: Checksum mismatch - content tampered");
|
|
160
|
-
if (!await D(
|
|
177
|
+
if (!await D(n, e, t))
|
|
161
178
|
throw new Error("SDK verification failed: Invalid signature - content tampered");
|
|
162
179
|
}
|
|
163
|
-
class
|
|
180
|
+
class A {
|
|
164
181
|
cleanApiEndpoint(e) {
|
|
165
182
|
return e.trim().replace(/\/+$/, "");
|
|
166
183
|
}
|
|
167
|
-
async fetchSDK(e, t,
|
|
184
|
+
async fetchSDK(e, t, n) {
|
|
168
185
|
try {
|
|
169
|
-
const
|
|
186
|
+
const i = this.cleanApiEndpoint(t), r = await fetch(`${i}/sdk-serve/sdk/v0`, {
|
|
170
187
|
method: "GET",
|
|
171
188
|
headers: {
|
|
172
189
|
Accept: "application/javascript",
|
|
@@ -174,16 +191,16 @@ class b {
|
|
|
174
191
|
Origin: window?.location?.origin || ""
|
|
175
192
|
}
|
|
176
193
|
});
|
|
177
|
-
return
|
|
194
|
+
return r.ok ? this.handleSuccessfulFetch(r, n) : null;
|
|
178
195
|
} catch {
|
|
179
196
|
return null;
|
|
180
197
|
}
|
|
181
198
|
}
|
|
182
199
|
async handleSuccessfulFetch(e, t) {
|
|
183
|
-
const
|
|
184
|
-
if (!
|
|
200
|
+
const n = e.headers.get("x-sdk-checksum"), i = e.headers.get("x-sdk-version"), r = e.headers.get("x-sdk-signature"), a = await e.text();
|
|
201
|
+
if (!i || !a || !n)
|
|
185
202
|
throw Object.fromEntries(e.headers.entries()), new Error("Invalid SDK response: missing version, code, or checksum");
|
|
186
|
-
return await
|
|
203
|
+
return await v(a, n, r, t), { code: a, version: i, checksum: n, signature: r || "" };
|
|
187
204
|
}
|
|
188
205
|
}
|
|
189
206
|
class g {
|
|
@@ -208,8 +225,8 @@ class g {
|
|
|
208
225
|
}
|
|
209
226
|
replayCommand(e) {
|
|
210
227
|
try {
|
|
211
|
-
const t = window.Deway,
|
|
212
|
-
typeof
|
|
228
|
+
const t = window.Deway, n = t?.[e.method];
|
|
229
|
+
typeof n == "function" && n.apply(t, e.args);
|
|
213
230
|
} catch {
|
|
214
231
|
}
|
|
215
232
|
}
|
|
@@ -225,12 +242,12 @@ class u {
|
|
|
225
242
|
*/
|
|
226
243
|
async cacheRemoteConfig(e, t) {
|
|
227
244
|
try {
|
|
228
|
-
const
|
|
245
|
+
const n = {
|
|
229
246
|
config: e,
|
|
230
247
|
ttl_seconds: t,
|
|
231
248
|
timestamp: Date.now()
|
|
232
249
|
};
|
|
233
|
-
localStorage.setItem(u.CACHE_KEY, JSON.stringify(
|
|
250
|
+
localStorage.setItem(u.CACHE_KEY, JSON.stringify(n));
|
|
234
251
|
} catch {
|
|
235
252
|
}
|
|
236
253
|
}
|
|
@@ -257,11 +274,11 @@ class u {
|
|
|
257
274
|
* @returns true if cache is still valid
|
|
258
275
|
*/
|
|
259
276
|
isCacheValid(e, t) {
|
|
260
|
-
const
|
|
261
|
-
return
|
|
277
|
+
const n = Date.now(), i = e + t * 1e3;
|
|
278
|
+
return n < i;
|
|
262
279
|
}
|
|
263
280
|
}
|
|
264
|
-
class
|
|
281
|
+
class b {
|
|
265
282
|
cleanApiEndpoint(e) {
|
|
266
283
|
return e.trim().replace(/\/+$/, "");
|
|
267
284
|
}
|
|
@@ -275,7 +292,7 @@ class v {
|
|
|
275
292
|
*/
|
|
276
293
|
async fetchRemoteConfig(e, t) {
|
|
277
294
|
try {
|
|
278
|
-
const
|
|
295
|
+
const n = this.cleanApiEndpoint(t), i = await fetch(`${n}/sdk-remote-config-serve/`, {
|
|
279
296
|
method: "GET",
|
|
280
297
|
headers: {
|
|
281
298
|
Accept: "application/json",
|
|
@@ -283,13 +300,13 @@ class v {
|
|
|
283
300
|
Origin: window?.location?.origin || ""
|
|
284
301
|
}
|
|
285
302
|
});
|
|
286
|
-
return
|
|
303
|
+
return i.ok ? await i.json() : null;
|
|
287
304
|
} catch {
|
|
288
305
|
return null;
|
|
289
306
|
}
|
|
290
307
|
}
|
|
291
308
|
}
|
|
292
|
-
class
|
|
309
|
+
class I {
|
|
293
310
|
async executeSDK(e) {
|
|
294
311
|
return new Promise((t) => {
|
|
295
312
|
try {
|
|
@@ -297,16 +314,16 @@ class K {
|
|
|
297
314
|
t(!1);
|
|
298
315
|
return;
|
|
299
316
|
}
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
let
|
|
303
|
-
const
|
|
304
|
-
|
|
317
|
+
const n = document.createElement("script");
|
|
318
|
+
n.textContent = e, n.type = "text/javascript";
|
|
319
|
+
let i = !1;
|
|
320
|
+
const r = (a) => {
|
|
321
|
+
i || (i = !0, this.cleanupScript(n), t(a));
|
|
305
322
|
};
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
},
|
|
309
|
-
!
|
|
323
|
+
n.onerror = () => {
|
|
324
|
+
r(!1);
|
|
325
|
+
}, n.onload = () => r(!0), document.head.appendChild(n), setTimeout(() => {
|
|
326
|
+
!i && this.verifySDKLoaded() ? r(!0) : i || r(!1);
|
|
310
327
|
}, 100);
|
|
311
328
|
} catch {
|
|
312
329
|
t(!1);
|
|
@@ -326,7 +343,7 @@ class K {
|
|
|
326
343
|
}
|
|
327
344
|
}
|
|
328
345
|
}
|
|
329
|
-
class
|
|
346
|
+
class K {
|
|
330
347
|
validateConfig(e) {
|
|
331
348
|
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);
|
|
332
349
|
}
|
|
@@ -338,11 +355,11 @@ class k {
|
|
|
338
355
|
}
|
|
339
356
|
}
|
|
340
357
|
}
|
|
341
|
-
const
|
|
358
|
+
const h = {
|
|
342
359
|
apiEndpoint: "https://service.deway.app",
|
|
343
360
|
publicKey: "9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY="
|
|
344
361
|
};
|
|
345
|
-
class
|
|
362
|
+
class k {
|
|
346
363
|
isLoaded = !1;
|
|
347
364
|
isLoading = !1;
|
|
348
365
|
cacheManager;
|
|
@@ -354,7 +371,7 @@ class I {
|
|
|
354
371
|
remoteConfigCache;
|
|
355
372
|
sdkConfigStore;
|
|
356
373
|
constructor() {
|
|
357
|
-
this.cacheManager = new s(), this.scriptExecutor = new
|
|
374
|
+
this.cacheManager = new s(), this.scriptExecutor = new I(), this.commandQueue = new g(), this.sdkFetcher = new A(), this.configValidator = new K(), this.sdkConfigStore = new S(), this.remoteConfigFetcher = new b(), this.remoteConfigCache = new u();
|
|
358
375
|
}
|
|
359
376
|
init(e) {
|
|
360
377
|
this.performInit(e).catch((t) => {
|
|
@@ -364,15 +381,15 @@ class I {
|
|
|
364
381
|
try {
|
|
365
382
|
if (!this.canInitialize())
|
|
366
383
|
return;
|
|
367
|
-
const t = this.isInitializationPayload(e),
|
|
368
|
-
if (!this.configValidator.validateConfig(
|
|
384
|
+
const t = this.isInitializationPayload(e), n = t ? e.localConfig : e;
|
|
385
|
+
if (!this.configValidator.validateConfig(n))
|
|
369
386
|
return;
|
|
370
387
|
this.isLoading = !0;
|
|
371
|
-
const
|
|
388
|
+
const i = n.apiEndpoint || h.apiEndpoint, r = n.publicKey || h.publicKey, [a, d] = await Promise.all([this.fetchOrLoadSDK(n.appKey, i, r), this.fetchRemoteConfigWithCache(n, i)]);
|
|
372
389
|
if (!a)
|
|
373
390
|
return;
|
|
374
|
-
const
|
|
375
|
-
if (!await this.scriptExecutor.executeSDK(a.code) || !this.initializeSDK(
|
|
391
|
+
const f = t ? e : this.createInitializationPayload(d, n);
|
|
392
|
+
if (!await this.scriptExecutor.executeSDK(a.code) || !this.initializeSDK(f))
|
|
376
393
|
return;
|
|
377
394
|
this.commandQueue.replayQueuedCommands(), this.isLoaded = !0;
|
|
378
395
|
} finally {
|
|
@@ -391,13 +408,13 @@ class I {
|
|
|
391
408
|
*/
|
|
392
409
|
async fetchRemoteConfigWithCache(e, t) {
|
|
393
410
|
this.sdkConfigStore.saveConfig(e);
|
|
394
|
-
const
|
|
395
|
-
if (
|
|
396
|
-
return await this.remoteConfigCache.cacheRemoteConfig(
|
|
397
|
-
const
|
|
398
|
-
return
|
|
399
|
-
config:
|
|
400
|
-
ttl_seconds:
|
|
411
|
+
const n = await this.remoteConfigFetcher.fetchRemoteConfig(e.appKey, t);
|
|
412
|
+
if (n)
|
|
413
|
+
return await this.remoteConfigCache.cacheRemoteConfig(n.config, n.ttl_seconds), n;
|
|
414
|
+
const i = await this.remoteConfigCache.getCachedRemoteConfig();
|
|
415
|
+
return i ? {
|
|
416
|
+
config: i.config,
|
|
417
|
+
ttl_seconds: i.ttl_seconds
|
|
401
418
|
} : null;
|
|
402
419
|
}
|
|
403
420
|
/**
|
|
@@ -409,12 +426,12 @@ class I {
|
|
|
409
426
|
return {
|
|
410
427
|
localConfig: t,
|
|
411
428
|
remoteConfig: e?.config ?? null,
|
|
412
|
-
defaults:
|
|
429
|
+
defaults: h
|
|
413
430
|
};
|
|
414
431
|
}
|
|
415
|
-
async fetchOrLoadSDK(e, t,
|
|
416
|
-
const
|
|
417
|
-
return
|
|
432
|
+
async fetchOrLoadSDK(e, t, n) {
|
|
433
|
+
const i = await this.sdkFetcher.fetchSDK(e, t, n);
|
|
434
|
+
return i ? (await this.cacheManager.cacheSDK(i.code, i.version, i.checksum, i.signature), i) : this.loadFromCache();
|
|
418
435
|
}
|
|
419
436
|
async loadFromCache() {
|
|
420
437
|
const e = await this.cacheManager.getCachedSDK();
|
|
@@ -483,18 +500,18 @@ class I {
|
|
|
483
500
|
return typeof window < "u" && "Deway" in window && !!window.Deway;
|
|
484
501
|
}
|
|
485
502
|
}
|
|
486
|
-
const c = new
|
|
487
|
-
init: (
|
|
488
|
-
identify: (
|
|
489
|
-
reportEvent: (
|
|
490
|
-
setUserProfile: (
|
|
491
|
-
show: (
|
|
503
|
+
const c = new k(), x = {
|
|
504
|
+
init: (o) => c.init(o),
|
|
505
|
+
identify: (o) => c.identify(o),
|
|
506
|
+
reportEvent: (o, e) => c.reportEvent(o, e),
|
|
507
|
+
setUserProfile: (o) => c.setUserProfile(o),
|
|
508
|
+
show: (o) => c.show(o),
|
|
492
509
|
hide: () => c.hide(),
|
|
493
510
|
isVisible: () => c.isVisible(),
|
|
494
511
|
isInitialized: () => c.isInitialized(),
|
|
495
512
|
destroy: () => c.destroy()
|
|
496
513
|
};
|
|
497
|
-
typeof window < "u" && (window.Deway =
|
|
514
|
+
typeof window < "u" && (window.Deway = x);
|
|
498
515
|
export {
|
|
499
|
-
|
|
516
|
+
x as default
|
|
500
517
|
};
|
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}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}));
|
|
1
|
+
(function(u,l){typeof exports=="object"&&typeof module<"u"?module.exports=l():typeof define=="function"&&define.amd?define(l):(u=typeof globalThis<"u"?globalThis:u||self,u.Deway=l())})(this,(function(){"use strict";const u="deway-sdk-config",l=["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(u,t)}catch{}}loadConfig(){if(window?.localStorage)try{const e=window.localStorage.getItem(u);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??l}getSupportHandoff(){return this.loadConfig()?.supportHandoff??null}getSupportHandoffButtonText(){return this.getSupportHandoff()?.button_text??"talk to Support"}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}getCustomIcons(){return this.loadConfig()?.customIcons??null}getBookmarkIconInlineSvg(){return this.getCustomIcons()?.bookmark_icon_inline_svg??void 0}getEmptyChatStateIconInlineSvg(){return this.getCustomIcons()?.empty_chat_state_icon_inline_svg??void 0}}class s{static CACHE_KEY="deway-sdk-cache";static DB_NAME="DewaySdk";static DB_VERSION=1;static STORE_NAME="sdk";async cacheSDK(e,t,n,i){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:n,signature:i,timestamp:Date.now()});f.onsuccess=()=>y(f.result),f.onerror=()=>S(f.error)})}catch{try{const a=JSON.stringify({code:e,version:t,checksum:n,signature:i,timestamp:Date.now()});localStorage.setItem(s.CACHE_KEY,a)}catch{}}}async getCachedSDK(){try{const n=(await this.openIndexedDB()).transaction([s.STORE_NAME],"readonly").objectStore(s.STORE_NAME),i=await new Promise((r,a)=>{const d=n.get("latest");d.onsuccess=()=>r(d.result||null),d.onerror=()=>a(d.error)});if(i)return i}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 n=indexedDB.open(s.DB_NAME,s.DB_VERSION);n.onerror=()=>t(n.error),n.onsuccess=()=>e(n.result),n.onupgradeneeded=i=>{const r=i.target.result;r.objectStoreNames.contains(s.STORE_NAME)||r.createObjectStore(s.STORE_NAME,{keyPath:"id"})}})}}async function E(o){const t=new TextEncoder().encode(o),n=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(n)).map(r=>r.toString(16).padStart(2,"0")).join("")}function w(o){const e=atob(o),t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n);return t}function D(o){const e=new Uint8Array(o.length/2);for(let t=0;t<o.length;t+=2)e[t/2]=Number.parseInt(o.substr(t,2),16);return e}async function v(o,e,t){try{const n=w(o),i=D(e),r=w(t),a=await crypto.subtle.importKey("raw",n,{name:"Ed25519"},!1,["verify"]);return await crypto.subtle.verify("Ed25519",a,r,i)}catch{return!1}}async function A(o,e,t,n){if(!e||!t)throw new Error("SDK verification failed: Missing security headers");if(await E(o)!==e)throw new Error("SDK verification failed: Checksum mismatch - content tampered");if(!await v(n,e,t))throw new Error("SDK verification failed: Invalid signature - content tampered")}class b{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchSDK(e,t,n){try{const i=this.cleanApiEndpoint(t),r=await fetch(`${i}/sdk-serve/sdk/v0`,{method:"GET",headers:{Accept:"application/javascript","deway-app-key":e,Origin:window?.location?.origin||""}});return r.ok?this.handleSuccessfulFetch(r,n):null}catch{return null}}async handleSuccessfulFetch(e,t){const n=e.headers.get("x-sdk-checksum"),i=e.headers.get("x-sdk-version"),r=e.headers.get("x-sdk-signature"),a=await e.text();if(!i||!a||!n)throw Object.fromEntries(e.headers.entries()),new Error("Invalid SDK response: missing version, code, or checksum");return await A(a,n,r,t),{code:a,version:i,checksum:n,signature:r||""}}}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,n=t?.[e.method];typeof n=="function"&&n.apply(t,e.args)}catch{}}}class h{static CACHE_KEY="deway-remote-config-cache";async cacheRemoteConfig(e,t){try{const n={config:e,ttl_seconds:t,timestamp:Date.now()};localStorage.setItem(h.CACHE_KEY,JSON.stringify(n))}catch{}}async getCachedRemoteConfig(){try{const e=localStorage.getItem(h.CACHE_KEY);return e?JSON.parse(e):null}catch{return null}}isCacheValid(e,t){const n=Date.now(),i=e+t*1e3;return n<i}}class I{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchRemoteConfig(e,t){try{const n=this.cleanApiEndpoint(t),i=await fetch(`${n}/sdk-remote-config-serve/`,{method:"GET",headers:{Accept:"application/json","deway-app-key":e,Origin:window?.location?.origin||""}});return i.ok?await i.json():null}catch{return null}}}class K{async executeSDK(e){return new Promise(t=>{try{if(!this.isDocumentReady()){t(!1);return}const n=document.createElement("script");n.textContent=e,n.type="text/javascript";let i=!1;const r=a=>{i||(i=!0,this.cleanupScript(n),t(a))};n.onerror=()=>{r(!1)},n.onload=()=>r(!0),document.head.appendChild(n),setTimeout(()=>{!i&&this.verifySDKLoaded()?r(!0):i||r(!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 k{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 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 g,this.sdkFetcher=new b,this.configValidator=new k,this.sdkConfigStore=new C,this.remoteConfigFetcher=new I,this.remoteConfigCache=new h}init(e){this.performInit(e).catch(t=>{})}async performInit(e){try{if(!this.canInitialize())return;const t=this.isInitializationPayload(e),n=t?e.localConfig:e;if(!this.configValidator.validateConfig(n))return;this.isLoading=!0;const i=n.apiEndpoint||m.apiEndpoint,r=n.publicKey||m.publicKey,[a,d]=await Promise.all([this.fetchOrLoadSDK(n.appKey,i,r),this.fetchRemoteConfigWithCache(n,i)]);if(!a)return;const y=t?e:this.createInitializationPayload(d,n);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 n=await this.remoteConfigFetcher.fetchRemoteConfig(e.appKey,t);if(n)return await this.remoteConfigCache.cacheRemoteConfig(n.config,n.ttl_seconds),n;const i=await this.remoteConfigCache.getCachedRemoteConfig();return i?{config:i.config,ttl_seconds:i.ttl_seconds}:null}createInitializationPayload(e,t){return{localConfig:t,remoteConfig:e?.config??null,defaults:m}}async fetchOrLoadSDK(e,t,n){const i=await this.sdkFetcher.fetchSDK(e,t,n);return i?(await this.cacheManager.cacheSDK(i.code,i.version,i.checksum,i.signature),i):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:o=>c.init(o),identify:o=>c.identify(o),reportEvent:(o,e)=>c.reportEvent(o,e),setUserProfile:o=>c.setUserProfile(o),show:o=>c.show(o),hide:()=>c.hide(),isVisible:()=>c.isVisible(),isInitialized:()=>c.isInitialized(),destroy:()=>c.destroy()};return typeof window<"u"&&(window.Deway=p),p}));
|