@yassirbenmoussa/aicommerce-sdk 1.9.0 → 1.9.1
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/ai-commerce.min.js +55 -35
- package/dist/index.cjs +37 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +37 -10
- package/dist/index.mjs.map +1 -1
- package/dist/widget.min.js +37 -17
- package/dist/widget.min.js.map +1 -1
- package/package.json +1 -1
package/dist/ai-commerce.min.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var AICommerceSDK=(function(exports){'use strict';/*! AI Commerce SDK v1.0.0 | MIT License | https://aicommerce.dev */
|
|
2
|
-
var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object.getOwnPropertyNames;var pe=Object.prototype.hasOwnProperty;var H=(
|
|
2
|
+
var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object.getOwnPropertyNames;var pe=Object.prototype.hasOwnProperty;var H=(a,r)=>()=>(a&&(r=a(a=0)),r);var G=(a,r)=>{for(var e in r)B(a,e,{get:r[e],enumerable:true});},ue=(a,r,e,d)=>{if(r&&typeof r=="object"||typeof r=="function")for(let h of le(r))!pe.call(a,h)&&h!==e&&B(a,h,{get:()=>r[h],enumerable:!(d=me(r,h))||d.enumerable});return a};var j=a=>ue(B({},"__esModule",{value:true}),a);var W={};G(W,{AICommerce:()=>exports.AICommerce,AICommerceError:()=>exports.AICommerceError});exports.AICommerce=void 0;exports.AICommerceError=void 0;var R=H(()=>{exports.AICommerce=class a{constructor(r){this.sessionToken=null;this.products={create:async r=>this.request("/api/v1/products",{method:"POST",body:JSON.stringify(r)}),batchUpsert:async r=>this.request("/api/v1/products",{method:"POST",body:JSON.stringify({products:r})}),list:async r=>{let e=new URLSearchParams;r?.page&&e.set("page",String(r.page)),r?.perPage&&e.set("perPage",String(r.perPage)),r?.search&&e.set("search",r.search),r?.categoryId&&e.set("categoryId",r.categoryId),r?.isActive!==void 0&&e.set("isActive",String(r.isActive));let d=e.toString();return this.request(`/api/v1/products${d?`?${d}`:""}`)},get:async r=>this.request(`/api/v1/products/${r}`),update:async(r,e)=>this.request(`/api/v1/products/${r}`,{method:"PUT",body:JSON.stringify(e)}),delete:async r=>this.request(`/api/v1/products/${r}`,{method:"DELETE"})};if(!r.apiKey)throw new Error("AICommerce: apiKey is required");this.apiKey=r.apiKey,this.storeId=r.storeId,this.baseUrl=this.normalizeUrl(r.baseUrl||this.detectBaseUrl()),this.timeout=r.timeout||3e4;}detectBaseUrl(){if(typeof window<"u"){let r=document.querySelector("script[data-aicommerce-url]");if(r)return r.getAttribute("data-aicommerce-url")||"https://api.aicommerce.dev"}return "https://api.aicommerce.dev"}normalizeUrl(r){return r.replace(/\/$/,"")}async request(r,e={}){let d=`${this.baseUrl}${r}`,h=new AbortController,s=setTimeout(()=>h.abort(),this.timeout);try{let g=await fetch(d,{...e,signal:h.signal,headers:{"Content-Type":"application/json","x-api-key":this.apiKey,...this.storeId&&{"x-store-id":this.storeId},...this.sessionToken&&{"X-Session-Token":this.sessionToken},...e.headers}});if(clearTimeout(s),!g.ok){let S=await g.json().catch(()=>({})),w={code:S.code||"UNKNOWN_ERROR",message:S.message||S.error||`HTTP ${g.status}`,status:g.status};throw new exports.AICommerceError(w.message,w.code,w.status)}return g.json()}catch(g){throw clearTimeout(s),g instanceof exports.AICommerceError?g:g instanceof Error&&g.name==="AbortError"?new exports.AICommerceError("Request timeout","TIMEOUT",408):new exports.AICommerceError(g instanceof Error?g.message:"Unknown error","NETWORK_ERROR",0)}}async chat(r,e){let d=typeof r=="string"?{message:r,context:e,sessionToken:this.sessionToken||void 0}:{...r,sessionToken:r.sessionToken||this.sessionToken||void 0},h=await this.request("/api/v1/chat",{method:"POST",body:JSON.stringify(d)});return h.sessionToken&&(this.sessionToken=h.sessionToken),h}async chatWithAudio(r,e){let d=await r.arrayBuffer(),s={audioBase64:btoa(new Uint8Array(d).reduce((S,w)=>S+String.fromCharCode(w),"")),audioMimeType:r.type||"audio/webm",context:e,sessionToken:this.sessionToken||void 0},g=await this.request("/api/v1/chat",{method:"POST",body:JSON.stringify(s)});return g.sessionToken&&(this.sessionToken=g.sessionToken),g}async createSession(){let r=await this.request("/api/v1/chat/session",{method:"POST"});return this.sessionToken=r.session.token,r.session}clearSession(){this.sessionToken=null;}getSessionToken(){return this.sessionToken}setSessionToken(r){this.sessionToken=r;}async upload(r,e){let d=new FormData;d.append("file",r),e?.folder&&d.append("folder",e.folder),e?.productId&&d.append("productId",e.productId),e?.isPrimary&&d.append("isPrimary","true");let h=`${this.baseUrl}/api/v1/upload`,s=await fetch(h,{method:"POST",headers:{"X-API-Key":this.apiKey},body:d});if(!s.ok){let g=await s.json().catch(()=>({}));throw new exports.AICommerceError(g.message||g.error||`HTTP ${s.status}`,g.code||"UPLOAD_ERROR",s.status)}return s.json()}static async quickChat(r){return new a({apiKey:r.apiKey,baseUrl:r.baseUrl}).chat(r.message,r.context)}},exports.AICommerceError=class a extends Error{constructor(r,e,d){super(r),this.name="AICommerceError",this.code=e,this.status=d,Object.setPrototypeOf(this,a.prototype);}};});function ge(a){let r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(a);return r?{r:parseInt(r[1],16),g:parseInt(r[2],16),b:parseInt(r[3],16)}:{r:99,g:102,b:241}}function z(a){let r=a.primaryColor,e=ge(r),d=a.position==="bottom-left";return `
|
|
3
3
|
/* AI Commerce Widget Styles */
|
|
4
4
|
#aicommerce-widget {
|
|
5
5
|
--aic-primary: ${r};
|
|
@@ -13,14 +13,14 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
13
13
|
--aic-border: #e2e8f0;
|
|
14
14
|
--aic-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
|
15
15
|
--aic-radius: 16px;
|
|
16
|
-
--aic-z-index: ${
|
|
16
|
+
--aic-z-index: ${a.zIndex};
|
|
17
17
|
|
|
18
18
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
|
|
19
19
|
font-size: 14px;
|
|
20
20
|
line-height: 1.5;
|
|
21
21
|
position: fixed;
|
|
22
22
|
bottom: 20px;
|
|
23
|
-
${
|
|
23
|
+
${d?"left: 20px;":"right: 20px;"}
|
|
24
24
|
z-index: var(--aic-z-index);
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -74,7 +74,7 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
74
74
|
.aicommerce-chat {
|
|
75
75
|
position: absolute;
|
|
76
76
|
bottom: 0;
|
|
77
|
-
${
|
|
77
|
+
${d?"left: 0;":"right: 0;"}
|
|
78
78
|
width: 380px;
|
|
79
79
|
max-width: calc(100vw - 40px);
|
|
80
80
|
height: 600px;
|
|
@@ -86,7 +86,7 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
86
86
|
flex-direction: column;
|
|
87
87
|
overflow: hidden;
|
|
88
88
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
89
|
-
transform-origin: bottom ${
|
|
89
|
+
transform-origin: bottom ${d?"left":"right"};
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
.aicommerce-chat.aicommerce-closed {
|
|
@@ -515,7 +515,7 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
515
515
|
@media (max-width: 420px) {
|
|
516
516
|
#aicommerce-widget {
|
|
517
517
|
bottom: 16px;
|
|
518
|
-
${
|
|
518
|
+
${d?"left: 16px;":"right: 16px;"}
|
|
519
519
|
}
|
|
520
520
|
|
|
521
521
|
.aicommerce-chat {
|
|
@@ -552,7 +552,7 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
552
552
|
Embedded Mode Styles - ChatGPT Style
|
|
553
553
|
============================================ */
|
|
554
554
|
|
|
555
|
-
/* Embedded container -
|
|
555
|
+
/* Embedded container - starts small, grows to max-height, then scrolls */
|
|
556
556
|
#aicommerce-widget.aicommerce-embedded {
|
|
557
557
|
position: relative;
|
|
558
558
|
bottom: auto;
|
|
@@ -560,6 +560,7 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
560
560
|
right: auto;
|
|
561
561
|
width: 100%;
|
|
562
562
|
height: auto;
|
|
563
|
+
min-height: 80px;
|
|
563
564
|
max-height: var(--aic-max-height, 600px);
|
|
564
565
|
display: flex;
|
|
565
566
|
flex-direction: column;
|
|
@@ -581,11 +582,12 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
581
582
|
display: none !important;
|
|
582
583
|
}
|
|
583
584
|
|
|
584
|
-
/* Embedded mode: chat
|
|
585
|
+
/* Embedded mode: chat container grows with content */
|
|
585
586
|
.aicommerce-embedded .aicommerce-chat {
|
|
586
587
|
position: relative;
|
|
587
588
|
width: 100%;
|
|
588
589
|
height: auto;
|
|
590
|
+
max-height: 100%;
|
|
589
591
|
max-width: 100%;
|
|
590
592
|
border-radius: 0;
|
|
591
593
|
background: transparent;
|
|
@@ -604,13 +606,15 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
604
606
|
pointer-events: auto !important;
|
|
605
607
|
}
|
|
606
608
|
|
|
607
|
-
/* Embedded mode: messages area -
|
|
609
|
+
/* Embedded mode: messages area - scrollable when content overflows */
|
|
608
610
|
.aicommerce-embedded .aicommerce-messages {
|
|
611
|
+
flex: 1 1 auto;
|
|
612
|
+
min-height: 0;
|
|
613
|
+
max-height: calc(var(--aic-max-height, 600px) - 100px);
|
|
609
614
|
display: flex;
|
|
610
615
|
flex-direction: column;
|
|
611
|
-
justify-content: flex-
|
|
616
|
+
justify-content: flex-start;
|
|
612
617
|
overflow-y: auto;
|
|
613
|
-
max-height: calc(var(--aic-max-height, 600px) - 100px);
|
|
614
618
|
padding: 16px;
|
|
615
619
|
max-width: 700px;
|
|
616
620
|
margin: 0 auto;
|
|
@@ -735,19 +739,28 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
735
739
|
color: var(--aic-text);
|
|
736
740
|
}
|
|
737
741
|
|
|
738
|
-
/* Embedded mode: product cards styling */
|
|
742
|
+
/* Embedded mode: product cards styling - horizontal scroll like widget mode */
|
|
739
743
|
.aicommerce-embedded .aicommerce-products {
|
|
740
744
|
display: flex;
|
|
741
|
-
flex-wrap:
|
|
745
|
+
flex-wrap: nowrap;
|
|
742
746
|
gap: 12px;
|
|
743
747
|
margin-top: 12px;
|
|
748
|
+
overflow-x: auto;
|
|
749
|
+
padding-bottom: 8px;
|
|
750
|
+
cursor: grab;
|
|
751
|
+
scrollbar-width: none;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
.aicommerce-embedded .aicommerce-products::-webkit-scrollbar {
|
|
755
|
+
display: none;
|
|
744
756
|
}
|
|
745
757
|
|
|
746
758
|
.aicommerce-embedded .aicommerce-product-card {
|
|
759
|
+
flex-shrink: 0;
|
|
760
|
+
width: 180px;
|
|
747
761
|
background: var(--aic-bg);
|
|
748
762
|
border: 1px solid var(--aic-border);
|
|
749
763
|
border-radius: 12px;
|
|
750
|
-
max-width: 180px;
|
|
751
764
|
}
|
|
752
765
|
|
|
753
766
|
/* Embedded mode: typing indicator */
|
|
@@ -842,12 +855,12 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
842
855
|
.aicommerce-spinner {
|
|
843
856
|
animation: aicommerce-spin 1s linear infinite;
|
|
844
857
|
}
|
|
845
|
-
`}function _(
|
|
858
|
+
`}function _(a){let r=document.createElement("style");r.id="aicommerce-widget-styles",r.textContent=a;let e=document.getElementById("aicommerce-widget-styles");return e&&e.remove(),document.head.appendChild(r),r}var Q=H(()=>{});var Z={};G(Z,{AICommerceWidget:()=>exports.AICommerceWidget,createWidget:()=>D});function D(a){if(!a.apiKey)throw new Error("AICommerceWidget: apiKey is required");let r=new exports.AICommerce({apiKey:a.apiKey,storeId:a.storeId,baseUrl:a.baseUrl}),e={isOpen:false,isLoading:true,isRecording:false,messages:[],storeConfig:null},d=null,h=[],s=null,w=null,m;async function ee(){try{let o=a.baseUrl||N(),i=await fetch(`${o}/api/v1/store`,{headers:{"x-api-key":a.apiKey}});return i.ok?(await i.json()).store:null}catch(o){return console.error("Failed to fetch store config:",o),null}}function N(){if(typeof window<"u"){let o=document.querySelector("script[data-aicommerce-url]");if(o)return o.getAttribute("data-aicommerce-url")||""}return "https://api.aicommerce.dev"}async function re(){e.storeConfig=await ee();let o=a.displayMode||"widget",i=o==="embedded";m={apiKey:a.apiKey,storeId:a.storeId,baseUrl:a.baseUrl||N(),displayMode:o,container:a.container,maxHeight:a.maxHeight||"600px",placeholder:a.placeholder||"Ask me anything about our products...",position:a.position||"bottom-right",theme:a.theme||"auto",primaryColor:a.primaryColor||e.storeConfig?.primaryColor||"#6366f1",welcomeMessage:a.welcomeMessage||e.storeConfig?.welcomeMessage||"Hi! How can I help you find the perfect product today?",botName:a.botName||e.storeConfig?.chatBotName||"Shopping Assistant",zIndex:a.zIndex||9999,buttonText:a.buttonText||"\u{1F4AC}",hideLauncher:a.hideLauncher||false,addToCartText:a.addToCartText,onOpen:a.onOpen,onClose:a.onClose,onProductClick:a.onProductClick,onAddToCart:a.onAddToCart,onMessage:a.onMessage};let c=z(m);if(w=_(c),i){let b=null;if(typeof a.container=="string"?b=document.querySelector(a.container):a.container instanceof HTMLElement&&(b=a.container),!b){console.error("[AI Commerce] Embedded mode requires a valid container element or selector");return}s=document.createElement("div"),s.id="aicommerce-widget",s.className=`aicommerce-widget aicommerce-embedded aicommerce-theme-${m.theme}`,s.style.setProperty("--aic-max-height",m.maxHeight),b.appendChild(s),e.isOpen=true;}else s=document.createElement("div"),s.id="aicommerce-widget",s.className=`aicommerce-widget aicommerce-${m.position} aicommerce-theme-${m.theme}`,document.body.appendChild(s);k(),i||e.messages.push({role:"assistant",content:m.welcomeMessage}),e.isLoading=false,k();}async function te(o,i=1){let c=o;if(o.includes("gid://")){let u=o.match(/\/(\d+)$/);u&&(c=u[1]);}if(!(await fetch("/cart/add.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:c,quantity:i})})).ok)throw new Error("Failed to add to cart");document.dispatchEvent(new CustomEvent("cart:refresh"));}function k(){if(!s)return;let o=m.displayMode==="embedded",i=e.messages.some(l=>l.role==="user");o&&(s.classList.remove("aicommerce-no-messages","aicommerce-has-messages"),s.classList.add(i?"aicommerce-has-messages":"aicommerce-no-messages"));let c=m.placeholder||"Ask me anything about our products...",b=`
|
|
846
859
|
<div class="aicommerce-input-container">
|
|
847
|
-
${
|
|
860
|
+
${o?`
|
|
848
861
|
<textarea
|
|
849
862
|
class="aicommerce-input"
|
|
850
|
-
placeholder="${
|
|
863
|
+
placeholder="${c}"
|
|
851
864
|
rows="1"
|
|
852
865
|
${e.isLoading||e.isRecording?"disabled":""}
|
|
853
866
|
></textarea>
|
|
@@ -855,7 +868,7 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
855
868
|
<input
|
|
856
869
|
type="text"
|
|
857
870
|
class="aicommerce-input"
|
|
858
|
-
placeholder="${
|
|
871
|
+
placeholder="${c}"
|
|
859
872
|
${e.isLoading||e.isRecording?"disabled":""}
|
|
860
873
|
/>
|
|
861
874
|
`}
|
|
@@ -880,14 +893,14 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
880
893
|
</button>
|
|
881
894
|
</div>
|
|
882
895
|
`,u=`
|
|
883
|
-
${!
|
|
896
|
+
${!o&&!m.hideLauncher?`
|
|
884
897
|
<button class="aicommerce-launcher ${e.isOpen?"aicommerce-hidden":""}" aria-label="Open chat">
|
|
885
898
|
<span class="aicommerce-launcher-icon">${m.buttonText}</span>
|
|
886
899
|
</button>
|
|
887
900
|
`:""}
|
|
888
901
|
|
|
889
902
|
<div class="aicommerce-chat ${e.isOpen?"aicommerce-open":"aicommerce-closed"}">
|
|
890
|
-
${
|
|
903
|
+
${o?"":`
|
|
891
904
|
<div class="aicommerce-header">
|
|
892
905
|
<div class="aicommerce-header-info">
|
|
893
906
|
<div class="aicommerce-avatar">
|
|
@@ -902,17 +915,17 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
902
915
|
</div>
|
|
903
916
|
`}
|
|
904
917
|
|
|
905
|
-
${
|
|
918
|
+
${o&&i?`
|
|
906
919
|
<div class="aicommerce-messages">
|
|
907
|
-
${e.messages.map((l,
|
|
920
|
+
${e.messages.map((l,L)=>{let A=J(l.content),n=l.role==="user";return `
|
|
908
921
|
<div class="aicommerce-message aicommerce-${l.role}">
|
|
909
922
|
<div class="aicommerce-message-content ${A?"aicommerce-rtl":"aicommerce-ltr"}">
|
|
910
|
-
${l.audioUrl?Y(l,
|
|
923
|
+
${l.audioUrl?Y(l,L,n):T(l.content)}
|
|
911
924
|
</div>
|
|
912
925
|
${l.products&&l.products.length>0?`
|
|
913
926
|
<div class="aicommerce-products">
|
|
914
927
|
${l.products.map(t=>`
|
|
915
|
-
<div class="aicommerce-product-card" data-product-id="${t.id}">
|
|
928
|
+
<div class="aicommerce-product-card" data-product-id="${t.id}" data-variant-id="${t.variantId||""}">
|
|
916
929
|
${t.image||t.imageUrl?`
|
|
917
930
|
<img src="${t.image||t.imageUrl}" alt="${T(t.name)}" class="aicommerce-product-image" />
|
|
918
931
|
`:`
|
|
@@ -922,6 +935,13 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
922
935
|
<span class="aicommerce-product-name" title="${T(t.name)}">${T(t.name)}</span>
|
|
923
936
|
${t.description?`<p class="aicommerce-product-desc">${T(t.description)}</p>`:""}
|
|
924
937
|
<span class="aicommerce-product-price">${X(t.price,t.currency)}</span>
|
|
938
|
+
<button class="aicommerce-add-to-cart" data-product-id="${t.id}">
|
|
939
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
940
|
+
<circle cx="9" cy="21" r="1"/><circle cx="20" cy="21" r="1"/>
|
|
941
|
+
<path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"/>
|
|
942
|
+
</svg>
|
|
943
|
+
${m.addToCartText||"Add to Cart"}
|
|
944
|
+
</button>
|
|
925
945
|
</div>
|
|
926
946
|
</div>
|
|
927
947
|
`).join("")}
|
|
@@ -939,12 +959,12 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
939
959
|
</div>
|
|
940
960
|
`:""}
|
|
941
961
|
|
|
942
|
-
${
|
|
962
|
+
${o?"":`
|
|
943
963
|
<div class="aicommerce-messages">
|
|
944
|
-
${e.messages.map((l,
|
|
964
|
+
${e.messages.map((l,L)=>{let A=J(l.content),n=l.role==="user";return `
|
|
945
965
|
<div class="aicommerce-message aicommerce-${l.role}">
|
|
946
966
|
<div class="aicommerce-message-content ${A?"aicommerce-rtl":"aicommerce-ltr"}">
|
|
947
|
-
${l.audioUrl?Y(l,
|
|
967
|
+
${l.audioUrl?Y(l,L,n):T(l.content)}
|
|
948
968
|
</div>
|
|
949
969
|
${l.products&&l.products.length>0?`
|
|
950
970
|
<div class="aicommerce-products">
|
|
@@ -983,31 +1003,31 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
983
1003
|
</div>
|
|
984
1004
|
`}
|
|
985
1005
|
|
|
986
|
-
${
|
|
1006
|
+
${o?`
|
|
987
1007
|
<div class="aicommerce-input-wrapper">
|
|
988
1008
|
${b}
|
|
989
1009
|
</div>
|
|
990
1010
|
`:b}
|
|
991
1011
|
</div>
|
|
992
|
-
`;s.innerHTML=u,oe();let E=s.querySelector(".aicommerce-messages");E&&(E.scrollTop=E.scrollHeight);}function Y(
|
|
1012
|
+
`;s.innerHTML=u,oe();let E=s.querySelector(".aicommerce-messages");E&&(E.scrollTop=E.scrollHeight);}function Y(o,i,c){return `
|
|
993
1013
|
<div class="aicommerce-audio-player" data-message-index="${i}">
|
|
994
1014
|
<button class="aicommerce-audio-btn">
|
|
995
1015
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
|
|
996
1016
|
</button>
|
|
997
1017
|
<div class="aicommerce-audio-waveform">
|
|
998
1018
|
<div class="aicommerce-waveform-bars">
|
|
999
|
-
${(
|
|
1000
|
-
<div class="aicommerce-waveform-bar" style="height: ${b}%; background-color: ${
|
|
1019
|
+
${(o.waveformBars||Array(40).fill(10)).map(b=>`
|
|
1020
|
+
<div class="aicommerce-waveform-bar" style="height: ${b}%; background-color: ${c?"rgba(255,255,255,0.4)":"rgba(99,102,241,0.3)"}"></div>
|
|
1001
1021
|
`).join("")}
|
|
1002
1022
|
</div>
|
|
1003
1023
|
<div class="aicommerce-audio-time">
|
|
1004
1024
|
<span class="aicommerce-current-time">0:00</span>
|
|
1005
|
-
<span>${V(
|
|
1025
|
+
<span>${V(o.audioDuration||0)}</span>
|
|
1006
1026
|
</div>
|
|
1007
1027
|
</div>
|
|
1008
|
-
<audio src="${
|
|
1028
|
+
<audio src="${o.audioUrl}" preload="metadata"></audio>
|
|
1009
1029
|
</div>
|
|
1010
|
-
`}function oe(){if(!s)return;let
|
|
1030
|
+
`}function oe(){if(!s)return;let o=s.querySelector(".aicommerce-launcher");o&&o.addEventListener("click",()=>q());let i=s.querySelector(".aicommerce-close");i&&i.addEventListener("click",()=>O());let c=s.querySelector(".aicommerce-input"),b=s.querySelector(".aicommerce-send");c&&(c.addEventListener("keydown",n=>{let t=n;if(t.key==="Enter"){let p=c instanceof HTMLTextAreaElement;if(p&&t.shiftKey)return;n.preventDefault();let f=c.value.trim();f&&(U(f),c.value="",p&&(c.style.height="auto"));}}),c instanceof HTMLTextAreaElement&&c.addEventListener("input",()=>{c.style.height="auto",c.style.height=Math.min(c.scrollHeight,150)+"px";})),b&&c&&b.addEventListener("click",()=>{let n=c.value.trim();n&&(U(n),c.value="",c instanceof HTMLTextAreaElement&&(c.style.height="auto"));});let u=s.querySelector(".aicommerce-mic");u&&u.addEventListener("click",()=>ae()),s.querySelectorAll(".aicommerce-product-card").forEach(n=>{n.addEventListener("click",t=>{if(t.target.closest(".aicommerce-add-to-cart"))return;let p=n.getAttribute("data-product-id"),f=e.messages.flatMap(y=>y.products||[]).find(y=>y.id===p);f&&(m.onProductClick?m.onProductClick(f):f.url&&window.open(f.url,"_blank","noopener,noreferrer"));});}),s.querySelectorAll(".aicommerce-add-to-cart").forEach(n=>{n.addEventListener("click",async t=>{t.stopPropagation();let p=n,f=p.closest(".aicommerce-product-card"),y=f?.getAttribute("data-product-id"),x=f?.getAttribute("data-variant-id"),C=e.messages.flatMap($=>$.products||[]).find($=>$.id===y);if(!C)return;let v=p.innerHTML;p.disabled=true,p.innerHTML=`
|
|
1011
1031
|
<svg class="aicommerce-spinner" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
1012
1032
|
<circle cx="12" cy="12" r="10" stroke-dasharray="32" stroke-dashoffset="32"/>
|
|
1013
1033
|
</svg>
|
|
@@ -1017,5 +1037,5 @@ var B=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var le=Object
|
|
|
1017
1037
|
<polyline points="20 6 9 17 4 12"/>
|
|
1018
1038
|
</svg>
|
|
1019
1039
|
Added!
|
|
1020
|
-
`,setTimeout(()=>{p.innerHTML=v,p.disabled=!1;},2e3);}catch(
|
|
1040
|
+
`,setTimeout(()=>{p.innerHTML=v,p.disabled=!1;},2e3);}catch($){console.error("[AI Commerce] Add to cart failed:",$),p.innerHTML=v,p.disabled=false;}});}),s.querySelectorAll(".aicommerce-products").forEach(n=>{let t=false,p=0,f=0;n.addEventListener("mousedown",y=>{t=true,n.style.cursor="grabbing",p=y.pageX-n.offsetLeft,f=n.scrollLeft;}),n.addEventListener("mouseleave",()=>{t=false,n.style.cursor="grab";}),n.addEventListener("mouseup",()=>{t=false,n.style.cursor="grab";}),n.addEventListener("mousemove",y=>{if(!t)return;y.preventDefault();let C=(y.pageX-n.offsetLeft-p)*2;n.scrollLeft=f-C;});}),s.querySelectorAll(".aicommerce-audio-player").forEach(n=>{let t=n.querySelector("audio"),p=n.querySelector(".aicommerce-audio-btn"),f=n.querySelectorAll(".aicommerce-waveform-bar"),y=n.querySelector(".aicommerce-current-time");if(!t||!p)return;p.addEventListener("click",()=>{!t.paused?(t.pause(),p.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>'):(s?.querySelectorAll("audio").forEach(v=>{if(v!==t&&!v.paused){v.pause();let M=v.closest(".aicommerce-audio-player")?.querySelector(".aicommerce-audio-btn");M&&(M.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>');}}),t.play(),p.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect></svg>');}),t.addEventListener("timeupdate",()=>{if(y&&(y.textContent=V(t.currentTime)),t.duration){let C=t.currentTime/t.duration*100;f.forEach((v,$)=>{$/f.length*100<=C?v.style.backgroundColor=n.closest(".aicommerce-user")?"rgba(255,255,255,1)":"var(--aic-primary)":v.style.backgroundColor=n.closest(".aicommerce-user")?"rgba(255,255,255,0.4)":"rgba(99,102,241,0.3)";});}}),t.addEventListener("ended",()=>{p.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>';});let x=n.querySelector(".aicommerce-waveform-bars");x&&x.addEventListener("click",C=>{let v=x.getBoundingClientRect(),M=(C.clientX-v.left)/v.width;t.duration&&(t.currentTime=M*t.duration);});});}async function ae(){if(e.isRecording)d&&d.state!=="inactive"&&d.stop();else try{let o=await navigator.mediaDevices.getUserMedia({audio:!0});h=[],d=new MediaRecorder(o,{mimeType:MediaRecorder.isTypeSupported("audio/webm")?"audio/webm":"audio/mp4"}),d.ondataavailable=i=>{i.data.size>0&&h.push(i.data);},d.onstop=async()=>{if(o.getTracks().forEach(i=>i.stop()),h.length>0){let i=new Blob(h,{type:d?.mimeType||"audio/webm"});await ie(i);}e.isRecording=!1,k();},d.start(),e.isRecording=!0,k();}catch(o){console.error("Failed to start recording:",o),e.messages.push({role:"assistant",content:"Unable to access microphone. Please check your permissions."}),k();}}async function ie(o){let i=URL.createObjectURL(o),c=Array(40).fill(10),b=0;try{c=await se(o);let u=new Audio(i);await new Promise(E=>{u.onloadedmetadata=()=>{b=u.duration,E();},u.onerror=()=>E();});}catch(u){console.error("Audio analysis failed",u);}e.messages.push({role:"user",content:"Voice message",audioUrl:i,audioDuration:b,waveformBars:c}),e.isLoading=true,k();try{let u=await r.chatWithAudio(o);return e.messages.push({role:"assistant",content:u.reply,products:u.products}),m.onMessage&&m.onMessage("Voice message",u),u}catch(u){throw e.messages.push({role:"assistant",content:"Sorry, I encountered an error processing your voice message. Please try again."}),u}finally{e.isLoading=false,k();}}function J(o){return /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/.test(o)}function V(o){let i=Math.floor(o/60),c=Math.floor(o%60);return `${i}:${c.toString().padStart(2,"0")}`}async function se(o){try{let i=new(window.AudioContext||window.webkitAudioContext),c=await o.arrayBuffer(),u=(await i.decodeAudioData(c)).getChannelData(0),E=40,l=Math.floor(u.length/E),L=[];for(let A=0;A<E;A++){let n=A*l,t=n+l,p=0;for(let x=n;x<t;x++)u[x]&&(p+=u[x]*u[x]);let f=Math.sqrt(p/l),y=Math.min(100,Math.max(10,f*400));L.push(y);}return L}catch(i){return console.error("Analysis error",i),Array.from({length:40},()=>20+Math.random()*60)}}async function U(o){e.messages.push({role:"user",content:o}),e.isLoading=true,k();try{let i=await r.chat(o);return e.messages.push({role:"assistant",content:i.reply,products:i.products}),m.onMessage&&m.onMessage(o,i),i}catch(i){throw e.messages.push({role:"assistant",content:"Sorry, I encountered an error. Please try again."}),i}finally{e.isLoading=false,k();}}function q(){e.isOpen=true,k(),m.onOpen?.(),setTimeout(()=>{s?.querySelector(".aicommerce-input")?.focus();},100);}function O(){e.isOpen=false,k(),m.onClose?.();}function ne(){e.isOpen?O():q();}function ce(){s&&(s.remove(),s=null),w&&(w.remove(),w=null);}function de(o){if(Object.assign(m,o),o.primaryColor){let i=z(m);w&&(w.textContent=i);}k();}function T(o){let i=document.createElement("div");return i.textContent=o,i.innerHTML}function X(o,i){let b={USD:"$",EUR:"\u20AC",GBP:"\xA3",MAD:"DH",SAR:"SAR",AED:"AED",JPY:"\xA5",CNY:"\xA5"}[i||"USD"]||i||"$";return `${o.toFixed(2)} ${b}`}return re(),{open:q,close:O,toggle:ne,destroy:ce,sendMessage:U,updateConfig:de}}exports.AICommerceWidget=void 0;var K=H(()=>{R();Q();exports.AICommerceWidget={init:D,VERSION:"1.0.0"};typeof window<"u"&&(window.AICommerceWidget=exports.AICommerceWidget);});R();K();var xe="1.0.0";typeof window<"u"&&(window.AICommerce=(R(),j(W)).AICommerce,window.AICommerceError=(R(),j(W)).AICommerceError,window.AICommerceWidget=(K(),j(Z)).AICommerceWidget);exports.VERSION=xe;exports.createWidget=D;return exports;})({});//# sourceMappingURL=index.min.js.map
|
|
1021
1041
|
//# sourceMappingURL=index.min.js.map
|
package/dist/index.cjs
CHANGED
|
@@ -907,7 +907,7 @@ function createWidgetStyles(config) {
|
|
|
907
907
|
Embedded Mode Styles - ChatGPT Style
|
|
908
908
|
============================================ */
|
|
909
909
|
|
|
910
|
-
/* Embedded container -
|
|
910
|
+
/* Embedded container - starts small, grows to max-height, then scrolls */
|
|
911
911
|
#aicommerce-widget.aicommerce-embedded {
|
|
912
912
|
position: relative;
|
|
913
913
|
bottom: auto;
|
|
@@ -915,6 +915,7 @@ function createWidgetStyles(config) {
|
|
|
915
915
|
right: auto;
|
|
916
916
|
width: 100%;
|
|
917
917
|
height: auto;
|
|
918
|
+
min-height: 80px;
|
|
918
919
|
max-height: var(--aic-max-height, 600px);
|
|
919
920
|
display: flex;
|
|
920
921
|
flex-direction: column;
|
|
@@ -936,11 +937,12 @@ function createWidgetStyles(config) {
|
|
|
936
937
|
display: none !important;
|
|
937
938
|
}
|
|
938
939
|
|
|
939
|
-
/* Embedded mode: chat
|
|
940
|
+
/* Embedded mode: chat container grows with content */
|
|
940
941
|
.aicommerce-embedded .aicommerce-chat {
|
|
941
942
|
position: relative;
|
|
942
943
|
width: 100%;
|
|
943
944
|
height: auto;
|
|
945
|
+
max-height: 100%;
|
|
944
946
|
max-width: 100%;
|
|
945
947
|
border-radius: 0;
|
|
946
948
|
background: transparent;
|
|
@@ -959,13 +961,15 @@ function createWidgetStyles(config) {
|
|
|
959
961
|
pointer-events: auto !important;
|
|
960
962
|
}
|
|
961
963
|
|
|
962
|
-
/* Embedded mode: messages area -
|
|
964
|
+
/* Embedded mode: messages area - scrollable when content overflows */
|
|
963
965
|
.aicommerce-embedded .aicommerce-messages {
|
|
966
|
+
flex: 1 1 auto;
|
|
967
|
+
min-height: 0;
|
|
968
|
+
max-height: calc(var(--aic-max-height, 600px) - 100px);
|
|
964
969
|
display: flex;
|
|
965
970
|
flex-direction: column;
|
|
966
|
-
justify-content: flex-
|
|
971
|
+
justify-content: flex-start;
|
|
967
972
|
overflow-y: auto;
|
|
968
|
-
max-height: calc(var(--aic-max-height, 600px) - 100px);
|
|
969
973
|
padding: 16px;
|
|
970
974
|
max-width: 700px;
|
|
971
975
|
margin: 0 auto;
|
|
@@ -1090,19 +1094,28 @@ function createWidgetStyles(config) {
|
|
|
1090
1094
|
color: var(--aic-text);
|
|
1091
1095
|
}
|
|
1092
1096
|
|
|
1093
|
-
/* Embedded mode: product cards styling */
|
|
1097
|
+
/* Embedded mode: product cards styling - horizontal scroll like widget mode */
|
|
1094
1098
|
.aicommerce-embedded .aicommerce-products {
|
|
1095
1099
|
display: flex;
|
|
1096
|
-
flex-wrap:
|
|
1100
|
+
flex-wrap: nowrap;
|
|
1097
1101
|
gap: 12px;
|
|
1098
1102
|
margin-top: 12px;
|
|
1103
|
+
overflow-x: auto;
|
|
1104
|
+
padding-bottom: 8px;
|
|
1105
|
+
cursor: grab;
|
|
1106
|
+
scrollbar-width: none;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
.aicommerce-embedded .aicommerce-products::-webkit-scrollbar {
|
|
1110
|
+
display: none;
|
|
1099
1111
|
}
|
|
1100
1112
|
|
|
1101
1113
|
.aicommerce-embedded .aicommerce-product-card {
|
|
1114
|
+
flex-shrink: 0;
|
|
1115
|
+
width: 180px;
|
|
1102
1116
|
background: var(--aic-bg);
|
|
1103
1117
|
border: 1px solid var(--aic-border);
|
|
1104
1118
|
border-radius: 12px;
|
|
1105
|
-
max-width: 180px;
|
|
1106
1119
|
}
|
|
1107
1120
|
|
|
1108
1121
|
/* Embedded mode: typing indicator */
|
|
@@ -1328,13 +1341,20 @@ function createWidget(config) {
|
|
|
1328
1341
|
render();
|
|
1329
1342
|
}
|
|
1330
1343
|
async function addToShopifyCart(variantId, quantity = 1) {
|
|
1344
|
+
let numericVariantId = variantId;
|
|
1345
|
+
if (variantId.includes("gid://")) {
|
|
1346
|
+
const match = variantId.match(/\/(\d+)$/);
|
|
1347
|
+
if (match) {
|
|
1348
|
+
numericVariantId = match[1];
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1331
1351
|
const response = await fetch("/cart/add.js", {
|
|
1332
1352
|
method: "POST",
|
|
1333
1353
|
headers: {
|
|
1334
1354
|
"Content-Type": "application/json"
|
|
1335
1355
|
},
|
|
1336
1356
|
body: JSON.stringify({
|
|
1337
|
-
id:
|
|
1357
|
+
id: numericVariantId,
|
|
1338
1358
|
quantity
|
|
1339
1359
|
})
|
|
1340
1360
|
});
|
|
@@ -1426,7 +1446,7 @@ function createWidget(config) {
|
|
|
1426
1446
|
${msg.products && msg.products.length > 0 ? `
|
|
1427
1447
|
<div class="aicommerce-products">
|
|
1428
1448
|
${msg.products.map((product) => `
|
|
1429
|
-
<div class="aicommerce-product-card" data-product-id="${product.id}">
|
|
1449
|
+
<div class="aicommerce-product-card" data-product-id="${product.id}" data-variant-id="${product.variantId || ""}">
|
|
1430
1450
|
${product.image || product.imageUrl ? `
|
|
1431
1451
|
<img src="${product.image || product.imageUrl}" alt="${escapeHtml(product.name)}" class="aicommerce-product-image" />
|
|
1432
1452
|
` : `
|
|
@@ -1436,6 +1456,13 @@ function createWidget(config) {
|
|
|
1436
1456
|
<span class="aicommerce-product-name" title="${escapeHtml(product.name)}">${escapeHtml(product.name)}</span>
|
|
1437
1457
|
${product.description ? `<p class="aicommerce-product-desc">${escapeHtml(product.description)}</p>` : ""}
|
|
1438
1458
|
<span class="aicommerce-product-price">${formatPrice(product.price, product.currency)}</span>
|
|
1459
|
+
<button class="aicommerce-add-to-cart" data-product-id="${product.id}">
|
|
1460
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
1461
|
+
<circle cx="9" cy="21" r="1"/><circle cx="20" cy="21" r="1"/>
|
|
1462
|
+
<path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"/>
|
|
1463
|
+
</svg>
|
|
1464
|
+
${resolvedConfig.addToCartText || "Add to Cart"}
|
|
1465
|
+
</button>
|
|
1439
1466
|
</div>
|
|
1440
1467
|
</div>
|
|
1441
1468
|
`).join("")}
|