@getnexorai/sdk 0.1.4 → 0.1.7
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/chat.cjs +124 -20
- package/dist/chat.cjs.map +1 -1
- package/dist/chat.d.cts +2 -2
- package/dist/chat.d.ts +2 -2
- package/dist/chat.js +1 -1
- package/dist/{chunk-WUUXZIQN.js → chunk-DSKP6MXM.js} +126 -22
- package/dist/chunk-DSKP6MXM.js.map +1 -0
- package/dist/{config-C39P5Aax.d.cts → config-DBEY3q4Q.d.cts} +13 -1
- package/dist/{config-C39P5Aax.d.ts → config-DBEY3q4Q.d.ts} +13 -1
- package/dist/index.cjs +124 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/nexor.iife.js +71 -20
- package/dist/nexor.iife.js.map +1 -1
- package/package.json +4 -2
- package/dist/chunk-WUUXZIQN.js.map +0 -1
package/dist/chat.cjs
CHANGED
|
@@ -237,10 +237,21 @@ function randomHex(bytes) {
|
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
// src/chat/validate.ts
|
|
240
|
+
var EMAIL_RE = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/;
|
|
240
241
|
function isValidEmail(value) {
|
|
241
242
|
const s = (value || "").trim();
|
|
242
243
|
if (s.length < 6 || s.length > 254) return false;
|
|
243
|
-
|
|
244
|
+
const at = s.lastIndexOf("@");
|
|
245
|
+
if (at < 1) return false;
|
|
246
|
+
const local = s.slice(0, at);
|
|
247
|
+
const domain = s.slice(at + 1);
|
|
248
|
+
if (local.length > 64) return false;
|
|
249
|
+
if (local.startsWith(".") || local.endsWith(".") || local.includes("..")) {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
if (domain.includes("..")) return false;
|
|
253
|
+
if (!/\.[a-zA-Z]{2,}$/.test(domain)) return false;
|
|
254
|
+
return EMAIL_RE.test(s);
|
|
244
255
|
}
|
|
245
256
|
|
|
246
257
|
// src/chat/template.ts
|
|
@@ -701,6 +712,40 @@ var widgetCss = (accent, accentText) => `
|
|
|
701
712
|
}
|
|
702
713
|
.nexor-chat__msg--bot .nexor-chat__msg-time { text-align: left; }
|
|
703
714
|
|
|
715
|
+
/* File Library attachment: the image itself is the bubble (no padding/bg). */
|
|
716
|
+
.nexor-chat__msg--media {
|
|
717
|
+
padding: 0;
|
|
718
|
+
background: transparent;
|
|
719
|
+
border: none;
|
|
720
|
+
box-shadow: none;
|
|
721
|
+
overflow: hidden;
|
|
722
|
+
}
|
|
723
|
+
.nexor-chat__media-img {
|
|
724
|
+
display: block;
|
|
725
|
+
max-width: 100%;
|
|
726
|
+
max-height: 260px;
|
|
727
|
+
width: auto;
|
|
728
|
+
height: auto;
|
|
729
|
+
border-radius: 14px;
|
|
730
|
+
border-bottom-left-radius: 4px;
|
|
731
|
+
object-fit: cover;
|
|
732
|
+
}
|
|
733
|
+
.nexor-chat__media-doc {
|
|
734
|
+
display: inline-flex;
|
|
735
|
+
align-items: center;
|
|
736
|
+
gap: 6px;
|
|
737
|
+
padding: 8px 12px;
|
|
738
|
+
border-radius: 14px;
|
|
739
|
+
border-bottom-left-radius: 4px;
|
|
740
|
+
background: #fff;
|
|
741
|
+
border: 1px solid rgba(0,0,0,0.06);
|
|
742
|
+
color: ${accent};
|
|
743
|
+
text-decoration: none;
|
|
744
|
+
font-size: 13px;
|
|
745
|
+
font-weight: 500;
|
|
746
|
+
}
|
|
747
|
+
.nexor-chat__media-doc::before { content: "\\1F4CE"; }
|
|
748
|
+
|
|
704
749
|
@keyframes nexor-msg-in {
|
|
705
750
|
from { transform: translateY(8px) scale(0.96); opacity: 0; }
|
|
706
751
|
to { transform: translateY(0) scale(1); opacity: 1; }
|
|
@@ -840,7 +885,8 @@ var widgetCss = (accent, accentText) => `
|
|
|
840
885
|
transition: border-color 140ms ease, box-shadow 140ms ease;
|
|
841
886
|
}
|
|
842
887
|
/* Composer textarea: auto-grows (height managed in JS) up to ~4 lines, then
|
|
843
|
-
scrolls. resize:none disables the manual drag handle.
|
|
888
|
+
scrolls. resize:none disables the manual drag handle. Filled style: neutral
|
|
889
|
+
pill at rest that "lights up" white on focus \u2014 calmer than a glowing ring. */
|
|
844
890
|
textarea.nexor-chat__input {
|
|
845
891
|
display: block;
|
|
846
892
|
resize: none;
|
|
@@ -849,11 +895,22 @@ textarea.nexor-chat__input {
|
|
|
849
895
|
max-height: 98px; /* 4 lines (20\xD74) + 16 padding + 2 border */
|
|
850
896
|
white-space: pre-wrap;
|
|
851
897
|
word-break: break-word;
|
|
898
|
+
background: #f3f4f6;
|
|
899
|
+
border-color: transparent;
|
|
900
|
+
border-radius: 19px;
|
|
901
|
+
padding: 8px 14px;
|
|
902
|
+
transition: background 140ms ease, border-color 140ms ease, box-shadow 140ms ease;
|
|
852
903
|
}
|
|
904
|
+
textarea.nexor-chat__input::placeholder { color: #9ca3af; }
|
|
853
905
|
.nexor-chat__input:focus,
|
|
854
906
|
.nexor-chat__capture input:focus {
|
|
855
907
|
border-color: ${accent};
|
|
856
|
-
box-shadow: 0 0 0
|
|
908
|
+
box-shadow: 0 0 0 2px ${accent}1f;
|
|
909
|
+
}
|
|
910
|
+
textarea.nexor-chat__input:focus {
|
|
911
|
+
background: #fff;
|
|
912
|
+
border-color: ${accent}99;
|
|
913
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.06);
|
|
857
914
|
}
|
|
858
915
|
.nexor-chat__input--error,
|
|
859
916
|
.nexor-chat__capture input.nexor-chat__input--error {
|
|
@@ -994,21 +1051,26 @@ textarea.nexor-chat__input {
|
|
|
994
1051
|
background: ${accent};
|
|
995
1052
|
color: ${accentText};
|
|
996
1053
|
border: none;
|
|
997
|
-
border-radius:
|
|
998
|
-
padding: 0
|
|
1054
|
+
border-radius: 9999px; /* circle, matches the pill composer */
|
|
1055
|
+
padding: 0;
|
|
999
1056
|
font: inherit;
|
|
1000
1057
|
font-weight: 600;
|
|
1001
1058
|
cursor: pointer;
|
|
1002
|
-
|
|
1059
|
+
width: 38px;
|
|
1003
1060
|
height: 38px; /* matches the one-line textarea height */
|
|
1004
1061
|
flex: none;
|
|
1005
1062
|
display: flex;
|
|
1006
1063
|
align-items: center;
|
|
1007
1064
|
justify-content: center;
|
|
1008
|
-
|
|
1065
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.12);
|
|
1066
|
+
transition: transform 140ms ease, filter 140ms ease, box-shadow 140ms ease;
|
|
1067
|
+
}
|
|
1068
|
+
.nexor-chat__send:hover {
|
|
1069
|
+
filter: brightness(1.08);
|
|
1070
|
+
box-shadow: 0 2px 6px rgba(0,0,0,0.18);
|
|
1071
|
+
transform: translateY(-1px);
|
|
1009
1072
|
}
|
|
1010
|
-
.nexor-chat__send:
|
|
1011
|
-
.nexor-chat__send:active { transform: scale(0.95); }
|
|
1073
|
+
.nexor-chat__send:active { transform: scale(0.93); }
|
|
1012
1074
|
.nexor-chat__send[disabled] {
|
|
1013
1075
|
opacity: 0.6;
|
|
1014
1076
|
cursor: not-allowed;
|
|
@@ -1019,7 +1081,7 @@ textarea.nexor-chat__input {
|
|
|
1019
1081
|
height: 18px;
|
|
1020
1082
|
transition: transform 200ms ease;
|
|
1021
1083
|
}
|
|
1022
|
-
.nexor-chat__send:not([disabled]):hover svg { transform:
|
|
1084
|
+
.nexor-chat__send:not([disabled]):hover svg { transform: translateY(-1.5px); }
|
|
1023
1085
|
|
|
1024
1086
|
/* Small spinner inside the send button while a turn is in flight */
|
|
1025
1087
|
.nexor-chat__send--loading svg { display: none; }
|
|
@@ -1172,11 +1234,13 @@ textarea.nexor-chat__input {
|
|
|
1172
1234
|
// src/chat/dom.ts
|
|
1173
1235
|
var STYLE_ATTR = "data-nexor-chat-styles";
|
|
1174
1236
|
function injectStyles(accent, accentText) {
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1237
|
+
let style = document.querySelector(`style[${STYLE_ATTR}]`);
|
|
1238
|
+
if (!style) {
|
|
1239
|
+
style = document.createElement("style");
|
|
1240
|
+
style.setAttribute(STYLE_ATTR, "1");
|
|
1241
|
+
document.head.appendChild(style);
|
|
1242
|
+
}
|
|
1178
1243
|
style.textContent = widgetCss(accent, accentText);
|
|
1179
|
-
document.head.appendChild(style);
|
|
1180
1244
|
}
|
|
1181
1245
|
var CHAT_ICON = `
|
|
1182
1246
|
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
@@ -1539,8 +1603,8 @@ function buildComposer(cfg) {
|
|
|
1539
1603
|
send.setAttribute("aria-label", "Send message");
|
|
1540
1604
|
send.innerHTML = `
|
|
1541
1605
|
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
1542
|
-
<path d="
|
|
1543
|
-
stroke="currentColor" stroke-width="
|
|
1606
|
+
<path d="M12 19V5.8M5.8 12 12 5.8 18.2 12"
|
|
1607
|
+
stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/>
|
|
1544
1608
|
</svg>
|
|
1545
1609
|
`;
|
|
1546
1610
|
form.appendChild(input);
|
|
@@ -1582,6 +1646,28 @@ function buildMessage(role, text, ts, locale) {
|
|
|
1582
1646
|
}
|
|
1583
1647
|
return el;
|
|
1584
1648
|
}
|
|
1649
|
+
function buildMediaMessage(item) {
|
|
1650
|
+
const el = document.createElement("div");
|
|
1651
|
+
el.className = "nexor-chat__msg nexor-chat__msg--bot nexor-chat__msg--media";
|
|
1652
|
+
if (item.type === "image") {
|
|
1653
|
+
const img = document.createElement("img");
|
|
1654
|
+
img.className = "nexor-chat__media-img";
|
|
1655
|
+
img.src = item.url;
|
|
1656
|
+
img.alt = item.filename || "";
|
|
1657
|
+
img.loading = "lazy";
|
|
1658
|
+
img.addEventListener("error", () => el.remove());
|
|
1659
|
+
el.appendChild(img);
|
|
1660
|
+
} else {
|
|
1661
|
+
const a = document.createElement("a");
|
|
1662
|
+
a.className = "nexor-chat__media-doc";
|
|
1663
|
+
a.href = item.url;
|
|
1664
|
+
a.target = "_blank";
|
|
1665
|
+
a.rel = "noopener noreferrer";
|
|
1666
|
+
a.textContent = item.filename || "Descargar archivo";
|
|
1667
|
+
el.appendChild(a);
|
|
1668
|
+
}
|
|
1669
|
+
return el;
|
|
1670
|
+
}
|
|
1585
1671
|
function formatRelativeTime(ts, locale, now = Date.now()) {
|
|
1586
1672
|
try {
|
|
1587
1673
|
const diff = Math.max(0, now - ts);
|
|
@@ -1759,7 +1845,8 @@ function initChat(client, options) {
|
|
|
1759
1845
|
setView("chat");
|
|
1760
1846
|
renderResumeBanner();
|
|
1761
1847
|
for (const m of persisted.history) {
|
|
1762
|
-
|
|
1848
|
+
if (m.media) appendNode(buildMediaMessage(m.media));
|
|
1849
|
+
else appendBubble(m.role === "user" ? "user" : "bot", m.text, m.ts);
|
|
1763
1850
|
}
|
|
1764
1851
|
scrollToBottom();
|
|
1765
1852
|
}
|
|
@@ -2292,9 +2379,12 @@ function initChat(client, options) {
|
|
|
2292
2379
|
renderResumeBanner(true);
|
|
2293
2380
|
}
|
|
2294
2381
|
const reply = (res.reply ?? "").trim();
|
|
2382
|
+
const hasMedia = Array.isArray(res.media) && res.media.length > 0;
|
|
2295
2383
|
hideTyping();
|
|
2296
2384
|
if (reply) {
|
|
2297
|
-
appendBotReply(reply);
|
|
2385
|
+
appendBotReply(reply, hasMedia ? () => appendBotMedia(res.media) : void 0);
|
|
2386
|
+
} else if (hasMedia) {
|
|
2387
|
+
appendBotMedia(res.media);
|
|
2298
2388
|
} else {
|
|
2299
2389
|
appendSystem(cfg.errorText);
|
|
2300
2390
|
cfg.onError?.(new Error("Nexor SDK: empty reply from server"));
|
|
@@ -2329,10 +2419,21 @@ function initChat(client, options) {
|
|
|
2329
2419
|
if (!state.isOpen) bumpUnread();
|
|
2330
2420
|
cfg.onMessage?.({ role: "bot", text });
|
|
2331
2421
|
}
|
|
2332
|
-
function
|
|
2422
|
+
function appendBotMedia(items) {
|
|
2423
|
+
if (!Array.isArray(items) || items.length === 0) return;
|
|
2424
|
+
for (const item of items) {
|
|
2425
|
+
if (!item || typeof item.url !== "string" || !item.url) continue;
|
|
2426
|
+
appendNode(buildMediaMessage(item));
|
|
2427
|
+
state.history.push({ role: "bot", text: "", ts: Date.now(), media: item });
|
|
2428
|
+
}
|
|
2429
|
+
saveHistory();
|
|
2430
|
+
if (!state.isOpen) bumpUnread();
|
|
2431
|
+
}
|
|
2432
|
+
function appendBotReply(text, after) {
|
|
2333
2433
|
const parts = cfg.splitReplies ? splitReply(text) : [text];
|
|
2334
2434
|
if (parts.length <= 1) {
|
|
2335
2435
|
appendBot(text);
|
|
2436
|
+
after?.();
|
|
2336
2437
|
return;
|
|
2337
2438
|
}
|
|
2338
2439
|
const [first, ...rest] = parts;
|
|
@@ -2340,7 +2441,10 @@ function initChat(client, options) {
|
|
|
2340
2441
|
let i = 0;
|
|
2341
2442
|
const sendNext = () => {
|
|
2342
2443
|
const part = rest[i];
|
|
2343
|
-
if (part === void 0)
|
|
2444
|
+
if (part === void 0) {
|
|
2445
|
+
after?.();
|
|
2446
|
+
return;
|
|
2447
|
+
}
|
|
2344
2448
|
const isLast = i === rest.length - 1;
|
|
2345
2449
|
i++;
|
|
2346
2450
|
showTyping();
|