@aforoai/storefront-widgets 1.0.4 → 1.0.5

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/CHANGELOG.md CHANGED
@@ -8,8 +8,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [1.0.5] — 2026-08-26
12
+
11
13
  ### Fixed
12
14
 
15
+ - **Upgrade/Cancel (and every other widget's) bridge-exchange session refresh
16
+ threw "Malformed bridge exchange response" even though the exchange call
17
+ itself returned HTTP 200.** `BridgeClient.exchange()` — along with
18
+ `fetchHeadlessConfig()`, `fetchSubscriptions()`, and `initiateCheckout()` —
19
+ read the session/config/subscription/checkout payload directly off the
20
+ response body, but storefront-service wraps it in a `{success, data}`
21
+ envelope. Every field lookup came back `undefined`, so `exchange()`'s own
22
+ shape validation correctly rejected the (correctly-wrapped) response as
23
+ malformed. All four methods now unwrap `body.data ?? body` before reading
24
+ fields, so both a flat and an enveloped response parse correctly. This was
25
+ the root cause of "Confirm cancellation" failing on the Upgrade/Cancel
26
+ Script Tag widget after a legitimate session refresh mid-flow.
27
+ - **PricingCard falls back to per-unit rate when `priceCents` is null.**
28
+ Offerings with no flat/base price (pure PER_UNIT rate plans, e.g. $9/unit)
29
+ previously rendered as "Contact us". PricingCard now reads the primary rate
30
+ plan's `perUnitPriceCents` from `OfferingPayload.ratePlans` and renders
31
+ "$9.00 / unit" in both the card-grid and comparison-table layouts.
32
+
33
+ ### Fixed (carried over from unreleased, pre-1.0.5)
34
+
13
35
  - **Script-tag loader now parses the PricingCard presentation attributes
14
36
  `data-cta-text`, `data-cta-url`, `data-max-plans`, and
15
37
  `data-show-features`.** `pricingCardConfigToProps` reads all four
package/dist/index.cjs CHANGED
@@ -171,7 +171,8 @@ var _BridgeClient = class _BridgeClient {
171
171
  throw await this.parseError(resp);
172
172
  }
173
173
  const body = await resp.json();
174
- if (!body.sessionJwt || typeof body.expiresAt !== "number") {
174
+ const data = body?.data ?? body;
175
+ if (!data || !data.sessionJwt || typeof data.expiresAt !== "number") {
175
176
  throw new BridgeClientError(
176
177
  "Malformed bridge exchange response",
177
178
  500,
@@ -180,9 +181,9 @@ var _BridgeClient = class _BridgeClient {
180
181
  );
181
182
  }
182
183
  return {
183
- sessionJwt: body.sessionJwt,
184
- expiresAt: body.expiresAt,
185
- customerId: body.customerId ?? null
184
+ sessionJwt: data.sessionJwt,
185
+ expiresAt: data.expiresAt,
186
+ customerId: data.customerId ?? null
186
187
  };
187
188
  }
188
189
  /**
@@ -268,16 +269,17 @@ var _BridgeClient = class _BridgeClient {
268
269
  try {
269
270
  const body = await resp.json();
270
271
  if (!body || typeof body !== "object") return null;
272
+ const data = body.data ?? body;
271
273
  return {
272
- tenantSlug: body.tenantSlug,
274
+ tenantSlug: data.tenantSlug,
273
275
  branding: {
274
- primaryColor: body.primaryColor ?? null,
275
- secondaryColor: body.secondaryColor ?? null,
276
- logoUrl: body.logoUrl ?? null,
277
- fontFamily: body.fontFamily ?? null
276
+ primaryColor: data.primaryColor ?? null,
277
+ secondaryColor: data.secondaryColor ?? null,
278
+ logoUrl: data.logoUrl ?? null,
279
+ fontFamily: data.fontFamily ?? null
278
280
  },
279
- offerings: Array.isArray(body.offerings) ? body.offerings : [],
280
- embeddableWidget: body.embeddableWidget ?? null
281
+ offerings: Array.isArray(data.offerings) ? data.offerings : [],
282
+ embeddableWidget: data.embeddableWidget ?? null
281
283
  };
282
284
  } catch {
283
285
  return null;
@@ -422,7 +424,8 @@ var _BridgeClient = class _BridgeClient {
422
424
  false
423
425
  );
424
426
  }
425
- if (!body.checkoutUrl || !body.checkoutSessionId || !body.expiresAt) {
427
+ const data = body?.data ?? body ?? {};
428
+ if (!data.checkoutUrl || !data.checkoutSessionId || !data.expiresAt) {
426
429
  throw new BridgeClientError(
427
430
  "Malformed checkout-initiate response (missing required fields)",
428
431
  500,
@@ -431,9 +434,9 @@ var _BridgeClient = class _BridgeClient {
431
434
  );
432
435
  }
433
436
  return {
434
- checkoutUrl: body.checkoutUrl,
435
- checkoutSessionId: body.checkoutSessionId,
436
- expiresAt: body.expiresAt
437
+ checkoutUrl: data.checkoutUrl,
438
+ checkoutSessionId: data.checkoutSessionId,
439
+ expiresAt: data.expiresAt
437
440
  };
438
441
  }
439
442
  /* ────────────────────────────────────────────────────────────────────
@@ -1241,13 +1244,16 @@ var _BridgeClient = class _BridgeClient {
1241
1244
  if (!resp.ok) return emptyPage;
1242
1245
  try {
1243
1246
  const body = await resp.json();
1244
- if (!body || typeof body !== "object") return emptyPage;
1247
+ if (!body || typeof body !== "object") {
1248
+ return emptyPage;
1249
+ }
1250
+ const data = body.data ?? body;
1245
1251
  return {
1246
- content: Array.isArray(body.content) ? body.content : [],
1247
- totalElements: typeof body.totalElements === "number" && Number.isFinite(body.totalElements) ? body.totalElements : 0,
1248
- totalPages: typeof body.totalPages === "number" && Number.isFinite(body.totalPages) ? body.totalPages : 0,
1249
- page: typeof body.page === "number" && Number.isFinite(body.page) ? body.page : filter.page ?? 0,
1250
- size: typeof body.size === "number" && Number.isFinite(body.size) ? body.size : filter.size ?? 10
1252
+ content: Array.isArray(data.content) ? data.content : [],
1253
+ totalElements: typeof data.totalElements === "number" && Number.isFinite(data.totalElements) ? data.totalElements : 0,
1254
+ totalPages: typeof data.totalPages === "number" && Number.isFinite(data.totalPages) ? data.totalPages : 0,
1255
+ page: typeof data.page === "number" && Number.isFinite(data.page) ? data.page : filter.page ?? 0,
1256
+ size: typeof data.size === "number" && Number.isFinite(data.size) ? data.size : filter.size ?? 10
1251
1257
  };
1252
1258
  } catch {
1253
1259
  return emptyPage;
@@ -2751,6 +2757,20 @@ function safeFormatCurrency(priceCents, currency, locale, intlOverride) {
2751
2757
  return `${currency} ${amount.toFixed(2)}`;
2752
2758
  }
2753
2759
  }
2760
+ function resolveDisplayPrice(offering, locale, intlOverride) {
2761
+ const flat = safeFormatCurrency(offering.priceCents, offering.currency, locale, intlOverride);
2762
+ if (flat !== "\u2014") return { text: flat, unitSuffix: null };
2763
+ const perUnitPlan = offering.ratePlans?.find(
2764
+ (rp) => rp.pricingModel === "PER_UNIT" && rp.perUnitPriceCents != null
2765
+ );
2766
+ if (perUnitPlan) {
2767
+ const unitPrice = safeFormatCurrency(perUnitPlan.perUnitPriceCents, offering.currency, locale, intlOverride);
2768
+ if (unitPrice !== "\u2014") {
2769
+ return { text: unitPrice, unitSuffix: perUnitPlan.unitLabel || "unit" };
2770
+ }
2771
+ }
2772
+ return { text: "\u2014", unitSuffix: null };
2773
+ }
2754
2774
  function localizedName(o) {
2755
2775
  return o.localizedDisplayName || o.name || "(unnamed plan)";
2756
2776
  }
@@ -3154,12 +3174,7 @@ function PlanCard({
3154
3174
  onCtaClick,
3155
3175
  intlOverride
3156
3176
  }) {
3157
- const price = safeFormatCurrency(
3158
- offering.priceCents,
3159
- offering.currency,
3160
- locale,
3161
- intlOverride
3162
- );
3177
+ const { text: price, unitSuffix } = resolveDisplayPrice(offering, locale, intlOverride);
3163
3178
  const isContactSales = price === "\u2014";
3164
3179
  const planName = localizedName(offering);
3165
3180
  const description = localizedDescription(offering);
@@ -3180,7 +3195,7 @@ function PlanCard({
3180
3195
  "div",
3181
3196
  {
3182
3197
  role: "group",
3183
- "aria-label": `${planName}, ${price} per ${offering.billingCycle}`,
3198
+ "aria-label": `${planName}, ${price} per ${unitSuffix ?? offering.billingCycle}`,
3184
3199
  className: `aforo-w-pc-card${featured ? " aforo-w-pc-card-featured" : ""}`,
3185
3200
  style: cardStyle2,
3186
3201
  children: [
@@ -3245,14 +3260,14 @@ function PlanCard({
3245
3260
  children: price
3246
3261
  }
3247
3262
  ),
3248
- !isContactSales && offering.billingCycle ? /* @__PURE__ */ jsxRuntime.jsxs(
3263
+ !isContactSales && (unitSuffix || offering.billingCycle) ? /* @__PURE__ */ jsxRuntime.jsxs(
3249
3264
  "span",
3250
3265
  {
3251
3266
  className: "aforo-w-pc-cycle",
3252
3267
  style: { fontSize: 13, color: tokens.textMuted },
3253
3268
  children: [
3254
3269
  "/ ",
3255
- humanCycle(offering.billingCycle)
3270
+ unitSuffix ?? humanCycle(offering.billingCycle)
3256
3271
  ]
3257
3272
  }
3258
3273
  ) : null
@@ -3410,6 +3425,7 @@ function TableLayout({
3410
3425
  /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", style: { ...headerCellStyle, color: tokens.textMuted, fontSize: 12 }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "aforo-w-pc-sr-only", style: srOnlyStyle, children: "Feature" }) }),
3411
3426
  offerings.map((o) => {
3412
3427
  const featured = offeringIsFeatured(o, featuredOverride);
3428
+ const { text: tablePrice, unitSuffix: tableUnitSuffix } = resolveDisplayPrice(o, locale, intlOverride);
3413
3429
  return /* @__PURE__ */ jsxRuntime.jsx(
3414
3430
  "th",
3415
3431
  {
@@ -3439,13 +3455,20 @@ function TableLayout({
3439
3455
  children: "Most popular"
3440
3456
  }
3441
3457
  ) : null,
3442
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 22, fontWeight: 700 }, children: safeFormatCurrency(o.priceCents, o.currency, locale, intlOverride) }),
3458
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 22, fontWeight: 700 }, children: [
3459
+ tablePrice,
3460
+ tableUnitSuffix ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: 12, fontWeight: 400, color: tokens.textMuted }, children: [
3461
+ " ",
3462
+ "/ ",
3463
+ tableUnitSuffix
3464
+ ] }) : null
3465
+ ] }),
3443
3466
  /* @__PURE__ */ jsxRuntime.jsx(
3444
3467
  "button",
3445
3468
  {
3446
3469
  type: "button",
3447
3470
  onClick: () => onCtaClick(o),
3448
- "aria-label": `${ctaLabel(o, ctaTextProp, safeFormatCurrency(o.priceCents, o.currency, locale, intlOverride) === "\u2014")} for ${localizedName(o)}`,
3471
+ "aria-label": `${ctaLabel(o, ctaTextProp, tablePrice === "\u2014")} for ${localizedName(o)}`,
3449
3472
  style: {
3450
3473
  inlineSize: "100%",
3451
3474
  padding: "8px 12px",
@@ -3458,7 +3481,7 @@ function TableLayout({
3458
3481
  cursor: "pointer",
3459
3482
  fontFamily: tokens.fontFamily
3460
3483
  },
3461
- children: ctaLabel(o, ctaTextProp, safeFormatCurrency(o.priceCents, o.currency, locale, intlOverride) === "\u2014")
3484
+ children: ctaLabel(o, ctaTextProp, tablePrice === "\u2014")
3462
3485
  }
3463
3486
  )
3464
3487
  ] })
@@ -12175,7 +12198,7 @@ function ResultPanel({
12175
12198
  }
12176
12199
 
12177
12200
  // src/core/version.ts
12178
- var VERSION = "1.0.4";
12201
+ var VERSION = "1.0.5";
12179
12202
 
12180
12203
  // src/core/AforoEmbed.ts
12181
12204
  var mountedElements = /* @__PURE__ */ new WeakMap();
package/dist/index.mjs CHANGED
@@ -149,7 +149,8 @@ var _BridgeClient = class _BridgeClient {
149
149
  throw await this.parseError(resp);
150
150
  }
151
151
  const body = await resp.json();
152
- if (!body.sessionJwt || typeof body.expiresAt !== "number") {
152
+ const data = body?.data ?? body;
153
+ if (!data || !data.sessionJwt || typeof data.expiresAt !== "number") {
153
154
  throw new BridgeClientError(
154
155
  "Malformed bridge exchange response",
155
156
  500,
@@ -158,9 +159,9 @@ var _BridgeClient = class _BridgeClient {
158
159
  );
159
160
  }
160
161
  return {
161
- sessionJwt: body.sessionJwt,
162
- expiresAt: body.expiresAt,
163
- customerId: body.customerId ?? null
162
+ sessionJwt: data.sessionJwt,
163
+ expiresAt: data.expiresAt,
164
+ customerId: data.customerId ?? null
164
165
  };
165
166
  }
166
167
  /**
@@ -246,16 +247,17 @@ var _BridgeClient = class _BridgeClient {
246
247
  try {
247
248
  const body = await resp.json();
248
249
  if (!body || typeof body !== "object") return null;
250
+ const data = body.data ?? body;
249
251
  return {
250
- tenantSlug: body.tenantSlug,
252
+ tenantSlug: data.tenantSlug,
251
253
  branding: {
252
- primaryColor: body.primaryColor ?? null,
253
- secondaryColor: body.secondaryColor ?? null,
254
- logoUrl: body.logoUrl ?? null,
255
- fontFamily: body.fontFamily ?? null
254
+ primaryColor: data.primaryColor ?? null,
255
+ secondaryColor: data.secondaryColor ?? null,
256
+ logoUrl: data.logoUrl ?? null,
257
+ fontFamily: data.fontFamily ?? null
256
258
  },
257
- offerings: Array.isArray(body.offerings) ? body.offerings : [],
258
- embeddableWidget: body.embeddableWidget ?? null
259
+ offerings: Array.isArray(data.offerings) ? data.offerings : [],
260
+ embeddableWidget: data.embeddableWidget ?? null
259
261
  };
260
262
  } catch {
261
263
  return null;
@@ -400,7 +402,8 @@ var _BridgeClient = class _BridgeClient {
400
402
  false
401
403
  );
402
404
  }
403
- if (!body.checkoutUrl || !body.checkoutSessionId || !body.expiresAt) {
405
+ const data = body?.data ?? body ?? {};
406
+ if (!data.checkoutUrl || !data.checkoutSessionId || !data.expiresAt) {
404
407
  throw new BridgeClientError(
405
408
  "Malformed checkout-initiate response (missing required fields)",
406
409
  500,
@@ -409,9 +412,9 @@ var _BridgeClient = class _BridgeClient {
409
412
  );
410
413
  }
411
414
  return {
412
- checkoutUrl: body.checkoutUrl,
413
- checkoutSessionId: body.checkoutSessionId,
414
- expiresAt: body.expiresAt
415
+ checkoutUrl: data.checkoutUrl,
416
+ checkoutSessionId: data.checkoutSessionId,
417
+ expiresAt: data.expiresAt
415
418
  };
416
419
  }
417
420
  /* ────────────────────────────────────────────────────────────────────
@@ -1219,13 +1222,16 @@ var _BridgeClient = class _BridgeClient {
1219
1222
  if (!resp.ok) return emptyPage;
1220
1223
  try {
1221
1224
  const body = await resp.json();
1222
- if (!body || typeof body !== "object") return emptyPage;
1225
+ if (!body || typeof body !== "object") {
1226
+ return emptyPage;
1227
+ }
1228
+ const data = body.data ?? body;
1223
1229
  return {
1224
- content: Array.isArray(body.content) ? body.content : [],
1225
- totalElements: typeof body.totalElements === "number" && Number.isFinite(body.totalElements) ? body.totalElements : 0,
1226
- totalPages: typeof body.totalPages === "number" && Number.isFinite(body.totalPages) ? body.totalPages : 0,
1227
- page: typeof body.page === "number" && Number.isFinite(body.page) ? body.page : filter.page ?? 0,
1228
- size: typeof body.size === "number" && Number.isFinite(body.size) ? body.size : filter.size ?? 10
1230
+ content: Array.isArray(data.content) ? data.content : [],
1231
+ totalElements: typeof data.totalElements === "number" && Number.isFinite(data.totalElements) ? data.totalElements : 0,
1232
+ totalPages: typeof data.totalPages === "number" && Number.isFinite(data.totalPages) ? data.totalPages : 0,
1233
+ page: typeof data.page === "number" && Number.isFinite(data.page) ? data.page : filter.page ?? 0,
1234
+ size: typeof data.size === "number" && Number.isFinite(data.size) ? data.size : filter.size ?? 10
1229
1235
  };
1230
1236
  } catch {
1231
1237
  return emptyPage;
@@ -2729,6 +2735,20 @@ function safeFormatCurrency(priceCents, currency, locale, intlOverride) {
2729
2735
  return `${currency} ${amount.toFixed(2)}`;
2730
2736
  }
2731
2737
  }
2738
+ function resolveDisplayPrice(offering, locale, intlOverride) {
2739
+ const flat = safeFormatCurrency(offering.priceCents, offering.currency, locale, intlOverride);
2740
+ if (flat !== "\u2014") return { text: flat, unitSuffix: null };
2741
+ const perUnitPlan = offering.ratePlans?.find(
2742
+ (rp) => rp.pricingModel === "PER_UNIT" && rp.perUnitPriceCents != null
2743
+ );
2744
+ if (perUnitPlan) {
2745
+ const unitPrice = safeFormatCurrency(perUnitPlan.perUnitPriceCents, offering.currency, locale, intlOverride);
2746
+ if (unitPrice !== "\u2014") {
2747
+ return { text: unitPrice, unitSuffix: perUnitPlan.unitLabel || "unit" };
2748
+ }
2749
+ }
2750
+ return { text: "\u2014", unitSuffix: null };
2751
+ }
2732
2752
  function localizedName(o) {
2733
2753
  return o.localizedDisplayName || o.name || "(unnamed plan)";
2734
2754
  }
@@ -3132,12 +3152,7 @@ function PlanCard({
3132
3152
  onCtaClick,
3133
3153
  intlOverride
3134
3154
  }) {
3135
- const price = safeFormatCurrency(
3136
- offering.priceCents,
3137
- offering.currency,
3138
- locale,
3139
- intlOverride
3140
- );
3155
+ const { text: price, unitSuffix } = resolveDisplayPrice(offering, locale, intlOverride);
3141
3156
  const isContactSales = price === "\u2014";
3142
3157
  const planName = localizedName(offering);
3143
3158
  const description = localizedDescription(offering);
@@ -3158,7 +3173,7 @@ function PlanCard({
3158
3173
  "div",
3159
3174
  {
3160
3175
  role: "group",
3161
- "aria-label": `${planName}, ${price} per ${offering.billingCycle}`,
3176
+ "aria-label": `${planName}, ${price} per ${unitSuffix ?? offering.billingCycle}`,
3162
3177
  className: `aforo-w-pc-card${featured ? " aforo-w-pc-card-featured" : ""}`,
3163
3178
  style: cardStyle2,
3164
3179
  children: [
@@ -3223,14 +3238,14 @@ function PlanCard({
3223
3238
  children: price
3224
3239
  }
3225
3240
  ),
3226
- !isContactSales && offering.billingCycle ? /* @__PURE__ */ jsxs(
3241
+ !isContactSales && (unitSuffix || offering.billingCycle) ? /* @__PURE__ */ jsxs(
3227
3242
  "span",
3228
3243
  {
3229
3244
  className: "aforo-w-pc-cycle",
3230
3245
  style: { fontSize: 13, color: tokens.textMuted },
3231
3246
  children: [
3232
3247
  "/ ",
3233
- humanCycle(offering.billingCycle)
3248
+ unitSuffix ?? humanCycle(offering.billingCycle)
3234
3249
  ]
3235
3250
  }
3236
3251
  ) : null
@@ -3388,6 +3403,7 @@ function TableLayout({
3388
3403
  /* @__PURE__ */ jsx("th", { scope: "col", style: { ...headerCellStyle, color: tokens.textMuted, fontSize: 12 }, children: /* @__PURE__ */ jsx("span", { className: "aforo-w-pc-sr-only", style: srOnlyStyle, children: "Feature" }) }),
3389
3404
  offerings.map((o) => {
3390
3405
  const featured = offeringIsFeatured(o, featuredOverride);
3406
+ const { text: tablePrice, unitSuffix: tableUnitSuffix } = resolveDisplayPrice(o, locale, intlOverride);
3391
3407
  return /* @__PURE__ */ jsx(
3392
3408
  "th",
3393
3409
  {
@@ -3417,13 +3433,20 @@ function TableLayout({
3417
3433
  children: "Most popular"
3418
3434
  }
3419
3435
  ) : null,
3420
- /* @__PURE__ */ jsx("div", { style: { fontSize: 22, fontWeight: 700 }, children: safeFormatCurrency(o.priceCents, o.currency, locale, intlOverride) }),
3436
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: 22, fontWeight: 700 }, children: [
3437
+ tablePrice,
3438
+ tableUnitSuffix ? /* @__PURE__ */ jsxs("span", { style: { fontSize: 12, fontWeight: 400, color: tokens.textMuted }, children: [
3439
+ " ",
3440
+ "/ ",
3441
+ tableUnitSuffix
3442
+ ] }) : null
3443
+ ] }),
3421
3444
  /* @__PURE__ */ jsx(
3422
3445
  "button",
3423
3446
  {
3424
3447
  type: "button",
3425
3448
  onClick: () => onCtaClick(o),
3426
- "aria-label": `${ctaLabel(o, ctaTextProp, safeFormatCurrency(o.priceCents, o.currency, locale, intlOverride) === "\u2014")} for ${localizedName(o)}`,
3449
+ "aria-label": `${ctaLabel(o, ctaTextProp, tablePrice === "\u2014")} for ${localizedName(o)}`,
3427
3450
  style: {
3428
3451
  inlineSize: "100%",
3429
3452
  padding: "8px 12px",
@@ -3436,7 +3459,7 @@ function TableLayout({
3436
3459
  cursor: "pointer",
3437
3460
  fontFamily: tokens.fontFamily
3438
3461
  },
3439
- children: ctaLabel(o, ctaTextProp, safeFormatCurrency(o.priceCents, o.currency, locale, intlOverride) === "\u2014")
3462
+ children: ctaLabel(o, ctaTextProp, tablePrice === "\u2014")
3440
3463
  }
3441
3464
  )
3442
3465
  ] })
@@ -12153,7 +12176,7 @@ function ResultPanel({
12153
12176
  }
12154
12177
 
12155
12178
  // src/core/version.ts
12156
- var VERSION = "1.0.4";
12179
+ var VERSION = "1.0.5";
12157
12180
 
12158
12181
  // src/core/AforoEmbed.ts
12159
12182
  var mountedElements = /* @__PURE__ */ new WeakMap();
package/dist/loader.js CHANGED
@@ -1,3 +1,3 @@
1
- var AforoEmbedLoader=(function(exports){'use strict';var T="1.0.4";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 AforoEmbedLoader=(function(exports){'use strict';var T="1.0.5";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
  exports.AforoEmbed=b;exports.bootstrap=E;return exports;})({});//# sourceMappingURL=loader.js.map
3
3
  //# sourceMappingURL=loader.js.map
package/dist/loader.mjs CHANGED
@@ -1,3 +1,3 @@
1
- var T="1.0.4";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.5";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.4",
3
- "generatedAt": "2026-08-12T07:41:16.132Z",
2
+ "version": "1.0.5",
3
+ "generatedAt": "2026-08-26T07:52:12.266Z",
4
4
  "bundles": {
5
- "loader.js": "sha384-1PaCVhvIgReR0XDRtQjRnIqIqkg6XyUE8vGWDYwVPrIquBJ8nzLQ5YTYJGQ+gglP",
6
- "widgets/checkout-flow.js": "sha384-xuqKo2+LKENycKs1xQRr+1MEoBNi/Gja7PTMORrJishixFMpb59od8dcBiMu3bTn",
7
- "widgets/invoice-list.js": "sha384-BYAiV3yNVgfDWFM1oe+Nn/VPIBff2WCrclHtw1lTB/PiRC9fFRYggC8+ap2bwOBo",
8
- "widgets/payment-method.js": "sha384-UKvAuOn02kOi05DyJrJS611LsoJjTMLC+y6rUCEHlZLZbym4k0jSp48C8YjvgDEm",
9
- "widgets/pricing-card.js": "sha384-C1Y7pt2S0+jETNNnFoBH2rfySqbRTuB+IYA4hjeUuZKir9s+BM1Hu4g1ItSuEXlO",
10
- "widgets/subscribe-button.js": "sha384-i7mqtIWTb2Olg2Uyw9sMAR+Jf53AGTwqIBRWb8QBGQNfy7eSsFNkF2J7yljl+BVz",
11
- "widgets/subscription-manager.js": "sha384-rXZz4PRPYHhhfImIUVdfjtUJvJvNrfDLxfi/iV2EgSzONQ1m6Rc/lmhCsQYtyqeX",
12
- "widgets/upgrade-cancel.js": "sha384-ZYZHCtJjqIlRn0yz2QR2pyv39C3mH4eFFQjSd/QkPUsqV3ht8ypbRkZOgi9Mmn8t",
13
- "widgets/usage-meter.js": "sha384-8Jokz8Lmyb86GW9DBCaTJcsKF5KwCwoLOcZuTyecmMedIvvsSZQjZZtS4ou8bLN/"
5
+ "loader.js": "sha384-dSFfjDiOhFwuhOq6QaJlGLJq05Fl3yau3wPc5kuYnO+OmN/MKp91+AwOpG0zFAJ7",
6
+ "widgets/checkout-flow.js": "sha384-ABsG5M7QXhYJUmB81gURADHt98yRZaJpMxw5qDXiUs7LHa34LGXgfGEzSZrMC2Lr",
7
+ "widgets/invoice-list.js": "sha384-Dk5I2atCFalMIClYl6NkhZo3rrQNsfxq64y+geG+Lm3vZ1rZSg3xeVfY4tVMl0mD",
8
+ "widgets/payment-method.js": "sha384-xkM3m6gLJBhs0aK/A+/tcEQIWjz5Fj/h5dl4X/aEXmu6Dc0fVfxIV2ZQ1NDKDfsa",
9
+ "widgets/pricing-card.js": "sha384-F0ZraASZJCoL/E3v2tCQAAilNm6BndFRYsH5CFAYlWizibZyrNCVddq/pZ4ZQeP6",
10
+ "widgets/subscribe-button.js": "sha384-85KTFUAYOsDkedU1SKInEn0V0iAMUX4hokvn7ve69Q2Ouh9dvJoPY9OEYuWsDvfF",
11
+ "widgets/subscription-manager.js": "sha384-3BNZFvMphX9jAsmzrE09tnPBIKbXsxLhVSv1KynXrJK217OmFekbdHLzkPtGphcw",
12
+ "widgets/upgrade-cancel.js": "sha384-ZvFGSCqU3+MoAeXeytEbYzpDZInRDP0YJ9AUl6yoMdwQ4p4W7stLLgdM3l3dNIxZ",
13
+ "widgets/usage-meter.js": "sha384-2g3qNlSZMkw6sTHKsXbsupaWQbdQzE+4U8jbFlRUaV0qpMKeptV4po98z0PpSM61"
14
14
  }
15
15
  }