@aforoai/storefront-widgets 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AforoEmbed-CmqjlYlt.d.ts → AforoEmbed-BkJF1hAN.d.ts} +1 -1
- package/dist/{AforoEmbed-BqQOFsl3.d.cts → AforoEmbed-VYb6_GXB.d.cts} +1 -1
- package/dist/index.cjs +37 -10
- package/dist/index.d.cts +22 -9
- package/dist/index.d.ts +22 -9
- package/dist/index.mjs +37 -10
- package/dist/loader.js +1 -1
- package/dist/loader.mjs +1 -1
- package/dist/sri.json +11 -11
- package/dist/{types-Dm6cp_Cc.d.cts → types-BbQw2_32.d.cts} +1 -1
- package/dist/{types-Dm6cp_Cc.d.ts → types-BbQw2_32.d.ts} +1 -1
- package/dist/vanilla/index.cjs +37 -10
- package/dist/vanilla/index.d.cts +2 -2
- package/dist/vanilla/index.d.ts +2 -2
- package/dist/vanilla/index.mjs +37 -10
- package/dist/vue/index.cjs +37 -10
- package/dist/vue/index.d.cts +1 -1
- package/dist/vue/index.d.ts +1 -1
- package/dist/vue/index.mjs +37 -10
- package/dist/widgets/checkout-flow.js +5 -5
- package/dist/widgets/invoice-list.js +7 -7
- package/dist/widgets/payment-method.js +2 -2
- package/dist/widgets/pricing-card.js +7 -7
- package/dist/widgets/subscribe-button.js +8 -8
- package/dist/widgets/subscription-manager.js +5 -5
- package/dist/widgets/upgrade-cancel.js +6 -6
- package/dist/widgets/usage-meter.js +5 -5
- package/loader.sri.txt +1 -1
- package/package.json +2 -4
|
@@ -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-BbQw2_32.js';
|
|
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-BbQw2_32.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* AforoEmbed — vanilla-JS + script-tag mount API.
|
package/dist/index.cjs
CHANGED
|
@@ -35,7 +35,7 @@ var BridgeClientError = class extends Error {
|
|
|
35
35
|
this.retryable = retryable;
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
|
-
var DEFAULT_BASE = "https://
|
|
38
|
+
var DEFAULT_BASE = "https://storefront.aforo.ai";
|
|
39
39
|
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
40
40
|
function uuidv4() {
|
|
41
41
|
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
@@ -223,10 +223,23 @@ var _BridgeClient = class _BridgeClient {
|
|
|
223
223
|
/**
|
|
224
224
|
* Headless config — the PricingCard widget's primary read path.
|
|
225
225
|
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
226
|
+
* Hits `GET /api/v1/portal/embed/tenant-config/{slug}` — the SAME
|
|
227
|
+
* embed-key-authenticated endpoint {@link getTenantBrandKit} uses, now
|
|
228
|
+
* extended server-side with `offerings` + `embeddableWidget`. This was
|
|
229
|
+
* previously wired to `GET /api/v1/portal/headless/config`, an unrelated
|
|
230
|
+
* T6 Headless-tier endpoint that requires `X-Storefront-Key`/
|
|
231
|
+
* `X-Tenant-Id` auth — headers the embed key flow never sends. Every
|
|
232
|
+
* embed-tier fetch against that URL failed 400 "Missing tenant
|
|
233
|
+
* identification" by construction; this endpoint is scoped to the same
|
|
234
|
+
* `EmbedKeyAuthFilter` gate as the rest of the embed plane, so the
|
|
235
|
+
* `Authorization: Bearer <embed_key>` header `buildHeaders()` already
|
|
236
|
+
* sends is sufficient.
|
|
237
|
+
*
|
|
238
|
+
* The backend response is still a flat record (`tenantSlug,
|
|
239
|
+
* primaryColor, secondaryColor, logoUrl, fontFamily, offerings,
|
|
240
|
+
* embeddableWidget`) — kept flat so `getTenantBrandKit()`'s existing
|
|
241
|
+
* consumers (the ThemeReader cascade) are unaffected. This method nests
|
|
242
|
+
* the branding fields into the shape `HeadlessConfigResponse` expects.
|
|
230
243
|
*
|
|
231
244
|
* Pattern #18 fail-soft — returns `null` on transport failure, 404, or
|
|
232
245
|
* malformed JSON. Widgets fall through to their empty / error state and
|
|
@@ -241,7 +254,7 @@ var _BridgeClient = class _BridgeClient {
|
|
|
241
254
|
}
|
|
242
255
|
const target = slug || this.tenantSlug;
|
|
243
256
|
if (!target) return null;
|
|
244
|
-
const url = `${this.baseUrl}/api/v1/portal/
|
|
257
|
+
const url = `${this.baseUrl}/api/v1/portal/embed/tenant-config/${encodeURIComponent(target)}`;
|
|
245
258
|
let resp;
|
|
246
259
|
try {
|
|
247
260
|
resp = await this.send(url, {
|
|
@@ -254,7 +267,18 @@ var _BridgeClient = class _BridgeClient {
|
|
|
254
267
|
if (!resp.ok) return null;
|
|
255
268
|
try {
|
|
256
269
|
const body = await resp.json();
|
|
257
|
-
|
|
270
|
+
if (!body || typeof body !== "object") return null;
|
|
271
|
+
return {
|
|
272
|
+
tenantSlug: body.tenantSlug,
|
|
273
|
+
branding: {
|
|
274
|
+
primaryColor: body.primaryColor ?? null,
|
|
275
|
+
secondaryColor: body.secondaryColor ?? null,
|
|
276
|
+
logoUrl: body.logoUrl ?? null,
|
|
277
|
+
fontFamily: body.fontFamily ?? null
|
|
278
|
+
},
|
|
279
|
+
offerings: Array.isArray(body.offerings) ? body.offerings : [],
|
|
280
|
+
embeddableWidget: body.embeddableWidget ?? null
|
|
281
|
+
};
|
|
258
282
|
} catch {
|
|
259
283
|
return null;
|
|
260
284
|
}
|
|
@@ -1759,9 +1783,10 @@ var AforoSession = {
|
|
|
1759
1783
|
};
|
|
1760
1784
|
sessions.set(k, entry);
|
|
1761
1785
|
if (config.bridgeToken) {
|
|
1762
|
-
|
|
1763
|
-
|
|
1786
|
+
const exchangePromise = refreshSession(entry);
|
|
1787
|
+
exchangePromise.catch(() => {
|
|
1764
1788
|
});
|
|
1789
|
+
entry.pendingExchange = exchangePromise;
|
|
1765
1790
|
} else if (config.magicLinkMode) {
|
|
1766
1791
|
const tokenInUrl = readMagicTokenFromUrl();
|
|
1767
1792
|
if (tokenInUrl) {
|
|
@@ -1771,6 +1796,8 @@ var AforoSession = {
|
|
|
1771
1796
|
pending = runMagicLinkVerify(entry, tokenInUrl).finally(() => {
|
|
1772
1797
|
pendingMagicLinkVerifies.delete(dedupKey);
|
|
1773
1798
|
});
|
|
1799
|
+
pending.catch(() => {
|
|
1800
|
+
});
|
|
1774
1801
|
pendingMagicLinkVerifies.set(dedupKey, pending);
|
|
1775
1802
|
}
|
|
1776
1803
|
entry.pendingExchange = pending;
|
|
@@ -12148,7 +12175,7 @@ function ResultPanel({
|
|
|
12148
12175
|
}
|
|
12149
12176
|
|
|
12150
12177
|
// src/core/version.ts
|
|
12151
|
-
var VERSION = "1.0.
|
|
12178
|
+
var VERSION = "1.0.4";
|
|
12152
12179
|
|
|
12153
12180
|
// src/core/AforoEmbed.ts
|
|
12154
12181
|
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-BbQw2_32.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-BbQw2_32.cjs';
|
|
4
|
+
export { A as AforoEmbed } from './AforoEmbed-VYb6_GXB.cjs';
|
|
5
5
|
export { EmbedEnvironment, EmbedKey } from '@aforoai/types';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -639,7 +639,7 @@ declare function AforoUpgradeCancel(props: AforoUpgradeCancelProps): React.React
|
|
|
639
639
|
* POST /api/v1/portal/embed/bridge/exchange — bridge JWT → session JWT
|
|
640
640
|
* POST /api/v1/portal/embed/bridge/refresh — session JWT refresh (Prompt 8)
|
|
641
641
|
* POST /api/v1/portal/embed/telemetry — telemetry batch sink
|
|
642
|
-
* GET /api/v1/portal/embed/tenant-config/{slug} — brand kit
|
|
642
|
+
* GET /api/v1/portal/embed/tenant-config/{slug} — brand kit + offerings + embeddableWidget
|
|
643
643
|
* GET /api/v1/portal/embed/health — public liveness
|
|
644
644
|
*
|
|
645
645
|
* Headers:
|
|
@@ -657,7 +657,7 @@ declare function AforoUpgradeCancel(props: AforoUpgradeCancelProps): React.React
|
|
|
657
657
|
|
|
658
658
|
type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
659
659
|
interface BridgeClientOptions {
|
|
660
|
-
/** Default `https://embed.aforo.ai
|
|
660
|
+
/** Default `https://storefront.aforo.ai` (the storefront-service BFF, not the embed.aforo.ai CDN). Override for tests / dev. */
|
|
661
661
|
embedBaseUrl?: string;
|
|
662
662
|
/** Embed key (Bearer token for all embed-key-gated endpoints). */
|
|
663
663
|
embedKey: string;
|
|
@@ -707,10 +707,23 @@ declare class BridgeClient {
|
|
|
707
707
|
/**
|
|
708
708
|
* Headless config — the PricingCard widget's primary read path.
|
|
709
709
|
*
|
|
710
|
-
*
|
|
711
|
-
*
|
|
712
|
-
*
|
|
713
|
-
*
|
|
710
|
+
* Hits `GET /api/v1/portal/embed/tenant-config/{slug}` — the SAME
|
|
711
|
+
* embed-key-authenticated endpoint {@link getTenantBrandKit} uses, now
|
|
712
|
+
* extended server-side with `offerings` + `embeddableWidget`. This was
|
|
713
|
+
* previously wired to `GET /api/v1/portal/headless/config`, an unrelated
|
|
714
|
+
* T6 Headless-tier endpoint that requires `X-Storefront-Key`/
|
|
715
|
+
* `X-Tenant-Id` auth — headers the embed key flow never sends. Every
|
|
716
|
+
* embed-tier fetch against that URL failed 400 "Missing tenant
|
|
717
|
+
* identification" by construction; this endpoint is scoped to the same
|
|
718
|
+
* `EmbedKeyAuthFilter` gate as the rest of the embed plane, so the
|
|
719
|
+
* `Authorization: Bearer <embed_key>` header `buildHeaders()` already
|
|
720
|
+
* sends is sufficient.
|
|
721
|
+
*
|
|
722
|
+
* The backend response is still a flat record (`tenantSlug,
|
|
723
|
+
* primaryColor, secondaryColor, logoUrl, fontFamily, offerings,
|
|
724
|
+
* embeddableWidget`) — kept flat so `getTenantBrandKit()`'s existing
|
|
725
|
+
* consumers (the ThemeReader cascade) are unaffected. This method nests
|
|
726
|
+
* the branding fields into the shape `HeadlessConfigResponse` expects.
|
|
714
727
|
*
|
|
715
728
|
* Pattern #18 fail-soft — returns `null` on transport failure, 404, or
|
|
716
729
|
* malformed JSON. Widgets fall through to their empty / error state and
|
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-BbQw2_32.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-BbQw2_32.js';
|
|
4
|
+
export { A as AforoEmbed } from './AforoEmbed-BkJF1hAN.js';
|
|
5
5
|
export { EmbedEnvironment, EmbedKey } from '@aforoai/types';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -639,7 +639,7 @@ declare function AforoUpgradeCancel(props: AforoUpgradeCancelProps): React.React
|
|
|
639
639
|
* POST /api/v1/portal/embed/bridge/exchange — bridge JWT → session JWT
|
|
640
640
|
* POST /api/v1/portal/embed/bridge/refresh — session JWT refresh (Prompt 8)
|
|
641
641
|
* POST /api/v1/portal/embed/telemetry — telemetry batch sink
|
|
642
|
-
* GET /api/v1/portal/embed/tenant-config/{slug} — brand kit
|
|
642
|
+
* GET /api/v1/portal/embed/tenant-config/{slug} — brand kit + offerings + embeddableWidget
|
|
643
643
|
* GET /api/v1/portal/embed/health — public liveness
|
|
644
644
|
*
|
|
645
645
|
* Headers:
|
|
@@ -657,7 +657,7 @@ declare function AforoUpgradeCancel(props: AforoUpgradeCancelProps): React.React
|
|
|
657
657
|
|
|
658
658
|
type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
659
659
|
interface BridgeClientOptions {
|
|
660
|
-
/** Default `https://embed.aforo.ai
|
|
660
|
+
/** Default `https://storefront.aforo.ai` (the storefront-service BFF, not the embed.aforo.ai CDN). Override for tests / dev. */
|
|
661
661
|
embedBaseUrl?: string;
|
|
662
662
|
/** Embed key (Bearer token for all embed-key-gated endpoints). */
|
|
663
663
|
embedKey: string;
|
|
@@ -707,10 +707,23 @@ declare class BridgeClient {
|
|
|
707
707
|
/**
|
|
708
708
|
* Headless config — the PricingCard widget's primary read path.
|
|
709
709
|
*
|
|
710
|
-
*
|
|
711
|
-
*
|
|
712
|
-
*
|
|
713
|
-
*
|
|
710
|
+
* Hits `GET /api/v1/portal/embed/tenant-config/{slug}` — the SAME
|
|
711
|
+
* embed-key-authenticated endpoint {@link getTenantBrandKit} uses, now
|
|
712
|
+
* extended server-side with `offerings` + `embeddableWidget`. This was
|
|
713
|
+
* previously wired to `GET /api/v1/portal/headless/config`, an unrelated
|
|
714
|
+
* T6 Headless-tier endpoint that requires `X-Storefront-Key`/
|
|
715
|
+
* `X-Tenant-Id` auth — headers the embed key flow never sends. Every
|
|
716
|
+
* embed-tier fetch against that URL failed 400 "Missing tenant
|
|
717
|
+
* identification" by construction; this endpoint is scoped to the same
|
|
718
|
+
* `EmbedKeyAuthFilter` gate as the rest of the embed plane, so the
|
|
719
|
+
* `Authorization: Bearer <embed_key>` header `buildHeaders()` already
|
|
720
|
+
* sends is sufficient.
|
|
721
|
+
*
|
|
722
|
+
* The backend response is still a flat record (`tenantSlug,
|
|
723
|
+
* primaryColor, secondaryColor, logoUrl, fontFamily, offerings,
|
|
724
|
+
* embeddableWidget`) — kept flat so `getTenantBrandKit()`'s existing
|
|
725
|
+
* consumers (the ThemeReader cascade) are unaffected. This method nests
|
|
726
|
+
* the branding fields into the shape `HeadlessConfigResponse` expects.
|
|
714
727
|
*
|
|
715
728
|
* Pattern #18 fail-soft — returns `null` on transport failure, 404, or
|
|
716
729
|
* malformed JSON. Widgets fall through to their empty / error state and
|
package/dist/index.mjs
CHANGED
|
@@ -13,7 +13,7 @@ var BridgeClientError = class extends Error {
|
|
|
13
13
|
this.retryable = retryable;
|
|
14
14
|
}
|
|
15
15
|
};
|
|
16
|
-
var DEFAULT_BASE = "https://
|
|
16
|
+
var DEFAULT_BASE = "https://storefront.aforo.ai";
|
|
17
17
|
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
18
18
|
function uuidv4() {
|
|
19
19
|
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
@@ -201,10 +201,23 @@ var _BridgeClient = class _BridgeClient {
|
|
|
201
201
|
/**
|
|
202
202
|
* Headless config — the PricingCard widget's primary read path.
|
|
203
203
|
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
204
|
+
* Hits `GET /api/v1/portal/embed/tenant-config/{slug}` — the SAME
|
|
205
|
+
* embed-key-authenticated endpoint {@link getTenantBrandKit} uses, now
|
|
206
|
+
* extended server-side with `offerings` + `embeddableWidget`. This was
|
|
207
|
+
* previously wired to `GET /api/v1/portal/headless/config`, an unrelated
|
|
208
|
+
* T6 Headless-tier endpoint that requires `X-Storefront-Key`/
|
|
209
|
+
* `X-Tenant-Id` auth — headers the embed key flow never sends. Every
|
|
210
|
+
* embed-tier fetch against that URL failed 400 "Missing tenant
|
|
211
|
+
* identification" by construction; this endpoint is scoped to the same
|
|
212
|
+
* `EmbedKeyAuthFilter` gate as the rest of the embed plane, so the
|
|
213
|
+
* `Authorization: Bearer <embed_key>` header `buildHeaders()` already
|
|
214
|
+
* sends is sufficient.
|
|
215
|
+
*
|
|
216
|
+
* The backend response is still a flat record (`tenantSlug,
|
|
217
|
+
* primaryColor, secondaryColor, logoUrl, fontFamily, offerings,
|
|
218
|
+
* embeddableWidget`) — kept flat so `getTenantBrandKit()`'s existing
|
|
219
|
+
* consumers (the ThemeReader cascade) are unaffected. This method nests
|
|
220
|
+
* the branding fields into the shape `HeadlessConfigResponse` expects.
|
|
208
221
|
*
|
|
209
222
|
* Pattern #18 fail-soft — returns `null` on transport failure, 404, or
|
|
210
223
|
* malformed JSON. Widgets fall through to their empty / error state and
|
|
@@ -219,7 +232,7 @@ var _BridgeClient = class _BridgeClient {
|
|
|
219
232
|
}
|
|
220
233
|
const target = slug || this.tenantSlug;
|
|
221
234
|
if (!target) return null;
|
|
222
|
-
const url = `${this.baseUrl}/api/v1/portal/
|
|
235
|
+
const url = `${this.baseUrl}/api/v1/portal/embed/tenant-config/${encodeURIComponent(target)}`;
|
|
223
236
|
let resp;
|
|
224
237
|
try {
|
|
225
238
|
resp = await this.send(url, {
|
|
@@ -232,7 +245,18 @@ var _BridgeClient = class _BridgeClient {
|
|
|
232
245
|
if (!resp.ok) return null;
|
|
233
246
|
try {
|
|
234
247
|
const body = await resp.json();
|
|
235
|
-
|
|
248
|
+
if (!body || typeof body !== "object") return null;
|
|
249
|
+
return {
|
|
250
|
+
tenantSlug: body.tenantSlug,
|
|
251
|
+
branding: {
|
|
252
|
+
primaryColor: body.primaryColor ?? null,
|
|
253
|
+
secondaryColor: body.secondaryColor ?? null,
|
|
254
|
+
logoUrl: body.logoUrl ?? null,
|
|
255
|
+
fontFamily: body.fontFamily ?? null
|
|
256
|
+
},
|
|
257
|
+
offerings: Array.isArray(body.offerings) ? body.offerings : [],
|
|
258
|
+
embeddableWidget: body.embeddableWidget ?? null
|
|
259
|
+
};
|
|
236
260
|
} catch {
|
|
237
261
|
return null;
|
|
238
262
|
}
|
|
@@ -1737,9 +1761,10 @@ var AforoSession = {
|
|
|
1737
1761
|
};
|
|
1738
1762
|
sessions.set(k, entry);
|
|
1739
1763
|
if (config.bridgeToken) {
|
|
1740
|
-
|
|
1741
|
-
|
|
1764
|
+
const exchangePromise = refreshSession(entry);
|
|
1765
|
+
exchangePromise.catch(() => {
|
|
1742
1766
|
});
|
|
1767
|
+
entry.pendingExchange = exchangePromise;
|
|
1743
1768
|
} else if (config.magicLinkMode) {
|
|
1744
1769
|
const tokenInUrl = readMagicTokenFromUrl();
|
|
1745
1770
|
if (tokenInUrl) {
|
|
@@ -1749,6 +1774,8 @@ var AforoSession = {
|
|
|
1749
1774
|
pending = runMagicLinkVerify(entry, tokenInUrl).finally(() => {
|
|
1750
1775
|
pendingMagicLinkVerifies.delete(dedupKey);
|
|
1751
1776
|
});
|
|
1777
|
+
pending.catch(() => {
|
|
1778
|
+
});
|
|
1752
1779
|
pendingMagicLinkVerifies.set(dedupKey, pending);
|
|
1753
1780
|
}
|
|
1754
1781
|
entry.pendingExchange = pending;
|
|
@@ -12126,7 +12153,7 @@ function ResultPanel({
|
|
|
12126
12153
|
}
|
|
12127
12154
|
|
|
12128
12155
|
// src/core/version.ts
|
|
12129
|
-
var VERSION = "1.0.
|
|
12156
|
+
var VERSION = "1.0.4";
|
|
12130
12157
|
|
|
12131
12158
|
// src/core/AforoEmbed.ts
|
|
12132
12159
|
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.
|
|
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};
|
|
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.
|
|
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};
|
|
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.
|
|
3
|
-
"generatedAt": "2026-08-
|
|
2
|
+
"version": "1.0.4",
|
|
3
|
+
"generatedAt": "2026-08-12T07:41:16.132Z",
|
|
4
4
|
"bundles": {
|
|
5
|
-
"loader.js": "sha384-
|
|
6
|
-
"widgets/checkout-flow.js": "sha384-
|
|
7
|
-
"widgets/invoice-list.js": "sha384-
|
|
8
|
-
"widgets/payment-method.js": "sha384-
|
|
9
|
-
"widgets/pricing-card.js": "sha384-
|
|
10
|
-
"widgets/subscribe-button.js": "sha384-
|
|
11
|
-
"widgets/subscription-manager.js": "sha384-
|
|
12
|
-
"widgets/upgrade-cancel.js": "sha384-
|
|
13
|
-
"widgets/usage-meter.js": "sha384-
|
|
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/"
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -61,7 +61,7 @@ interface SessionConfig {
|
|
|
61
61
|
* naturally only ever set one).
|
|
62
62
|
*/
|
|
63
63
|
magicLinkMode?: boolean;
|
|
64
|
-
/** Override the default `https://
|
|
64
|
+
/** Override the default `https://storefront.aforo.ai` origin. Tests + dev. */
|
|
65
65
|
apiBaseUrl?: string;
|
|
66
66
|
/** Override embed-key authenticated endpoint base. */
|
|
67
67
|
embedBaseUrl?: string;
|
|
@@ -61,7 +61,7 @@ interface SessionConfig {
|
|
|
61
61
|
* naturally only ever set one).
|
|
62
62
|
*/
|
|
63
63
|
magicLinkMode?: boolean;
|
|
64
|
-
/** Override the default `https://
|
|
64
|
+
/** Override the default `https://storefront.aforo.ai` origin. Tests + dev. */
|
|
65
65
|
apiBaseUrl?: string;
|
|
66
66
|
/** Override embed-key authenticated endpoint base. */
|
|
67
67
|
embedBaseUrl?: string;
|
package/dist/vanilla/index.cjs
CHANGED
|
@@ -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.
|
|
30
|
+
var VERSION = "1.0.4";
|
|
31
31
|
|
|
32
32
|
// src/core/AforoEmbed.ts
|
|
33
33
|
var mountedElements = /* @__PURE__ */ new WeakMap();
|
|
@@ -411,7 +411,7 @@ var BridgeClientError = class extends Error {
|
|
|
411
411
|
this.retryable = retryable;
|
|
412
412
|
}
|
|
413
413
|
};
|
|
414
|
-
var DEFAULT_BASE = "https://
|
|
414
|
+
var DEFAULT_BASE = "https://storefront.aforo.ai";
|
|
415
415
|
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
416
416
|
function uuidv4() {
|
|
417
417
|
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
@@ -599,10 +599,23 @@ var _BridgeClient = class _BridgeClient {
|
|
|
599
599
|
/**
|
|
600
600
|
* Headless config — the PricingCard widget's primary read path.
|
|
601
601
|
*
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
*
|
|
602
|
+
* Hits `GET /api/v1/portal/embed/tenant-config/{slug}` — the SAME
|
|
603
|
+
* embed-key-authenticated endpoint {@link getTenantBrandKit} uses, now
|
|
604
|
+
* extended server-side with `offerings` + `embeddableWidget`. This was
|
|
605
|
+
* previously wired to `GET /api/v1/portal/headless/config`, an unrelated
|
|
606
|
+
* T6 Headless-tier endpoint that requires `X-Storefront-Key`/
|
|
607
|
+
* `X-Tenant-Id` auth — headers the embed key flow never sends. Every
|
|
608
|
+
* embed-tier fetch against that URL failed 400 "Missing tenant
|
|
609
|
+
* identification" by construction; this endpoint is scoped to the same
|
|
610
|
+
* `EmbedKeyAuthFilter` gate as the rest of the embed plane, so the
|
|
611
|
+
* `Authorization: Bearer <embed_key>` header `buildHeaders()` already
|
|
612
|
+
* sends is sufficient.
|
|
613
|
+
*
|
|
614
|
+
* The backend response is still a flat record (`tenantSlug,
|
|
615
|
+
* primaryColor, secondaryColor, logoUrl, fontFamily, offerings,
|
|
616
|
+
* embeddableWidget`) — kept flat so `getTenantBrandKit()`'s existing
|
|
617
|
+
* consumers (the ThemeReader cascade) are unaffected. This method nests
|
|
618
|
+
* the branding fields into the shape `HeadlessConfigResponse` expects.
|
|
606
619
|
*
|
|
607
620
|
* Pattern #18 fail-soft — returns `null` on transport failure, 404, or
|
|
608
621
|
* malformed JSON. Widgets fall through to their empty / error state and
|
|
@@ -617,7 +630,7 @@ var _BridgeClient = class _BridgeClient {
|
|
|
617
630
|
}
|
|
618
631
|
const target = slug || this.tenantSlug;
|
|
619
632
|
if (!target) return null;
|
|
620
|
-
const url = `${this.baseUrl}/api/v1/portal/
|
|
633
|
+
const url = `${this.baseUrl}/api/v1/portal/embed/tenant-config/${encodeURIComponent(target)}`;
|
|
621
634
|
let resp;
|
|
622
635
|
try {
|
|
623
636
|
resp = await this.send(url, {
|
|
@@ -630,7 +643,18 @@ var _BridgeClient = class _BridgeClient {
|
|
|
630
643
|
if (!resp.ok) return null;
|
|
631
644
|
try {
|
|
632
645
|
const body = await resp.json();
|
|
633
|
-
|
|
646
|
+
if (!body || typeof body !== "object") return null;
|
|
647
|
+
return {
|
|
648
|
+
tenantSlug: body.tenantSlug,
|
|
649
|
+
branding: {
|
|
650
|
+
primaryColor: body.primaryColor ?? null,
|
|
651
|
+
secondaryColor: body.secondaryColor ?? null,
|
|
652
|
+
logoUrl: body.logoUrl ?? null,
|
|
653
|
+
fontFamily: body.fontFamily ?? null
|
|
654
|
+
},
|
|
655
|
+
offerings: Array.isArray(body.offerings) ? body.offerings : [],
|
|
656
|
+
embeddableWidget: body.embeddableWidget ?? null
|
|
657
|
+
};
|
|
634
658
|
} catch {
|
|
635
659
|
return null;
|
|
636
660
|
}
|
|
@@ -2135,9 +2159,10 @@ var AforoSession = {
|
|
|
2135
2159
|
};
|
|
2136
2160
|
sessions.set(k, entry);
|
|
2137
2161
|
if (config.bridgeToken) {
|
|
2138
|
-
|
|
2139
|
-
|
|
2162
|
+
const exchangePromise = refreshSession(entry);
|
|
2163
|
+
exchangePromise.catch(() => {
|
|
2140
2164
|
});
|
|
2165
|
+
entry.pendingExchange = exchangePromise;
|
|
2141
2166
|
} else if (config.magicLinkMode) {
|
|
2142
2167
|
const tokenInUrl = readMagicTokenFromUrl();
|
|
2143
2168
|
if (tokenInUrl) {
|
|
@@ -2147,6 +2172,8 @@ var AforoSession = {
|
|
|
2147
2172
|
pending = runMagicLinkVerify(entry, tokenInUrl).finally(() => {
|
|
2148
2173
|
pendingMagicLinkVerifies.delete(dedupKey);
|
|
2149
2174
|
});
|
|
2175
|
+
pending.catch(() => {
|
|
2176
|
+
});
|
|
2150
2177
|
pendingMagicLinkVerifies.set(dedupKey, pending);
|
|
2151
2178
|
}
|
|
2152
2179
|
entry.pendingExchange = pending;
|
package/dist/vanilla/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { A as AforoEmbed } from '../AforoEmbed-
|
|
2
|
-
import { aD as WidgetMountConfig } from '../types-
|
|
1
|
+
export { A as AforoEmbed } from '../AforoEmbed-VYb6_GXB.cjs';
|
|
2
|
+
import { aD as WidgetMountConfig } from '../types-BbQw2_32.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @aforoai/storefront-widgets/vanilla — vanilla-JS adapter (FR-TIER-3,
|
package/dist/vanilla/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { A as AforoEmbed } from '../AforoEmbed-
|
|
2
|
-
import { aD as WidgetMountConfig } from '../types-
|
|
1
|
+
export { A as AforoEmbed } from '../AforoEmbed-BkJF1hAN.js';
|
|
2
|
+
import { aD as WidgetMountConfig } from '../types-BbQw2_32.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @aforoai/storefront-widgets/vanilla — vanilla-JS adapter (FR-TIER-3,
|