@xapps-platform/marketplace-ui 0.1.6 → 0.1.8
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/i18n.d.ts.map +1 -1
- package/dist/index.js +317 -19
- package/dist/index.js.map +4 -4
- package/dist/pages/RequestDetailPage.d.ts.map +1 -1
- package/dist/pages/RequestsPage.d.ts.map +1 -1
- package/dist/pages/WidgetView.d.ts.map +1 -1
- package/dist/pages/XappDetailPage.d.ts.map +1 -1
- package/dist/pages/XappDetailPage.monetization.test.d.ts +2 -0
- package/dist/pages/XappDetailPage.monetization.test.d.ts.map +1 -0
- package/dist/types.d.ts +50 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/guardMonetization.d.ts +7 -0
- package/dist/utils/guardMonetization.d.ts.map +1 -0
- package/dist/utils/guardMonetization.test.d.ts +2 -0
- package/dist/utils/guardMonetization.test.d.ts.map +1 -0
- package/dist/utils/monetizationAccess.d.ts +14 -0
- package/dist/utils/monetizationAccess.d.ts.map +1 -0
- package/package.json +2 -2
package/dist/i18n.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,aAAa,EAAW,MAAM,+BAA+B,CAAC;AAC1F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,aAAa,EAAW,MAAM,+BAA+B,CAAC;AAC1F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAmlBvC,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,2CAMtF;AAED,wBAAgB,kBAAkB;;;;;;;EAEjC;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAmC3F"}
|
package/dist/index.js
CHANGED
|
@@ -261,6 +261,8 @@ var MARKETPLACE_CATALOGS = {
|
|
|
261
261
|
"activity.guard_badge": "guard: {value}",
|
|
262
262
|
"activity.trigger_badge": "trigger: {value}",
|
|
263
263
|
"activity.outcome_badge": "outcome: {value}",
|
|
264
|
+
"activity.current_access_badge": "access: {value}",
|
|
265
|
+
"activity.current_access_detail": "Current access: {value}",
|
|
264
266
|
"activity.reason_detail": "reason={value}",
|
|
265
267
|
"activity.guard_action_upgrade_subscription": "Upgrade subscription{suffix}",
|
|
266
268
|
"activity.guard_action_complete_payment": "Complete payment{suffix}",
|
|
@@ -317,6 +319,23 @@ var MARKETPLACE_CATALOGS = {
|
|
|
317
319
|
"xapp.screenshots_title": "Screenshots",
|
|
318
320
|
"xapp.screenshot_alt": "Screenshot {index}",
|
|
319
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",
|
|
320
339
|
"xapp.available_label": "Available",
|
|
321
340
|
"xapp.ready_to_use": "{count} ready to use",
|
|
322
341
|
"xapp.source_label": "Source",
|
|
@@ -518,6 +537,8 @@ var MARKETPLACE_CATALOGS = {
|
|
|
518
537
|
"activity.guard_badge": "gard\u0103: {value}",
|
|
519
538
|
"activity.trigger_badge": "declan\u0219ator: {value}",
|
|
520
539
|
"activity.outcome_badge": "rezultat: {value}",
|
|
540
|
+
"activity.current_access_badge": "acces: {value}",
|
|
541
|
+
"activity.current_access_detail": "Acces curent: {value}",
|
|
521
542
|
"activity.reason_detail": "motiv={value}",
|
|
522
543
|
"activity.guard_action_upgrade_subscription": "Actualizeaz\u0103 abonamentul{suffix}",
|
|
523
544
|
"activity.guard_action_complete_payment": "Finalizeaz\u0103 plata{suffix}",
|
|
@@ -574,6 +595,23 @@ var MARKETPLACE_CATALOGS = {
|
|
|
574
595
|
"xapp.screenshots_title": "Capturi de ecran",
|
|
575
596
|
"xapp.screenshot_alt": "Captur\u0103 de ecran {index}",
|
|
576
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",
|
|
577
615
|
"xapp.available_label": "Disponibile",
|
|
578
616
|
"xapp.ready_to_use": "{count} gata de utilizare",
|
|
579
617
|
"xapp.source_label": "Surs\u0103",
|
|
@@ -2824,6 +2862,35 @@ function resolvePaymentLockStateFromGuardSummary(summaryInput, options) {
|
|
|
2824
2862
|
};
|
|
2825
2863
|
}
|
|
2826
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
|
+
|
|
2827
2894
|
// src/utils/operationalSurfaces.ts
|
|
2828
2895
|
function readPathEmbedded() {
|
|
2829
2896
|
return typeof window !== "undefined" && window.location.pathname.startsWith("/embed");
|
|
@@ -3145,6 +3212,13 @@ function RequestDetailPage() {
|
|
|
3145
3212
|
);
|
|
3146
3213
|
const isPaymentPending = String(status || "").trim().toUpperCase() === "PAYMENT_PENDING";
|
|
3147
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
|
+
);
|
|
3148
3222
|
const eventPaymentSessionId = useMemo6(() => {
|
|
3149
3223
|
const events = Array.isArray(dataRecord.events) ? dataRecord.events : [];
|
|
3150
3224
|
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
@@ -3364,7 +3438,7 @@ function RequestDetailPage() {
|
|
|
3364
3438
|
).trim();
|
|
3365
3439
|
const res = await client.reconcileMyRequestPayment({
|
|
3366
3440
|
requestId: String(id),
|
|
3367
|
-
paymentSessionId: effectivePaymentSessionId || void 0,
|
|
3441
|
+
paymentSessionId: isPaymentPending ? void 0 : effectivePaymentSessionId || void 0,
|
|
3368
3442
|
returnUrl: currentReturnUrl || void 0,
|
|
3369
3443
|
cancelUrl: currentReturnUrl || void 0
|
|
3370
3444
|
});
|
|
@@ -3504,6 +3578,11 @@ function RequestDetailPage() {
|
|
|
3504
3578
|
void 0,
|
|
3505
3579
|
"Waiting for payment confirmation\u2026"
|
|
3506
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,
|
|
3507
3586
|
/* @__PURE__ */ jsxs8("div", { className: "mx-payment-lock-actions", children: [
|
|
3508
3587
|
isPaymentPending || effectivePaymentSessionId || directPaymentUrl || paymentSurfaceHref ? /* @__PURE__ */ jsx12(
|
|
3509
3588
|
"button",
|
|
@@ -3629,6 +3708,18 @@ function RequestDetailPage() {
|
|
|
3629
3708
|
const progress = typeof eventRecord.progress === "number" ? eventRecord.progress : null;
|
|
3630
3709
|
const guardSummary = extractGuardSummary(ev) ?? extractGuardSummary(getEventPayload(ev)) ?? extractGuardSummary(eventRecord.payload);
|
|
3631
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
|
+
);
|
|
3632
3723
|
return /* @__PURE__ */ jsxs8(
|
|
3633
3724
|
"li",
|
|
3634
3725
|
{
|
|
@@ -3713,6 +3804,11 @@ function RequestDetailPage() {
|
|
|
3713
3804
|
"activity.outcome_badge",
|
|
3714
3805
|
{ value: guardSummary.outcome },
|
|
3715
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}"
|
|
3716
3812
|
) })
|
|
3717
3813
|
] }),
|
|
3718
3814
|
(guardSummary.reason || guardActionLabel) && /* @__PURE__ */ jsxs8("div", { className: "mx-event-guard-detail", children: [
|
|
@@ -4053,7 +4149,11 @@ function RequestsPage() {
|
|
|
4053
4149
|
const guardReason = readString(guardSummary.reason);
|
|
4054
4150
|
const guardOutcome = readString(guardSummary.outcome);
|
|
4055
4151
|
const guardActionHint = renderGuardActionHint(guardSummary);
|
|
4056
|
-
const
|
|
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);
|
|
4057
4157
|
return /* @__PURE__ */ jsxs9("tr", { children: [
|
|
4058
4158
|
/* @__PURE__ */ jsx13("td", { className: "mx-cell-id", "data-label": t("common.id", void 0, "ID"), children: /* @__PURE__ */ jsxs9(Link8, { to: href, children: [
|
|
4059
4159
|
readFirstString(request.id).slice(0, 8),
|
|
@@ -4070,7 +4170,12 @@ function RequestsPage() {
|
|
|
4070
4170
|
(guardSlug || guardOutcome) && guardReason ? " \xB7 " : "",
|
|
4071
4171
|
guardReason ? `reason=${guardReason}` : ""
|
|
4072
4172
|
] }),
|
|
4073
|
-
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
|
+
) })
|
|
4074
4179
|
] })
|
|
4075
4180
|
] }),
|
|
4076
4181
|
/* @__PURE__ */ jsx13(
|
|
@@ -4136,6 +4241,46 @@ function RequestsPage() {
|
|
|
4136
4241
|
// src/pages/XappDetailPage.tsx
|
|
4137
4242
|
import { useEffect as useEffect9, useMemo as useMemo8, useRef, useState as useState7 } from "react";
|
|
4138
4243
|
import { Link as Link9, useLocation as useLocation7, useNavigate as useNavigate3, useParams as useParams2 } from "react-router-dom";
|
|
4244
|
+
|
|
4245
|
+
// src/utils/monetizationAccess.ts
|
|
4246
|
+
function asRecord5(value) {
|
|
4247
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
4248
|
+
return value;
|
|
4249
|
+
}
|
|
4250
|
+
function readCurrentAccessFlag(value) {
|
|
4251
|
+
return typeof value === "boolean" ? value : false;
|
|
4252
|
+
}
|
|
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;
|
|
4260
|
+
});
|
|
4261
|
+
}
|
|
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";
|
|
4268
|
+
}
|
|
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;
|
|
4273
|
+
}
|
|
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;
|
|
4281
|
+
}
|
|
4282
|
+
|
|
4283
|
+
// src/pages/XappDetailPage.tsx
|
|
4139
4284
|
import { Fragment as Fragment8, jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4140
4285
|
function useQueryToken7() {
|
|
4141
4286
|
const loc = useLocation7();
|
|
@@ -4161,7 +4306,7 @@ function buildRequestsHref(input) {
|
|
|
4161
4306
|
if (input.isEmbedded) return `/requests?${s}`;
|
|
4162
4307
|
return `/marketplace/requests?${s}`;
|
|
4163
4308
|
}
|
|
4164
|
-
function
|
|
4309
|
+
function asRecord6(value) {
|
|
4165
4310
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
4166
4311
|
return value;
|
|
4167
4312
|
}
|
|
@@ -4174,8 +4319,25 @@ function readBoolean(value, fallback) {
|
|
|
4174
4319
|
function readNumber(value) {
|
|
4175
4320
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
4176
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
|
+
}
|
|
4177
4339
|
function normalizeUsageCreditSummary(value) {
|
|
4178
|
-
const summary =
|
|
4340
|
+
const summary = asRecord6(value);
|
|
4179
4341
|
if (!summary) return null;
|
|
4180
4342
|
const availableCount = readNumber(summary.available_count) ?? 0;
|
|
4181
4343
|
const availableSessionBackedCount = readNumber(summary.available_session_backed_count) ?? 0;
|
|
@@ -4186,7 +4348,7 @@ function normalizeUsageCreditSummary(value) {
|
|
|
4186
4348
|
const consumedCount = readNumber(summary.consumed_count) ?? 0;
|
|
4187
4349
|
const byToolRaw = Array.isArray(summary.by_tool) ? summary.by_tool : [];
|
|
4188
4350
|
const byTool = byToolRaw.map((entry) => {
|
|
4189
|
-
const record =
|
|
4351
|
+
const record = asRecord6(entry);
|
|
4190
4352
|
if (!record) return null;
|
|
4191
4353
|
const toolName = readString4(record.tool_name);
|
|
4192
4354
|
if (!toolName) return null;
|
|
@@ -4220,7 +4382,7 @@ function normalizeUsageCreditSummary(value) {
|
|
|
4220
4382
|
}
|
|
4221
4383
|
function normalizeGuardPolicyKind(policy) {
|
|
4222
4384
|
if (policy === "all" || policy === "any") return policy;
|
|
4223
|
-
const policyObj =
|
|
4385
|
+
const policyObj = asRecord6(policy);
|
|
4224
4386
|
const mode = readString4(policyObj?.mode);
|
|
4225
4387
|
return mode === "any" ? "any" : "all";
|
|
4226
4388
|
}
|
|
@@ -4267,6 +4429,7 @@ function XappDetailPage() {
|
|
|
4267
4429
|
const updateAppLabel = env?.copy?.updateAppLabel || t("xapp.update_app", void 0, "Update app");
|
|
4268
4430
|
const openAppLabel = env?.copy?.openAppLabel || t("xapp.open_app", void 0, "Open app");
|
|
4269
4431
|
const [data, setData] = useState7(null);
|
|
4432
|
+
const [monetization, setMonetization] = useState7(null);
|
|
4270
4433
|
const [error, setError] = useState7(null);
|
|
4271
4434
|
const [busy, setBusy] = useState7(true);
|
|
4272
4435
|
const [discoveredOperationalSurfaces, setDiscoveredOperationalSurfaces] = useState7([]);
|
|
@@ -4290,9 +4453,9 @@ function XappDetailPage() {
|
|
|
4290
4453
|
const res = await client.getCatalogXapp(String(xappId), {
|
|
4291
4454
|
installationId: installation?.installationId ?? null
|
|
4292
4455
|
});
|
|
4293
|
-
setData(
|
|
4456
|
+
setData(asRecord6(res));
|
|
4294
4457
|
} catch (e) {
|
|
4295
|
-
setError(readString4(
|
|
4458
|
+
setError(readString4(asRecord6(e)?.message) || String(e));
|
|
4296
4459
|
} finally {
|
|
4297
4460
|
setBusy(false);
|
|
4298
4461
|
}
|
|
@@ -4327,14 +4490,37 @@ function XappDetailPage() {
|
|
|
4327
4490
|
cancelled = true;
|
|
4328
4491
|
};
|
|
4329
4492
|
}, [client, installation?.installationId, xappId]);
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
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);
|
|
4334
4520
|
const title = resolveMarketplaceText(manifest?.title, locale) || readString4(xappRecord?.name) || t("xapp.kicker_default", void 0, "Xapp");
|
|
4335
4521
|
const description = resolveMarketplaceText(manifest?.description, locale) || readString4(xappRecord?.description) || "";
|
|
4336
4522
|
const imageUrl = readString4(manifest?.image) || "https://picsum.photos/seed/xapps-detail/840/360";
|
|
4337
|
-
const widgets = Array.isArray(data?.widgets) ? data.widgets.filter((widget) => Boolean(
|
|
4523
|
+
const widgets = Array.isArray(data?.widgets) ? data.widgets.filter((widget) => Boolean(asRecord6(widget))) : [];
|
|
4338
4524
|
const defaultWidget = useMemo8(() => {
|
|
4339
4525
|
const def = widgets.find((w) => readBoolean(w.default, false));
|
|
4340
4526
|
return def || widgets[0] || null;
|
|
@@ -4348,7 +4534,7 @@ function XappDetailPage() {
|
|
|
4348
4534
|
pathname: isEmbedded ? "/embed/catalog" : "..",
|
|
4349
4535
|
search: tokenSearch
|
|
4350
4536
|
};
|
|
4351
|
-
const terms =
|
|
4537
|
+
const terms = asRecord6(manifest?.terms);
|
|
4352
4538
|
const termsTitle = resolveMarketplaceText(terms?.title, locale) || t("xapp.terms_title", void 0, "Terms & Conditions");
|
|
4353
4539
|
const termsText = resolveMarketplaceText(terms?.text, locale) || readString4(terms?.text);
|
|
4354
4540
|
const termsUrl = readString4(terms?.url);
|
|
@@ -4440,9 +4626,9 @@ function XappDetailPage() {
|
|
|
4440
4626
|
} : null;
|
|
4441
4627
|
const guardSummary = useMemo8(() => {
|
|
4442
4628
|
const guardsRaw = Array.isArray(manifest?.guards) ? manifest.guards : [];
|
|
4443
|
-
const policyMap =
|
|
4629
|
+
const policyMap = asRecord6(manifest?.guards_policy) ?? {};
|
|
4444
4630
|
const items = guardsRaw.map((raw) => {
|
|
4445
|
-
const guard =
|
|
4631
|
+
const guard = asRecord6(raw);
|
|
4446
4632
|
if (!guard) return null;
|
|
4447
4633
|
const trigger = readString4(guard.trigger);
|
|
4448
4634
|
const slug = readString4(guard.slug);
|
|
@@ -4475,6 +4661,42 @@ function XappDetailPage() {
|
|
|
4475
4661
|
() => normalizeUsageCreditSummary(data?.usage_credit_summary),
|
|
4476
4662
|
[data?.usage_credit_summary]
|
|
4477
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
|
+
);
|
|
4478
4700
|
const manifestScreenshots = Array.isArray(manifest?.screenshots) ? manifest.screenshots.map((shot) => readString4(shot)).filter(Boolean) : [];
|
|
4479
4701
|
const manifestTags = Array.isArray(manifest?.tags) ? manifest.tags.map((tag) => readString4(tag)).filter(Boolean) : [];
|
|
4480
4702
|
return /* @__PURE__ */ jsxs10("div", { className: `mx-detail-container ${isEmbedded ? "is-embedded" : ""}`, children: [
|
|
@@ -4923,6 +5145,49 @@ function XappDetailPage() {
|
|
|
4923
5145
|
] })
|
|
4924
5146
|
] }),
|
|
4925
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,
|
|
4926
5191
|
usageCreditSummary ? /* @__PURE__ */ jsxs10("div", { className: "mx-sidebar-card", children: [
|
|
4927
5192
|
/* @__PURE__ */ jsx14("h3", { className: "mx-section-title mx-detail-sidebar-title", children: t("xapp.usage_credits_title", void 0, "Usage Credits") }),
|
|
4928
5193
|
/* @__PURE__ */ jsxs10("div", { className: "mx-meta-item", children: [
|
|
@@ -5321,6 +5586,7 @@ function WidgetView() {
|
|
|
5321
5586
|
const [xappDetail, setXappDetail] = useState8(null);
|
|
5322
5587
|
const [discoveredOperationalSurfaces, setDiscoveredOperationalSurfaces] = useState8([]);
|
|
5323
5588
|
const [widgetToken, setWidgetToken] = useState8("");
|
|
5589
|
+
const [widgetSessionContext, setWidgetSessionContext] = useState8(null);
|
|
5324
5590
|
const [error, setError] = useState8(null);
|
|
5325
5591
|
const [sessionExpired, setSessionExpired] = useState8(null);
|
|
5326
5592
|
const [hostNestedExpandStage, setHostNestedExpandStage] = useState8("inline");
|
|
@@ -5413,12 +5679,14 @@ function WidgetView() {
|
|
|
5413
5679
|
let alive = true;
|
|
5414
5680
|
void (async () => {
|
|
5415
5681
|
try {
|
|
5416
|
-
const { token: wToken } = await client.getWidgetToken(installationId, widgetId);
|
|
5682
|
+
const { token: wToken, context } = await client.getWidgetToken(installationId, widgetId);
|
|
5417
5683
|
if (!alive) return;
|
|
5418
5684
|
setSessionExpired(null);
|
|
5419
5685
|
setWidgetToken(wToken);
|
|
5686
|
+
setWidgetSessionContext(context ?? null);
|
|
5420
5687
|
} catch (e) {
|
|
5421
5688
|
if (!alive) return;
|
|
5689
|
+
setWidgetSessionContext(null);
|
|
5422
5690
|
setError(readFirstString(asRecord(e).message) || String(e));
|
|
5423
5691
|
}
|
|
5424
5692
|
})();
|
|
@@ -5437,11 +5705,35 @@ function WidgetView() {
|
|
|
5437
5705
|
}
|
|
5438
5706
|
setSessionExpired(null);
|
|
5439
5707
|
setWidgetToken(nextToken);
|
|
5708
|
+
setWidgetSessionContext(refreshed?.context ?? null);
|
|
5440
5709
|
return {
|
|
5441
5710
|
token: nextToken,
|
|
5442
5711
|
expires_in: Number.isFinite(Number(refreshed?.expires_in)) && Number(refreshed?.expires_in) > 0 ? Number(refreshed?.expires_in) : void 0
|
|
5443
5712
|
};
|
|
5444
5713
|
}
|
|
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
|
+
}
|
|
5445
5737
|
useEffect10(() => {
|
|
5446
5738
|
return () => {
|
|
5447
5739
|
for (const [, pending] of nestedExpandPendingRef.current) {
|
|
@@ -5725,8 +6017,9 @@ function WidgetView() {
|
|
|
5725
6017
|
}
|
|
5726
6018
|
if ((msgType === "XAPPS_WIDGET_CONTEXT_REQUEST" || msgType === "XAPPS_WIDGET_READY") && e.source === iframeRef.current?.contentWindow) {
|
|
5727
6019
|
try {
|
|
6020
|
+
const payload = buildWidgetBridgeContext();
|
|
5728
6021
|
e.source?.postMessage(
|
|
5729
|
-
{
|
|
6022
|
+
payload || {
|
|
5730
6023
|
type: "XAPPS_WIDGET_CONTEXT",
|
|
5731
6024
|
locale: env?.locale || null
|
|
5732
6025
|
},
|
|
@@ -5800,9 +6093,14 @@ function WidgetView() {
|
|
|
5800
6093
|
return () => window.removeEventListener("message", handler);
|
|
5801
6094
|
}, [
|
|
5802
6095
|
widgetToken,
|
|
6096
|
+
widgetSessionContext,
|
|
5803
6097
|
installationId,
|
|
5804
6098
|
widgetId,
|
|
6099
|
+
xappDetail,
|
|
6100
|
+
host,
|
|
6101
|
+
xappId,
|
|
5805
6102
|
env?.embedMode,
|
|
6103
|
+
env?.locale,
|
|
5806
6104
|
navigate,
|
|
5807
6105
|
isEmbedded,
|
|
5808
6106
|
tokenSearch,
|