@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.
- package/CHANGELOG.md +111 -0
- package/dist/{AforoEmbed-VYb6_GXB.d.cts → AforoEmbed-BX2HPXWT.d.cts} +1 -1
- package/dist/{AforoEmbed-BkJF1hAN.d.ts → AforoEmbed-PsTY7zh0.d.ts} +1 -1
- package/dist/index.cjs +72 -45
- package/dist/index.d.cts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.mjs +72 -45
- package/dist/loader.js +1 -1
- package/dist/loader.mjs +1 -1
- package/dist/sri.json +11 -11
- package/dist/{types-BbQw2_32.d.cts → types-RMTEXoGw.d.cts} +7 -2
- package/dist/{types-BbQw2_32.d.ts → types-RMTEXoGw.d.ts} +7 -2
- package/dist/vanilla/index.cjs +74 -45
- package/dist/vanilla/index.d.cts +2 -2
- package/dist/vanilla/index.d.ts +2 -2
- package/dist/vanilla/index.mjs +74 -45
- package/dist/vue/index.cjs +74 -45
- package/dist/vue/index.d.cts +1 -1
- package/dist/vue/index.d.ts +1 -1
- package/dist/vue/index.mjs +74 -45
- package/dist/widgets/checkout-flow.js +5 -5
- package/dist/widgets/invoice-list.js +5 -5
- package/dist/widgets/payment-method.js +5 -5
- package/dist/widgets/pricing-card.js +8 -8
- package/dist/widgets/subscribe-button.js +7 -7
- package/dist/widgets/subscription-manager.js +5 -5
- package/dist/widgets/upgrade-cancel.js +5 -5
- package/dist/widgets/usage-meter.js +7 -7
- package/loader.sri.txt +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,117 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [1.0.11] — 2026-08-30
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **SC-Ticket-10: Checkout Flow's `createCart`/`getCart`/`updateCustomerDetails`/
|
|
16
|
+
`initiatePayment`/`confirmCart` threw "Malformed \<method\> response
|
|
17
|
+
(missing required fields)" on every genuinely successful backend
|
|
18
|
+
response.** `parseCartResponse()` (shared by the first four) and
|
|
19
|
+
`confirmCart()`'s own inline parser both read `cartId`/`cartType`/
|
|
20
|
+
`status`/`targetId` directly off the top-level JSON body instead of
|
|
21
|
+
unwrapping `{success, data, meta}` — same bug class as 1.0.7/1.0.9/1.0.10,
|
|
22
|
+
just never applied to the checkout-cart family. Live-verified against the
|
|
23
|
+
isopacai tenant with a real ACTIVE offering: `exchange()` itself (and the
|
|
24
|
+
rest of the bootstrap path) already worked fine — the reported ticket
|
|
25
|
+
title ("Malformed bridge exchange response") was a misdiagnosis one call
|
|
26
|
+
later in the same flow, exactly like SC-Ticket-5.
|
|
27
|
+
|
|
28
|
+
## [1.0.10] — 2026-08-29
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- **SC-Ticket-5: Payment Method widget's initial load silently showed 0
|
|
33
|
+
payment methods for every customer, even ones with real saved cards.**
|
|
34
|
+
`fetchPaymentMethods()` and `createPaymentMethodSetupIntent()` read
|
|
35
|
+
response fields directly off the top-level JSON body instead of
|
|
36
|
+
unwrapping `{success, data, meta}` — same bug class fixed for
|
|
37
|
+
`fetchInvoices()` (1.0.7) and the cancel/upgrade responses (1.0.9), never
|
|
38
|
+
applied here. `fetchPaymentMethods()` is Pattern #18 fail-soft, so this
|
|
39
|
+
never threw a visible error — it just silently returned an empty list
|
|
40
|
+
regardless of how many cards the customer actually had on file.
|
|
41
|
+
(Live-verified `exchange()` itself, and the widget bundle's own deployed
|
|
42
|
+
copy of it, are both already correct — the ticket's reported "Malformed
|
|
43
|
+
bridge exchange response" text is a misdiagnosis of this unwrap bug one
|
|
44
|
+
call later in the same load path.)
|
|
45
|
+
|
|
46
|
+
## [1.0.9] — 2026-08-29
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- **SC-Ticket-4 continued: cancellation succeeded server-side but the widget
|
|
51
|
+
still showed "Could not cancel."** After the 1.0.8 idempotencyKey fix,
|
|
52
|
+
live testing surfaced two more bugs in the same response path:
|
|
53
|
+
`cancelSubscription()`/`upgradeSubscription()` read fields directly off
|
|
54
|
+
the top-level response body instead of unwrapping `{success, data, meta}`
|
|
55
|
+
(same class of bug fixed for `fetchInvoices()` in 1.0.7, never applied
|
|
56
|
+
here), and `cancelSubscription()` additionally required `feedbackId` to
|
|
57
|
+
be present even though storefront-service's `/cancel` endpoint
|
|
58
|
+
deliberately omits it today (documented follow-up to read the V50 audit
|
|
59
|
+
row id back from pricing-service). Together these rejected every
|
|
60
|
+
genuinely successful cancellation as "malformed." `CancelResponse.feedbackId`
|
|
61
|
+
is now `string | null`. Live-verified: a real subscription
|
|
62
|
+
(`1b3af07f-d248-4860-a02b-9e3ee5601200`) was cancelled server-side
|
|
63
|
+
(confirmed `status: CANCELLED` in the raw API response) but the widget
|
|
64
|
+
still errored before this fix; re-tested after deploying 1.0.9.
|
|
65
|
+
|
|
66
|
+
## [1.0.8] — 2026-08-29
|
|
67
|
+
|
|
68
|
+
### Fixed
|
|
69
|
+
|
|
70
|
+
- **SC-Ticket-4: Upgrade/Cancel widget's Confirm step always failed** — the
|
|
71
|
+
ticket's reported symptom ("Malformed bridge exchange response") turned
|
|
72
|
+
out to be a misdiagnosis of a different, real bug one step later:
|
|
73
|
+
`cancelSubscription()` and `upgradeSubscription()` sent `idempotencyKey`
|
|
74
|
+
only via the `Idempotency-Key` header, but storefront-service's
|
|
75
|
+
`EmbedCancelRequest`/`EmbedUpgradeRequest` DTOs require it as a
|
|
76
|
+
`@NotBlank` BODY field too. Every real cancellation or upgrade 400'd with
|
|
77
|
+
"idempotencyKey is required" (or, before a separate backend fix shipped
|
|
78
|
+
the same day, "Invalid value 'DISCOUNT_20_PCT' for field
|
|
79
|
+
'retentionOfferShown'" — the backend enum never matched the widget's own
|
|
80
|
+
documented `RetentionOfferShown` values). Both methods now include
|
|
81
|
+
`idempotencyKey` in the serialized body as well as the header.
|
|
82
|
+
Live-verified: a real subscription was successfully cancelled end-to-end
|
|
83
|
+
through this exact code path after the fix.
|
|
84
|
+
|
|
85
|
+
## [1.0.7] — 2026-08-29
|
|
86
|
+
|
|
87
|
+
### Fixed
|
|
88
|
+
|
|
89
|
+
- **SC-Ticket-3: Invoice List widget always showed "0 invoices" even when
|
|
90
|
+
the customer had real, finalized invoices.** `BridgeClient.fetchInvoices()`
|
|
91
|
+
read `content`/`totalElements`/`totalPages` directly off the top-level
|
|
92
|
+
parsed JSON body, but `GET /api/v1/portal/embed/invoices` (like every
|
|
93
|
+
other Aforo endpoint) wraps its payload in `{success, data, meta}` via the
|
|
94
|
+
platform's global `ApiResponseAdvice`. `body.content` was therefore always
|
|
95
|
+
`undefined`, silently falling back to an empty page — same failure mode
|
|
96
|
+
as the pricing-card `offerings` bug fixed in 1.0.5, just never applied
|
|
97
|
+
here. Live-verified: the API correctly returned 3 real invoices
|
|
98
|
+
(confirmed via direct backend testing) while the widget rendered "No
|
|
99
|
+
invoices yet." `fetchInvoicePdfUrl()` and `initiateInvoicePayment()` had
|
|
100
|
+
the identical bug and are fixed the same way (`raw.data ?? raw` unwrap,
|
|
101
|
+
matching the existing pattern already used in `exchange()` /
|
|
102
|
+
`fetchHeadlessConfig()` / `initiateCheckout()`).
|
|
103
|
+
|
|
104
|
+
## [1.0.6] — 2026-08-26
|
|
105
|
+
|
|
106
|
+
### Fixed
|
|
107
|
+
|
|
108
|
+
- **PricingCard's published "Card border radius" setting (Embed Studio →
|
|
109
|
+
Appearance) was never applied.** `borderRadius` is a valid field on the
|
|
110
|
+
fetched `embeddableWidget` tenant-defaults object — the tenant config API
|
|
111
|
+
correctly returned it — but `extractTenantDefaults()` only extracted its
|
|
112
|
+
sibling fields (`layout`, `theme`, `maxPlans`, `showFeatures`, `ctaText`)
|
|
113
|
+
and silently dropped `borderRadius`. The plan card's corner radius was
|
|
114
|
+
also hardcoded (`borderRadius: 12`) rather than reading any dynamic value.
|
|
115
|
+
`AforoPricingCardProps` now accepts an explicit `borderRadius` prop,
|
|
116
|
+
`extractTenantDefaults()` reads it from the tenant's published config, and
|
|
117
|
+
the resolved value (prop → tenant default → built-in 12px) is applied to
|
|
118
|
+
the plan card and its loading-skeleton twin. `pricingCardConfigToProps()`
|
|
119
|
+
also maps a `data-border-radius`/`borderRadius` mount-config override for
|
|
120
|
+
Script Tag integrations.
|
|
121
|
+
|
|
11
122
|
## [1.0.5] — 2026-08-26
|
|
12
123
|
|
|
13
124
|
### Fixed
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { aD as WidgetMountConfig, Q as AforoEventType, N as AforoEventPayload, aC as WidgetId } from './types-
|
|
1
|
+
import { aD as WidgetMountConfig, Q as AforoEventType, N as AforoEventPayload, aC as WidgetId } from './types-RMTEXoGw.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* AforoEmbed — vanilla-JS + script-tag mount API.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { aD as WidgetMountConfig, Q as AforoEventType, N as AforoEventPayload, aC as WidgetId } from './types-
|
|
1
|
+
import { aD as WidgetMountConfig, Q as AforoEventType, N as AforoEventPayload, aC as WidgetId } from './types-RMTEXoGw.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* AforoEmbed — vanilla-JS + script-tag mount API.
|
package/dist/index.cjs
CHANGED
|
@@ -510,8 +510,9 @@ var _BridgeClient = class _BridgeClient {
|
|
|
510
510
|
}
|
|
511
511
|
if (!resp.ok) return emptyPage;
|
|
512
512
|
try {
|
|
513
|
-
const
|
|
514
|
-
if (!
|
|
513
|
+
const raw = await resp.json();
|
|
514
|
+
if (!raw || typeof raw !== "object") return emptyPage;
|
|
515
|
+
const body = raw.data ?? raw;
|
|
515
516
|
return {
|
|
516
517
|
content: Array.isArray(body.content) ? body.content : [],
|
|
517
518
|
totalElements: typeof body.totalElements === "number" && Number.isFinite(body.totalElements) ? body.totalElements : 0,
|
|
@@ -554,7 +555,8 @@ var _BridgeClient = class _BridgeClient {
|
|
|
554
555
|
}
|
|
555
556
|
if (!resp.ok) return null;
|
|
556
557
|
try {
|
|
557
|
-
const
|
|
558
|
+
const raw = await resp.json();
|
|
559
|
+
const body = raw ? raw.data ?? raw : null;
|
|
558
560
|
if (!body || typeof body.downloadUrl !== "string" || body.downloadUrl.length === 0) {
|
|
559
561
|
return null;
|
|
560
562
|
}
|
|
@@ -643,7 +645,8 @@ var _BridgeClient = class _BridgeClient {
|
|
|
643
645
|
}
|
|
644
646
|
let body;
|
|
645
647
|
try {
|
|
646
|
-
|
|
648
|
+
const raw = await resp.json();
|
|
649
|
+
body = raw?.data ?? raw;
|
|
647
650
|
} catch {
|
|
648
651
|
throw new BridgeClientError(
|
|
649
652
|
"Malformed invoice-payment-initiate response (not JSON)",
|
|
@@ -954,9 +957,9 @@ var _BridgeClient = class _BridgeClient {
|
|
|
954
957
|
if (!resp.ok) {
|
|
955
958
|
throw await this.parseError(resp);
|
|
956
959
|
}
|
|
957
|
-
let
|
|
960
|
+
let raw;
|
|
958
961
|
try {
|
|
959
|
-
|
|
962
|
+
raw = await resp.json();
|
|
960
963
|
} catch {
|
|
961
964
|
throw new BridgeClientError(
|
|
962
965
|
"Malformed confirmCart response (not JSON)",
|
|
@@ -965,6 +968,7 @@ var _BridgeClient = class _BridgeClient {
|
|
|
965
968
|
false
|
|
966
969
|
);
|
|
967
970
|
}
|
|
971
|
+
const body = raw?.data ?? raw ?? {};
|
|
968
972
|
if (!body.cartId || !body.status) {
|
|
969
973
|
throw new BridgeClientError(
|
|
970
974
|
"Malformed confirmCart response (missing required fields)",
|
|
@@ -1029,9 +1033,9 @@ var _BridgeClient = class _BridgeClient {
|
|
|
1029
1033
|
* undefined access.
|
|
1030
1034
|
*/
|
|
1031
1035
|
async parseCartResponse(resp, methodName) {
|
|
1032
|
-
let
|
|
1036
|
+
let raw;
|
|
1033
1037
|
try {
|
|
1034
|
-
|
|
1038
|
+
raw = await resp.json();
|
|
1035
1039
|
} catch {
|
|
1036
1040
|
throw new BridgeClientError(
|
|
1037
1041
|
`Malformed ${methodName} response (not JSON)`,
|
|
@@ -1040,7 +1044,8 @@ var _BridgeClient = class _BridgeClient {
|
|
|
1040
1044
|
false
|
|
1041
1045
|
);
|
|
1042
1046
|
}
|
|
1043
|
-
|
|
1047
|
+
const data = raw?.data ?? raw ?? {};
|
|
1048
|
+
if (!data.cartId || !data.cartType || !data.status || !data.targetId) {
|
|
1044
1049
|
throw new BridgeClientError(
|
|
1045
1050
|
`Malformed ${methodName} response (missing required fields)`,
|
|
1046
1051
|
500,
|
|
@@ -1049,21 +1054,21 @@ var _BridgeClient = class _BridgeClient {
|
|
|
1049
1054
|
);
|
|
1050
1055
|
}
|
|
1051
1056
|
return {
|
|
1052
|
-
cartId:
|
|
1053
|
-
cartType:
|
|
1054
|
-
targetId:
|
|
1055
|
-
status:
|
|
1056
|
-
totalCents: typeof
|
|
1057
|
-
currency: typeof
|
|
1058
|
-
gatewayProvider:
|
|
1059
|
-
gatewayClientSecret:
|
|
1060
|
-
gatewayOrderId:
|
|
1061
|
-
gatewayApprovalUrl:
|
|
1062
|
-
gatewaySandboxMode:
|
|
1063
|
-
subscriptionId:
|
|
1064
|
-
invoiceId:
|
|
1065
|
-
expiresAt: typeof
|
|
1066
|
-
completedAt:
|
|
1057
|
+
cartId: data.cartId,
|
|
1058
|
+
cartType: data.cartType,
|
|
1059
|
+
targetId: data.targetId,
|
|
1060
|
+
status: data.status,
|
|
1061
|
+
totalCents: typeof data.totalCents === "number" && Number.isFinite(data.totalCents) ? data.totalCents : 0,
|
|
1062
|
+
currency: typeof data.currency === "string" ? data.currency : "USD",
|
|
1063
|
+
gatewayProvider: data.gatewayProvider ?? null,
|
|
1064
|
+
gatewayClientSecret: data.gatewayClientSecret ?? null,
|
|
1065
|
+
gatewayOrderId: data.gatewayOrderId ?? null,
|
|
1066
|
+
gatewayApprovalUrl: data.gatewayApprovalUrl ?? null,
|
|
1067
|
+
gatewaySandboxMode: data.gatewaySandboxMode ?? null,
|
|
1068
|
+
subscriptionId: data.subscriptionId ?? null,
|
|
1069
|
+
invoiceId: data.invoiceId ?? null,
|
|
1070
|
+
expiresAt: typeof data.expiresAt === "string" ? data.expiresAt : (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
1071
|
+
completedAt: data.completedAt ?? null
|
|
1067
1072
|
};
|
|
1068
1073
|
}
|
|
1069
1074
|
/** Public liveness probe. Returns null on failure (not an error). */
|
|
@@ -1424,14 +1429,17 @@ var _BridgeClient = class _BridgeClient {
|
|
|
1424
1429
|
idempotencyKey,
|
|
1425
1430
|
sessionJwt
|
|
1426
1431
|
}),
|
|
1427
|
-
|
|
1432
|
+
// 2026-08-29 fix: same bug as cancelSubscription() below — EmbedUpgradeRequest
|
|
1433
|
+
// requires idempotencyKey as a @NotBlank BODY field, but this only ever sent
|
|
1434
|
+
// it via the Idempotency-Key header.
|
|
1435
|
+
body: JSON.stringify({ ...request, idempotencyKey })
|
|
1428
1436
|
});
|
|
1429
1437
|
if (!resp.ok) {
|
|
1430
1438
|
throw await this.parseError(resp);
|
|
1431
1439
|
}
|
|
1432
|
-
let
|
|
1440
|
+
let raw;
|
|
1433
1441
|
try {
|
|
1434
|
-
|
|
1442
|
+
raw = await resp.json();
|
|
1435
1443
|
} catch {
|
|
1436
1444
|
throw new BridgeClientError(
|
|
1437
1445
|
"Malformed upgrade response (not JSON)",
|
|
@@ -1440,6 +1448,7 @@ var _BridgeClient = class _BridgeClient {
|
|
|
1440
1448
|
false
|
|
1441
1449
|
);
|
|
1442
1450
|
}
|
|
1451
|
+
const body = raw ? raw.data ?? raw : {};
|
|
1443
1452
|
if (!body.subscriptionId || !body.previousOfferingId || !body.newOfferingId || !body.status) {
|
|
1444
1453
|
throw new BridgeClientError(
|
|
1445
1454
|
"Malformed upgrade response (missing required fields)",
|
|
@@ -1503,14 +1512,19 @@ var _BridgeClient = class _BridgeClient {
|
|
|
1503
1512
|
idempotencyKey,
|
|
1504
1513
|
sessionJwt
|
|
1505
1514
|
}),
|
|
1506
|
-
|
|
1515
|
+
// 2026-08-29 fix: EmbedCancelRequest (storefront-service) requires
|
|
1516
|
+
// idempotencyKey as a @NotBlank BODY field — this only ever sent it
|
|
1517
|
+
// via the Idempotency-Key header, so every real cancellation 400'd
|
|
1518
|
+
// with "idempotencyKey is required" regardless of any other field.
|
|
1519
|
+
// Confirmed live against production.
|
|
1520
|
+
body: JSON.stringify({ ...request, idempotencyKey })
|
|
1507
1521
|
});
|
|
1508
1522
|
if (!resp.ok) {
|
|
1509
1523
|
throw await this.parseError(resp);
|
|
1510
1524
|
}
|
|
1511
|
-
let
|
|
1525
|
+
let raw;
|
|
1512
1526
|
try {
|
|
1513
|
-
|
|
1527
|
+
raw = await resp.json();
|
|
1514
1528
|
} catch {
|
|
1515
1529
|
throw new BridgeClientError(
|
|
1516
1530
|
"Malformed cancel response (not JSON)",
|
|
@@ -1519,7 +1533,8 @@ var _BridgeClient = class _BridgeClient {
|
|
|
1519
1533
|
false
|
|
1520
1534
|
);
|
|
1521
1535
|
}
|
|
1522
|
-
|
|
1536
|
+
const body = raw ? raw.data ?? raw : null;
|
|
1537
|
+
if (!body || !body.subscriptionId || !body.status || !body.effectiveAt) {
|
|
1523
1538
|
throw new BridgeClientError(
|
|
1524
1539
|
"Malformed cancel response (missing required fields)",
|
|
1525
1540
|
500,
|
|
@@ -1532,7 +1547,7 @@ var _BridgeClient = class _BridgeClient {
|
|
|
1532
1547
|
status: body.status,
|
|
1533
1548
|
cancelledAt: body.cancelledAt ?? null,
|
|
1534
1549
|
effectiveAt: body.effectiveAt,
|
|
1535
|
-
feedbackId: body.feedbackId,
|
|
1550
|
+
feedbackId: body.feedbackId ?? null,
|
|
1536
1551
|
creditNoteId: body.creditNoteId ?? null
|
|
1537
1552
|
};
|
|
1538
1553
|
}
|
|
@@ -1562,7 +1577,8 @@ var _BridgeClient = class _BridgeClient {
|
|
|
1562
1577
|
if (!resp.ok) {
|
|
1563
1578
|
return { methods: [], defaultMethodId: null };
|
|
1564
1579
|
}
|
|
1565
|
-
const
|
|
1580
|
+
const raw = await resp.json();
|
|
1581
|
+
const body = raw ? raw.data ?? raw : {};
|
|
1566
1582
|
return {
|
|
1567
1583
|
methods: Array.isArray(body.methods) ? body.methods : [],
|
|
1568
1584
|
defaultMethodId: body.defaultMethodId ?? null
|
|
@@ -1592,7 +1608,8 @@ var _BridgeClient = class _BridgeClient {
|
|
|
1592
1608
|
body: JSON.stringify({})
|
|
1593
1609
|
});
|
|
1594
1610
|
if (!resp.ok) return null;
|
|
1595
|
-
const
|
|
1611
|
+
const raw = await resp.json();
|
|
1612
|
+
const body = raw ? raw.data ?? raw : {};
|
|
1596
1613
|
if (!body.clientSecret) return null;
|
|
1597
1614
|
return {
|
|
1598
1615
|
clientSecret: body.clientSecret,
|
|
@@ -2672,6 +2689,7 @@ function WidgetShell(props) {
|
|
|
2672
2689
|
var DEFAULT_LAYOUT = "horizontal";
|
|
2673
2690
|
var DEFAULT_MAX_PLANS = 4;
|
|
2674
2691
|
var DEFAULT_CTA_TEXT = "Get Started";
|
|
2692
|
+
var DEFAULT_CARD_RADIUS = 12;
|
|
2675
2693
|
function clampLayout(raw) {
|
|
2676
2694
|
return raw === "horizontal" || raw === "vertical" || raw === "table" ? raw : void 0;
|
|
2677
2695
|
}
|
|
@@ -2682,7 +2700,7 @@ function setTenantDefaultsIdempotent(setter, next) {
|
|
|
2682
2700
|
setter((prev) => {
|
|
2683
2701
|
if (prev === next) return prev;
|
|
2684
2702
|
if (!prev && !next) return prev;
|
|
2685
|
-
if (prev && next && prev.layout === next.layout && prev.theme === next.theme && prev.maxPlans === next.maxPlans && prev.showFeatures === next.showFeatures && prev.ctaText === next.ctaText) {
|
|
2703
|
+
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) {
|
|
2686
2704
|
return prev;
|
|
2687
2705
|
}
|
|
2688
2706
|
return next;
|
|
@@ -2697,7 +2715,8 @@ function extractTenantDefaults(config) {
|
|
|
2697
2715
|
theme: typeof raw.theme === "string" ? raw.theme : void 0,
|
|
2698
2716
|
maxPlans: typeof raw.maxPlans === "number" && Number.isFinite(raw.maxPlans) ? raw.maxPlans : void 0,
|
|
2699
2717
|
showFeatures: typeof raw.showFeatures === "boolean" ? raw.showFeatures : void 0,
|
|
2700
|
-
ctaText: typeof raw.ctaText === "string" && raw.ctaText.length > 0 ? raw.ctaText : void 0
|
|
2718
|
+
ctaText: typeof raw.ctaText === "string" && raw.ctaText.length > 0 ? raw.ctaText : void 0,
|
|
2719
|
+
borderRadius: typeof raw.borderRadius === "number" && Number.isFinite(raw.borderRadius) ? raw.borderRadius : void 0
|
|
2701
2720
|
};
|
|
2702
2721
|
}
|
|
2703
2722
|
var DARK_TOKEN_OVERLAY = {
|
|
@@ -2819,6 +2838,7 @@ function PricingCardBody(props) {
|
|
|
2819
2838
|
theme: themeProp,
|
|
2820
2839
|
locale: localeProp,
|
|
2821
2840
|
maxPlans: maxPlansProp,
|
|
2841
|
+
borderRadius: borderRadiusProp,
|
|
2822
2842
|
showFeatures: showFeaturesProp,
|
|
2823
2843
|
ctaText: ctaTextProp,
|
|
2824
2844
|
ctaUrl: ctaUrlProp,
|
|
@@ -2832,6 +2852,7 @@ function PricingCardBody(props) {
|
|
|
2832
2852
|
const maxPlans = typeof maxPlansProp === "number" && Number.isFinite(maxPlansProp) ? maxPlansProp : typeof tenantDefaults?.maxPlans === "number" && Number.isFinite(tenantDefaults.maxPlans) ? tenantDefaults.maxPlans : DEFAULT_MAX_PLANS;
|
|
2833
2853
|
const showFeatures = typeof showFeaturesProp === "boolean" ? showFeaturesProp : typeof tenantDefaults?.showFeatures === "boolean" ? tenantDefaults.showFeatures : true;
|
|
2834
2854
|
const ctaTextEffective = ctaTextProp ?? tenantDefaults?.ctaText ?? void 0;
|
|
2855
|
+
const cardRadius = typeof borderRadiusProp === "number" && Number.isFinite(borderRadiusProp) ? borderRadiusProp : typeof tenantDefaults?.borderRadius === "number" && Number.isFinite(tenantDefaults.borderRadius) ? tenantDefaults.borderRadius : DEFAULT_CARD_RADIUS;
|
|
2835
2856
|
const shell = useWidgetShell();
|
|
2836
2857
|
const { tokens: shellTokens, bridgeClient, telemetry, bus, tenantSlug } = shell;
|
|
2837
2858
|
const isDark = React7__namespace.useMemo(() => {
|
|
@@ -3049,7 +3070,8 @@ function PricingCardBody(props) {
|
|
|
3049
3070
|
{
|
|
3050
3071
|
layout,
|
|
3051
3072
|
tokens,
|
|
3052
|
-
prefersReducedMotion
|
|
3073
|
+
prefersReducedMotion,
|
|
3074
|
+
cardRadius
|
|
3053
3075
|
}
|
|
3054
3076
|
)
|
|
3055
3077
|
}
|
|
@@ -3121,7 +3143,8 @@ function PricingCardBody(props) {
|
|
|
3121
3143
|
ctaTextProp: ctaTextEffective,
|
|
3122
3144
|
featuredOverride: featuredOfferingId,
|
|
3123
3145
|
onCtaClick: handleCtaClick,
|
|
3124
|
-
intlOverride
|
|
3146
|
+
intlOverride,
|
|
3147
|
+
cardRadius
|
|
3125
3148
|
}
|
|
3126
3149
|
)
|
|
3127
3150
|
}
|
|
@@ -3136,7 +3159,8 @@ function PlanGrid({
|
|
|
3136
3159
|
ctaTextProp,
|
|
3137
3160
|
featuredOverride,
|
|
3138
3161
|
onCtaClick,
|
|
3139
|
-
intlOverride
|
|
3162
|
+
intlOverride,
|
|
3163
|
+
cardRadius
|
|
3140
3164
|
}) {
|
|
3141
3165
|
const isHorizontal = layout === "horizontal";
|
|
3142
3166
|
const gridStyle2 = isHorizontal ? {
|
|
@@ -3159,7 +3183,8 @@ function PlanGrid({
|
|
|
3159
3183
|
ctaTextProp,
|
|
3160
3184
|
featured: offeringIsFeatured(o, featuredOverride),
|
|
3161
3185
|
onCtaClick,
|
|
3162
|
-
intlOverride
|
|
3186
|
+
intlOverride,
|
|
3187
|
+
cardRadius
|
|
3163
3188
|
},
|
|
3164
3189
|
o.offeringId
|
|
3165
3190
|
)) });
|
|
@@ -3172,7 +3197,8 @@ function PlanCard({
|
|
|
3172
3197
|
ctaTextProp,
|
|
3173
3198
|
featured,
|
|
3174
3199
|
onCtaClick,
|
|
3175
|
-
intlOverride
|
|
3200
|
+
intlOverride,
|
|
3201
|
+
cardRadius
|
|
3176
3202
|
}) {
|
|
3177
3203
|
const { text: price, unitSuffix } = resolveDisplayPrice(offering, locale, intlOverride);
|
|
3178
3204
|
const isContactSales = price === "\u2014";
|
|
@@ -3183,7 +3209,7 @@ function PlanCard({
|
|
|
3183
3209
|
display: "flex",
|
|
3184
3210
|
flexDirection: "column",
|
|
3185
3211
|
padding: 24,
|
|
3186
|
-
borderRadius:
|
|
3212
|
+
borderRadius: cardRadius,
|
|
3187
3213
|
border: featured ? `2px solid ${tokens.primary}` : `1px solid ${tokens.border}`,
|
|
3188
3214
|
background: tokens.bg,
|
|
3189
3215
|
color: tokens.text,
|
|
@@ -3533,7 +3559,8 @@ function cellAria(label, feature) {
|
|
|
3533
3559
|
function LoadingSkeleton({
|
|
3534
3560
|
layout,
|
|
3535
3561
|
tokens,
|
|
3536
|
-
prefersReducedMotion
|
|
3562
|
+
prefersReducedMotion,
|
|
3563
|
+
cardRadius
|
|
3537
3564
|
}) {
|
|
3538
3565
|
const shimmerStyle = prefersReducedMotion ? { background: tokens.border, opacity: 0.6 } : {
|
|
3539
3566
|
background: `linear-gradient(90deg, ${tokens.border} 0%, ${tokens.bg} 50%, ${tokens.border} 100%)`,
|
|
@@ -3566,7 +3593,7 @@ function LoadingSkeleton({
|
|
|
3566
3593
|
"aria-hidden": "true",
|
|
3567
3594
|
style: {
|
|
3568
3595
|
padding: 24,
|
|
3569
|
-
borderRadius:
|
|
3596
|
+
borderRadius: cardRadius,
|
|
3570
3597
|
border: `1px solid ${tokens.border}`,
|
|
3571
3598
|
background: tokens.bg,
|
|
3572
3599
|
minHeight: 280,
|
|
@@ -12198,7 +12225,7 @@ function ResultPanel({
|
|
|
12198
12225
|
}
|
|
12199
12226
|
|
|
12200
12227
|
// src/core/version.ts
|
|
12201
|
-
var VERSION = "1.0.
|
|
12228
|
+
var VERSION = "1.0.11";
|
|
12202
12229
|
|
|
12203
12230
|
// src/core/AforoEmbed.ts
|
|
12204
12231
|
var mountedElements = /* @__PURE__ */ new WeakMap();
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { T as ThemeTokenOverrides, O as OfferingPayload, H as HeadlessConfigResponse, S as SubscriptionPayload, W as WidgetErrorPayload, a as SubscriptionForOfferingResponse, C as CheckoutCartType, b as CheckoutConfirmedPayload, c as CheckoutCancelledPayload, d as CheckoutCartResponse, e as SubscriptionStatusFilter, f as SubscriptionPayloadV2, g as SubscriptionPageResponse, I as InvoiceStatusFilter, h as InvoicePayload, i as InvoicePageResponse, U as UsageMetricPayload, j as UsageThreshold, k as UsageResponse, P as PaymentMethodListResponse, A as ApplyAt, l as UpgradeCancelResultPayload, D as DemoModeBridgeProvider, m as TenantBrandKit, n as InitiateCheckoutRequest, o as InitiateCheckoutResponse, p as InvoiceListFilter, q as InvoicePdfUrlResponse, r as InitiateInvoicePaymentRequest, s as InitiateInvoicePaymentResponse, t as CreateCartRequest, u as UpdateCustomerDetailsRequest, v as InitiateCartPaymentRequest, w as ConfirmCartResponse, R as RequestMagicLinkRequest, x as RequestMagicLinkResponse, V as VerifyMagicLinkResponse, y as SubscriptionListFilter, z as PreviewChangeRequest, B as PreviewChangeResponse, E as UpgradeRequest, F as UpgradeResponse, G as CancelWithFeedbackRequest, J as CancelResponse, K as SetupIntentResponse, L as SessionConfig, M as SessionState } from './types-
|
|
3
|
-
export { N as AforoEventPayload, Q as AforoEventType, X as CancelReason, Y as CheckoutBillingAddress, Z as CheckoutCartErrorResponse, _ as CheckoutCartStatus, $ as CheckoutCustomerDetailsSubmittedPayload, a0 as CheckoutExpiredPayload, a1 as CheckoutFlowPhase, a2 as CheckoutPaymentCompletedPayload, a3 as CheckoutPaymentInitiatedPayload, a4 as CheckoutPaymentProvider, a5 as CheckoutStepChangedPayload, a6 as ConsentState, a7 as FeaturePayload, a8 as HeadlessBrandingPayload, a9 as InvoiceDownloadedPayload, aa as InvoiceExpandedPayload, ab as InvoiceFilterChangedPayload, ac as InvoicePaidPayload, ad as InvoicePayRequestedPayload, ae as InvoiceSearchChangedPayload, af as InvoiceStatus, ag as InvoiceTypeKind, ah as LiveSubscriptionStatus, ai as MagicLinkFailureCode, aj as OfferingSummary, ak as RatePlanPayload, al as RetentionOfferShown, am as RetentionOutcome, an as SubscriptionCancelRequestedPayload, ao as SubscriptionChangeType, ap as SubscriptionClickedPayload, aq as SubscriptionFilterChangedPayload, ar as SubscriptionStatus, as as SubscriptionUpgradeRequestedPayload, at as ThemeTokens, au as UpgradeCancelAbandonedPayload, av as UpgradeCancelCompletedPayload, aw as UpgradeCancelDeflectionOfferAcceptedPayload, ax as UpgradeCancelDeflectionOfferShownPayload, ay as UpgradeCancelPreviewFetchedPayload, az as UpgradeCancelStepChangedPayload, aA as UsageMetricClickedPayload, aB as UsageThresholdReachedPayload, aC as WidgetId, aD as WidgetMountConfig } from './types-
|
|
4
|
-
export { A as AforoEmbed } from './AforoEmbed-
|
|
2
|
+
import { T as ThemeTokenOverrides, O as OfferingPayload, H as HeadlessConfigResponse, S as SubscriptionPayload, W as WidgetErrorPayload, a as SubscriptionForOfferingResponse, C as CheckoutCartType, b as CheckoutConfirmedPayload, c as CheckoutCancelledPayload, d as CheckoutCartResponse, e as SubscriptionStatusFilter, f as SubscriptionPayloadV2, g as SubscriptionPageResponse, I as InvoiceStatusFilter, h as InvoicePayload, i as InvoicePageResponse, U as UsageMetricPayload, j as UsageThreshold, k as UsageResponse, P as PaymentMethodListResponse, A as ApplyAt, l as UpgradeCancelResultPayload, D as DemoModeBridgeProvider, m as TenantBrandKit, n as InitiateCheckoutRequest, o as InitiateCheckoutResponse, p as InvoiceListFilter, q as InvoicePdfUrlResponse, r as InitiateInvoicePaymentRequest, s as InitiateInvoicePaymentResponse, t as CreateCartRequest, u as UpdateCustomerDetailsRequest, v as InitiateCartPaymentRequest, w as ConfirmCartResponse, R as RequestMagicLinkRequest, x as RequestMagicLinkResponse, V as VerifyMagicLinkResponse, y as SubscriptionListFilter, z as PreviewChangeRequest, B as PreviewChangeResponse, E as UpgradeRequest, F as UpgradeResponse, G as CancelWithFeedbackRequest, J as CancelResponse, K as SetupIntentResponse, L as SessionConfig, M as SessionState } from './types-RMTEXoGw.cjs';
|
|
3
|
+
export { N as AforoEventPayload, Q as AforoEventType, X as CancelReason, Y as CheckoutBillingAddress, Z as CheckoutCartErrorResponse, _ as CheckoutCartStatus, $ as CheckoutCustomerDetailsSubmittedPayload, a0 as CheckoutExpiredPayload, a1 as CheckoutFlowPhase, a2 as CheckoutPaymentCompletedPayload, a3 as CheckoutPaymentInitiatedPayload, a4 as CheckoutPaymentProvider, a5 as CheckoutStepChangedPayload, a6 as ConsentState, a7 as FeaturePayload, a8 as HeadlessBrandingPayload, a9 as InvoiceDownloadedPayload, aa as InvoiceExpandedPayload, ab as InvoiceFilterChangedPayload, ac as InvoicePaidPayload, ad as InvoicePayRequestedPayload, ae as InvoiceSearchChangedPayload, af as InvoiceStatus, ag as InvoiceTypeKind, ah as LiveSubscriptionStatus, ai as MagicLinkFailureCode, aj as OfferingSummary, ak as RatePlanPayload, al as RetentionOfferShown, am as RetentionOutcome, an as SubscriptionCancelRequestedPayload, ao as SubscriptionChangeType, ap as SubscriptionClickedPayload, aq as SubscriptionFilterChangedPayload, ar as SubscriptionStatus, as as SubscriptionUpgradeRequestedPayload, at as ThemeTokens, au as UpgradeCancelAbandonedPayload, av as UpgradeCancelCompletedPayload, aw as UpgradeCancelDeflectionOfferAcceptedPayload, ax as UpgradeCancelDeflectionOfferShownPayload, ay as UpgradeCancelPreviewFetchedPayload, az as UpgradeCancelStepChangedPayload, aA as UsageMetricClickedPayload, aB as UsageThresholdReachedPayload, aC as WidgetId, aD as WidgetMountConfig } from './types-RMTEXoGw.cjs';
|
|
4
|
+
export { A as AforoEmbed } from './AforoEmbed-BX2HPXWT.cjs';
|
|
5
5
|
export { EmbedEnvironment, EmbedKey } from '@aforoai/types';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -43,6 +43,8 @@ interface AforoPricingCardProps {
|
|
|
43
43
|
locale?: string;
|
|
44
44
|
/** Max plans to render — operator-set per FR-EMB-02. Default 4. */
|
|
45
45
|
maxPlans?: number;
|
|
46
|
+
/** Card corner radius in px — operator-set per Embed Studio Appearance (0–32px). Default 12. */
|
|
47
|
+
borderRadius?: number;
|
|
46
48
|
/** Whether to show the per-plan features list. Default `true`. */
|
|
47
49
|
showFeatures?: boolean;
|
|
48
50
|
/** Default CTA label when not overridden per-offering. Default `Get Started` (FR-EMB-03). */
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { T as ThemeTokenOverrides, O as OfferingPayload, H as HeadlessConfigResponse, S as SubscriptionPayload, W as WidgetErrorPayload, a as SubscriptionForOfferingResponse, C as CheckoutCartType, b as CheckoutConfirmedPayload, c as CheckoutCancelledPayload, d as CheckoutCartResponse, e as SubscriptionStatusFilter, f as SubscriptionPayloadV2, g as SubscriptionPageResponse, I as InvoiceStatusFilter, h as InvoicePayload, i as InvoicePageResponse, U as UsageMetricPayload, j as UsageThreshold, k as UsageResponse, P as PaymentMethodListResponse, A as ApplyAt, l as UpgradeCancelResultPayload, D as DemoModeBridgeProvider, m as TenantBrandKit, n as InitiateCheckoutRequest, o as InitiateCheckoutResponse, p as InvoiceListFilter, q as InvoicePdfUrlResponse, r as InitiateInvoicePaymentRequest, s as InitiateInvoicePaymentResponse, t as CreateCartRequest, u as UpdateCustomerDetailsRequest, v as InitiateCartPaymentRequest, w as ConfirmCartResponse, R as RequestMagicLinkRequest, x as RequestMagicLinkResponse, V as VerifyMagicLinkResponse, y as SubscriptionListFilter, z as PreviewChangeRequest, B as PreviewChangeResponse, E as UpgradeRequest, F as UpgradeResponse, G as CancelWithFeedbackRequest, J as CancelResponse, K as SetupIntentResponse, L as SessionConfig, M as SessionState } from './types-
|
|
3
|
-
export { N as AforoEventPayload, Q as AforoEventType, X as CancelReason, Y as CheckoutBillingAddress, Z as CheckoutCartErrorResponse, _ as CheckoutCartStatus, $ as CheckoutCustomerDetailsSubmittedPayload, a0 as CheckoutExpiredPayload, a1 as CheckoutFlowPhase, a2 as CheckoutPaymentCompletedPayload, a3 as CheckoutPaymentInitiatedPayload, a4 as CheckoutPaymentProvider, a5 as CheckoutStepChangedPayload, a6 as ConsentState, a7 as FeaturePayload, a8 as HeadlessBrandingPayload, a9 as InvoiceDownloadedPayload, aa as InvoiceExpandedPayload, ab as InvoiceFilterChangedPayload, ac as InvoicePaidPayload, ad as InvoicePayRequestedPayload, ae as InvoiceSearchChangedPayload, af as InvoiceStatus, ag as InvoiceTypeKind, ah as LiveSubscriptionStatus, ai as MagicLinkFailureCode, aj as OfferingSummary, ak as RatePlanPayload, al as RetentionOfferShown, am as RetentionOutcome, an as SubscriptionCancelRequestedPayload, ao as SubscriptionChangeType, ap as SubscriptionClickedPayload, aq as SubscriptionFilterChangedPayload, ar as SubscriptionStatus, as as SubscriptionUpgradeRequestedPayload, at as ThemeTokens, au as UpgradeCancelAbandonedPayload, av as UpgradeCancelCompletedPayload, aw as UpgradeCancelDeflectionOfferAcceptedPayload, ax as UpgradeCancelDeflectionOfferShownPayload, ay as UpgradeCancelPreviewFetchedPayload, az as UpgradeCancelStepChangedPayload, aA as UsageMetricClickedPayload, aB as UsageThresholdReachedPayload, aC as WidgetId, aD as WidgetMountConfig } from './types-
|
|
4
|
-
export { A as AforoEmbed } from './AforoEmbed-
|
|
2
|
+
import { T as ThemeTokenOverrides, O as OfferingPayload, H as HeadlessConfigResponse, S as SubscriptionPayload, W as WidgetErrorPayload, a as SubscriptionForOfferingResponse, C as CheckoutCartType, b as CheckoutConfirmedPayload, c as CheckoutCancelledPayload, d as CheckoutCartResponse, e as SubscriptionStatusFilter, f as SubscriptionPayloadV2, g as SubscriptionPageResponse, I as InvoiceStatusFilter, h as InvoicePayload, i as InvoicePageResponse, U as UsageMetricPayload, j as UsageThreshold, k as UsageResponse, P as PaymentMethodListResponse, A as ApplyAt, l as UpgradeCancelResultPayload, D as DemoModeBridgeProvider, m as TenantBrandKit, n as InitiateCheckoutRequest, o as InitiateCheckoutResponse, p as InvoiceListFilter, q as InvoicePdfUrlResponse, r as InitiateInvoicePaymentRequest, s as InitiateInvoicePaymentResponse, t as CreateCartRequest, u as UpdateCustomerDetailsRequest, v as InitiateCartPaymentRequest, w as ConfirmCartResponse, R as RequestMagicLinkRequest, x as RequestMagicLinkResponse, V as VerifyMagicLinkResponse, y as SubscriptionListFilter, z as PreviewChangeRequest, B as PreviewChangeResponse, E as UpgradeRequest, F as UpgradeResponse, G as CancelWithFeedbackRequest, J as CancelResponse, K as SetupIntentResponse, L as SessionConfig, M as SessionState } from './types-RMTEXoGw.js';
|
|
3
|
+
export { N as AforoEventPayload, Q as AforoEventType, X as CancelReason, Y as CheckoutBillingAddress, Z as CheckoutCartErrorResponse, _ as CheckoutCartStatus, $ as CheckoutCustomerDetailsSubmittedPayload, a0 as CheckoutExpiredPayload, a1 as CheckoutFlowPhase, a2 as CheckoutPaymentCompletedPayload, a3 as CheckoutPaymentInitiatedPayload, a4 as CheckoutPaymentProvider, a5 as CheckoutStepChangedPayload, a6 as ConsentState, a7 as FeaturePayload, a8 as HeadlessBrandingPayload, a9 as InvoiceDownloadedPayload, aa as InvoiceExpandedPayload, ab as InvoiceFilterChangedPayload, ac as InvoicePaidPayload, ad as InvoicePayRequestedPayload, ae as InvoiceSearchChangedPayload, af as InvoiceStatus, ag as InvoiceTypeKind, ah as LiveSubscriptionStatus, ai as MagicLinkFailureCode, aj as OfferingSummary, ak as RatePlanPayload, al as RetentionOfferShown, am as RetentionOutcome, an as SubscriptionCancelRequestedPayload, ao as SubscriptionChangeType, ap as SubscriptionClickedPayload, aq as SubscriptionFilterChangedPayload, ar as SubscriptionStatus, as as SubscriptionUpgradeRequestedPayload, at as ThemeTokens, au as UpgradeCancelAbandonedPayload, av as UpgradeCancelCompletedPayload, aw as UpgradeCancelDeflectionOfferAcceptedPayload, ax as UpgradeCancelDeflectionOfferShownPayload, ay as UpgradeCancelPreviewFetchedPayload, az as UpgradeCancelStepChangedPayload, aA as UsageMetricClickedPayload, aB as UsageThresholdReachedPayload, aC as WidgetId, aD as WidgetMountConfig } from './types-RMTEXoGw.js';
|
|
4
|
+
export { A as AforoEmbed } from './AforoEmbed-PsTY7zh0.js';
|
|
5
5
|
export { EmbedEnvironment, EmbedKey } from '@aforoai/types';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -43,6 +43,8 @@ interface AforoPricingCardProps {
|
|
|
43
43
|
locale?: string;
|
|
44
44
|
/** Max plans to render — operator-set per FR-EMB-02. Default 4. */
|
|
45
45
|
maxPlans?: number;
|
|
46
|
+
/** Card corner radius in px — operator-set per Embed Studio Appearance (0–32px). Default 12. */
|
|
47
|
+
borderRadius?: number;
|
|
46
48
|
/** Whether to show the per-plan features list. Default `true`. */
|
|
47
49
|
showFeatures?: boolean;
|
|
48
50
|
/** Default CTA label when not overridden per-offering. Default `Get Started` (FR-EMB-03). */
|