@locdo.tech/botiq-chat-sdk 0.3.2 → 0.3.4

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/sdk/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as e } from "./npm-CHWKiGUF.js";
1
+ import { t as e } from "./npm-BHJnX0sn.js";
2
2
  export { e as init };
@@ -1,30 +1,31 @@
1
1
  //#region src/core/config.ts
2
2
  var e = "https://bot-q-backend.vercel.app", t = {
3
- name: "BotIQ",
4
- design: {
5
- colors: {
6
- primary: "#F97316",
7
- header: "#F97316",
8
- userBubble: "#F97316",
9
- botBubble: "#1A1A1A",
10
- background: "#000000",
11
- text: "#FFFFFF"
12
- },
13
- layout: {
14
- position: "bottom-right",
15
- buttonShape: "circle",
16
- width: 360,
17
- height: 520
18
- },
19
- content: {
20
- greeting: "",
21
- suggestionChips: [],
22
- placeholder: ""
23
- },
24
- font: "inter"
3
+ colors: {
4
+ primary: "#F97316",
5
+ header: "#F97316",
6
+ userBubble: "#F97316",
7
+ botBubble: "#1A1A1A",
8
+ background: "#000000",
9
+ text: "#FFFFFF",
10
+ inputBackground: "#1A1A1A"
11
+ },
12
+ layout: {
13
+ position: "bottom-right",
14
+ buttonShape: "circle",
15
+ width: 360,
16
+ height: 520
17
+ },
18
+ content: {
19
+ greeting: "",
20
+ suggestionChips: [],
21
+ placeholder: ""
25
22
  },
23
+ font: "inter"
24
+ }, n = {
25
+ name: "BotIQ",
26
+ design: t,
26
27
  widgetLanguage: "vi"
27
- }, n = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/, r = new Set(["bottom-right", "bottom-left"]), i = new Set(["circle", "square"]), a = new Set([
28
+ }, r = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/, i = new Set(["bottom-right", "bottom-left"]), a = new Set(["circle", "square"]), o = new Set([
28
29
  "inter",
29
30
  "plus-jakarta",
30
31
  "poppins",
@@ -33,54 +34,74 @@ var e = "https://bot-q-backend.vercel.app", t = {
33
34
  "raleway",
34
35
  "lato",
35
36
  "playfair"
36
- ]), o = new Set([
37
+ ]), s = new Set([
37
38
  "none",
38
39
  "fade",
39
40
  "slide-up",
40
41
  "bounce"
41
- ]), s = new Set([
42
+ ]), c = new Set([
42
43
  "dots-bounce",
43
44
  "dots-pulse",
44
45
  "bar"
45
46
  ]);
46
- function c(e) {
47
+ function l(e) {
47
48
  let t = e.colors;
48
- if (![
49
+ if (t.inputBackground ||= "#1A1A1A", ![
49
50
  t.primary,
50
51
  t.header,
51
52
  t.userBubble,
52
53
  t.botBubble,
53
54
  t.background,
54
- t.text
55
- ].every((e) => typeof e == "string" && n.test(e)) || !r.has(e.layout.position) || !i.has(e.layout.buttonShape) || !a.has(e.font)) return !1;
56
- let { width: c, height: l } = e.layout;
57
- if (!Number.isFinite(c) || c < 280 || c > 800 || !Number.isFinite(l) || l < 200 || l > 900) return !1;
55
+ t.text,
56
+ t.inputBackground
57
+ ].every((e) => typeof e == "string" && r.test(e)) || !i.has(e.layout.position) || !a.has(e.layout.buttonShape) || !o.has(e.font)) return !1;
58
+ let { width: n, height: l } = e.layout;
59
+ if (!Number.isFinite(n) || n < 280 || n > 800 || !Number.isFinite(l) || l < 200 || l > 900) return !1;
58
60
  if (e.gradient) {
59
61
  let t = e.gradient;
60
- if (t.type !== "linear" && t.type !== "radial" || !n.test(t.from) || !n.test(t.to) || t.angle !== void 0 && (!Number.isFinite(t.angle) || t.angle < 0 || t.angle > 360)) return !1;
62
+ if (t.type !== "linear" && t.type !== "radial" || !r.test(t.from) || !r.test(t.to) || t.angle !== void 0 && (!Number.isFinite(t.angle) || t.angle < 0 || t.angle > 360)) return !1;
61
63
  }
62
- return !(e.animation && (!o.has(e.animation.bubbleOpen) || !s.has(e.animation.typingIndicator)) || e.customCSS !== void 0 && (typeof e.customCSS != "string" || e.customCSS.length > 8e3));
64
+ return !(e.animation && (!s.has(e.animation.bubbleOpen) || !c.has(e.animation.typingIndicator)) || e.customCSS !== void 0 && (typeof e.customCSS != "string" || e.customCSS.length > 8e3));
65
+ }
66
+ var u = 8e3;
67
+ function d(e, t) {
68
+ return fetch(`${t}/widget/meta`, {
69
+ headers: { "X-Api-Key": e },
70
+ referrerPolicy: "no-referrer-when-downgrade",
71
+ signal: AbortSignal.timeout(u)
72
+ });
63
73
  }
64
- async function l(e, n) {
74
+ async function f(e, r) {
75
+ let i;
65
76
  try {
66
- let r = await fetch(`${n}/widget/meta`, {
67
- headers: { "X-Api-Key": e },
68
- signal: AbortSignal.timeout(5e3)
69
- });
70
- if (!r.ok) return t;
71
- let i = await r.json();
72
- if (!i?.design?.colors || !i?.design?.layout || !i?.design?.content || !c(i.design)) return t;
73
- let a = typeof i.name == "string" && i.name.length > 0 ? i.name : "BotIQ", o = i.widgetLanguage === "en" ? "en" : "vi";
74
- return {
75
- name: a,
76
- design: i.design,
77
- widgetLanguage: o
78
- };
77
+ i = await d(e, r);
79
78
  } catch {
80
- return t;
79
+ try {
80
+ i = await d(e, r);
81
+ } catch {
82
+ return n;
83
+ }
81
84
  }
85
+ if (i.status === 401 || i.status === 403) return null;
86
+ if (!i.ok) return n;
87
+ let a;
88
+ try {
89
+ a = await i.json();
90
+ } catch {
91
+ return n;
92
+ }
93
+ let o = typeof a.name == "string" && a.name.length > 0 ? a.name : n.name, s = a.widgetLanguage === "en" ? "en" : "vi";
94
+ return !a.design?.colors || !a.design?.layout || !a.design?.content || !l(a.design) ? {
95
+ name: o,
96
+ design: t,
97
+ widgetLanguage: s
98
+ } : {
99
+ name: o,
100
+ design: a.design,
101
+ widgetLanguage: s
102
+ };
82
103
  }
83
- function u(t) {
104
+ function p(t) {
84
105
  return {
85
106
  apiKey: t.apiKey,
86
107
  apiUrl: e
@@ -88,32 +109,38 @@ function u(t) {
88
109
  }
89
110
  //#endregion
90
111
  //#region src/core/session.ts
91
- var d = "botiq:sessionId", f = "botiq:history:", p = 10;
92
- function m() {
112
+ var m = "botiq:sessionId", h = "botiq:sessionId:", g = "botiq:history:", _ = 10;
113
+ function v() {
114
+ try {
115
+ let e = localStorage.getItem(m);
116
+ localStorage.removeItem(m), e && localStorage.removeItem(g + e);
117
+ } catch {}
118
+ }
119
+ function y(e) {
93
120
  try {
94
- let e = localStorage.getItem(d);
95
- return e || (e = crypto.randomUUID(), localStorage.setItem(d, e)), e;
121
+ let t = h + e, n = localStorage.getItem(t);
122
+ return n || (n = crypto.randomUUID(), localStorage.setItem(t, n)), n;
96
123
  } catch {
97
124
  return crypto.randomUUID();
98
125
  }
99
126
  }
100
- function h(e) {
127
+ function b(e, t) {
101
128
  try {
102
- let t = localStorage.getItem(f + e);
103
- return t ? JSON.parse(t) : [];
129
+ let n = localStorage.getItem(`${g}${e}:${t}`);
130
+ return n ? JSON.parse(n) : [];
104
131
  } catch {
105
132
  return [];
106
133
  }
107
134
  }
108
- function g(e, t) {
135
+ function x(e, t, n) {
109
136
  try {
110
- let n = [...h(e), ...t].slice(-p);
111
- localStorage.setItem(f + e, JSON.stringify(n));
137
+ let r = [...b(e, t), ...n].slice(-_);
138
+ localStorage.setItem(`${g}${e}:${t}`, JSON.stringify(r));
112
139
  } catch {}
113
140
  }
114
141
  //#endregion
115
142
  //#region src/core/api.ts
116
- async function _(e, t, n, r, i, a) {
143
+ async function S(e, t, n, r, i, a) {
117
144
  try {
118
145
  let o = await fetch(`${e}/widget/chat`, {
119
146
  method: "POST",
@@ -121,6 +148,7 @@ async function _(e, t, n, r, i, a) {
121
148
  "Content-Type": "application/json",
122
149
  "X-Api-Key": t
123
150
  },
151
+ referrerPolicy: "no-referrer-when-downgrade",
124
152
  body: JSON.stringify({
125
153
  sessionId: n,
126
154
  message: r,
@@ -134,28 +162,28 @@ async function _(e, t, n, r, i, a) {
134
162
  }
135
163
  //#endregion
136
164
  //#region src/core/state.ts
137
- var v = {
165
+ var C = {
138
166
  messages: [],
139
167
  isLoading: !1,
140
168
  isOpen: !1
141
- }, y = /* @__PURE__ */ new Set();
142
- function b() {
143
- return v;
169
+ }, w = /* @__PURE__ */ new Set();
170
+ function T() {
171
+ return C;
144
172
  }
145
- function x(e) {
146
- Object.assign(v, e);
173
+ function E(e) {
174
+ Object.assign(C, e);
147
175
  let t = {
148
- ...v,
149
- messages: [...v.messages]
176
+ ...C,
177
+ messages: [...C.messages]
150
178
  };
151
- y.forEach((e) => e(t));
179
+ w.forEach((e) => e(t));
152
180
  }
153
- function S(e) {
154
- return y.add(e), () => y.delete(e);
181
+ function D(e) {
182
+ return w.add(e), () => w.delete(e);
155
183
  }
156
184
  //#endregion
157
185
  //#region src/core/styles.ts
158
- var C = {
186
+ var O = {
159
187
  inter: {
160
188
  url: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap",
161
189
  family: "'Inter', system-ui, -apple-system, sans-serif"
@@ -189,20 +217,20 @@ var C = {
189
217
  family: "'Playfair Display', Georgia, serif"
190
218
  }
191
219
  };
192
- function w(e, t) {
220
+ function k(e, t) {
193
221
  if (!t) return e;
194
222
  let n = t.angle ?? 135;
195
223
  return t.type === "linear" ? `linear-gradient(${n}deg, ${t.from}, ${t.to})` : `radial-gradient(circle, ${t.from}, ${t.to})`;
196
224
  }
197
- function T(e) {
225
+ function A(e) {
198
226
  return e.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\\[0-9a-fA-F]{1,6}\s?/g, "x").replace(/@import\b[^;]*;?/gi, "").replace(/url\s*\(\s*["']?\s*(?!data:)[^)]*["']?\s*\)/gi, "url(\"\")").replace(/expression\s*\(/gi, "expression_(").replace(/javascript\s*:/gi, "blocked:").replace(/-moz-binding\s*:/gi, "").replace(/\bbehavior\s*:/gi, "");
199
227
  }
200
- function E(e) {
228
+ function j(e) {
201
229
  let t = e?.bubbleOpen ?? "none", n = e?.typingIndicator ?? "dots-bounce";
202
230
  return [t === "fade" ? "@keyframes biq-open-fade { from { opacity: 0; } to { opacity: 1; } }\n.chat-window.open { animation: biq-open-fade .22s ease forwards; }" : t === "slide-up" ? "@keyframes biq-open-slide { from { opacity: 0; transform: scale(1) translateY(20px); } to { opacity: 1; transform: scale(1) translateY(0); } }\n.chat-window.open { animation: biq-open-slide .25s cubic-bezier(.22,1,.36,1) forwards; }" : t === "bounce" ? "@keyframes biq-open-bounce { 0% { opacity: 0; transform: scale(.85) translateY(8px); } 60% { transform: scale(1.03) translateY(-3px); } 100% { opacity: 1; transform: scale(1) translateY(0); } }\n.chat-window.open { animation: biq-open-bounce .35s cubic-bezier(.34,1.56,.64,1) forwards; }" : "", n === "dots-pulse" ? "@keyframes biq-pulse { 0%, 100% { opacity: 0.3; transform: scale(1); } 50% { opacity: 1; transform: scale(1.3); } }\n.typing span { animation: biq-pulse 1.2s infinite ease-in-out; }" : n === "bar" ? ".typing { gap: 3px; align-items: flex-end; }\n.typing span { width: 3px; height: 14px; border-radius: 2px; animation: biq-bar 1s infinite ease-in-out; }\n.typing span:nth-child(1) { animation-delay: 0s; }\n.typing span:nth-child(2) { animation-delay: .15s; height: 20px; }\n.typing span:nth-child(3) { animation-delay: .3s; }\n@keyframes biq-bar { 0%, 100% { transform: scaleY(.4); opacity: .5; } 50% { transform: scaleY(1); opacity: 1; } }" : ""].filter(Boolean).join("\n");
203
231
  }
204
- function D(e) {
205
- let { colors: t, layout: n, font: r, gradient: i, animation: a, customCSS: o, whiteLabel: s } = e, c = C[r] ?? C.inter, l = n.buttonShape === "square" ? "14px" : "50%", u = n.position === "bottom-left" ? "right: auto; left: 24px;" : "right: 24px;", d = n.position === "bottom-left" ? "bottom left" : "bottom right", f = n.position === "bottom-left" ? "right: auto; left: 0;" : "right: 0;", p = w(t.primary, i), m = w(t.header, i), h = w(t.userBubble, i), g = s ? ".botiq-badge { display: none !important; }" : "";
232
+ function M(e) {
233
+ let { colors: t, layout: n, font: r, gradient: i, animation: a, customCSS: o, whiteLabel: s } = e, c = O[r] ?? O.inter, l = n.buttonShape === "square" ? "14px" : "50%", u = n.position === "bottom-left" ? "right: auto; left: 24px;" : "right: 24px;", d = n.position === "bottom-left" ? "bottom left" : "bottom right", f = n.position === "bottom-left" ? "right: auto; left: 0;" : "right: 0;", p = k(t.primary, i), m = k(t.header, i), h = k(t.userBubble, i), g = s ? ".botiq-badge { display: none !important; }" : "";
206
234
  return `
207
235
  @import url('${c.url}');
208
236
 
@@ -219,6 +247,7 @@ function D(e) {
219
247
  --color-bot: ${t.botBubble};
220
248
  --color-bg: ${t.background};
221
249
  --color-text: ${t.text};
250
+ --color-input-bg: ${t.inputBackground};
222
251
  --gray-50: #1A1A1A;
223
252
  --gray-100: #222222;
224
253
  --gray-200: #2D2D2D;
@@ -354,21 +383,60 @@ function D(e) {
354
383
 
355
384
  .message { display: flex; flex-direction: column; max-width: 82%; }
356
385
  .message.user { align-self: flex-end; align-items: flex-end; }
357
- .message.assistant { align-self: flex-start; align-items: flex-start; }
386
+ .message.assistant { align-self: flex-start; align-items: flex-start; max-width: 92%; }
358
387
 
359
388
  .message-bubble {
360
389
  padding: 10px 14px;
361
390
  border-radius: var(--radius-msg);
362
391
  font-size: 14px;
363
392
  line-height: 1.5;
364
- white-space: pre-wrap;
393
+ white-space: normal;
365
394
  word-break: break-word;
395
+ overflow-x: auto;
396
+ }
397
+
398
+ /* ── Markdown inline elements ───────────────────────── */
399
+ .message-bubble strong { font-weight: 600; }
400
+ .message-bubble em { font-style: italic; }
401
+ .message-bubble a { color: var(--color-primary); text-decoration: underline; word-break: break-all; }
402
+ .message-bubble code {
403
+ font-family: monospace;
404
+ font-size: 12px;
405
+ padding: 1px 5px;
406
+ border-radius: 4px;
407
+ background: rgba(255,255,255,.1);
408
+ white-space: pre-wrap;
366
409
  }
367
410
 
411
+ /* ── Markdown tables ─────────────────────────────────── */
412
+ .message-bubble table {
413
+ border-collapse: collapse;
414
+ min-width: 100%;
415
+ font-size: 12.5px;
416
+ display: block;
417
+ overflow-x: auto;
418
+ margin: 4px 0;
419
+ }
420
+ .message-bubble th,
421
+ .message-bubble td {
422
+ border: 1px solid rgba(255,255,255,.15);
423
+ padding: 5px 10px;
424
+ text-align: left;
425
+ }
426
+ .message-bubble th { background: rgba(255,255,255,.08); font-weight: 600; white-space: nowrap; }
427
+ .message-bubble td { white-space: normal; }
428
+ .message-bubble tr:nth-child(even) td { background: rgba(255,255,255,.04); }
429
+
430
+ /* ── Markdown lists ──────────────────────────────────── */
431
+ .message-bubble ul,
432
+ .message-bubble ol { padding-left: 18px; margin: 2px 0; }
433
+ .message-bubble li { margin: 2px 0; }
434
+
368
435
  .message.user .message-bubble {
369
436
  background: ${h};
370
437
  color: #fff;
371
438
  border-bottom-right-radius: 4px;
439
+ white-space: pre-wrap;
372
440
  }
373
441
 
374
442
  .message.assistant .message-bubble {
@@ -489,13 +557,13 @@ function D(e) {
489
557
  color: var(--color-text);
490
558
  resize: none;
491
559
  outline: none;
492
- background: var(--gray-50);
560
+ background: var(--color-input-bg);
493
561
  line-height: 1.4;
494
562
  overflow-y: auto;
495
563
  transition: border-color .15s;
496
564
  }
497
565
 
498
- .input:focus { border-color: var(--color-primary); background: var(--gray-100); }
566
+ .input:focus { border-color: var(--color-primary); background: var(--color-input-bg); }
499
567
  .input::placeholder { color: var(--gray-400); }
500
568
 
501
569
  .send-btn {
@@ -518,62 +586,100 @@ function D(e) {
518
586
  .send-btn svg { width: 18px; height: 18px; fill: #fff; }
519
587
 
520
588
  ${g}
521
- ${E(a)}
522
- ${o ? T(o) : ""}
589
+ ${j(a)}
590
+ ${o ? A(o) : ""}
523
591
  `;
524
592
  }
525
593
  //#endregion
526
- //#region src/core/ui.ts
527
- var O = "https://bot-q-frontend.vercel.app/", k = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M20 2H4a2 2 0 00-2 2v18l4-4h14a2 2 0 002-2V4a2 2 0 00-2-2z\"/>\n</svg>", A = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/>\n</svg>", j = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 2a2 2 0 012 2c0 .74-.4 1.38-1 1.72V7h3a3 3 0 013 3v8a3 3 0 01-3 3H8a3 3 0 01-3-3v-8a3 3 0 013-3h3V5.72A2 2 0 0110 4a2 2 0 012-2zm-2 9a1.5 1.5 0 100 3 1.5 1.5 0 000-3zm4 0a1.5 1.5 0 100 3 1.5 1.5 0 000-3z\"/>\n</svg>", M = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\"/>\n</svg>", N = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M20 2H4a2 2 0 00-2 2v18l4-4h14a2 2 0 002-2V4a2 2 0 00-2-2zm-2 10H6v-2h12v2zm0-3H6V7h12v2z\"/>\n</svg>";
528
- function P(e) {
529
- if (!e || e.type === "icon") return j;
530
- if (e.type === "emoji") return `<span style="font-size:22px;line-height:1;display:flex;align-items:center;justify-content:center;width:100%;height:100%">${F(e.value)}</span>`;
594
+ //#region src/core/assets.ts
595
+ var N = "data:image/png;base64,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", P = "https://bot-q-frontend.vercel.app/", F = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M20 2H4a2 2 0 00-2 2v18l4-4h14a2 2 0 002-2V4a2 2 0 00-2-2z\"/>\n</svg>", I = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/>\n</svg>", L = `<img src="${N}" alt="" style="width:100%;height:100%;object-fit:cover;border-radius:50%" />`, R = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\"/>\n</svg>", z = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M20 2H4a2 2 0 00-2 2v18l4-4h14a2 2 0 002-2V4a2 2 0 00-2-2zm-2 10H6v-2h12v2zm0-3H6V7h12v2z\"/>\n</svg>";
596
+ function B(e) {
597
+ if (!e || e.type === "icon") return L;
598
+ if (e.type === "emoji") return `<span style="font-size:22px;line-height:1;display:flex;align-items:center;justify-content:center;width:100%;height:100%">${V(e.value)}</span>`;
531
599
  if (e.type === "initials") {
532
600
  let t = e.bgColor ?? "#F97316";
533
- return `<div style="width:100%;height:100%;border-radius:50%;background:${/^#[0-9A-Fa-f]{3,6}$/.test(t) ? t : "#F97316"};display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:700;color:#fff">${F(e.value.slice(0, 2).toUpperCase())}</div>`;
601
+ return `<div style="width:100%;height:100%;border-radius:50%;background:${/^#[0-9A-Fa-f]{3,6}$/.test(t) ? t : "#F97316"};display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:700;color:#fff">${V(e.value.slice(0, 2).toUpperCase())}</div>`;
534
602
  }
535
- return e.type === "image" ? `<img src="${F(e.value)}" style="width:100%;height:100%;object-fit:cover;border-radius:50%" alt="" />` : j;
603
+ return e.type === "image" ? `<img src="${V(e.value)}" style="width:100%;height:100%;object-fit:cover;border-radius:50%" alt="" />` : L;
536
604
  }
537
- function F(e) {
605
+ function V(e) {
538
606
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#x27;");
539
607
  }
540
- function I(e) {
541
- let t = F(e).replace(/\x00/g, ""), n = [];
542
- return t = t.replace(/`([^`]+)`/g, (e, t) => (n.push(`<code>${t}</code>`), `\x00CODE${n.length - 1}\x00`)), t = t.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>"), t = t.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>"), t = t.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g, "<em>$1</em>"), t = t.replace(/\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g, "<a href=\"$2\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>"), t = t.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1"), t = t.replace(/\n/g, "<br>"), t = t.replace(/\x00CODE(\d+)\x00/g, (e, t) => n[Number(t)]), t;
608
+ function H(e) {
609
+ let t = [];
610
+ return e = e.replace(/`([^`]+)`/g, (e, n) => (t.push(`<code>${n}</code>`), `\x00CODE${t.length - 1}\x00`)), e = e.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>"), e = e.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>"), e = e.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g, "<em>$1</em>"), e = e.replace(/\[([^\]]+)\]\(([^()]*(?:\([^()]*\))*[^()]*)\)/g, (e, t, n) => /^https?:\/\//.test(n) ? `<a href="${n}" target="_blank" rel="noopener noreferrer">${t}</a>` : t), e = e.replace(/\x00CODE(\d+)\x00/g, (e, n) => t[Number(n)]), e;
611
+ }
612
+ function U(e) {
613
+ return /^\|[\s\-:|]+\|$/.test(e);
614
+ }
615
+ function W(e) {
616
+ return e.replace(/^\|/, "").replace(/\|$/, "").split("|").map((e) => e.trim());
617
+ }
618
+ function G(e) {
619
+ let t = V(e).replace(/\x00/g, "").split("\n"), n = [], r = 0;
620
+ for (; r < t.length;) {
621
+ let e = t[r].trim();
622
+ if (e.startsWith("|") && e.endsWith("|")) {
623
+ let e = [];
624
+ for (; r < t.length && t[r].trim().startsWith("|") && t[r].trim().endsWith("|");) e.push(t[r].trim()), r++;
625
+ let i = e.findIndex(U), a = i > 0 ? e.slice(0, i) : [], o = i >= 0 ? e.slice(i + 1) : e, s = "<table>";
626
+ a.length > 0 && (s += "<thead>" + a.map((e) => "<tr>" + W(e).map((e) => `<th>${H(e)}</th>`).join("") + "</tr>").join("") + "</thead>"), o.length > 0 && (s += "<tbody>" + o.map((e) => "<tr>" + W(e).map((e) => `<td>${H(e)}</td>`).join("") + "</tr>").join("") + "</tbody>"), s += "</table>", n.push(s);
627
+ continue;
628
+ }
629
+ if (/^[-*]\s/.test(e)) {
630
+ let e = [];
631
+ for (; r < t.length && /^\s*[-*]\s/.test(t[r]);) e.push(t[r].trim().replace(/^[-*]\s+/, "")), r++;
632
+ n.push("<ul>" + e.map((e) => `<li>${H(e)}</li>`).join("") + "</ul>");
633
+ continue;
634
+ }
635
+ if (/^\d+\.\s/.test(e)) {
636
+ let e = [];
637
+ for (; r < t.length && /^\s*\d+\.\s/.test(t[r]);) e.push(t[r].trim().replace(/^\d+\.\s+/, "")), r++;
638
+ n.push("<ol>" + e.map((e) => `<li>${H(e)}</li>`).join("") + "</ol>");
639
+ continue;
640
+ }
641
+ if (e === "") {
642
+ n.push("<br>"), r++;
643
+ continue;
644
+ }
645
+ n.push(H(e)), n.push("<br>"), r++;
646
+ }
647
+ for (; n.length > 0 && n[n.length - 1] === "<br>";) n.pop();
648
+ return n.join("");
543
649
  }
544
- function L(e, t, n, r, i) {
650
+ function K(e, t, n, r, i) {
545
651
  let { name: a, design: o } = t, s, c, l, u, d, f, { content: p } = o;
546
652
  function m(e) {
547
- e.setAttribute("data-position", o.layout.position), s = e.attachShadow({ mode: "open" });
653
+ e.setAttribute("data-position", o.layout.position), s = e.attachShadow({ mode: "closed" });
548
654
  let t = document.createElement("style");
549
- t.textContent = D(o), s.appendChild(t), c = document.createElement("button"), c.className = "bubble", c.setAttribute("aria-label", n.ariaOpenChat), c.innerHTML = `
550
- <span class="icon-chat">${k}</span>
551
- <span class="icon-close">${A}</span>
655
+ t.textContent = M(o), s.appendChild(t), c = document.createElement("button"), c.className = "bubble", c.setAttribute("aria-label", n.ariaOpenChat), c.innerHTML = `
656
+ <span class="icon-chat">${F}</span>
657
+ <span class="icon-close">${I}</span>
552
658
  `, c.addEventListener("click", i), s.appendChild(c), l = document.createElement("div"), l.className = "chat-window", l.setAttribute("role", "dialog"), l.setAttribute("aria-label", `${a} chat`), l.innerHTML = `
553
659
  <div class="chat-header">
554
- <div class="avatar">${P(o.avatar)}</div>
660
+ <div class="avatar">${B(o.avatar)}</div>
555
661
  <div class="header-text">
556
- <span class="bot-name">${F(a)}</span>
557
- <span class="bot-status">${F(n.statusOnline)}</span>
662
+ <span class="bot-name">${V(a)}</span>
663
+ <span class="bot-status">${V(n.statusOnline)}</span>
558
664
  </div>
559
- <button class="close-btn" aria-label="${F(n.ariaCloseChat)}">×</button>
665
+ <button class="close-btn" aria-label="${V(n.ariaCloseChat)}">×</button>
560
666
  </div>
561
667
  <div class="messages" id="messages-container" role="log" aria-live="polite" aria-atomic="false"></div>
562
668
  <div class="chat-footer">
563
669
  <div class="input-row">
564
670
  <textarea
565
671
  class="input"
566
- placeholder="${F(p.placeholder || n.inputPlaceholder)}"
672
+ placeholder="${V(p.placeholder || n.inputPlaceholder)}"
567
673
  rows="1"
568
674
  maxlength="2000"
569
675
  aria-label="Message input"
570
676
  ></textarea>
571
- <button class="send-btn" aria-label="${F(n.ariaSendMessage)}">
572
- ${M}
677
+ <button class="send-btn" aria-label="${V(n.ariaSendMessage)}">
678
+ ${R}
573
679
  </button>
574
680
  </div>
575
- <a class="botiq-badge" href="${O}" target="_blank" rel="noopener noreferrer">
576
- ${F(n.poweredBy)} <span class="botiq-badge-name">BotIQ</span>
681
+ <a class="botiq-badge" href="${P}" target="_blank" rel="noopener noreferrer">
682
+ ${V(n.poweredBy)} <span class="botiq-badge-name">BotIQ</span>
577
683
  </a>
578
684
  </div>
579
685
  `, l.querySelector(".close-btn").addEventListener("click", i), u = l.querySelector("#messages-container"), d = l.querySelector(".input"), f = l.querySelector(".send-btn"), d.addEventListener("input", () => {
@@ -588,11 +694,11 @@ function L(e, t, n, r, i) {
588
694
  }
589
695
  function g(e) {
590
696
  if (e.messages.length === 0 && !e.isLoading) {
591
- let e = p.suggestionChips.length > 0 ? `<div class="chips">${p.suggestionChips.map((e) => `<button class="chip">${F(e)}</button>`).join("")}</div>` : "";
697
+ let e = p.suggestionChips.length > 0 ? `<div class="chips">${p.suggestionChips.map((e) => `<button class="chip">${V(e)}</button>`).join("")}</div>` : "";
592
698
  u.innerHTML = `
593
699
  <div class="empty-state">
594
- ${N}
595
- <span class="greeting">${F(p.greeting || n.defaultGreeting)}</span>
700
+ ${z}
701
+ <span class="greeting">${V(p.greeting || n.defaultGreeting)}</span>
596
702
  ${e}
597
703
  </div>
598
704
  `, u.querySelectorAll(".chip").forEach((e) => {
@@ -602,7 +708,7 @@ function L(e, t, n, r, i) {
602
708
  }
603
709
  let t = e.messages.map((e) => `
604
710
  <div class="message ${e.role}">
605
- <div class="message-bubble">${e.role === "assistant" ? I(e.content) : F(e.content)}</div>
711
+ <div class="message-bubble">${e.role === "assistant" ? G(e.content) : V(e.content)}</div>
606
712
  </div>
607
713
  `).join(""), i = e.isLoading ? "<div class=\"typing\"><span></span><span></span><span></span></div>" : "";
608
714
  u.innerHTML = t + i, u.scrollTop = u.scrollHeight;
@@ -617,7 +723,7 @@ function L(e, t, n, r, i) {
617
723
  }
618
724
  //#endregion
619
725
  //#region src/i18n/vi.ts
620
- var R = {
726
+ var q = {
621
727
  statusOnline: "Trực tuyến",
622
728
  inputPlaceholder: "Nhắn tin...",
623
729
  defaultGreeting: "Xin chào! Tôi có thể giúp gì cho bạn?",
@@ -633,7 +739,7 @@ var R = {
633
739
  ariaOpenChat: "Mở khung chat",
634
740
  ariaCloseChat: "Đóng khung chat",
635
741
  ariaSendMessage: "Gửi tin nhắn"
636
- }, z = {
742
+ }, J = {
637
743
  statusOnline: "Online",
638
744
  inputPlaceholder: "Type a message...",
639
745
  defaultGreeting: "Hello! How can I help you?",
@@ -652,53 +758,59 @@ var R = {
652
758
  };
653
759
  //#endregion
654
760
  //#region src/i18n/index.ts
655
- function B(e) {
656
- return e === "en" ? z : R;
761
+ function Y(e) {
762
+ return e === "en" ? J : q;
657
763
  }
658
764
  //#endregion
659
765
  //#region src/builds/npm/index.ts
660
- function V(e) {
766
+ function X(e) {
661
767
  if (!e.apiKey) return console.warn("[BotIQ] apiKey is required"), () => void 0;
662
- let t = u(e), n = m();
663
- x({ messages: h(n) });
664
- let r = document.createElement("div");
665
- document.body.appendChild(r);
666
- let i = () => void 0, a = !1, o = B(void 0);
667
- l(t.apiKey, t.apiUrl).then((e) => {
668
- if (a) return;
669
- o = B(e.widgetLanguage);
670
- let n = L(t, e, o, s, c);
671
- n.mount(r), i = S((e) => n.update(e)), n.update(b());
768
+ let t = p(e);
769
+ v();
770
+ let n = t.apiKey.slice(-16), r = y(n);
771
+ E({ messages: b(n, r) });
772
+ let i = document.createElement("div");
773
+ document.body.appendChild(i);
774
+ let a = () => void 0, o = !1, s = Y(void 0);
775
+ f(t.apiKey, t.apiUrl).then((e) => {
776
+ if (o) return;
777
+ if (e === null) {
778
+ console.warn("[BotIQ] Widget not authorised on this origin — skipped mount"), i.remove();
779
+ return;
780
+ }
781
+ s = Y(e.widgetLanguage);
782
+ let n = K(t, e, s, c, l);
783
+ n.mount(i), a = D((e) => n.update(e)), n.update(T());
672
784
  });
673
- function s(e) {
674
- let r = b();
675
- if (r.isLoading) return;
676
- let i = {
785
+ function c(e) {
786
+ let i = T();
787
+ if (i.isLoading) return;
788
+ let a = {
677
789
  role: "user",
678
790
  content: e
679
791
  };
680
- x({
681
- messages: [...r.messages, i],
792
+ E({
793
+ messages: [...i.messages, a],
682
794
  isLoading: !0
683
- }), _(t.apiUrl, t.apiKey, n, e, r.messages, o).then((e) => {
795
+ }), S(t.apiUrl, t.apiKey, r, e, i.messages, s).then((e) => {
684
796
  let t = {
685
797
  role: "assistant",
686
798
  content: e
687
799
  };
688
- x({
689
- messages: [...b().messages, t],
800
+ E({
801
+ messages: [...T().messages, t],
690
802
  isLoading: !1
691
- }), g(n, [i, t]);
803
+ }), x(n, r, [a, t]);
692
804
  }).catch(() => {
693
- x({ isLoading: !1 });
805
+ E({ isLoading: !1 });
694
806
  });
695
807
  }
696
- function c() {
697
- x({ isOpen: !b().isOpen });
808
+ function l() {
809
+ E({ isOpen: !T().isOpen });
698
810
  }
699
811
  return () => {
700
- a = !0, i(), r.remove();
812
+ o = !0, a(), i.remove();
701
813
  };
702
814
  }
703
815
  //#endregion
704
- export { V as t };
816
+ export { X as t };
package/dist/sdk/react.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as e } from "./npm-CHWKiGUF.js";
1
+ import { t as e } from "./npm-BHJnX0sn.js";
2
2
  import { useEffect as t } from "react";
3
3
  //#region src/builds/npm/react.tsx
4
4
  function n(n) {
package/dist/sdk/vue.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as e } from "./npm-CHWKiGUF.js";
1
+ import { t as e } from "./npm-BHJnX0sn.js";
2
2
  import { defineComponent as t, onMounted as n, onUnmounted as r } from "vue";
3
3
  //#region src/builds/npm/vue.ts
4
4
  var i = t({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@locdo.tech/botiq-chat-sdk",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "BotIQ chat widget SDK — embed AI chatbot into any website with vanilla JS, React, or Vue.",
5
5
  "keywords": [
6
6
  "botiq",
@@ -75,6 +75,11 @@
75
75
  "test:browser:chromium": "playwright test --project=chromium",
76
76
  "pretest:browser": "npm run build:cdn && cpx \"test/browser/fixtures/**\" dist/test-fixtures",
77
77
  "pretest:browser:chromium": "npm run pretest:browser",
78
+ "test:wordpress": "playwright test --config=playwright.wordpress.config.ts",
79
+ "pretest:wordpress": "npm run build:cdn",
80
+ "test:wordpress:up": "docker compose -f test/wordpress/docker-compose.wp.yml up -d",
81
+ "test:wordpress:down": "docker compose -f test/wordpress/docker-compose.wp.yml down -v",
82
+ "test:wordpress:logs": "docker compose -f test/wordpress/docker-compose.wp.yml logs --tail=100",
78
83
  "prepublishOnly": "npm run build:sdk",
79
84
  "rollback:cdn": "bash scripts/rollback/cdn-rollback.sh"
80
85
  },