@wix/himalaya-cli 0.1363.0 → 0.1364.0

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/cli.mjs CHANGED
@@ -7706,6 +7706,7 @@ function resolveTranslation(value, catalog3, sourceCatalog) {
7706
7706
  var BINDING_SIGILS, BINDING_SIGIL_RE, TRANSLATION_PREFIX, TRANSLATION_KEY_RE;
7707
7707
  var init_bindings = __esm({
7708
7708
  "../../core/ts/src/bindings.ts"() {
7709
+ "use strict";
7709
7710
  BINDING_SIGILS = ["service", "flag", "item", "t"];
7710
7711
  BINDING_SIGIL_RE = new RegExp(
7711
7712
  `^\\$(?:${BINDING_SIGILS.filter((s2) => s2 !== "t").join("|")})\\b|^\\$t:`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/himalaya-cli",
3
- "version": "0.1363.0",
3
+ "version": "0.1364.0",
4
4
  "type": "module",
5
5
  "description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
6
6
  "keywords": [
@@ -71,5 +71,5 @@
71
71
  "artifactId": "himalaya-cli"
72
72
  }
73
73
  },
74
- "falconPackageHash": "000d7f43b6f442daf4ff499fd016c52ee6a2b3bab69dd868db3b3d71"
74
+ "falconPackageHash": "d3c28af7c96bcc51af2111ceb585221c63a75150cacb4a2e9ec7facc"
75
75
  }
@@ -9,7 +9,7 @@ import { hostSessionFromGlobal, iapPriceFields, type IapCatalogItem } from "@him
9
9
  import { createIapCommerce, pricingPlanOrders } from "@himalaya/iap-checkout";
10
10
  import { iapPriceCopy, iapPurchaseCopy, resetUnhydratedKeysOnOlderRuntime } from "../_shared/iap-worker.js";
11
11
  import { formatCurrency } from "../_shared/engine-intl.js";
12
- import { isHostedWorker } from "../_shared/hosted-checkout.js";
12
+ import { isHostedWorker, hostedSitePageOpener } from "../_shared/hosted-checkout.js";
13
13
 
14
14
  /** Wix Pricing Plans appDefId — the vertical that owns a plan order, so the `appId` its
15
15
  * cashier order is paid under (mirrors AppDefId.PRICING_PLANS in Wix's RN apps). */
@@ -186,6 +186,8 @@ let started = false;
186
186
  let loading = 0;
187
187
  let contentReady = false;
188
188
  const joining = new Set<string>();
189
+ /** A hosted paid plan's page is being prepared by the host (one ticket at a time). */
190
+ let hostedPlanOpenInFlight = false;
189
191
  const memberSession = hostSessionFromGlobal();
190
192
  let regularGeneration = -1;
191
193
  let regularAccess = new Set<string>();
@@ -227,9 +229,27 @@ async function regularJoinMessage(row: PlanRow, reference: { kind: string; id: s
227
229
  // Hosted inside a host shell (Spaces) a plan cannot be paid in-app: classic Pricing Plans is not on
228
230
  // ecom, so the host's member checkout has no checkout to open, and the redirect session needs a
229
231
  // headless OAuth client a hosted app does not have. An online order created here would only be
230
- // left behind as a DRAFT, so none is — the member joins on the site. A FREE plan has nothing to
231
- // pay: its online order activates at once, so it still joins in-app.
232
+ // left behind as a DRAFT, so none is — the member joins on the site: the HOST opens the site's own
233
+ // plans page signed in as the lent member (`himi.host.memberSitePage {page:"plans"}`), or this
234
+ // message stands when it cannot. A FREE plan has nothing to pay: its online order activates at
235
+ // once, so it still joins in-app.
232
236
  if (isHostedWorker() && !row.free) {
237
+ // One host open at a time: the host keeps a single ticket, so a second plan's prepare would replace the
238
+ // first's and drop it. The checkout guard is re-read right before the host opens the page.
239
+ if (hostedPlanOpenInFlight) return "";
240
+ hostedPlanOpenInFlight = true;
241
+ let opened: boolean | "withdrawn";
242
+ try {
243
+ opened = await hostedSitePageOpener({ page: "plans", planId: row.id })(
244
+ async () => commerce.pricing.continueCheckoutGuard(reference).allowed);
245
+ } finally {
246
+ hostedPlanOpenInFlight = false;
247
+ }
248
+ if (generation !== memberSession.current().generation) return "";
249
+ if (opened === "withdrawn") return "";
250
+ if (opened === true) {
251
+ return copyTemplate("plans.continueOnSiteMessage", "Finish joining {name} on the site.", { name: row.name });
252
+ }
233
253
  return copyTemplate("plans.joinOnSiteMessage", "Memberships are purchased on the website — visit the site to join {name}.", { name: row.name });
234
254
  }
235
255
  try {
@@ -9,7 +9,7 @@ import { hostSessionFromGlobal, iapPriceFields, type IapCatalogItem } from "@him
9
9
  import { createIapCommerce, pricingPlanOrders } from "@himalaya/iap-checkout";
10
10
  import { iapPriceCopy, iapPurchaseCopy, resetUnhydratedKeysOnOlderRuntime } from "../_shared/iap-worker.js";
11
11
  import { formatCurrency } from "../_shared/engine-intl.js";
12
- import { isHostedWorker } from "../_shared/hosted-checkout.js";
12
+ import { isHostedWorker, hostedSitePageOpener } from "../_shared/hosted-checkout.js";
13
13
 
14
14
  /** Wix Pricing Plans appDefId — the vertical that owns a plan order, so the `appId` its
15
15
  * cashier order is paid under (mirrors AppDefId.PRICING_PLANS in Wix's RN apps). */
@@ -186,6 +186,8 @@ let started = false;
186
186
  let loading = 0;
187
187
  let contentReady = false;
188
188
  const joining = new Set<string>();
189
+ /** A hosted paid plan's page is being prepared by the host (one ticket at a time). */
190
+ let hostedPlanOpenInFlight = false;
189
191
  const memberSession = hostSessionFromGlobal();
190
192
  let regularGeneration = -1;
191
193
  let regularAccess = new Set<string>();
@@ -227,9 +229,27 @@ async function regularJoinMessage(row: PlanRow, reference: { kind: string; id: s
227
229
  // Hosted inside a host shell (Spaces) a plan cannot be paid in-app: classic Pricing Plans is not on
228
230
  // ecom, so the host's member checkout has no checkout to open, and the redirect session needs a
229
231
  // headless OAuth client a hosted app does not have. An online order created here would only be
230
- // left behind as a DRAFT, so none is — the member joins on the site. A FREE plan has nothing to
231
- // pay: its online order activates at once, so it still joins in-app.
232
+ // left behind as a DRAFT, so none is — the member joins on the site: the HOST opens the site's own
233
+ // plans page signed in as the lent member (`himi.host.memberSitePage {page:"plans"}`), or this
234
+ // message stands when it cannot. A FREE plan has nothing to pay: its online order activates at
235
+ // once, so it still joins in-app.
232
236
  if (isHostedWorker() && !row.free) {
237
+ // One host open at a time: the host keeps a single ticket, so a second plan's prepare would replace the
238
+ // first's and drop it. The checkout guard is re-read right before the host opens the page.
239
+ if (hostedPlanOpenInFlight) return "";
240
+ hostedPlanOpenInFlight = true;
241
+ let opened: boolean | "withdrawn";
242
+ try {
243
+ opened = await hostedSitePageOpener({ page: "plans", planId: row.id })(
244
+ async () => commerce.pricing.continueCheckoutGuard(reference).allowed);
245
+ } finally {
246
+ hostedPlanOpenInFlight = false;
247
+ }
248
+ if (generation !== memberSession.current().generation) return "";
249
+ if (opened === "withdrawn") return "";
250
+ if (opened === true) {
251
+ return copyTemplate("plans.continueOnSiteMessage", "Finish joining {name} on the site.", { name: row.name });
252
+ }
233
253
  return copyTemplate("plans.joinOnSiteMessage", "Memberships are purchased on the website — visit the site to join {name}.", { name: row.name });
234
254
  }
235
255
  try {
@@ -9,7 +9,7 @@ import { hostSessionFromGlobal, iapPriceFields, type IapCatalogItem } from "@him
9
9
  import { createIapCommerce, pricingPlanOrders } from "@himalaya/iap-checkout";
10
10
  import { iapPriceCopy, iapPurchaseCopy, resetUnhydratedKeysOnOlderRuntime } from "../_shared/iap-worker.js";
11
11
  import { formatCurrency } from "../_shared/engine-intl.js";
12
- import { isHostedWorker } from "../_shared/hosted-checkout.js";
12
+ import { isHostedWorker, hostedSitePageOpener } from "../_shared/hosted-checkout.js";
13
13
 
14
14
  /** Wix Pricing Plans appDefId — the vertical that owns a plan order, so the `appId` its
15
15
  * cashier order is paid under (mirrors AppDefId.PRICING_PLANS in Wix's RN apps). */
@@ -186,6 +186,8 @@ let started = false;
186
186
  let loading = 0;
187
187
  let contentReady = false;
188
188
  const joining = new Set<string>();
189
+ /** A hosted paid plan's page is being prepared by the host (one ticket at a time). */
190
+ let hostedPlanOpenInFlight = false;
189
191
  const memberSession = hostSessionFromGlobal();
190
192
  let regularGeneration = -1;
191
193
  let regularAccess = new Set<string>();
@@ -227,9 +229,27 @@ async function regularJoinMessage(row: PlanRow, reference: { kind: string; id: s
227
229
  // Hosted inside a host shell (Spaces) a plan cannot be paid in-app: classic Pricing Plans is not on
228
230
  // ecom, so the host's member checkout has no checkout to open, and the redirect session needs a
229
231
  // headless OAuth client a hosted app does not have. An online order created here would only be
230
- // left behind as a DRAFT, so none is — the member joins on the site. A FREE plan has nothing to
231
- // pay: its online order activates at once, so it still joins in-app.
232
+ // left behind as a DRAFT, so none is — the member joins on the site: the HOST opens the site's own
233
+ // plans page signed in as the lent member (`himi.host.memberSitePage {page:"plans"}`), or this
234
+ // message stands when it cannot. A FREE plan has nothing to pay: its online order activates at
235
+ // once, so it still joins in-app.
232
236
  if (isHostedWorker() && !row.free) {
237
+ // One host open at a time: the host keeps a single ticket, so a second plan's prepare would replace the
238
+ // first's and drop it. The checkout guard is re-read right before the host opens the page.
239
+ if (hostedPlanOpenInFlight) return "";
240
+ hostedPlanOpenInFlight = true;
241
+ let opened: boolean | "withdrawn";
242
+ try {
243
+ opened = await hostedSitePageOpener({ page: "plans", planId: row.id })(
244
+ async () => commerce.pricing.continueCheckoutGuard(reference).allowed);
245
+ } finally {
246
+ hostedPlanOpenInFlight = false;
247
+ }
248
+ if (generation !== memberSession.current().generation) return "";
249
+ if (opened === "withdrawn") return "";
250
+ if (opened === true) {
251
+ return copyTemplate("plans.continueOnSiteMessage", "Finish joining {name} on the site.", { name: row.name });
252
+ }
233
253
  return copyTemplate("plans.joinOnSiteMessage", "Memberships are purchased on the website — visit the site to join {name}.", { name: row.name });
234
254
  }
235
255
  try {
@@ -9,7 +9,7 @@ import { hostSessionFromGlobal, iapPriceFields, type IapCatalogItem } from "@him
9
9
  import { createIapCommerce, pricingPlanOrders } from "@himalaya/iap-checkout";
10
10
  import { iapPriceCopy, iapPurchaseCopy, resetUnhydratedKeysOnOlderRuntime } from "../_shared/iap-worker.js";
11
11
  import { formatCurrency } from "../_shared/engine-intl.js";
12
- import { isHostedWorker } from "../_shared/hosted-checkout.js";
12
+ import { isHostedWorker, hostedSitePageOpener } from "../_shared/hosted-checkout.js";
13
13
 
14
14
  /** Wix Pricing Plans appDefId — the vertical that owns a plan order, so the `appId` its
15
15
  * cashier order is paid under (mirrors AppDefId.PRICING_PLANS in Wix's RN apps). */
@@ -186,6 +186,8 @@ let started = false;
186
186
  let loading = 0;
187
187
  let contentReady = false;
188
188
  const joining = new Set<string>();
189
+ /** A hosted paid plan's page is being prepared by the host (one ticket at a time). */
190
+ let hostedPlanOpenInFlight = false;
189
191
  const memberSession = hostSessionFromGlobal();
190
192
  let regularGeneration = -1;
191
193
  let regularAccess = new Set<string>();
@@ -227,9 +229,27 @@ async function regularJoinMessage(row: PlanRow, reference: { kind: string; id: s
227
229
  // Hosted inside a host shell (Spaces) a plan cannot be paid in-app: classic Pricing Plans is not on
228
230
  // ecom, so the host's member checkout has no checkout to open, and the redirect session needs a
229
231
  // headless OAuth client a hosted app does not have. An online order created here would only be
230
- // left behind as a DRAFT, so none is — the member joins on the site. A FREE plan has nothing to
231
- // pay: its online order activates at once, so it still joins in-app.
232
+ // left behind as a DRAFT, so none is — the member joins on the site: the HOST opens the site's own
233
+ // plans page signed in as the lent member (`himi.host.memberSitePage {page:"plans"}`), or this
234
+ // message stands when it cannot. A FREE plan has nothing to pay: its online order activates at
235
+ // once, so it still joins in-app.
232
236
  if (isHostedWorker() && !row.free) {
237
+ // One host open at a time: the host keeps a single ticket, so a second plan's prepare would replace the
238
+ // first's and drop it. The checkout guard is re-read right before the host opens the page.
239
+ if (hostedPlanOpenInFlight) return "";
240
+ hostedPlanOpenInFlight = true;
241
+ let opened: boolean | "withdrawn";
242
+ try {
243
+ opened = await hostedSitePageOpener({ page: "plans", planId: row.id })(
244
+ async () => commerce.pricing.continueCheckoutGuard(reference).allowed);
245
+ } finally {
246
+ hostedPlanOpenInFlight = false;
247
+ }
248
+ if (generation !== memberSession.current().generation) return "";
249
+ if (opened === "withdrawn") return "";
250
+ if (opened === true) {
251
+ return copyTemplate("plans.continueOnSiteMessage", "Finish joining {name} on the site.", { name: row.name });
252
+ }
233
253
  return copyTemplate("plans.joinOnSiteMessage", "Memberships are purchased on the website — visit the site to join {name}.", { name: row.name });
234
254
  }
235
255
  try {
@@ -9,7 +9,7 @@ import { hostSessionFromGlobal, iapPriceFields, type IapCatalogItem } from "@him
9
9
  import { createIapCommerce, pricingPlanOrders } from "@himalaya/iap-checkout";
10
10
  import { iapPriceCopy, iapPurchaseCopy, resetUnhydratedKeysOnOlderRuntime } from "../_shared/iap-worker.js";
11
11
  import { formatCurrency } from "../_shared/engine-intl.js";
12
- import { isHostedWorker } from "../_shared/hosted-checkout.js";
12
+ import { isHostedWorker, hostedSitePageOpener } from "../_shared/hosted-checkout.js";
13
13
 
14
14
  /** Wix Pricing Plans appDefId — the vertical that owns a plan order, so the `appId` its
15
15
  * cashier order is paid under (mirrors AppDefId.PRICING_PLANS in Wix's RN apps). */
@@ -186,6 +186,8 @@ let started = false;
186
186
  let loading = 0;
187
187
  let contentReady = false;
188
188
  const joining = new Set<string>();
189
+ /** A hosted paid plan's page is being prepared by the host (one ticket at a time). */
190
+ let hostedPlanOpenInFlight = false;
189
191
  const memberSession = hostSessionFromGlobal();
190
192
  let regularGeneration = -1;
191
193
  let regularAccess = new Set<string>();
@@ -227,9 +229,27 @@ async function regularJoinMessage(row: PlanRow, reference: { kind: string; id: s
227
229
  // Hosted inside a host shell (Spaces) a plan cannot be paid in-app: classic Pricing Plans is not on
228
230
  // ecom, so the host's member checkout has no checkout to open, and the redirect session needs a
229
231
  // headless OAuth client a hosted app does not have. An online order created here would only be
230
- // left behind as a DRAFT, so none is — the member joins on the site. A FREE plan has nothing to
231
- // pay: its online order activates at once, so it still joins in-app.
232
+ // left behind as a DRAFT, so none is — the member joins on the site: the HOST opens the site's own
233
+ // plans page signed in as the lent member (`himi.host.memberSitePage {page:"plans"}`), or this
234
+ // message stands when it cannot. A FREE plan has nothing to pay: its online order activates at
235
+ // once, so it still joins in-app.
232
236
  if (isHostedWorker() && !row.free) {
237
+ // One host open at a time: the host keeps a single ticket, so a second plan's prepare would replace the
238
+ // first's and drop it. The checkout guard is re-read right before the host opens the page.
239
+ if (hostedPlanOpenInFlight) return "";
240
+ hostedPlanOpenInFlight = true;
241
+ let opened: boolean | "withdrawn";
242
+ try {
243
+ opened = await hostedSitePageOpener({ page: "plans", planId: row.id })(
244
+ async () => commerce.pricing.continueCheckoutGuard(reference).allowed);
245
+ } finally {
246
+ hostedPlanOpenInFlight = false;
247
+ }
248
+ if (generation !== memberSession.current().generation) return "";
249
+ if (opened === "withdrawn") return "";
250
+ if (opened === true) {
251
+ return copyTemplate("plans.continueOnSiteMessage", "Finish joining {name} on the site.", { name: row.name });
252
+ }
233
253
  return copyTemplate("plans.joinOnSiteMessage", "Memberships are purchased on the website — visit the site to join {name}.", { name: row.name });
234
254
  }
235
255
  try {
@@ -9,7 +9,7 @@ import { hostSessionFromGlobal, iapPriceFields, type IapCatalogItem } from "@him
9
9
  import { createIapCommerce, pricingPlanOrders } from "@himalaya/iap-checkout";
10
10
  import { iapPriceCopy, iapPurchaseCopy, resetUnhydratedKeysOnOlderRuntime } from "../_shared/iap-worker.js";
11
11
  import { formatCurrency } from "../_shared/engine-intl.js";
12
- import { isHostedWorker } from "../_shared/hosted-checkout.js";
12
+ import { isHostedWorker, hostedSitePageOpener } from "../_shared/hosted-checkout.js";
13
13
 
14
14
  /** Wix Pricing Plans appDefId — the vertical that owns a plan order, so the `appId` its
15
15
  * cashier order is paid under (mirrors AppDefId.PRICING_PLANS in Wix's RN apps). */
@@ -186,6 +186,8 @@ let started = false;
186
186
  let loading = 0;
187
187
  let contentReady = false;
188
188
  const joining = new Set<string>();
189
+ /** A hosted paid plan's page is being prepared by the host (one ticket at a time). */
190
+ let hostedPlanOpenInFlight = false;
189
191
  const memberSession = hostSessionFromGlobal();
190
192
  let regularGeneration = -1;
191
193
  let regularAccess = new Set<string>();
@@ -227,9 +229,27 @@ async function regularJoinMessage(row: PlanRow, reference: { kind: string; id: s
227
229
  // Hosted inside a host shell (Spaces) a plan cannot be paid in-app: classic Pricing Plans is not on
228
230
  // ecom, so the host's member checkout has no checkout to open, and the redirect session needs a
229
231
  // headless OAuth client a hosted app does not have. An online order created here would only be
230
- // left behind as a DRAFT, so none is — the member joins on the site. A FREE plan has nothing to
231
- // pay: its online order activates at once, so it still joins in-app.
232
+ // left behind as a DRAFT, so none is — the member joins on the site: the HOST opens the site's own
233
+ // plans page signed in as the lent member (`himi.host.memberSitePage {page:"plans"}`), or this
234
+ // message stands when it cannot. A FREE plan has nothing to pay: its online order activates at
235
+ // once, so it still joins in-app.
232
236
  if (isHostedWorker() && !row.free) {
237
+ // One host open at a time: the host keeps a single ticket, so a second plan's prepare would replace the
238
+ // first's and drop it. The checkout guard is re-read right before the host opens the page.
239
+ if (hostedPlanOpenInFlight) return "";
240
+ hostedPlanOpenInFlight = true;
241
+ let opened: boolean | "withdrawn";
242
+ try {
243
+ opened = await hostedSitePageOpener({ page: "plans", planId: row.id })(
244
+ async () => commerce.pricing.continueCheckoutGuard(reference).allowed);
245
+ } finally {
246
+ hostedPlanOpenInFlight = false;
247
+ }
248
+ if (generation !== memberSession.current().generation) return "";
249
+ if (opened === "withdrawn") return "";
250
+ if (opened === true) {
251
+ return copyTemplate("plans.continueOnSiteMessage", "Finish joining {name} on the site.", { name: row.name });
252
+ }
233
253
  return copyTemplate("plans.joinOnSiteMessage", "Memberships are purchased on the website — visit the site to join {name}.", { name: row.name });
234
254
  }
235
255
  try {