@aforoai/storefront-widgets 1.0.5 → 1.0.11

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.
@@ -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.5";
30
+ var VERSION = "1.0.11";
31
31
 
32
32
  // src/core/AforoEmbed.ts
33
33
  var mountedElements = /* @__PURE__ */ new WeakMap();
@@ -182,6 +182,7 @@ function pricingCardConfigToProps(config) {
182
182
  const theme = readEnum(extra.theme, ["light", "dark", "auto"], "auto");
183
183
  const locale = typeof extra.locale === "string" ? extra.locale : void 0;
184
184
  const maxPlans = typeof extra.maxPlans === "number" && Number.isFinite(extra.maxPlans) ? extra.maxPlans : void 0;
185
+ const borderRadius = typeof extra.borderRadius === "number" && Number.isFinite(extra.borderRadius) ? extra.borderRadius : void 0;
185
186
  const ctaText = typeof extra.ctaText === "string" ? extra.ctaText : void 0;
186
187
  const ctaUrl = typeof extra.ctaUrl === "string" ? extra.ctaUrl : void 0;
187
188
  const showFeatures = typeof extra.showFeatures === "boolean" ? extra.showFeatures : void 0;
@@ -195,6 +196,7 @@ function pricingCardConfigToProps(config) {
195
196
  theme,
196
197
  locale,
197
198
  maxPlans,
199
+ borderRadius,
198
200
  showFeatures,
199
201
  ctaText,
200
202
  ctaUrl,
@@ -886,8 +888,9 @@ var _BridgeClient = class _BridgeClient {
886
888
  }
887
889
  if (!resp.ok) return emptyPage;
888
890
  try {
889
- const body = await resp.json();
890
- 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;
891
894
  return {
892
895
  content: Array.isArray(body.content) ? body.content : [],
893
896
  totalElements: typeof body.totalElements === "number" && Number.isFinite(body.totalElements) ? body.totalElements : 0,
@@ -930,7 +933,8 @@ var _BridgeClient = class _BridgeClient {
930
933
  }
931
934
  if (!resp.ok) return null;
932
935
  try {
933
- const body = await resp.json();
936
+ const raw = await resp.json();
937
+ const body = raw ? raw.data ?? raw : null;
934
938
  if (!body || typeof body.downloadUrl !== "string" || body.downloadUrl.length === 0) {
935
939
  return null;
936
940
  }
@@ -1019,7 +1023,8 @@ var _BridgeClient = class _BridgeClient {
1019
1023
  }
1020
1024
  let body;
1021
1025
  try {
1022
- body = await resp.json();
1026
+ const raw = await resp.json();
1027
+ body = raw?.data ?? raw;
1023
1028
  } catch {
1024
1029
  throw new BridgeClientError(
1025
1030
  "Malformed invoice-payment-initiate response (not JSON)",
@@ -1330,9 +1335,9 @@ var _BridgeClient = class _BridgeClient {
1330
1335
  if (!resp.ok) {
1331
1336
  throw await this.parseError(resp);
1332
1337
  }
1333
- let body;
1338
+ let raw;
1334
1339
  try {
1335
- body = await resp.json();
1340
+ raw = await resp.json();
1336
1341
  } catch {
1337
1342
  throw new BridgeClientError(
1338
1343
  "Malformed confirmCart response (not JSON)",
@@ -1341,6 +1346,7 @@ var _BridgeClient = class _BridgeClient {
1341
1346
  false
1342
1347
  );
1343
1348
  }
1349
+ const body = raw?.data ?? raw ?? {};
1344
1350
  if (!body.cartId || !body.status) {
1345
1351
  throw new BridgeClientError(
1346
1352
  "Malformed confirmCart response (missing required fields)",
@@ -1405,9 +1411,9 @@ var _BridgeClient = class _BridgeClient {
1405
1411
  * undefined access.
1406
1412
  */
1407
1413
  async parseCartResponse(resp, methodName) {
1408
- let body;
1414
+ let raw;
1409
1415
  try {
1410
- body = await resp.json();
1416
+ raw = await resp.json();
1411
1417
  } catch {
1412
1418
  throw new BridgeClientError(
1413
1419
  `Malformed ${methodName} response (not JSON)`,
@@ -1416,7 +1422,8 @@ var _BridgeClient = class _BridgeClient {
1416
1422
  false
1417
1423
  );
1418
1424
  }
1419
- 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) {
1420
1427
  throw new BridgeClientError(
1421
1428
  `Malformed ${methodName} response (missing required fields)`,
1422
1429
  500,
@@ -1425,21 +1432,21 @@ var _BridgeClient = class _BridgeClient {
1425
1432
  );
1426
1433
  }
1427
1434
  return {
1428
- cartId: body.cartId,
1429
- cartType: body.cartType,
1430
- targetId: body.targetId,
1431
- status: body.status,
1432
- totalCents: typeof body.totalCents === "number" && Number.isFinite(body.totalCents) ? body.totalCents : 0,
1433
- currency: typeof body.currency === "string" ? body.currency : "USD",
1434
- gatewayProvider: body.gatewayProvider ?? null,
1435
- gatewayClientSecret: body.gatewayClientSecret ?? null,
1436
- gatewayOrderId: body.gatewayOrderId ?? null,
1437
- gatewayApprovalUrl: body.gatewayApprovalUrl ?? null,
1438
- gatewaySandboxMode: body.gatewaySandboxMode ?? null,
1439
- subscriptionId: body.subscriptionId ?? null,
1440
- invoiceId: body.invoiceId ?? null,
1441
- expiresAt: typeof body.expiresAt === "string" ? body.expiresAt : (/* @__PURE__ */ new Date(0)).toISOString(),
1442
- 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
1443
1450
  };
1444
1451
  }
1445
1452
  /** Public liveness probe. Returns null on failure (not an error). */
@@ -1800,14 +1807,17 @@ var _BridgeClient = class _BridgeClient {
1800
1807
  idempotencyKey,
1801
1808
  sessionJwt
1802
1809
  }),
1803
- body: JSON.stringify(request)
1810
+ // 2026-08-29 fix: same bug as cancelSubscription() below — EmbedUpgradeRequest
1811
+ // requires idempotencyKey as a @NotBlank BODY field, but this only ever sent
1812
+ // it via the Idempotency-Key header.
1813
+ body: JSON.stringify({ ...request, idempotencyKey })
1804
1814
  });
1805
1815
  if (!resp.ok) {
1806
1816
  throw await this.parseError(resp);
1807
1817
  }
1808
- let body;
1818
+ let raw;
1809
1819
  try {
1810
- body = await resp.json();
1820
+ raw = await resp.json();
1811
1821
  } catch {
1812
1822
  throw new BridgeClientError(
1813
1823
  "Malformed upgrade response (not JSON)",
@@ -1816,6 +1826,7 @@ var _BridgeClient = class _BridgeClient {
1816
1826
  false
1817
1827
  );
1818
1828
  }
1829
+ const body = raw ? raw.data ?? raw : {};
1819
1830
  if (!body.subscriptionId || !body.previousOfferingId || !body.newOfferingId || !body.status) {
1820
1831
  throw new BridgeClientError(
1821
1832
  "Malformed upgrade response (missing required fields)",
@@ -1879,14 +1890,19 @@ var _BridgeClient = class _BridgeClient {
1879
1890
  idempotencyKey,
1880
1891
  sessionJwt
1881
1892
  }),
1882
- body: JSON.stringify(request)
1893
+ // 2026-08-29 fix: EmbedCancelRequest (storefront-service) requires
1894
+ // idempotencyKey as a @NotBlank BODY field — this only ever sent it
1895
+ // via the Idempotency-Key header, so every real cancellation 400'd
1896
+ // with "idempotencyKey is required" regardless of any other field.
1897
+ // Confirmed live against production.
1898
+ body: JSON.stringify({ ...request, idempotencyKey })
1883
1899
  });
1884
1900
  if (!resp.ok) {
1885
1901
  throw await this.parseError(resp);
1886
1902
  }
1887
- let body;
1903
+ let raw;
1888
1904
  try {
1889
- body = await resp.json();
1905
+ raw = await resp.json();
1890
1906
  } catch {
1891
1907
  throw new BridgeClientError(
1892
1908
  "Malformed cancel response (not JSON)",
@@ -1895,7 +1911,8 @@ var _BridgeClient = class _BridgeClient {
1895
1911
  false
1896
1912
  );
1897
1913
  }
1898
- if (!body.subscriptionId || !body.status || !body.effectiveAt || !body.feedbackId) {
1914
+ const body = raw ? raw.data ?? raw : null;
1915
+ if (!body || !body.subscriptionId || !body.status || !body.effectiveAt) {
1899
1916
  throw new BridgeClientError(
1900
1917
  "Malformed cancel response (missing required fields)",
1901
1918
  500,
@@ -1908,7 +1925,7 @@ var _BridgeClient = class _BridgeClient {
1908
1925
  status: body.status,
1909
1926
  cancelledAt: body.cancelledAt ?? null,
1910
1927
  effectiveAt: body.effectiveAt,
1911
- feedbackId: body.feedbackId,
1928
+ feedbackId: body.feedbackId ?? null,
1912
1929
  creditNoteId: body.creditNoteId ?? null
1913
1930
  };
1914
1931
  }
@@ -1938,7 +1955,8 @@ var _BridgeClient = class _BridgeClient {
1938
1955
  if (!resp.ok) {
1939
1956
  return { methods: [], defaultMethodId: null };
1940
1957
  }
1941
- const body = await resp.json();
1958
+ const raw = await resp.json();
1959
+ const body = raw ? raw.data ?? raw : {};
1942
1960
  return {
1943
1961
  methods: Array.isArray(body.methods) ? body.methods : [],
1944
1962
  defaultMethodId: body.defaultMethodId ?? null
@@ -1968,7 +1986,8 @@ var _BridgeClient = class _BridgeClient {
1968
1986
  body: JSON.stringify({})
1969
1987
  });
1970
1988
  if (!resp.ok) return null;
1971
- const body = await resp.json();
1989
+ const raw = await resp.json();
1990
+ const body = raw ? raw.data ?? raw : {};
1972
1991
  if (!body.clientSecret) return null;
1973
1992
  return {
1974
1993
  clientSecret: body.clientSecret,
@@ -3048,6 +3067,7 @@ function WidgetShell(props) {
3048
3067
  var DEFAULT_LAYOUT = "horizontal";
3049
3068
  var DEFAULT_MAX_PLANS = 4;
3050
3069
  var DEFAULT_CTA_TEXT = "Get Started";
3070
+ var DEFAULT_CARD_RADIUS = 12;
3051
3071
  function clampLayout(raw) {
3052
3072
  return raw === "horizontal" || raw === "vertical" || raw === "table" ? raw : void 0;
3053
3073
  }
@@ -3058,7 +3078,7 @@ function setTenantDefaultsIdempotent(setter, next) {
3058
3078
  setter((prev) => {
3059
3079
  if (prev === next) return prev;
3060
3080
  if (!prev && !next) return prev;
3061
- if (prev && next && prev.layout === next.layout && prev.theme === next.theme && prev.maxPlans === next.maxPlans && prev.showFeatures === next.showFeatures && prev.ctaText === next.ctaText) {
3081
+ if (prev && next && prev.layout === next.layout && prev.theme === next.theme && prev.maxPlans === next.maxPlans && prev.showFeatures === next.showFeatures && prev.ctaText === next.ctaText && prev.borderRadius === next.borderRadius) {
3062
3082
  return prev;
3063
3083
  }
3064
3084
  return next;
@@ -3073,7 +3093,8 @@ function extractTenantDefaults(config) {
3073
3093
  theme: typeof raw.theme === "string" ? raw.theme : void 0,
3074
3094
  maxPlans: typeof raw.maxPlans === "number" && Number.isFinite(raw.maxPlans) ? raw.maxPlans : void 0,
3075
3095
  showFeatures: typeof raw.showFeatures === "boolean" ? raw.showFeatures : void 0,
3076
- ctaText: typeof raw.ctaText === "string" && raw.ctaText.length > 0 ? raw.ctaText : void 0
3096
+ ctaText: typeof raw.ctaText === "string" && raw.ctaText.length > 0 ? raw.ctaText : void 0,
3097
+ borderRadius: typeof raw.borderRadius === "number" && Number.isFinite(raw.borderRadius) ? raw.borderRadius : void 0
3077
3098
  };
3078
3099
  }
3079
3100
  var DARK_TOKEN_OVERLAY = {
@@ -3195,6 +3216,7 @@ function PricingCardBody(props) {
3195
3216
  theme: themeProp,
3196
3217
  locale: localeProp,
3197
3218
  maxPlans: maxPlansProp,
3219
+ borderRadius: borderRadiusProp,
3198
3220
  showFeatures: showFeaturesProp,
3199
3221
  ctaText: ctaTextProp,
3200
3222
  ctaUrl: ctaUrlProp,
@@ -3208,6 +3230,7 @@ function PricingCardBody(props) {
3208
3230
  const maxPlans = typeof maxPlansProp === "number" && Number.isFinite(maxPlansProp) ? maxPlansProp : typeof tenantDefaults?.maxPlans === "number" && Number.isFinite(tenantDefaults.maxPlans) ? tenantDefaults.maxPlans : DEFAULT_MAX_PLANS;
3209
3231
  const showFeatures = typeof showFeaturesProp === "boolean" ? showFeaturesProp : typeof tenantDefaults?.showFeatures === "boolean" ? tenantDefaults.showFeatures : true;
3210
3232
  const ctaTextEffective = ctaTextProp ?? tenantDefaults?.ctaText ?? void 0;
3233
+ const cardRadius = typeof borderRadiusProp === "number" && Number.isFinite(borderRadiusProp) ? borderRadiusProp : typeof tenantDefaults?.borderRadius === "number" && Number.isFinite(tenantDefaults.borderRadius) ? tenantDefaults.borderRadius : DEFAULT_CARD_RADIUS;
3211
3234
  const shell = useWidgetShell();
3212
3235
  const { tokens: shellTokens, bridgeClient, telemetry, bus, tenantSlug } = shell;
3213
3236
  const isDark = React7__namespace.useMemo(() => {
@@ -3425,7 +3448,8 @@ function PricingCardBody(props) {
3425
3448
  {
3426
3449
  layout,
3427
3450
  tokens,
3428
- prefersReducedMotion
3451
+ prefersReducedMotion,
3452
+ cardRadius
3429
3453
  }
3430
3454
  )
3431
3455
  }
@@ -3497,7 +3521,8 @@ function PricingCardBody(props) {
3497
3521
  ctaTextProp: ctaTextEffective,
3498
3522
  featuredOverride: featuredOfferingId,
3499
3523
  onCtaClick: handleCtaClick,
3500
- intlOverride
3524
+ intlOverride,
3525
+ cardRadius
3501
3526
  }
3502
3527
  )
3503
3528
  }
@@ -3512,7 +3537,8 @@ function PlanGrid({
3512
3537
  ctaTextProp,
3513
3538
  featuredOverride,
3514
3539
  onCtaClick,
3515
- intlOverride
3540
+ intlOverride,
3541
+ cardRadius
3516
3542
  }) {
3517
3543
  const isHorizontal = layout === "horizontal";
3518
3544
  const gridStyle2 = isHorizontal ? {
@@ -3535,7 +3561,8 @@ function PlanGrid({
3535
3561
  ctaTextProp,
3536
3562
  featured: offeringIsFeatured(o, featuredOverride),
3537
3563
  onCtaClick,
3538
- intlOverride
3564
+ intlOverride,
3565
+ cardRadius
3539
3566
  },
3540
3567
  o.offeringId
3541
3568
  )) });
@@ -3548,7 +3575,8 @@ function PlanCard({
3548
3575
  ctaTextProp,
3549
3576
  featured,
3550
3577
  onCtaClick,
3551
- intlOverride
3578
+ intlOverride,
3579
+ cardRadius
3552
3580
  }) {
3553
3581
  const { text: price, unitSuffix } = resolveDisplayPrice(offering, locale, intlOverride);
3554
3582
  const isContactSales = price === "\u2014";
@@ -3559,7 +3587,7 @@ function PlanCard({
3559
3587
  display: "flex",
3560
3588
  flexDirection: "column",
3561
3589
  padding: 24,
3562
- borderRadius: 12,
3590
+ borderRadius: cardRadius,
3563
3591
  border: featured ? `2px solid ${tokens.primary}` : `1px solid ${tokens.border}`,
3564
3592
  background: tokens.bg,
3565
3593
  color: tokens.text,
@@ -3909,7 +3937,8 @@ function cellAria(label, feature) {
3909
3937
  function LoadingSkeleton({
3910
3938
  layout,
3911
3939
  tokens,
3912
- prefersReducedMotion
3940
+ prefersReducedMotion,
3941
+ cardRadius
3913
3942
  }) {
3914
3943
  const shimmerStyle = prefersReducedMotion ? { background: tokens.border, opacity: 0.6 } : {
3915
3944
  background: `linear-gradient(90deg, ${tokens.border} 0%, ${tokens.bg} 50%, ${tokens.border} 100%)`,
@@ -3942,7 +3971,7 @@ function LoadingSkeleton({
3942
3971
  "aria-hidden": "true",
3943
3972
  style: {
3944
3973
  padding: 24,
3945
- borderRadius: 12,
3974
+ borderRadius: cardRadius,
3946
3975
  border: `1px solid ${tokens.border}`,
3947
3976
  background: tokens.bg,
3948
3977
  minHeight: 280,
@@ -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,