@wix/himalaya-cli 0.1551.0 → 0.1552.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/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/builder.d.ts +3 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/iap/src/wix-payments-contract.d.ts +2 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/iap-checkout/src/apple-iap-contract.d.ts +24 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/iap-checkout/src/order-refs.d.ts +12 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/forms/src/extensions.d.ts +83 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/iap-checkout.mjs +146 -23
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/iap.mjs +8 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/screens.mjs +147 -24
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-forms.mjs +19 -0
- package/dist/cli.mjs +2455 -2166
- package/fixtures/wix-canned.json +14 -7
- package/guides/getting-started.md +17 -1
- package/guides/headless-loop.md +7 -1
- package/guides/himi-skill.md +17 -1
- package/guides/himi-test.md +95 -7
- package/guides/iap-pricing.md +1 -1
- package/guides/iap-products.md +2 -2
- package/guides/iap-screen-adoption.md +1 -1
- package/guides/index.json +1 -1
- package/guides/sdk-reference.json +82 -4
- package/guides/skill.md +16 -0
- package/package.json +2 -2
- package/templates/beauty-salon/config.ts +13 -0
- package/templates/beauty-salon/tier5-src/_shared/iap-attendance-purchase.ts +1 -1
- package/templates/beauty-salon/tier5-src/_shared/iap-worker.ts +1 -1
- package/templates/beauty-salon/tier5-src/himi-store-product/index.ts +1 -1
- package/templates/branded-lite/config.ts +13 -0
- package/templates/branded-lite/dev/index.ts +1338 -2011
- package/templates/branded-lite/tier5-src/_shared/branded-form.ts +262 -0
- package/templates/branded-lite/tier5-src/_shared/iap-attendance-purchase.ts +1 -1
- package/templates/branded-lite/tier5-src/_shared/iap-worker.ts +1 -1
- package/templates/branded-lite/tier5-src/himi-branded-lite-form/index.ts +399 -0
- package/templates/branded-lite/tier5-src/himi-branded-lite-forms/index.ts +22 -7
- package/templates/branded-lite/tier5-src/himi-store-product/index.ts +1 -1
- package/templates/community-club/config.ts +13 -0
- package/templates/community-club/tier5-src/_shared/iap-attendance-purchase.ts +1 -1
- package/templates/community-club/tier5-src/_shared/iap-worker.ts +1 -1
- package/templates/events-meetups/config.ts +13 -0
- package/templates/events-meetups/tier5-src/_shared/iap-attendance-purchase.ts +1 -1
- package/templates/events-meetups/tier5-src/_shared/iap-worker.ts +1 -1
- package/templates/gym-fitness/config.ts +13 -0
- package/templates/gym-fitness/tier5-src/_shared/iap-attendance-purchase.ts +1 -1
- package/templates/gym-fitness/tier5-src/_shared/iap-worker.ts +1 -1
- package/templates/gym-fitness/tier5-src/himi-store-product/index.ts +1 -1
- package/templates/nonprofit-cause/config.ts +13 -0
- package/templates/nonprofit-cause/tier5-src/_shared/iap-attendance-purchase.ts +1 -1
- package/templates/nonprofit-cause/tier5-src/_shared/iap-worker.ts +1 -1
- package/templates/podcast-creator/config.ts +13 -0
- package/templates/podcast-creator/tier5-src/_shared/iap-attendance-purchase.ts +1 -1
- package/templates/podcast-creator/tier5-src/_shared/iap-worker.ts +1 -1
- package/templates/portfolio-creative/config.ts +13 -0
- package/templates/portfolio-creative/tier5-src/_shared/iap-attendance-purchase.ts +1 -1
- package/templates/portfolio-creative/tier5-src/_shared/iap-worker.ts +1 -1
- package/templates/portfolio-creative/tier5-src/himi-store-product/index.ts +1 -1
- package/templates/restaurant/config.ts +13 -0
- package/templates/restaurant/tier5-src/_shared/iap-attendance-purchase.ts +1 -1
- package/templates/restaurant/tier5-src/_shared/iap-worker.ts +1 -1
- package/templates/retail-store/config.ts +13 -0
- package/templates/retail-store/tier5-src/_shared/iap-worker.ts +1 -1
- package/templates/retail-store/tier5-src/himi-store-product/index.ts +1 -1
- package/templates/yoga-studio/config.ts +13 -0
- package/templates/yoga-studio/tier5-src/_shared/iap-attendance-purchase.ts +1 -1
- package/templates/yoga-studio/tier5-src/_shared/iap-worker.ts +1 -1
- package/templates/branded-lite/tier5-src/wix-spaces-form-detail/index.ts +0 -30
|
@@ -1240,8 +1240,8 @@ var sameReference = (value, reference) => isObject2(value) && value.kind === ref
|
|
|
1240
1240
|
|
|
1241
1241
|
// ../../core/sdk/iap/src/wix-payments-contract.ts
|
|
1242
1242
|
var HIMALAYA_SERVE_IAP_ROUTE = { prefix: "/himalaya-serve/v1/iap" };
|
|
1243
|
-
var BOOKINGS_APPLE_SALES_ENABLED =
|
|
1244
|
-
var EVENTS_APPLE_SALES_ENABLED =
|
|
1243
|
+
var BOOKINGS_APPLE_SALES_ENABLED = true;
|
|
1244
|
+
var EVENTS_APPLE_SALES_ENABLED = true;
|
|
1245
1245
|
var ATTENDANCE_SALE_RULE = { appProductId: (id2) => id2, productType: "CONSUMABLE" };
|
|
1246
1246
|
var STORES_ITEM_PAYMENT_ENABLED = false;
|
|
1247
1247
|
var STORES_APPLE_SALES_ENABLED = true;
|
|
@@ -2005,10 +2005,13 @@ function locationType(raw) {
|
|
|
2005
2005
|
return type === "CUSTOM" && addresses.every(describesNoPlace) ? ADDRESSLESS_CUSTOM : type;
|
|
2006
2006
|
}
|
|
2007
2007
|
function describesNoPlace(address) {
|
|
2008
|
-
const parts = ["country", "subdivision", "city", "postalCode", "
|
|
2008
|
+
const parts = ["country", "subdivision", "city", "postalCode", "addressLine2", "streetAddress", "location"];
|
|
2009
2009
|
if (parts.some((key) => address[key] !== void 0 && address[key] !== "")) return false;
|
|
2010
|
-
|
|
2011
|
-
|
|
2010
|
+
return [address.addressLine, address.formattedAddress].every((value) => {
|
|
2011
|
+
if (value !== void 0 && typeof value !== "string") return false;
|
|
2012
|
+
const description = value?.trim() ?? "";
|
|
2013
|
+
return description === "" || ONLINE_LABEL.test(description);
|
|
2014
|
+
});
|
|
2012
2015
|
}
|
|
2013
2016
|
var ONLINE_LABEL = /^(online|virtual)(\s+(class|classes|classroom|course|session|sessions|meeting|lesson|training|workshop|event))?$/i;
|
|
2014
2017
|
function ticketAttendanceOf(event, definition) {
|
|
@@ -2272,9 +2275,33 @@ function isFinalRefusal(status) {
|
|
|
2272
2275
|
var NEEDS_SUPPORT_HOLD_MS = 6048e5;
|
|
2273
2276
|
var ITEM_START_HOLD_MS = 36e5;
|
|
2274
2277
|
function pruneExpiredHolds(partition, now) {
|
|
2275
|
-
const expired = partition.refs().filter((ref) => now - ref.updatedAt >= (HOLD_MS[ref.stage] ?? Infinity));
|
|
2278
|
+
const expired = partition.refs().filter((ref) => now - ref.updatedAt >= (HOLD_MS[ref.stage] ?? Infinity) || released(ref, now));
|
|
2276
2279
|
return expired.filter((ref) => partition.remove(ref.key)).map((ref) => ref.key);
|
|
2277
2280
|
}
|
|
2281
|
+
var OPENING_SETTLE_MS = 3e5;
|
|
2282
|
+
async function settleOpening(partition, adapter, guard, item, bridge, now) {
|
|
2283
|
+
const resolve = adapter.resolveOpening;
|
|
2284
|
+
if (!resolve) return "held";
|
|
2285
|
+
let current = guard;
|
|
2286
|
+
const claim = () => {
|
|
2287
|
+
const next = { ...current, updatedAt: now };
|
|
2288
|
+
if (!isStoredGuard(partition, current) || !partition.put(next)) return false;
|
|
2289
|
+
current = next;
|
|
2290
|
+
return true;
|
|
2291
|
+
};
|
|
2292
|
+
const resolution = await resolve(guard, item, bridge, { settled: now - guard.updatedAt >= OPENING_SETTLE_MS, claim });
|
|
2293
|
+
if (isStoredGuard(partition, current)) {
|
|
2294
|
+
if (resolution !== "released") return resolution;
|
|
2295
|
+
return partition.remove(guard.key) ? "released" : "storageUnavailable";
|
|
2296
|
+
}
|
|
2297
|
+
const stored = partition.refs().find((ref) => ref.key === guard.key);
|
|
2298
|
+
if (!stored) return "released";
|
|
2299
|
+
return stored.stage === "openingOrder" ? resolve(stored, item, bridge, { settled: false, claim: () => false }) : "held";
|
|
2300
|
+
}
|
|
2301
|
+
function isStoredGuard(partition, guard) {
|
|
2302
|
+
const stored = partition.refs().find((ref) => ref.key === guard.key);
|
|
2303
|
+
return stored?.stage === "openingOrder" && stored.updatedAt === guard.updatedAt;
|
|
2304
|
+
}
|
|
2278
2305
|
var MAX_ORDER_REFS = 16;
|
|
2279
2306
|
function createWorkerOrderRefStore(storage) {
|
|
2280
2307
|
const kv = () => storage ?? hostStorage();
|
|
@@ -2351,10 +2378,14 @@ function writeVerified(store, location, value) {
|
|
|
2351
2378
|
function isOrderRef(value) {
|
|
2352
2379
|
if (!isObject6(value) || typeof value.key !== "string" || !STAGES.has(value.stage)) return false;
|
|
2353
2380
|
if (typeof value.updatedAt !== "number") return false;
|
|
2381
|
+
if (value.releaseAt !== void 0 && typeof value.releaseAt !== "number") return false;
|
|
2354
2382
|
const optional = ["kind", "cashierOrderId", "wixTransactionId", "paymentId", "storeProductId", "appProductId", "appleTransactionId", "appAccountToken"];
|
|
2355
2383
|
if (!optional.every((field) => value[field] === void 0 || typeof value[field] === "string")) return false;
|
|
2356
2384
|
return value.verticalRef === void 0 || isStringMap(value.verticalRef);
|
|
2357
2385
|
}
|
|
2386
|
+
function released(ref, now) {
|
|
2387
|
+
return ref.stage === "openingOrder" && ref.releaseAt !== void 0 && now >= ref.releaseAt;
|
|
2388
|
+
}
|
|
2358
2389
|
function isPartitionKey(key) {
|
|
2359
2390
|
return isUUID3(key.purchasesAppId) && isUUID3(key.siteId) && isUUID3(key.memberId);
|
|
2360
2391
|
}
|
|
@@ -2491,6 +2522,8 @@ function createWixOrderBackend(deps) {
|
|
|
2491
2522
|
async function getPurchaseContext(session, catalogRef) {
|
|
2492
2523
|
const sale = await saleFor(session, catalogRef);
|
|
2493
2524
|
if (isStop(sale)) return contextResult(catalogRef, sale);
|
|
2525
|
+
const unresolved = await resolveOpenings(sale);
|
|
2526
|
+
if (unresolved) return contextResult(catalogRef, unresolved);
|
|
2494
2527
|
const blocked = saleBlocked(sale);
|
|
2495
2528
|
if (blocked) return contextResult(catalogRef, blocked);
|
|
2496
2529
|
const itemPayment = deps.itemPaymentEnabled ? sale.adapter.itemPayment?.(sale.item) : null;
|
|
@@ -2509,11 +2542,26 @@ function createWixOrderBackend(deps) {
|
|
|
2509
2542
|
if (failure3) return stopWith("rejected", failure3);
|
|
2510
2543
|
if (sale.adapter.repeatable) {
|
|
2511
2544
|
const prefix = `${sale.item.reference.kind}:${sale.item.reference.id}#`;
|
|
2512
|
-
const unresolved = sale.partition.refs().find((ref) => ref.key.startsWith(prefix) && ["openingOrder", "held", "needsSupport"].includes(ref.stage));
|
|
2513
|
-
if (unresolved) return stopWith("rejected", unresolved.stage === "openingOrder" ? "
|
|
2545
|
+
const unresolved = sale.partition.refs().find((ref) => ref.key.startsWith(prefix) && !sale.unrelated.has(ref.key) && ["openingOrder", "held", "needsSupport"].includes(ref.stage));
|
|
2546
|
+
if (unresolved) return stopWith("rejected", unresolved.stage === "openingOrder" ? "paymentInProgress" : "needsSupport");
|
|
2514
2547
|
}
|
|
2515
2548
|
return deps.productBusy?.(sale.appleProduct.productId) ? stopWith("rejected", "paymentInProgress") : null;
|
|
2516
2549
|
}
|
|
2550
|
+
async function resolveOpenings(sale) {
|
|
2551
|
+
if (!sale.adapter.repeatable || !sale.adapter.resolveOpening) return null;
|
|
2552
|
+
for (const guard of openingsOf(sale)) {
|
|
2553
|
+
const resolution = await settleOpening(sale.partition, sale.adapter, guard, sale.item, sale.bridge, now());
|
|
2554
|
+
if (!sale.bridge.isCurrent() || resolution === "sessionChanged") return STALE2;
|
|
2555
|
+
if (resolution === "unavailable") return retry("unavailable");
|
|
2556
|
+
if (resolution === "storageUnavailable") return stopWith("rejected", "storageUnavailable");
|
|
2557
|
+
if (resolution === "unrelated") sale.unrelated.add(guard.key);
|
|
2558
|
+
}
|
|
2559
|
+
return null;
|
|
2560
|
+
}
|
|
2561
|
+
function openingsOf(sale) {
|
|
2562
|
+
const prefix = `${sale.item.reference.kind}:${sale.item.reference.id}#`;
|
|
2563
|
+
return sale.partition.refs().filter((ref) => ref.stage === "openingOrder" && ref.key.startsWith(prefix));
|
|
2564
|
+
}
|
|
2517
2565
|
async function saleFor(session, catalogRef) {
|
|
2518
2566
|
const sold = deps.itemFor(catalogRef);
|
|
2519
2567
|
const adapter = sold && adapterFor(sold.item.reference.kind);
|
|
@@ -2534,13 +2582,15 @@ function createWixOrderBackend(deps) {
|
|
|
2534
2582
|
adapter,
|
|
2535
2583
|
member,
|
|
2536
2584
|
partition: member.partition,
|
|
2537
|
-
bridge: bindBridge(session, deps.session, deps.bridge)
|
|
2585
|
+
bridge: bindBridge(session, deps.session, deps.bridge),
|
|
2586
|
+
unrelated: /* @__PURE__ */ new Set()
|
|
2538
2587
|
};
|
|
2539
2588
|
}
|
|
2540
2589
|
async function orderFor(sale) {
|
|
2541
2590
|
const existing = refAt(sale.partition, sale.catalogRef);
|
|
2542
2591
|
let prevented;
|
|
2543
|
-
|
|
2592
|
+
let guarded;
|
|
2593
|
+
const beforeCreate = (guard = {}) => {
|
|
2544
2594
|
if (!sale.adapter.repeatable || existing) return true;
|
|
2545
2595
|
if (!sale.bridge.isCurrent()) {
|
|
2546
2596
|
prevented = STALE2;
|
|
@@ -2551,18 +2601,30 @@ function createWixOrderBackend(deps) {
|
|
|
2551
2601
|
prevented = blocked;
|
|
2552
2602
|
return false;
|
|
2553
2603
|
}
|
|
2554
|
-
const opening = persist(sale, { key: sale.catalogRef, kind: sale.adapter.kind, stage: "openingOrder", updatedAt: now() });
|
|
2604
|
+
const opening = persist(sale, { ...guard, key: sale.catalogRef, kind: sale.adapter.kind, stage: "openingOrder", updatedAt: now() });
|
|
2555
2605
|
if (isStop(opening)) {
|
|
2556
2606
|
prevented = opening;
|
|
2557
2607
|
return false;
|
|
2558
2608
|
}
|
|
2609
|
+
guarded = opening.updatedAt;
|
|
2559
2610
|
return true;
|
|
2560
2611
|
};
|
|
2561
|
-
const
|
|
2612
|
+
const afterCreate = (guard) => {
|
|
2613
|
+
const opening = refAt(sale.partition, sale.catalogRef);
|
|
2614
|
+
if (opening?.stage !== "openingOrder" || opening.updatedAt !== guarded) return;
|
|
2615
|
+
const recorded = persist(sale, { ...opening, ...guard, verticalRef: { ...opening.verticalRef, ...guard.verticalRef }, updatedAt: now() });
|
|
2616
|
+
if (!isStop(recorded)) guarded = recorded.updatedAt;
|
|
2617
|
+
};
|
|
2618
|
+
const attempt4 = existing?.cashierOrderId && existing.verticalRef ? await reopenOrOpen(sale, { cashierOrderId: existing.cashierOrderId, verticalRef: existing.verticalRef }) : await sale.adapter.openOrder(sale.item, sale.bridge, beforeCreate, afterCreate);
|
|
2562
2619
|
if (prevented) return prevented;
|
|
2620
|
+
if (guarded !== void 0 && attempt4.status === "open" && !stillGuarded(sale, guarded)) return retry("unavailable");
|
|
2563
2621
|
const ref = recordOrder(sale, existing, attempt4);
|
|
2564
2622
|
return isStop(ref) ? ref : { ref, placed: isPlaced(attempt4) };
|
|
2565
2623
|
}
|
|
2624
|
+
function stillGuarded(sale, guarded) {
|
|
2625
|
+
const stored = refAt(sale.partition, sale.catalogRef);
|
|
2626
|
+
return stored?.stage === "openingOrder" && stored.updatedAt === guarded;
|
|
2627
|
+
}
|
|
2566
2628
|
async function reopenOrOpen(sale, order) {
|
|
2567
2629
|
const reopened = await sale.adapter.reopenOrder(order, sale.bridge);
|
|
2568
2630
|
const closed = reopened.status === "refused" && reopened.reason === "orderClosed";
|
|
@@ -2805,8 +2867,9 @@ var NOT_CONFIGURED = { stop: true, result: "rejected", failure: "notConfigured"
|
|
|
2805
2867
|
var UNAVAILABLE = { stop: true, result: "retryable", failure: "unavailable" };
|
|
2806
2868
|
var OUTCOME_UNKNOWN = { stop: true, result: "rejected", failure: "outcomeUnknown" };
|
|
2807
2869
|
var BLOCKING_STAGES = {
|
|
2870
|
+
// A repeatable sale's guard settles on a later tap, so it keeps the action tappable.
|
|
2808
2871
|
startingItem: "outcomeUnknown",
|
|
2809
|
-
openingOrder: "
|
|
2872
|
+
openingOrder: "paymentInProgress",
|
|
2810
2873
|
submitted: "paymentInProgress",
|
|
2811
2874
|
held: "paymentHeld",
|
|
2812
2875
|
needsSupport: "needsSupport"
|
|
@@ -3065,6 +3128,7 @@ function enabledCheckout(deps) {
|
|
|
3065
3128
|
if (!tracked) return backOffDue();
|
|
3066
3129
|
partitionRead = null;
|
|
3067
3130
|
for (const key of pruneExpiredHolds(tracked.partition, deps.clock.now())) payments.delete(key);
|
|
3131
|
+
if (!options.dueOnly) await settleOpenings(session, tracked.partition);
|
|
3068
3132
|
for (const ref of tracked.partition.refs()) {
|
|
3069
3133
|
if (!isCurrent(session)) return;
|
|
3070
3134
|
if (ref.stage === "needsSupport") setPayment(ref.key, "needsSupport");
|
|
@@ -3080,6 +3144,13 @@ function enabledCheckout(deps) {
|
|
|
3080
3144
|
}
|
|
3081
3145
|
publish();
|
|
3082
3146
|
}
|
|
3147
|
+
async function settleOpenings(session, partition) {
|
|
3148
|
+
for (const ref of partition.refs()) {
|
|
3149
|
+
const adapter = deps.adapters.find((candidate) => candidate.kind === ref.kind);
|
|
3150
|
+
if (ref.stage !== "openingOrder" || !adapter?.resolveOpening || !isCurrent(session)) continue;
|
|
3151
|
+
await settleOpening(partition, adapter, ref, void 0, bindBridge(session, deps.session, bridge), deps.clock.now());
|
|
3152
|
+
}
|
|
3153
|
+
}
|
|
3083
3154
|
async function trackedPartition(session) {
|
|
3084
3155
|
const binding = await bindingOf(deps.binding);
|
|
3085
3156
|
if (!binding || !isCurrent(session)) return binding === null ? "none" : null;
|
|
@@ -3713,6 +3784,12 @@ var BOOKING = "bookingsService";
|
|
|
3713
3784
|
var TICKET = "eventsTicket";
|
|
3714
3785
|
var NOT_ENABLED = { status: "refused", reason: "notEnabled" };
|
|
3715
3786
|
var CHANGED = { status: "refused", reason: "productChanged" };
|
|
3787
|
+
var MINUTE_MS = 6e4;
|
|
3788
|
+
var RELEASE_MARGIN_MS = 3e5;
|
|
3789
|
+
var DEFAULT_RESERVATION_MINUTES = 60;
|
|
3790
|
+
var PAYMENT_TAKEN = ["PAID", "PARTIALLY_PAID", "EXEMPT", "REFUNDED"];
|
|
3791
|
+
var HAS_OFFSET = /(?:Z|[+-]\d{2}:?\d{2})$/i;
|
|
3792
|
+
var LATEST_ZONE_MS = 432e5;
|
|
3716
3793
|
function attendanceOrdersWith(options) {
|
|
3717
3794
|
const now = options.now ?? Date.now;
|
|
3718
3795
|
return {
|
|
@@ -3720,7 +3797,8 @@ function attendanceOrdersWith(options) {
|
|
|
3720
3797
|
kind: BOOKING,
|
|
3721
3798
|
repeatable: true,
|
|
3722
3799
|
eligibility: (item) => eligible(item, BOOKING, options.bookingsEnabled),
|
|
3723
|
-
openOrder: (item, bridge, beforeCreate) => options.bookingsEnabled ? openBooking(item, bridge, beforeCreate) : Promise.resolve(NOT_ENABLED),
|
|
3800
|
+
openOrder: (item, bridge, beforeCreate, afterCreate) => options.bookingsEnabled ? openBooking(item, bridge, beforeCreate, afterCreate) : Promise.resolve(NOT_ENABLED),
|
|
3801
|
+
resolveOpening: resolveBookingOpening,
|
|
3724
3802
|
readAccess: bookingAccess,
|
|
3725
3803
|
reopenOrder: (order, bridge) => reopen(order, bridge, bookingAccess)
|
|
3726
3804
|
},
|
|
@@ -3728,7 +3806,7 @@ function attendanceOrdersWith(options) {
|
|
|
3728
3806
|
kind: TICKET,
|
|
3729
3807
|
repeatable: true,
|
|
3730
3808
|
eligibility: (item) => eligible(item, TICKET, options.eventsEnabled),
|
|
3731
|
-
openOrder: (item, bridge, beforeCreate) => options.eventsEnabled ? openTicket(item, bridge, now, beforeCreate) : Promise.resolve(NOT_ENABLED),
|
|
3809
|
+
openOrder: (item, bridge, beforeCreate, afterCreate) => options.eventsEnabled ? openTicket(item, bridge, now, beforeCreate, afterCreate) : Promise.resolve(NOT_ENABLED),
|
|
3732
3810
|
readAccess: ticketAccess,
|
|
3733
3811
|
reopenOrder: (order, bridge) => reopen(order, bridge, ticketAccess, now)
|
|
3734
3812
|
}
|
|
@@ -3741,7 +3819,7 @@ function eligible(item, kind, enabled) {
|
|
|
3741
3819
|
const selection = kind === BOOKING ? item.attendance.booking : item.attendance.ticket;
|
|
3742
3820
|
return selection ? { eligible: true } : UNSUPPORTED;
|
|
3743
3821
|
}
|
|
3744
|
-
async function openBooking(item, bridge, beforeCreate) {
|
|
3822
|
+
async function openBooking(item, bridge, beforeCreate, afterCreate) {
|
|
3745
3823
|
if (!eligible(item, BOOKING, true).eligible) return notCreated(ORDER_REFUSED);
|
|
3746
3824
|
const selected = item.attendance.booking;
|
|
3747
3825
|
if (selected.slot.serviceId !== item.reference.id || !isNonEmpty3(selected.slot.startDate) || !isNonEmpty3(selected.slot.endDate)) return notCreated(ORDER_REFUSED);
|
|
@@ -3755,11 +3833,49 @@ async function openBooking(item, bridge, beforeCreate) {
|
|
|
3755
3833
|
if (isRefusal(availability)) return notCreated(attemptRefused(availability));
|
|
3756
3834
|
const entries = isObject7(availability.body) ? availability.body.availabilityEntries : void 0;
|
|
3757
3835
|
if (!Array.isArray(entries) || !entries.some((entry) => isObject7(entry) && entry.bookable === true && matchesSlot(entry.slot, selected.slot))) return notCreated(CHANGED);
|
|
3758
|
-
if (beforeCreate && !beforeCreate()) return notCreated({ status: "refused", reason: "storageUnavailable" });
|
|
3836
|
+
if (beforeCreate && !beforeCreate(slotGuard(selected.slot))) return notCreated({ status: "refused", reason: "storageUnavailable" });
|
|
3759
3837
|
const created = await bridge.call("POST", "/bookings/v2/bookings", { booking: { bookedEntity: { slot: selected.slot }, contactDetails: selected.contactDetails, totalParticipants: 1, selectedPaymentOption: "ONLINE", ...selected.formInfo ? { formInfo: selected.formInfo } : {} } });
|
|
3760
3838
|
if (isRefusal(created)) return creationRefused(created);
|
|
3761
3839
|
const bookingId = bodyObject(created, "booking")?.id;
|
|
3762
|
-
|
|
3840
|
+
if (!isNonEmpty3(bookingId)) return ORDER_REFUSED;
|
|
3841
|
+
afterCreate?.({ verticalRef: { bookingId } });
|
|
3842
|
+
return bookingCheckout(item, bookingId, bridge);
|
|
3843
|
+
}
|
|
3844
|
+
function slotGuard(slot) {
|
|
3845
|
+
const verticalRef = {};
|
|
3846
|
+
for (const key of ["sessionId", "startDate"]) if (isNonEmpty3(slot[key])) verticalRef[key] = slot[key];
|
|
3847
|
+
const ends = latestInstant(String(slot.endDate));
|
|
3848
|
+
return Number.isFinite(ends) ? { verticalRef, releaseAt: ends + RELEASE_MARGIN_MS } : { verticalRef };
|
|
3849
|
+
}
|
|
3850
|
+
function latestInstant(value) {
|
|
3851
|
+
if (HAS_OFFSET.test(value)) return Date.parse(value);
|
|
3852
|
+
return Date.parse(`${value}Z`) + LATEST_ZONE_MS;
|
|
3853
|
+
}
|
|
3854
|
+
async function resolveBookingOpening(guard, item, bridge, options) {
|
|
3855
|
+
const scope = sameSlot(guard.verticalRef, item?.attendance?.booking?.slot) ? "held" : "unrelated";
|
|
3856
|
+
const bookingId = guard.verticalRef?.bookingId;
|
|
3857
|
+
if (!bookingId || !options.settled) return scope;
|
|
3858
|
+
const released2 = await releaseBooking(bookingId, bridge, options.claim);
|
|
3859
|
+
return released2 === "held" || released2 === "unavailable" && scope === "unrelated" ? scope : released2;
|
|
3860
|
+
}
|
|
3861
|
+
async function releaseBooking(bookingId, bridge, claim) {
|
|
3862
|
+
const read2 = await bridge.call("POST", "/bookings/v2/bookings/query", { query: { filter: { id: { $eq: bookingId } } } });
|
|
3863
|
+
if (isRefusal(read2)) return read2.status === "http" && read2.httpStatus === 404 ? "released" : openingRefused(read2);
|
|
3864
|
+
const rows = isObject7(read2.body) ? read2.body.bookings : void 0;
|
|
3865
|
+
const booking = Array.isArray(rows) ? rows.find((b) => isObject7(b) && b.id === bookingId) : void 0;
|
|
3866
|
+
if (!isObject7(booking)) return "held";
|
|
3867
|
+
if (["CANCELED", "CANCELLED", "DECLINED"].includes(String(booking.status)) || PAYMENT_TAKEN.includes(String(booking.paymentStatus))) return "released";
|
|
3868
|
+
if (booking.status !== "CREATED" || !claim()) return "held";
|
|
3869
|
+
const cancelled = await bridge.call("POST", `/bookings/v2/bookings/${encodeURIComponent(bookingId)}/cancel`, { participantNotification: { notifyParticipants: false }, revision: booking.revision });
|
|
3870
|
+
return isRefusal(cancelled) ? openingRefused(cancelled) : "released";
|
|
3871
|
+
}
|
|
3872
|
+
function openingRefused(refusal) {
|
|
3873
|
+
if (refusal.status === "sessionChanged") return "sessionChanged";
|
|
3874
|
+
return refusal.status === "unavailable" ? "unavailable" : "held";
|
|
3875
|
+
}
|
|
3876
|
+
function sameSlot(guarded, slot) {
|
|
3877
|
+
if (!guarded || !slot) return true;
|
|
3878
|
+
return guarded.sessionId === slot.sessionId && Date.parse(guarded.startDate ?? "") === Date.parse(String(slot.startDate));
|
|
3763
3879
|
}
|
|
3764
3880
|
async function bookingCheckout(item, bookingId, bridge) {
|
|
3765
3881
|
const checkout = await bridge.call("POST", "/ecom/v1/checkouts", { lineItems: [{ quantity: 1, catalogReference: { appId: "13d21c63-b5ec-5912-8397-c3a5ddb27a97", catalogItemId: bookingId } }], channelType: "OTHER_PLATFORM" });
|
|
@@ -3788,7 +3904,7 @@ async function bookingAccess(ref, bridge) {
|
|
|
3788
3904
|
if (booking.status === "CANCELED" || booking.status === "CANCELLED" || booking.status === "DECLINED") return "none";
|
|
3789
3905
|
return payment === "PAID" && booking.status === "CONFIRMED" && booking.paymentStatus === "PAID" ? "granted" : "pending";
|
|
3790
3906
|
}
|
|
3791
|
-
async function openTicket(item, bridge, now, beforeCreate) {
|
|
3907
|
+
async function openTicket(item, bridge, now, beforeCreate, afterCreate) {
|
|
3792
3908
|
if (!eligible(item, TICKET, true).eligible) return notCreated(ORDER_REFUSED);
|
|
3793
3909
|
const selected = item.attendance.ticket;
|
|
3794
3910
|
if (!isNonEmpty3(selected.eventId)) return notCreated(ORDER_REFUSED);
|
|
@@ -3799,16 +3915,23 @@ async function openTicket(item, bridge, now, beforeCreate) {
|
|
|
3799
3915
|
const definitions = isObject7(available.body) ? available.body.definitions : void 0;
|
|
3800
3916
|
const live = Array.isArray(definitions) ? definitions.find((t) => isObject7(t) && t.id === item.reference.id && t.saleStatus === "SALE_STARTED") : void 0;
|
|
3801
3917
|
if (!isObject7(live) || !samePrice(live.price, item)) return notCreated(CHANGED);
|
|
3802
|
-
|
|
3803
|
-
if (
|
|
3804
|
-
return
|
|
3918
|
+
const event = bodyObject(read2, "event");
|
|
3919
|
+
if (live.eventId !== selected.eventId || classifyForApple(availableTicketAttendanceOf(event, live), item.attendance.currency) !== "appleIap") return notCreated(ORDER_REFUSED);
|
|
3920
|
+
if (beforeCreate && !beforeCreate({ releaseAt: now() + reservationMinutes(event) * MINUTE_MS + RELEASE_MARGIN_MS })) return notCreated({ status: "refused", reason: "storageUnavailable" });
|
|
3921
|
+
return reserveTicket(item, bridge, now, afterCreate);
|
|
3922
|
+
}
|
|
3923
|
+
function reservationMinutes(event) {
|
|
3924
|
+
const registration = isObject7(event?.registration) ? event.registration : void 0;
|
|
3925
|
+
const minutes = isObject7(registration?.tickets) ? registration.tickets.reservationDurationInMinutes : void 0;
|
|
3926
|
+
return typeof minutes === "number" && minutes > 0 ? minutes : DEFAULT_RESERVATION_MINUTES;
|
|
3805
3927
|
}
|
|
3806
|
-
async function reserveTicket(item, bridge, now) {
|
|
3928
|
+
async function reserveTicket(item, bridge, now, afterCreate) {
|
|
3807
3929
|
const selected = item.attendance.ticket;
|
|
3808
3930
|
const held = await bridge.call("POST", "/events/v1/checkout/reservations", { eventId: selected.eventId, ticketQuantities: [{ ticketDefinitionId: item.reference.id, quantity: 1 }], ignoreLimits: false, allowHiddenTickets: false });
|
|
3809
3931
|
if (isRefusal(held)) return creationRefused(held);
|
|
3810
3932
|
const reservation = held.body;
|
|
3811
3933
|
if (!isObject7(reservation) || !isNonEmpty3(reservation.id) || !future(reservation.expires, now)) return ORDER_CLOSED;
|
|
3934
|
+
afterCreate?.({ verticalRef: { reservationId: reservation.id }, releaseAt: Date.parse(reservation.expires) + RELEASE_MARGIN_MS });
|
|
3812
3935
|
if (!heldAsSelected(reservation, item)) return CHANGED;
|
|
3813
3936
|
const placed = await bridge.call("POST", "/events/v1/checkout", { eventId: selected.eventId, reservationId: reservation.id, buyer: selected.buyer, ...selected.guests ? { guests: selected.guests } : {}, ...selected.buyerSubmission ? { buyerSubmission: selected.buyerSubmission } : {}, ...selected.guestSubmissions ? { guestSubmissions: selected.guestSubmissions } : {}, options: { silent: false, payInPerson: false, ignoreFormValidation: false, markAsPaid: false } });
|
|
3814
3937
|
if (isRefusal(placed)) return attemptRefused(placed);
|
|
@@ -4200,7 +4323,7 @@ function createCheckoutService(opts = {}) {
|
|
|
4200
4323
|
const commerce = createIapCommerce({ adapters: [pricingPlanOrders], onChange: () => {
|
|
4201
4324
|
void svc.pricingPublish();
|
|
4202
4325
|
} });
|
|
4203
|
-
const purchaseCopy = { buy: c.joinCta ?? "
|
|
4326
|
+
const purchaseCopy = { buy: c.joinCta ?? "Buy now", processing: c.pendingNotice ?? "Processing your purchase\u2026", awaitingApproval: "Waiting for approval", unavailable: c.failedNotice ?? "Purchasing is temporarily unavailable.", signInRequired: c.signInFirst ?? "Sign in to join a plan \u2014 memberships belong to a member account.", retry: c.failedNotice ?? "Something went wrong. Try again.", priceChanged: "The price changed. Check it and try again.", support: "We couldn't finish this purchase. Contact support." };
|
|
4204
4327
|
let catalogRows = [];
|
|
4205
4328
|
let items = [];
|
|
4206
4329
|
let started = false;
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
// ../../stdlib/wix-sdk/forms/src/extensions.ts
|
|
2
|
+
var SUBMISSIONS_PATH = "/form-submission-service/v4/submissions";
|
|
3
|
+
function createSubmission(req, opts) {
|
|
4
|
+
if (!req?.submission?.formId) throw new Error("createSubmission: submission.formId is required");
|
|
5
|
+
if (opts?.offline !== "queue") return wixCall("POST", SUBMISSIONS_PATH, req, opts);
|
|
6
|
+
const api = globalThis.himalaya?.wixApi;
|
|
7
|
+
if (!api) return Promise.reject(new Error("@himalaya/wix-forms: host did not install the wixApi bridge"));
|
|
8
|
+
const site = opts.site?.trim();
|
|
9
|
+
const headers = site ? { "wix-site-id": site } : void 0;
|
|
10
|
+
if (!api.offline) return api.call("POST", SUBMISSIONS_PATH, req, headers).then((value) => ({ status: "sent", value }));
|
|
11
|
+
return api.call("POST", SUBMISSIONS_PATH, req, headers, { offline: "queue" });
|
|
12
|
+
}
|
|
13
|
+
function validateFormSubmission(req, opts) {
|
|
14
|
+
if (!req?.submission?.formId) throw new Error("validateFormSubmission: submission.formId is required");
|
|
15
|
+
return wixCall("POST", `${SUBMISSIONS_PATH}/validate`, req, opts);
|
|
16
|
+
}
|
|
17
|
+
|
|
1
18
|
// ../../stdlib/wix-sdk/forms/src/index.ts
|
|
2
19
|
function wixCallHeaders(opts) {
|
|
3
20
|
const site = opts?.site?.trim();
|
|
@@ -67,10 +84,12 @@ function getSubmission(id, opts) {
|
|
|
67
84
|
);
|
|
68
85
|
}
|
|
69
86
|
export {
|
|
87
|
+
createSubmission,
|
|
70
88
|
getForm,
|
|
71
89
|
getSubmission,
|
|
72
90
|
queryForms,
|
|
73
91
|
querySubmissions,
|
|
92
|
+
validateFormSubmission,
|
|
74
93
|
wixCall
|
|
75
94
|
};
|
|
76
95
|
//# sourceMappingURL=wix-forms.mjs.map
|