@xapps-platform/marketplace-ui 0.1.5 → 0.1.7

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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/MarketplaceContext.tsx
2
- import { createContext as createContext2, useContext as useContext2 } from "react";
2
+ import { createContext as createContext2, useContext as useContext2, useEffect } from "react";
3
3
 
4
4
  // ../platform-i18n/src/index.tsx
5
5
  import { createContext, useContext, useMemo } from "react";
@@ -235,11 +235,13 @@ var MARKETPLACE_CATALOGS = {
235
235
  "activity.show_details": "Show details",
236
236
  "activity.hide_details": "Hide details",
237
237
  "activity.response_title": "Response",
238
+ "activity.payment_pending": "Payment Pending",
238
239
  "activity.payment_required": "Payment Required",
239
240
  "activity.complete_payment": "Complete Payment",
240
241
  "activity.confirm_payment": "Confirm Payment",
241
242
  "activity.confirming_payment": "Confirming...",
242
243
  "activity.refresh_status": "Refresh Status",
244
+ "activity.waiting_for_payment": "Waiting for payment confirmation\u2026",
243
245
  "activity.waiting_for_response": "Waiting for response\u2026",
244
246
  "activity.execution_timeline": "Execution Timeline",
245
247
  "activity.artifacts_title": "Artifacts",
@@ -259,6 +261,8 @@ var MARKETPLACE_CATALOGS = {
259
261
  "activity.guard_badge": "guard: {value}",
260
262
  "activity.trigger_badge": "trigger: {value}",
261
263
  "activity.outcome_badge": "outcome: {value}",
264
+ "activity.current_access_badge": "access: {value}",
265
+ "activity.current_access_detail": "Current access: {value}",
262
266
  "activity.reason_detail": "reason={value}",
263
267
  "activity.guard_action_upgrade_subscription": "Upgrade subscription{suffix}",
264
268
  "activity.guard_action_complete_payment": "Complete payment{suffix}",
@@ -315,6 +319,23 @@ var MARKETPLACE_CATALOGS = {
315
319
  "xapp.screenshots_title": "Screenshots",
316
320
  "xapp.screenshot_alt": "Screenshot {index}",
317
321
  "xapp.usage_credits_title": "Usage Credits",
322
+ "xapp.current_access_title": "Current Access",
323
+ "xapp.current_plan_label": "Current plan",
324
+ "xapp.access_state_label": "Access state",
325
+ "xapp.access_state_available": "available",
326
+ "xapp.subscription_status_label": "Subscription status",
327
+ "xapp.subscription_coverage_label": "Coverage",
328
+ "xapp.subscription_reason_label": "Status reason",
329
+ "xapp.subscription_overdue_since_label": "Overdue since",
330
+ "xapp.subscription_expiry_boundary_label": "Expiry boundary",
331
+ "xapp.subscription_coverage_active": "Still covered",
332
+ "xapp.subscription_coverage_inactive": "Not covered",
333
+ "xapp.subscription_reason_grace_covered_past_due": "Coverage remains during grace period",
334
+ "xapp.subscription_reason_past_due_after_period_end": "Current period ended without successful renewal",
335
+ "xapp.subscription_reason_expired_after_boundary": "Expiry boundary reached",
336
+ "xapp.renews_at_label": "Renews at",
337
+ "xapp.expires_at_label": "Expires at",
338
+ "xapp.credits_remaining_label": "Credits remaining",
318
339
  "xapp.available_label": "Available",
319
340
  "xapp.ready_to_use": "{count} ready to use",
320
341
  "xapp.source_label": "Source",
@@ -490,11 +511,13 @@ var MARKETPLACE_CATALOGS = {
490
511
  "activity.show_details": "Arat\u0103 detalii",
491
512
  "activity.hide_details": "Ascunde detalii",
492
513
  "activity.response_title": "R\u0103spuns",
514
+ "activity.payment_pending": "Plat\u0103 \xEEn a\u0219teptare",
493
515
  "activity.payment_required": "Plata este necesar\u0103",
494
516
  "activity.complete_payment": "Finalizeaz\u0103 plata",
495
517
  "activity.confirm_payment": "Confirm\u0103 plata",
496
518
  "activity.confirming_payment": "Se confirm\u0103...",
497
519
  "activity.refresh_status": "Re\xEEmprosp\u0103teaz\u0103 starea",
520
+ "activity.waiting_for_payment": "\xCEn a\u0219teptarea confirm\u0103rii pl\u0103\u021Bii\u2026",
498
521
  "activity.waiting_for_response": "\xCEn a\u0219teptarea r\u0103spunsului\u2026",
499
522
  "activity.execution_timeline": "Cronologia execu\u021Biei",
500
523
  "activity.artifacts_title": "Artefacte",
@@ -514,6 +537,8 @@ var MARKETPLACE_CATALOGS = {
514
537
  "activity.guard_badge": "gard\u0103: {value}",
515
538
  "activity.trigger_badge": "declan\u0219ator: {value}",
516
539
  "activity.outcome_badge": "rezultat: {value}",
540
+ "activity.current_access_badge": "acces: {value}",
541
+ "activity.current_access_detail": "Acces curent: {value}",
517
542
  "activity.reason_detail": "motiv={value}",
518
543
  "activity.guard_action_upgrade_subscription": "Actualizeaz\u0103 abonamentul{suffix}",
519
544
  "activity.guard_action_complete_payment": "Finalizeaz\u0103 plata{suffix}",
@@ -570,6 +595,23 @@ var MARKETPLACE_CATALOGS = {
570
595
  "xapp.screenshots_title": "Capturi de ecran",
571
596
  "xapp.screenshot_alt": "Captur\u0103 de ecran {index}",
572
597
  "xapp.usage_credits_title": "Credite de utilizare",
598
+ "xapp.current_access_title": "Acces curent",
599
+ "xapp.current_plan_label": "Plan curent",
600
+ "xapp.access_state_label": "Stare acces",
601
+ "xapp.access_state_available": "disponibil",
602
+ "xapp.subscription_status_label": "Stare abonament",
603
+ "xapp.subscription_coverage_label": "Acoperire",
604
+ "xapp.subscription_reason_label": "Motiv stare",
605
+ "xapp.subscription_overdue_since_label": "\xCEn \xEEnt\xE2rziere din",
606
+ "xapp.subscription_expiry_boundary_label": "Limit\u0103 expirare",
607
+ "xapp.subscription_coverage_active": "\xCEnc\u0103 activ",
608
+ "xapp.subscription_coverage_inactive": "Inactiv",
609
+ "xapp.subscription_reason_grace_covered_past_due": "Accesul r\u0103m\xE2ne activ \xEEn perioada de gra\u021Bie",
610
+ "xapp.subscription_reason_past_due_after_period_end": "Perioada curent\u0103 s-a \xEEncheiat f\u0103r\u0103 re\xEEnnoire reu\u0219it\u0103",
611
+ "xapp.subscription_reason_expired_after_boundary": "A fost atins\u0103 limita de expirare",
612
+ "xapp.renews_at_label": "Se re\xEEnnoie\u0219te la",
613
+ "xapp.expires_at_label": "Expir\u0103 la",
614
+ "xapp.credits_remaining_label": "Credite r\u0103mase",
573
615
  "xapp.available_label": "Disponibile",
574
616
  "xapp.ready_to_use": "{count} gata de utilizare",
575
617
  "xapp.source_label": "Surs\u0103",
@@ -662,10 +704,73 @@ function resolveMarketplaceText(value, locale) {
662
704
  }
663
705
 
664
706
  // src/MarketplaceContext.tsx
665
- import { jsx as jsx3 } from "react/jsx-runtime";
707
+ import { Fragment, jsx as jsx3 } from "react/jsx-runtime";
666
708
  var Ctx = createContext2(null);
709
+ function applyMarketplaceThemeToDocument(theme) {
710
+ if (!theme || typeof document === "undefined") return;
711
+ const root = document.documentElement;
712
+ const map = [
713
+ ["primary", ["--cx-primary", "--mx-primary"]],
714
+ ["primaryDark", ["--cx-primary-dark", "--mx-primary-hover"]],
715
+ ["bg", ["--cx-bg", "--mx-bg"]],
716
+ ["bgSubtle", ["--cx-bg-subtle", "--mx-bg-subtle"]],
717
+ ["card", ["--cx-card", "--mx-card-bg"]],
718
+ ["border", ["--cx-border", "--mx-border"]],
719
+ ["text", ["--cx-text", "--mx-text-main"]],
720
+ ["muted", ["--cx-muted", "--mx-text-muted"]],
721
+ ["shadowSm", ["--cx-shadow-sm", "--mx-shadow-sm"]],
722
+ ["shadow", ["--cx-shadow", "--mx-shadow"]],
723
+ ["shadowLg", ["--cx-shadow-lg", "--mx-shadow-lg"]],
724
+ ["radiusSm", ["--cx-radius-sm", "--mx-radius-sm"]],
725
+ ["radiusMd", ["--cx-radius-md", "--mx-radius-md"]],
726
+ ["radius", ["--cx-radius", "--cx-radius-lg", "--mx-radius-md", "--mx-radius-lg"]],
727
+ ["radiusLg", ["--cx-radius-lg", "--mx-radius-lg"]],
728
+ ["fontFamily", ["--mx-font-family"]]
729
+ ];
730
+ for (const [key, cssVars] of map) {
731
+ const rawValue = theme[key];
732
+ const value = typeof rawValue === "string" ? rawValue.trim() : "";
733
+ if (!value) continue;
734
+ for (const cssVar of cssVars) root.style.setProperty(cssVar, value);
735
+ }
736
+ if (typeof theme.radius === "string" && theme.radius.trim() && !(typeof theme.radiusSm === "string" && theme.radiusSm.trim())) {
737
+ root.style.setProperty("--cx-radius-sm", theme.radius.trim());
738
+ root.style.setProperty("--mx-radius-sm", theme.radius.trim());
739
+ }
740
+ if (typeof theme.bg === "string" && theme.bg.trim() && !theme.bgSubtle) {
741
+ root.style.setProperty("--cx-bg-subtle", theme.bg.trim());
742
+ root.style.setProperty("--mx-bg-subtle", theme.bg.trim());
743
+ }
744
+ const directTokens = theme.tokens && typeof theme.tokens === "object" && !Array.isArray(theme.tokens) ? theme.tokens : null;
745
+ if (directTokens) {
746
+ for (const [cssVar, rawValue] of Object.entries(directTokens)) {
747
+ const value = typeof rawValue === "string" ? rawValue.trim() : "";
748
+ if (!value) continue;
749
+ if (!cssVar.startsWith("--mx-") && !cssVar.startsWith("--cx-") && !cssVar.startsWith("--xapps-")) {
750
+ continue;
751
+ }
752
+ root.style.setProperty(cssVar, value);
753
+ }
754
+ }
755
+ const themeMode = typeof theme.mode === "string" ? theme.mode.trim().toLowerCase() : typeof theme.themeMode === "string" ? theme.themeMode.trim().toLowerCase() : "";
756
+ if (themeMode === "dark" || themeMode === "light") {
757
+ root.dataset.xappsThemeMode = themeMode;
758
+ }
759
+ }
760
+ function MarketplaceRuntimeBridge(props) {
761
+ useEffect(() => {
762
+ const locale = String(props.env?.locale || props.host.locale || "").trim();
763
+ if (locale && typeof document !== "undefined") {
764
+ document.documentElement.lang = locale;
765
+ }
766
+ }, [props.env?.locale, props.host.locale]);
767
+ useEffect(() => {
768
+ applyMarketplaceThemeToDocument(props.host.theme || null);
769
+ }, [props.host.theme]);
770
+ return /* @__PURE__ */ jsx3(Fragment, { children: props.children });
771
+ }
667
772
  function MarketplaceProvider(props) {
668
- return /* @__PURE__ */ jsx3(MarketplaceI18nProvider, { locale: props.env?.locale, children: /* @__PURE__ */ jsx3(Ctx.Provider, { value: { client: props.client, host: props.host, env: props.env }, children: props.children }) });
773
+ return /* @__PURE__ */ jsx3(MarketplaceI18nProvider, { locale: props.env?.locale, children: /* @__PURE__ */ jsx3(MarketplaceRuntimeBridge, { host: props.host, env: props.env, children: /* @__PURE__ */ jsx3(Ctx.Provider, { value: { client: props.client, host: props.host, env: props.env }, children: props.children }) }) });
669
774
  }
670
775
  function useMarketplace() {
671
776
  const v = useContext2(Ctx);
@@ -677,11 +782,11 @@ function useMarketplace() {
677
782
  import { Route, Routes } from "react-router-dom";
678
783
 
679
784
  // src/pages/CatalogPage.tsx
680
- import { useEffect as useEffect2, useMemo as useMemo2, useState } from "react";
785
+ import { useEffect as useEffect3, useMemo as useMemo2, useState } from "react";
681
786
  import { Link as Link2, useLocation, useNavigate } from "react-router-dom";
682
787
 
683
788
  // src/components/ConfirmActionModal.tsx
684
- import { useEffect } from "react";
789
+ import { useEffect as useEffect2 } from "react";
685
790
  import { jsx as jsx4, jsxs } from "react/jsx-runtime";
686
791
  function ConfirmActionModal(props) {
687
792
  const { t } = useMarketplaceI18n();
@@ -694,7 +799,7 @@ function ConfirmActionModal(props) {
694
799
  onConfirm,
695
800
  onCancel
696
801
  } = props;
697
- useEffect(() => {
802
+ useEffect2(() => {
698
803
  if (!open || typeof window === "undefined") return;
699
804
  const handleKeyDown = (event) => {
700
805
  if (event.key === "Escape") {
@@ -859,7 +964,7 @@ function normalizeExpandStage(value, expanded) {
859
964
  }
860
965
 
861
966
  // src/pages/CatalogPage.tsx
862
- import { Fragment, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
967
+ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
863
968
  function useQueryToken() {
864
969
  const loc = useLocation();
865
970
  const qs = new URLSearchParams(loc.search);
@@ -961,22 +1066,22 @@ function CatalogPage() {
961
1066
  setBusy(false);
962
1067
  }
963
1068
  }
964
- useEffect2(() => {
1069
+ useEffect3(() => {
965
1070
  void refresh();
966
1071
  host.refreshInstallations();
967
1072
  }, []);
968
- useEffect2(() => {
1073
+ useEffect3(() => {
969
1074
  const stored = readStoredCatalogFilters(storageKey);
970
1075
  setInstalledOnly(Boolean(stored?.addedOnly));
971
1076
  setSelectedTag(typeof stored?.selectedTag === "string" ? stored.selectedTag : defaultTag);
972
1077
  }, [defaultTag, storageKey]);
973
- useEffect2(() => {
1078
+ useEffect3(() => {
974
1079
  const restrictedTags = env?.tags ?? [];
975
1080
  if (selectedTag && restrictedTags.length > 0 && !restrictedTags.includes(selectedTag)) {
976
1081
  setSelectedTag(defaultTag);
977
1082
  }
978
1083
  }, [defaultTag, env?.tags, selectedTag]);
979
- useEffect2(() => {
1084
+ useEffect3(() => {
980
1085
  writeStoredCatalogFilters(storageKey, {
981
1086
  addedOnly: installedOnly,
982
1087
  selectedTag: selectedTag || ""
@@ -1115,7 +1220,7 @@ function CatalogPage() {
1115
1220
  /* @__PURE__ */ jsx6("div", { className: "mx-skeleton-line mx-skeleton-line-full" }),
1116
1221
  /* @__PURE__ */ jsx6("div", { className: "mx-skeleton-line mx-skeleton-line-short" })
1117
1222
  ] })
1118
- ] }, i)) }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
1223
+ ] }, i)) }) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
1119
1224
  !busy && /* @__PURE__ */ jsx6("div", { className: "mx-results-bar", children: /* @__PURE__ */ jsx6("div", { className: "mx-results-count", children: filtered.length === items.length ? t(
1120
1225
  "catalog.results_all",
1121
1226
  {
@@ -1280,7 +1385,7 @@ function CatalogPage() {
1280
1385
  }
1281
1386
 
1282
1387
  // src/pages/InvoicesPage.tsx
1283
- import { useEffect as useEffect3, useMemo as useMemo3, useState as useState2 } from "react";
1388
+ import { useEffect as useEffect4, useMemo as useMemo3, useState as useState2 } from "react";
1284
1389
  import { Link as Link4, useLocation as useLocation2 } from "react-router-dom";
1285
1390
 
1286
1391
  // src/components/MarketplaceActivityTabs.tsx
@@ -1333,7 +1438,7 @@ function MarketplaceActivityTabs(props) {
1333
1438
  }
1334
1439
 
1335
1440
  // src/pages/InvoicesPage.tsx
1336
- import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
1441
+ import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
1337
1442
  function useQueryToken2() {
1338
1443
  const loc = useLocation2();
1339
1444
  const qs = new URLSearchParams(loc.search);
@@ -1408,7 +1513,7 @@ function InvoicesPage() {
1408
1513
  setBusy(false);
1409
1514
  }
1410
1515
  }
1411
- useEffect3(() => {
1516
+ useEffect4(() => {
1412
1517
  void refresh(pageParam);
1413
1518
  host.notifyNavigation?.({
1414
1519
  path: typeof window !== "undefined" ? window.location.pathname : "",
@@ -1416,7 +1521,7 @@ function InvoicesPage() {
1416
1521
  params: { xappId: xappIdFilter || null }
1417
1522
  });
1418
1523
  }, [installationIdFilter, pageParam, paymentSessionIdFilter, xappIdFilter]);
1419
- useEffect3(() => {
1524
+ useEffect4(() => {
1420
1525
  if (!focusedInvoiceId || !client.getMyInvoiceHistory) {
1421
1526
  setFocusedInvoice(null);
1422
1527
  setFocusedHistory([]);
@@ -1445,7 +1550,7 @@ function InvoicesPage() {
1445
1550
  cancelled = true;
1446
1551
  };
1447
1552
  }, [client, focusedInvoiceId]);
1448
- useEffect3(() => {
1553
+ useEffect4(() => {
1449
1554
  if (!xappIdFilter) {
1450
1555
  setXappTitle("");
1451
1556
  return;
@@ -1493,7 +1598,7 @@ function InvoicesPage() {
1493
1598
  return /* @__PURE__ */ jsxs4("div", { className: `mx-catalog-container ${isEmbedded ? "is-embedded" : ""}`, children: [
1494
1599
  /* @__PURE__ */ jsxs4("div", { className: "mx-breadcrumb", children: [
1495
1600
  /* @__PURE__ */ jsx8(Link4, { to: isEmbedded ? "/" : "/marketplace", children: t("common.marketplace", void 0, "Marketplace") }),
1496
- xappLink && /* @__PURE__ */ jsxs4(Fragment2, { children: [
1601
+ xappLink && /* @__PURE__ */ jsxs4(Fragment3, { children: [
1497
1602
  /* @__PURE__ */ jsx8("span", { className: "mx-breadcrumb-sep", children: "/" }),
1498
1603
  /* @__PURE__ */ jsx8(Link4, { to: xappLink, children: xappTitle || xappIdFilter })
1499
1604
  ] }),
@@ -1571,7 +1676,7 @@ function InvoicesPage() {
1571
1676
  ] }),
1572
1677
  /* @__PURE__ */ jsx8(Link4, { to: listHref, className: "mx-btn mx-btn-ghost", children: t("activity.back_to_invoice_list", void 0, "Back to invoice list") })
1573
1678
  ] }),
1574
- focusedError ? /* @__PURE__ */ jsx8("div", { className: "mx-alert mx-alert-error mx-alert-panel", children: focusedError }) : focusedInvoice ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
1679
+ focusedError ? /* @__PURE__ */ jsx8("div", { className: "mx-alert mx-alert-error mx-alert-panel", children: focusedError }) : focusedInvoice ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
1575
1680
  /* @__PURE__ */ jsxs4("div", { className: "mx-record-grid", children: [
1576
1681
  /* @__PURE__ */ jsxs4("div", { className: "mx-record-field", children: [
1577
1682
  /* @__PURE__ */ jsx8("div", { className: "mx-record-label", children: t("common.status", void 0, "Status") }),
@@ -1766,9 +1871,9 @@ function InvoicesPage() {
1766
1871
  }
1767
1872
 
1768
1873
  // src/pages/NotificationsPage.tsx
1769
- import { useEffect as useEffect4, useMemo as useMemo4, useState as useState3 } from "react";
1874
+ import { useEffect as useEffect5, useMemo as useMemo4, useState as useState3 } from "react";
1770
1875
  import { Link as Link5, useLocation as useLocation3 } from "react-router-dom";
1771
- import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
1876
+ import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
1772
1877
  function useQueryToken3() {
1773
1878
  const loc = useLocation3();
1774
1879
  const qs = new URLSearchParams(loc.search);
@@ -1882,7 +1987,7 @@ function NotificationsPage() {
1882
1987
  setError(readFirstString(asRecord(e).message) || String(e));
1883
1988
  }
1884
1989
  }
1885
- useEffect4(() => {
1990
+ useEffect5(() => {
1886
1991
  void refresh();
1887
1992
  host.notifyNavigation?.({
1888
1993
  path: typeof window !== "undefined" ? window.location.pathname : "",
@@ -1890,7 +1995,7 @@ function NotificationsPage() {
1890
1995
  params: { xappId: xappIdFilter || null }
1891
1996
  });
1892
1997
  }, [focusedNotificationId, installationIdFilter, xappIdFilter]);
1893
- useEffect4(() => {
1998
+ useEffect5(() => {
1894
1999
  if (!focusedNotificationId) {
1895
2000
  setFocusedNotification(null);
1896
2001
  setFocusedError(null);
@@ -1919,7 +2024,7 @@ function NotificationsPage() {
1919
2024
  cancelled = true;
1920
2025
  };
1921
2026
  }, [client, focusedNotificationId, installationIdFilter, xappIdFilter]);
1922
- useEffect4(() => {
2027
+ useEffect5(() => {
1923
2028
  if (!xappIdFilter) {
1924
2029
  setXappTitle("");
1925
2030
  return;
@@ -1966,7 +2071,7 @@ function NotificationsPage() {
1966
2071
  return /* @__PURE__ */ jsxs5("div", { className: `mx-catalog-container ${isEmbedded ? "is-embedded" : ""}`, children: [
1967
2072
  /* @__PURE__ */ jsxs5("div", { className: "mx-breadcrumb", children: [
1968
2073
  /* @__PURE__ */ jsx9(Link5, { to: isEmbedded ? "/" : "/marketplace", children: t("common.marketplace", void 0, "Marketplace") }),
1969
- xappLink && /* @__PURE__ */ jsxs5(Fragment3, { children: [
2074
+ xappLink && /* @__PURE__ */ jsxs5(Fragment4, { children: [
1970
2075
  /* @__PURE__ */ jsx9("span", { className: "mx-breadcrumb-sep", children: "/" }),
1971
2076
  /* @__PURE__ */ jsx9(Link5, { to: xappLink, children: xappTitle || xappIdFilter })
1972
2077
  ] }),
@@ -2189,9 +2294,9 @@ function NotificationsPage() {
2189
2294
  }
2190
2295
 
2191
2296
  // src/pages/PaymentsPage.tsx
2192
- import { useEffect as useEffect5, useMemo as useMemo5, useState as useState4 } from "react";
2297
+ import { useEffect as useEffect6, useMemo as useMemo5, useState as useState4 } from "react";
2193
2298
  import { Link as Link6, useLocation as useLocation4 } from "react-router-dom";
2194
- import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
2299
+ import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
2195
2300
  function useQueryToken4() {
2196
2301
  const loc = useLocation4();
2197
2302
  const qs = new URLSearchParams(loc.search);
@@ -2251,7 +2356,7 @@ function PaymentsPage() {
2251
2356
  setBusy(false);
2252
2357
  }
2253
2358
  }
2254
- useEffect5(() => {
2359
+ useEffect6(() => {
2255
2360
  void refresh();
2256
2361
  host.notifyNavigation?.({
2257
2362
  path: typeof window !== "undefined" ? window.location.pathname : "",
@@ -2259,7 +2364,7 @@ function PaymentsPage() {
2259
2364
  params: { xappId: xappIdFilter || null }
2260
2365
  });
2261
2366
  }, [focusedPaymentSessionId, installationIdFilter, xappIdFilter]);
2262
- useEffect5(() => {
2367
+ useEffect6(() => {
2263
2368
  if (!focusedPaymentSessionId || !client.getMyPaymentSession) {
2264
2369
  setFocusedSession(null);
2265
2370
  setFocusedError(null);
@@ -2283,7 +2388,7 @@ function PaymentsPage() {
2283
2388
  cancelled = true;
2284
2389
  };
2285
2390
  }, [client, focusedPaymentSessionId]);
2286
- useEffect5(() => {
2391
+ useEffect6(() => {
2287
2392
  if (!xappIdFilter) {
2288
2393
  setXappTitle("");
2289
2394
  return;
@@ -2330,7 +2435,7 @@ function PaymentsPage() {
2330
2435
  return /* @__PURE__ */ jsxs6("div", { className: `mx-catalog-container ${isEmbedded ? "is-embedded" : ""}`, children: [
2331
2436
  /* @__PURE__ */ jsxs6("div", { className: "mx-breadcrumb", children: [
2332
2437
  /* @__PURE__ */ jsx10(Link6, { to: isEmbedded ? "/" : "/marketplace", children: t("common.marketplace", void 0, "Marketplace") }),
2333
- xappLink && /* @__PURE__ */ jsxs6(Fragment4, { children: [
2438
+ xappLink && /* @__PURE__ */ jsxs6(Fragment5, { children: [
2334
2439
  /* @__PURE__ */ jsx10("span", { className: "mx-breadcrumb-sep", children: "/" }),
2335
2440
  /* @__PURE__ */ jsx10(Link6, { to: xappLink, children: xappTitle || xappIdFilter })
2336
2441
  ] }),
@@ -2548,7 +2653,7 @@ function PaymentsPage() {
2548
2653
  }
2549
2654
 
2550
2655
  // src/pages/RequestDetailPage.tsx
2551
- import { useEffect as useEffect6, useMemo as useMemo6, useState as useState5 } from "react";
2656
+ import { useEffect as useEffect7, useMemo as useMemo6, useState as useState5 } from "react";
2552
2657
  import { Link as Link7, useLocation as useLocation5, useNavigate as useNavigate2, useParams } from "react-router-dom";
2553
2658
 
2554
2659
  // src/components/SchemaOutputView.tsx
@@ -2636,6 +2741,10 @@ function normalizeActionKind(raw) {
2636
2741
  function resolveText(t, key, fallback) {
2637
2742
  return typeof t === "function" ? t(key, fallback) : fallback;
2638
2743
  }
2744
+ function isSettledPaymentStatus(value) {
2745
+ const normalized = readString3(value).toLowerCase();
2746
+ return normalized === "paid" || normalized === "settled" || normalized === "succeeded" || normalized === "completed";
2747
+ }
2639
2748
  function resolveCtaLabel(actionKind, t) {
2640
2749
  if (actionKind === "complete_payment") {
2641
2750
  return resolveText(t, "payment_lock.complete_payment", "Complete Payment");
@@ -2734,7 +2843,11 @@ function resolvePaymentLockStateFromGuardSummary(summaryInput, options) {
2734
2843
  })();
2735
2844
  const isPaymentKind = actionKind === "complete_payment" || actionKind === "payment_required";
2736
2845
  const isPaymentReason = reason === "payment_required" || reason === "payment_evidence_missing" || reason === "payment_receipt_already_used";
2737
- const isLocked = isPaymentKind || isPaymentReason;
2846
+ const requestStatus = readString3(options?.requestStatus).toUpperCase();
2847
+ const paymentSettled = isSettledPaymentStatus(options?.paymentStatus);
2848
+ const isHeldForPayment = requestStatus === "PAYMENT_PENDING";
2849
+ const isResolvedPastHold = paymentSettled && requestStatus !== "" && !isHeldForPayment;
2850
+ const isLocked = !isResolvedPastHold && (isPaymentKind || isPaymentReason);
2738
2851
  return {
2739
2852
  isLocked,
2740
2853
  reason,
@@ -2749,8 +2862,166 @@ function resolvePaymentLockStateFromGuardSummary(summaryInput, options) {
2749
2862
  };
2750
2863
  }
2751
2864
 
2865
+ // src/utils/guardMonetization.ts
2866
+ function asRecord4(value) {
2867
+ return value && typeof value === "object" ? value : {};
2868
+ }
2869
+ function readGuardMonetizationState(input) {
2870
+ const root = asRecord4(input);
2871
+ const details = asRecord4(root.details);
2872
+ const guard = asRecord4(root.guard);
2873
+ const guardDetails = asRecord4(guard.details);
2874
+ const candidates = [
2875
+ asRecord4(root.monetization_state),
2876
+ asRecord4(details.monetization_state),
2877
+ asRecord4(guardDetails.monetization_state)
2878
+ ];
2879
+ for (const candidate of candidates) {
2880
+ if (Object.keys(candidate).length > 0) return candidate;
2881
+ }
2882
+ return null;
2883
+ }
2884
+ function readGuardHasCurrentAccess(input) {
2885
+ const value = readGuardMonetizationState(input)?.has_current_access;
2886
+ return typeof value === "boolean" ? value : null;
2887
+ }
2888
+ function describeGuardCurrentAccess(input, labels) {
2889
+ const hasCurrentAccess = readGuardHasCurrentAccess(input);
2890
+ if (hasCurrentAccess === null) return "";
2891
+ return hasCurrentAccess ? labels.available : labels.unavailable;
2892
+ }
2893
+
2894
+ // src/utils/operationalSurfaces.ts
2895
+ function readPathEmbedded() {
2896
+ return typeof window !== "undefined" && window.location.pathname.startsWith("/embed");
2897
+ }
2898
+ function getOperationalSurfaces(detail) {
2899
+ const value = detail?.operational_surfaces;
2900
+ if (!value || typeof value !== "object") return null;
2901
+ return value;
2902
+ }
2903
+ function readOperationalSurfaceMode(input) {
2904
+ const policy = input.env?.operationalSurfacesVisibility;
2905
+ return input.isEmbedded ? policy?.embed ?? "contract" : policy?.portal ?? "contract";
2906
+ }
2907
+ function isOperationalSurfaceVisible(detail, surface, options) {
2908
+ const surfaces = getOperationalSurfaces(detail);
2909
+ const descriptor = surfaces?.[surface];
2910
+ if (!descriptor?.enabled) return false;
2911
+ const isEmbedded = options?.isEmbedded ?? readPathEmbedded();
2912
+ return isEmbedded ? descriptor.visibility.embed : descriptor.visibility.portal;
2913
+ }
2914
+ function surfaceClientAvailable(client, surface) {
2915
+ if (surface === "requests") return typeof client.listMyRequests === "function";
2916
+ if (surface === "payments") return typeof client.listMyPaymentSessions === "function";
2917
+ if (surface === "invoices") return typeof client.listMyInvoices === "function";
2918
+ if (surface === "notifications") return typeof client.listMyNotifications === "function";
2919
+ return false;
2920
+ }
2921
+ function buildOperationalSurfaceHref(input) {
2922
+ const isEmbedded = input.isEmbedded ?? readPathEmbedded();
2923
+ const params = new URLSearchParams({
2924
+ xappId: input.xappId,
2925
+ ...input.installationId ? { installationId: input.installationId } : {},
2926
+ ...input.paymentSessionId ? { paymentSessionId: input.paymentSessionId } : {},
2927
+ ...input.invoiceId ? { invoiceId: input.invoiceId } : {},
2928
+ ...input.notificationId ? { notificationId: input.notificationId } : {},
2929
+ ...input.token ? { token: input.token } : {}
2930
+ });
2931
+ const base = isEmbedded ? `/${input.surface}` : `/marketplace/${input.surface}`;
2932
+ const detailSegment = input.surface === "requests" && input.requestId ? `/${encodeURIComponent(input.requestId)}` : "";
2933
+ return `${base}${detailSegment}?${params.toString()}`;
2934
+ }
2935
+ function getVisibleOperationalSurfaces(input) {
2936
+ const isEmbedded = input.isEmbedded ?? readPathEmbedded();
2937
+ const mode = readOperationalSurfaceMode({
2938
+ env: input.env,
2939
+ isEmbedded
2940
+ });
2941
+ const allSurfaces = [
2942
+ "requests",
2943
+ "payments",
2944
+ "invoices",
2945
+ "notifications"
2946
+ ];
2947
+ if (mode === "testing_all") {
2948
+ return allSurfaces.filter((surface) => {
2949
+ if (surface === "requests" && input.env?.requestsEnabled === false) return false;
2950
+ return surfaceClientAvailable(input.client, surface);
2951
+ });
2952
+ }
2953
+ const surfaces = getOperationalSurfaces(input.detail);
2954
+ if (!surfaces) return [];
2955
+ return allSurfaces.filter(
2956
+ (surface) => surfaceClientAvailable(input.client, surface) && isOperationalSurfaceVisible(input.detail, surface, { isEmbedded })
2957
+ );
2958
+ }
2959
+ function getOperationalSurfaceLabel(surface) {
2960
+ if (surface === "requests") return "Requests";
2961
+ if (surface === "payments") return "Payments";
2962
+ if (surface === "invoices") return "Invoices";
2963
+ return "Notifications";
2964
+ }
2965
+ function resolveOperationalSurfacePlacement(input) {
2966
+ const isEmbedded = input.isEmbedded ?? readPathEmbedded();
2967
+ const policy = input.env?.operationalSurfacePlacement;
2968
+ const scopePolicy = isEmbedded ? policy?.embed : policy?.portal;
2969
+ const bySurface = scopePolicy?.bySurface?.[input.surface];
2970
+ if (bySurface) return bySurface;
2971
+ return scopePolicy?.default ?? "in_router";
2972
+ }
2973
+ async function discoverOperationalSurfaceData(input) {
2974
+ const xappId = String(input.xappId || "").trim();
2975
+ const installationId = String(input.installationId || "").trim();
2976
+ if (!xappId) return [];
2977
+ const queryBase = {
2978
+ xappId,
2979
+ ...installationId ? { installationId } : {}
2980
+ };
2981
+ const checks = await Promise.all([
2982
+ (async () => {
2983
+ if (typeof input.client.listMyPaymentSessions !== "function") return null;
2984
+ try {
2985
+ const res = await input.client.listMyPaymentSessions({
2986
+ ...queryBase,
2987
+ limit: 1
2988
+ });
2989
+ return Array.isArray(res?.items) && res.items.length > 0 ? "payments" : null;
2990
+ } catch {
2991
+ return null;
2992
+ }
2993
+ })(),
2994
+ (async () => {
2995
+ if (typeof input.client.listMyInvoices !== "function") return null;
2996
+ try {
2997
+ const res = await input.client.listMyInvoices({
2998
+ ...queryBase,
2999
+ page: 1,
3000
+ pageSize: 1
3001
+ });
3002
+ return Array.isArray(res?.items) && res.items.length > 0 ? "invoices" : null;
3003
+ } catch {
3004
+ return null;
3005
+ }
3006
+ })(),
3007
+ (async () => {
3008
+ if (typeof input.client.listMyNotifications !== "function") return null;
3009
+ try {
3010
+ const res = await input.client.listMyNotifications({
3011
+ ...queryBase,
3012
+ limit: 1
3013
+ });
3014
+ return Array.isArray(res?.items) && res.items.length > 0 || Number(res?.unread_count || 0) > 0 ? "notifications" : null;
3015
+ } catch {
3016
+ return null;
3017
+ }
3018
+ })()
3019
+ ]);
3020
+ return checks.filter((surface) => Boolean(surface));
3021
+ }
3022
+
2752
3023
  // src/pages/RequestDetailPage.tsx
2753
- import { Fragment as Fragment5, jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
3024
+ import { Fragment as Fragment6, jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
2754
3025
  function useQueryToken5() {
2755
3026
  const loc = useLocation5();
2756
3027
  const qs = new URLSearchParams(loc.search);
@@ -2760,6 +3031,18 @@ function useQuery4() {
2760
3031
  const loc = useLocation5();
2761
3032
  return useMemo6(() => new URLSearchParams(loc.search), [loc.search]);
2762
3033
  }
3034
+ function navigateToExternalOrHost(url) {
3035
+ const next = String(url || "").trim();
3036
+ if (!next || typeof window === "undefined") return;
3037
+ try {
3038
+ if (window.parent && window.parent !== window) {
3039
+ window.parent.postMessage({ type: "XAPPS_UI_NAVIGATE", data: { path: next } }, "*");
3040
+ return;
3041
+ }
3042
+ } catch {
3043
+ }
3044
+ window.location.href = next;
3045
+ }
2763
3046
  function RequestDetailPage() {
2764
3047
  const { client, host, env } = useMarketplace();
2765
3048
  const { t, locale } = useMarketplaceI18n();
@@ -2780,6 +3063,8 @@ function RequestDetailPage() {
2780
3063
  const requestRecord = asRecord(dataRecord.request);
2781
3064
  const toolRecord = asRecord(dataRecord.tool);
2782
3065
  const manifestRecord = asRecord(dataRecord.manifest);
3066
+ const requestPayment = asRecord(requestRecord.payment);
3067
+ const requestPaymentSummary = asRecord(requestRecord.payment_summary);
2783
3068
  const status = readFirstString(requestRecord.status) || void 0;
2784
3069
  const isTerminal = status === "COMPLETED" || status === "FAILED";
2785
3070
  const effectiveXappId = readFirstString(requestRecord.xapp_id, xappIdFilter);
@@ -2812,6 +3097,8 @@ function RequestDetailPage() {
2812
3097
  if (!resolvePaymentLockStateFromGuardSummary(
2813
3098
  asRecord(asRecord(res).request).guard_summary ?? null,
2814
3099
  {
3100
+ requestStatus: readFirstString(asRecord(asRecord(res).request).status),
3101
+ paymentStatus: readFirstString(asRecord(asRecord(res).request).payment_status),
2815
3102
  t: (key, fallback) => t(key, void 0, fallback)
2816
3103
  }
2817
3104
  ).isLocked) {
@@ -2823,31 +3110,7 @@ function RequestDetailPage() {
2823
3110
  setBusy(false);
2824
3111
  }
2825
3112
  }
2826
- async function reconcilePaymentFinality() {
2827
- if (!id || reconcileBusy || !client.reconcileMyRequestPayment) return;
2828
- setReconcileError(null);
2829
- setReconcileState("confirming_payment");
2830
- setReconcileBusy(true);
2831
- try {
2832
- const res = await client.reconcileMyRequestPayment({
2833
- requestId: String(id),
2834
- paymentSessionId: requestPaymentLock.paymentSessionId
2835
- });
2836
- setReconcileState(res?.finality_state || "none");
2837
- const redirectUrl = String(res?.redirect_url || "").trim();
2838
- if (redirectUrl) {
2839
- window.location.href = redirectUrl;
2840
- return;
2841
- }
2842
- await refreshOnce();
2843
- } catch (e) {
2844
- setReconcileError(readFirstString(asRecord(e).message) || String(e));
2845
- setReconcileState("failed");
2846
- } finally {
2847
- setReconcileBusy(false);
2848
- }
2849
- }
2850
- useEffect6(() => {
3113
+ useEffect7(() => {
2851
3114
  if (!id) return;
2852
3115
  let alive = true;
2853
3116
  let timer = null;
@@ -2940,11 +3203,69 @@ function RequestDetailPage() {
2940
3203
  }, [toolRecord]);
2941
3204
  const requestPaymentLock = useMemo6(
2942
3205
  () => resolvePaymentLockStateFromGuardSummary(requestRecord.guard_summary ?? null, {
3206
+ requestStatus: readFirstString(requestRecord.status),
3207
+ paymentStatus: readFirstString(requestRecord.payment_status),
2943
3208
  reconcileState,
2944
3209
  t: (key, fallback) => t(key, void 0, fallback)
2945
3210
  }),
2946
3211
  [requestRecord.guard_summary, reconcileState, t]
2947
3212
  );
3213
+ const isPaymentPending = String(status || "").trim().toUpperCase() === "PAYMENT_PENDING";
3214
+ const showPaymentWaitState = requestPaymentLock.isLocked || isPaymentPending;
3215
+ const requestGuardCurrentAccess = describeGuardCurrentAccess(
3216
+ requestRecord.guard_summary ?? null,
3217
+ {
3218
+ available: t("common.available", void 0, "Available"),
3219
+ unavailable: t("xapp.subscription_coverage_inactive", void 0, "Not covered")
3220
+ }
3221
+ );
3222
+ const eventPaymentSessionId = useMemo6(() => {
3223
+ const events = Array.isArray(dataRecord.events) ? dataRecord.events : [];
3224
+ for (let index = events.length - 1; index >= 0; index -= 1) {
3225
+ const candidate = readPaymentSessionIdFromUnknown(getEventPayload(events[index]));
3226
+ if (candidate) return candidate;
3227
+ }
3228
+ return "";
3229
+ }, [dataRecord.events]);
3230
+ const effectivePaymentSessionId = readFirstString(
3231
+ requestPaymentLock.paymentSessionId,
3232
+ requestRecord.payment_session_id,
3233
+ requestRecord.paymentSessionId,
3234
+ requestPayment.payment_session_id,
3235
+ requestPayment.paymentSessionId,
3236
+ requestPaymentSummary.payment_session_id,
3237
+ requestPaymentSummary.paymentSessionId,
3238
+ eventPaymentSessionId
3239
+ ) || "";
3240
+ const directPaymentUrl = readFirstString(
3241
+ requestRecord.payment_resume_url,
3242
+ requestRecord.paymentResumeUrl,
3243
+ requestPayment.resume_url,
3244
+ requestPayment.resumeUrl,
3245
+ requestPaymentSummary.payment_resume_url,
3246
+ requestPaymentSummary.paymentResumeUrl,
3247
+ requestPaymentLock.actionUrl
3248
+ ) || "";
3249
+ const paymentSurfaceHref = (() => {
3250
+ if (!effectivePaymentSessionId) return "";
3251
+ const installationId = readFirstString(requestRecord.installation_id) || void 0;
3252
+ if (effectiveXappId) {
3253
+ return buildOperationalSurfaceHref({
3254
+ surface: "payments",
3255
+ xappId: effectiveXappId,
3256
+ installationId,
3257
+ paymentSessionId: effectivePaymentSessionId,
3258
+ token: token || void 0,
3259
+ isEmbedded
3260
+ });
3261
+ }
3262
+ const params = new URLSearchParams({
3263
+ paymentSessionId: effectivePaymentSessionId,
3264
+ ...installationId ? { installationId } : {},
3265
+ ...token ? { token } : {}
3266
+ });
3267
+ return `${isEmbedded ? "/payments" : "/marketplace/payments"}?${params.toString()}`;
3268
+ })();
2948
3269
  function getEventPayload(ev) {
2949
3270
  const eventRecord = asRecord(ev);
2950
3271
  if (!Object.keys(eventRecord).length) return null;
@@ -2961,6 +3282,39 @@ function RequestDetailPage() {
2961
3282
  }
2962
3283
  return null;
2963
3284
  }
3285
+ function readPaymentSessionIdFromUnknown(value) {
3286
+ const record = asRecord(value);
3287
+ const direct = readFirstString(
3288
+ record.payment_session_id,
3289
+ record.paymentSessionId,
3290
+ asRecord(record.action).payment_session_id,
3291
+ asRecord(record.action).paymentSessionId,
3292
+ asRecord(record.guard).payment_session_id,
3293
+ asRecord(asRecord(record.guard).action).payment_session_id,
3294
+ asRecord(asRecord(record.guard).action).paymentSessionId
3295
+ );
3296
+ if (direct) return direct;
3297
+ const url = readFirstString(
3298
+ record.url,
3299
+ record.payment_url,
3300
+ record.paymentUrl,
3301
+ asRecord(record.action).url,
3302
+ asRecord(asRecord(record.guard).action).url
3303
+ );
3304
+ if (!url) return "";
3305
+ try {
3306
+ const parsed = new URL(
3307
+ url,
3308
+ typeof window !== "undefined" ? window.location.href : "http://localhost"
3309
+ );
3310
+ return readFirstString(
3311
+ parsed.searchParams.get("payment_session_id"),
3312
+ parsed.searchParams.get("paymentSessionId")
3313
+ ) || "";
3314
+ } catch {
3315
+ return "";
3316
+ }
3317
+ }
2964
3318
  function extractGuardSummary(payload) {
2965
3319
  const p = asRecord(payload);
2966
3320
  const guard = asRecord(p.guard);
@@ -3038,7 +3392,7 @@ function RequestDetailPage() {
3038
3392
  if (raw == null) return null;
3039
3393
  const enriched = attachArtifactLinks(raw, artifacts);
3040
3394
  const isOpen = expandedPayloads[idx] ?? false;
3041
- return /* @__PURE__ */ jsxs8(Fragment5, { children: [
3395
+ return /* @__PURE__ */ jsxs8(Fragment6, { children: [
3042
3396
  /* @__PURE__ */ jsxs8(
3043
3397
  "button",
3044
3398
  {
@@ -3067,14 +3421,56 @@ function RequestDetailPage() {
3067
3421
  }
3068
3422
  function StatusBadge4({ status: status2 }) {
3069
3423
  const s = String(status2 || "");
3424
+ const normalized = s.trim().toUpperCase();
3070
3425
  const className = s === "COMPLETED" ? "mx-badge-success" : s === "FAILED" ? "mx-badge-danger" : "mx-badge-warning";
3071
- return /* @__PURE__ */ jsx12("span", { className: `mx-badge ${className}`, children: s || "\u2014" });
3426
+ const label = normalized === "PAYMENT_PENDING" ? t("activity.payment_pending", void 0, "Payment Pending") : s || "\u2014";
3427
+ return /* @__PURE__ */ jsx12("span", { className: `mx-badge ${className}`, children: label });
3428
+ }
3429
+ async function continuePayment() {
3430
+ if (client.reconcileMyRequestPayment && isPaymentPending) {
3431
+ setReconcileError(null);
3432
+ setReconcileState("confirming_payment");
3433
+ setReconcileBusy(true);
3434
+ try {
3435
+ const hostReturnUrl = readHostReturnUrl(loc.search);
3436
+ const currentReturnUrl = String(
3437
+ hostReturnUrl || (typeof window !== "undefined" ? window.location.href : "") || ""
3438
+ ).trim();
3439
+ const res = await client.reconcileMyRequestPayment({
3440
+ requestId: String(id),
3441
+ paymentSessionId: isPaymentPending ? void 0 : effectivePaymentSessionId || void 0,
3442
+ returnUrl: currentReturnUrl || void 0,
3443
+ cancelUrl: currentReturnUrl || void 0
3444
+ });
3445
+ setReconcileState(res?.finality_state || "none");
3446
+ const redirectUrl = String(res?.redirect_url || "").trim();
3447
+ if (redirectUrl) {
3448
+ navigateToExternalOrHost(redirectUrl);
3449
+ return;
3450
+ }
3451
+ await refreshOnce();
3452
+ return;
3453
+ } catch (e) {
3454
+ setReconcileError(readFirstString(asRecord(e).message) || String(e));
3455
+ setReconcileState("failed");
3456
+ return;
3457
+ } finally {
3458
+ setReconcileBusy(false);
3459
+ }
3460
+ }
3461
+ if (directPaymentUrl) {
3462
+ navigateToExternalOrHost(directPaymentUrl);
3463
+ return;
3464
+ }
3465
+ if (paymentSurfaceHref) {
3466
+ void navigate(paymentSurfaceHref);
3467
+ }
3072
3468
  }
3073
3469
  return /* @__PURE__ */ jsxs8("div", { className: `mx-catalog-container ${isEmbedded ? "is-embedded" : ""}`, children: [
3074
3470
  /* @__PURE__ */ jsxs8("div", { className: "mx-breadcrumb", children: [
3075
3471
  !env?.singleXappMode && /* @__PURE__ */ jsx12(Link7, { to: marketplaceTo, children: t("common.marketplace", void 0, "Marketplace") }),
3076
3472
  env?.singleXappMode && !env?.embedMode && /* @__PURE__ */ jsx12(Link7, { to: marketplaceTo, children: t("common.marketplace", void 0, "Marketplace") }),
3077
- xappTo && /* @__PURE__ */ jsxs8(Fragment5, { children: [
3473
+ xappTo && /* @__PURE__ */ jsxs8(Fragment6, { children: [
3078
3474
  (!env?.singleXappMode || env?.singleXappMode && !env?.embedMode) && /* @__PURE__ */ jsx12("span", { className: "mx-breadcrumb-sep", children: "/" }),
3079
3475
  /* @__PURE__ */ jsx12(Link7, { to: xappTo, children: xappCrumbLabel })
3080
3476
  ] }),
@@ -3143,7 +3539,7 @@ function RequestDetailPage() {
3143
3539
  /* @__PURE__ */ jsx12("h2", { className: "mx-title mx-request-section-title", children: title }),
3144
3540
  /* @__PURE__ */ jsxs8("div", { className: "mx-request-meta-row", children: [
3145
3541
  /* @__PURE__ */ jsx12("span", { children: effectiveXappTitle || "\u2014" }),
3146
- readString(requestRecord.xapp_version) && /* @__PURE__ */ jsxs8(Fragment5, { children: [
3542
+ readString(requestRecord.xapp_version) && /* @__PURE__ */ jsxs8(Fragment6, { children: [
3147
3543
  /* @__PURE__ */ jsx12("span", { children: "\xB7" }),
3148
3544
  /* @__PURE__ */ jsxs8("span", { children: [
3149
3545
  "v",
@@ -3175,34 +3571,37 @@ function RequestDetailPage() {
3175
3571
  ] }),
3176
3572
  /* @__PURE__ */ jsxs8("section", { className: "mx-table-container mx-request-section", children: [
3177
3573
  /* @__PURE__ */ jsx12("h3", { className: "mx-section-title mx-section-title-md", children: t("activity.response_title", void 0, "Response") }),
3178
- requestPaymentLock.isLocked && requestPaymentLock.actionUrl ? /* @__PURE__ */ jsxs8("div", { className: "mx-payment-lock-banner", children: [
3179
- /* @__PURE__ */ jsx12("div", { className: "mx-payment-lock-title", children: t("activity.payment_required", void 0, "Payment Required") }),
3180
- /* @__PURE__ */ jsx12("div", { className: "mx-payment-lock-message", children: requestPaymentLock.message }),
3574
+ showPaymentWaitState ? /* @__PURE__ */ jsxs8("div", { className: "mx-payment-lock-banner", children: [
3575
+ /* @__PURE__ */ jsx12("div", { className: "mx-payment-lock-title", children: isPaymentPending ? t("activity.payment_pending", void 0, "Payment Pending") : t("activity.payment_required", void 0, "Payment Required") }),
3576
+ /* @__PURE__ */ jsx12("div", { className: "mx-payment-lock-message", children: requestPaymentLock.isLocked ? requestPaymentLock.message : t(
3577
+ "activity.waiting_for_payment",
3578
+ void 0,
3579
+ "Waiting for payment confirmation\u2026"
3580
+ ) }),
3581
+ requestGuardCurrentAccess ? /* @__PURE__ */ jsx12("div", { className: "mx-payment-lock-message", children: t(
3582
+ "activity.current_access_detail",
3583
+ { value: requestGuardCurrentAccess },
3584
+ "Current access: {value}"
3585
+ ) }) : null,
3181
3586
  /* @__PURE__ */ jsxs8("div", { className: "mx-payment-lock-actions", children: [
3182
- /* @__PURE__ */ jsx12(
3587
+ isPaymentPending || effectivePaymentSessionId || directPaymentUrl || paymentSurfaceHref ? /* @__PURE__ */ jsx12(
3183
3588
  "button",
3184
3589
  {
3185
3590
  className: "mx-btn mx-btn-primary",
3186
- onClick: () => {
3187
- window.location.href = requestPaymentLock.actionUrl;
3188
- },
3189
- children: requestPaymentLock.ctaLabel || t("activity.complete_payment", void 0, "Complete Payment")
3190
- }
3191
- ),
3192
- client.reconcileMyRequestPayment && requestPaymentLock.paymentSessionId ? /* @__PURE__ */ jsx12(
3193
- "button",
3194
- {
3195
- className: "mx-btn mx-btn-secondary",
3196
- onClick: () => void reconcilePaymentFinality(),
3197
- disabled: reconcileBusy || requestPaymentLock.reconcileState === "confirmed_paid",
3198
- children: reconcileBusy ? t("activity.confirming_payment", void 0, "Confirming...") : t("activity.confirm_payment", void 0, "Confirm Payment")
3591
+ onClick: () => void continuePayment(),
3592
+ disabled: reconcileBusy,
3593
+ children: t("activity.complete_payment", void 0, "Complete Payment")
3199
3594
  }
3200
3595
  ) : null,
3201
3596
  /* @__PURE__ */ jsx12("button", { className: "mx-btn mx-btn-secondary", onClick: () => void refreshOnce(), children: t("activity.refresh_status", void 0, "Refresh Status") })
3202
3597
  ] }),
3203
3598
  reconcileError ? /* @__PURE__ */ jsx12("div", { className: "mx-payment-lock-error", children: reconcileError }) : null
3204
3599
  ] }) : null,
3205
- !isTerminal ? /* @__PURE__ */ jsx12("div", { className: "mx-waiting-state", children: t("activity.waiting_for_response", void 0, "Waiting for response\u2026") }) : /* @__PURE__ */ jsx12(SchemaOutputView, { schema: outputSchema, value: responsePayload })
3600
+ !isTerminal ? showPaymentWaitState ? /* @__PURE__ */ jsx12("div", { className: "mx-waiting-state", children: t(
3601
+ "activity.waiting_for_payment",
3602
+ void 0,
3603
+ "Waiting for payment confirmation\u2026"
3604
+ ) }) : /* @__PURE__ */ jsx12("div", { className: "mx-waiting-state", children: t("activity.waiting_for_response", void 0, "Waiting for response\u2026") }) : /* @__PURE__ */ jsx12(SchemaOutputView, { schema: outputSchema, value: responsePayload })
3206
3605
  ] }),
3207
3606
  Array.isArray(dataRecord.events) && dataRecord.events.length > 0 && (() => {
3208
3607
  const evts = dataRecord.events;
@@ -3309,6 +3708,18 @@ function RequestDetailPage() {
3309
3708
  const progress = typeof eventRecord.progress === "number" ? eventRecord.progress : null;
3310
3709
  const guardSummary = extractGuardSummary(ev) ?? extractGuardSummary(getEventPayload(ev)) ?? extractGuardSummary(eventRecord.payload);
3311
3710
  const guardActionLabel = renderGuardActionLabel(guardSummary);
3711
+ const guardMonetizationSource = getEventPayload(ev) ?? eventRecord.payload ?? ev;
3712
+ const guardCurrentAccess = describeGuardCurrentAccess(
3713
+ guardMonetizationSource,
3714
+ {
3715
+ available: t("common.available", void 0, "Available"),
3716
+ unavailable: t(
3717
+ "xapp.subscription_coverage_inactive",
3718
+ void 0,
3719
+ "Not covered"
3720
+ )
3721
+ }
3722
+ );
3312
3723
  return /* @__PURE__ */ jsxs8(
3313
3724
  "li",
3314
3725
  {
@@ -3393,6 +3804,11 @@ function RequestDetailPage() {
3393
3804
  "activity.outcome_badge",
3394
3805
  { value: guardSummary.outcome },
3395
3806
  "outcome: {value}"
3807
+ ) }),
3808
+ guardCurrentAccess && /* @__PURE__ */ jsx12("span", { className: "mx-badge mx-badge-warning", children: t(
3809
+ "activity.current_access_badge",
3810
+ { value: guardCurrentAccess },
3811
+ "access: {value}"
3396
3812
  ) })
3397
3813
  ] }),
3398
3814
  (guardSummary.reason || guardActionLabel) && /* @__PURE__ */ jsxs8("div", { className: "mx-event-guard-detail", children: [
@@ -3500,9 +3916,9 @@ function RequestDetailPage() {
3500
3916
  }
3501
3917
 
3502
3918
  // src/pages/RequestsPage.tsx
3503
- import { useEffect as useEffect7, useMemo as useMemo7, useState as useState6 } from "react";
3919
+ import { useEffect as useEffect8, useMemo as useMemo7, useState as useState6 } from "react";
3504
3920
  import { Link as Link8, useLocation as useLocation6 } from "react-router-dom";
3505
- import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
3921
+ import { Fragment as Fragment7, jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
3506
3922
  function useQueryToken6() {
3507
3923
  const loc = useLocation6();
3508
3924
  const qs = new URLSearchParams(loc.search);
@@ -3515,10 +3931,9 @@ function useQuery5() {
3515
3931
  function renderGuardActionHint(summary) {
3516
3932
  const action = asRecord(summary.action);
3517
3933
  const kind = readString(action.kind);
3518
- const url = readString(action.url);
3519
- if (kind === "upgrade_subscription") return `Upgrade subscription${url ? ` (${url})` : ""}`;
3520
- if (kind === "complete_payment") return `Complete payment${url ? ` (${url})` : ""}`;
3521
- if (kind === "step_up_auth") return `Complete step-up authentication${url ? ` (${url})` : ""}`;
3934
+ if (kind === "upgrade_subscription") return "Upgrade subscription";
3935
+ if (kind === "complete_payment") return "Complete payment";
3936
+ if (kind === "step_up_auth") return "Complete step-up authentication";
3522
3937
  if (kind === "confirm_action") {
3523
3938
  const msg = readString(action.message);
3524
3939
  return msg ? `Confirm action (${msg})` : "Confirm action";
@@ -3561,7 +3976,7 @@ function RequestsPage() {
3561
3976
  setBusy(false);
3562
3977
  }
3563
3978
  }
3564
- useEffect7(() => {
3979
+ useEffect8(() => {
3565
3980
  void refresh(pageParam);
3566
3981
  host.notifyNavigation?.({
3567
3982
  path: window.location.pathname,
@@ -3569,7 +3984,7 @@ function RequestsPage() {
3569
3984
  params: { xappId: xappIdFilter }
3570
3985
  });
3571
3986
  }, [xappIdFilter, pageParam]);
3572
- useEffect7(() => {
3987
+ useEffect8(() => {
3573
3988
  if (!xappIdFilter) {
3574
3989
  setXappTitle("");
3575
3990
  return;
@@ -3607,8 +4022,10 @@ function RequestsPage() {
3607
4022
  };
3608
4023
  function StatusBadge4({ status }) {
3609
4024
  const s = String(status || "");
4025
+ const normalized = s.trim().toUpperCase();
3610
4026
  const className = s === "COMPLETED" ? "mx-badge-success" : s === "FAILED" ? "mx-badge-danger" : "mx-badge-warning";
3611
- return /* @__PURE__ */ jsx13("span", { className: `mx-badge ${className}`, children: s || "\u2014" });
4027
+ const label = normalized === "PAYMENT_PENDING" ? t("activity.payment_pending", void 0, "Payment Pending") : s || "\u2014";
4028
+ return /* @__PURE__ */ jsx13("span", { className: `mx-badge ${className}`, children: label });
3612
4029
  }
3613
4030
  if (env?.requestsEnabled === false) {
3614
4031
  return /* @__PURE__ */ jsx13("div", { className: `mx-catalog-container ${isEmbedded ? "is-embedded" : ""}`, children: /* @__PURE__ */ jsxs9("div", { className: "mx-table-container mx-unavailable", children: [
@@ -3628,7 +4045,7 @@ function RequestsPage() {
3628
4045
  /* @__PURE__ */ jsxs9("div", { className: "mx-breadcrumb", children: [
3629
4046
  !env?.singleXappMode && /* @__PURE__ */ jsx13(Link8, { to: isEmbedded ? "/" : "/marketplace", children: t("common.marketplace", void 0, "Marketplace") }),
3630
4047
  env?.singleXappMode && !isEmbedded && /* @__PURE__ */ jsx13(Link8, { to: isEmbedded ? "/" : "/marketplace", children: t("common.marketplace", void 0, "Marketplace") }),
3631
- xappIdFilter && xappLink && /* @__PURE__ */ jsxs9(Fragment6, { children: [
4048
+ xappIdFilter && xappLink && /* @__PURE__ */ jsxs9(Fragment7, { children: [
3632
4049
  (!env?.singleXappMode || env?.singleXappMode && !isEmbedded) && /* @__PURE__ */ jsx13("span", { className: "mx-breadcrumb-sep", children: "/" }),
3633
4050
  /* @__PURE__ */ jsx13(Link8, { to: xappLink, children: xappTitle || xappIdFilter })
3634
4051
  ] }),
@@ -3732,7 +4149,11 @@ function RequestsPage() {
3732
4149
  const guardReason = readString(guardSummary.reason);
3733
4150
  const guardOutcome = readString(guardSummary.outcome);
3734
4151
  const guardActionHint = renderGuardActionHint(guardSummary);
3735
- const hasGuardInfo = Boolean(guardSlug) || Boolean(guardReason) || Boolean(guardActionHint);
4152
+ const guardAccessHint = describeGuardCurrentAccess(guardSummary, {
4153
+ available: t("common.available", void 0, "Available"),
4154
+ unavailable: t("xapp.subscription_coverage_inactive", void 0, "Not covered")
4155
+ });
4156
+ const hasGuardInfo = Boolean(guardSlug) || Boolean(guardReason) || Boolean(guardActionHint) || Boolean(guardAccessHint);
3736
4157
  return /* @__PURE__ */ jsxs9("tr", { children: [
3737
4158
  /* @__PURE__ */ jsx13("td", { className: "mx-cell-id", "data-label": t("common.id", void 0, "ID"), children: /* @__PURE__ */ jsxs9(Link8, { to: href, children: [
3738
4159
  readFirstString(request.id).slice(0, 8),
@@ -3749,7 +4170,12 @@ function RequestsPage() {
3749
4170
  (guardSlug || guardOutcome) && guardReason ? " \xB7 " : "",
3750
4171
  guardReason ? `reason=${guardReason}` : ""
3751
4172
  ] }),
3752
- guardActionHint && /* @__PURE__ */ jsx13("div", { children: guardActionHint })
4173
+ guardActionHint && /* @__PURE__ */ jsx13("div", { children: guardActionHint }),
4174
+ guardAccessHint && /* @__PURE__ */ jsx13("div", { children: t(
4175
+ "activity.current_access_detail",
4176
+ { value: guardAccessHint },
4177
+ "Current access: {value}"
4178
+ ) })
3753
4179
  ] })
3754
4180
  ] }),
3755
4181
  /* @__PURE__ */ jsx13(
@@ -3813,140 +4239,49 @@ function RequestsPage() {
3813
4239
  }
3814
4240
 
3815
4241
  // src/pages/XappDetailPage.tsx
3816
- import { useEffect as useEffect8, useMemo as useMemo8, useRef, useState as useState7 } from "react";
4242
+ import { useEffect as useEffect9, useMemo as useMemo8, useRef, useState as useState7 } from "react";
3817
4243
  import { Link as Link9, useLocation as useLocation7, useNavigate as useNavigate3, useParams as useParams2 } from "react-router-dom";
3818
4244
 
3819
- // src/utils/operationalSurfaces.ts
3820
- function readPathEmbedded() {
3821
- return typeof window !== "undefined" && window.location.pathname.startsWith("/embed");
3822
- }
3823
- function getOperationalSurfaces(detail) {
3824
- const value = detail?.operational_surfaces;
3825
- if (!value || typeof value !== "object") return null;
4245
+ // src/utils/monetizationAccess.ts
4246
+ function asRecord5(value) {
4247
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
3826
4248
  return value;
3827
4249
  }
3828
- function readOperationalSurfaceMode(input) {
3829
- const policy = input.env?.operationalSurfacesVisibility;
3830
- return input.isEmbedded ? policy?.embed ?? "contract" : policy?.portal ?? "contract";
3831
- }
3832
- function isOperationalSurfaceVisible(detail, surface, options) {
3833
- const surfaces = getOperationalSurfaces(detail);
3834
- const descriptor = surfaces?.[surface];
3835
- if (!descriptor?.enabled) return false;
3836
- const isEmbedded = options?.isEmbedded ?? readPathEmbedded();
3837
- return isEmbedded ? descriptor.visibility.embed : descriptor.visibility.portal;
3838
- }
3839
- function surfaceClientAvailable(client, surface) {
3840
- if (surface === "requests") return typeof client.listMyRequests === "function";
3841
- if (surface === "payments") return typeof client.listMyPaymentSessions === "function";
3842
- if (surface === "invoices") return typeof client.listMyInvoices === "function";
3843
- if (surface === "notifications") return typeof client.listMyNotifications === "function";
3844
- return false;
4250
+ function readCurrentAccessFlag(value) {
4251
+ return typeof value === "boolean" ? value : false;
3845
4252
  }
3846
- function buildOperationalSurfaceHref(input) {
3847
- const isEmbedded = input.isEmbedded ?? readPathEmbedded();
3848
- const params = new URLSearchParams({
3849
- xappId: input.xappId,
3850
- ...input.installationId ? { installationId: input.installationId } : {},
3851
- ...input.paymentSessionId ? { paymentSessionId: input.paymentSessionId } : {},
3852
- ...input.invoiceId ? { invoiceId: input.invoiceId } : {},
3853
- ...input.notificationId ? { notificationId: input.notificationId } : {},
3854
- ...input.token ? { token: input.token } : {}
4253
+ function hasMarketplaceCatalogMonetization(manifest) {
4254
+ const manifestRecord = asRecord5(manifest);
4255
+ const monetization = asRecord5(manifestRecord?.monetization);
4256
+ if (!monetization) return false;
4257
+ return ["products", "offerings", "packages", "prices"].some((key) => {
4258
+ const items = monetization[key];
4259
+ return Array.isArray(items) && items.length > 0;
3855
4260
  });
3856
- const base = isEmbedded ? `/${input.surface}` : `/marketplace/${input.surface}`;
3857
- const detailSegment = input.surface === "requests" && input.requestId ? `/${encodeURIComponent(input.requestId)}` : "";
3858
- return `${base}${detailSegment}?${params.toString()}`;
3859
4261
  }
3860
- function getVisibleOperationalSurfaces(input) {
3861
- const isEmbedded = input.isEmbedded ?? readPathEmbedded();
3862
- const mode = readOperationalSurfaceMode({
3863
- env: input.env,
3864
- isEmbedded
3865
- });
3866
- const allSurfaces = [
3867
- "requests",
3868
- "payments",
3869
- "invoices",
3870
- "notifications"
3871
- ];
3872
- if (mode === "testing_all") {
3873
- return allSurfaces.filter((surface) => {
3874
- if (surface === "requests" && input.env?.requestsEnabled === false) return false;
3875
- return surfaceClientAvailable(input.client, surface);
3876
- });
3877
- }
3878
- const surfaces = getOperationalSurfaces(input.detail);
3879
- if (!surfaces) return [];
3880
- return allSurfaces.filter(
3881
- (surface) => surfaceClientAvailable(input.client, surface) && isOperationalSurfaceVisible(input.detail, surface, { isEmbedded })
3882
- );
4262
+ function hasMarketplaceCurrentAccess(projection) {
4263
+ if (!projection) return false;
4264
+ if (readCurrentAccessFlag(projection.has_current_access)) return true;
4265
+ const entitlementState = readString(projection.entitlement_state);
4266
+ const balanceState = readString(projection.balance_state);
4267
+ return entitlementState === "active" || entitlementState === "grace_period" || balanceState === "sufficient";
3883
4268
  }
3884
- function getOperationalSurfaceLabel(surface) {
3885
- if (surface === "requests") return "Requests";
3886
- if (surface === "payments") return "Payments";
3887
- if (surface === "invoices") return "Invoices";
3888
- return "Notifications";
4269
+ function resolveMarketplaceAccessState(input) {
4270
+ const entitlementState = readString(input.projection?.entitlement_state);
4271
+ if (entitlementState && entitlementState !== "inactive") return entitlementState;
4272
+ return hasMarketplaceCurrentAccess(input.projection) ? input.availableLabel : entitlementState || null;
3889
4273
  }
3890
- function resolveOperationalSurfacePlacement(input) {
3891
- const isEmbedded = input.isEmbedded ?? readPathEmbedded();
3892
- const policy = input.env?.operationalSurfacePlacement;
3893
- const scopePolicy = isEmbedded ? policy?.embed : policy?.portal;
3894
- const bySurface = scopePolicy?.bySurface?.[input.surface];
3895
- if (bySurface) return bySurface;
3896
- return scopePolicy?.default ?? "in_router";
3897
- }
3898
- async function discoverOperationalSurfaceData(input) {
3899
- const xappId = String(input.xappId || "").trim();
3900
- const installationId = String(input.installationId || "").trim();
3901
- if (!xappId) return [];
3902
- const queryBase = {
3903
- xappId,
3904
- ...installationId ? { installationId } : {}
3905
- };
3906
- const checks = await Promise.all([
3907
- (async () => {
3908
- if (typeof input.client.listMyPaymentSessions !== "function") return null;
3909
- try {
3910
- const res = await input.client.listMyPaymentSessions({
3911
- ...queryBase,
3912
- limit: 1
3913
- });
3914
- return Array.isArray(res?.items) && res.items.length > 0 ? "payments" : null;
3915
- } catch {
3916
- return null;
3917
- }
3918
- })(),
3919
- (async () => {
3920
- if (typeof input.client.listMyInvoices !== "function") return null;
3921
- try {
3922
- const res = await input.client.listMyInvoices({
3923
- ...queryBase,
3924
- page: 1,
3925
- pageSize: 1
3926
- });
3927
- return Array.isArray(res?.items) && res.items.length > 0 ? "invoices" : null;
3928
- } catch {
3929
- return null;
3930
- }
3931
- })(),
3932
- (async () => {
3933
- if (typeof input.client.listMyNotifications !== "function") return null;
3934
- try {
3935
- const res = await input.client.listMyNotifications({
3936
- ...queryBase,
3937
- limit: 1
3938
- });
3939
- return Array.isArray(res?.items) && res.items.length > 0 || Number(res?.unread_count || 0) > 0 ? "notifications" : null;
3940
- } catch {
3941
- return null;
3942
- }
3943
- })()
3944
- ]);
3945
- return checks.filter((surface) => Boolean(surface));
4274
+ function resolveMarketplaceDefaultAccessState(input) {
4275
+ const resolved = resolveMarketplaceAccessState(input);
4276
+ if (resolved && resolved !== "inactive") return resolved;
4277
+ if (input.projection && input.hasCatalogMonetization === false) {
4278
+ return input.availableLabel;
4279
+ }
4280
+ return resolved;
3946
4281
  }
3947
4282
 
3948
4283
  // src/pages/XappDetailPage.tsx
3949
- import { Fragment as Fragment7, jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
4284
+ import { Fragment as Fragment8, jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
3950
4285
  function useQueryToken7() {
3951
4286
  const loc = useLocation7();
3952
4287
  const qs = new URLSearchParams(loc.search);
@@ -3971,7 +4306,7 @@ function buildRequestsHref(input) {
3971
4306
  if (input.isEmbedded) return `/requests?${s}`;
3972
4307
  return `/marketplace/requests?${s}`;
3973
4308
  }
3974
- function asRecord4(value) {
4309
+ function asRecord6(value) {
3975
4310
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
3976
4311
  return value;
3977
4312
  }
@@ -3984,8 +4319,25 @@ function readBoolean(value, fallback) {
3984
4319
  function readNumber(value) {
3985
4320
  return typeof value === "number" && Number.isFinite(value) ? value : null;
3986
4321
  }
4322
+ function formatDateTime2(value, locale) {
4323
+ const raw = readString4(value);
4324
+ if (!raw) return "";
4325
+ const parsed = new Date(raw);
4326
+ if (Number.isNaN(parsed.getTime())) return raw;
4327
+ try {
4328
+ return parsed.toLocaleString(locale || void 0, {
4329
+ year: "numeric",
4330
+ month: "short",
4331
+ day: "2-digit",
4332
+ hour: "2-digit",
4333
+ minute: "2-digit"
4334
+ });
4335
+ } catch {
4336
+ return parsed.toISOString();
4337
+ }
4338
+ }
3987
4339
  function normalizeUsageCreditSummary(value) {
3988
- const summary = asRecord4(value);
4340
+ const summary = asRecord6(value);
3989
4341
  if (!summary) return null;
3990
4342
  const availableCount = readNumber(summary.available_count) ?? 0;
3991
4343
  const availableSessionBackedCount = readNumber(summary.available_session_backed_count) ?? 0;
@@ -3996,7 +4348,7 @@ function normalizeUsageCreditSummary(value) {
3996
4348
  const consumedCount = readNumber(summary.consumed_count) ?? 0;
3997
4349
  const byToolRaw = Array.isArray(summary.by_tool) ? summary.by_tool : [];
3998
4350
  const byTool = byToolRaw.map((entry) => {
3999
- const record = asRecord4(entry);
4351
+ const record = asRecord6(entry);
4000
4352
  if (!record) return null;
4001
4353
  const toolName = readString4(record.tool_name);
4002
4354
  if (!toolName) return null;
@@ -4030,7 +4382,7 @@ function normalizeUsageCreditSummary(value) {
4030
4382
  }
4031
4383
  function normalizeGuardPolicyKind(policy) {
4032
4384
  if (policy === "all" || policy === "any") return policy;
4033
- const policyObj = asRecord4(policy);
4385
+ const policyObj = asRecord6(policy);
4034
4386
  const mode = readString4(policyObj?.mode);
4035
4387
  return mode === "any" ? "any" : "all";
4036
4388
  }
@@ -4077,6 +4429,7 @@ function XappDetailPage() {
4077
4429
  const updateAppLabel = env?.copy?.updateAppLabel || t("xapp.update_app", void 0, "Update app");
4078
4430
  const openAppLabel = env?.copy?.openAppLabel || t("xapp.open_app", void 0, "Open app");
4079
4431
  const [data, setData] = useState7(null);
4432
+ const [monetization, setMonetization] = useState7(null);
4080
4433
  const [error, setError] = useState7(null);
4081
4434
  const [busy, setBusy] = useState7(true);
4082
4435
  const [discoveredOperationalSurfaces, setDiscoveredOperationalSurfaces] = useState7([]);
@@ -4100,14 +4453,14 @@ function XappDetailPage() {
4100
4453
  const res = await client.getCatalogXapp(String(xappId), {
4101
4454
  installationId: installation?.installationId ?? null
4102
4455
  });
4103
- setData(asRecord4(res));
4456
+ setData(asRecord6(res));
4104
4457
  } catch (e) {
4105
- setError(readString4(asRecord4(e)?.message) || String(e));
4458
+ setError(readString4(asRecord6(e)?.message) || String(e));
4106
4459
  } finally {
4107
4460
  setBusy(false);
4108
4461
  }
4109
4462
  }
4110
- useEffect8(() => {
4463
+ useEffect9(() => {
4111
4464
  void refresh();
4112
4465
  host.refreshInstallations();
4113
4466
  host.notifyNavigation?.({
@@ -4116,7 +4469,7 @@ function XappDetailPage() {
4116
4469
  params: { xappId }
4117
4470
  });
4118
4471
  }, [client, installation?.installationId, xappId]);
4119
- useEffect8(() => {
4472
+ useEffect9(() => {
4120
4473
  const currentXappId = String(xappId ?? "").trim();
4121
4474
  if (!currentXappId) {
4122
4475
  setDiscoveredOperationalSurfaces([]);
@@ -4137,14 +4490,37 @@ function XappDetailPage() {
4137
4490
  cancelled = true;
4138
4491
  };
4139
4492
  }, [client, installation?.installationId, xappId]);
4140
- const manifest = asRecord4(data?.manifest);
4141
- const xappRecord = asRecord4(data?.xapp);
4142
- const versionRecord = asRecord4(data?.version);
4143
- const publisherRecord = asRecord4(xappRecord?.publisher);
4493
+ useEffect9(() => {
4494
+ const currentXappId = String(xappId ?? "").trim();
4495
+ if (!currentXappId || !host.subjectId || typeof client.getMyXappMonetization !== "function") {
4496
+ setMonetization(null);
4497
+ return;
4498
+ }
4499
+ let cancelled = false;
4500
+ void (async () => {
4501
+ try {
4502
+ const next = await client.getMyXappMonetization(currentXappId);
4503
+ if (!cancelled) {
4504
+ setMonetization(next);
4505
+ }
4506
+ } catch {
4507
+ if (!cancelled) {
4508
+ setMonetization(null);
4509
+ }
4510
+ }
4511
+ })();
4512
+ return () => {
4513
+ cancelled = true;
4514
+ };
4515
+ }, [client, host.subjectId, xappId]);
4516
+ const manifest = asRecord6(data?.manifest);
4517
+ const xappRecord = asRecord6(data?.xapp);
4518
+ const versionRecord = asRecord6(data?.version);
4519
+ const publisherRecord = asRecord6(xappRecord?.publisher);
4144
4520
  const title = resolveMarketplaceText(manifest?.title, locale) || readString4(xappRecord?.name) || t("xapp.kicker_default", void 0, "Xapp");
4145
4521
  const description = resolveMarketplaceText(manifest?.description, locale) || readString4(xappRecord?.description) || "";
4146
4522
  const imageUrl = readString4(manifest?.image) || "https://picsum.photos/seed/xapps-detail/840/360";
4147
- const widgets = Array.isArray(data?.widgets) ? data.widgets.filter((widget) => Boolean(asRecord4(widget))) : [];
4523
+ const widgets = Array.isArray(data?.widgets) ? data.widgets.filter((widget) => Boolean(asRecord6(widget))) : [];
4148
4524
  const defaultWidget = useMemo8(() => {
4149
4525
  const def = widgets.find((w) => readBoolean(w.default, false));
4150
4526
  return def || widgets[0] || null;
@@ -4158,13 +4534,13 @@ function XappDetailPage() {
4158
4534
  pathname: isEmbedded ? "/embed/catalog" : "..",
4159
4535
  search: tokenSearch
4160
4536
  };
4161
- const terms = asRecord4(manifest?.terms);
4537
+ const terms = asRecord6(manifest?.terms);
4162
4538
  const termsTitle = resolveMarketplaceText(terms?.title, locale) || t("xapp.terms_title", void 0, "Terms & Conditions");
4163
4539
  const termsText = resolveMarketplaceText(terms?.text, locale) || readString4(terms?.text);
4164
4540
  const termsUrl = readString4(terms?.url);
4165
4541
  const hasTermsContent = Boolean(termsText || termsUrl);
4166
4542
  const requiresTerms = Boolean(terms || action === "install" || action === "update");
4167
- useEffect8(() => {
4543
+ useEffect9(() => {
4168
4544
  if (action === "install") {
4169
4545
  setTermsAccepted(false);
4170
4546
  setTermsAction("install");
@@ -4177,7 +4553,7 @@ function XappDetailPage() {
4177
4553
  setTermsOpen(true);
4178
4554
  }
4179
4555
  }, [action, installation]);
4180
- useEffect8(() => {
4556
+ useEffect9(() => {
4181
4557
  if (action !== "open-widget") return;
4182
4558
  if (env?.embedMode) return;
4183
4559
  if (!installation || !widgetsEnabled) return;
@@ -4250,9 +4626,9 @@ function XappDetailPage() {
4250
4626
  } : null;
4251
4627
  const guardSummary = useMemo8(() => {
4252
4628
  const guardsRaw = Array.isArray(manifest?.guards) ? manifest.guards : [];
4253
- const policyMap = asRecord4(manifest?.guards_policy) ?? {};
4629
+ const policyMap = asRecord6(manifest?.guards_policy) ?? {};
4254
4630
  const items = guardsRaw.map((raw) => {
4255
- const guard = asRecord4(raw);
4631
+ const guard = asRecord6(raw);
4256
4632
  if (!guard) return null;
4257
4633
  const trigger = readString4(guard.trigger);
4258
4634
  const slug = readString4(guard.slug);
@@ -4285,6 +4661,42 @@ function XappDetailPage() {
4285
4661
  () => normalizeUsageCreditSummary(data?.usage_credit_summary),
4286
4662
  [data?.usage_credit_summary]
4287
4663
  );
4664
+ const monetizationAccessProjection = monetization?.access_projection ?? null;
4665
+ const hasCatalogMonetization = hasMarketplaceCatalogMonetization(manifest);
4666
+ const monetizationAccess = asRecord6(monetization?.access_projection);
4667
+ const monetizationSubscription = asRecord6(monetization?.current_subscription);
4668
+ const overduePolicy = asRecord6(monetizationSubscription?.overdue_policy);
4669
+ const currentTier = readString4(monetizationSubscription?.tier) || readString4(monetizationAccess?.tier);
4670
+ const balanceState = readString4(monetizationAccess?.balance_state);
4671
+ const subscriptionStatus = readString4(monetizationSubscription?.status);
4672
+ const subscriptionCoverage = typeof overduePolicy?.has_current_access === "boolean" ? overduePolicy.has_current_access ? t("xapp.subscription_coverage_active", void 0, "Still covered") : t("xapp.subscription_coverage_inactive", void 0, "Not covered") : null;
4673
+ const subscriptionReasonKey = readString4(overduePolicy?.effective_status_reason);
4674
+ const subscriptionReason = subscriptionReasonKey === "grace_covered_past_due" ? t(
4675
+ "xapp.subscription_reason_grace_covered_past_due",
4676
+ void 0,
4677
+ "Coverage remains during grace period"
4678
+ ) : subscriptionReasonKey === "past_due_after_period_end" ? t(
4679
+ "xapp.subscription_reason_past_due_after_period_end",
4680
+ void 0,
4681
+ "Current period ended without successful renewal"
4682
+ ) : subscriptionReasonKey === "expired_after_boundary" ? t(
4683
+ "xapp.subscription_reason_expired_after_boundary",
4684
+ void 0,
4685
+ "Expiry boundary reached"
4686
+ ) : null;
4687
+ const overdueSince = formatDateTime2(overduePolicy?.overdue_since, locale);
4688
+ const expiryBoundaryAt = formatDateTime2(overduePolicy?.expiry_boundary_at, locale);
4689
+ const renewsAt = formatDateTime2(monetizationSubscription?.renews_at, locale);
4690
+ const expiresAt = formatDateTime2(monetizationSubscription?.expired_at, locale) || formatDateTime2(monetizationSubscription?.current_period_ends_at, locale);
4691
+ const creditsRemaining = readString4(monetizationAccess?.credits_remaining);
4692
+ const accessState = resolveMarketplaceDefaultAccessState({
4693
+ projection: monetizationAccessProjection,
4694
+ hasCatalogMonetization,
4695
+ availableLabel: t("xapp.access_state_available", void 0, "available")
4696
+ });
4697
+ const hasMonetizationState = Boolean(
4698
+ currentTier || accessState || subscriptionStatus || subscriptionCoverage || subscriptionReason || overdueSince || expiryBoundaryAt || renewsAt || expiresAt || creditsRemaining
4699
+ );
4288
4700
  const manifestScreenshots = Array.isArray(manifest?.screenshots) ? manifest.screenshots.map((shot) => readString4(shot)).filter(Boolean) : [];
4289
4701
  const manifestTags = Array.isArray(manifest?.tags) ? manifest.tags.map((tag) => readString4(tag)).filter(Boolean) : [];
4290
4702
  return /* @__PURE__ */ jsxs10("div", { className: `mx-detail-container ${isEmbedded ? "is-embedded" : ""}`, children: [
@@ -4319,7 +4731,7 @@ function XappDetailPage() {
4319
4731
  ) })
4320
4732
  ] }),
4321
4733
  error && /* @__PURE__ */ jsx14("div", { className: "mx-detail-error", children: error }),
4322
- busy && !data ? /* @__PURE__ */ jsxs10(Fragment7, { children: [
4734
+ busy && !data ? /* @__PURE__ */ jsxs10(Fragment8, { children: [
4323
4735
  /* @__PURE__ */ jsxs10("div", { className: "mx-detail-skeleton-header", "aria-busy": "true", children: [
4324
4736
  /* @__PURE__ */ jsx14("div", { className: "mx-detail-skeleton-icon" }),
4325
4737
  /* @__PURE__ */ jsxs10("div", { className: "mx-detail-skeleton-info", children: [
@@ -4353,7 +4765,7 @@ function XappDetailPage() {
4353
4765
  /* @__PURE__ */ jsx14("div", { className: "mx-skeleton-line mx-skeleton-line-short" })
4354
4766
  ] }) })
4355
4767
  ] })
4356
- ] }) : /* @__PURE__ */ jsxs10(Fragment7, { children: [
4768
+ ] }) : /* @__PURE__ */ jsxs10(Fragment8, { children: [
4357
4769
  /* @__PURE__ */ jsxs10("header", { className: "mx-detail-header", children: [
4358
4770
  /* @__PURE__ */ jsx14("img", { src: imageUrl, alt: title, className: "mx-detail-icon" }),
4359
4771
  /* @__PURE__ */ jsxs10("div", { className: "mx-detail-info", children: [
@@ -4373,7 +4785,7 @@ function XappDetailPage() {
4373
4785
  updateAvailable ? /* @__PURE__ */ jsx14("div", { className: "mx-detail-update-pill", children: t("xapp.update_available", void 0, "Update available") }) : null
4374
4786
  ] })
4375
4787
  ] }),
4376
- /* @__PURE__ */ jsx14("div", { className: "mx-detail-actions", children: canMutate ? /* @__PURE__ */ jsxs10(Fragment7, { children: [
4788
+ /* @__PURE__ */ jsx14("div", { className: "mx-detail-actions", children: canMutate ? /* @__PURE__ */ jsxs10(Fragment8, { children: [
4377
4789
  installation && updateAvailable && host.requestUpdate ? /* @__PURE__ */ jsx14(
4378
4790
  "button",
4379
4791
  {
@@ -4733,6 +5145,49 @@ function XappDetailPage() {
4733
5145
  ] })
4734
5146
  ] }),
4735
5147
  /* @__PURE__ */ jsxs10("aside", { className: "mx-detail-sidebar", children: [
5148
+ hasMonetizationState ? /* @__PURE__ */ jsxs10("div", { className: "mx-sidebar-card", children: [
5149
+ /* @__PURE__ */ jsx14("h3", { className: "mx-section-title mx-detail-sidebar-title", children: t("xapp.current_access_title", void 0, "Current Access") }),
5150
+ currentTier ? /* @__PURE__ */ jsxs10("div", { className: "mx-meta-item", children: [
5151
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-label", children: t("xapp.current_plan_label", void 0, "Current plan") }),
5152
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-value", children: currentTier })
5153
+ ] }) : null,
5154
+ accessState ? /* @__PURE__ */ jsxs10("div", { className: "mx-meta-item", children: [
5155
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-label", children: t("xapp.access_state_label", void 0, "Access state") }),
5156
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-value", children: accessState })
5157
+ ] }) : null,
5158
+ subscriptionStatus ? /* @__PURE__ */ jsxs10("div", { className: "mx-meta-item", children: [
5159
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-label", children: t("xapp.subscription_status_label", void 0, "Subscription status") }),
5160
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-value", children: subscriptionStatus })
5161
+ ] }) : null,
5162
+ subscriptionCoverage ? /* @__PURE__ */ jsxs10("div", { className: "mx-meta-item", children: [
5163
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-label", children: t("xapp.subscription_coverage_label", void 0, "Coverage") }),
5164
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-value", children: subscriptionCoverage })
5165
+ ] }) : null,
5166
+ subscriptionReason ? /* @__PURE__ */ jsxs10("div", { className: "mx-meta-item mx-meta-item-top", children: [
5167
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-label", children: t("xapp.subscription_reason_label", void 0, "Status reason") }),
5168
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-value", children: subscriptionReason })
5169
+ ] }) : null,
5170
+ overdueSince ? /* @__PURE__ */ jsxs10("div", { className: "mx-meta-item", children: [
5171
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-label", children: t("xapp.subscription_overdue_since_label", void 0, "Overdue since") }),
5172
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-value", children: overdueSince })
5173
+ ] }) : null,
5174
+ expiryBoundaryAt ? /* @__PURE__ */ jsxs10("div", { className: "mx-meta-item", children: [
5175
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-label", children: t("xapp.subscription_expiry_boundary_label", void 0, "Expiry boundary") }),
5176
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-value", children: expiryBoundaryAt })
5177
+ ] }) : null,
5178
+ renewsAt ? /* @__PURE__ */ jsxs10("div", { className: "mx-meta-item", children: [
5179
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-label", children: t("xapp.renews_at_label", void 0, "Renews at") }),
5180
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-value", children: renewsAt })
5181
+ ] }) : null,
5182
+ expiresAt ? /* @__PURE__ */ jsxs10("div", { className: "mx-meta-item", children: [
5183
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-label", children: t("xapp.expires_at_label", void 0, "Expires at") }),
5184
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-value", children: expiresAt })
5185
+ ] }) : null,
5186
+ creditsRemaining ? /* @__PURE__ */ jsxs10("div", { className: "mx-meta-item", children: [
5187
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-label", children: t("xapp.credits_remaining_label", void 0, "Credits remaining") }),
5188
+ /* @__PURE__ */ jsx14("span", { className: "mx-meta-value", children: creditsRemaining })
5189
+ ] }) : null
5190
+ ] }) : null,
4736
5191
  usageCreditSummary ? /* @__PURE__ */ jsxs10("div", { className: "mx-sidebar-card", children: [
4737
5192
  /* @__PURE__ */ jsx14("h3", { className: "mx-section-title mx-detail-sidebar-title", children: t("xapp.usage_credits_title", void 0, "Usage Credits") }),
4738
5193
  /* @__PURE__ */ jsxs10("div", { className: "mx-meta-item", children: [
@@ -5058,9 +5513,9 @@ function XappDetailPage() {
5058
5513
  }
5059
5514
 
5060
5515
  // src/pages/WidgetView.tsx
5061
- import { useEffect as useEffect9, useRef as useRef2, useState as useState8 } from "react";
5516
+ import { useEffect as useEffect10, useRef as useRef2, useState as useState8 } from "react";
5062
5517
  import { Link as Link10, useLocation as useLocation8, useNavigate as useNavigate4, useParams as useParams3 } from "react-router-dom";
5063
- import { Fragment as Fragment8, jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
5518
+ import { Fragment as Fragment9, jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
5064
5519
  function useQueryToken8() {
5065
5520
  const loc = useLocation8();
5066
5521
  const qs = new URLSearchParams(loc.search);
@@ -5131,6 +5586,7 @@ function WidgetView() {
5131
5586
  const [xappDetail, setXappDetail] = useState8(null);
5132
5587
  const [discoveredOperationalSurfaces, setDiscoveredOperationalSurfaces] = useState8([]);
5133
5588
  const [widgetToken, setWidgetToken] = useState8("");
5589
+ const [widgetSessionContext, setWidgetSessionContext] = useState8(null);
5134
5590
  const [error, setError] = useState8(null);
5135
5591
  const [sessionExpired, setSessionExpired] = useState8(null);
5136
5592
  const [hostNestedExpandStage, setHostNestedExpandStage] = useState8("inline");
@@ -5161,7 +5617,7 @@ function WidgetView() {
5161
5617
  page: "portal-home"
5162
5618
  });
5163
5619
  };
5164
- useEffect9(() => {
5620
+ useEffect10(() => {
5165
5621
  if (!installationId) return;
5166
5622
  let alive = true;
5167
5623
  void (async () => {
@@ -5190,7 +5646,7 @@ function WidgetView() {
5190
5646
  alive = false;
5191
5647
  };
5192
5648
  }, [installationId, client, host, locale]);
5193
- useEffect9(() => {
5649
+ useEffect10(() => {
5194
5650
  if (!xappId) {
5195
5651
  setDiscoveredOperationalSurfaces([]);
5196
5652
  return;
@@ -5210,7 +5666,7 @@ function WidgetView() {
5210
5666
  cancelled = true;
5211
5667
  };
5212
5668
  }, [client, installationId, xappId]);
5213
- useEffect9(() => {
5669
+ useEffect10(() => {
5214
5670
  if (!installationId || !widgetId || !host.notifyNavigation) return;
5215
5671
  host.notifyNavigation({
5216
5672
  path: window.location.pathname,
@@ -5218,17 +5674,19 @@ function WidgetView() {
5218
5674
  params: { installationId, widgetId }
5219
5675
  });
5220
5676
  }, [installationId, widgetId, host]);
5221
- useEffect9(() => {
5677
+ useEffect10(() => {
5222
5678
  if (!installationId || !widgetId) return;
5223
5679
  let alive = true;
5224
5680
  void (async () => {
5225
5681
  try {
5226
- const { token: wToken } = await client.getWidgetToken(installationId, widgetId);
5682
+ const { token: wToken, context } = await client.getWidgetToken(installationId, widgetId);
5227
5683
  if (!alive) return;
5228
5684
  setSessionExpired(null);
5229
5685
  setWidgetToken(wToken);
5686
+ setWidgetSessionContext(context ?? null);
5230
5687
  } catch (e) {
5231
5688
  if (!alive) return;
5689
+ setWidgetSessionContext(null);
5232
5690
  setError(readFirstString(asRecord(e).message) || String(e));
5233
5691
  }
5234
5692
  })();
@@ -5247,12 +5705,36 @@ function WidgetView() {
5247
5705
  }
5248
5706
  setSessionExpired(null);
5249
5707
  setWidgetToken(nextToken);
5708
+ setWidgetSessionContext(refreshed?.context ?? null);
5250
5709
  return {
5251
5710
  token: nextToken,
5252
5711
  expires_in: Number.isFinite(Number(refreshed?.expires_in)) && Number(refreshed?.expires_in) > 0 ? Number(refreshed?.expires_in) : void 0
5253
5712
  };
5254
5713
  }
5255
- useEffect9(() => {
5714
+ function buildWidgetBridgeContext() {
5715
+ const context = widgetSessionContext;
5716
+ if (!context || !widgetToken) return null;
5717
+ const matchingWidget = Array.isArray(xappDetail?.widgets) ? xappDetail.widgets.find((item) => String(item?.id || "") === String(widgetId || "")) : null;
5718
+ return {
5719
+ type: "XAPPS_WIDGET_CONTEXT",
5720
+ token: widgetToken,
5721
+ baseUrl: window.location.origin,
5722
+ hostOrigin: window.location.origin,
5723
+ installationId: context.installationId || String(installationId || ""),
5724
+ clientId: context.clientId,
5725
+ xappId: context.xappId || xappId,
5726
+ subjectId: context.subjectId,
5727
+ publisherUserId: null,
5728
+ email: null,
5729
+ bindToolName: readFirstString(
5730
+ asRecord(matchingWidget).bind_tool_name,
5731
+ asRecord(matchingWidget).bindToolName
5732
+ ) || null,
5733
+ theme: host.theme || null,
5734
+ locale: context.locale || env?.locale || host.locale || null
5735
+ };
5736
+ }
5737
+ useEffect10(() => {
5256
5738
  return () => {
5257
5739
  for (const [, pending] of nestedExpandPendingRef.current) {
5258
5740
  window.clearTimeout(pending.timeoutId);
@@ -5262,7 +5744,7 @@ function WidgetView() {
5262
5744
  nestedExpandPendingRef.current.clear();
5263
5745
  };
5264
5746
  }, []);
5265
- useEffect9(() => {
5747
+ useEffect10(() => {
5266
5748
  const shell = shellRef.current;
5267
5749
  const rootEl = shell?.parentElement ?? null;
5268
5750
  const htmlEl = document.documentElement;
@@ -5295,7 +5777,7 @@ function WidgetView() {
5295
5777
  }
5296
5778
  };
5297
5779
  }, [env?.embedMode, hostNestedExpandStage]);
5298
- useEffect9(() => {
5780
+ useEffect10(() => {
5299
5781
  if (!env?.embedMode) return;
5300
5782
  const handler = (e) => {
5301
5783
  if (e.source !== window.parent) return;
@@ -5311,7 +5793,7 @@ function WidgetView() {
5311
5793
  window.addEventListener("message", handler);
5312
5794
  return () => window.removeEventListener("message", handler);
5313
5795
  }, [env?.embedMode]);
5314
- useEffect9(() => {
5796
+ useEffect10(() => {
5315
5797
  const handler = (e) => {
5316
5798
  const msg = asRecord(e.data);
5317
5799
  const msgType = readString(msg.type);
@@ -5345,7 +5827,7 @@ function WidgetView() {
5345
5827
  window.addEventListener("message", handler);
5346
5828
  return () => window.removeEventListener("message", handler);
5347
5829
  }, []);
5348
- useEffect9(() => {
5830
+ useEffect10(() => {
5349
5831
  if (!widgetToken) return;
5350
5832
  const postExpandResultToWidget = (target, result) => {
5351
5833
  if (!target || typeof target.postMessage !== "function") return;
@@ -5535,8 +6017,9 @@ function WidgetView() {
5535
6017
  }
5536
6018
  if ((msgType === "XAPPS_WIDGET_CONTEXT_REQUEST" || msgType === "XAPPS_WIDGET_READY") && e.source === iframeRef.current?.contentWindow) {
5537
6019
  try {
6020
+ const payload = buildWidgetBridgeContext();
5538
6021
  e.source?.postMessage(
5539
- {
6022
+ payload || {
5540
6023
  type: "XAPPS_WIDGET_CONTEXT",
5541
6024
  locale: env?.locale || null
5542
6025
  },
@@ -5610,9 +6093,14 @@ function WidgetView() {
5610
6093
  return () => window.removeEventListener("message", handler);
5611
6094
  }, [
5612
6095
  widgetToken,
6096
+ widgetSessionContext,
5613
6097
  installationId,
5614
6098
  widgetId,
6099
+ xappDetail,
6100
+ host,
6101
+ xappId,
5615
6102
  env?.embedMode,
6103
+ env?.locale,
5616
6104
  navigate,
5617
6105
  isEmbedded,
5618
6106
  tokenSearch,
@@ -5620,7 +6108,7 @@ function WidgetView() {
5620
6108
  xappId,
5621
6109
  t
5622
6110
  ]);
5623
- useEffect9(() => {
6111
+ useEffect10(() => {
5624
6112
  if (!widgetToken || !env?.locale) return;
5625
6113
  try {
5626
6114
  iframeRef.current?.contentWindow?.postMessage(
@@ -5638,6 +6126,11 @@ function WidgetView() {
5638
6126
  const params = new URLSearchParams({ token: widgetToken });
5639
6127
  const hostReturnUrl = readHostReturnUrl(loc.search);
5640
6128
  if (hostReturnUrl) params.set("xapps_host_return_url", hostReturnUrl);
6129
+ if (env?.embedMode && hostNestedExpandStage !== "inline") {
6130
+ params.set("xapps_host_overlay", "1");
6131
+ } else {
6132
+ params.delete("xapps_host_overlay");
6133
+ }
5641
6134
  const paymentParams = readPaymentEvidenceParams(loc.search);
5642
6135
  for (const [k, v] of paymentParams.entries()) {
5643
6136
  params.set(k, v);
@@ -5648,7 +6141,7 @@ function WidgetView() {
5648
6141
  return /* @__PURE__ */ jsxs11("div", { className: `mx-catalog-container ${isEmbedded ? "is-embedded" : ""}`, children: [
5649
6142
  /* @__PURE__ */ jsxs11("div", { className: "mx-breadcrumb", children: [
5650
6143
  /* @__PURE__ */ jsx15("button", { className: "mx-breadcrumb-link-btn", onClick: onBackToPortal, children: t("common.portal", void 0, "Portal") }),
5651
- !env?.singleXappMode && /* @__PURE__ */ jsxs11(Fragment8, { children: [
6144
+ !env?.singleXappMode && /* @__PURE__ */ jsxs11(Fragment9, { children: [
5652
6145
  /* @__PURE__ */ jsx15("span", { className: "mx-breadcrumb-sep", children: "/" }),
5653
6146
  /* @__PURE__ */ jsx15(Link10, { to: marketplaceTo, children: t("common.marketplace", void 0, "Marketplace") })
5654
6147
  ] }),
@@ -5669,7 +6162,7 @@ function WidgetView() {
5669
6162
  return /* @__PURE__ */ jsxs11("div", { className: `mx-catalog-container ${isEmbedded ? "is-embedded" : ""}`, children: [
5670
6163
  /* @__PURE__ */ jsxs11("div", { className: "mx-breadcrumb", children: [
5671
6164
  /* @__PURE__ */ jsx15("button", { className: "mx-breadcrumb-link-btn", onClick: onBackToPortal, children: t("common.portal", void 0, "Portal") }),
5672
- !env?.singleXappMode && /* @__PURE__ */ jsxs11(Fragment8, { children: [
6165
+ !env?.singleXappMode && /* @__PURE__ */ jsxs11(Fragment9, { children: [
5673
6166
  /* @__PURE__ */ jsx15("span", { className: "mx-breadcrumb-sep", children: "/" }),
5674
6167
  /* @__PURE__ */ jsx15(Link10, { to: marketplaceTo, children: t("common.marketplace", void 0, "Marketplace") })
5675
6168
  ] }),
@@ -5690,7 +6183,7 @@ function WidgetView() {
5690
6183
  return /* @__PURE__ */ jsxs11("div", { className: `mx-catalog-container ${isEmbedded ? "is-embedded" : ""}`, children: [
5691
6184
  /* @__PURE__ */ jsxs11("div", { className: "mx-breadcrumb", children: [
5692
6185
  /* @__PURE__ */ jsx15("button", { className: "mx-breadcrumb-link-btn", onClick: onBackToPortal, children: t("common.portal", void 0, "Portal") }),
5693
- !env?.singleXappMode && /* @__PURE__ */ jsxs11(Fragment8, { children: [
6186
+ !env?.singleXappMode && /* @__PURE__ */ jsxs11(Fragment9, { children: [
5694
6187
  /* @__PURE__ */ jsx15("span", { className: "mx-breadcrumb-sep", children: "/" }),
5695
6188
  /* @__PURE__ */ jsx15(Link10, { to: marketplaceTo, children: t("common.marketplace", void 0, "Marketplace") })
5696
6189
  ] }),
@@ -5723,11 +6216,11 @@ function WidgetView() {
5723
6216
  children: [
5724
6217
  env?.embedMode && hostNestedExpandStage === "inline" && /* @__PURE__ */ jsxs11("div", { className: "mx-breadcrumb mx-breadcrumb-top", children: [
5725
6218
  /* @__PURE__ */ jsx15("button", { className: "mx-breadcrumb-link-btn", onClick: onBackToPortal, children: t("common.portal", void 0, "Portal") }),
5726
- !env?.singleXappMode && /* @__PURE__ */ jsxs11(Fragment8, { children: [
6219
+ !env?.singleXappMode && /* @__PURE__ */ jsxs11(Fragment9, { children: [
5727
6220
  /* @__PURE__ */ jsx15("span", { className: "mx-breadcrumb-sep", children: "/" }),
5728
6221
  /* @__PURE__ */ jsx15(Link10, { to: marketplaceTo, children: t("common.marketplace", void 0, "Marketplace") })
5729
6222
  ] }),
5730
- xappTo && /* @__PURE__ */ jsxs11(Fragment8, { children: [
6223
+ xappTo && /* @__PURE__ */ jsxs11(Fragment9, { children: [
5731
6224
  /* @__PURE__ */ jsx15("span", { className: "mx-breadcrumb-sep", children: "/" }),
5732
6225
  /* @__PURE__ */ jsx15(Link10, { to: xappTo, children: xappTitle || t("common.app", void 0, "App") })
5733
6226
  ] }),
@@ -5736,7 +6229,7 @@ function WidgetView() {
5736
6229
  ] }),
5737
6230
  !env?.embedMode && hostNestedExpandStage === "inline" && /* @__PURE__ */ jsxs11("div", { className: "mx-breadcrumb", children: [
5738
6231
  /* @__PURE__ */ jsx15(Link10, { to: marketplaceTo, children: t("common.marketplace", void 0, "Marketplace") }),
5739
- xappTo && /* @__PURE__ */ jsxs11(Fragment8, { children: [
6232
+ xappTo && /* @__PURE__ */ jsxs11(Fragment9, { children: [
5740
6233
  /* @__PURE__ */ jsx15("span", { className: "mx-breadcrumb-sep", children: "/" }),
5741
6234
  /* @__PURE__ */ jsx15(Link10, { to: xappTo, children: xappTitle || t("common.app", void 0, "App") })
5742
6235
  ] }),
@@ -5787,9 +6280,9 @@ function WidgetView() {
5787
6280
  }
5788
6281
 
5789
6282
  // src/pages/PublishersPage.tsx
5790
- import { useEffect as useEffect10, useMemo as useMemo9, useState as useState9 } from "react";
6283
+ import { useEffect as useEffect11, useMemo as useMemo9, useState as useState9 } from "react";
5791
6284
  import { Link as Link11, useLocation as useLocation9 } from "react-router-dom";
5792
- import { Fragment as Fragment9, jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
6285
+ import { Fragment as Fragment10, jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
5793
6286
  function useQueryToken9() {
5794
6287
  const loc = useLocation9();
5795
6288
  const qs = new URLSearchParams(loc.search);
@@ -5847,7 +6340,7 @@ function PublishersPage() {
5847
6340
  }
5848
6341
  setItems(Array.from(grouped.values()).sort((a, b) => a.name.localeCompare(b.name)));
5849
6342
  }
5850
- useEffect10(() => {
6343
+ useEffect11(() => {
5851
6344
  void (async () => {
5852
6345
  setBusy(true);
5853
6346
  setError(null);
@@ -5965,7 +6458,7 @@ function PublishersPage() {
5965
6458
  /* @__PURE__ */ jsx16("div", { className: "mx-skeleton-line mx-skeleton-line-title" }),
5966
6459
  /* @__PURE__ */ jsx16("div", { className: "mx-skeleton-line mx-skeleton-line-short" })
5967
6460
  ] })
5968
- ] }) }) }, i)) }) : /* @__PURE__ */ jsxs12(Fragment9, { children: [
6461
+ ] }) }) }, i)) }) : /* @__PURE__ */ jsxs12(Fragment10, { children: [
5969
6462
  !busy && /* @__PURE__ */ jsx16("div", { className: "mx-results-bar", children: /* @__PURE__ */ jsx16("div", { className: "mx-results-count", children: t(
5970
6463
  "publisher.results_count",
5971
6464
  { count: ordered.length, suffix: ordered.length === 1 ? "" : "s" },
@@ -6042,9 +6535,9 @@ function PublishersPage() {
6042
6535
  }
6043
6536
 
6044
6537
  // src/pages/PublisherDetailPage.tsx
6045
- import { useEffect as useEffect11, useMemo as useMemo10, useState as useState10 } from "react";
6538
+ import { useEffect as useEffect12, useMemo as useMemo10, useState as useState10 } from "react";
6046
6539
  import { Link as Link12, useLocation as useLocation10, useParams as useParams4 } from "react-router-dom";
6047
- import { Fragment as Fragment10, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
6540
+ import { Fragment as Fragment11, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
6048
6541
  function useQueryToken10() {
6049
6542
  const loc = useLocation10();
6050
6543
  const qs = new URLSearchParams(loc.search);
@@ -6083,7 +6576,7 @@ function PublisherDetailPage() {
6083
6576
  setBusy(false);
6084
6577
  }
6085
6578
  }
6086
- useEffect11(() => {
6579
+ useEffect12(() => {
6087
6580
  void refresh();
6088
6581
  }, [publisherSlug]);
6089
6582
  const publisherName = useMemo10(() => {
@@ -6174,7 +6667,7 @@ function PublisherDetailPage() {
6174
6667
  /* @__PURE__ */ jsx17("div", { className: "mx-skeleton-line mx-skeleton-line-full" }),
6175
6668
  /* @__PURE__ */ jsx17("div", { className: "mx-skeleton-line mx-skeleton-line-short" })
6176
6669
  ] })
6177
- ] }, i)) }) : /* @__PURE__ */ jsxs13(Fragment10, { children: [
6670
+ ] }, i)) }) : /* @__PURE__ */ jsxs13(Fragment11, { children: [
6178
6671
  !busy && /* @__PURE__ */ jsx17("div", { className: "mx-results-bar", children: /* @__PURE__ */ jsx17("div", { className: "mx-results-count", children: filteredItems.length === items.length ? `${filteredItems.length} xapp${filteredItems.length === 1 ? "" : "s"}` : `${filteredItems.length} of ${items.length} xapp${items.length === 1 ? "" : "s"}` }) }),
6179
6672
  /* @__PURE__ */ jsx17("div", { className: "mx-grid", children: filteredItems.length === 0 && !busy ? /* @__PURE__ */ jsxs13("div", { className: "mx-empty-catalog", children: [
6180
6673
  /* @__PURE__ */ jsx17("div", { className: "mx-empty-catalog-icon", children: "\u2315" }),