@deway-ai/web-sdk 0.44.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 +117 -94
- 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 ?? {};
|
|
@@ -45,6 +53,12 @@ class S {
|
|
|
45
53
|
getPromptSuggestions() {
|
|
46
54
|
return this.loadConfig()?.promptSuggestions;
|
|
47
55
|
}
|
|
56
|
+
getWelcomeTitle() {
|
|
57
|
+
return this.loadConfig()?.welcomeTitle ?? "How can I help you today?";
|
|
58
|
+
}
|
|
59
|
+
getWelcomeSubtitle() {
|
|
60
|
+
return this.loadConfig()?.welcomeSubtitle ?? "I'm ready to help you navigate, learn, and get things done.";
|
|
61
|
+
}
|
|
48
62
|
getBookmarkAppearanceMode() {
|
|
49
63
|
return this.loadConfig()?.bookmarkAppearanceMode ?? "bookmark";
|
|
50
64
|
}
|
|
@@ -60,48 +74,57 @@ class S {
|
|
|
60
74
|
const t = this.getTenantTheme();
|
|
61
75
|
return t ? e === "dark" ? t.dark : t.light : null;
|
|
62
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
|
+
}
|
|
63
86
|
}
|
|
64
87
|
class s {
|
|
65
88
|
static CACHE_KEY = "deway-sdk-cache";
|
|
66
89
|
static DB_NAME = "DewaySdk";
|
|
67
90
|
static DB_VERSION = 1;
|
|
68
91
|
static STORE_NAME = "sdk";
|
|
69
|
-
async cacheSDK(e, t,
|
|
92
|
+
async cacheSDK(e, t, n, i) {
|
|
70
93
|
try {
|
|
71
94
|
const d = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readwrite").objectStore(s.STORE_NAME);
|
|
72
|
-
await new Promise((
|
|
95
|
+
await new Promise((f, m) => {
|
|
73
96
|
const l = d.put({
|
|
74
97
|
id: "latest",
|
|
75
98
|
code: e,
|
|
76
99
|
version: t,
|
|
77
|
-
checksum:
|
|
78
|
-
signature:
|
|
100
|
+
checksum: n,
|
|
101
|
+
signature: i,
|
|
79
102
|
timestamp: Date.now()
|
|
80
103
|
});
|
|
81
|
-
l.onsuccess = () =>
|
|
104
|
+
l.onsuccess = () => f(l.result), l.onerror = () => m(l.error);
|
|
82
105
|
});
|
|
83
106
|
} catch {
|
|
84
107
|
try {
|
|
85
|
-
const
|
|
108
|
+
const a = JSON.stringify({
|
|
86
109
|
code: e,
|
|
87
110
|
version: t,
|
|
88
|
-
checksum:
|
|
89
|
-
signature:
|
|
111
|
+
checksum: n,
|
|
112
|
+
signature: i,
|
|
90
113
|
timestamp: Date.now()
|
|
91
114
|
});
|
|
92
|
-
localStorage.setItem(s.CACHE_KEY,
|
|
115
|
+
localStorage.setItem(s.CACHE_KEY, a);
|
|
93
116
|
} catch {
|
|
94
117
|
}
|
|
95
118
|
}
|
|
96
119
|
}
|
|
97
120
|
async getCachedSDK() {
|
|
98
121
|
try {
|
|
99
|
-
const
|
|
100
|
-
const d =
|
|
101
|
-
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);
|
|
102
125
|
});
|
|
103
|
-
if (
|
|
104
|
-
return
|
|
126
|
+
if (i)
|
|
127
|
+
return i;
|
|
105
128
|
} catch {
|
|
106
129
|
}
|
|
107
130
|
try {
|
|
@@ -114,53 +137,53 @@ class s {
|
|
|
114
137
|
}
|
|
115
138
|
openIndexedDB() {
|
|
116
139
|
return new Promise((e, t) => {
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
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" });
|
|
121
144
|
};
|
|
122
145
|
});
|
|
123
146
|
}
|
|
124
147
|
}
|
|
125
|
-
async function C(
|
|
126
|
-
const t = new TextEncoder().encode(
|
|
127
|
-
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("");
|
|
128
151
|
}
|
|
129
|
-
function w(
|
|
130
|
-
const e = atob(
|
|
131
|
-
for (let
|
|
132
|
-
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);
|
|
133
156
|
return t;
|
|
134
157
|
}
|
|
135
|
-
function E(
|
|
136
|
-
const e = new Uint8Array(
|
|
137
|
-
for (let t = 0; t <
|
|
138
|
-
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);
|
|
139
162
|
return e;
|
|
140
163
|
}
|
|
141
|
-
async function D(
|
|
164
|
+
async function D(o, e, t) {
|
|
142
165
|
try {
|
|
143
|
-
const
|
|
144
|
-
return await crypto.subtle.verify("Ed25519",
|
|
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);
|
|
145
168
|
} catch {
|
|
146
169
|
return !1;
|
|
147
170
|
}
|
|
148
171
|
}
|
|
149
|
-
async function
|
|
172
|
+
async function v(o, e, t, n) {
|
|
150
173
|
if (!e || !t)
|
|
151
174
|
throw new Error("SDK verification failed: Missing security headers");
|
|
152
|
-
if (await C(
|
|
175
|
+
if (await C(o) !== e)
|
|
153
176
|
throw new Error("SDK verification failed: Checksum mismatch - content tampered");
|
|
154
|
-
if (!await D(
|
|
177
|
+
if (!await D(n, e, t))
|
|
155
178
|
throw new Error("SDK verification failed: Invalid signature - content tampered");
|
|
156
179
|
}
|
|
157
|
-
class
|
|
180
|
+
class A {
|
|
158
181
|
cleanApiEndpoint(e) {
|
|
159
182
|
return e.trim().replace(/\/+$/, "");
|
|
160
183
|
}
|
|
161
|
-
async fetchSDK(e, t,
|
|
184
|
+
async fetchSDK(e, t, n) {
|
|
162
185
|
try {
|
|
163
|
-
const
|
|
186
|
+
const i = this.cleanApiEndpoint(t), r = await fetch(`${i}/sdk-serve/sdk/v0`, {
|
|
164
187
|
method: "GET",
|
|
165
188
|
headers: {
|
|
166
189
|
Accept: "application/javascript",
|
|
@@ -168,16 +191,16 @@ class b {
|
|
|
168
191
|
Origin: window?.location?.origin || ""
|
|
169
192
|
}
|
|
170
193
|
});
|
|
171
|
-
return
|
|
194
|
+
return r.ok ? this.handleSuccessfulFetch(r, n) : null;
|
|
172
195
|
} catch {
|
|
173
196
|
return null;
|
|
174
197
|
}
|
|
175
198
|
}
|
|
176
199
|
async handleSuccessfulFetch(e, t) {
|
|
177
|
-
const
|
|
178
|
-
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)
|
|
179
202
|
throw Object.fromEntries(e.headers.entries()), new Error("Invalid SDK response: missing version, code, or checksum");
|
|
180
|
-
return await
|
|
203
|
+
return await v(a, n, r, t), { code: a, version: i, checksum: n, signature: r || "" };
|
|
181
204
|
}
|
|
182
205
|
}
|
|
183
206
|
class g {
|
|
@@ -202,8 +225,8 @@ class g {
|
|
|
202
225
|
}
|
|
203
226
|
replayCommand(e) {
|
|
204
227
|
try {
|
|
205
|
-
const t = window.Deway,
|
|
206
|
-
typeof
|
|
228
|
+
const t = window.Deway, n = t?.[e.method];
|
|
229
|
+
typeof n == "function" && n.apply(t, e.args);
|
|
207
230
|
} catch {
|
|
208
231
|
}
|
|
209
232
|
}
|
|
@@ -219,12 +242,12 @@ class u {
|
|
|
219
242
|
*/
|
|
220
243
|
async cacheRemoteConfig(e, t) {
|
|
221
244
|
try {
|
|
222
|
-
const
|
|
245
|
+
const n = {
|
|
223
246
|
config: e,
|
|
224
247
|
ttl_seconds: t,
|
|
225
248
|
timestamp: Date.now()
|
|
226
249
|
};
|
|
227
|
-
localStorage.setItem(u.CACHE_KEY, JSON.stringify(
|
|
250
|
+
localStorage.setItem(u.CACHE_KEY, JSON.stringify(n));
|
|
228
251
|
} catch {
|
|
229
252
|
}
|
|
230
253
|
}
|
|
@@ -251,11 +274,11 @@ class u {
|
|
|
251
274
|
* @returns true if cache is still valid
|
|
252
275
|
*/
|
|
253
276
|
isCacheValid(e, t) {
|
|
254
|
-
const
|
|
255
|
-
return
|
|
277
|
+
const n = Date.now(), i = e + t * 1e3;
|
|
278
|
+
return n < i;
|
|
256
279
|
}
|
|
257
280
|
}
|
|
258
|
-
class
|
|
281
|
+
class b {
|
|
259
282
|
cleanApiEndpoint(e) {
|
|
260
283
|
return e.trim().replace(/\/+$/, "");
|
|
261
284
|
}
|
|
@@ -269,7 +292,7 @@ class v {
|
|
|
269
292
|
*/
|
|
270
293
|
async fetchRemoteConfig(e, t) {
|
|
271
294
|
try {
|
|
272
|
-
const
|
|
295
|
+
const n = this.cleanApiEndpoint(t), i = await fetch(`${n}/sdk-remote-config-serve/`, {
|
|
273
296
|
method: "GET",
|
|
274
297
|
headers: {
|
|
275
298
|
Accept: "application/json",
|
|
@@ -277,13 +300,13 @@ class v {
|
|
|
277
300
|
Origin: window?.location?.origin || ""
|
|
278
301
|
}
|
|
279
302
|
});
|
|
280
|
-
return
|
|
303
|
+
return i.ok ? await i.json() : null;
|
|
281
304
|
} catch {
|
|
282
305
|
return null;
|
|
283
306
|
}
|
|
284
307
|
}
|
|
285
308
|
}
|
|
286
|
-
class
|
|
309
|
+
class I {
|
|
287
310
|
async executeSDK(e) {
|
|
288
311
|
return new Promise((t) => {
|
|
289
312
|
try {
|
|
@@ -291,16 +314,16 @@ class K {
|
|
|
291
314
|
t(!1);
|
|
292
315
|
return;
|
|
293
316
|
}
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
let
|
|
297
|
-
const
|
|
298
|
-
|
|
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));
|
|
299
322
|
};
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
},
|
|
303
|
-
!
|
|
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);
|
|
304
327
|
}, 100);
|
|
305
328
|
} catch {
|
|
306
329
|
t(!1);
|
|
@@ -320,7 +343,7 @@ class K {
|
|
|
320
343
|
}
|
|
321
344
|
}
|
|
322
345
|
}
|
|
323
|
-
class
|
|
346
|
+
class K {
|
|
324
347
|
validateConfig(e) {
|
|
325
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);
|
|
326
349
|
}
|
|
@@ -332,11 +355,11 @@ class k {
|
|
|
332
355
|
}
|
|
333
356
|
}
|
|
334
357
|
}
|
|
335
|
-
const
|
|
358
|
+
const h = {
|
|
336
359
|
apiEndpoint: "https://service.deway.app",
|
|
337
360
|
publicKey: "9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY="
|
|
338
361
|
};
|
|
339
|
-
class
|
|
362
|
+
class k {
|
|
340
363
|
isLoaded = !1;
|
|
341
364
|
isLoading = !1;
|
|
342
365
|
cacheManager;
|
|
@@ -348,7 +371,7 @@ class I {
|
|
|
348
371
|
remoteConfigCache;
|
|
349
372
|
sdkConfigStore;
|
|
350
373
|
constructor() {
|
|
351
|
-
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();
|
|
352
375
|
}
|
|
353
376
|
init(e) {
|
|
354
377
|
this.performInit(e).catch((t) => {
|
|
@@ -358,15 +381,15 @@ class I {
|
|
|
358
381
|
try {
|
|
359
382
|
if (!this.canInitialize())
|
|
360
383
|
return;
|
|
361
|
-
const t = this.isInitializationPayload(e),
|
|
362
|
-
if (!this.configValidator.validateConfig(
|
|
384
|
+
const t = this.isInitializationPayload(e), n = t ? e.localConfig : e;
|
|
385
|
+
if (!this.configValidator.validateConfig(n))
|
|
363
386
|
return;
|
|
364
387
|
this.isLoading = !0;
|
|
365
|
-
const
|
|
366
|
-
if (!
|
|
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)]);
|
|
389
|
+
if (!a)
|
|
367
390
|
return;
|
|
368
|
-
const
|
|
369
|
-
if (!await this.scriptExecutor.executeSDK(
|
|
391
|
+
const f = t ? e : this.createInitializationPayload(d, n);
|
|
392
|
+
if (!await this.scriptExecutor.executeSDK(a.code) || !this.initializeSDK(f))
|
|
370
393
|
return;
|
|
371
394
|
this.commandQueue.replayQueuedCommands(), this.isLoaded = !0;
|
|
372
395
|
} finally {
|
|
@@ -385,13 +408,13 @@ class I {
|
|
|
385
408
|
*/
|
|
386
409
|
async fetchRemoteConfigWithCache(e, t) {
|
|
387
410
|
this.sdkConfigStore.saveConfig(e);
|
|
388
|
-
const
|
|
389
|
-
if (
|
|
390
|
-
return await this.remoteConfigCache.cacheRemoteConfig(
|
|
391
|
-
const
|
|
392
|
-
return
|
|
393
|
-
config:
|
|
394
|
-
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
|
|
395
418
|
} : null;
|
|
396
419
|
}
|
|
397
420
|
/**
|
|
@@ -403,12 +426,12 @@ class I {
|
|
|
403
426
|
return {
|
|
404
427
|
localConfig: t,
|
|
405
428
|
remoteConfig: e?.config ?? null,
|
|
406
|
-
defaults:
|
|
429
|
+
defaults: h
|
|
407
430
|
};
|
|
408
431
|
}
|
|
409
|
-
async fetchOrLoadSDK(e, t,
|
|
410
|
-
const
|
|
411
|
-
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();
|
|
412
435
|
}
|
|
413
436
|
async loadFromCache() {
|
|
414
437
|
const e = await this.cacheManager.getCachedSDK();
|
|
@@ -477,18 +500,18 @@ class I {
|
|
|
477
500
|
return typeof window < "u" && "Deway" in window && !!window.Deway;
|
|
478
501
|
}
|
|
479
502
|
}
|
|
480
|
-
const c = new
|
|
481
|
-
init: (
|
|
482
|
-
identify: (
|
|
483
|
-
reportEvent: (
|
|
484
|
-
setUserProfile: (
|
|
485
|
-
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),
|
|
486
509
|
hide: () => c.hide(),
|
|
487
510
|
isVisible: () => c.isVisible(),
|
|
488
511
|
isInitialized: () => c.isInitialized(),
|
|
489
512
|
destroy: () => c.destroy()
|
|
490
513
|
};
|
|
491
|
-
typeof window < "u" && (window.Deway =
|
|
514
|
+
typeof window < "u" && (window.Deway = x);
|
|
492
515
|
export {
|
|
493
|
-
|
|
516
|
+
x as default
|
|
494
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}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 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 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 g={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 m,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||g.apiEndpoint,o=i.publicKey||g.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:g}}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}));
|