@aforoai/storefront-widgets 1.0.6 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/loader.mjs CHANGED
@@ -1,3 +1,3 @@
1
- var T="1.0.6";var y=new WeakMap,c=new Map,f={},A=false;function h(){A||typeof window!="undefined"&&(window.addEventListener("message",e=>{let t=e.data;!t||typeof t!="object"||typeof t.type!="string"||t.type.startsWith("aforo.")&&$(t);}),A=true);}function $(e){let t=c.get(e.type);if(t)for(let o of t)try{o(e);}catch(i){}let n=c.get("*");if(n)for(let o of n)try{o(e);}catch(i){}}var p=new Map;function N(e,t){p.set(e,t);}function w(e){return typeof e=="object"&&e!==null&&typeof e.tagName=="string"}var b={version:T,configure(e){f={...f,...e};},getConfig(){return {...f}},mount(e,t){var r,l,u,s,d;if(!w(e)||y.has(e))return false;let n=t.widget,o=p.get(n);if(!o)return typeof console!="undefined"&&console.warn(`[aforo:embed] No mount handler registered for widget "${n}". Loader bundle may not have finished loading.`),false;let i={widget:n,tenantSlug:(l=(r=t.tenantSlug)!=null?r:f.tenantSlug)!=null?l:"",embedKey:(s=(u=t.embedKey)!=null?u:f.embedKey)!=null?s:"",bridgeToken:(d=t.bridgeToken)!=null?d:f.bridgeToken,layout:t.layout,themeOverrides:t.themeOverrides,config:t.config};if(!i.tenantSlug||!i.embedKey)return typeof console!="undefined"&&console.error(`[aforo:embed] Widget "${n}" requires tenantSlug + embedKey. Provide via AforoEmbed.configure() or data-* attributes.`),false;h();let a=o(e,i);return y.set(e,{element:e,widget:n,teardown:a}),true},unmount(e){if(!w(e))return false;let t=y.get(e);if(!t)return false;try{t.teardown();}catch(n){}return y.delete(e),true},on(e,t){h();let n=c.get(e);return n||(n=new Set,c.set(e,n)),n.add(t),()=>{let o=c.get(e);o&&(o.delete(t),o.size===0&&c.delete(e));}},_registerWidget:N,_registeredWidgetsForTesting(){return Array.from(p.keys())},_resetForTesting(){p.clear(),c.clear(),f={};}};function k(e){if(!e)return {};try{let t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t)){let n={},o=["primary","primaryContrast","text","textMuted","bg","border","radius","fontFamily"],i=t;for(let a of o){let r=i[a];typeof r=="string"&&r.length>0&&(n[a]=r);}return n}}catch(t){}return {}}var U=new Set(["pricing-card","subscribe-button","checkout-flow","subscription-manager","invoice-list","usage-meter","payment-method","upgrade-cancel"]),B="https://embed.aforo.ai/v1/widgets",g="[aforo:loader]";function D(){let e=typeof document!="undefined"?document.currentScript:null;if(e&&e.tagName==="SCRIPT")return e;if(typeof document!="undefined"){let t=document.getElementsByTagName("script");for(let n=t.length-1;n>=0;n--){let o=t[n];if(!o)continue;let i=o.getAttribute("src")||"";if(/(\/v1)?\/loader(\.umd)?\.js$/.test(i))return o}}return null}function G(e){let t=e==null?void 0:e.getAttribute("src");if(!t)return null;try{let n=typeof location!="undefined"?location.href:void 0,o=new URL(t,n),i=o.pathname.replace(/\/loader(\.umd)?\.js$/,"");return `${o.origin}${i}/widgets`}catch(n){return null}}function v(e,t){let n=e.getAttribute(t);if(n==null||n.trim()==="")return;let o=Number(n);return Number.isFinite(o)?o:void 0}function j(e,t){let n=e.getAttribute(t);if(n==null)return;let o=n.trim().toLowerCase();if(o==="true")return true;if(o==="false")return false}function V(e){let t=(e.getAttribute("data-aforo-widget")||"").trim(),n=e.getAttribute("data-tenant-slug")||e.getAttribute("data-tenant")||"",o=e.getAttribute("data-embed-key")||"",i=e.getAttribute("data-bridge-token")||void 0,a=e.getAttribute("data-layout")||void 0,r=k(e.getAttribute("data-theme-overrides")),l=e.getAttribute("data-offering-id")||void 0,u=e.getAttribute("data-subscription-id")||void 0,s=e.getAttribute("data-metric")||void 0,d=e.getAttribute("data-featured-offering-id")||void 0,m=e.getAttribute("data-mode")||void 0,M=e.getAttribute("data-return-url")||void 0,S=e.getAttribute("data-default-status")||void 0,F=e.getAttribute("data-render-mode")||void 0,_=e.getAttribute("data-locale")||void 0,C=v(e,"data-page-size"),O=v(e,"data-poll-interval-ms"),I=e.getAttribute("data-theme")||void 0,R=e.getAttribute("data-cart-type")||void 0,W=e.getAttribute("data-target-id")||void 0,H=e.getAttribute("data-cta-text")||void 0,x=e.getAttribute("data-cta-url")||void 0,P=v(e,"data-max-plans"),K=j(e,"data-show-features");return {widget:t,tenantSlug:n,embedKey:o,bridgeToken:i,layout:a,themeOverrides:r,config:{offeringId:l,subscriptionId:u,metricName:s,featuredOfferingId:d,mode:m,returnUrl:M,defaultStatus:S,renderMode:F,locale:_,pageSize:C,pollIntervalMs:O,theme:I,cartType:R,targetId:W,ctaText:H,ctaUrl:x,maxPlans:P,showFeatures:K}}}function z(e,t,n){return new Promise((o,i)=>{if(typeof document=="undefined")return i(new Error("no document"));let a=document.querySelector(`script[data-aforo-bundle="${e}"]`);if(a){if(a.dataset.aforoLoaded==="1")return o();a.addEventListener("load",()=>o()),a.addEventListener("error",()=>i(new Error(`bundle load failed: ${e}`)));return}let r=document.createElement("script");r.src=`${t}/${e}.js`,r.async=true,r.crossOrigin="anonymous",r.dataset.aforoBundle=e,n&&r.setAttribute("nonce",n),r.addEventListener("load",()=>{r.dataset.aforoLoaded="1",o();}),r.addEventListener("error",()=>i(new Error(`bundle load failed: ${e}`))),document.head.appendChild(r);})}function L(e){if(!e.__aforoEmbedReadyFired){e.__aforoEmbedReadyFired=true;try{typeof e.aforoEmbedReady=="function"&&e.aforoEmbedReady();}catch(t){typeof console!="undefined"&&console.error(`${g} aforoEmbedReady callback threw`,t);}if(typeof document!="undefined"&&typeof CustomEvent!="undefined")try{document.dispatchEvent(new CustomEvent("aforoEmbedReady"));}catch(t){}}}async function E(e){if(typeof window=="undefined"||typeof document=="undefined")return;let t=window;if(window.location.protocol!=="https:"&&window.location.hostname!=="localhost"){typeof console!="undefined"&&console.error(`${g} Refusing to mount Aforo widgets on a non-HTTPS page. Embed Plugin requires HTTPS (FR-TIER-12). Current origin: ${window.location.origin}`);return}if(t.__aforoEmbedLoaderInitialized){typeof console!="undefined"&&console.warn(`${g} Loader already initialised on this page \u2014 skipping duplicate run.`);return}t.__aforoEmbedLoaderInitialized=true,t.aforoEmbed||(t.aforoEmbed=b);let n=D(),o=(n==null?void 0:n.getAttribute("nonce"))||null,i=(e==null?void 0:e.bundleBaseUrl)||G(n)||B,a=Array.from(document.querySelectorAll("[data-aforo-widget]"));if(a.length===0){L(t);return}let r=new Map;for(let u of a){let s=(u.getAttribute("data-aforo-widget")||"").trim();if(!U.has(s)){typeof console!="undefined"&&console.warn(`${g} Unknown widget id "${s}" \u2014 skipping`);continue}let d=r.get(s);d||(d=[],r.set(s,d)),d.push(u);}let l=Array.from(r.entries()).map(async([u,s])=>{try{await z(u,i,o);for(let d of s){let m=V(d);if(!m.widget||!m.tenantSlug||!m.embedKey){typeof console!="undefined"&&console.error(`${g} Placeholder missing required attributes (data-tenant-slug + data-embed-key). Skipping element.`,d);continue}b.mount(d,m);}}catch(d){typeof console!="undefined"&&console.error(`${g} Failed to load bundle for "${u}"`,d);}});await Promise.all(l).catch(()=>{}),L(t);}typeof document!="undefined"&&document.readyState!=="loading"?Promise.resolve().then(()=>{E();}):typeof document!="undefined"&&document.addEventListener("DOMContentLoaded",()=>{E();});b._loader={bootstrap:E};
1
+ var T="1.0.12";var y=new WeakMap,c=new Map,f={},A=false;function h(){A||typeof window!="undefined"&&(window.addEventListener("message",e=>{let t=e.data;!t||typeof t!="object"||typeof t.type!="string"||t.type.startsWith("aforo.")&&$(t);}),A=true);}function $(e){let t=c.get(e.type);if(t)for(let o of t)try{o(e);}catch(i){}let n=c.get("*");if(n)for(let o of n)try{o(e);}catch(i){}}var p=new Map;function N(e,t){p.set(e,t);}function w(e){return typeof e=="object"&&e!==null&&typeof e.tagName=="string"}var b={version:T,configure(e){f={...f,...e};},getConfig(){return {...f}},mount(e,t){var r,l,u,s,d;if(!w(e)||y.has(e))return false;let n=t.widget,o=p.get(n);if(!o)return typeof console!="undefined"&&console.warn(`[aforo:embed] No mount handler registered for widget "${n}". Loader bundle may not have finished loading.`),false;let i={widget:n,tenantSlug:(l=(r=t.tenantSlug)!=null?r:f.tenantSlug)!=null?l:"",embedKey:(s=(u=t.embedKey)!=null?u:f.embedKey)!=null?s:"",bridgeToken:(d=t.bridgeToken)!=null?d:f.bridgeToken,layout:t.layout,themeOverrides:t.themeOverrides,config:t.config};if(!i.tenantSlug||!i.embedKey)return typeof console!="undefined"&&console.error(`[aforo:embed] Widget "${n}" requires tenantSlug + embedKey. Provide via AforoEmbed.configure() or data-* attributes.`),false;h();let a=o(e,i);return y.set(e,{element:e,widget:n,teardown:a}),true},unmount(e){if(!w(e))return false;let t=y.get(e);if(!t)return false;try{t.teardown();}catch(n){}return y.delete(e),true},on(e,t){h();let n=c.get(e);return n||(n=new Set,c.set(e,n)),n.add(t),()=>{let o=c.get(e);o&&(o.delete(t),o.size===0&&c.delete(e));}},_registerWidget:N,_registeredWidgetsForTesting(){return Array.from(p.keys())},_resetForTesting(){p.clear(),c.clear(),f={};}};function k(e){if(!e)return {};try{let t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t)){let n={},o=["primary","primaryContrast","text","textMuted","bg","border","radius","fontFamily"],i=t;for(let a of o){let r=i[a];typeof r=="string"&&r.length>0&&(n[a]=r);}return n}}catch(t){}return {}}var U=new Set(["pricing-card","subscribe-button","checkout-flow","subscription-manager","invoice-list","usage-meter","payment-method","upgrade-cancel"]),B="https://embed.aforo.ai/v1/widgets",g="[aforo:loader]";function D(){let e=typeof document!="undefined"?document.currentScript:null;if(e&&e.tagName==="SCRIPT")return e;if(typeof document!="undefined"){let t=document.getElementsByTagName("script");for(let n=t.length-1;n>=0;n--){let o=t[n];if(!o)continue;let i=o.getAttribute("src")||"";if(/(\/v1)?\/loader(\.umd)?\.js$/.test(i))return o}}return null}function G(e){let t=e==null?void 0:e.getAttribute("src");if(!t)return null;try{let n=typeof location!="undefined"?location.href:void 0,o=new URL(t,n),i=o.pathname.replace(/\/loader(\.umd)?\.js$/,"");return `${o.origin}${i}/widgets`}catch(n){return null}}function v(e,t){let n=e.getAttribute(t);if(n==null||n.trim()==="")return;let o=Number(n);return Number.isFinite(o)?o:void 0}function j(e,t){let n=e.getAttribute(t);if(n==null)return;let o=n.trim().toLowerCase();if(o==="true")return true;if(o==="false")return false}function V(e){let t=(e.getAttribute("data-aforo-widget")||"").trim(),n=e.getAttribute("data-tenant-slug")||e.getAttribute("data-tenant")||"",o=e.getAttribute("data-embed-key")||"",i=e.getAttribute("data-bridge-token")||void 0,a=e.getAttribute("data-layout")||void 0,r=k(e.getAttribute("data-theme-overrides")),l=e.getAttribute("data-offering-id")||void 0,u=e.getAttribute("data-subscription-id")||void 0,s=e.getAttribute("data-metric")||void 0,d=e.getAttribute("data-featured-offering-id")||void 0,m=e.getAttribute("data-mode")||void 0,M=e.getAttribute("data-return-url")||void 0,S=e.getAttribute("data-default-status")||void 0,F=e.getAttribute("data-render-mode")||void 0,_=e.getAttribute("data-locale")||void 0,C=v(e,"data-page-size"),O=v(e,"data-poll-interval-ms"),I=e.getAttribute("data-theme")||void 0,R=e.getAttribute("data-cart-type")||void 0,W=e.getAttribute("data-target-id")||void 0,H=e.getAttribute("data-cta-text")||void 0,x=e.getAttribute("data-cta-url")||void 0,P=v(e,"data-max-plans"),K=j(e,"data-show-features");return {widget:t,tenantSlug:n,embedKey:o,bridgeToken:i,layout:a,themeOverrides:r,config:{offeringId:l,subscriptionId:u,metricName:s,featuredOfferingId:d,mode:m,returnUrl:M,defaultStatus:S,renderMode:F,locale:_,pageSize:C,pollIntervalMs:O,theme:I,cartType:R,targetId:W,ctaText:H,ctaUrl:x,maxPlans:P,showFeatures:K}}}function z(e,t,n){return new Promise((o,i)=>{if(typeof document=="undefined")return i(new Error("no document"));let a=document.querySelector(`script[data-aforo-bundle="${e}"]`);if(a){if(a.dataset.aforoLoaded==="1")return o();a.addEventListener("load",()=>o()),a.addEventListener("error",()=>i(new Error(`bundle load failed: ${e}`)));return}let r=document.createElement("script");r.src=`${t}/${e}.js`,r.async=true,r.crossOrigin="anonymous",r.dataset.aforoBundle=e,n&&r.setAttribute("nonce",n),r.addEventListener("load",()=>{r.dataset.aforoLoaded="1",o();}),r.addEventListener("error",()=>i(new Error(`bundle load failed: ${e}`))),document.head.appendChild(r);})}function L(e){if(!e.__aforoEmbedReadyFired){e.__aforoEmbedReadyFired=true;try{typeof e.aforoEmbedReady=="function"&&e.aforoEmbedReady();}catch(t){typeof console!="undefined"&&console.error(`${g} aforoEmbedReady callback threw`,t);}if(typeof document!="undefined"&&typeof CustomEvent!="undefined")try{document.dispatchEvent(new CustomEvent("aforoEmbedReady"));}catch(t){}}}async function E(e){if(typeof window=="undefined"||typeof document=="undefined")return;let t=window;if(window.location.protocol!=="https:"&&window.location.hostname!=="localhost"){typeof console!="undefined"&&console.error(`${g} Refusing to mount Aforo widgets on a non-HTTPS page. Embed Plugin requires HTTPS (FR-TIER-12). Current origin: ${window.location.origin}`);return}if(t.__aforoEmbedLoaderInitialized){typeof console!="undefined"&&console.warn(`${g} Loader already initialised on this page \u2014 skipping duplicate run.`);return}t.__aforoEmbedLoaderInitialized=true,t.aforoEmbed||(t.aforoEmbed=b);let n=D(),o=(n==null?void 0:n.getAttribute("nonce"))||null,i=(e==null?void 0:e.bundleBaseUrl)||G(n)||B,a=Array.from(document.querySelectorAll("[data-aforo-widget]"));if(a.length===0){L(t);return}let r=new Map;for(let u of a){let s=(u.getAttribute("data-aforo-widget")||"").trim();if(!U.has(s)){typeof console!="undefined"&&console.warn(`${g} Unknown widget id "${s}" \u2014 skipping`);continue}let d=r.get(s);d||(d=[],r.set(s,d)),d.push(u);}let l=Array.from(r.entries()).map(async([u,s])=>{try{await z(u,i,o);for(let d of s){let m=V(d);if(!m.widget||!m.tenantSlug||!m.embedKey){typeof console!="undefined"&&console.error(`${g} Placeholder missing required attributes (data-tenant-slug + data-embed-key). Skipping element.`,d);continue}b.mount(d,m);}}catch(d){typeof console!="undefined"&&console.error(`${g} Failed to load bundle for "${u}"`,d);}});await Promise.all(l).catch(()=>{}),L(t);}typeof document!="undefined"&&document.readyState!=="loading"?Promise.resolve().then(()=>{E();}):typeof document!="undefined"&&document.addEventListener("DOMContentLoaded",()=>{E();});b._loader={bootstrap:E};
2
2
  export{b as AforoEmbed,E as bootstrap};//# sourceMappingURL=loader.mjs.map
3
3
  //# sourceMappingURL=loader.mjs.map
package/dist/sri.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
- "version": "1.0.6",
3
- "generatedAt": "2026-08-26T08:25:03.608Z",
2
+ "version": "1.0.12",
3
+ "generatedAt": "2026-08-30T08:43:36.504Z",
4
4
  "bundles": {
5
- "loader.js": "sha384-rX5O1gvlt56peSNtNEJduwPfDsM5oLSlw6AFh0nBuysuBTup7dH3cqK9aKLzewWN",
6
- "widgets/checkout-flow.js": "sha384-3Rb+nizUBhxFhOh2VUu+i2l1QzX5bNJwjVdxG+VTnWrRzPGeU+8znz/I83Uqo6Lo",
7
- "widgets/invoice-list.js": "sha384-R7ugqnPN9QzMwuv41eyYVIHvhWXT1l9MUqv3/lkwpWqeBimUGj4Jum97jgL6HwXA",
8
- "widgets/payment-method.js": "sha384-gAMorea0TI66Sv1ygVCqyKriR+mDNgNNeHyTuTJADzSJi4wATSTzcAAUqz1JPEVK",
9
- "widgets/pricing-card.js": "sha384-O0pOl4rPkd915RHmoW63fs1B4zng9WL1gtoJVb06qBC2QnTL6NO1aYNWBsDKLkql",
10
- "widgets/subscribe-button.js": "sha384-rmG1ib5UoYVby5fSBNB6Omyu8j9beLzZSxmc97vaWrHhzsK/OKy8NM73URpS9wuF",
11
- "widgets/subscription-manager.js": "sha384-Brhr0eLy2khBWGC1IWjmHdqMHlu5ul+TNEjk5iIJ+iwRf7qPWkcLU3Qw2+u3x2WT",
12
- "widgets/upgrade-cancel.js": "sha384-9as15ROb0lsazumcF0NbPpAzCjWDE7NUFACSKzl5XC3bzzK7y1kNQukuqsNzlcaX",
13
- "widgets/usage-meter.js": "sha384-vA74x194TdKa54vMuxJzdc/TWMNkLG+XGohe873qqFFILos6LaJVLG2iRZzcULEP"
5
+ "loader.js": "sha384-ypYDb5FygS9HRZzNroYUmUzmTvHVNfiuzAu3WYyGk7mQookYeF1Mxo1RzfbrU0u7",
6
+ "widgets/checkout-flow.js": "sha384-U/J+lsyyAQE8SkpPhJwNBysilHeVCOV0b6qE3pfg4ZD0xcy27sN1d3C9aM137P5d",
7
+ "widgets/invoice-list.js": "sha384-gHftyyVGQ4nFY+H5AmAqwi0Uy+bQqK11UcoUz6v7rWdxhpWfm7nmfyIvCujv4AVK",
8
+ "widgets/payment-method.js": "sha384-kDE+KIJgVpGgZg3oDNvqoeL+F2iT2gYKocr7+R7/QQYRNgG6fl5+fYQStqfv2yQG",
9
+ "widgets/pricing-card.js": "sha384-bPD6LYpwZ8MLVUhpDBaX3Bc7oI2sPnj/MMxUrsks2P+6raR3QBbNDh6T6UFM0Z/N",
10
+ "widgets/subscribe-button.js": "sha384-3EL2dSXVTwwM0hBN06qIkm9mkRYGo64aILywWd+10vuUy3xYf02nSke8i13AwZui",
11
+ "widgets/subscription-manager.js": "sha384-zKGKiGR79ycHzQzCUhFdVsmzQFkSoxdbzOvR5DXuzeOrGIMygxY5E3eD6/X42Xbn",
12
+ "widgets/upgrade-cancel.js": "sha384-P8mhIa/azqwCJ6nhHlAISYv721aSSpzUuCZgfAMBHA78qNVKVVL24YyLo1ygTd5C",
13
+ "widgets/usage-meter.js": "sha384-WutNc1kA0rVnXzYHlF+Qcl0TJjeRyUB3+pqvvHDrkAzoWJUcwBMjXjbRNMWsBXag"
14
14
  }
15
15
  }
@@ -1030,8 +1030,13 @@ interface CancelResponse {
1030
1030
  cancelledAt: string | null;
1031
1031
  /** ISO-8601 timestamp the cancellation takes/took effect (today for IMMEDIATE, period end for PERIOD_END). */
1032
1032
  effectiveAt: string;
1033
- /** V50 feedback row id — useful for audit cross-reference. */
1034
- feedbackId: string;
1033
+ /**
1034
+ * V50 feedback row id — useful for audit cross-reference. Nullable:
1035
+ * storefront-service's cancel endpoint doesn't read it back from
1036
+ * pricing-service after writing it (documented follow-up), so it's
1037
+ * omitted from the response today (2026-08-29).
1038
+ */
1039
+ feedbackId: string | null;
1035
1040
  /** Credit note produced by an IMMEDIATE cancel with prorated refund. */
1036
1041
  creditNoteId: string | null;
1037
1042
  }
@@ -1030,8 +1030,13 @@ interface CancelResponse {
1030
1030
  cancelledAt: string | null;
1031
1031
  /** ISO-8601 timestamp the cancellation takes/took effect (today for IMMEDIATE, period end for PERIOD_END). */
1032
1032
  effectiveAt: string;
1033
- /** V50 feedback row id — useful for audit cross-reference. */
1034
- feedbackId: string;
1033
+ /**
1034
+ * V50 feedback row id — useful for audit cross-reference. Nullable:
1035
+ * storefront-service's cancel endpoint doesn't read it back from
1036
+ * pricing-service after writing it (documented follow-up), so it's
1037
+ * omitted from the response today (2026-08-29).
1038
+ */
1039
+ feedbackId: string | null;
1035
1040
  /** Credit note produced by an IMMEDIATE cancel with prorated refund. */
1036
1041
  creditNoteId: string | null;
1037
1042
  }
@@ -27,7 +27,7 @@ var React7__namespace = /*#__PURE__*/_interopNamespace(React7);
27
27
  // src/vanilla/index.ts
28
28
 
29
29
  // src/core/version.ts
30
- var VERSION = "1.0.6";
30
+ var VERSION = "1.0.12";
31
31
 
32
32
  // src/core/AforoEmbed.ts
33
33
  var mountedElements = /* @__PURE__ */ new WeakMap();
@@ -888,8 +888,9 @@ var _BridgeClient = class _BridgeClient {
888
888
  }
889
889
  if (!resp.ok) return emptyPage;
890
890
  try {
891
- const body = await resp.json();
892
- if (!body || typeof body !== "object") return emptyPage;
891
+ const raw = await resp.json();
892
+ if (!raw || typeof raw !== "object") return emptyPage;
893
+ const body = raw.data ?? raw;
893
894
  return {
894
895
  content: Array.isArray(body.content) ? body.content : [],
895
896
  totalElements: typeof body.totalElements === "number" && Number.isFinite(body.totalElements) ? body.totalElements : 0,
@@ -932,7 +933,8 @@ var _BridgeClient = class _BridgeClient {
932
933
  }
933
934
  if (!resp.ok) return null;
934
935
  try {
935
- const body = await resp.json();
936
+ const raw = await resp.json();
937
+ const body = raw ? raw.data ?? raw : null;
936
938
  if (!body || typeof body.downloadUrl !== "string" || body.downloadUrl.length === 0) {
937
939
  return null;
938
940
  }
@@ -1021,7 +1023,8 @@ var _BridgeClient = class _BridgeClient {
1021
1023
  }
1022
1024
  let body;
1023
1025
  try {
1024
- body = await resp.json();
1026
+ const raw = await resp.json();
1027
+ body = raw?.data ?? raw;
1025
1028
  } catch {
1026
1029
  throw new BridgeClientError(
1027
1030
  "Malformed invoice-payment-initiate response (not JSON)",
@@ -1332,9 +1335,9 @@ var _BridgeClient = class _BridgeClient {
1332
1335
  if (!resp.ok) {
1333
1336
  throw await this.parseError(resp);
1334
1337
  }
1335
- let body;
1338
+ let raw;
1336
1339
  try {
1337
- body = await resp.json();
1340
+ raw = await resp.json();
1338
1341
  } catch {
1339
1342
  throw new BridgeClientError(
1340
1343
  "Malformed confirmCart response (not JSON)",
@@ -1343,6 +1346,7 @@ var _BridgeClient = class _BridgeClient {
1343
1346
  false
1344
1347
  );
1345
1348
  }
1349
+ const body = raw?.data ?? raw ?? {};
1346
1350
  if (!body.cartId || !body.status) {
1347
1351
  throw new BridgeClientError(
1348
1352
  "Malformed confirmCart response (missing required fields)",
@@ -1407,9 +1411,9 @@ var _BridgeClient = class _BridgeClient {
1407
1411
  * undefined access.
1408
1412
  */
1409
1413
  async parseCartResponse(resp, methodName) {
1410
- let body;
1414
+ let raw;
1411
1415
  try {
1412
- body = await resp.json();
1416
+ raw = await resp.json();
1413
1417
  } catch {
1414
1418
  throw new BridgeClientError(
1415
1419
  `Malformed ${methodName} response (not JSON)`,
@@ -1418,7 +1422,8 @@ var _BridgeClient = class _BridgeClient {
1418
1422
  false
1419
1423
  );
1420
1424
  }
1421
- if (!body.cartId || !body.cartType || !body.status || !body.targetId) {
1425
+ const data = raw?.data ?? raw ?? {};
1426
+ if (!data.cartId || !data.cartType || !data.status || !data.targetId) {
1422
1427
  throw new BridgeClientError(
1423
1428
  `Malformed ${methodName} response (missing required fields)`,
1424
1429
  500,
@@ -1427,21 +1432,21 @@ var _BridgeClient = class _BridgeClient {
1427
1432
  );
1428
1433
  }
1429
1434
  return {
1430
- cartId: body.cartId,
1431
- cartType: body.cartType,
1432
- targetId: body.targetId,
1433
- status: body.status,
1434
- totalCents: typeof body.totalCents === "number" && Number.isFinite(body.totalCents) ? body.totalCents : 0,
1435
- currency: typeof body.currency === "string" ? body.currency : "USD",
1436
- gatewayProvider: body.gatewayProvider ?? null,
1437
- gatewayClientSecret: body.gatewayClientSecret ?? null,
1438
- gatewayOrderId: body.gatewayOrderId ?? null,
1439
- gatewayApprovalUrl: body.gatewayApprovalUrl ?? null,
1440
- gatewaySandboxMode: body.gatewaySandboxMode ?? null,
1441
- subscriptionId: body.subscriptionId ?? null,
1442
- invoiceId: body.invoiceId ?? null,
1443
- expiresAt: typeof body.expiresAt === "string" ? body.expiresAt : (/* @__PURE__ */ new Date(0)).toISOString(),
1444
- completedAt: body.completedAt ?? null
1435
+ cartId: data.cartId,
1436
+ cartType: data.cartType,
1437
+ targetId: data.targetId,
1438
+ status: data.status,
1439
+ totalCents: typeof data.totalCents === "number" && Number.isFinite(data.totalCents) ? data.totalCents : 0,
1440
+ currency: typeof data.currency === "string" ? data.currency : "USD",
1441
+ gatewayProvider: data.gatewayProvider ?? null,
1442
+ gatewayClientSecret: data.gatewayClientSecret ?? null,
1443
+ gatewayOrderId: data.gatewayOrderId ?? null,
1444
+ gatewayApprovalUrl: data.gatewayApprovalUrl ?? null,
1445
+ gatewaySandboxMode: data.gatewaySandboxMode ?? null,
1446
+ subscriptionId: data.subscriptionId ?? null,
1447
+ invoiceId: data.invoiceId ?? null,
1448
+ expiresAt: typeof data.expiresAt === "string" ? data.expiresAt : (/* @__PURE__ */ new Date(0)).toISOString(),
1449
+ completedAt: data.completedAt ?? null
1445
1450
  };
1446
1451
  }
1447
1452
  /** Public liveness probe. Returns null on failure (not an error). */
@@ -1673,7 +1678,8 @@ var _BridgeClient = class _BridgeClient {
1673
1678
  }
1674
1679
  if (!resp.ok) return null;
1675
1680
  try {
1676
- const body = await resp.json();
1681
+ const raw = await resp.json();
1682
+ const body = raw?.data ?? raw ?? {};
1677
1683
  if (!body || typeof body !== "object" || !body.subscriptionId) {
1678
1684
  return null;
1679
1685
  }
@@ -1802,14 +1808,17 @@ var _BridgeClient = class _BridgeClient {
1802
1808
  idempotencyKey,
1803
1809
  sessionJwt
1804
1810
  }),
1805
- body: JSON.stringify(request)
1811
+ // 2026-08-29 fix: same bug as cancelSubscription() below — EmbedUpgradeRequest
1812
+ // requires idempotencyKey as a @NotBlank BODY field, but this only ever sent
1813
+ // it via the Idempotency-Key header.
1814
+ body: JSON.stringify({ ...request, idempotencyKey })
1806
1815
  });
1807
1816
  if (!resp.ok) {
1808
1817
  throw await this.parseError(resp);
1809
1818
  }
1810
- let body;
1819
+ let raw;
1811
1820
  try {
1812
- body = await resp.json();
1821
+ raw = await resp.json();
1813
1822
  } catch {
1814
1823
  throw new BridgeClientError(
1815
1824
  "Malformed upgrade response (not JSON)",
@@ -1818,6 +1827,7 @@ var _BridgeClient = class _BridgeClient {
1818
1827
  false
1819
1828
  );
1820
1829
  }
1830
+ const body = raw ? raw.data ?? raw : {};
1821
1831
  if (!body.subscriptionId || !body.previousOfferingId || !body.newOfferingId || !body.status) {
1822
1832
  throw new BridgeClientError(
1823
1833
  "Malformed upgrade response (missing required fields)",
@@ -1881,14 +1891,19 @@ var _BridgeClient = class _BridgeClient {
1881
1891
  idempotencyKey,
1882
1892
  sessionJwt
1883
1893
  }),
1884
- body: JSON.stringify(request)
1894
+ // 2026-08-29 fix: EmbedCancelRequest (storefront-service) requires
1895
+ // idempotencyKey as a @NotBlank BODY field — this only ever sent it
1896
+ // via the Idempotency-Key header, so every real cancellation 400'd
1897
+ // with "idempotencyKey is required" regardless of any other field.
1898
+ // Confirmed live against production.
1899
+ body: JSON.stringify({ ...request, idempotencyKey })
1885
1900
  });
1886
1901
  if (!resp.ok) {
1887
1902
  throw await this.parseError(resp);
1888
1903
  }
1889
- let body;
1904
+ let raw;
1890
1905
  try {
1891
- body = await resp.json();
1906
+ raw = await resp.json();
1892
1907
  } catch {
1893
1908
  throw new BridgeClientError(
1894
1909
  "Malformed cancel response (not JSON)",
@@ -1897,7 +1912,8 @@ var _BridgeClient = class _BridgeClient {
1897
1912
  false
1898
1913
  );
1899
1914
  }
1900
- if (!body.subscriptionId || !body.status || !body.effectiveAt || !body.feedbackId) {
1915
+ const body = raw ? raw.data ?? raw : null;
1916
+ if (!body || !body.subscriptionId || !body.status || !body.effectiveAt) {
1901
1917
  throw new BridgeClientError(
1902
1918
  "Malformed cancel response (missing required fields)",
1903
1919
  500,
@@ -1910,7 +1926,7 @@ var _BridgeClient = class _BridgeClient {
1910
1926
  status: body.status,
1911
1927
  cancelledAt: body.cancelledAt ?? null,
1912
1928
  effectiveAt: body.effectiveAt,
1913
- feedbackId: body.feedbackId,
1929
+ feedbackId: body.feedbackId ?? null,
1914
1930
  creditNoteId: body.creditNoteId ?? null
1915
1931
  };
1916
1932
  }
@@ -1940,7 +1956,8 @@ var _BridgeClient = class _BridgeClient {
1940
1956
  if (!resp.ok) {
1941
1957
  return { methods: [], defaultMethodId: null };
1942
1958
  }
1943
- const body = await resp.json();
1959
+ const raw = await resp.json();
1960
+ const body = raw ? raw.data ?? raw : {};
1944
1961
  return {
1945
1962
  methods: Array.isArray(body.methods) ? body.methods : [],
1946
1963
  defaultMethodId: body.defaultMethodId ?? null
@@ -1970,7 +1987,8 @@ var _BridgeClient = class _BridgeClient {
1970
1987
  body: JSON.stringify({})
1971
1988
  });
1972
1989
  if (!resp.ok) return null;
1973
- const body = await resp.json();
1990
+ const raw = await resp.json();
1991
+ const body = raw ? raw.data ?? raw : {};
1974
1992
  if (!body.clientSecret) return null;
1975
1993
  return {
1976
1994
  clientSecret: body.clientSecret,
@@ -1,5 +1,5 @@
1
- export { A as AforoEmbed } from '../AforoEmbed-VYb6_GXB.cjs';
2
- import { aD as WidgetMountConfig } from '../types-BbQw2_32.cjs';
1
+ export { A as AforoEmbed } from '../AforoEmbed-BX2HPXWT.cjs';
2
+ import { aD as WidgetMountConfig } from '../types-RMTEXoGw.cjs';
3
3
 
4
4
  /**
5
5
  * @aforoai/storefront-widgets/vanilla — vanilla-JS adapter (FR-TIER-3,
@@ -1,5 +1,5 @@
1
- export { A as AforoEmbed } from '../AforoEmbed-BkJF1hAN.js';
2
- import { aD as WidgetMountConfig } from '../types-BbQw2_32.js';
1
+ export { A as AforoEmbed } from '../AforoEmbed-PsTY7zh0.js';
2
+ import { aD as WidgetMountConfig } from '../types-RMTEXoGw.js';
3
3
 
4
4
  /**
5
5
  * @aforoai/storefront-widgets/vanilla — vanilla-JS adapter (FR-TIER-3,
@@ -5,7 +5,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  // src/vanilla/index.ts
6
6
 
7
7
  // src/core/version.ts
8
- var VERSION = "1.0.6";
8
+ var VERSION = "1.0.12";
9
9
 
10
10
  // src/core/AforoEmbed.ts
11
11
  var mountedElements = /* @__PURE__ */ new WeakMap();
@@ -866,8 +866,9 @@ var _BridgeClient = class _BridgeClient {
866
866
  }
867
867
  if (!resp.ok) return emptyPage;
868
868
  try {
869
- const body = await resp.json();
870
- if (!body || typeof body !== "object") return emptyPage;
869
+ const raw = await resp.json();
870
+ if (!raw || typeof raw !== "object") return emptyPage;
871
+ const body = raw.data ?? raw;
871
872
  return {
872
873
  content: Array.isArray(body.content) ? body.content : [],
873
874
  totalElements: typeof body.totalElements === "number" && Number.isFinite(body.totalElements) ? body.totalElements : 0,
@@ -910,7 +911,8 @@ var _BridgeClient = class _BridgeClient {
910
911
  }
911
912
  if (!resp.ok) return null;
912
913
  try {
913
- const body = await resp.json();
914
+ const raw = await resp.json();
915
+ const body = raw ? raw.data ?? raw : null;
914
916
  if (!body || typeof body.downloadUrl !== "string" || body.downloadUrl.length === 0) {
915
917
  return null;
916
918
  }
@@ -999,7 +1001,8 @@ var _BridgeClient = class _BridgeClient {
999
1001
  }
1000
1002
  let body;
1001
1003
  try {
1002
- body = await resp.json();
1004
+ const raw = await resp.json();
1005
+ body = raw?.data ?? raw;
1003
1006
  } catch {
1004
1007
  throw new BridgeClientError(
1005
1008
  "Malformed invoice-payment-initiate response (not JSON)",
@@ -1310,9 +1313,9 @@ var _BridgeClient = class _BridgeClient {
1310
1313
  if (!resp.ok) {
1311
1314
  throw await this.parseError(resp);
1312
1315
  }
1313
- let body;
1316
+ let raw;
1314
1317
  try {
1315
- body = await resp.json();
1318
+ raw = await resp.json();
1316
1319
  } catch {
1317
1320
  throw new BridgeClientError(
1318
1321
  "Malformed confirmCart response (not JSON)",
@@ -1321,6 +1324,7 @@ var _BridgeClient = class _BridgeClient {
1321
1324
  false
1322
1325
  );
1323
1326
  }
1327
+ const body = raw?.data ?? raw ?? {};
1324
1328
  if (!body.cartId || !body.status) {
1325
1329
  throw new BridgeClientError(
1326
1330
  "Malformed confirmCart response (missing required fields)",
@@ -1385,9 +1389,9 @@ var _BridgeClient = class _BridgeClient {
1385
1389
  * undefined access.
1386
1390
  */
1387
1391
  async parseCartResponse(resp, methodName) {
1388
- let body;
1392
+ let raw;
1389
1393
  try {
1390
- body = await resp.json();
1394
+ raw = await resp.json();
1391
1395
  } catch {
1392
1396
  throw new BridgeClientError(
1393
1397
  `Malformed ${methodName} response (not JSON)`,
@@ -1396,7 +1400,8 @@ var _BridgeClient = class _BridgeClient {
1396
1400
  false
1397
1401
  );
1398
1402
  }
1399
- if (!body.cartId || !body.cartType || !body.status || !body.targetId) {
1403
+ const data = raw?.data ?? raw ?? {};
1404
+ if (!data.cartId || !data.cartType || !data.status || !data.targetId) {
1400
1405
  throw new BridgeClientError(
1401
1406
  `Malformed ${methodName} response (missing required fields)`,
1402
1407
  500,
@@ -1405,21 +1410,21 @@ var _BridgeClient = class _BridgeClient {
1405
1410
  );
1406
1411
  }
1407
1412
  return {
1408
- cartId: body.cartId,
1409
- cartType: body.cartType,
1410
- targetId: body.targetId,
1411
- status: body.status,
1412
- totalCents: typeof body.totalCents === "number" && Number.isFinite(body.totalCents) ? body.totalCents : 0,
1413
- currency: typeof body.currency === "string" ? body.currency : "USD",
1414
- gatewayProvider: body.gatewayProvider ?? null,
1415
- gatewayClientSecret: body.gatewayClientSecret ?? null,
1416
- gatewayOrderId: body.gatewayOrderId ?? null,
1417
- gatewayApprovalUrl: body.gatewayApprovalUrl ?? null,
1418
- gatewaySandboxMode: body.gatewaySandboxMode ?? null,
1419
- subscriptionId: body.subscriptionId ?? null,
1420
- invoiceId: body.invoiceId ?? null,
1421
- expiresAt: typeof body.expiresAt === "string" ? body.expiresAt : (/* @__PURE__ */ new Date(0)).toISOString(),
1422
- completedAt: body.completedAt ?? null
1413
+ cartId: data.cartId,
1414
+ cartType: data.cartType,
1415
+ targetId: data.targetId,
1416
+ status: data.status,
1417
+ totalCents: typeof data.totalCents === "number" && Number.isFinite(data.totalCents) ? data.totalCents : 0,
1418
+ currency: typeof data.currency === "string" ? data.currency : "USD",
1419
+ gatewayProvider: data.gatewayProvider ?? null,
1420
+ gatewayClientSecret: data.gatewayClientSecret ?? null,
1421
+ gatewayOrderId: data.gatewayOrderId ?? null,
1422
+ gatewayApprovalUrl: data.gatewayApprovalUrl ?? null,
1423
+ gatewaySandboxMode: data.gatewaySandboxMode ?? null,
1424
+ subscriptionId: data.subscriptionId ?? null,
1425
+ invoiceId: data.invoiceId ?? null,
1426
+ expiresAt: typeof data.expiresAt === "string" ? data.expiresAt : (/* @__PURE__ */ new Date(0)).toISOString(),
1427
+ completedAt: data.completedAt ?? null
1423
1428
  };
1424
1429
  }
1425
1430
  /** Public liveness probe. Returns null on failure (not an error). */
@@ -1651,7 +1656,8 @@ var _BridgeClient = class _BridgeClient {
1651
1656
  }
1652
1657
  if (!resp.ok) return null;
1653
1658
  try {
1654
- const body = await resp.json();
1659
+ const raw = await resp.json();
1660
+ const body = raw?.data ?? raw ?? {};
1655
1661
  if (!body || typeof body !== "object" || !body.subscriptionId) {
1656
1662
  return null;
1657
1663
  }
@@ -1780,14 +1786,17 @@ var _BridgeClient = class _BridgeClient {
1780
1786
  idempotencyKey,
1781
1787
  sessionJwt
1782
1788
  }),
1783
- body: JSON.stringify(request)
1789
+ // 2026-08-29 fix: same bug as cancelSubscription() below — EmbedUpgradeRequest
1790
+ // requires idempotencyKey as a @NotBlank BODY field, but this only ever sent
1791
+ // it via the Idempotency-Key header.
1792
+ body: JSON.stringify({ ...request, idempotencyKey })
1784
1793
  });
1785
1794
  if (!resp.ok) {
1786
1795
  throw await this.parseError(resp);
1787
1796
  }
1788
- let body;
1797
+ let raw;
1789
1798
  try {
1790
- body = await resp.json();
1799
+ raw = await resp.json();
1791
1800
  } catch {
1792
1801
  throw new BridgeClientError(
1793
1802
  "Malformed upgrade response (not JSON)",
@@ -1796,6 +1805,7 @@ var _BridgeClient = class _BridgeClient {
1796
1805
  false
1797
1806
  );
1798
1807
  }
1808
+ const body = raw ? raw.data ?? raw : {};
1799
1809
  if (!body.subscriptionId || !body.previousOfferingId || !body.newOfferingId || !body.status) {
1800
1810
  throw new BridgeClientError(
1801
1811
  "Malformed upgrade response (missing required fields)",
@@ -1859,14 +1869,19 @@ var _BridgeClient = class _BridgeClient {
1859
1869
  idempotencyKey,
1860
1870
  sessionJwt
1861
1871
  }),
1862
- body: JSON.stringify(request)
1872
+ // 2026-08-29 fix: EmbedCancelRequest (storefront-service) requires
1873
+ // idempotencyKey as a @NotBlank BODY field — this only ever sent it
1874
+ // via the Idempotency-Key header, so every real cancellation 400'd
1875
+ // with "idempotencyKey is required" regardless of any other field.
1876
+ // Confirmed live against production.
1877
+ body: JSON.stringify({ ...request, idempotencyKey })
1863
1878
  });
1864
1879
  if (!resp.ok) {
1865
1880
  throw await this.parseError(resp);
1866
1881
  }
1867
- let body;
1882
+ let raw;
1868
1883
  try {
1869
- body = await resp.json();
1884
+ raw = await resp.json();
1870
1885
  } catch {
1871
1886
  throw new BridgeClientError(
1872
1887
  "Malformed cancel response (not JSON)",
@@ -1875,7 +1890,8 @@ var _BridgeClient = class _BridgeClient {
1875
1890
  false
1876
1891
  );
1877
1892
  }
1878
- if (!body.subscriptionId || !body.status || !body.effectiveAt || !body.feedbackId) {
1893
+ const body = raw ? raw.data ?? raw : null;
1894
+ if (!body || !body.subscriptionId || !body.status || !body.effectiveAt) {
1879
1895
  throw new BridgeClientError(
1880
1896
  "Malformed cancel response (missing required fields)",
1881
1897
  500,
@@ -1888,7 +1904,7 @@ var _BridgeClient = class _BridgeClient {
1888
1904
  status: body.status,
1889
1905
  cancelledAt: body.cancelledAt ?? null,
1890
1906
  effectiveAt: body.effectiveAt,
1891
- feedbackId: body.feedbackId,
1907
+ feedbackId: body.feedbackId ?? null,
1892
1908
  creditNoteId: body.creditNoteId ?? null
1893
1909
  };
1894
1910
  }
@@ -1918,7 +1934,8 @@ var _BridgeClient = class _BridgeClient {
1918
1934
  if (!resp.ok) {
1919
1935
  return { methods: [], defaultMethodId: null };
1920
1936
  }
1921
- const body = await resp.json();
1937
+ const raw = await resp.json();
1938
+ const body = raw ? raw.data ?? raw : {};
1922
1939
  return {
1923
1940
  methods: Array.isArray(body.methods) ? body.methods : [],
1924
1941
  defaultMethodId: body.defaultMethodId ?? null
@@ -1948,7 +1965,8 @@ var _BridgeClient = class _BridgeClient {
1948
1965
  body: JSON.stringify({})
1949
1966
  });
1950
1967
  if (!resp.ok) return null;
1951
- const body = await resp.json();
1968
+ const raw = await resp.json();
1969
+ const body = raw ? raw.data ?? raw : {};
1952
1970
  if (!body.clientSecret) return null;
1953
1971
  return {
1954
1972
  clientSecret: body.clientSecret,