copilot-chat-widget 0.1.27 → 0.1.28

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.
@@ -1,7 +1,7 @@
1
- (function(){"use strict";(()=>{if(typeof window>"u"||typeof document>"u"||window.__copilotWidgetLoaded)return;window.__copilotWidgetLoaded=!0;const T="http://localhost:3000",b=64,y=720,x=document.currentScript,k=t=>{if(!t?.src)return{};try{const s=new URL(t.src,window.location.href),n={};return s.searchParams.forEach((l,c)=>{n[c]=l}),n}catch(s){return console.warn("[CopilotChat] Failed to parse script query params:",s),{}}},I=t=>{document.readyState==="complete"||document.readyState==="interactive"?setTimeout(t,0):document.addEventListener("DOMContentLoaded",t)},v=()=>x||Array.from(document.querySelectorAll("script")).reverse().find(n=>n.dataset?.token||n.src&&n.src.includes("chat-widget"))||null,U=({iframeUrl:t,launcherIcon:s})=>{const n=document.querySelector("[data-copilot-widget-root]");n&&n.remove();const l=w=>{const a=document.querySelector("[data-copilot-checkout-toast]");a&&a.remove();const h=document.createElement("div");h.setAttribute("data-copilot-checkout-toast","true"),h.innerText=w,Object.assign(h.style,{position:"fixed",top:"20px",left:"50%",transform:"translateX(-50%)",padding:"12px 16px",background:"#0f172a",color:"white",borderRadius:"12px",boxShadow:"0 8px 24px rgba(0,0,0,0.25)",zIndex:2147483647,fontSize:"14px",fontWeight:"600",maxWidth:"420px",lineHeight:"1.4",textAlign:"center"}),document.body.appendChild(h),setTimeout(()=>{h.remove()},4500)},c=document.createElement("div");c.setAttribute("data-copilot-widget-root","true");const C=c.attachShadow({mode:"open"});document.body.appendChild(c);const e=document.createElement("button");e.type="button",e.setAttribute("aria-label","Open Copilot chat"),e.innerHTML=`
1
+ (function(){"use strict";(()=>{if(typeof window>"u"||typeof document>"u"||window.__copilotWidgetLoaded)return;window.__copilotWidgetLoaded=!0;const T="http://localhost:3000",b=64,x=720,y=document.currentScript,k=t=>{if(!t?.src)return{};try{const s=new URL(t.src,window.location.href),n={};return s.searchParams.forEach((l,c)=>{n[c]=l}),n}catch(s){return console.warn("[CopilotChat] Failed to parse script query params:",s),{}}},I=t=>{document.readyState==="complete"||document.readyState==="interactive"?setTimeout(t,0):document.addEventListener("DOMContentLoaded",t)},E=()=>y||Array.from(document.querySelectorAll("script")).reverse().find(n=>n.dataset?.token||n.src&&n.src.includes("chat-widget"))||null,U=({iframeUrl:t,launcherIcon:s})=>{const n=document.querySelector("[data-copilot-widget-root]");n&&n.remove();const l=w=>{const a=document.querySelector("[data-copilot-checkout-toast]");a&&a.remove();const h=document.createElement("div");h.setAttribute("data-copilot-checkout-toast","true"),h.innerText=w,Object.assign(h.style,{position:"fixed",top:"20px",left:"50%",transform:"translateX(-50%)",padding:"12px 16px",background:"#0f172a",color:"white",borderRadius:"12px",boxShadow:"0 8px 24px rgba(0,0,0,0.25)",zIndex:2147483647,fontSize:"14px",fontWeight:"600",maxWidth:"420px",lineHeight:"1.4",textAlign:"center"}),document.body.appendChild(h),setTimeout(()=>{h.remove()},4500)},c=document.createElement("div");c.setAttribute("data-copilot-widget-root","true");const C=c.attachShadow({mode:"open"});document.body.appendChild(c);const e=document.createElement("button");e.type="button",e.setAttribute("aria-label","Open Copilot chat"),e.innerHTML=`
2
2
  <img
3
3
  src="${s}"
4
4
  alt="Copilot chat launcher"
5
5
  style="width: 38px; height: 38px; object-fit: contain; border-radius: 50%; pointer-events: none;"
6
6
  />
7
- `,Object.assign(e.style,{position:"fixed",bottom:"24px",right:"24px",width:`${b}px`,height:`${b}px`,borderRadius:"50%",border:"none",background:"linear-gradient(135deg, #0078ff, #00c6ff)",color:"white",cursor:"pointer",zIndex:999998,display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 6px 14px rgba(0,0,0,0.25)",transition:"all 0.25s ease"}),e.onmouseover=()=>{e.style.transform="scale(1.12)",e.style.boxShadow="0 10px 25px rgba(0,0,0,0.3)"},e.onmouseout=()=>{e.style.transform="scale(1)",e.style.boxShadow="0 6px 14px rgba(0,0,0,0.25)"};const i=document.createElement("div");i.setAttribute("data-copilot-widget-root","true"),Object.assign(i.style,{display:"none",position:"fixed",bottom:`${b+36}px`,right:"24px",zIndex:"999999",transformOrigin:"bottom right",transform:"scale(0.8) translateY(20px)",opacity:"0",transition:"all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55)"});const o=document.createElement("div"),r=document.createElement("div"),m=document.createElement("div");Object.assign(o.style,{position:"absolute",bottom:"-14px",right:"28px",width:"30px",height:"20px",pointerEvents:"none",display:"none",zIndex:"1"}),Object.assign(r.style,{position:"absolute",bottom:"0",left:"0",right:"0",margin:"0 auto",width:"0",height:"0",borderLeft:"15px solid transparent",borderRight:"15px solid transparent",borderTop:"15px solid rgba(15,23,42,0.1)"}),Object.assign(m.style,{position:"absolute",bottom:"2px",left:"0",right:"0",margin:"0 auto",width:"0",height:"0",borderLeft:"13px solid transparent",borderRight:"13px solid transparent",borderTop:"13px solid white",boxShadow:"0 6px 16px rgba(15,23,42,0.12)",borderRadius:"2px"}),o.appendChild(r),o.appendChild(m);const p=document.createElement("div");Object.assign(p.style,{width:`${y}px`,maxWidth:"calc(100vw - 48px)",height:`${Math.min(y,Math.max(320,window.innerHeight-140))}px`,maxHeight:"calc(100vh - 150px)",borderRadius:"20px",background:"white",border:"1px solid rgba(15,23,42,0.12)",boxShadow:"0 18px 45px rgba(15,23,42,0.16)",overflow:"hidden"}),C.appendChild(p);const d=document.createElement("iframe");d.src=t,d.title="Copilot chat widget",d.allow="clipboard-read; clipboard-write; microphone; camera; display-capture",d.setAttribute("scrolling","no"),Object.assign(d.style,{width:"100%",height:"100%",border:"none",display:"block",background:"transparent",overflow:"hidden"}),C.appendChild(p),p.appendChild(d),i.appendChild(o),i.appendChild(p),document.body.appendChild(e),document.body.appendChild(i);let u=!1;const f=()=>{u&&(u=!1,i.style.opacity="0",i.style.transform="scale(0.8) translateY(20px)",o.style.display="none",setTimeout(()=>{i.style.display="none"},250),e.style.transform="scale(1)")},O=w=>{const{data:a,source:h}=w||{};if(a?.type){if(a.type==="CART_CHECKOUT"&&h===d.contentWindow){console.log("[CopilotChat] Received checkout payload from widget:",a),l("Checkout message received from chat widget. Check console for payload.");return}if(a.type==="WIDGET_READY"&&h===d.contentWindow){d.contentWindow.postMessage({type:"INIT_WIDGET"},"*");return}a.type==="CHAT_CLOSED"&&f()}};e.onclick=w=>{w.stopPropagation(),u=!u,u?(i.style.display="block",o.style.display="block",requestAnimationFrame(()=>{i.style.opacity="1",i.style.transform="scale(1) translateY(0)"})):f()},window.addEventListener("message",O),document.addEventListener("click",w=>{const a=w.target;a&&u&&!i.contains(a)&&a!==e&&f()});const g={close:f,open:()=>{u||e.click()}};return window.CopilotChat=window.CopilotChat||{},window.CopilotChat.close=g.close,window.CopilotChat.open=g.open,window.CopilotChat.controls=g,g},E=t=>{console.error(`[CopilotChat] ${t}`)},A=()=>{const t=v();if(!t)return!1;const s=k(t),n=t.dataset||{},l=n.token||s.token,c=typeof window<"u"&&window.CopilotChatConfig&&window.CopilotChatConfig.token;return(l||c)&&n.autoload!=="false"},S=async(t={})=>{const s=t.scriptEl||v(),n=window.CopilotChatConfig||{},l=s?.dataset||{},c=k(s),e=(()=>{const o=t.token||n.token||l.token||c.token;if(o)return o;try{const r=window.localStorage.getItem("copilotChatToken");if(r)return r}catch{}if(typeof window<"u"&&typeof window.prompt=="function"){const r=window.prompt("Enter your Copilot Chat token:");if(r){try{window.localStorage.setItem("copilotChatToken",r)}catch{}return r}}return null})();if(!e)return E("Missing token (provide via init config, window.CopilotChatConfig.token, or data-token attribute)."),null;const i=t.baseUrl||n.baseUrl||l.baseUrl||c.baseUrl||T;try{const o=await fetch(`${i}/api/chat-widget/config?token=${encodeURIComponent(e)}`,{credentials:"omit",mode:"cors"});if(!o.ok)throw new Error(`Server responded with ${o.status}`);const r=await o.json();if(!r?.iframeUrl||!r?.launcherIcon)throw new Error("Received incomplete widget configuration from server.");return window.CopilotChat=window.CopilotChat||{},window.CopilotChat.init=(p={})=>{const d={iframeUrl:p.iframeUrl||r.iframeUrl,launcherIcon:p.launcherIcon||r.launcherIcon};return U(d)},window.CopilotChat.init(t)}catch(o){return E(o instanceof Error?o.message:"Unknown error during widget bootstrap."),null}};A()&&I(()=>{S()}),window.CopilotChat=window.CopilotChat||{},window.CopilotChat.load=S})()})();
7
+ `,Object.assign(e.style,{position:"fixed",bottom:"24px",right:"24px",width:`${b}px`,height:`${b}px`,borderRadius:"50%",border:"none",background:"linear-gradient(135deg, #0078ff, #00c6ff)",color:"white",cursor:"pointer",zIndex:999998,display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 6px 14px rgba(0,0,0,0.25)",transition:"all 0.25s ease"}),e.onmouseover=()=>{e.style.transform="scale(1.12)",e.style.boxShadow="0 10px 25px rgba(0,0,0,0.3)"},e.onmouseout=()=>{e.style.transform="scale(1)",e.style.boxShadow="0 6px 14px rgba(0,0,0,0.25)"};const i=document.createElement("div");i.setAttribute("data-copilot-widget-root","true"),Object.assign(i.style,{display:"none",position:"fixed",bottom:`${b+36}px`,right:"24px",zIndex:"999999",transformOrigin:"bottom right",transform:"scale(0.8) translateY(20px)",opacity:"0",transition:"all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55)"});const o=document.createElement("div"),r=document.createElement("div"),m=document.createElement("div");Object.assign(o.style,{position:"absolute",bottom:"-14px",right:"28px",width:"30px",height:"20px",pointerEvents:"none",display:"none",zIndex:"1"}),Object.assign(r.style,{position:"absolute",bottom:"0",left:"0",right:"0",margin:"0 auto",width:"0",height:"0",borderLeft:"15px solid transparent",borderRight:"15px solid transparent",borderTop:"15px solid rgba(15,23,42,0.1)"}),Object.assign(m.style,{position:"absolute",bottom:"2px",left:"0",right:"0",margin:"0 auto",width:"0",height:"0",borderLeft:"13px solid transparent",borderRight:"13px solid transparent",borderTop:"13px solid white",boxShadow:"0 6px 16px rgba(15,23,42,0.12)",borderRadius:"2px"}),o.appendChild(r),o.appendChild(m);const p=document.createElement("div");Object.assign(p.style,{width:`${x}px`,maxWidth:"calc(100vw - 48px)",height:`${Math.min(x,Math.max(320,window.innerHeight-140))}px`,maxHeight:"calc(100vh - 150px)",borderRadius:"20px",background:"white",border:"1px solid rgba(15,23,42,0.12)",boxShadow:"0 18px 45px rgba(15,23,42,0.16)",overflow:"hidden"}),C.appendChild(p);const d=document.createElement("iframe");d.src=t,d.title="Copilot chat widget",d.allow="clipboard-read; clipboard-write; microphone; camera; display-capture",d.setAttribute("scrolling","no"),Object.assign(d.style,{width:"100%",height:"100%",border:"none",display:"block",background:"transparent",overflow:"hidden"}),C.appendChild(p),p.appendChild(d),i.appendChild(o),i.appendChild(p),document.body.appendChild(e),document.body.appendChild(i);let u=!1;const f=()=>{u&&(u=!1,i.style.opacity="0",i.style.transform="scale(0.8) translateY(20px)",o.style.display="none",setTimeout(()=>{i.style.display="none"},250),e.style.transform="scale(1)")},O=w=>{const{data:a,source:h}=w||{};if(a?.type){if(a.type==="CART_CHECKOUT"&&h===d.contentWindow){console.log("[CopilotChat] Received checkout payload from widget:",a),l("Data:");return}if(a.type==="WIDGET_READY"&&h===d.contentWindow){d.contentWindow.postMessage({type:"INIT_WIDGET"},"*");return}a.type==="CHAT_CLOSED"&&f()}};e.onclick=w=>{w.stopPropagation(),u=!u,u?(i.style.display="block",o.style.display="block",requestAnimationFrame(()=>{i.style.opacity="1",i.style.transform="scale(1) translateY(0)"})):f()},window.addEventListener("message",O),document.addEventListener("click",w=>{const a=w.target;a&&u&&!i.contains(a)&&a!==e&&f()});const g={close:f,open:()=>{u||e.click()}};return window.CopilotChat=window.CopilotChat||{},window.CopilotChat.close=g.close,window.CopilotChat.open=g.open,window.CopilotChat.controls=g,g},v=t=>{console.error(`[CopilotChat] ${t}`)},A=()=>{const t=E();if(!t)return!1;const s=k(t),n=t.dataset||{},l=n.token||s.token,c=typeof window<"u"&&window.CopilotChatConfig&&window.CopilotChatConfig.token;return(l||c)&&n.autoload!=="false"},S=async(t={})=>{const s=t.scriptEl||E(),n=window.CopilotChatConfig||{},l=s?.dataset||{},c=k(s),e=(()=>{const o=t.token||n.token||l.token||c.token;if(o)return o;try{const r=window.localStorage.getItem("copilotChatToken");if(r)return r}catch{}if(typeof window<"u"&&typeof window.prompt=="function"){const r=window.prompt("Enter your Copilot Chat token:");if(r){try{window.localStorage.setItem("copilotChatToken",r)}catch{}return r}}return null})();if(!e)return v("Missing token (provide via init config, window.CopilotChatConfig.token, or data-token attribute)."),null;const i=t.baseUrl||n.baseUrl||l.baseUrl||c.baseUrl||T;try{const o=await fetch(`${i}/api/chat-widget/config?token=${encodeURIComponent(e)}`,{credentials:"omit",mode:"cors"});if(!o.ok)throw new Error(`Server responded with ${o.status}`);const r=await o.json();if(!r?.iframeUrl||!r?.launcherIcon)throw new Error("Received incomplete widget configuration from server.");return window.CopilotChat=window.CopilotChat||{},window.CopilotChat.init=(p={})=>{const d={iframeUrl:p.iframeUrl||r.iframeUrl,launcherIcon:p.launcherIcon||r.launcherIcon};return U(d)},window.CopilotChat.init(t)}catch(o){return v(o instanceof Error?o.message:"Unknown error during widget bootstrap."),null}};A()&&I(()=>{S()}),window.CopilotChat=window.CopilotChat||{},window.CopilotChat.load=S})()})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "copilot-chat-widget",
3
- "version": "0.1.27",
3
+ "version": "0.1.28",
4
4
  "description": "Embeddable Copilot chat widget that can be loaded via NPM or a script tag.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -27,7 +27,10 @@
27
27
  };
28
28
 
29
29
  const ready = (fn) => {
30
- if (document.readyState === "complete" || document.readyState === "interactive") {
30
+ if (
31
+ document.readyState === "complete" ||
32
+ document.readyState === "interactive"
33
+ ) {
31
34
  setTimeout(fn, 0);
32
35
  } else {
33
36
  document.addEventListener("DOMContentLoaded", fn);
@@ -40,7 +43,10 @@
40
43
  const srcUrl = new URL(scriptEl.src, window.location.href);
41
44
  return `${srcUrl.protocol}//${srcUrl.host}`;
42
45
  } catch (error) {
43
- console.warn("[CopilotChat] Unable to infer base URL from script source.", error);
46
+ console.warn(
47
+ "[CopilotChat] Unable to infer base URL from script source.",
48
+ error
49
+ );
44
50
  return null;
45
51
  }
46
52
  };
@@ -53,7 +59,11 @@
53
59
  const scripts = Array.from(document.querySelectorAll("script"));
54
60
  const candidate = scripts
55
61
  .reverse()
56
- .find((script) => script.dataset?.token || (script.src && script.src.includes("chat-widget")));
62
+ .find(
63
+ (script) =>
64
+ script.dataset?.token ||
65
+ (script.src && script.src.includes("chat-widget"))
66
+ );
57
67
 
58
68
  return candidate || null;
59
69
  };
@@ -65,7 +75,9 @@
65
75
  }
66
76
 
67
77
  const showCheckoutToast = (message) => {
68
- const existingToast = document.querySelector("[data-copilot-checkout-toast]");
78
+ const existingToast = document.querySelector(
79
+ "[data-copilot-checkout-toast]"
80
+ );
69
81
  if (existingToast) {
70
82
  existingToast.remove();
71
83
  }
@@ -223,7 +235,8 @@
223
235
  const iframe = document.createElement("iframe");
224
236
  iframe.src = iframeUrl;
225
237
  iframe.title = "Copilot chat widget";
226
- iframe.allow = "clipboard-read; clipboard-write; microphone; camera; display-capture";
238
+ iframe.allow =
239
+ "clipboard-read; clipboard-write; microphone; camera; display-capture";
227
240
  iframe.setAttribute("scrolling", "no");
228
241
  Object.assign(iframe.style, {
229
242
  width: "100%",
@@ -261,8 +274,12 @@
261
274
  if (!data?.type) return;
262
275
 
263
276
  if (data.type === "CART_CHECKOUT" && source === iframe.contentWindow) {
264
- console.log("[CopilotChat] Received checkout payload from widget:", data);
265
- showCheckoutToast("Checkout message received from chat widget. Check console for payload.");
277
+ console.log(
278
+ "[CopilotChat] Received checkout payload from widget:",
279
+ data
280
+ );
281
+ showCheckoutToast("Data:", data);
282
+
266
283
  return;
267
284
  }
268
285
 
@@ -328,7 +345,10 @@
328
345
  const queryConfig = readQueryConfig(scriptEl);
329
346
  const dataset = scriptEl.dataset || {};
330
347
  const hasTokenHint = dataset.token || queryConfig.token;
331
- const hasGlobalToken = typeof window !== "undefined" && window.CopilotChatConfig && window.CopilotChatConfig.token;
348
+ const hasGlobalToken =
349
+ typeof window !== "undefined" &&
350
+ window.CopilotChatConfig &&
351
+ window.CopilotChatConfig.token;
332
352
  return (hasTokenHint || hasGlobalToken) && dataset.autoload !== "false";
333
353
  };
334
354
 
@@ -339,7 +359,11 @@
339
359
  const queryConfig = readQueryConfig(scriptEl);
340
360
 
341
361
  const resolveToken = () => {
342
- const fromConfig = config.token || globalConfig.token || datasetConfig.token || queryConfig.token;
362
+ const fromConfig =
363
+ config.token ||
364
+ globalConfig.token ||
365
+ datasetConfig.token ||
366
+ queryConfig.token;
343
367
  if (fromConfig) return fromConfig;
344
368
 
345
369
  try {
@@ -349,7 +373,10 @@
349
373
  // ignore storage errors
350
374
  }
351
375
 
352
- if (typeof window !== "undefined" && typeof window.prompt === "function") {
376
+ if (
377
+ typeof window !== "undefined" &&
378
+ typeof window.prompt === "function"
379
+ ) {
353
380
  const entered = window.prompt("Enter your Copilot Chat token:");
354
381
  if (entered) {
355
382
  try {
@@ -367,7 +394,9 @@
367
394
  const token = resolveToken();
368
395
 
369
396
  if (!token) {
370
- handleError("Missing token (provide via init config, window.CopilotChatConfig.token, or data-token attribute).");
397
+ handleError(
398
+ "Missing token (provide via init config, window.CopilotChatConfig.token, or data-token attribute)."
399
+ );
371
400
  return null;
372
401
  }
373
402
 
@@ -382,15 +411,20 @@
382
411
  null;
383
412
 
384
413
  if (!baseUrl) {
385
- handleError("Unable to resolve base URL from embedding script or window.location.");
414
+ handleError(
415
+ "Unable to resolve base URL from embedding script or window.location."
416
+ );
386
417
  return null;
387
418
  }
388
419
 
389
420
  try {
390
- const response = await fetch(`${baseUrl}/api/chat-widget/config?token=${encodeURIComponent(token)}`, {
391
- credentials: "omit",
392
- mode: "cors",
393
- });
421
+ const response = await fetch(
422
+ `${baseUrl}/api/chat-widget/config?token=${encodeURIComponent(token)}`,
423
+ {
424
+ credentials: "omit",
425
+ mode: "cors",
426
+ }
427
+ );
394
428
 
395
429
  if (!response.ok) {
396
430
  throw new Error(`Server responded with ${response.status}`);
@@ -398,7 +432,9 @@
398
432
 
399
433
  const remoteConfig = await response.json();
400
434
  if (!remoteConfig?.iframeUrl || !remoteConfig?.launcherIcon) {
401
- throw new Error("Received incomplete widget configuration from server.");
435
+ throw new Error(
436
+ "Received incomplete widget configuration from server."
437
+ );
402
438
  }
403
439
 
404
440
  window.CopilotChat = window.CopilotChat || {};
@@ -414,7 +450,11 @@
414
450
  const controls = window.CopilotChat.init(config);
415
451
  return controls;
416
452
  } catch (error) {
417
- handleError(error instanceof Error ? error.message : "Unknown error during widget bootstrap.");
453
+ handleError(
454
+ error instanceof Error
455
+ ? error.message
456
+ : "Unknown error during widget bootstrap."
457
+ );
418
458
  return null;
419
459
  }
420
460
  };