@rebuy/rebuy 3.59.0 → 3.60.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/index.cjs +17 -1
- package/dist/index.mjs +17 -1
- package/dist/schema/checkout-and-beyond/constants.cjs +2 -0
- package/dist/schema/checkout-and-beyond/constants.mjs +2 -0
- package/dist/schema/checkout-and-beyond/index.cjs +2 -0
- package/dist/schema/checkout-and-beyond/index.mjs +2 -0
- package/dist/schema/offerProduct.d.ts +16 -0
- package/dist/schema/postPurchaseProductSettings.d.ts +1 -0
- package/dist/schema/widgets/checkout-and-beyond/common.d.ts +10 -1
- package/dist/schema/widgets/post-purchase-offer/postPurchaseOffer.d.ts +1 -0
- package/dist/schema/widgets/post-purchase-offer/postPurchaseSettings.d.ts +1 -0
- package/dist/schema/widgets/post-purchase-offer/postPurchaseWidget.d.ts +1 -0
- package/dist/server/index.cjs +1734 -1674
- package/dist/server/index.mjs +1692 -1632
- package/dist/server/normalizePostPurchaseCollection.d.ts +2 -0
- package/dist/server/normalizePostPurchaseProduct.d.ts +4 -0
- package/dist/server/offerProductReviews.d.ts +13 -0
- package/dist/server/postPurchaseReviewData.d.ts +9 -0
- package/dist/server/preparePostPurchaseMemberView.d.ts +4 -0
- package/dist/server/preparePostPurchaseStsMember.d.ts +2 -0
- package/dist/server/projectPostPurchaseProduct.d.ts +1 -0
- package/dist/server/shared.d.ts +2 -2
- package/dist/transforms/index.cjs +3 -0
- package/dist/transforms/index.mjs +3 -0
- package/dist/transforms/postPurchase/productCardSettings.d.ts +1 -0
- package/package.json +1 -1
package/dist/server/index.cjs
CHANGED
|
@@ -383,6 +383,10 @@ var OfferProductVariant = import_zod3.z.object({
|
|
|
383
383
|
price: import_zod3.z.string(),
|
|
384
384
|
title: import_zod3.z.string()
|
|
385
385
|
});
|
|
386
|
+
var OfferProductReviews = import_zod3.z.object({
|
|
387
|
+
rating: import_zod3.z.number().positive().max(5),
|
|
388
|
+
reviewCount: import_zod3.z.number().int().nonnegative()
|
|
389
|
+
});
|
|
386
390
|
var OfferProduct = import_zod3.z.object({
|
|
387
391
|
description: import_zod3.z.string().optional(),
|
|
388
392
|
discount: OfferProductDiscount.optional(),
|
|
@@ -398,6 +402,7 @@ var OfferProduct = import_zod3.z.object({
|
|
|
398
402
|
link: import_zod3.z.string().optional(),
|
|
399
403
|
metafields: import_zod3.z.array(import_zod3.z.object({ key: import_zod3.z.string(), namespace: import_zod3.z.string(), value: import_zod3.z.string() })).optional(),
|
|
400
404
|
options: import_zod3.z.array(OfferProductOption),
|
|
405
|
+
reviews: OfferProductReviews.nullish().catch(void 0),
|
|
401
406
|
sellingPlanGroups: import_zod3.z.array(import_zod3.z.object({ requiresSellingPlan: import_zod3.z.boolean().optional() })).optional(),
|
|
402
407
|
title: import_zod3.z.string(),
|
|
403
408
|
/** At least one variant — a zero-variant product renders an offer card with no addable merchandise (no Add CTA). `keepValidProduct` drops it with a `variants` drift signal rather than shipping a dead card. */
|
|
@@ -406,6 +411,27 @@ var OfferProduct = import_zod3.z.object({
|
|
|
406
411
|
|
|
407
412
|
// src/server/b2bAvailability.ts
|
|
408
413
|
var import_zod4 = require("zod");
|
|
414
|
+
|
|
415
|
+
// src/server/shared.ts
|
|
416
|
+
var REBUY_ENGINE_HOST = "rebuyengine.com";
|
|
417
|
+
var unwrapData = (body) => body && typeof body === "object" && "data" in body ? body.data : body;
|
|
418
|
+
var isEmptyObject = (x) => x == null || typeof x === "object" && !Array.isArray(x) && Object.keys(x).length === 0;
|
|
419
|
+
var UpstreamError = class extends Error {
|
|
420
|
+
constructor(status, body, message) {
|
|
421
|
+
super(message ?? `Upstream returned ${status}`);
|
|
422
|
+
this.body = body;
|
|
423
|
+
this.name = "UpstreamError";
|
|
424
|
+
this.status = status;
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
var NotFoundError = class extends Error {
|
|
428
|
+
constructor(message) {
|
|
429
|
+
super(message);
|
|
430
|
+
this.name = "NotFoundError";
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
// src/server/b2bAvailability.ts
|
|
409
435
|
var B2B_AVAILABILITY_PATH = "/admin/api/v1/shop/b2b-catalog-availability";
|
|
410
436
|
var productGid = (product) => `gid://shopify/Product/${String(product.id)}`;
|
|
411
437
|
var Verdict = import_zod4.z.record(import_zod4.z.string(), import_zod4.z.boolean());
|
|
@@ -413,9 +439,18 @@ var B2bAvailabilityResponse = import_zod4.z.object({
|
|
|
413
439
|
availability: Verdict.optional(),
|
|
414
440
|
data: import_zod4.z.object({ availability: Verdict.optional() }).optional()
|
|
415
441
|
}).transform(({ availability, data }) => availability ?? data?.availability ?? null);
|
|
442
|
+
var MAX_REASON_LENGTH = 120;
|
|
443
|
+
var failureReason = (error) => {
|
|
444
|
+
if (!(error instanceof Error)) return "unknown error";
|
|
445
|
+
const cut = error.message.indexOf(": ");
|
|
446
|
+
const label2 = (cut === -1 ? error.message : error.message.slice(0, cut)).slice(0, MAX_REASON_LENGTH);
|
|
447
|
+
if (!(error instanceof UpstreamError)) return label2 || error.name;
|
|
448
|
+
return label2 && label2 !== `Upstream returned ${error.status}` ? `upstream ${error.status}: ${label2}` : `upstream ${error.status}`;
|
|
449
|
+
};
|
|
416
450
|
var filterByB2bAvailability = async (products, input, ctx) => {
|
|
417
451
|
if (!input.companyLocationId || products.length === 0) return products;
|
|
418
452
|
let verdict;
|
|
453
|
+
let reason = "unreadable verdict";
|
|
419
454
|
try {
|
|
420
455
|
const response = await ctx.fetchUpstream(
|
|
421
456
|
B2B_AVAILABILITY_PATH,
|
|
@@ -434,12 +469,13 @@ var filterByB2bAvailability = async (products, input, ctx) => {
|
|
|
434
469
|
);
|
|
435
470
|
const parsed = B2bAvailabilityResponse.safeParse(response);
|
|
436
471
|
verdict = parsed.success ? parsed.data : null;
|
|
437
|
-
} catch {
|
|
472
|
+
} catch (error) {
|
|
438
473
|
verdict = null;
|
|
474
|
+
reason = failureReason(error);
|
|
439
475
|
}
|
|
440
476
|
if (verdict === null) {
|
|
441
477
|
ctx.reportDrift?.({
|
|
442
|
-
detail:
|
|
478
|
+
detail: `b2b availability check failed (${reason}) \u2014 products served unfiltered`,
|
|
443
479
|
kind: "b2bAvailability"
|
|
444
480
|
});
|
|
445
481
|
return products;
|
|
@@ -447,265 +483,48 @@ var filterByB2bAvailability = async (products, input, ctx) => {
|
|
|
447
483
|
return products.filter((product) => verdict[productGid(product)] !== false);
|
|
448
484
|
};
|
|
449
485
|
|
|
450
|
-
// src/server/
|
|
451
|
-
var
|
|
452
|
-
var unwrapData = (body) => body && typeof body === "object" && "data" in body ? body.data : body;
|
|
453
|
-
var isEmptyObject = (x) => x == null || typeof x === "object" && !Array.isArray(x) && Object.keys(x).length === 0;
|
|
454
|
-
var UpstreamError = class extends Error {
|
|
455
|
-
constructor(status, body, message) {
|
|
456
|
-
super(message ?? `Upstream returned ${status}`);
|
|
457
|
-
this.body = body;
|
|
458
|
-
this.name = "UpstreamError";
|
|
459
|
-
this.status = status;
|
|
460
|
-
}
|
|
461
|
-
};
|
|
462
|
-
var NotFoundError = class extends Error {
|
|
463
|
-
constructor(message) {
|
|
464
|
-
super(message);
|
|
465
|
-
this.name = "NotFoundError";
|
|
466
|
-
}
|
|
467
|
-
};
|
|
468
|
-
|
|
469
|
-
// src/server/shopSubtotal.ts
|
|
470
|
-
var shopCurrencyRate = (cart) => {
|
|
471
|
-
const rate = cart.currencyRate ?? 1;
|
|
472
|
-
return Number.isFinite(rate) && rate > 0 ? rate : 1;
|
|
473
|
-
};
|
|
474
|
-
var shopSubtotalCents = (cart) => Math.round((cart.subtotal - (cart.discountTotal ?? 0)) / shopCurrencyRate(cart));
|
|
475
|
-
var toShopCents = (majorPresentment, rate) => Math.round(majorPresentment * 100 / rate);
|
|
486
|
+
// src/server/postPurchaseReviewData.ts
|
|
487
|
+
var import_zod17 = require("zod");
|
|
476
488
|
|
|
477
|
-
// src/schema/
|
|
478
|
-
var
|
|
489
|
+
// src/schema/postPurchaseProductReviews.ts
|
|
490
|
+
var import_zod12 = require("zod");
|
|
479
491
|
|
|
480
|
-
// src/schema/
|
|
481
|
-
var
|
|
492
|
+
// src/schema/widgets/post-purchase-offer/postPurchaseSettings.ts
|
|
493
|
+
var import_zod11 = require("zod");
|
|
482
494
|
|
|
483
|
-
// src/schema/
|
|
495
|
+
// src/schema/widgets/post-purchase-offer/common.ts
|
|
496
|
+
var import_compat = require("es-toolkit/compat");
|
|
484
497
|
var import_zod5 = require("zod");
|
|
485
|
-
var
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
variantIds: import_zod5.z.array(import_zod5.z.coerce.number()).optional()
|
|
491
|
-
});
|
|
492
|
-
var SmartCartTierExclusion = import_zod5.z.looseObject({
|
|
493
|
-
collectionIds: import_zod5.z.array(import_zod5.z.coerce.number()).optional().catch(void 0),
|
|
494
|
-
productIds: import_zod5.z.array(import_zod5.z.coerce.number()).optional().catch(void 0),
|
|
495
|
-
tags: import_zod5.z.array(import_zod5.z.string()).optional().catch(void 0),
|
|
496
|
-
type: import_zod5.z.string().optional().catch(void 0)
|
|
497
|
-
});
|
|
498
|
-
var SmartCartTier = import_zod5.z.looseObject({
|
|
499
|
-
allProducts: import_zod5.z.array(SmartCartTierProduct).optional(),
|
|
500
|
-
/** Merchant-set tier label (e.g. "Free gift", "$100 reward"), shown on the step row when enabled. */
|
|
501
|
-
customTierLabel: import_zod5.z.boolean().optional(),
|
|
502
|
-
customTierLabelText: import_zod5.z.string().optional(),
|
|
503
|
-
decorativeAmountReachedLabel: import_zod5.z.boolean().optional(),
|
|
504
|
-
decorativeAmountReachedLabelText: import_zod5.z.string().optional(),
|
|
505
|
-
decorativeAmountRemainingLabel: import_zod5.z.boolean().optional(),
|
|
506
|
-
decorativeAmountRemainingLabelText: import_zod5.z.string().optional(),
|
|
507
|
-
/** Order-discount reward: `'fixedAmount'` (shop-currency dollars) or `'percentage'` (whole percent). */
|
|
508
|
-
discountAmountFromTotal: import_zod5.z.coerce.number().optional(),
|
|
509
|
-
discountAmountReachedLabel: import_zod5.z.boolean().optional(),
|
|
510
|
-
discountAmountReachedLabelText: import_zod5.z.string().optional(),
|
|
511
|
-
discountAmountRemainingLabel: import_zod5.z.boolean().optional(),
|
|
512
|
-
discountAmountRemainingLabelText: import_zod5.z.string().optional(),
|
|
513
|
-
discountType: import_zod5.z.string().optional(),
|
|
514
|
-
/**
|
|
515
|
-
* onsite `exclusions` + `exclusions_enabled` (REB-22305): per-tier rules the converter carries onto
|
|
516
|
-
* `CABProgressTier.exclusions`. `.catch(undefined)` for the same blast-radius reason as `productTierImage`:
|
|
517
|
-
* one drifted value must degrade to "no tier exclusions", never drop every progress bar for the shop.
|
|
518
|
-
*
|
|
519
|
-
* `exclusionsEnabled` is a STRICT boolean on purpose, even though failing open here changes the tier's math
|
|
520
|
-
* (a non-boolean reads as disabled) rather than just an icon. onsite reads its sibling tier flags strictly —
|
|
521
|
-
* `shouldFilterOutOfStockVariantsFromTier` is `tier?.filter_oos_variants === true`, and its `progressBar.ts`
|
|
522
|
-
* types every tier flag as `boolean` — so a stored `1` / `"1"` / `"true"` is "disabled" on the onsite bar too.
|
|
523
|
-
* A truthiness preprocess would make CAB exclude where onsite does not: the opposite parity break.
|
|
524
|
-
*/
|
|
525
|
-
exclusions: import_zod5.z.array(SmartCartTierExclusion).optional().catch(void 0),
|
|
526
|
-
exclusionsEnabled: import_zod5.z.boolean().optional().catch(void 0),
|
|
527
|
-
filterOosVariants: import_zod5.z.boolean().optional(),
|
|
528
|
-
id: import_zod5.z.string().optional(),
|
|
529
|
-
/**
|
|
530
|
-
* A `null`/absent minimum stays `undefined` (NOT coerced to `0`): a threshold-0 tier is always reached
|
|
531
|
-
* and would auto-add its gift to every cart. onsite's `isTierDataValid` drops a non-numeric minimum for
|
|
532
|
-
* exactly this reason; the converter's `renderableTiers` mirrors that (`Number.isFinite`). A literal `0`
|
|
533
|
-
* is kept — onsite keeps it too. DELIBERATE DIVERGENCE from onsite for string minimums: onsite's
|
|
534
|
-
* `isTierDataValid` is a strict `typeof === 'number'`, so it drops `'50'`; the converter instead coerces
|
|
535
|
-
* `'50' → 50` and keeps the tier (a numeric-string minimum is a valid threshold, not a data defect).
|
|
536
|
-
*/
|
|
537
|
-
minimum: import_zod5.z.preprocess((value) => value == null ? void 0 : value, import_zod5.z.coerce.number().optional()),
|
|
538
|
-
presentmentCurrencies: import_zod5.z.looseObject({ enabled: import_zod5.z.boolean().optional() }).optional(),
|
|
539
|
-
productAmountReachedLabel: import_zod5.z.boolean().optional(),
|
|
540
|
-
productAmountReachedLabelText: import_zod5.z.string().optional(),
|
|
541
|
-
productAmountRemainingLabel: import_zod5.z.boolean().optional(),
|
|
542
|
-
productAmountRemainingLabelText: import_zod5.z.string().optional(),
|
|
543
|
-
products: import_zod5.z.array(SmartCartTierProduct).optional(),
|
|
544
|
-
/**
|
|
545
|
-
* onsite `product_tier_element_size`: the step-row icon's square size as a px STRING (`'18px'` …
|
|
546
|
-
* `'36px'` — the admin's five-value Size control, default `'18px'`). React stamps it onto the icon
|
|
547
|
-
* SVG's `width`/`height` (`getProgressStepIconSize`), so the milestone renders at the merchant's
|
|
548
|
-
* chosen size; the converter turns it into `CABProgressTier.iconSizePx` for the CAB renderer.
|
|
549
|
-
*
|
|
550
|
-
* `.catch(undefined)` for the same blast-radius reason as `productTierImage` below: this key was
|
|
551
|
-
* previously unknown-and-ignored by the `looseObject`, and `SmartCartConfig` is parsed
|
|
552
|
-
* `.nullish().catch(undefined)` with no intermediate catch, so one drifted value (a bare number, a
|
|
553
|
-
* `'2rem'`) would drop EVERY progress bar for the shop rather than just this setting. Failing open to
|
|
554
|
-
* `undefined` lands on the documented 18px default — strictly safer than that blast radius. The
|
|
555
|
-
* converter parses the number out and clamps it, so a junk-but-string value degrades the same way.
|
|
556
|
-
*/
|
|
557
|
-
productTierElementSize: import_zod5.z.string().optional().catch(void 0),
|
|
558
|
-
/**
|
|
559
|
-
* onsite `product_tier_image`: on a product (gift) tier, show the gift's product image in the step-row
|
|
560
|
-
* slot instead of the generic bag icon (React `TierProgressIcon` swaps in the image when this is set and
|
|
561
|
-
* an image resolves). Per-tier; the client resolves the image (config carries only product IDs).
|
|
562
|
-
*
|
|
563
|
-
* `.catch(undefined)` is load-bearing. This key was previously unknown-and-ignored by the `looseObject`;
|
|
564
|
-
* declaring it as a real boolean means a stored non-boolean (`1` / `"1"` / `"true"`) would now FAIL the
|
|
565
|
-
* tier — and since `SmartCartConfig` is parsed `.nullish().catch(undefined)` (userConfig/cabShopConfig)
|
|
566
|
-
* with no intermediate catch, one drifted flag would drop EVERY progress bar for the shop, not just the
|
|
567
|
-
* flag. The converter only reads it for truthiness (`gift && tier.productTierImage`), so failing open to
|
|
568
|
-
* `undefined` (bag-icon fallback, the documented default) is strictly safer than that blast radius.
|
|
569
|
-
*/
|
|
570
|
-
productTierImage: import_zod5.z.boolean().optional().catch(void 0),
|
|
571
|
-
type: import_zod5.z.string().optional(),
|
|
572
|
-
/**
|
|
573
|
-
* onsite's PER-TIER unit switch (`unlock_condition_type`): `'item_quantity'` makes `minimum` an
|
|
574
|
-
* item count (checked before any money handling — no ×100, no FX, no presentment overrides,
|
|
575
|
-
* mirroring onsite `getTierMinimum`); anything else (or absent) keeps the money semantics.
|
|
576
|
-
*/
|
|
577
|
-
unlockConditionType: import_zod5.z.string().optional()
|
|
578
|
-
});
|
|
579
|
-
var SmartCartBar = import_zod5.z.looseObject({
|
|
580
|
-
countryCodes: import_zod5.z.array(import_zod5.z.string()).optional(),
|
|
581
|
-
/**
|
|
582
|
-
* onsite `exclude_discount_in_subtotal`: measure progress against the PRE-discount subtotal so an
|
|
583
|
-
* applied code/order discount doesn't lower progress. The client adds cart discount allocations back.
|
|
584
|
-
*/
|
|
585
|
-
excludeDiscountInSubtotal: import_zod5.z.boolean().optional(),
|
|
586
|
-
/** Products excluded from the progress subtotal; the client subtracts their variants' cart cost. */
|
|
587
|
-
excludedProducts: import_zod5.z.array(import_zod5.z.looseObject({ variantIds: import_zod5.z.array(import_zod5.z.coerce.number()).optional() })).optional(),
|
|
588
|
-
freeShippingOnSubscription: import_zod5.z.boolean().optional(),
|
|
589
|
-
geolocationEnabled: import_zod5.z.boolean().optional(),
|
|
590
|
-
id: import_zod5.z.string().optional(),
|
|
591
|
-
language: import_zod5.z.looseObject({
|
|
592
|
-
freeShippingReached: import_zod5.z.string().optional(),
|
|
593
|
-
freeShippingRemaining: import_zod5.z.string().optional(),
|
|
594
|
-
giftAreaTitle: import_zod5.z.string().optional()
|
|
595
|
-
}).optional(),
|
|
596
|
-
name: import_zod5.z.string().optional(),
|
|
597
|
-
tiers: import_zod5.z.array(SmartCartTier).optional()
|
|
598
|
-
});
|
|
599
|
-
var SmartCartComponent = import_zod5.z.looseObject({
|
|
600
|
-
settings: import_zod5.z.looseObject({ bars: import_zod5.z.array(SmartCartBar).optional() }).optional(),
|
|
601
|
-
type: import_zod5.z.string().optional()
|
|
602
|
-
});
|
|
603
|
-
var SmartCartConfig = import_zod5.z.looseObject({
|
|
604
|
-
components: import_zod5.z.array(SmartCartComponent).optional()
|
|
605
|
-
});
|
|
498
|
+
var strictNumber = import_zod5.z.union([
|
|
499
|
+
import_zod5.z.number(),
|
|
500
|
+
import_zod5.z.string().transform((value) => (0, import_compat.toNumber)((0, import_compat.replace)((0, import_compat.toString)(value), /[^0-9.]/g, "")) || 0),
|
|
501
|
+
import_zod5.z.unknown().transform(() => 0)
|
|
502
|
+
]);
|
|
606
503
|
|
|
607
|
-
// src/schema/
|
|
608
|
-
var
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
var
|
|
621
|
-
/**
|
|
622
|
-
* Per-element resilient: parse as `unknown[]` (non-array → `[]`), then keep only the experiments that
|
|
623
|
-
* validate. A single drifted experiment drops itself instead of `.catch`-ing the WHOLE array to `[]` and
|
|
624
|
-
* silently disabling every live A/B test fleet-wide.
|
|
625
|
-
*/
|
|
626
|
-
activeExperiments: import_zod6.z.array(import_zod6.z.unknown()).catch([]).default([]).transform(
|
|
627
|
-
(experiments) => experiments.flatMap((experiment) => {
|
|
628
|
-
const result = CabActiveExperiment.safeParse(experiment);
|
|
629
|
-
return result.success ? [result.data] : [];
|
|
630
|
-
})
|
|
631
|
-
),
|
|
632
|
-
/**
|
|
633
|
-
* Only the two fields the smart-cart entitlement gate reads (`shortName`/`isActive`). Per-element
|
|
634
|
-
* resilient like `activeExperiments`: a drifted package entry degrades to an inert `''`/false one that
|
|
635
|
-
* matches nothing, so a real active `cart-merchandising` package still gates correctly and a sibling
|
|
636
|
-
* drift never fails the shared config parse. Note the salvage is fail-CLOSED, not fail-open, for an
|
|
637
|
-
* entitled v6 shop: a malformed whole array (⇒ `[]`) or an inerted `cart-merchandising` entry (e.g.
|
|
638
|
-
* `is_active: 1` ⇒ inactive) makes the gate find no active package and drop every bar. That matches
|
|
639
|
-
* React's "no proof of entitlement ⇒ render null", but it silently removes bars — so the server gate
|
|
640
|
-
* ({@link file://../server/widgetSettings.ts} `fetchProgressBarContext`) emits a `shopConfig` drift
|
|
641
|
-
* when it sees the inert-entry sentinel (`shortName === ''`). The whole-array `[]` case leaves no
|
|
642
|
-
* sentinel and is not separately signalable here.
|
|
643
|
-
*/
|
|
644
|
-
activePackages: import_zod6.z.array(import_zod6.z.object({ isActive: import_zod6.z.boolean(), shortName: import_zod6.z.string() }).catch({ isActive: false, shortName: "" })).catch([]).default([]),
|
|
645
|
-
apiKey: import_zod6.z.string(),
|
|
646
|
-
/** The shop's billing generation; the smart-cart entitlement gate only fires for `'v6'`. Missing/drift ⇒ `null` (fail open, ungated). */
|
|
647
|
-
billingVersion: import_zod6.z.string().nullable().catch(null).default(null),
|
|
648
|
-
/**
|
|
649
|
-
* The shop's rotating cache-buster: `onsite_cache_key` internally — a unix timestamp the engine bumps,
|
|
650
|
-
* and the edge copy of this config purges, on every widget/settings/theme edit — but serialized on the
|
|
651
|
-
* wire as `cache_key`, which `deepCamelCase` maps to this field (renaming it `onsiteCacheKey` would
|
|
652
|
-
* sever the mapping silently; the wire-level assertion in `userConfig.test.ts` is what fails loudly).
|
|
653
|
-
* Threaded onto the widgets/settings read as `cache_key` so the engine marks the response
|
|
654
|
-
* immutable-cacheable and the `cached.*` edge serves it fresh-by-URL. The engine sends a numeric
|
|
655
|
-
* string — coerce — but admit only number/string inputs and constrain to a positive integer: a bare
|
|
656
|
-
* coercion folds `null`/`''`/`false` to `0` and `true` to `1` — "valid" numbers that would go upstream
|
|
657
|
-
* as a constant never-rotating buster and pin the edge copy permanently stale. A real key is always a
|
|
658
|
-
* positive int sent as number or string, so everything else lands on `.catch()` and degrades that read
|
|
659
|
-
* to un-busted (origin-served — slower, never stale), never a parse fail.
|
|
660
|
-
*/
|
|
661
|
-
cacheKey: import_zod6.z.union([import_zod6.z.number(), import_zod6.z.string()]).transform((value) => Number(value)).pipe(import_zod6.z.number().int().positive()).optional().catch(void 0),
|
|
662
|
-
/**
|
|
663
|
-
* The shop's base-currency ISO code (e.g. `'USD'`). CAB derives the shop minor-unit exponent from it
|
|
664
|
-
* (`currencyDecimals`) so a Functions-applied fixed discount — whose amount is in shop minor units —
|
|
665
|
-
* converts to the buyer's currency exactly in a cross-decimal market. `.catch()` like its siblings: a
|
|
666
|
-
* missing/renamed currency degrades to "unknown" (client falls back to buyer decimals), never a parse fail.
|
|
667
|
-
*/
|
|
668
|
-
currency: import_zod6.z.string().optional().catch(void 0),
|
|
669
|
-
/**
|
|
670
|
-
* The merchant's "Use Markets in Data Sources" toggle. The engine (CI2) never reads it on the serve
|
|
671
|
-
* path, so the proxy honouring it before sending market context is what makes the setting mean
|
|
672
|
-
* anything (REB-21688). Fail-CLOSED, unlike the fail-open siblings: a missing/null/drifted field reads
|
|
673
|
-
* as markets OFF — market context silently dropped (engine serves shop-default market), never sent
|
|
674
|
-
* against the merchant's setting. The OFF-reading salvages stay distinguishable: missing AND null are
|
|
675
|
-
* the engine's normal absent vocabulary (`.nullish()`, like `monetize`/`billingVersion`) and read as
|
|
676
|
-
* the plain default — not drift — while only a drifted SHAPE `.catch`es, to the {@link DRIFTED_MARKETS}
|
|
677
|
-
* identity sentinel, so `fetchUserConfig` can emit a `shopConfig` drift for the one case that means an
|
|
678
|
-
* engine rename/retype; otherwise a markets-enabled merchant degrading to shop-default pricing would
|
|
679
|
-
* be indistinguishable from markets genuinely off. The missing-key case is EXPLICIT via `.default()`
|
|
680
|
-
* (a factory, so parses never share a mutable object) rather than inferred from zod running an
|
|
681
|
-
* optional key's transform on `undefined`; `null` flows past the default through `.nullish()` into the
|
|
682
|
-
* transform. `Readonly` on the output type because the drifted salvage IS frozen — an assignment to
|
|
683
|
-
* `markets.enabled` downstream would throw only for drifted shops in production, so surface direct
|
|
684
|
-
* writes to tsc (a guard for the direct case only: TS doesn't check `readonly` in assignability, so
|
|
685
|
-
* laundering through a mutable-shaped alias still compiles).
|
|
686
|
-
* The inner `enabled` stays strict on purpose: `{ enabled: null }` is a genuine retype and drifting is
|
|
687
|
-
* the correct answer (the editor-path `ShopConfig.markets` would hard-fail the same payload).
|
|
688
|
-
*/
|
|
689
|
-
markets: import_zod6.z.object({ enabled: import_zod6.z.boolean() }).nullish().catch(DRIFTED_MARKETS).default(() => ({ enabled: false })).transform((markets) => markets ?? { enabled: false }),
|
|
690
|
-
monetize: import_zod6.z.object({ publisherKey: import_zod6.z.string().nullable() }).nullish().catch(void 0),
|
|
691
|
-
shopId: import_zod6.z.number().optional().catch(void 0),
|
|
692
|
-
/**
|
|
693
|
-
* The merchant's display name ("Gift Basket Store") — the Monetize header copy reads it.
|
|
694
|
-
* `.catch()` like its siblings: a missing/drifted name degrades the header to the
|
|
695
|
-
* myshopify-domain slug (the pre-CAB React fallback), never a parse fail. An empty string is a
|
|
696
|
-
* VALID parse — the slug fallback for `''` (and whitespace/tag-only names) lives in
|
|
697
|
-
* composeOffer's `||` chain, not here.
|
|
698
|
-
*/
|
|
699
|
-
shopName: import_zod6.z.string().nullish().catch(void 0)
|
|
700
|
-
});
|
|
701
|
-
var CabUserConfig = import_zod6.z.object({
|
|
702
|
-
shop: CabShopConfig,
|
|
703
|
-
smartCart: SmartCartConfig.nullish().catch(void 0)
|
|
704
|
-
});
|
|
504
|
+
// src/schema/widgets/post-purchase-offer/constants.ts
|
|
505
|
+
var import_zod6 = require("zod");
|
|
506
|
+
var blockTypes = [
|
|
507
|
+
"callout_banner",
|
|
508
|
+
"image",
|
|
509
|
+
"image_content",
|
|
510
|
+
"pay_button",
|
|
511
|
+
"product_information",
|
|
512
|
+
"separator",
|
|
513
|
+
"text",
|
|
514
|
+
"timer"
|
|
515
|
+
];
|
|
516
|
+
var blockType = import_zod6.z.enum(blockTypes);
|
|
517
|
+
var BlockType = blockType.enum;
|
|
705
518
|
|
|
706
|
-
// src/schema/widgets/
|
|
707
|
-
var
|
|
708
|
-
var
|
|
519
|
+
// src/schema/widgets/post-purchase-offer/postPurchaseBlocks.ts
|
|
520
|
+
var import_compat4 = require("es-toolkit/compat");
|
|
521
|
+
var import_uuid2 = require("uuid");
|
|
522
|
+
var import_zod10 = require("zod");
|
|
523
|
+
|
|
524
|
+
// src/schema/widgets/checkout-and-beyond/text.ts
|
|
525
|
+
var import_compat3 = require("es-toolkit/compat");
|
|
526
|
+
var import_uuid = require("uuid");
|
|
527
|
+
var import_zod9 = require("zod");
|
|
709
528
|
|
|
710
529
|
// src/schema/widgets/checkout-and-beyond/common.ts
|
|
711
530
|
var freezeEnum = (values2) => Object.freeze(Object.fromEntries(values2.map((v) => [v, v])));
|
|
@@ -859,6 +678,7 @@ var sectionTypes = [
|
|
|
859
678
|
"variants"
|
|
860
679
|
];
|
|
861
680
|
var SectionType = freezeEnum(sectionTypes);
|
|
681
|
+
var SALVAGED_SECTION_TYPE = "unknown";
|
|
862
682
|
var spacings = ["none", "extraTight", "tight", "base", "loose", "extraLoose"];
|
|
863
683
|
var Spacing = freezeEnum(spacings);
|
|
864
684
|
var textAlignments = ["start", "center", "end"];
|
|
@@ -909,34 +729,1092 @@ var widgetTypes = [
|
|
|
909
729
|
];
|
|
910
730
|
var WidgetType = freezeEnum(widgetTypes);
|
|
911
731
|
|
|
912
|
-
// src/schema/widgets/checkout-and-beyond/
|
|
913
|
-
var
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
732
|
+
// src/schema/widgets/checkout-and-beyond/regex.ts
|
|
733
|
+
var DYNAMIC_TOKEN_REGEX = /^\{\{\s*[A-Za-z]+\s*\}\}$/;
|
|
734
|
+
var HEX_COLOR_REGEX = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
735
|
+
var ROOT_RELATIVE_PATH_REGEX = /^\/(?!\/)/;
|
|
736
|
+
var HTML_TAGS_REGEX = /<\/?[a-zA-Z][^>]*>/g;
|
|
737
|
+
|
|
738
|
+
// src/schema/widgets/checkout-and-beyond/utils.ts
|
|
739
|
+
var import_es_toolkit2 = require("es-toolkit");
|
|
740
|
+
var import_compat2 = require("es-toolkit/compat");
|
|
741
|
+
|
|
742
|
+
// src/transforms/convertNumericObjects.ts
|
|
743
|
+
var import_es_toolkit = require("es-toolkit");
|
|
744
|
+
var ARRAY_INDEX_STRING = /^(?:0|[1-9]\d*)$/;
|
|
745
|
+
var hasOnlyNumericKeys = (input, requireCompleteRun) => {
|
|
746
|
+
const keys = Object.keys(input);
|
|
747
|
+
if (keys.length === 0) return false;
|
|
748
|
+
if (!keys.every((key) => ARRAY_INDEX_STRING.test(key) && Number.isSafeInteger(Number(key)))) return false;
|
|
749
|
+
if (!requireCompleteRun) return true;
|
|
750
|
+
const sorted = keys.map(Number).sort((a, b) => a - b);
|
|
751
|
+
return sorted.every((n, i) => n === i);
|
|
752
|
+
};
|
|
753
|
+
var numericObjectToArray = (input) => Object.entries(input).sort(([a], [b]) => Number(a) - Number(b)).map(([, value]) => value);
|
|
754
|
+
var convert = (input, requireCompleteRun) => {
|
|
755
|
+
if (Array.isArray(input)) return input.map((item) => convert(item, requireCompleteRun));
|
|
756
|
+
if ((0, import_es_toolkit.isPlainObject)(input)) {
|
|
757
|
+
if (hasOnlyNumericKeys(input, requireCompleteRun)) {
|
|
758
|
+
return numericObjectToArray(input).map((item) => convert(item, requireCompleteRun));
|
|
759
|
+
}
|
|
760
|
+
const out = {};
|
|
761
|
+
for (const [key, value] of Object.entries(input)) out[key] = convert(value, requireCompleteRun);
|
|
762
|
+
return out;
|
|
763
|
+
}
|
|
764
|
+
return input;
|
|
765
|
+
};
|
|
766
|
+
var convertNumericObjects = (input) => convert(input, true);
|
|
767
|
+
|
|
768
|
+
// src/schema/widgets/checkout-and-beyond/utils.ts
|
|
769
|
+
var isHTML = (html = "") => {
|
|
770
|
+
if (typeof window !== "undefined") {
|
|
771
|
+
const parser = new DOMParser();
|
|
772
|
+
const doc = parser.parseFromString(html, "text/html");
|
|
773
|
+
const hasHTML = (nodeList) => Array.from(nodeList).some((node) => node.nodeType === 1);
|
|
774
|
+
return hasHTML(doc.body.childNodes) || hasHTML(doc.head.childNodes);
|
|
775
|
+
}
|
|
776
|
+
return html.search(HTML_TAGS_REGEX) !== -1;
|
|
777
|
+
};
|
|
778
|
+
var hasHTMLInDoc = (doc) => doc.content.some(({ content = [] }) => content.some(({ text: text2 }) => isHTML(text2)));
|
|
779
|
+
var checkForHTML = (input) => !((0, import_compat2.isString)(input) && isHTML(input) || (0, import_es_toolkit2.isPlainObject)(input) && hasHTMLInDoc(input));
|
|
780
|
+
var NO_HTML = { message: "HTML is not supported" };
|
|
781
|
+
var isSectionType = (sectionType) => (section) => (0, import_compat2.get)(section, "sectionType") === sectionType;
|
|
782
|
+
var isBannerType = isSectionType(SectionType.banner);
|
|
783
|
+
var isButtonType = isSectionType(SectionType.button);
|
|
784
|
+
var isCarouselType = isSectionType(SectionType.carousel);
|
|
785
|
+
var isCartLineType = isSectionType(SectionType.cartLine);
|
|
786
|
+
var isDataSourceType = isSectionType(
|
|
787
|
+
SectionType.dataSource
|
|
788
|
+
);
|
|
789
|
+
var isDiscountType = isSectionType(SectionType.discount);
|
|
790
|
+
var isImageType = isSectionType(SectionType.image);
|
|
791
|
+
var isLayoutType = isSectionType(SectionType.layout);
|
|
792
|
+
var isMonetizeType = isSectionType(SectionType.monetize);
|
|
793
|
+
var isOffersType = isSectionType(SectionType.offers);
|
|
794
|
+
var isProductType = isSectionType(SectionType.product);
|
|
795
|
+
var isProductsType = isSectionType(SectionType.products);
|
|
796
|
+
var isProgressBarType = isSectionType(
|
|
797
|
+
SectionType.progressBar
|
|
798
|
+
);
|
|
799
|
+
var isQuantityType = isSectionType(SectionType.quantity);
|
|
800
|
+
var isReviewsType = isSectionType(SectionType.reviews);
|
|
801
|
+
var isTextType = isSectionType(SectionType.text);
|
|
802
|
+
var isVariantsType = isSectionType(SectionType.variants);
|
|
803
|
+
|
|
804
|
+
// src/schema/widgets/checkout-and-beyond/variables.ts
|
|
805
|
+
var import_zod8 = require("zod");
|
|
806
|
+
|
|
807
|
+
// src/schema/widgets/checkout-and-beyond/rule.ts
|
|
808
|
+
var import_zod7 = require("zod");
|
|
809
|
+
var ruleTypes = [
|
|
810
|
+
"cart",
|
|
811
|
+
"cart_count",
|
|
812
|
+
"cart_item_count",
|
|
813
|
+
"cart_line_count",
|
|
814
|
+
"cart_subtotal",
|
|
815
|
+
"collection",
|
|
816
|
+
"customer",
|
|
817
|
+
"customer_order_count",
|
|
818
|
+
"customer_tag",
|
|
819
|
+
"customer_total_spent",
|
|
820
|
+
"date",
|
|
821
|
+
"product",
|
|
822
|
+
"product_tag",
|
|
823
|
+
"product_title",
|
|
824
|
+
"product_type",
|
|
825
|
+
"product_vendor"
|
|
826
|
+
];
|
|
827
|
+
var ruleType = import_zod7.z.enum(ruleTypes);
|
|
828
|
+
var RuleType = ruleType.enum;
|
|
829
|
+
var ruleOperators = [
|
|
830
|
+
"after",
|
|
831
|
+
"anything",
|
|
832
|
+
"before",
|
|
833
|
+
"contains",
|
|
834
|
+
"contains_any",
|
|
835
|
+
"does_not_contain",
|
|
836
|
+
"does_not_contain_any",
|
|
837
|
+
"equals",
|
|
838
|
+
"does_not_equal",
|
|
839
|
+
"greater_than",
|
|
840
|
+
"less_than"
|
|
841
|
+
];
|
|
842
|
+
var ruleOperator = import_zod7.z.enum(ruleOperators);
|
|
843
|
+
var RuleOperator = ruleOperator.enum;
|
|
844
|
+
var RuleCondition = import_zod7.z.object({
|
|
845
|
+
operator: import_zod7.z.enum(ruleOperators).default(RuleOperator.anything),
|
|
846
|
+
products: import_zod7.z.union([import_zod7.z.array(import_zod7.z.unknown()), import_zod7.z.strictObject({}).transform(() => [])]).default(() => []),
|
|
847
|
+
type: import_zod7.z.enum(ruleTypes).default(RuleType.cart_subtotal),
|
|
848
|
+
value: import_zod7.z.coerce.string().default("")
|
|
849
|
+
});
|
|
850
|
+
var RuleLogicBlock = import_zod7.z.object({
|
|
851
|
+
rules: import_zod7.z.array(RuleCondition).default(() => [])
|
|
852
|
+
});
|
|
853
|
+
var CABRulesetEntry = import_zod7.z.object({
|
|
854
|
+
exitIfMatched: import_zod7.z.boolean().default(true),
|
|
855
|
+
logic: import_zod7.z.array(RuleLogicBlock).default(() => []),
|
|
856
|
+
output: import_zod7.z.array(
|
|
857
|
+
import_zod7.z.object({
|
|
858
|
+
key: import_zod7.z.string().default("should_show"),
|
|
859
|
+
type: import_zod7.z.literal("data_json").default("data_json"),
|
|
860
|
+
value: import_zod7.z.string().default("true")
|
|
861
|
+
})
|
|
862
|
+
).default(() => [{ key: "should_show", type: "data_json", value: "true" }])
|
|
863
|
+
});
|
|
864
|
+
var CABRuleset = import_zod7.z.union([import_zod7.z.array(CABRulesetEntry), import_zod7.z.strictObject({}).transform(() => [])]).default(() => []);
|
|
865
|
+
|
|
866
|
+
// src/schema/widgets/checkout-and-beyond/variables.ts
|
|
867
|
+
var variableEffect = import_zod8.z.enum(variableEffects);
|
|
868
|
+
var CABVariableSeed = import_zod8.z.object({
|
|
869
|
+
dataSourceId: import_zod8.z.number().nullable().default(null),
|
|
870
|
+
ruleset: CABRuleset
|
|
871
|
+
});
|
|
872
|
+
var CABBooleanVariable = import_zod8.z.object({
|
|
873
|
+
/**
|
|
874
|
+
* Holds until the first seed verdict lands (and forever, for unseeded variables). Omitted, it derives
|
|
875
|
+
* from seededness — `false` with a `seed` (visibility is EARNED), `true` without — via the transform
|
|
876
|
+
* below; a cross-field default has no `.default()` spelling. An explicit value always wins.
|
|
877
|
+
*/
|
|
878
|
+
defaultValue: import_zod8.z.boolean().optional(),
|
|
879
|
+
name: import_zod8.z.string().min(1),
|
|
880
|
+
seed: CABVariableSeed.optional(),
|
|
881
|
+
/** Defaulted so every stored declaration (all boolean before `text` existed) parses unchanged. */
|
|
882
|
+
type: import_zod8.z.literal(VariableType.boolean).default(VariableType.boolean)
|
|
883
|
+
});
|
|
884
|
+
var CABTextVariable = import_zod8.z.object({
|
|
885
|
+
defaultValue: import_zod8.z.string(),
|
|
886
|
+
name: import_zod8.z.string().min(1),
|
|
887
|
+
seed: import_zod8.z.never().optional(),
|
|
888
|
+
type: import_zod8.z.literal(VariableType.text)
|
|
889
|
+
});
|
|
890
|
+
var CABNumberVariable = import_zod8.z.object({
|
|
891
|
+
defaultValue: import_zod8.z.number(),
|
|
892
|
+
name: import_zod8.z.string().min(1),
|
|
893
|
+
seed: import_zod8.z.never().optional(),
|
|
894
|
+
type: import_zod8.z.literal(VariableType.number)
|
|
895
|
+
});
|
|
896
|
+
var CABVariable = import_zod8.z.union([CABTextVariable, CABNumberVariable, CABBooleanVariable]).transform(
|
|
897
|
+
(variable) => variable.type === VariableType.boolean ? { ...variable, defaultValue: variable.defaultValue ?? variable.seed === void 0 } : variable
|
|
898
|
+
);
|
|
899
|
+
var CABVariableEffect = import_zod8.z.object({
|
|
900
|
+
effect: variableEffect.default(VariableEffect.toggle),
|
|
901
|
+
variable: import_zod8.z.string().min(1)
|
|
902
|
+
});
|
|
903
|
+
var CABVisibility = import_zod8.z.object({
|
|
904
|
+
variable: import_zod8.z.string().min(1),
|
|
905
|
+
visibleWhen: import_zod8.z.boolean().default(true)
|
|
906
|
+
});
|
|
907
|
+
var contentOperator = import_zod8.z.enum(contentOperators);
|
|
908
|
+
var resultCountOperator = import_zod8.z.enum(resultCountOperators);
|
|
909
|
+
var resultTagOperator = import_zod8.z.enum(resultTagOperators);
|
|
910
|
+
var mutatorEvent = import_zod8.z.enum(mutatorEvents);
|
|
911
|
+
var CABContentTrigger = import_zod8.z.object({
|
|
912
|
+
operator: contentOperator.default(ContentOperator.is_empty),
|
|
913
|
+
type: import_zod8.z.literal("content")
|
|
914
|
+
});
|
|
915
|
+
var CABResultCountTrigger = import_zod8.z.object({
|
|
916
|
+
operator: resultCountOperator.default(ResultCountOperator.equals),
|
|
917
|
+
type: import_zod8.z.literal("result_count"),
|
|
918
|
+
value: import_zod8.z.number().default(0)
|
|
919
|
+
});
|
|
920
|
+
var CABResultTagTrigger = import_zod8.z.object({
|
|
921
|
+
operator: resultTagOperator.default(ResultTagOperator.contains),
|
|
922
|
+
type: import_zod8.z.literal("result_tag"),
|
|
923
|
+
value: import_zod8.z.string().min(1)
|
|
924
|
+
});
|
|
925
|
+
var CABEventTrigger = import_zod8.z.object({
|
|
926
|
+
event: mutatorEvent,
|
|
927
|
+
type: import_zod8.z.literal("event")
|
|
928
|
+
});
|
|
929
|
+
var CABVariableTrigger = import_zod8.z.discriminatedUnion("type", [
|
|
930
|
+
CABContentTrigger,
|
|
931
|
+
CABEventTrigger,
|
|
932
|
+
CABResultCountTrigger,
|
|
933
|
+
CABResultTagTrigger
|
|
934
|
+
]);
|
|
935
|
+
var CABVariableMutator = import_zod8.z.object({
|
|
936
|
+
effect: variableEffect.default(VariableEffect.set_false),
|
|
937
|
+
variable: import_zod8.z.string().min(1),
|
|
938
|
+
when: CABVariableTrigger
|
|
939
|
+
});
|
|
940
|
+
var CABVariableFields = {
|
|
941
|
+
mutators: import_zod8.z.array(CABVariableMutator).optional(),
|
|
942
|
+
variables: import_zod8.z.array(CABVariable).refine((variables) => new Set(variables.map(({ name }) => name)).size === variables.length, {
|
|
943
|
+
message: "variable names must be unique within a section"
|
|
944
|
+
}).optional(),
|
|
945
|
+
visibility: CABVisibility.optional()
|
|
946
|
+
};
|
|
947
|
+
|
|
948
|
+
// src/schema/widgets/checkout-and-beyond/text.ts
|
|
949
|
+
var enumOrOmit = (...vals) => import_zod9.z.string().transform((val) => vals.includes(val) ? val : void 0).optional();
|
|
950
|
+
var TiptapText = import_zod9.z.object({
|
|
951
|
+
marks: import_zod9.z.union([
|
|
952
|
+
import_zod9.z.array(
|
|
953
|
+
import_zod9.z.discriminatedUnion("type", [
|
|
954
|
+
import_zod9.z.object({ type: import_zod9.z.literal("bold") }),
|
|
955
|
+
import_zod9.z.object({ type: import_zod9.z.literal("italic") }),
|
|
956
|
+
import_zod9.z.object({
|
|
957
|
+
attrs: import_zod9.z.object({
|
|
958
|
+
class: import_zod9.z.string().nullable(),
|
|
959
|
+
href: import_zod9.z.union([
|
|
960
|
+
import_zod9.z.url(),
|
|
961
|
+
import_zod9.z.literal("#"),
|
|
962
|
+
import_zod9.z.string().regex(DYNAMIC_TOKEN_REGEX),
|
|
963
|
+
import_zod9.z.string().regex(ROOT_RELATIVE_PATH_REGEX)
|
|
964
|
+
]),
|
|
965
|
+
rel: import_zod9.z.string().default("noopener noreferrer nofollow"),
|
|
966
|
+
target: import_zod9.z.string().default("_blank")
|
|
967
|
+
}),
|
|
968
|
+
type: import_zod9.z.literal("link")
|
|
969
|
+
}),
|
|
970
|
+
import_zod9.z.object({ type: import_zod9.z.literal("strike") }),
|
|
971
|
+
import_zod9.z.object({
|
|
972
|
+
attrs: import_zod9.z.object({
|
|
973
|
+
color: enumOrOmit(...textColorNames).default(TextColorName.base),
|
|
974
|
+
fontSize: enumOrOmit(...textSizeNames).default(TextSizeName.base)
|
|
975
|
+
}),
|
|
976
|
+
type: import_zod9.z.literal("textStyle")
|
|
977
|
+
})
|
|
978
|
+
])
|
|
979
|
+
),
|
|
980
|
+
import_zod9.z.strictObject({}).transform(() => [])
|
|
981
|
+
]).optional(),
|
|
982
|
+
text: import_zod9.z.string().default(""),
|
|
983
|
+
type: import_zod9.z.literal("text").default("text")
|
|
984
|
+
});
|
|
985
|
+
var TiptapParagraph = import_zod9.z.object({
|
|
986
|
+
attrs: import_zod9.z.object({
|
|
987
|
+
textAlign: enumOrOmit(...textAlignments)
|
|
988
|
+
}).default({ textAlign: TextAlignment.start }),
|
|
989
|
+
content: import_zod9.z.union([import_zod9.z.array(TiptapText), import_zod9.z.strictObject({}).transform(() => [])]).default(() => []),
|
|
990
|
+
type: import_zod9.z.literal("paragraph").default("paragraph")
|
|
991
|
+
});
|
|
992
|
+
var TiptapDocument = import_zod9.z.object({
|
|
993
|
+
attrs: import_zod9.z.object({
|
|
994
|
+
blockSpacing: enumOrOmit(...spacings)
|
|
995
|
+
}).default({ blockSpacing: Spacing.base }),
|
|
996
|
+
content: import_zod9.z.union([import_zod9.z.array(TiptapParagraph), import_zod9.z.strictObject({}).transform(() => [])]).default(() => [TiptapParagraph.parse({})]),
|
|
997
|
+
type: import_zod9.z.literal("doc").default("doc")
|
|
998
|
+
});
|
|
999
|
+
var CABTextTier = import_zod9.z.object({
|
|
1000
|
+
threshold: import_zod9.z.number().int().nonnegative(),
|
|
1001
|
+
thresholds: import_zod9.z.record(import_zod9.z.string(), import_zod9.z.number().int().nonnegative()).default(() => ({})),
|
|
1002
|
+
tierId: import_zod9.z.string().optional(),
|
|
1003
|
+
tierType: import_zod9.z.enum(progressTierTypes).default(ProgressTierType.shipping)
|
|
1004
|
+
});
|
|
1005
|
+
var CABTextSection = import_zod9.z.object({
|
|
1006
|
+
...CABVariableFields,
|
|
1007
|
+
buttonField: import_zod9.z.enum(buttonFields).optional(),
|
|
1008
|
+
content: import_zod9.z.record(import_zod9.z.string(), import_zod9.z.union([import_zod9.z.string(), TiptapDocument]).refine(checkForHTML, NO_HTML).optional()).default({ en: TiptapDocument.parse({}) }).optional(),
|
|
1009
|
+
name: import_zod9.z.string().optional(),
|
|
1010
|
+
optionId: import_zod9.z.number().optional(),
|
|
1011
|
+
sectionId: import_zod9.z.uuid().default(() => (0, import_uuid.v7)()),
|
|
1012
|
+
sectionType: import_zod9.z.literal(SectionType.text).default(SectionType.text),
|
|
1013
|
+
tier: CABTextTier.optional()
|
|
1014
|
+
}).superRefine(({ buttonField, content }, ctx) => {
|
|
1015
|
+
if (buttonField === ButtonField.destinationUrl && content) {
|
|
1016
|
+
(0, import_compat3.forEach)(content, (value, lang) => {
|
|
1017
|
+
if (value && (0, import_compat3.isString)(value)) {
|
|
1018
|
+
if (DYNAMIC_TOKEN_REGEX.test(value)) return;
|
|
1019
|
+
try {
|
|
1020
|
+
new URL(value);
|
|
1021
|
+
} catch {
|
|
1022
|
+
ctx.addIssue({
|
|
1023
|
+
code: "custom",
|
|
1024
|
+
message: "Invalid URL",
|
|
1025
|
+
path: ["content", lang]
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1031
|
+
});
|
|
1032
|
+
|
|
1033
|
+
// src/schema/widgets/post-purchase-offer/postPurchaseBlocks.ts
|
|
1034
|
+
var TextAlignment2 = import_zod10.z.union([import_zod10.z.enum(["leading", "center", "trailing"]), import_zod10.z.unknown().transform(() => "leading")]);
|
|
1035
|
+
var TextSize = import_zod10.z.union([
|
|
1036
|
+
import_zod10.z.enum(["xsmall", "small", "base", "default", "medium", "large", "xlarge"]),
|
|
1037
|
+
import_zod10.z.unknown().transform(() => "medium")
|
|
1038
|
+
]);
|
|
1039
|
+
var CalloutBannerBlock = import_zod10.z.object({
|
|
1040
|
+
id: import_zod10.z.string().optional().default(() => (0, import_uuid2.v4)()),
|
|
1041
|
+
name: import_zod10.z.string().optional(),
|
|
1042
|
+
settings: import_zod10.z.object({
|
|
1043
|
+
superTitle: import_zod10.z.union([import_zod10.z.string(), TiptapDocument]).default(() => "Limited-time Offer"),
|
|
1044
|
+
title: import_zod10.z.union([import_zod10.z.string(), TiptapDocument]).default(() => "Add this customer favorite to your order")
|
|
1045
|
+
}),
|
|
1046
|
+
styles: import_zod10.z.object({
|
|
1047
|
+
superTitleEmphasized: import_zod10.z.boolean().default(false),
|
|
1048
|
+
superTitleSize: TextSize.default("large"),
|
|
1049
|
+
textAlignment: TextAlignment2.default("center"),
|
|
1050
|
+
titleEmphasized: import_zod10.z.boolean().default(true),
|
|
1051
|
+
titleSize: TextSize.default("large")
|
|
1052
|
+
}),
|
|
1053
|
+
type: import_zod10.z.literal(BlockType.callout_banner).default(BlockType.callout_banner)
|
|
1054
|
+
});
|
|
1055
|
+
var ImageBlock = import_zod10.z.object({
|
|
1056
|
+
id: import_zod10.z.string().optional().default(() => (0, import_uuid2.v4)()),
|
|
1057
|
+
name: import_zod10.z.string().optional(),
|
|
1058
|
+
settings: import_zod10.z.union([
|
|
1059
|
+
import_zod10.z.object({
|
|
1060
|
+
/** This isn't used in the post-purchase offer widget */
|
|
1061
|
+
alt: import_zod10.z.string().optional().default(""),
|
|
1062
|
+
image: import_zod10.z.union([import_zod10.z.literal(""), import_zod10.z.url()]).default(""),
|
|
1063
|
+
imageSize: import_zod10.z.number().default(20),
|
|
1064
|
+
imageType: import_zod10.z.enum(["URL", "UPLOAD"]).default("URL")
|
|
1065
|
+
}),
|
|
1066
|
+
import_zod10.z.array(import_zod10.z.never()).transform(() => ({}))
|
|
1067
|
+
]),
|
|
1068
|
+
type: import_zod10.z.literal(BlockType.image).default(BlockType.image)
|
|
1069
|
+
});
|
|
1070
|
+
var ImageContentBlock = import_zod10.z.object({
|
|
1071
|
+
id: import_zod10.z.string().optional().default(() => (0, import_uuid2.v4)()),
|
|
1072
|
+
name: import_zod10.z.string().optional(),
|
|
1073
|
+
settings: import_zod10.z.object({
|
|
1074
|
+
alt: import_zod10.z.string().optional().default(""),
|
|
1075
|
+
description: import_zod10.z.union([import_zod10.z.string(), TiptapDocument, import_zod10.z.null()]).default(
|
|
1076
|
+
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
|
|
1077
|
+
),
|
|
1078
|
+
descriptionSize: TextSize.default("medium"),
|
|
1079
|
+
horizontalAlignment: TextAlignment2.default("leading"),
|
|
1080
|
+
image: import_zod10.z.union([import_zod10.z.literal(""), import_zod10.z.url()]).default(""),
|
|
1081
|
+
imagePlacement: import_zod10.z.enum(["bottom", "left", "right", "top"]).optional().default("left"),
|
|
1082
|
+
imageSize: import_zod10.z.number().default(20),
|
|
1083
|
+
superTitle: import_zod10.z.union([import_zod10.z.string(), TiptapDocument]).default("Lorem Ipsum!"),
|
|
1084
|
+
superTitleSize: TextSize.default("medium"),
|
|
1085
|
+
/** This isn't configurable in the admin-nextjs editor */
|
|
1086
|
+
swapContent: import_zod10.z.boolean().optional().default(false),
|
|
1087
|
+
title: import_zod10.z.union([import_zod10.z.string(), TiptapDocument]).nullable().default("Lorem ipsum dolor sit amet"),
|
|
1088
|
+
titleSize: TextSize.default("medium")
|
|
1089
|
+
}),
|
|
1090
|
+
type: import_zod10.z.literal(BlockType.image_content).default(BlockType.image_content)
|
|
1091
|
+
});
|
|
1092
|
+
var PayButtonBlock = import_zod10.z.object({
|
|
1093
|
+
id: import_zod10.z.string().optional().default(() => (0, import_uuid2.v4)()),
|
|
1094
|
+
name: import_zod10.z.string().optional(),
|
|
1095
|
+
settings: import_zod10.z.union([
|
|
1096
|
+
import_zod10.z.object({
|
|
1097
|
+
label: import_zod10.z.string().default("Pay Now")
|
|
1098
|
+
}),
|
|
1099
|
+
import_zod10.z.array(import_zod10.z.never()).transform(() => ({
|
|
1100
|
+
label: "Pay Now"
|
|
1101
|
+
}))
|
|
1102
|
+
]),
|
|
1103
|
+
styles: import_zod10.z.union([
|
|
1104
|
+
import_zod10.z.object({
|
|
1105
|
+
buttonWidth: import_zod10.z.number().min(10).max(100).default(50)
|
|
1106
|
+
}),
|
|
1107
|
+
import_zod10.z.array(import_zod10.z.never()).transform(() => ({
|
|
1108
|
+
buttonWidth: 50
|
|
1109
|
+
}))
|
|
1110
|
+
]),
|
|
1111
|
+
type: import_zod10.z.literal(BlockType.pay_button).default(BlockType.pay_button)
|
|
1112
|
+
});
|
|
1113
|
+
var ProductInformationBlock = import_zod10.z.object({
|
|
1114
|
+
/** This isn't configurable in the admin-nextjs editor */
|
|
1115
|
+
hideProductImage: import_zod10.z.boolean().optional().default(false),
|
|
1116
|
+
id: import_zod10.z.string().optional().default(() => (0, import_uuid2.v4)()),
|
|
1117
|
+
name: import_zod10.z.string().optional(),
|
|
1118
|
+
type: import_zod10.z.literal(BlockType.product_information).default(BlockType.product_information)
|
|
1119
|
+
});
|
|
1120
|
+
var SeparatorBlock = import_zod10.z.object({
|
|
1121
|
+
id: import_zod10.z.string().optional().default(() => (0, import_uuid2.v4)()),
|
|
1122
|
+
name: import_zod10.z.string().optional(),
|
|
1123
|
+
type: import_zod10.z.literal(BlockType.separator).default(BlockType.separator)
|
|
1124
|
+
});
|
|
1125
|
+
var TextBlock = import_zod10.z.object({
|
|
1126
|
+
id: import_zod10.z.string().optional().default(() => (0, import_uuid2.v4)()),
|
|
1127
|
+
name: import_zod10.z.string().optional(),
|
|
1128
|
+
settings: import_zod10.z.object({
|
|
1129
|
+
description: import_zod10.z.union([import_zod10.z.string(), TiptapDocument]).optional().default(
|
|
1130
|
+
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
|
|
1131
|
+
),
|
|
1132
|
+
/** This isn't used in the post-purchase offer widget */
|
|
1133
|
+
descriptionSize: TextSize.default("medium"),
|
|
1134
|
+
horizontalAlignment: TextAlignment2.default("leading"),
|
|
1135
|
+
superTitle: import_zod10.z.union([import_zod10.z.string(), TiptapDocument]).default("Super Title"),
|
|
1136
|
+
/** This isn't used in the post-purchase offer widget */
|
|
1137
|
+
superTitleSize: TextSize.default("medium"),
|
|
1138
|
+
title: import_zod10.z.union([import_zod10.z.string(), TiptapDocument]).nullable().default("Lorem ipsum dolor sit amet."),
|
|
1139
|
+
/** This isn't used in the post-purchase offer widget */
|
|
1140
|
+
titleSize: TextSize.default("medium")
|
|
1141
|
+
}),
|
|
1142
|
+
type: import_zod10.z.literal(BlockType.text).default(BlockType.text)
|
|
1143
|
+
});
|
|
1144
|
+
var TimerBlock = import_zod10.z.object({
|
|
1145
|
+
id: import_zod10.z.string().optional().default(() => (0, import_uuid2.v4)()),
|
|
1146
|
+
name: import_zod10.z.string().optional(),
|
|
1147
|
+
settings: import_zod10.z.object({
|
|
1148
|
+
durationMinutes: import_zod10.z.number().min(0).default(10),
|
|
1149
|
+
durationSeconds: import_zod10.z.union([import_zod10.z.number().min(0), import_zod10.z.unknown().transform(() => 0)]).default(0),
|
|
1150
|
+
endOffer: import_zod10.z.boolean().default(true),
|
|
1151
|
+
title: import_zod10.z.union([import_zod10.z.string(), TiptapDocument]).default("Hurry \u2014 your special offer ends in:")
|
|
1152
|
+
}),
|
|
1153
|
+
styles: import_zod10.z.object({
|
|
1154
|
+
textAlignment: TextAlignment2.default("center"),
|
|
1155
|
+
timerBackgroundColor: import_zod10.z.enum(["info", "warning", "success", "critical"]).default("warning"),
|
|
1156
|
+
timerEmphasized: import_zod10.z.union([import_zod10.z.boolean(), import_zod10.z.unknown().transform(() => true)]).default(true),
|
|
1157
|
+
timerSize: TextSize.default("medium"),
|
|
1158
|
+
timerWidth: import_zod10.z.number().min(10).max(100).optional().default(100),
|
|
1159
|
+
titleEmphasized: import_zod10.z.union([import_zod10.z.boolean(), import_zod10.z.unknown().transform(() => true)]).default(false),
|
|
1160
|
+
titleSize: TextSize.default("medium")
|
|
1161
|
+
}),
|
|
1162
|
+
type: import_zod10.z.literal(BlockType.timer).default(BlockType.timer)
|
|
1163
|
+
});
|
|
1164
|
+
var PostPurchaseBlock = import_zod10.z.discriminatedUnion("type", [
|
|
1165
|
+
CalloutBannerBlock,
|
|
1166
|
+
ImageBlock,
|
|
1167
|
+
ImageContentBlock,
|
|
1168
|
+
PayButtonBlock,
|
|
1169
|
+
ProductInformationBlock,
|
|
1170
|
+
SeparatorBlock,
|
|
1171
|
+
TextBlock,
|
|
1172
|
+
TimerBlock
|
|
1173
|
+
]);
|
|
1174
|
+
|
|
1175
|
+
// src/schema/widgets/post-purchase-offer/postPurchaseSettings.ts
|
|
1176
|
+
var PostPurchaseSettings = import_zod11.z.object({
|
|
1177
|
+
advance: import_zod11.z.object({ removePartialOrder: import_zod11.z.boolean().default(true) }).optional().default(() => ({ removePartialOrder: true })),
|
|
1178
|
+
blocks: import_zod11.z.union([import_zod11.z.array(PostPurchaseBlock), import_zod11.z.unknown().transform(() => [])]).default(() => [
|
|
1179
|
+
PostPurchaseBlock.parse({ settings: {}, styles: {}, type: BlockType.timer }),
|
|
1180
|
+
PostPurchaseBlock.parse({ settings: {}, styles: {}, type: BlockType.callout_banner }),
|
|
1181
|
+
PostPurchaseBlock.parse({ type: BlockType.product_information })
|
|
1182
|
+
]),
|
|
1183
|
+
columnLayout: import_zod11.z.boolean().optional(),
|
|
1184
|
+
discount: import_zod11.z.object({
|
|
1185
|
+
amount: strictNumber.default(30),
|
|
1186
|
+
shouldShowSavingText: import_zod11.z.boolean().optional().default(true),
|
|
1187
|
+
type: import_zod11.z.enum(["none", "fixed_amount", "percentage"]).default("none")
|
|
1188
|
+
}),
|
|
1189
|
+
discountedFrom: import_zod11.z.enum(["price", "compare_at_price"]).optional().default("price"),
|
|
1190
|
+
endpoint: import_zod11.z.string().optional(),
|
|
1191
|
+
integrations: import_zod11.z.object({
|
|
1192
|
+
judgeme: import_zod11.z.boolean().default(false),
|
|
1193
|
+
junip: import_zod11.z.boolean().optional().default(false),
|
|
1194
|
+
klaviyo: import_zod11.z.boolean().default(false),
|
|
1195
|
+
loox: import_zod11.z.boolean().default(false),
|
|
1196
|
+
okendo: import_zod11.z.boolean().default(false),
|
|
1197
|
+
opinew: import_zod11.z.boolean().optional().default(false),
|
|
1198
|
+
reviewsio: import_zod11.z.boolean().optional().default(false),
|
|
1199
|
+
stamped: import_zod11.z.boolean().default(false),
|
|
1200
|
+
yotpo: import_zod11.z.boolean().default(false)
|
|
1201
|
+
}),
|
|
1202
|
+
key: import_zod11.z.string().optional(),
|
|
1203
|
+
language: import_zod11.z.object({
|
|
1204
|
+
description: import_zod11.z.union([import_zod11.z.string(), import_zod11.z.unknown().transform(() => "")]).default(""),
|
|
1205
|
+
descriptionEnabled: import_zod11.z.boolean().optional().default(false),
|
|
1206
|
+
descriptionRte: import_zod11.z.object({
|
|
1207
|
+
content: import_zod11.z.array(import_zod11.z.unknown()),
|
|
1208
|
+
type: import_zod11.z.string()
|
|
1209
|
+
}).optional(),
|
|
1210
|
+
descriptionSpacing: import_zod11.z.enum(["none", "xtight", "tight", "default", "loose", "xloose"]).optional(),
|
|
1211
|
+
displayCtaPrice: import_zod11.z.boolean().default(true),
|
|
1212
|
+
global: import_zod11.z.object({
|
|
1213
|
+
declineAll: import_zod11.z.string().optional().default("Decline All"),
|
|
1214
|
+
declineThisOffer: import_zod11.z.string().default("Decline this offer"),
|
|
1215
|
+
free: import_zod11.z.string().optional().default("Free"),
|
|
1216
|
+
notAvailable: import_zod11.z.string().optional().default("Not available"),
|
|
1217
|
+
/** Label for the one-time choice beside `subscriptionOption` in the purchase-type selector */
|
|
1218
|
+
oneTimePurchase: import_zod11.z.string().optional().default("One-time Purchase"),
|
|
1219
|
+
payNow: import_zod11.z.string().default("Pay Now"),
|
|
1220
|
+
payNowUpgradeToSubscription: import_zod11.z.string().optional().default("Upgrade to Subscription"),
|
|
1221
|
+
quantity: import_zod11.z.string().default("Quantity"),
|
|
1222
|
+
/** This isn't configurable in the admin-nextjs editor */
|
|
1223
|
+
recurringShipping: import_zod11.z.string().optional().default("Recurring shipping"),
|
|
1224
|
+
recurringSubtotal: import_zod11.z.string().default("Recurring subtotal"),
|
|
1225
|
+
reviewsPlural: import_zod11.z.string().optional().default("Reviews"),
|
|
1226
|
+
reviewsSingular: import_zod11.z.string().optional().default("Review"),
|
|
1227
|
+
save: import_zod11.z.union([import_zod11.z.string(), import_zod11.z.unknown().transform(() => "Save")]).optional().default("Save"),
|
|
1228
|
+
shipping: import_zod11.z.string().default("Shipping"),
|
|
1229
|
+
subscriptionOption: import_zod11.z.string().optional().default("Subscribe and Save"),
|
|
1230
|
+
subtotal: import_zod11.z.string().default("Subtotal"),
|
|
1231
|
+
taxes: import_zod11.z.string().default("Taxes"),
|
|
1232
|
+
total: import_zod11.z.string().default("Total")
|
|
1233
|
+
}).optional().default(() => ({
|
|
1234
|
+
declineAll: "Decline All",
|
|
1235
|
+
declineThisOffer: "Decline this offer",
|
|
1236
|
+
free: "Free",
|
|
1237
|
+
notAvailable: "Not available",
|
|
1238
|
+
oneTimePurchase: "One-time Purchase",
|
|
1239
|
+
payNow: "Pay Now",
|
|
1240
|
+
payNowUpgradeToSubscription: "Upgrade to Subscription",
|
|
1241
|
+
quantity: "Quantity",
|
|
1242
|
+
/** This isn't configurable in the admin-nextjs editor */
|
|
1243
|
+
recurringShipping: "Recurring shipping",
|
|
1244
|
+
recurringSubtotal: "Recurring subtotal",
|
|
1245
|
+
reviewsPlural: "Reviews",
|
|
1246
|
+
reviewsSingular: "Review",
|
|
1247
|
+
save: "Save",
|
|
1248
|
+
shipping: "Shipping",
|
|
1249
|
+
subscriptionOption: "Subscribe and Save",
|
|
1250
|
+
subtotal: "Subtotal",
|
|
1251
|
+
taxes: "Taxes",
|
|
1252
|
+
total: "Total"
|
|
1253
|
+
})),
|
|
1254
|
+
globalTranslation: import_zod11.z.string().optional().default("english")
|
|
1255
|
+
}),
|
|
1256
|
+
metafields: import_zod11.z.boolean().default(false),
|
|
1257
|
+
/** This isn't configurable in the admin-nextjs editor */
|
|
1258
|
+
offer: import_zod11.z.object({
|
|
1259
|
+
count: import_zod11.z.number().default(1)
|
|
1260
|
+
}),
|
|
1261
|
+
offersLayout: import_zod11.z.object({
|
|
1262
|
+
itemsPerPage: import_zod11.z.number().optional(),
|
|
1263
|
+
type: import_zod11.z.enum(["list", "grid", "carousel"]).default("list")
|
|
1264
|
+
}).optional().default({
|
|
1265
|
+
type: "list"
|
|
1266
|
+
}),
|
|
1267
|
+
/** This isn't configurable in the admin-nextjs editor */
|
|
1268
|
+
previewMode: import_zod11.z.boolean().default(false),
|
|
1269
|
+
productLimit: import_zod11.z.number().optional().default(1),
|
|
1270
|
+
productOptions: import_zod11.z.object({
|
|
1271
|
+
/** This isn't configurable in the admin-nextjs editor */
|
|
1272
|
+
hideOutOfStockVariants: import_zod11.z.boolean().optional().default(false),
|
|
1273
|
+
matchVariant: import_zod11.z.boolean().optional().default(true),
|
|
1274
|
+
showDeclineAll: import_zod11.z.enum(["above", "below", "both", "none"]).optional(),
|
|
1275
|
+
showShipping: import_zod11.z.boolean().optional().default(true),
|
|
1276
|
+
showSubtotal: import_zod11.z.boolean().optional().default(true),
|
|
1277
|
+
showTaxes: import_zod11.z.boolean().optional().default(true),
|
|
1278
|
+
showTotal: import_zod11.z.boolean().optional().default(true),
|
|
1279
|
+
showVariantSelectors: import_zod11.z.boolean().optional().default(true),
|
|
1280
|
+
variantSelectorDisplayMode: import_zod11.z.enum(["separate", "single"]).optional().default("separate")
|
|
1281
|
+
}),
|
|
1282
|
+
productType: import_zod11.z.union([import_zod11.z.enum(["one-time", "subscription", "both"]), import_zod11.z.literal("").transform(() => "one-time")]).default("one-time"),
|
|
1283
|
+
productTypeSelector: import_zod11.z.enum(["dropdown", "radio"]).optional().default("radio"),
|
|
1284
|
+
quantityInputs: import_zod11.z.object({
|
|
1285
|
+
defaultQuantity: import_zod11.z.union([import_zod11.z.number(), import_zod11.z.null().transform(() => 1)]).default(1),
|
|
1286
|
+
enabled: import_zod11.z.boolean().default(true),
|
|
1287
|
+
maxValue: import_zod11.z.union([import_zod11.z.number(), import_zod11.z.null().transform(() => 15)]).default(15),
|
|
1288
|
+
minValue: import_zod11.z.union([import_zod11.z.number().min(0), import_zod11.z.unknown().transform(() => 0)]).default(1)
|
|
1289
|
+
}),
|
|
1290
|
+
shipping: import_zod11.z.object({
|
|
1291
|
+
amount: strictNumber.default(10),
|
|
1292
|
+
/** This isn't configurable in the admin-nextjs editor */
|
|
1293
|
+
enabled: import_zod11.z.boolean().default(true),
|
|
1294
|
+
title: import_zod11.z.string().optional().default("Shipping Fees"),
|
|
1295
|
+
type: import_zod11.z.enum(["free", "fixed_amount"]).default("free")
|
|
1296
|
+
}),
|
|
1297
|
+
styles: import_zod11.z.object({
|
|
1298
|
+
starColor: import_zod11.z.string().optional().default("#fadb14"),
|
|
1299
|
+
starSize: import_zod11.z.union([import_zod11.z.enum(["small", "medium", "large"]), import_zod11.z.unknown().transform(() => "large")]).optional().default("large"),
|
|
1300
|
+
starStrokeColor: import_zod11.z.string().optional().default("#fadb14"),
|
|
1301
|
+
strokeWidth: import_zod11.z.string().optional().default("1")
|
|
1302
|
+
}).optional(),
|
|
1303
|
+
subImages: import_zod11.z.number().nullish().default(8),
|
|
1304
|
+
subscription: import_zod11.z.object({
|
|
1305
|
+
discount: import_zod11.z.object({
|
|
1306
|
+
amount: strictNumber.default(30),
|
|
1307
|
+
shouldShowSavingText: import_zod11.z.boolean().optional().default(true),
|
|
1308
|
+
type: import_zod11.z.enum(["none", "fixed_amount", "percentage"]).default("none")
|
|
1309
|
+
}),
|
|
1310
|
+
shipping: import_zod11.z.object({
|
|
1311
|
+
amount: strictNumber.default(1),
|
|
1312
|
+
/** This isn't configurable in the admin-nextjs editor */
|
|
1313
|
+
enabled: import_zod11.z.boolean().default(true),
|
|
1314
|
+
/** This isn't configurable in the admin-nextjs editor */
|
|
1315
|
+
recurringAmount: strictNumber.default(2),
|
|
1316
|
+
shippingTitle: import_zod11.z.string().default("Shipping Fees"),
|
|
1317
|
+
type: import_zod11.z.enum(["free", "fixed_amount"]).default("free")
|
|
1318
|
+
})
|
|
1319
|
+
}).optional().default({
|
|
1320
|
+
discount: {
|
|
1321
|
+
amount: 30,
|
|
1322
|
+
shouldShowSavingText: true,
|
|
1323
|
+
type: "none"
|
|
1324
|
+
},
|
|
1325
|
+
shipping: {
|
|
1326
|
+
amount: 1,
|
|
1327
|
+
/** This isn't configurable in the admin-nextjs editor */
|
|
1328
|
+
enabled: true,
|
|
1329
|
+
/** This isn't configurable in the admin-nextjs editor */
|
|
1330
|
+
recurringAmount: 2,
|
|
1331
|
+
shippingTitle: "Shipping Fees",
|
|
1332
|
+
type: "free"
|
|
1333
|
+
}
|
|
1334
|
+
}),
|
|
1335
|
+
subscriptionIsDefault: import_zod11.z.boolean().optional(),
|
|
1336
|
+
/** This isn't configurable in the admin-nextjs editor */
|
|
1337
|
+
template: import_zod11.z.string().optional().default(""),
|
|
1338
|
+
type: import_zod11.z.literal("shopify_post_purchase_extension").default("shopify_post_purchase_extension"),
|
|
1339
|
+
upgradeToSubscription: import_zod11.z.object({
|
|
1340
|
+
acceptButtonText: import_zod11.z.string().optional().default("Upgrade"),
|
|
1341
|
+
allow: import_zod11.z.boolean().optional().default(false),
|
|
1342
|
+
emailRefundNotice: import_zod11.z.boolean().optional().default(false),
|
|
1343
|
+
errorBannerText: import_zod11.z.string().optional().default("This subscription cannot be added - limit one per order")
|
|
1344
|
+
}).optional().default(() => ({
|
|
1345
|
+
acceptButtonText: "Upgrade",
|
|
1346
|
+
allow: false,
|
|
1347
|
+
emailRefundNotice: false,
|
|
1348
|
+
errorBannerText: "This subscription cannot be added - limit one per order"
|
|
1349
|
+
}))
|
|
1350
|
+
});
|
|
1351
|
+
|
|
1352
|
+
// src/schema/postPurchaseProductReviews.ts
|
|
1353
|
+
var decimal = import_zod12.z.union([
|
|
1354
|
+
import_zod12.z.number(),
|
|
1355
|
+
import_zod12.z.string().regex(/^\d+(?:\.\d+)?$/).transform(Number)
|
|
1356
|
+
]);
|
|
1357
|
+
var PostPurchaseCommonReviewRating = import_zod12.z.object({ value: decimal.pipe(import_zod12.z.number().min(0).max(5)) });
|
|
1358
|
+
var PostPurchaseKlaviyoReviewRating = PostPurchaseCommonReviewRating.extend({
|
|
1359
|
+
// Legacy validates key presence, then displays the raw value on five stars without rescaling.
|
|
1360
|
+
scale_max: import_zod12.z.unknown().nonoptional(),
|
|
1361
|
+
scale_min: import_zod12.z.unknown().nonoptional()
|
|
1362
|
+
});
|
|
1363
|
+
var PostPurchaseReviewCount = import_zod12.z.string().regex(/^\d+(?:\.\d+)?$/).transform(Number).pipe(import_zod12.z.number().int().nonnegative());
|
|
1364
|
+
var PostPurchaseReviewStyles = PostPurchaseSettings.shape.styles.unwrap().extend({
|
|
1365
|
+
strokeWidth: decimal.pipe(import_zod12.z.number().nonnegative()).default(1)
|
|
1366
|
+
}).prefault({});
|
|
1367
|
+
var PostPurchaseProductReviews = import_zod12.z.object({
|
|
1368
|
+
color: import_zod12.z.string(),
|
|
1369
|
+
rating: import_zod12.z.number().positive().max(5),
|
|
1370
|
+
reviewCount: import_zod12.z.number().int().nonnegative(),
|
|
1371
|
+
reviewsPlural: import_zod12.z.string(),
|
|
1372
|
+
reviewsSingular: import_zod12.z.string(),
|
|
1373
|
+
size: import_zod12.z.enum(["small", "medium", "large"]),
|
|
1374
|
+
strokeColor: import_zod12.z.string(),
|
|
1375
|
+
strokeWidth: import_zod12.z.number().nonnegative()
|
|
1376
|
+
});
|
|
1377
|
+
|
|
1378
|
+
// src/server/postPurchaseJudgeMeReviews.ts
|
|
1379
|
+
var import_zod14 = require("zod");
|
|
1380
|
+
|
|
1381
|
+
// src/server/postPurchaseReviewFields.ts
|
|
1382
|
+
var import_zod13 = require("zod");
|
|
1383
|
+
var Field = import_zod13.z.object({ key: import_zod13.z.string(), namespace: import_zod13.z.string(), value: import_zod13.z.unknown().optional() });
|
|
1384
|
+
var reviewFields = (raw) => {
|
|
1385
|
+
const fields4 = import_zod13.z.array(import_zod13.z.unknown()).parse(raw).flatMap((field) => {
|
|
1386
|
+
const parsed = Field.safeParse(field);
|
|
1387
|
+
return parsed.success ? [parsed.data] : [];
|
|
1388
|
+
});
|
|
1389
|
+
return (namespace, key) => fields4.find((field) => field.namespace === namespace && field.key === key);
|
|
1390
|
+
};
|
|
1391
|
+
var ReviewFieldError = class extends Error {
|
|
1392
|
+
constructor(field) {
|
|
1393
|
+
super(`Unreadable review field ${field}`);
|
|
1394
|
+
this.field = field;
|
|
1395
|
+
}
|
|
1396
|
+
};
|
|
1397
|
+
var readReviewField = (field, read) => {
|
|
1398
|
+
try {
|
|
1399
|
+
return read(field.value);
|
|
1400
|
+
} catch {
|
|
1401
|
+
throw new ReviewFieldError(`${field.namespace}.${field.key}`);
|
|
1402
|
+
}
|
|
1403
|
+
};
|
|
1404
|
+
|
|
1405
|
+
// src/server/postPurchaseJudgeMeReviews.ts
|
|
1406
|
+
var readJudgeMeReviews = (find) => {
|
|
1407
|
+
const field = find("judgeme", "badge");
|
|
1408
|
+
if (!field) return null;
|
|
1409
|
+
return readReviewField(field, (value) => {
|
|
1410
|
+
const html = import_zod14.z.string().parse(value);
|
|
1411
|
+
const rating = html.match(/data-average-rating=['"](\d+(?:\.\d+)?)['"]/);
|
|
1412
|
+
const count = html.match(/data-number-of-reviews=['"](\d+)['"]/);
|
|
1413
|
+
if (!rating || !count) throw new Error("Unreadable Judge.me attributes");
|
|
1414
|
+
return {
|
|
1415
|
+
rating: PostPurchaseCommonReviewRating.parse({ value: rating[1] }).value,
|
|
1416
|
+
reviewCount: PostPurchaseReviewCount.parse(count[1])
|
|
1417
|
+
};
|
|
1418
|
+
});
|
|
1419
|
+
};
|
|
1420
|
+
|
|
1421
|
+
// src/server/postPurchaseOkendoReviews.ts
|
|
1422
|
+
var import_zod15 = require("zod");
|
|
1423
|
+
var Summary = import_zod15.z.object({
|
|
1424
|
+
reviewAverageValue: PostPurchaseCommonReviewRating.shape.value,
|
|
1425
|
+
reviewCount: import_zod15.z.union([PostPurchaseProductReviews.shape.reviewCount, PostPurchaseReviewCount])
|
|
1426
|
+
});
|
|
1427
|
+
var readOkendoReviews = (find) => {
|
|
1428
|
+
const field = find("okendo", "summaryData");
|
|
1429
|
+
if (!field) return null;
|
|
1430
|
+
const summary = readReviewField(field, (value) => Summary.parse(JSON.parse(import_zod15.z.string().parse(value))));
|
|
1431
|
+
return { rating: summary.reviewAverageValue, reviewCount: summary.reviewCount };
|
|
1432
|
+
};
|
|
1433
|
+
|
|
1434
|
+
// src/server/postPurchaseScalarReviews.ts
|
|
1435
|
+
var import_zod16 = require("zod");
|
|
1436
|
+
var readScalarReviews = (find, namespace, ratingKey, countKey) => {
|
|
1437
|
+
const rating = find(namespace, ratingKey);
|
|
1438
|
+
const count = find(namespace, countKey);
|
|
1439
|
+
if (!rating || !count) return null;
|
|
1440
|
+
return {
|
|
1441
|
+
rating: readReviewField(
|
|
1442
|
+
rating,
|
|
1443
|
+
(value) => PostPurchaseCommonReviewRating.parse({ value: import_zod16.z.string().parse(value) }).value
|
|
1444
|
+
),
|
|
1445
|
+
reviewCount: readReviewField(count, (value) => PostPurchaseReviewCount.parse(value))
|
|
1446
|
+
};
|
|
1447
|
+
};
|
|
1448
|
+
|
|
1449
|
+
// src/server/postPurchaseReviewData.ts
|
|
1450
|
+
var readStandardReviews = (find) => {
|
|
1451
|
+
const rating = find("reviews", "rating");
|
|
1452
|
+
const count = find("reviews", "rating_count");
|
|
1453
|
+
if (!rating || !count) return null;
|
|
1454
|
+
return {
|
|
1455
|
+
rating: readReviewField(rating, (raw) => {
|
|
1456
|
+
const value = import_zod17.z.string().parse(raw);
|
|
1457
|
+
return PostPurchaseCommonReviewRating.parse(/^\d+(?:\.\d+)?$/.test(value) ? { value } : JSON.parse(value)).value;
|
|
1458
|
+
}),
|
|
1459
|
+
reviewCount: readReviewField(count, (value) => PostPurchaseReviewCount.parse(value))
|
|
1460
|
+
};
|
|
1461
|
+
};
|
|
1462
|
+
var readPostPurchaseReviewData = (provider, find) => {
|
|
1463
|
+
if (provider === "yotpo") return readScalarReviews(find, "yotpo", "reviews_average", "reviews_count");
|
|
1464
|
+
if (provider === "stamped") return readScalarReviews(find, "stamped", "reviews_average", "reviews_count");
|
|
1465
|
+
if (provider === "judgeme") return readJudgeMeReviews(find);
|
|
1466
|
+
if (provider === "okendo") return readOkendoReviews(find);
|
|
1467
|
+
if (provider === "opinew") return readScalarReviews(find, "opinew_metafields", "reviews_average", "reviews_count");
|
|
1468
|
+
if (provider === "reviewsio")
|
|
1469
|
+
return readScalarReviews(find, "reviewscouk", "rating", "total") ?? readStandardReviews(find);
|
|
1470
|
+
if (provider === "loox") return readScalarReviews(find, "loox", "avg_rating", "num_reviews");
|
|
1471
|
+
if (provider === "junip") return readScalarReviews(find, "junip", "rating_average", "rating_count");
|
|
1472
|
+
const rating = find("reviews", "rating");
|
|
1473
|
+
const count = find("reviews", "rating_count");
|
|
1474
|
+
if (!rating || !count) return null;
|
|
1475
|
+
return {
|
|
1476
|
+
rating: readReviewField(
|
|
1477
|
+
rating,
|
|
1478
|
+
(value) => PostPurchaseKlaviyoReviewRating.parse(JSON.parse(import_zod17.z.string().parse(value))).value
|
|
1479
|
+
),
|
|
1480
|
+
reviewCount: readReviewField(count, (value) => PostPurchaseReviewCount.parse(value))
|
|
1481
|
+
};
|
|
1482
|
+
};
|
|
1483
|
+
|
|
1484
|
+
// src/server/postPurchaseReviewProvider.ts
|
|
1485
|
+
var import_zod18 = require("zod");
|
|
1486
|
+
var IntegrationInput = import_zod18.z.record(import_zod18.z.string(), import_zod18.z.unknown()).prefault({});
|
|
1487
|
+
var precedence = [
|
|
1488
|
+
"klaviyo",
|
|
1489
|
+
"judgeme",
|
|
1490
|
+
"junip",
|
|
1491
|
+
"loox",
|
|
1492
|
+
"okendo",
|
|
1493
|
+
"opinew",
|
|
1494
|
+
"reviewsio",
|
|
1495
|
+
"stamped",
|
|
1496
|
+
"yotpo"
|
|
1497
|
+
];
|
|
1498
|
+
var ReviewsIoFlag = import_zod18.z.preprocess((value) => {
|
|
1499
|
+
if (typeof value === "string") {
|
|
1500
|
+
const flag = value.toLowerCase();
|
|
1501
|
+
if (flag === "true" || flag === "yes") return true;
|
|
1502
|
+
if (flag === "false" || flag === "no") return false;
|
|
1503
|
+
}
|
|
1504
|
+
return value;
|
|
1505
|
+
}, PostPurchaseSettings.shape.integrations.shape.reviewsio);
|
|
1506
|
+
var selectPostPurchaseReviewProvider = (raw) => {
|
|
1507
|
+
const integrations = IntegrationInput.parse(raw);
|
|
1508
|
+
for (const provider of precedence) {
|
|
1509
|
+
const schema = provider === "reviewsio" ? ReviewsIoFlag : PostPurchaseSettings.shape.integrations.shape[provider];
|
|
1510
|
+
if (schema.parse(integrations[provider])) return provider;
|
|
1511
|
+
}
|
|
1512
|
+
return null;
|
|
1513
|
+
};
|
|
1514
|
+
|
|
1515
|
+
// src/server/offerProductReviews.ts
|
|
1516
|
+
var readOrReport = (read, productId2, report) => {
|
|
1517
|
+
try {
|
|
1518
|
+
return read();
|
|
1519
|
+
} catch (error) {
|
|
1520
|
+
if (!(error instanceof ReviewFieldError)) throw error;
|
|
1521
|
+
report?.({
|
|
1522
|
+
detail: "Unreadable offer product reviews metafield",
|
|
1523
|
+
field: error.field,
|
|
1524
|
+
kind: "reviews",
|
|
1525
|
+
productId: productId2
|
|
1526
|
+
});
|
|
1527
|
+
return null;
|
|
1528
|
+
}
|
|
1529
|
+
};
|
|
1530
|
+
var readReviews = (provider, find, productId2, report) => (provider === "klaviyo" ? null : readOrReport(() => readPostPurchaseReviewData(provider, find), productId2, report)) ?? readOrReport(() => readStandardReviews(find), productId2, report);
|
|
1531
|
+
var projectOfferProductReviews = (integrations, { id: productId2, metafields }, report) => {
|
|
1532
|
+
let provider;
|
|
1533
|
+
try {
|
|
1534
|
+
provider = selectPostPurchaseReviewProvider(integrations);
|
|
1535
|
+
} catch {
|
|
1536
|
+
return void 0;
|
|
1537
|
+
}
|
|
1538
|
+
if (!provider) return void 0;
|
|
1539
|
+
try {
|
|
1540
|
+
if (!Array.isArray(metafields)) return null;
|
|
1541
|
+
const data = readReviews(provider, reviewFields(metafields), productId2, report);
|
|
1542
|
+
return data && data.rating > 0 ? data : null;
|
|
1543
|
+
} catch {
|
|
1544
|
+
report?.({ detail: "Unreadable offer product reviews", kind: "product" });
|
|
1545
|
+
return null;
|
|
1546
|
+
}
|
|
1547
|
+
};
|
|
1548
|
+
|
|
1549
|
+
// src/server/shopSubtotal.ts
|
|
1550
|
+
var shopCurrencyRate = (cart) => {
|
|
1551
|
+
const rate = cart.currencyRate ?? 1;
|
|
1552
|
+
return Number.isFinite(rate) && rate > 0 ? rate : 1;
|
|
1553
|
+
};
|
|
1554
|
+
var shopSubtotalCents = (cart) => Math.round((cart.subtotal - (cart.discountTotal ?? 0)) / shopCurrencyRate(cart));
|
|
1555
|
+
var toShopCents = (majorPresentment, rate) => Math.round(majorPresentment * 100 / rate);
|
|
1556
|
+
|
|
1557
|
+
// src/schema/cabShopConfig.ts
|
|
1558
|
+
var import_zod20 = require("zod");
|
|
1559
|
+
|
|
1560
|
+
// src/schema/driftedMarkets.ts
|
|
1561
|
+
var DRIFTED_MARKETS = Object.freeze({ enabled: false });
|
|
1562
|
+
|
|
1563
|
+
// src/schema/smartCart.ts
|
|
1564
|
+
var import_zod19 = require("zod");
|
|
1565
|
+
var SmartCartTierProduct = import_zod19.z.looseObject({
|
|
1566
|
+
handle: import_zod19.z.string().optional(),
|
|
1567
|
+
id: import_zod19.z.coerce.number().optional(),
|
|
1568
|
+
productId: import_zod19.z.coerce.number().optional(),
|
|
1569
|
+
title: import_zod19.z.string().optional(),
|
|
1570
|
+
variantIds: import_zod19.z.array(import_zod19.z.coerce.number()).optional()
|
|
1571
|
+
});
|
|
1572
|
+
var SmartCartTierExclusion = import_zod19.z.looseObject({
|
|
1573
|
+
collectionIds: import_zod19.z.array(import_zod19.z.coerce.number()).optional().catch(void 0),
|
|
1574
|
+
productIds: import_zod19.z.array(import_zod19.z.coerce.number()).optional().catch(void 0),
|
|
1575
|
+
tags: import_zod19.z.array(import_zod19.z.string()).optional().catch(void 0),
|
|
1576
|
+
type: import_zod19.z.string().optional().catch(void 0)
|
|
1577
|
+
});
|
|
1578
|
+
var SmartCartTier = import_zod19.z.looseObject({
|
|
1579
|
+
allProducts: import_zod19.z.array(SmartCartTierProduct).optional(),
|
|
1580
|
+
/** Merchant-set tier label (e.g. "Free gift", "$100 reward"), shown on the step row when enabled. */
|
|
1581
|
+
customTierLabel: import_zod19.z.boolean().optional(),
|
|
1582
|
+
customTierLabelText: import_zod19.z.string().optional(),
|
|
1583
|
+
decorativeAmountReachedLabel: import_zod19.z.boolean().optional(),
|
|
1584
|
+
decorativeAmountReachedLabelText: import_zod19.z.string().optional(),
|
|
1585
|
+
decorativeAmountRemainingLabel: import_zod19.z.boolean().optional(),
|
|
1586
|
+
decorativeAmountRemainingLabelText: import_zod19.z.string().optional(),
|
|
1587
|
+
/** Order-discount reward: `'fixedAmount'` (shop-currency dollars) or `'percentage'` (whole percent). */
|
|
1588
|
+
discountAmountFromTotal: import_zod19.z.coerce.number().optional(),
|
|
1589
|
+
discountAmountReachedLabel: import_zod19.z.boolean().optional(),
|
|
1590
|
+
discountAmountReachedLabelText: import_zod19.z.string().optional(),
|
|
1591
|
+
discountAmountRemainingLabel: import_zod19.z.boolean().optional(),
|
|
1592
|
+
discountAmountRemainingLabelText: import_zod19.z.string().optional(),
|
|
1593
|
+
discountType: import_zod19.z.string().optional(),
|
|
1594
|
+
/**
|
|
1595
|
+
* onsite `exclusions` + `exclusions_enabled` (REB-22305): per-tier rules the converter carries onto
|
|
1596
|
+
* `CABProgressTier.exclusions`. `.catch(undefined)` for the same blast-radius reason as `productTierImage`:
|
|
1597
|
+
* one drifted value must degrade to "no tier exclusions", never drop every progress bar for the shop.
|
|
1598
|
+
*
|
|
1599
|
+
* `exclusionsEnabled` is a STRICT boolean on purpose, even though failing open here changes the tier's math
|
|
1600
|
+
* (a non-boolean reads as disabled) rather than just an icon. onsite reads its sibling tier flags strictly —
|
|
1601
|
+
* `shouldFilterOutOfStockVariantsFromTier` is `tier?.filter_oos_variants === true`, and its `progressBar.ts`
|
|
1602
|
+
* types every tier flag as `boolean` — so a stored `1` / `"1"` / `"true"` is "disabled" on the onsite bar too.
|
|
1603
|
+
* A truthiness preprocess would make CAB exclude where onsite does not: the opposite parity break.
|
|
1604
|
+
*/
|
|
1605
|
+
exclusions: import_zod19.z.array(SmartCartTierExclusion).optional().catch(void 0),
|
|
1606
|
+
exclusionsEnabled: import_zod19.z.boolean().optional().catch(void 0),
|
|
1607
|
+
filterOosVariants: import_zod19.z.boolean().optional(),
|
|
1608
|
+
id: import_zod19.z.string().optional(),
|
|
1609
|
+
/**
|
|
1610
|
+
* A `null`/absent minimum stays `undefined` (NOT coerced to `0`): a threshold-0 tier is always reached
|
|
1611
|
+
* and would auto-add its gift to every cart. onsite's `isTierDataValid` drops a non-numeric minimum for
|
|
1612
|
+
* exactly this reason; the converter's `renderableTiers` mirrors that (`Number.isFinite`). A literal `0`
|
|
1613
|
+
* is kept — onsite keeps it too. DELIBERATE DIVERGENCE from onsite for string minimums: onsite's
|
|
1614
|
+
* `isTierDataValid` is a strict `typeof === 'number'`, so it drops `'50'`; the converter instead coerces
|
|
1615
|
+
* `'50' → 50` and keeps the tier (a numeric-string minimum is a valid threshold, not a data defect).
|
|
1616
|
+
*/
|
|
1617
|
+
minimum: import_zod19.z.preprocess((value) => value == null ? void 0 : value, import_zod19.z.coerce.number().optional()),
|
|
1618
|
+
presentmentCurrencies: import_zod19.z.looseObject({ enabled: import_zod19.z.boolean().optional() }).optional(),
|
|
1619
|
+
productAmountReachedLabel: import_zod19.z.boolean().optional(),
|
|
1620
|
+
productAmountReachedLabelText: import_zod19.z.string().optional(),
|
|
1621
|
+
productAmountRemainingLabel: import_zod19.z.boolean().optional(),
|
|
1622
|
+
productAmountRemainingLabelText: import_zod19.z.string().optional(),
|
|
1623
|
+
products: import_zod19.z.array(SmartCartTierProduct).optional(),
|
|
1624
|
+
/**
|
|
1625
|
+
* onsite `product_tier_element_size`: the step-row icon's square size as a px STRING (`'18px'` …
|
|
1626
|
+
* `'36px'` — the admin's five-value Size control, default `'18px'`). React stamps it onto the icon
|
|
1627
|
+
* SVG's `width`/`height` (`getProgressStepIconSize`), so the milestone renders at the merchant's
|
|
1628
|
+
* chosen size; the converter turns it into `CABProgressTier.iconSizePx` for the CAB renderer.
|
|
1629
|
+
*
|
|
1630
|
+
* `.catch(undefined)` for the same blast-radius reason as `productTierImage` below: this key was
|
|
1631
|
+
* previously unknown-and-ignored by the `looseObject`, and `SmartCartConfig` is parsed
|
|
1632
|
+
* `.nullish().catch(undefined)` with no intermediate catch, so one drifted value (a bare number, a
|
|
1633
|
+
* `'2rem'`) would drop EVERY progress bar for the shop rather than just this setting. Failing open to
|
|
1634
|
+
* `undefined` lands on the documented 18px default — strictly safer than that blast radius. The
|
|
1635
|
+
* converter parses the number out and clamps it, so a junk-but-string value degrades the same way.
|
|
1636
|
+
*/
|
|
1637
|
+
productTierElementSize: import_zod19.z.string().optional().catch(void 0),
|
|
1638
|
+
/**
|
|
1639
|
+
* onsite `product_tier_image`: on a product (gift) tier, show the gift's product image in the step-row
|
|
1640
|
+
* slot instead of the generic bag icon (React `TierProgressIcon` swaps in the image when this is set and
|
|
1641
|
+
* an image resolves). Per-tier; the client resolves the image (config carries only product IDs).
|
|
1642
|
+
*
|
|
1643
|
+
* `.catch(undefined)` is load-bearing. This key was previously unknown-and-ignored by the `looseObject`;
|
|
1644
|
+
* declaring it as a real boolean means a stored non-boolean (`1` / `"1"` / `"true"`) would now FAIL the
|
|
1645
|
+
* tier — and since `SmartCartConfig` is parsed `.nullish().catch(undefined)` (userConfig/cabShopConfig)
|
|
1646
|
+
* with no intermediate catch, one drifted flag would drop EVERY progress bar for the shop, not just the
|
|
1647
|
+
* flag. The converter only reads it for truthiness (`gift && tier.productTierImage`), so failing open to
|
|
1648
|
+
* `undefined` (bag-icon fallback, the documented default) is strictly safer than that blast radius.
|
|
1649
|
+
*/
|
|
1650
|
+
productTierImage: import_zod19.z.boolean().optional().catch(void 0),
|
|
1651
|
+
type: import_zod19.z.string().optional(),
|
|
1652
|
+
/**
|
|
1653
|
+
* onsite's PER-TIER unit switch (`unlock_condition_type`): `'item_quantity'` makes `minimum` an
|
|
1654
|
+
* item count (checked before any money handling — no ×100, no FX, no presentment overrides,
|
|
1655
|
+
* mirroring onsite `getTierMinimum`); anything else (or absent) keeps the money semantics.
|
|
1656
|
+
*/
|
|
1657
|
+
unlockConditionType: import_zod19.z.string().optional()
|
|
1658
|
+
});
|
|
1659
|
+
var SmartCartBar = import_zod19.z.looseObject({
|
|
1660
|
+
countryCodes: import_zod19.z.array(import_zod19.z.string()).optional(),
|
|
1661
|
+
/**
|
|
1662
|
+
* onsite `exclude_discount_in_subtotal`: measure progress against the PRE-discount subtotal so an
|
|
1663
|
+
* applied code/order discount doesn't lower progress. The client adds cart discount allocations back.
|
|
1664
|
+
*/
|
|
1665
|
+
excludeDiscountInSubtotal: import_zod19.z.boolean().optional(),
|
|
1666
|
+
/** Products excluded from the progress subtotal; the client subtracts their variants' cart cost. */
|
|
1667
|
+
excludedProducts: import_zod19.z.array(import_zod19.z.looseObject({ variantIds: import_zod19.z.array(import_zod19.z.coerce.number()).optional() })).optional(),
|
|
1668
|
+
freeShippingOnSubscription: import_zod19.z.boolean().optional(),
|
|
1669
|
+
geolocationEnabled: import_zod19.z.boolean().optional(),
|
|
1670
|
+
id: import_zod19.z.string().optional(),
|
|
1671
|
+
language: import_zod19.z.looseObject({
|
|
1672
|
+
freeShippingReached: import_zod19.z.string().optional(),
|
|
1673
|
+
freeShippingRemaining: import_zod19.z.string().optional(),
|
|
1674
|
+
giftAreaTitle: import_zod19.z.string().optional()
|
|
1675
|
+
}).optional(),
|
|
1676
|
+
name: import_zod19.z.string().optional(),
|
|
1677
|
+
tiers: import_zod19.z.array(SmartCartTier).optional()
|
|
1678
|
+
});
|
|
1679
|
+
var SmartCartComponent = import_zod19.z.looseObject({
|
|
1680
|
+
settings: import_zod19.z.looseObject({ bars: import_zod19.z.array(SmartCartBar).optional() }).optional(),
|
|
1681
|
+
type: import_zod19.z.string().optional()
|
|
1682
|
+
});
|
|
1683
|
+
var SmartCartConfig = import_zod19.z.looseObject({
|
|
1684
|
+
components: import_zod19.z.array(SmartCartComponent).optional()
|
|
1685
|
+
});
|
|
1686
|
+
|
|
1687
|
+
// src/schema/cabShopConfig.ts
|
|
1688
|
+
var CabActiveExperiment = import_zod20.z.object({
|
|
1689
|
+
data: import_zod20.z.array(
|
|
1690
|
+
import_zod20.z.object({
|
|
1691
|
+
elementId: import_zod20.z.coerce.number(),
|
|
1692
|
+
id: import_zod20.z.coerce.number(),
|
|
1693
|
+
traffic: import_zod20.z.coerce.number()
|
|
1694
|
+
})
|
|
1695
|
+
),
|
|
1696
|
+
id: import_zod20.z.coerce.number(),
|
|
1697
|
+
placeholderId: import_zod20.z.coerce.number().nullable(),
|
|
1698
|
+
type: import_zod20.z.string()
|
|
1699
|
+
});
|
|
1700
|
+
var CabShopConfig = import_zod20.z.object({
|
|
1701
|
+
/**
|
|
1702
|
+
* Per-element resilient: parse as `unknown[]` (non-array → `[]`), then keep only the experiments that
|
|
1703
|
+
* validate. A single drifted experiment drops itself instead of `.catch`-ing the WHOLE array to `[]` and
|
|
1704
|
+
* silently disabling every live A/B test fleet-wide.
|
|
1705
|
+
*/
|
|
1706
|
+
activeExperiments: import_zod20.z.array(import_zod20.z.unknown()).catch([]).default([]).transform(
|
|
1707
|
+
(experiments) => experiments.flatMap((experiment) => {
|
|
1708
|
+
const result = CabActiveExperiment.safeParse(experiment);
|
|
1709
|
+
return result.success ? [result.data] : [];
|
|
1710
|
+
})
|
|
1711
|
+
),
|
|
1712
|
+
/**
|
|
1713
|
+
* Only the two fields the smart-cart entitlement gate reads (`shortName`/`isActive`). Per-element
|
|
1714
|
+
* resilient like `activeExperiments`: a drifted package entry degrades to an inert `''`/false one that
|
|
1715
|
+
* matches nothing, so a real active `cart-merchandising` package still gates correctly and a sibling
|
|
1716
|
+
* drift never fails the shared config parse. Note the salvage is fail-CLOSED, not fail-open, for an
|
|
1717
|
+
* entitled v6 shop: a malformed whole array (⇒ `[]`) or an inerted `cart-merchandising` entry (e.g.
|
|
1718
|
+
* `is_active: 1` ⇒ inactive) makes the gate find no active package and drop every bar. That matches
|
|
1719
|
+
* React's "no proof of entitlement ⇒ render null", but it silently removes bars — so the server gate
|
|
1720
|
+
* ({@link file://../server/widgetSettings.ts} `fetchProgressBarContext`) emits a `shopConfig` drift
|
|
1721
|
+
* when it sees the inert-entry sentinel (`shortName === ''`). The whole-array `[]` case leaves no
|
|
1722
|
+
* sentinel and is not separately signalable here.
|
|
1723
|
+
*/
|
|
1724
|
+
activePackages: import_zod20.z.array(import_zod20.z.object({ isActive: import_zod20.z.boolean(), shortName: import_zod20.z.string() }).catch({ isActive: false, shortName: "" })).catch([]).default([]),
|
|
1725
|
+
apiKey: import_zod20.z.string(),
|
|
1726
|
+
/** The shop's billing generation; the smart-cart entitlement gate only fires for `'v6'`. Missing/drift ⇒ `null` (fail open, ungated). */
|
|
1727
|
+
billingVersion: import_zod20.z.string().nullable().catch(null).default(null),
|
|
1728
|
+
/**
|
|
1729
|
+
* The shop's rotating cache-buster: `onsite_cache_key` internally — a unix timestamp the engine bumps,
|
|
1730
|
+
* and the edge copy of this config purges, on every widget/settings/theme edit — but serialized on the
|
|
1731
|
+
* wire as `cache_key`, which `deepCamelCase` maps to this field (renaming it `onsiteCacheKey` would
|
|
1732
|
+
* sever the mapping silently; the wire-level assertion in `userConfig.test.ts` is what fails loudly).
|
|
1733
|
+
* Threaded onto the widgets/settings read as `cache_key` so the engine marks the response
|
|
1734
|
+
* immutable-cacheable and the `cached.*` edge serves it fresh-by-URL. The engine sends a numeric
|
|
1735
|
+
* string — coerce — but admit only number/string inputs and constrain to a positive integer: a bare
|
|
1736
|
+
* coercion folds `null`/`''`/`false` to `0` and `true` to `1` — "valid" numbers that would go upstream
|
|
1737
|
+
* as a constant never-rotating buster and pin the edge copy permanently stale. A real key is always a
|
|
1738
|
+
* positive int sent as number or string, so everything else lands on `.catch()` and degrades that read
|
|
1739
|
+
* to un-busted (origin-served — slower, never stale), never a parse fail.
|
|
1740
|
+
*/
|
|
1741
|
+
cacheKey: import_zod20.z.union([import_zod20.z.number(), import_zod20.z.string()]).transform((value) => Number(value)).pipe(import_zod20.z.number().int().positive()).optional().catch(void 0),
|
|
1742
|
+
/**
|
|
1743
|
+
* The shop's base-currency ISO code (e.g. `'USD'`). CAB derives the shop minor-unit exponent from it
|
|
1744
|
+
* (`currencyDecimals`) so a Functions-applied fixed discount — whose amount is in shop minor units —
|
|
1745
|
+
* converts to the buyer's currency exactly in a cross-decimal market. `.catch()` like its siblings: a
|
|
1746
|
+
* missing/renamed currency degrades to "unknown" (client falls back to buyer decimals), never a parse fail.
|
|
1747
|
+
*/
|
|
1748
|
+
currency: import_zod20.z.string().optional().catch(void 0),
|
|
1749
|
+
/**
|
|
1750
|
+
* The merchant's "Use Markets in Data Sources" toggle. The engine (CI2) never reads it on the serve
|
|
1751
|
+
* path, so the proxy honouring it before sending market context is what makes the setting mean
|
|
1752
|
+
* anything (REB-21688). Fail-CLOSED, unlike the fail-open siblings: a missing/null/drifted field reads
|
|
1753
|
+
* as markets OFF — market context silently dropped (engine serves shop-default market), never sent
|
|
1754
|
+
* against the merchant's setting. The OFF-reading salvages stay distinguishable: missing AND null are
|
|
1755
|
+
* the engine's normal absent vocabulary (`.nullish()`, like `monetize`/`billingVersion`) and read as
|
|
1756
|
+
* the plain default — not drift — while only a drifted SHAPE `.catch`es, to the {@link DRIFTED_MARKETS}
|
|
1757
|
+
* identity sentinel, so `fetchUserConfig` can emit a `shopConfig` drift for the one case that means an
|
|
1758
|
+
* engine rename/retype; otherwise a markets-enabled merchant degrading to shop-default pricing would
|
|
1759
|
+
* be indistinguishable from markets genuinely off. The missing-key case is EXPLICIT via `.default()`
|
|
1760
|
+
* (a factory, so parses never share a mutable object) rather than inferred from zod running an
|
|
1761
|
+
* optional key's transform on `undefined`; `null` flows past the default through `.nullish()` into the
|
|
1762
|
+
* transform. `Readonly` on the output type because the drifted salvage IS frozen — an assignment to
|
|
1763
|
+
* `markets.enabled` downstream would throw only for drifted shops in production, so surface direct
|
|
1764
|
+
* writes to tsc (a guard for the direct case only: TS doesn't check `readonly` in assignability, so
|
|
1765
|
+
* laundering through a mutable-shaped alias still compiles).
|
|
1766
|
+
* The inner `enabled` stays strict on purpose: `{ enabled: null }` is a genuine retype and drifting is
|
|
1767
|
+
* the correct answer (the editor-path `ShopConfig.markets` would hard-fail the same payload).
|
|
1768
|
+
*/
|
|
1769
|
+
markets: import_zod20.z.object({ enabled: import_zod20.z.boolean() }).nullish().catch(DRIFTED_MARKETS).default(() => ({ enabled: false })).transform((markets) => markets ?? { enabled: false }),
|
|
1770
|
+
monetize: import_zod20.z.object({ publisherKey: import_zod20.z.string().nullable() }).nullish().catch(void 0),
|
|
1771
|
+
shopId: import_zod20.z.number().optional().catch(void 0),
|
|
1772
|
+
/**
|
|
1773
|
+
* The merchant's display name ("Gift Basket Store") — the Monetize header copy reads it.
|
|
1774
|
+
* `.catch()` like its siblings: a missing/drifted name degrades the header to the
|
|
1775
|
+
* myshopify-domain slug (the pre-CAB React fallback), never a parse fail. An empty string is a
|
|
1776
|
+
* VALID parse — the slug fallback for `''` (and whitespace/tag-only names) lives in
|
|
1777
|
+
* composeOffer's `||` chain, not here.
|
|
1778
|
+
*/
|
|
1779
|
+
shopName: import_zod20.z.string().nullish().catch(void 0)
|
|
1780
|
+
});
|
|
1781
|
+
var CabUserConfig = import_zod20.z.object({
|
|
1782
|
+
shop: CabShopConfig,
|
|
1783
|
+
smartCart: SmartCartConfig.nullish().catch(void 0)
|
|
1784
|
+
});
|
|
1785
|
+
|
|
1786
|
+
// src/schema/widgets/checkout-and-beyond/image.ts
|
|
1787
|
+
var import_uuid14 = require("uuid");
|
|
1788
|
+
var import_zod39 = require("zod");
|
|
1789
|
+
|
|
1790
|
+
// src/schema/widgets/checkout-and-beyond/icons.ts
|
|
1791
|
+
var iconNames = [
|
|
1792
|
+
"alert-circle",
|
|
1793
|
+
"alert-triangle",
|
|
1794
|
+
"alert-triangle-filled",
|
|
1795
|
+
"arrow-down",
|
|
1796
|
+
"arrow-left",
|
|
1797
|
+
"arrow-right",
|
|
1798
|
+
"arrow-up",
|
|
1799
|
+
"arrow-up-right",
|
|
1800
|
+
"bag",
|
|
1801
|
+
"bullet",
|
|
1802
|
+
"calendar",
|
|
1803
|
+
"camera",
|
|
1804
|
+
"caret-down",
|
|
1805
|
+
"cart",
|
|
1806
|
+
"cash-dollar",
|
|
1807
|
+
"categories",
|
|
1808
|
+
"check",
|
|
1809
|
+
"check-circle",
|
|
1810
|
+
"check-circle-filled",
|
|
1811
|
+
"chevron-down",
|
|
1812
|
+
"chevron-left",
|
|
1813
|
+
"chevron-right",
|
|
1814
|
+
"chevron-up",
|
|
1815
|
+
"circle",
|
|
1816
|
+
"clipboard",
|
|
1817
|
+
"clock",
|
|
940
1818
|
"credit-card",
|
|
941
1819
|
"delete",
|
|
942
1820
|
"delivered",
|
|
@@ -994,283 +1872,65 @@ var iconTones = ["auto", "critical", "custom", "info", "neutral", "success", "wa
|
|
|
994
1872
|
var IconTone = freezeEnum(iconTones);
|
|
995
1873
|
|
|
996
1874
|
// src/schema/widgets/checkout-and-beyond/imageThumbnails.ts
|
|
997
|
-
var
|
|
998
|
-
var CABImageThumbnails =
|
|
999
|
-
limit:
|
|
1000
|
-
perLine:
|
|
1001
|
-
});
|
|
1002
|
-
|
|
1003
|
-
// src/schema/widgets/checkout-and-beyond/regex.ts
|
|
1004
|
-
var DYNAMIC_TOKEN_REGEX = /^\{\{\s*[A-Za-z]+\s*\}\}$/;
|
|
1005
|
-
var HEX_COLOR_REGEX = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
1006
|
-
var ROOT_RELATIVE_PATH_REGEX = /^\/(?!\/)/;
|
|
1007
|
-
var HTML_TAGS_REGEX = /<\/?[a-zA-Z][^>]*>/g;
|
|
1875
|
+
var import_zod21 = require("zod");
|
|
1876
|
+
var CABImageThumbnails = import_zod21.z.object({
|
|
1877
|
+
limit: import_zod21.z.number().int().min(1).default(8),
|
|
1878
|
+
perLine: import_zod21.z.number().int().min(1).max(8).default(4)
|
|
1879
|
+
});
|
|
1008
1880
|
|
|
1009
1881
|
// src/schema/widgets/checkout-and-beyond/shared.ts
|
|
1010
|
-
var
|
|
1882
|
+
var import_zod38 = require("zod");
|
|
1011
1883
|
|
|
1012
1884
|
// src/schema/widgets/checkout-and-beyond/banner.ts
|
|
1013
|
-
var
|
|
1014
|
-
|
|
1015
|
-
// src/schema/widgets/checkout-and-beyond/layout.ts
|
|
1016
|
-
var import_uuid = require("uuid");
|
|
1017
|
-
var import_zod10 = require("zod");
|
|
1018
|
-
|
|
1019
|
-
// src/schema/widgets/checkout-and-beyond/variables.ts
|
|
1020
|
-
var import_zod9 = require("zod");
|
|
1021
|
-
|
|
1022
|
-
// src/schema/widgets/checkout-and-beyond/rule.ts
|
|
1023
|
-
var import_zod8 = require("zod");
|
|
1024
|
-
var ruleTypes = [
|
|
1025
|
-
"cart",
|
|
1026
|
-
"cart_count",
|
|
1027
|
-
"cart_item_count",
|
|
1028
|
-
"cart_line_count",
|
|
1029
|
-
"cart_subtotal",
|
|
1030
|
-
"collection",
|
|
1031
|
-
"customer",
|
|
1032
|
-
"customer_order_count",
|
|
1033
|
-
"customer_tag",
|
|
1034
|
-
"customer_total_spent",
|
|
1035
|
-
"date",
|
|
1036
|
-
"product",
|
|
1037
|
-
"product_tag",
|
|
1038
|
-
"product_title",
|
|
1039
|
-
"product_type",
|
|
1040
|
-
"product_vendor"
|
|
1041
|
-
];
|
|
1042
|
-
var ruleType = import_zod8.z.enum(ruleTypes);
|
|
1043
|
-
var RuleType = ruleType.enum;
|
|
1044
|
-
var ruleOperators = [
|
|
1045
|
-
"after",
|
|
1046
|
-
"anything",
|
|
1047
|
-
"before",
|
|
1048
|
-
"contains",
|
|
1049
|
-
"contains_any",
|
|
1050
|
-
"does_not_contain",
|
|
1051
|
-
"does_not_contain_any",
|
|
1052
|
-
"equals",
|
|
1053
|
-
"does_not_equal",
|
|
1054
|
-
"greater_than",
|
|
1055
|
-
"less_than"
|
|
1056
|
-
];
|
|
1057
|
-
var ruleOperator = import_zod8.z.enum(ruleOperators);
|
|
1058
|
-
var RuleOperator = ruleOperator.enum;
|
|
1059
|
-
var RuleCondition = import_zod8.z.object({
|
|
1060
|
-
operator: import_zod8.z.enum(ruleOperators).default(RuleOperator.anything),
|
|
1061
|
-
products: import_zod8.z.union([import_zod8.z.array(import_zod8.z.unknown()), import_zod8.z.strictObject({}).transform(() => [])]).default(() => []),
|
|
1062
|
-
type: import_zod8.z.enum(ruleTypes).default(RuleType.cart_subtotal),
|
|
1063
|
-
value: import_zod8.z.coerce.string().default("")
|
|
1064
|
-
});
|
|
1065
|
-
var RuleLogicBlock = import_zod8.z.object({
|
|
1066
|
-
rules: import_zod8.z.array(RuleCondition).default(() => [])
|
|
1067
|
-
});
|
|
1068
|
-
var CABRulesetEntry = import_zod8.z.object({
|
|
1069
|
-
exitIfMatched: import_zod8.z.boolean().default(true),
|
|
1070
|
-
logic: import_zod8.z.array(RuleLogicBlock).default(() => []),
|
|
1071
|
-
output: import_zod8.z.array(
|
|
1072
|
-
import_zod8.z.object({
|
|
1073
|
-
key: import_zod8.z.string().default("should_show"),
|
|
1074
|
-
type: import_zod8.z.literal("data_json").default("data_json"),
|
|
1075
|
-
value: import_zod8.z.string().default("true")
|
|
1076
|
-
})
|
|
1077
|
-
).default(() => [{ key: "should_show", type: "data_json", value: "true" }])
|
|
1078
|
-
});
|
|
1079
|
-
var CABRuleset = import_zod8.z.union([import_zod8.z.array(CABRulesetEntry), import_zod8.z.strictObject({}).transform(() => [])]).default(() => []);
|
|
1080
|
-
|
|
1081
|
-
// src/schema/widgets/checkout-and-beyond/variables.ts
|
|
1082
|
-
var variableEffect = import_zod9.z.enum(variableEffects);
|
|
1083
|
-
var CABVariableSeed = import_zod9.z.object({
|
|
1084
|
-
dataSourceId: import_zod9.z.number().nullable().default(null),
|
|
1085
|
-
ruleset: CABRuleset
|
|
1086
|
-
});
|
|
1087
|
-
var CABBooleanVariable = import_zod9.z.object({
|
|
1088
|
-
/**
|
|
1089
|
-
* Holds until the first seed verdict lands (and forever, for unseeded variables). Omitted, it derives
|
|
1090
|
-
* from seededness — `false` with a `seed` (visibility is EARNED), `true` without — via the transform
|
|
1091
|
-
* below; a cross-field default has no `.default()` spelling. An explicit value always wins.
|
|
1092
|
-
*/
|
|
1093
|
-
defaultValue: import_zod9.z.boolean().optional(),
|
|
1094
|
-
name: import_zod9.z.string().min(1),
|
|
1095
|
-
seed: CABVariableSeed.optional(),
|
|
1096
|
-
/** Defaulted so every stored declaration (all boolean before `text` existed) parses unchanged. */
|
|
1097
|
-
type: import_zod9.z.literal(VariableType.boolean).default(VariableType.boolean)
|
|
1098
|
-
});
|
|
1099
|
-
var CABTextVariable = import_zod9.z.object({
|
|
1100
|
-
defaultValue: import_zod9.z.string(),
|
|
1101
|
-
name: import_zod9.z.string().min(1),
|
|
1102
|
-
seed: import_zod9.z.never().optional(),
|
|
1103
|
-
type: import_zod9.z.literal(VariableType.text)
|
|
1104
|
-
});
|
|
1105
|
-
var CABNumberVariable = import_zod9.z.object({
|
|
1106
|
-
defaultValue: import_zod9.z.number(),
|
|
1107
|
-
name: import_zod9.z.string().min(1),
|
|
1108
|
-
seed: import_zod9.z.never().optional(),
|
|
1109
|
-
type: import_zod9.z.literal(VariableType.number)
|
|
1110
|
-
});
|
|
1111
|
-
var CABVariable = import_zod9.z.union([CABTextVariable, CABNumberVariable, CABBooleanVariable]).transform(
|
|
1112
|
-
(variable) => variable.type === VariableType.boolean ? { ...variable, defaultValue: variable.defaultValue ?? variable.seed === void 0 } : variable
|
|
1113
|
-
);
|
|
1114
|
-
var CABVariableEffect = import_zod9.z.object({
|
|
1115
|
-
effect: variableEffect.default(VariableEffect.toggle),
|
|
1116
|
-
variable: import_zod9.z.string().min(1)
|
|
1117
|
-
});
|
|
1118
|
-
var CABVisibility = import_zod9.z.object({
|
|
1119
|
-
variable: import_zod9.z.string().min(1),
|
|
1120
|
-
visibleWhen: import_zod9.z.boolean().default(true)
|
|
1121
|
-
});
|
|
1122
|
-
var contentOperator = import_zod9.z.enum(contentOperators);
|
|
1123
|
-
var resultCountOperator = import_zod9.z.enum(resultCountOperators);
|
|
1124
|
-
var resultTagOperator = import_zod9.z.enum(resultTagOperators);
|
|
1125
|
-
var mutatorEvent = import_zod9.z.enum(mutatorEvents);
|
|
1126
|
-
var CABContentTrigger = import_zod9.z.object({
|
|
1127
|
-
operator: contentOperator.default(ContentOperator.is_empty),
|
|
1128
|
-
type: import_zod9.z.literal("content")
|
|
1129
|
-
});
|
|
1130
|
-
var CABResultCountTrigger = import_zod9.z.object({
|
|
1131
|
-
operator: resultCountOperator.default(ResultCountOperator.equals),
|
|
1132
|
-
type: import_zod9.z.literal("result_count"),
|
|
1133
|
-
value: import_zod9.z.number().default(0)
|
|
1134
|
-
});
|
|
1135
|
-
var CABResultTagTrigger = import_zod9.z.object({
|
|
1136
|
-
operator: resultTagOperator.default(ResultTagOperator.contains),
|
|
1137
|
-
type: import_zod9.z.literal("result_tag"),
|
|
1138
|
-
value: import_zod9.z.string().min(1)
|
|
1139
|
-
});
|
|
1140
|
-
var CABEventTrigger = import_zod9.z.object({
|
|
1141
|
-
event: mutatorEvent,
|
|
1142
|
-
type: import_zod9.z.literal("event")
|
|
1143
|
-
});
|
|
1144
|
-
var CABVariableTrigger = import_zod9.z.discriminatedUnion("type", [
|
|
1145
|
-
CABContentTrigger,
|
|
1146
|
-
CABEventTrigger,
|
|
1147
|
-
CABResultCountTrigger,
|
|
1148
|
-
CABResultTagTrigger
|
|
1149
|
-
]);
|
|
1150
|
-
var CABVariableMutator = import_zod9.z.object({
|
|
1151
|
-
effect: variableEffect.default(VariableEffect.set_false),
|
|
1152
|
-
variable: import_zod9.z.string().min(1),
|
|
1153
|
-
when: CABVariableTrigger
|
|
1154
|
-
});
|
|
1155
|
-
var CABVariableFields = {
|
|
1156
|
-
mutators: import_zod9.z.array(CABVariableMutator).optional(),
|
|
1157
|
-
variables: import_zod9.z.array(CABVariable).refine((variables) => new Set(variables.map(({ name }) => name)).size === variables.length, {
|
|
1158
|
-
message: "variable names must be unique within a section"
|
|
1159
|
-
}).optional(),
|
|
1160
|
-
visibility: CABVisibility.optional()
|
|
1161
|
-
};
|
|
1885
|
+
var import_zod23 = require("zod");
|
|
1162
1886
|
|
|
1163
1887
|
// src/schema/widgets/checkout-and-beyond/layout.ts
|
|
1164
|
-
var
|
|
1165
|
-
var
|
|
1166
|
-
|
|
1167
|
-
|
|
1888
|
+
var import_uuid3 = require("uuid");
|
|
1889
|
+
var import_zod22 = require("zod");
|
|
1890
|
+
var GridItem = import_zod22.z.union([import_zod22.z.literal("auto"), import_zod22.z.literal("fill"), import_zod22.z.string().regex(/^\d+%$/), import_zod22.z.number()]);
|
|
1891
|
+
var CABLayoutWrapping = import_zod22.z.object({
|
|
1892
|
+
breakAt: import_zod22.z.number().positive(),
|
|
1893
|
+
maxPerLine: import_zod22.z.number().int().positive()
|
|
1168
1894
|
});
|
|
1169
|
-
var CABLayoutSection =
|
|
1895
|
+
var CABLayoutSection = import_zod22.z.object({
|
|
1170
1896
|
...CABVariableFields,
|
|
1171
|
-
alignment:
|
|
1172
|
-
horizontal:
|
|
1173
|
-
vertical:
|
|
1897
|
+
alignment: import_zod22.z.object({
|
|
1898
|
+
horizontal: import_zod22.z.enum(horizontalAlignments).default(HorizontalAlignment.start),
|
|
1899
|
+
vertical: import_zod22.z.enum(verticalAlignments).default(VerticalAlignment.top)
|
|
1174
1900
|
}).default({
|
|
1175
1901
|
horizontal: HorizontalAlignment.start,
|
|
1176
1902
|
vertical: VerticalAlignment.top
|
|
1177
1903
|
}),
|
|
1178
|
-
border:
|
|
1179
|
-
buttonField:
|
|
1180
|
-
direction:
|
|
1904
|
+
border: import_zod22.z.lazy(() => CABBorder),
|
|
1905
|
+
buttonField: import_zod22.z.enum(buttonFields).optional(),
|
|
1906
|
+
direction: import_zod22.z.enum(directions).default(Direction.rows),
|
|
1181
1907
|
/**
|
|
1182
1908
|
* Platform chrome around the section, not a layout behavior: `callout` is a subdued box with block borders
|
|
1183
1909
|
* (the legacy post-purchase callout banner), `offer-content` the post-purchase offer's own content card.
|
|
1184
1910
|
*/
|
|
1185
|
-
frame:
|
|
1186
|
-
grid:
|
|
1187
|
-
columns:
|
|
1188
|
-
rows:
|
|
1911
|
+
frame: import_zod22.z.enum(layoutFrames).optional(),
|
|
1912
|
+
grid: import_zod22.z.object({
|
|
1913
|
+
columns: import_zod22.z.union([import_zod22.z.array(GridItem), import_zod22.z.undefined()]).default(() => ["auto"]),
|
|
1914
|
+
rows: import_zod22.z.union([import_zod22.z.array(GridItem), import_zod22.z.undefined()]).default(() => ["auto"])
|
|
1189
1915
|
}).default({ columns: ["auto"], rows: ["auto"] }).optional(),
|
|
1190
|
-
name:
|
|
1191
|
-
padding:
|
|
1192
|
-
sectionId:
|
|
1193
|
-
sections:
|
|
1194
|
-
sectionType:
|
|
1195
|
-
spacing:
|
|
1916
|
+
name: import_zod22.z.string().optional(),
|
|
1917
|
+
padding: import_zod22.z.enum(spacings).default(Spacing.none),
|
|
1918
|
+
sectionId: import_zod22.z.uuid().default(() => (0, import_uuid3.v7)()),
|
|
1919
|
+
sections: import_zod22.z.union([import_zod22.z.array(import_zod22.z.lazy(() => CABSection)), import_zod22.z.strictObject({}).transform(() => [])]).default(() => []),
|
|
1920
|
+
sectionType: import_zod22.z.literal(SectionType.layout).default(SectionType.layout),
|
|
1921
|
+
spacing: import_zod22.z.enum(spacings).default(Spacing.base),
|
|
1196
1922
|
/** Fire-and-forget impression pixel POSTed once when the section is shown (e.g. a Monetize offer view). */
|
|
1197
|
-
viewUrl:
|
|
1198
|
-
width:
|
|
1923
|
+
viewUrl: import_zod22.z.string().optional(),
|
|
1924
|
+
width: import_zod22.z.number().default(100),
|
|
1199
1925
|
wrapping: CABLayoutWrapping.optional()
|
|
1200
1926
|
});
|
|
1201
1927
|
|
|
1202
|
-
// src/schema/widgets/checkout-and-beyond/utils.ts
|
|
1203
|
-
var import_es_toolkit2 = require("es-toolkit");
|
|
1204
|
-
var import_compat = require("es-toolkit/compat");
|
|
1205
|
-
|
|
1206
|
-
// src/transforms/convertNumericObjects.ts
|
|
1207
|
-
var import_es_toolkit = require("es-toolkit");
|
|
1208
|
-
var ARRAY_INDEX_STRING = /^(?:0|[1-9]\d*)$/;
|
|
1209
|
-
var hasOnlyNumericKeys = (input, requireCompleteRun) => {
|
|
1210
|
-
const keys = Object.keys(input);
|
|
1211
|
-
if (keys.length === 0) return false;
|
|
1212
|
-
if (!keys.every((key) => ARRAY_INDEX_STRING.test(key) && Number.isSafeInteger(Number(key)))) return false;
|
|
1213
|
-
if (!requireCompleteRun) return true;
|
|
1214
|
-
const sorted = keys.map(Number).sort((a, b) => a - b);
|
|
1215
|
-
return sorted.every((n, i) => n === i);
|
|
1216
|
-
};
|
|
1217
|
-
var numericObjectToArray = (input) => Object.entries(input).sort(([a], [b]) => Number(a) - Number(b)).map(([, value]) => value);
|
|
1218
|
-
var convert = (input, requireCompleteRun) => {
|
|
1219
|
-
if (Array.isArray(input)) return input.map((item) => convert(item, requireCompleteRun));
|
|
1220
|
-
if ((0, import_es_toolkit.isPlainObject)(input)) {
|
|
1221
|
-
if (hasOnlyNumericKeys(input, requireCompleteRun)) {
|
|
1222
|
-
return numericObjectToArray(input).map((item) => convert(item, requireCompleteRun));
|
|
1223
|
-
}
|
|
1224
|
-
const out = {};
|
|
1225
|
-
for (const [key, value] of Object.entries(input)) out[key] = convert(value, requireCompleteRun);
|
|
1226
|
-
return out;
|
|
1227
|
-
}
|
|
1228
|
-
return input;
|
|
1229
|
-
};
|
|
1230
|
-
var convertNumericObjects = (input) => convert(input, true);
|
|
1231
|
-
|
|
1232
|
-
// src/schema/widgets/checkout-and-beyond/utils.ts
|
|
1233
|
-
var isHTML = (html = "") => {
|
|
1234
|
-
if (typeof window !== "undefined") {
|
|
1235
|
-
const parser = new DOMParser();
|
|
1236
|
-
const doc = parser.parseFromString(html, "text/html");
|
|
1237
|
-
const hasHTML = (nodeList) => Array.from(nodeList).some((node) => node.nodeType === 1);
|
|
1238
|
-
return hasHTML(doc.body.childNodes) || hasHTML(doc.head.childNodes);
|
|
1239
|
-
}
|
|
1240
|
-
return html.search(HTML_TAGS_REGEX) !== -1;
|
|
1241
|
-
};
|
|
1242
|
-
var hasHTMLInDoc = (doc) => doc.content.some(({ content = [] }) => content.some(({ text: text2 }) => isHTML(text2)));
|
|
1243
|
-
var checkForHTML = (input) => !((0, import_compat.isString)(input) && isHTML(input) || (0, import_es_toolkit2.isPlainObject)(input) && hasHTMLInDoc(input));
|
|
1244
|
-
var NO_HTML = { message: "HTML is not supported" };
|
|
1245
|
-
var isSectionType = (sectionType) => (section) => (0, import_compat.get)(section, "sectionType") === sectionType;
|
|
1246
|
-
var isBannerType = isSectionType(SectionType.banner);
|
|
1247
|
-
var isButtonType = isSectionType(SectionType.button);
|
|
1248
|
-
var isCarouselType = isSectionType(SectionType.carousel);
|
|
1249
|
-
var isCartLineType = isSectionType(SectionType.cartLine);
|
|
1250
|
-
var isDataSourceType = isSectionType(
|
|
1251
|
-
SectionType.dataSource
|
|
1252
|
-
);
|
|
1253
|
-
var isDiscountType = isSectionType(SectionType.discount);
|
|
1254
|
-
var isImageType = isSectionType(SectionType.image);
|
|
1255
|
-
var isLayoutType = isSectionType(SectionType.layout);
|
|
1256
|
-
var isMonetizeType = isSectionType(SectionType.monetize);
|
|
1257
|
-
var isOffersType = isSectionType(SectionType.offers);
|
|
1258
|
-
var isProductType = isSectionType(SectionType.product);
|
|
1259
|
-
var isProductsType = isSectionType(SectionType.products);
|
|
1260
|
-
var isProgressBarType = isSectionType(
|
|
1261
|
-
SectionType.progressBar
|
|
1262
|
-
);
|
|
1263
|
-
var isQuantityType = isSectionType(SectionType.quantity);
|
|
1264
|
-
var isReviewsType = isSectionType(SectionType.reviews);
|
|
1265
|
-
var isTextType = isSectionType(SectionType.text);
|
|
1266
|
-
var isVariantsType = isSectionType(SectionType.variants);
|
|
1267
|
-
|
|
1268
1928
|
// src/schema/widgets/checkout-and-beyond/banner.ts
|
|
1269
|
-
var CABBannerSection =
|
|
1929
|
+
var CABBannerSection = import_zod23.z.lazy(
|
|
1270
1930
|
() => CABLayoutSection.omit({ sectionType: true }).extend({
|
|
1271
|
-
buttonField:
|
|
1272
|
-
color:
|
|
1273
|
-
dismissible:
|
|
1931
|
+
buttonField: import_zod23.z.enum(buttonFields).optional(),
|
|
1932
|
+
color: import_zod23.z.enum(bannerColors).default("info"),
|
|
1933
|
+
dismissible: import_zod23.z.boolean().default(true),
|
|
1274
1934
|
/**
|
|
1275
1935
|
* The `s-banner` heading — localized content (a buyer can see a merchant-composed banner). Absent OR
|
|
1276
1936
|
* blank ⇒ no heading; the renderer emits no heading slot for `''` rather than an empty one.
|
|
@@ -1286,140 +1946,50 @@ var CABBannerSection = import_zod11.z.lazy(
|
|
|
1286
1946
|
* not a 500. Nothing emits `heading` yet; the first converter that maps merchant banner copy into it
|
|
1287
1947
|
* either strips first or teaches `normalizeTextContent` to strip this field.
|
|
1288
1948
|
*/
|
|
1289
|
-
heading:
|
|
1290
|
-
sectionType:
|
|
1949
|
+
heading: import_zod23.z.record(import_zod23.z.string(), import_zod23.z.string().refine(checkForHTML, NO_HTML)).optional(),
|
|
1950
|
+
sectionType: import_zod23.z.literal(SectionType.banner).default(SectionType.banner)
|
|
1291
1951
|
})
|
|
1292
1952
|
);
|
|
1293
1953
|
|
|
1294
1954
|
// src/schema/widgets/checkout-and-beyond/button.ts
|
|
1295
|
-
var
|
|
1296
|
-
var
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
var import_compat2 = require("es-toolkit/compat");
|
|
1300
|
-
var import_uuid2 = require("uuid");
|
|
1301
|
-
var import_zod12 = require("zod");
|
|
1302
|
-
var enumOrOmit = (...vals) => import_zod12.z.string().transform((val) => vals.includes(val) ? val : void 0).optional();
|
|
1303
|
-
var TiptapText = import_zod12.z.object({
|
|
1304
|
-
marks: import_zod12.z.union([
|
|
1305
|
-
import_zod12.z.array(
|
|
1306
|
-
import_zod12.z.discriminatedUnion("type", [
|
|
1307
|
-
import_zod12.z.object({ type: import_zod12.z.literal("bold") }),
|
|
1308
|
-
import_zod12.z.object({ type: import_zod12.z.literal("italic") }),
|
|
1309
|
-
import_zod12.z.object({
|
|
1310
|
-
attrs: import_zod12.z.object({
|
|
1311
|
-
class: import_zod12.z.string().nullable(),
|
|
1312
|
-
href: import_zod12.z.union([
|
|
1313
|
-
import_zod12.z.url(),
|
|
1314
|
-
import_zod12.z.literal("#"),
|
|
1315
|
-
import_zod12.z.string().regex(DYNAMIC_TOKEN_REGEX),
|
|
1316
|
-
import_zod12.z.string().regex(ROOT_RELATIVE_PATH_REGEX)
|
|
1317
|
-
]),
|
|
1318
|
-
rel: import_zod12.z.string().default("noopener noreferrer nofollow"),
|
|
1319
|
-
target: import_zod12.z.string().default("_blank")
|
|
1320
|
-
}),
|
|
1321
|
-
type: import_zod12.z.literal("link")
|
|
1322
|
-
}),
|
|
1323
|
-
import_zod12.z.object({ type: import_zod12.z.literal("strike") }),
|
|
1324
|
-
import_zod12.z.object({
|
|
1325
|
-
attrs: import_zod12.z.object({
|
|
1326
|
-
color: enumOrOmit(...textColorNames).default(TextColorName.base),
|
|
1327
|
-
fontSize: enumOrOmit(...textSizeNames).default(TextSizeName.base)
|
|
1328
|
-
}),
|
|
1329
|
-
type: import_zod12.z.literal("textStyle")
|
|
1330
|
-
})
|
|
1331
|
-
])
|
|
1332
|
-
),
|
|
1333
|
-
import_zod12.z.strictObject({}).transform(() => [])
|
|
1334
|
-
]).optional(),
|
|
1335
|
-
text: import_zod12.z.string().default(""),
|
|
1336
|
-
type: import_zod12.z.literal("text").default("text")
|
|
1337
|
-
});
|
|
1338
|
-
var TiptapParagraph = import_zod12.z.object({
|
|
1339
|
-
attrs: import_zod12.z.object({
|
|
1340
|
-
textAlign: enumOrOmit(...textAlignments)
|
|
1341
|
-
}).default({ textAlign: TextAlignment.start }),
|
|
1342
|
-
content: import_zod12.z.union([import_zod12.z.array(TiptapText), import_zod12.z.strictObject({}).transform(() => [])]).default(() => []),
|
|
1343
|
-
type: import_zod12.z.literal("paragraph").default("paragraph")
|
|
1344
|
-
});
|
|
1345
|
-
var TiptapDocument = import_zod12.z.object({
|
|
1346
|
-
attrs: import_zod12.z.object({
|
|
1347
|
-
blockSpacing: enumOrOmit(...spacings)
|
|
1348
|
-
}).default({ blockSpacing: Spacing.base }),
|
|
1349
|
-
content: import_zod12.z.union([import_zod12.z.array(TiptapParagraph), import_zod12.z.strictObject({}).transform(() => [])]).default(() => [TiptapParagraph.parse({})]),
|
|
1350
|
-
type: import_zod12.z.literal("doc").default("doc")
|
|
1351
|
-
});
|
|
1352
|
-
var CABTextTier = import_zod12.z.object({
|
|
1353
|
-
threshold: import_zod12.z.number().int().nonnegative(),
|
|
1354
|
-
thresholds: import_zod12.z.record(import_zod12.z.string(), import_zod12.z.number().int().nonnegative()).default(() => ({})),
|
|
1355
|
-
tierId: import_zod12.z.string().optional(),
|
|
1356
|
-
tierType: import_zod12.z.enum(progressTierTypes).default(ProgressTierType.shipping)
|
|
1357
|
-
});
|
|
1358
|
-
var CABTextSection = import_zod12.z.object({
|
|
1359
|
-
...CABVariableFields,
|
|
1360
|
-
buttonField: import_zod12.z.enum(buttonFields).optional(),
|
|
1361
|
-
content: import_zod12.z.record(import_zod12.z.string(), import_zod12.z.union([import_zod12.z.string(), TiptapDocument]).refine(checkForHTML, NO_HTML).optional()).default({ en: TiptapDocument.parse({}) }).optional(),
|
|
1362
|
-
name: import_zod12.z.string().optional(),
|
|
1363
|
-
optionId: import_zod12.z.number().optional(),
|
|
1364
|
-
sectionId: import_zod12.z.uuid().default(() => (0, import_uuid2.v7)()),
|
|
1365
|
-
sectionType: import_zod12.z.literal(SectionType.text).default(SectionType.text),
|
|
1366
|
-
tier: CABTextTier.optional()
|
|
1367
|
-
}).superRefine(({ buttonField, content }, ctx) => {
|
|
1368
|
-
if (buttonField === ButtonField.destinationUrl && content) {
|
|
1369
|
-
(0, import_compat2.forEach)(content, (value, lang) => {
|
|
1370
|
-
if (value && (0, import_compat2.isString)(value)) {
|
|
1371
|
-
if (DYNAMIC_TOKEN_REGEX.test(value)) return;
|
|
1372
|
-
try {
|
|
1373
|
-
new URL(value);
|
|
1374
|
-
} catch {
|
|
1375
|
-
ctx.addIssue({
|
|
1376
|
-
code: "custom",
|
|
1377
|
-
message: "Invalid URL",
|
|
1378
|
-
path: ["content", lang]
|
|
1379
|
-
});
|
|
1380
|
-
}
|
|
1381
|
-
}
|
|
1382
|
-
});
|
|
1383
|
-
}
|
|
1384
|
-
});
|
|
1385
|
-
|
|
1386
|
-
// src/schema/widgets/checkout-and-beyond/button.ts
|
|
1387
|
-
var CABButtonContent = import_zod13.z.lazy(
|
|
1388
|
-
() => import_zod13.z.discriminatedUnion("sectionType", [CABImageSection, CABLayoutSection, CABTextSection])
|
|
1955
|
+
var import_uuid4 = require("uuid");
|
|
1956
|
+
var import_zod24 = require("zod");
|
|
1957
|
+
var CABButtonContent = import_zod24.z.lazy(
|
|
1958
|
+
() => import_zod24.z.discriminatedUnion("sectionType", [CABImageSection, CABLayoutSection, CABTextSection])
|
|
1389
1959
|
);
|
|
1390
|
-
var CABButtonSection =
|
|
1960
|
+
var CABButtonSection = import_zod24.z.object({
|
|
1391
1961
|
...CABVariableFields,
|
|
1392
|
-
action:
|
|
1393
|
-
buttonStyle:
|
|
1394
|
-
custom:
|
|
1395
|
-
color:
|
|
1396
|
-
height:
|
|
1397
|
-
width:
|
|
1962
|
+
action: import_zod24.z.union([import_zod24.z.literal(""), import_zod24.z.enum(buttonActions)]).default(""),
|
|
1963
|
+
buttonStyle: import_zod24.z.enum(buttonStyles).default(ButtonStyle.primary),
|
|
1964
|
+
custom: import_zod24.z.object({
|
|
1965
|
+
color: import_zod24.z.string().regex(HEX_COLOR_REGEX).default("#005bd3"),
|
|
1966
|
+
height: import_zod24.z.number().default(52),
|
|
1967
|
+
width: import_zod24.z.number().default(300)
|
|
1398
1968
|
}).default({
|
|
1399
1969
|
color: "#005bd3",
|
|
1400
1970
|
height: 52,
|
|
1401
1971
|
width: 300
|
|
1402
1972
|
}),
|
|
1403
|
-
disableDowngrade:
|
|
1973
|
+
disableDowngrade: import_zod24.z.boolean().default(false),
|
|
1404
1974
|
/**
|
|
1405
1975
|
* What labels a `switchToSubscription` button's frequency options. `planName` shows the selling plan's
|
|
1406
1976
|
* own name (legacy post-purchase, L115) and falls back to the `subscriptionOption` template for a plan
|
|
1407
1977
|
* without one; absent or `template` is the template alone (the checkout card). Optional and additive
|
|
1408
1978
|
* (REB-24846); an unknown value reads as absent.
|
|
1409
1979
|
*/
|
|
1410
|
-
frequencyLabel:
|
|
1411
|
-
name:
|
|
1412
|
-
optionId:
|
|
1413
|
-
popover:
|
|
1414
|
-
alignment:
|
|
1415
|
-
position:
|
|
1980
|
+
frequencyLabel: import_zod24.z.enum(["planName", "template"]).optional().catch(void 0),
|
|
1981
|
+
name: import_zod24.z.string().optional(),
|
|
1982
|
+
optionId: import_zod24.z.number().optional(),
|
|
1983
|
+
popover: import_zod24.z.object({
|
|
1984
|
+
alignment: import_zod24.z.enum(textAlignments).default(TextAlignment.center),
|
|
1985
|
+
position: import_zod24.z.enum(popoverPositions).default(PopoverPosition.blockStart)
|
|
1416
1986
|
}).optional().default(() => ({
|
|
1417
1987
|
alignment: TextAlignment.center,
|
|
1418
1988
|
position: PopoverPosition.blockStart
|
|
1419
1989
|
})),
|
|
1420
|
-
sectionId:
|
|
1421
|
-
sections:
|
|
1422
|
-
sectionType:
|
|
1990
|
+
sectionId: import_zod24.z.uuid().default(() => (0, import_uuid4.v7)()),
|
|
1991
|
+
sections: import_zod24.z.union([import_zod24.z.array(CABButtonContent), import_zod24.z.strictObject({}).transform(() => [])]).default(() => []),
|
|
1992
|
+
sectionType: import_zod24.z.literal(SectionType.button).default(SectionType.button),
|
|
1423
1993
|
/**
|
|
1424
1994
|
* The smart-cart tier this button acts on (`addGift`/`removeGift`): scopes the click to one tier's gift. The
|
|
1425
1995
|
* client resolves the tier's gift (productId) from the progress-bar context by this `tierId` — the button node
|
|
@@ -1434,25 +2004,25 @@ var CABButtonSection = import_zod13.z.object({
|
|
|
1434
2004
|
* lookup finds no tier and the click resolves to nothing. Safe to bound — the field is new, so there are no
|
|
1435
2005
|
* stored payloads to grandfather, and the producer is client code, not a merchant form.
|
|
1436
2006
|
*/
|
|
1437
|
-
tier:
|
|
2007
|
+
tier: import_zod24.z.object({ tierId: import_zod24.z.string().min(1) }).optional(),
|
|
1438
2008
|
/** Fire-and-forget pixel POSTed when the button is clicked (e.g. a Monetize decline). */
|
|
1439
|
-
trackingUrl:
|
|
2009
|
+
trackingUrl: import_zod24.z.string().optional(),
|
|
1440
2010
|
/**
|
|
1441
2011
|
* Secondary effects applied to in-scope variables on click, alongside (never instead of) the primary
|
|
1442
2012
|
* `action` — an `addToOrder` button can also flip a variable. Applied in array order.
|
|
1443
2013
|
*/
|
|
1444
|
-
variableEffects:
|
|
2014
|
+
variableEffects: import_zod24.z.array(CABVariableEffect).optional()
|
|
1445
2015
|
});
|
|
1446
2016
|
|
|
1447
2017
|
// src/schema/widgets/checkout-and-beyond/carousel.ts
|
|
1448
|
-
var
|
|
2018
|
+
var import_zod29 = require("zod");
|
|
1449
2019
|
|
|
1450
2020
|
// src/schema/widgets/checkout-and-beyond/offers.ts
|
|
1451
|
-
var
|
|
2021
|
+
var import_zod28 = require("zod");
|
|
1452
2022
|
|
|
1453
2023
|
// src/schema/widgets/checkout-and-beyond/dataSource.ts
|
|
1454
|
-
var
|
|
1455
|
-
var
|
|
2024
|
+
var import_uuid5 = require("uuid");
|
|
2025
|
+
var import_zod25 = require("zod");
|
|
1456
2026
|
|
|
1457
2027
|
// src/schema/widgets/checkout-and-beyond/constants.ts
|
|
1458
2028
|
var import_es_toolkit3 = require("es-toolkit");
|
|
@@ -1506,77 +2076,77 @@ var targetAreas = {
|
|
|
1506
2076
|
};
|
|
1507
2077
|
|
|
1508
2078
|
// src/schema/widgets/checkout-and-beyond/dataSource.ts
|
|
1509
|
-
var CABDiscount =
|
|
1510
|
-
amount:
|
|
1511
|
-
discountedBy:
|
|
1512
|
-
discountedFrom:
|
|
1513
|
-
type:
|
|
1514
|
-
});
|
|
1515
|
-
var CABIntegrations =
|
|
1516
|
-
judgeme:
|
|
1517
|
-
junip:
|
|
1518
|
-
klaviyo:
|
|
1519
|
-
loox:
|
|
1520
|
-
okendo:
|
|
1521
|
-
opinew:
|
|
1522
|
-
reviewsio:
|
|
1523
|
-
stamped:
|
|
1524
|
-
yotpo:
|
|
1525
|
-
});
|
|
1526
|
-
var CABVariantLabels =
|
|
1527
|
-
variantOption:
|
|
1528
|
-
variantOptions:
|
|
1529
|
-
});
|
|
1530
|
-
var CABDataSourceSection =
|
|
1531
|
-
dataSourceId:
|
|
1532
|
-
dataSourcePath:
|
|
2079
|
+
var CABDiscount = import_zod25.z.object({
|
|
2080
|
+
amount: import_zod25.z.union([import_zod25.z.number(), import_zod25.z.string()]).catch(0),
|
|
2081
|
+
discountedBy: import_zod25.z.string().optional(),
|
|
2082
|
+
discountedFrom: import_zod25.z.enum(discountSources).optional().catch(void 0),
|
|
2083
|
+
type: import_zod25.z.enum(discountTypes).catch("none")
|
|
2084
|
+
});
|
|
2085
|
+
var CABIntegrations = import_zod25.z.object({
|
|
2086
|
+
judgeme: import_zod25.z.boolean().default(false),
|
|
2087
|
+
junip: import_zod25.z.boolean().default(false),
|
|
2088
|
+
klaviyo: import_zod25.z.boolean().default(false),
|
|
2089
|
+
loox: import_zod25.z.boolean().default(false),
|
|
2090
|
+
okendo: import_zod25.z.boolean().default(false),
|
|
2091
|
+
opinew: import_zod25.z.boolean().default(false),
|
|
2092
|
+
reviewsio: import_zod25.z.boolean().default(false),
|
|
2093
|
+
stamped: import_zod25.z.boolean().default(false),
|
|
2094
|
+
yotpo: import_zod25.z.boolean().default(false)
|
|
2095
|
+
});
|
|
2096
|
+
var CABVariantLabels = import_zod25.z.object({
|
|
2097
|
+
variantOption: import_zod25.z.string().optional().catch(void 0),
|
|
2098
|
+
variantOptions: import_zod25.z.string().optional().catch(void 0)
|
|
2099
|
+
});
|
|
2100
|
+
var CABDataSourceSection = import_zod25.z.object({
|
|
2101
|
+
dataSourceId: import_zod25.z.number().nullable().default(null),
|
|
2102
|
+
dataSourcePath: import_zod25.z.string().default(DEFAULT_ENDPOINTS[0].value),
|
|
1533
2103
|
discount: CABDiscount.optional(),
|
|
1534
2104
|
integrations: CABIntegrations.optional(),
|
|
1535
|
-
limit:
|
|
1536
|
-
matchVariant:
|
|
1537
|
-
matchVariantOutOfStock:
|
|
1538
|
-
name:
|
|
1539
|
-
productType:
|
|
1540
|
-
sectionId:
|
|
1541
|
-
sectionType:
|
|
2105
|
+
limit: import_zod25.z.number().default(1),
|
|
2106
|
+
matchVariant: import_zod25.z.boolean().default(false),
|
|
2107
|
+
matchVariantOutOfStock: import_zod25.z.boolean().default(false),
|
|
2108
|
+
name: import_zod25.z.string().default(DEFAULT_ENDPOINTS[0].label),
|
|
2109
|
+
productType: import_zod25.z.enum(productTypes).optional(),
|
|
2110
|
+
sectionId: import_zod25.z.uuid().default(() => (0, import_uuid5.v7)()),
|
|
2111
|
+
sectionType: import_zod25.z.literal(SectionType.dataSource).default(SectionType.dataSource),
|
|
1542
2112
|
/** Default subscribe-vs-one-time for `productType: both` (legacy `subscription_is_default`). */
|
|
1543
|
-
subscriptionIsDefault:
|
|
1544
|
-
treatAsGwp:
|
|
2113
|
+
subscriptionIsDefault: import_zod25.z.boolean().default(false),
|
|
2114
|
+
treatAsGwp: import_zod25.z.boolean().default(false),
|
|
1545
2115
|
variantLabels: CABVariantLabels.optional().catch(void 0)
|
|
1546
2116
|
});
|
|
1547
2117
|
|
|
1548
2118
|
// src/schema/widgets/checkout-and-beyond/products.ts
|
|
1549
|
-
var
|
|
1550
|
-
var
|
|
2119
|
+
var import_uuid7 = require("uuid");
|
|
2120
|
+
var import_zod27 = require("zod");
|
|
1551
2121
|
|
|
1552
2122
|
// src/schema/widgets/checkout-and-beyond/product.ts
|
|
1553
|
-
var
|
|
1554
|
-
var
|
|
1555
|
-
var CABVariantContent =
|
|
1556
|
-
() =>
|
|
2123
|
+
var import_uuid6 = require("uuid");
|
|
2124
|
+
var import_zod26 = require("zod");
|
|
2125
|
+
var CABVariantContent = import_zod26.z.lazy(
|
|
2126
|
+
() => import_zod26.z.discriminatedUnion("sectionType", [CABButtonSection, CABTextSection])
|
|
1557
2127
|
);
|
|
1558
|
-
var CABProductSection =
|
|
2128
|
+
var CABProductSection = import_zod26.z.object({
|
|
1559
2129
|
...CABVariableFields,
|
|
1560
|
-
name:
|
|
1561
|
-
productId:
|
|
1562
|
-
sectionId:
|
|
1563
|
-
sections:
|
|
1564
|
-
sectionType:
|
|
1565
|
-
selectors:
|
|
1566
|
-
variantMode:
|
|
2130
|
+
name: import_zod26.z.string().optional(),
|
|
2131
|
+
productId: import_zod26.z.number().nullable().default(null),
|
|
2132
|
+
sectionId: import_zod26.z.uuid().default(() => (0, import_uuid6.v7)()),
|
|
2133
|
+
sections: import_zod26.z.union([import_zod26.z.array(CABVariantContent), import_zod26.z.strictObject({}).transform(() => [])]).default(() => []),
|
|
2134
|
+
sectionType: import_zod26.z.literal(SectionType.product).default(SectionType.product),
|
|
2135
|
+
selectors: import_zod26.z.record(import_zod26.z.string(), import_zod26.z.enum(variantSelectors).default(VariantSelector.menu)).default(() => ({})),
|
|
2136
|
+
variantMode: import_zod26.z.enum(variantModes).default(VariantMode.multiple)
|
|
1567
2137
|
});
|
|
1568
2138
|
|
|
1569
2139
|
// src/schema/widgets/checkout-and-beyond/products.ts
|
|
1570
|
-
var CABProductsSection =
|
|
2140
|
+
var CABProductsSection = import_zod27.z.object({
|
|
1571
2141
|
...CABVariableFields,
|
|
1572
|
-
name:
|
|
1573
|
-
sectionId:
|
|
1574
|
-
sections:
|
|
1575
|
-
sectionType:
|
|
2142
|
+
name: import_zod27.z.string().optional(),
|
|
2143
|
+
sectionId: import_zod27.z.uuid().default(() => (0, import_uuid7.v7)()),
|
|
2144
|
+
sections: import_zod27.z.union([import_zod27.z.array(import_zod27.z.lazy(() => CABProductSection)), import_zod27.z.strictObject({}).transform(() => [])]).default(() => []),
|
|
2145
|
+
sectionType: import_zod27.z.literal(SectionType.products).default(SectionType.products)
|
|
1576
2146
|
});
|
|
1577
2147
|
|
|
1578
2148
|
// src/schema/widgets/checkout-and-beyond/offers.ts
|
|
1579
|
-
var CABOffersSection =
|
|
2149
|
+
var CABOffersSection = import_zod28.z.lazy(
|
|
1580
2150
|
() => CABLayoutSection.omit({ sections: true, sectionType: true }).extend({
|
|
1581
2151
|
/**
|
|
1582
2152
|
* A rule between consecutive cards in the vertical list — legacy checkout-offers' `<Divider />`,
|
|
@@ -1584,8 +2154,8 @@ var CABOffersSection = import_zod17.z.lazy(
|
|
|
1584
2154
|
* run of products). Optional, not defaulted: only the v1 converter sets it (REB-24265); a
|
|
1585
2155
|
* hand-built tree keeps React CAB's dividerless rendering.
|
|
1586
2156
|
*/
|
|
1587
|
-
divider:
|
|
1588
|
-
sections:
|
|
2157
|
+
divider: import_zod28.z.boolean().optional(),
|
|
2158
|
+
sections: import_zod28.z.union([import_zod28.z.array(import_zod28.z.lazy(() => CABSection)), import_zod28.z.strictObject({}).transform(() => [])]).default(() => [
|
|
1589
2159
|
CABBannerSection.parse({
|
|
1590
2160
|
buttonField: "undoAddToOrder",
|
|
1591
2161
|
color: "success",
|
|
@@ -1599,77 +2169,77 @@ var CABOffersSection = import_zod17.z.lazy(
|
|
|
1599
2169
|
CABDataSourceSection.parse({}),
|
|
1600
2170
|
CABProductsSection.parse({})
|
|
1601
2171
|
]),
|
|
1602
|
-
sectionType:
|
|
2172
|
+
sectionType: import_zod28.z.literal(SectionType.offers).default(SectionType.offers)
|
|
1603
2173
|
})
|
|
1604
2174
|
);
|
|
1605
2175
|
|
|
1606
2176
|
// src/schema/widgets/checkout-and-beyond/carousel.ts
|
|
1607
|
-
var CABCarouselSection =
|
|
2177
|
+
var CABCarouselSection = import_zod29.z.lazy(
|
|
1608
2178
|
() => CABLayoutSection.omit({ sections: true, sectionType: true }).extend({
|
|
1609
|
-
autoAdvanceInterval:
|
|
1610
|
-
itemsAtOnce:
|
|
2179
|
+
autoAdvanceInterval: import_zod29.z.number().default(0),
|
|
2180
|
+
itemsAtOnce: import_zod29.z.number().min(1).default(1),
|
|
1611
2181
|
/** Card arrangement for the offers child (`horizontal` = side-by-side) — NOT the carousel's own `direction`. */
|
|
1612
|
-
offersDirection:
|
|
1613
|
-
sections:
|
|
1614
|
-
sectionType:
|
|
2182
|
+
offersDirection: import_zod29.z.enum(offersDirections).default("vertical"),
|
|
2183
|
+
sections: import_zod29.z.union([import_zod29.z.array(import_zod29.z.lazy(() => CABSection)), import_zod29.z.strictObject({}).transform(() => [])]).default(() => [CABOffersSection.parse({})]),
|
|
2184
|
+
sectionType: import_zod29.z.literal(SectionType.carousel).default(SectionType.carousel)
|
|
1615
2185
|
})
|
|
1616
2186
|
);
|
|
1617
2187
|
|
|
1618
2188
|
// src/schema/widgets/checkout-and-beyond/cartLine.ts
|
|
1619
|
-
var
|
|
1620
|
-
var CABCartLineSection =
|
|
2189
|
+
var import_zod30 = require("zod");
|
|
2190
|
+
var CABCartLineSection = import_zod30.z.lazy(
|
|
1621
2191
|
() => CABLayoutSection.omit({ sections: true, sectionType: true }).extend({
|
|
1622
|
-
sections:
|
|
1623
|
-
sectionType:
|
|
2192
|
+
sections: import_zod30.z.union([import_zod30.z.array(import_zod30.z.lazy(() => CABSection)), import_zod30.z.strictObject({}).transform(() => [])]).default(() => [CABButtonSection.parse({ action: ButtonAction.switchToSubscription })]),
|
|
2193
|
+
sectionType: import_zod30.z.literal(SectionType.cartLine).default(SectionType.cartLine)
|
|
1624
2194
|
})
|
|
1625
2195
|
);
|
|
1626
2196
|
|
|
1627
2197
|
// src/schema/widgets/checkout-and-beyond/discount.ts
|
|
1628
|
-
var
|
|
1629
|
-
var
|
|
1630
|
-
var CABDiscountSection =
|
|
2198
|
+
var import_uuid8 = require("uuid");
|
|
2199
|
+
var import_zod31 = require("zod");
|
|
2200
|
+
var CABDiscountSection = import_zod31.z.object({
|
|
1631
2201
|
...CABVariableFields,
|
|
1632
|
-
amount:
|
|
1633
|
-
discountedBy:
|
|
1634
|
-
discountedFrom:
|
|
1635
|
-
message:
|
|
1636
|
-
name:
|
|
1637
|
-
quantity:
|
|
1638
|
-
sectionId:
|
|
1639
|
-
sectionType:
|
|
1640
|
-
type:
|
|
2202
|
+
amount: import_zod31.z.union([import_zod31.z.number(), import_zod31.z.string()]).catch(0),
|
|
2203
|
+
discountedBy: import_zod31.z.string().optional(),
|
|
2204
|
+
discountedFrom: import_zod31.z.enum(discountSources).optional().catch(void 0),
|
|
2205
|
+
message: import_zod31.z.string().optional(),
|
|
2206
|
+
name: import_zod31.z.string().optional(),
|
|
2207
|
+
quantity: import_zod31.z.number().default(1),
|
|
2208
|
+
sectionId: import_zod31.z.uuid().default(() => (0, import_uuid8.v7)()),
|
|
2209
|
+
sectionType: import_zod31.z.literal(SectionType.discount).default(SectionType.discount),
|
|
2210
|
+
type: import_zod31.z.enum(discountTypes).catch("none")
|
|
1641
2211
|
});
|
|
1642
2212
|
|
|
1643
2213
|
// src/schema/widgets/checkout-and-beyond/monetize.ts
|
|
1644
|
-
var
|
|
1645
|
-
var
|
|
1646
|
-
var CABMonetizeAds =
|
|
1647
|
-
requestId:
|
|
2214
|
+
var import_uuid9 = require("uuid");
|
|
2215
|
+
var import_zod32 = require("zod");
|
|
2216
|
+
var CABMonetizeAds = import_zod32.z.object({
|
|
2217
|
+
requestId: import_zod32.z.string().optional(),
|
|
1648
2218
|
/** Defaulted here, never in the beacon: absence of information is `ads` itself being absent. */
|
|
1649
|
-
testing:
|
|
2219
|
+
testing: import_zod32.z.boolean().default(false)
|
|
1650
2220
|
});
|
|
1651
|
-
var CABMonetizeSection =
|
|
2221
|
+
var CABMonetizeSection = import_zod32.z.object({
|
|
1652
2222
|
...CABVariableFields,
|
|
1653
2223
|
ads: CABMonetizeAds.optional(),
|
|
1654
|
-
name:
|
|
2224
|
+
name: import_zod32.z.string().optional(),
|
|
1655
2225
|
/**
|
|
1656
2226
|
* Server-hydrated offer cards (inline hydration): when `/cab/sections` was asked with a `monetize`
|
|
1657
2227
|
* context block, the composed cards ride the marker itself — `[]` means "hydrated, no fill" (render
|
|
1658
2228
|
* nothing, skip the fetch); ABSENT means "not hydrated" (the client fetches via `/cab/monetize`).
|
|
1659
2229
|
*/
|
|
1660
|
-
offers:
|
|
2230
|
+
offers: import_zod32.z.array(import_zod32.z.lazy(() => CABSection)).optional(),
|
|
1661
2231
|
/** Privacy Policy footer href (the widget's `privacy_policy_url` setting); read server-side for hydration, relayed by the client only on the legacy `/cab/monetize` fallback. */
|
|
1662
|
-
privacyPolicyUrl:
|
|
1663
|
-
sectionId:
|
|
1664
|
-
sectionType:
|
|
2232
|
+
privacyPolicyUrl: import_zod32.z.string().optional(),
|
|
2233
|
+
sectionId: import_zod32.z.uuid().default(() => (0, import_uuid9.v7)()),
|
|
2234
|
+
sectionType: import_zod32.z.literal(SectionType.monetize).default(SectionType.monetize),
|
|
1665
2235
|
/** Ads-taxonomy sub-vertical id (the widget's `sub_vertical` setting); paired with `vertical`. */
|
|
1666
|
-
subVertical:
|
|
2236
|
+
subVertical: import_zod32.z.string().optional(),
|
|
1667
2237
|
/** Ads-taxonomy vertical id (the widget's `vertical` setting) — with `subVertical`, the admin Monetize editor's two configurables. */
|
|
1668
|
-
vertical:
|
|
2238
|
+
vertical: import_zod32.z.string().optional()
|
|
1669
2239
|
});
|
|
1670
2240
|
|
|
1671
2241
|
// src/schema/widgets/checkout-and-beyond/progressBar.ts
|
|
1672
|
-
var
|
|
2242
|
+
var import_zod33 = require("zod");
|
|
1673
2243
|
|
|
1674
2244
|
// src/schema/widgets/checkout-and-beyond/giftLabels.ts
|
|
1675
2245
|
var GIFT_LABELS = {
|
|
@@ -1788,34 +2358,34 @@ var GIFT_LABELS = {
|
|
|
1788
2358
|
};
|
|
1789
2359
|
|
|
1790
2360
|
// src/schema/widgets/checkout-and-beyond/progressBar.ts
|
|
1791
|
-
var CABProgressTierExclusion =
|
|
1792
|
-
collectionIds:
|
|
1793
|
-
productIds:
|
|
1794
|
-
tags:
|
|
1795
|
-
type:
|
|
2361
|
+
var CABProgressTierExclusion = import_zod33.z.object({
|
|
2362
|
+
collectionIds: import_zod33.z.array(import_zod33.z.number().int().positive()).default(() => []),
|
|
2363
|
+
productIds: import_zod33.z.array(import_zod33.z.number().int().positive()).default(() => []),
|
|
2364
|
+
tags: import_zod33.z.array(import_zod33.z.string().min(1)).default(() => []),
|
|
2365
|
+
type: import_zod33.z.enum(progressTierExclusionTypes)
|
|
1796
2366
|
});
|
|
1797
|
-
var CABProgressTier =
|
|
2367
|
+
var CABProgressTier = import_zod33.z.object({
|
|
1798
2368
|
/**
|
|
1799
2369
|
* Order-discount tiers only (onsite `discount`): the reward the order-discount Function applies at
|
|
1800
2370
|
* cart time, carried so the client can resolve the `{{discountAmount}}` token in this tier's copy.
|
|
1801
2371
|
* `fixedAmount`: shop-currency CENTS (FX-scaled by the client, like {@link CABProgressTier.threshold});
|
|
1802
2372
|
* `percentage`: the whole-percent number rendered raw (`{n}%`). Absent on non-discount tiers.
|
|
1803
2373
|
*/
|
|
1804
|
-
discount:
|
|
2374
|
+
discount: import_zod33.z.object({ amount: import_zod33.z.number().nonnegative(), type: import_zod33.z.enum(["fixedAmount", "percentage"]) }).optional(),
|
|
1805
2375
|
/**
|
|
1806
2376
|
* Per-tier exclusion rules (onsite `exclusions` when `exclusions_enabled`): lines they match don't count
|
|
1807
2377
|
* toward this tier. Empty (the default, and the converter's output for a disabled or ruleless tier) means
|
|
1808
2378
|
* the tier measures the plain bar-level adjusted progress. Consumers read ONLY the list named by the rule's
|
|
1809
2379
|
* `type` — the converter leaves the other two at `[]`, so a populated off-type list never reaches the tree.
|
|
1810
2380
|
*/
|
|
1811
|
-
exclusions:
|
|
2381
|
+
exclusions: import_zod33.z.array(CABProgressTierExclusion).default(() => []),
|
|
1812
2382
|
/**
|
|
1813
2383
|
* Smart-cart product (gift) tiers only (onsite `filter_oos_variants`): when set, the client drops this
|
|
1814
2384
|
* tier entirely once its gift has NO in-stock eligible variant — the milestone, fill slot and gift
|
|
1815
2385
|
* controls all disappear, mirroring onsite removing the tier from `bar.tiers` before it renders. Absent
|
|
1816
2386
|
* on shipping/discount/decorative tiers and left off by default (the tier renders regardless of stock).
|
|
1817
2387
|
*/
|
|
1818
|
-
filterOosVariants:
|
|
2388
|
+
filterOosVariants: import_zod33.z.boolean().default(false),
|
|
1819
2389
|
/**
|
|
1820
2390
|
* Smart-cart product (gift) tiers only: the reward unlocked at this tier. The client enriches
|
|
1821
2391
|
* `productId`/`variantIds` to live variants (availability, price) and adds the chosen one to the cart
|
|
@@ -1823,10 +2393,10 @@ var CABProgressTier = import_zod22.z.object({
|
|
|
1823
2393
|
* tiers and on tiers with no configured product. Cart add/remove is a later stage; carried here so the
|
|
1824
2394
|
* tree is complete.
|
|
1825
2395
|
*/
|
|
1826
|
-
gift:
|
|
1827
|
-
productId:
|
|
1828
|
-
title:
|
|
1829
|
-
variantIds:
|
|
2396
|
+
gift: import_zod33.z.object({
|
|
2397
|
+
productId: import_zod33.z.number().int().positive(),
|
|
2398
|
+
title: import_zod33.z.string().optional(),
|
|
2399
|
+
variantIds: import_zod33.z.array(import_zod33.z.number().int().positive()).default(() => [])
|
|
1830
2400
|
}).optional(),
|
|
1831
2401
|
/**
|
|
1832
2402
|
* The step-row icon's square size in PIXELS (onsite `product_tier_element_size`, an admin px string the
|
|
@@ -1846,7 +2416,7 @@ var CABProgressTier = import_zod22.z.object({
|
|
|
1846
2416
|
* renderer never spells a fallback), which also makes a tree authored before this field render at
|
|
1847
2417
|
* React's size rather than the old hardcoded 20.
|
|
1848
2418
|
*/
|
|
1849
|
-
iconSizePx:
|
|
2419
|
+
iconSizePx: import_zod33.z.number().int().min(1).max(64).default(18),
|
|
1850
2420
|
/**
|
|
1851
2421
|
* The step-row label at this tier's slot (onsite `getTierLabel`): the merchant custom label, else the
|
|
1852
2422
|
* type default — 'Free Shipping' or '{n}% Discount'. A PRODUCT tier gets NO converter label: its name is
|
|
@@ -1856,35 +2426,35 @@ var CABProgressTier = import_zod22.z.object({
|
|
|
1856
2426
|
* turns a blank label into an absent key, and a client-authored blank means the same thing — the renderer
|
|
1857
2427
|
* emits no caption slot rather than an empty one). Plain text — a compact icon+label.
|
|
1858
2428
|
*/
|
|
1859
|
-
label:
|
|
2429
|
+
label: import_zod33.z.record(import_zod33.z.string(), import_zod33.z.string()).optional(),
|
|
1860
2430
|
/**
|
|
1861
2431
|
* Smart-cart product (gift) tiers only (onsite `product_tier_image`): show the gift's product image in
|
|
1862
2432
|
* the step-row slot instead of the generic bag icon. The converter can't supply the image URL (config
|
|
1863
2433
|
* carries only product IDs), so the client resolves it (authoritative Shopify featured image, React
|
|
1864
2434
|
* parity) and falls back to the bag icon when the flag is off or no image resolves. Default false.
|
|
1865
2435
|
*/
|
|
1866
|
-
productTierImage:
|
|
2436
|
+
productTierImage: import_zod33.z.boolean().default(false),
|
|
1867
2437
|
/**
|
|
1868
2438
|
* The tier's goal, measured per `unit`. `currency` (default): SHOP-currency cents — the canonical
|
|
1869
2439
|
* fallback: when the buyer's presentment currency has no entry in `thresholds`, the client
|
|
1870
2440
|
* multiplies this by the live FX rate (converter maps the v1 `unlock_price`, e.g. `75` → `7500`).
|
|
1871
2441
|
* `item`: a raw item count — no cents, no FX, no `thresholds` overrides.
|
|
1872
2442
|
*/
|
|
1873
|
-
threshold:
|
|
2443
|
+
threshold: import_zod33.z.number().int().nonnegative(),
|
|
1874
2444
|
/**
|
|
1875
2445
|
* Per-presentment-currency goal overrides — lowercased ISO currency code → cents (e.g. `{ cad: 9900 }`).
|
|
1876
2446
|
* When the buyer's currency has an entry, the client uses it verbatim INSTEAD of FX-converting
|
|
1877
2447
|
* `threshold`, so merchants show intentional, clean per-market amounts (Shopify Markets) rather than a
|
|
1878
2448
|
* converted base. Defaults to `{}` — no overrides means always fall back to `threshold`.
|
|
1879
2449
|
*/
|
|
1880
|
-
thresholds:
|
|
2450
|
+
thresholds: import_zod33.z.record(import_zod33.z.string(), import_zod33.z.number().int().nonnegative()).default(() => ({})),
|
|
1881
2451
|
/**
|
|
1882
2452
|
* Smart-cart tier identifier, mirrored onto the gift cart line's `_tier` attribute so the client can
|
|
1883
2453
|
* match an in-cart gift back to its tier (add on reach, remove on downgrade/decline). Absent on the
|
|
1884
2454
|
* shipping bar (single unlabeled tier, no gift).
|
|
1885
2455
|
*/
|
|
1886
|
-
tierId:
|
|
1887
|
-
tierType:
|
|
2456
|
+
tierId: import_zod33.z.string().optional(),
|
|
2457
|
+
tierType: import_zod33.z.enum(progressTierTypes).default(ProgressTierType.shipping),
|
|
1888
2458
|
/**
|
|
1889
2459
|
* What this tier's progress is measured in — PER TIER (onsite's `unlock_condition_type` model, NOT
|
|
1890
2460
|
* the React port's bar-level `tiers[0]` shortcut). `currency` compares money cents against the
|
|
@@ -1895,9 +2465,9 @@ var CABProgressTier = import_zod22.z.object({
|
|
|
1895
2465
|
* count carries no injected noun (no English `item`/`items` inflection on localized copy); merchant
|
|
1896
2466
|
* template text supplies grammatically-neutral wording around the token.
|
|
1897
2467
|
*/
|
|
1898
|
-
unit:
|
|
2468
|
+
unit: import_zod33.z.enum(progressTierUnits).default(ProgressTierUnit.currency)
|
|
1899
2469
|
});
|
|
1900
|
-
var CABProgressBarSection =
|
|
2470
|
+
var CABProgressBarSection = import_zod33.z.lazy(
|
|
1901
2471
|
() => CABLayoutSection.omit({ sectionType: true }).extend({
|
|
1902
2472
|
/**
|
|
1903
2473
|
* The onsite bar id (smart-cart TPB bars only). The client mirrors it to the cart's `_barId` attribute
|
|
@@ -1906,35 +2476,35 @@ var CABProgressBarSection = import_zod22.z.lazy(
|
|
|
1906
2476
|
* checkout reaches the extension without it, so the client writes it or the tier gift's 100% discount
|
|
1907
2477
|
* (and any tier order discount) never applies. Absent on the v1 shipping bar (no gift tiers, no id).
|
|
1908
2478
|
*/
|
|
1909
|
-
barId:
|
|
2479
|
+
barId: import_zod33.z.string().optional(),
|
|
1910
2480
|
/** Empty = shown everywhere; otherwise uppercase ISO country codes. */
|
|
1911
|
-
countryCodes:
|
|
2481
|
+
countryCodes: import_zod33.z.array(import_zod33.z.string().transform((code) => code.trim().toUpperCase())).default(() => []),
|
|
1912
2482
|
/**
|
|
1913
2483
|
* Uppercase ISO codes where a higher-precedence geo bar applies, so this (default, non-geo) bar is
|
|
1914
2484
|
* hidden there — replicates React `getbar`'s geo-match-over-default precedence. Empty = never excluded.
|
|
1915
2485
|
*/
|
|
1916
|
-
excludeCountryCodes:
|
|
2486
|
+
excludeCountryCodes: import_zod33.z.array(import_zod33.z.string().transform((code) => code.trim().toUpperCase())).default(() => []),
|
|
1917
2487
|
/**
|
|
1918
2488
|
* Measure progress against the PRE-discount subtotal (onsite `exclude_discount_in_subtotal`, and
|
|
1919
2489
|
* forced on for bars with a discount tier so its own reward can't un-reach the tier). The client
|
|
1920
2490
|
* adds the cart's discount allocations back to the live subtotal.
|
|
1921
2491
|
*/
|
|
1922
|
-
excludeDiscountInSubtotal:
|
|
2492
|
+
excludeDiscountInSubtotal: import_zod33.z.boolean().default(false),
|
|
1923
2493
|
/** Variant ids the client subtracts from the adjusted subtotal (React `bar.excluded_products`). */
|
|
1924
|
-
excludedVariantIds:
|
|
2494
|
+
excludedVariantIds: import_zod33.z.array(import_zod33.z.number().int().positive()).default(() => []),
|
|
1925
2495
|
/**
|
|
1926
2496
|
* When the cart holds a subscription item, treat the bar as reached regardless of subtotal (React
|
|
1927
2497
|
* `free_shipping_on_subscription(s)`). `freeShippingOnAll` is already a zero-threshold tier instead.
|
|
1928
2498
|
*/
|
|
1929
|
-
freeShippingOnSubscription:
|
|
2499
|
+
freeShippingOnSubscription: import_zod33.z.boolean().default(false),
|
|
1930
2500
|
/** Localized heading over the gift controls (onsite `gift_area_title`, default 'FREE GIFTS'). */
|
|
1931
|
-
giftAreaTitle:
|
|
2501
|
+
giftAreaTitle: import_zod33.z.record(import_zod33.z.string(), import_zod33.z.string()).default(() => ({ en: "FREE GIFTS" })),
|
|
1932
2502
|
/** Localized gift-control labels (add/remove/heading); a tier's gift `title` beats `yourGift`. */
|
|
1933
|
-
giftLabels:
|
|
1934
|
-
addGift:
|
|
1935
|
-
remove:
|
|
1936
|
-
selectOptions:
|
|
1937
|
-
yourGift:
|
|
2503
|
+
giftLabels: import_zod33.z.object({
|
|
2504
|
+
addGift: import_zod33.z.record(import_zod33.z.string(), import_zod33.z.string()).default(() => ({ ...GIFT_LABELS.addGift })),
|
|
2505
|
+
remove: import_zod33.z.record(import_zod33.z.string(), import_zod33.z.string()).default(() => ({ ...GIFT_LABELS.remove })),
|
|
2506
|
+
selectOptions: import_zod33.z.record(import_zod33.z.string(), import_zod33.z.string()).default(() => ({ ...GIFT_LABELS.selectOptions })),
|
|
2507
|
+
yourGift: import_zod33.z.record(import_zod33.z.string(), import_zod33.z.string()).default(() => ({ ...GIFT_LABELS.yourGift }))
|
|
1938
2508
|
}).default(() => ({
|
|
1939
2509
|
addGift: { ...GIFT_LABELS.addGift },
|
|
1940
2510
|
remove: { ...GIFT_LABELS.remove },
|
|
@@ -1942,38 +2512,38 @@ var CABProgressBarSection = import_zod22.z.lazy(
|
|
|
1942
2512
|
yourGift: { ...GIFT_LABELS.yourGift }
|
|
1943
2513
|
})),
|
|
1944
2514
|
/** The bar's a11y label; the merchant names it in the editor, else this default (React parity). */
|
|
1945
|
-
name:
|
|
2515
|
+
name: import_zod33.z.string().default("Order progress"),
|
|
1946
2516
|
/**
|
|
1947
2517
|
* Bar fill color. An explicit (widget-authored) value is used verbatim; when absent the server
|
|
1948
2518
|
* fills it with the live shop theme's `buttonBackground` (React `useRebuyTheme` parity). Still
|
|
1949
2519
|
* absent after that ⇒ the theme fetch failed and the client renders its platform-default bar —
|
|
1950
2520
|
* optional, not defaulted, so "merchant chose no color" stays distinguishable from any real value.
|
|
1951
2521
|
*/
|
|
1952
|
-
progressColor:
|
|
1953
|
-
sectionType:
|
|
2522
|
+
progressColor: import_zod33.z.string().optional(),
|
|
2523
|
+
sectionType: import_zod33.z.literal(SectionType.progressBar).default(SectionType.progressBar),
|
|
1954
2524
|
/**
|
|
1955
2525
|
* The bar's milestones in the merchant's CONFIGURED order — the renderer does NOT sort them (022
|
|
1956
2526
|
* O-B2: sorting by resolved threshold reversed configured milestones on out-of-order or mixed-unit
|
|
1957
2527
|
* count-vs-cents bars). Drives the fill (even slot per tier) and, for smart-cart product tiers, the
|
|
1958
2528
|
* gift add/remove. The visual tier display lives in `sections` (composable), NOT here.
|
|
1959
2529
|
*/
|
|
1960
|
-
tiers:
|
|
2530
|
+
tiers: import_zod33.z.union([import_zod33.z.array(CABProgressTier), import_zod33.z.strictObject({}).transform(() => [])]).default(() => [])
|
|
1961
2531
|
})
|
|
1962
2532
|
);
|
|
1963
2533
|
|
|
1964
2534
|
// src/schema/widgets/checkout-and-beyond/quantity.ts
|
|
1965
|
-
var
|
|
1966
|
-
var
|
|
1967
|
-
var CABQuantitySection =
|
|
2535
|
+
var import_uuid10 = require("uuid");
|
|
2536
|
+
var import_zod34 = require("zod");
|
|
2537
|
+
var CABQuantitySection = import_zod34.z.object({
|
|
1968
2538
|
...CABVariableFields,
|
|
1969
|
-
errorMessages:
|
|
1970
|
-
|
|
1971
|
-
|
|
2539
|
+
errorMessages: import_zod34.z.record(
|
|
2540
|
+
import_zod34.z.string(),
|
|
2541
|
+
import_zod34.z.object({
|
|
1972
2542
|
/** `{{step}}` is interpolated at render — the off-increment message React never gave a merchant key. */
|
|
1973
|
-
increment:
|
|
1974
|
-
max:
|
|
1975
|
-
min:
|
|
1976
|
-
neg:
|
|
2543
|
+
increment: import_zod34.z.string().optional(),
|
|
2544
|
+
max: import_zod34.z.string().optional(),
|
|
2545
|
+
min: import_zod34.z.string().optional(),
|
|
2546
|
+
neg: import_zod34.z.string().optional()
|
|
1977
2547
|
})
|
|
1978
2548
|
).default({
|
|
1979
2549
|
en: {
|
|
@@ -1983,18 +2553,18 @@ var CABQuantitySection = import_zod23.z.object({
|
|
|
1983
2553
|
neg: "Quantity cannot be negative"
|
|
1984
2554
|
}
|
|
1985
2555
|
}),
|
|
1986
|
-
inputType:
|
|
1987
|
-
max:
|
|
1988
|
-
min:
|
|
2556
|
+
inputType: import_zod34.z.enum(quantityInputs).default(QuantityInput.select),
|
|
2557
|
+
max: import_zod34.z.number().min(1).max(100).default(10),
|
|
2558
|
+
min: import_zod34.z.number().min(1).default(1),
|
|
1989
2559
|
/** The a11y label for the quantity control; the merchant names it in the editor, else this default. */
|
|
1990
|
-
name:
|
|
1991
|
-
sectionId:
|
|
1992
|
-
sectionType:
|
|
2560
|
+
name: import_zod34.z.string().default("Quantity"),
|
|
2561
|
+
sectionId: import_zod34.z.uuid().default(() => (0, import_uuid10.v7)()),
|
|
2562
|
+
sectionType: import_zod34.z.literal(SectionType.quantity).default(SectionType.quantity)
|
|
1993
2563
|
});
|
|
1994
2564
|
|
|
1995
2565
|
// src/schema/widgets/checkout-and-beyond/reviews.ts
|
|
1996
|
-
var
|
|
1997
|
-
var
|
|
2566
|
+
var import_uuid11 = require("uuid");
|
|
2567
|
+
var import_zod35 = require("zod");
|
|
1998
2568
|
|
|
1999
2569
|
// src/schema/widgets/checkout-and-beyond/reviewLabels.ts
|
|
2000
2570
|
var REVIEW_LABELS = {
|
|
@@ -2057,49 +2627,49 @@ var REVIEW_LABELS = {
|
|
|
2057
2627
|
};
|
|
2058
2628
|
|
|
2059
2629
|
// src/schema/widgets/checkout-and-beyond/reviews.ts
|
|
2060
|
-
var CABReviewsSection =
|
|
2630
|
+
var CABReviewsSection = import_zod35.z.object({
|
|
2061
2631
|
...CABVariableFields,
|
|
2062
|
-
color:
|
|
2632
|
+
color: import_zod35.z.string().default("#fadb14"),
|
|
2063
2633
|
/**
|
|
2064
2634
|
* Localized review-count templates (`{{reviewCount}}`), one/other plural forms; the client picks the
|
|
2065
2635
|
* form via `Intl.PluralRules`. Defaults here (schema-first) so every tree localizes without converter
|
|
2066
2636
|
* or merchant work.
|
|
2067
2637
|
*/
|
|
2068
|
-
countLabels:
|
|
2069
|
-
one:
|
|
2070
|
-
other:
|
|
2638
|
+
countLabels: import_zod35.z.object({
|
|
2639
|
+
one: import_zod35.z.record(import_zod35.z.string(), import_zod35.z.string()).default(() => ({ ...REVIEW_LABELS.one })),
|
|
2640
|
+
other: import_zod35.z.record(import_zod35.z.string(), import_zod35.z.string()).default(() => ({ ...REVIEW_LABELS.other }))
|
|
2071
2641
|
}).default(() => ({ one: { ...REVIEW_LABELS.one }, other: { ...REVIEW_LABELS.other } })),
|
|
2072
|
-
name:
|
|
2073
|
-
sectionId:
|
|
2074
|
-
sectionType:
|
|
2075
|
-
size:
|
|
2642
|
+
name: import_zod35.z.string().optional(),
|
|
2643
|
+
sectionId: import_zod35.z.uuid().default(() => (0, import_uuid11.v7)()),
|
|
2644
|
+
sectionType: import_zod35.z.literal(SectionType.reviews).default(SectionType.reviews),
|
|
2645
|
+
size: import_zod35.z.enum(reviewsSizes).default(ReviewsSize.default),
|
|
2076
2646
|
/**
|
|
2077
2647
|
* Star outline color, interpolated into a style by the renderer, so it is hex-constrained like
|
|
2078
2648
|
* `CABButtonSection.color`. The legacy source (`PostPurchaseSettings.styles.starStrokeColor`) is a free
|
|
2079
2649
|
* string: its converter must validate and fall back to this default rather than let one odd value drop
|
|
2080
2650
|
* the whole reviews section.
|
|
2081
2651
|
*/
|
|
2082
|
-
strokeColor:
|
|
2652
|
+
strokeColor: import_zod35.z.string().regex(HEX_COLOR_REGEX).default("#fadb14"),
|
|
2083
2653
|
/** Star outline width in px; `0` draws no outline. The legacy `styles.strokeWidth` is a STRING ('1') — its converter coerces. */
|
|
2084
|
-
strokeWidth:
|
|
2654
|
+
strokeWidth: import_zod35.z.number().nonnegative().default(0)
|
|
2085
2655
|
});
|
|
2086
2656
|
|
|
2087
2657
|
// src/schema/widgets/checkout-and-beyond/separator.ts
|
|
2088
|
-
var
|
|
2089
|
-
var
|
|
2090
|
-
var CABSeparatorSection =
|
|
2658
|
+
var import_uuid12 = require("uuid");
|
|
2659
|
+
var import_zod36 = require("zod");
|
|
2660
|
+
var CABSeparatorSection = import_zod36.z.object({
|
|
2091
2661
|
...CABVariableFields,
|
|
2092
|
-
sectionId:
|
|
2093
|
-
sectionType:
|
|
2662
|
+
sectionId: import_zod36.z.uuid().default(() => (0, import_uuid12.v7)()),
|
|
2663
|
+
sectionType: import_zod36.z.literal(SectionType.separator).default(SectionType.separator)
|
|
2094
2664
|
});
|
|
2095
2665
|
|
|
2096
2666
|
// src/schema/widgets/checkout-and-beyond/variants.ts
|
|
2097
|
-
var
|
|
2098
|
-
var
|
|
2099
|
-
var
|
|
2100
|
-
var CABVariantsSection =
|
|
2667
|
+
var import_compat5 = require("es-toolkit/compat");
|
|
2668
|
+
var import_uuid13 = require("uuid");
|
|
2669
|
+
var import_zod37 = require("zod");
|
|
2670
|
+
var CABVariantsSection = import_zod37.z.object({
|
|
2101
2671
|
...CABVariableFields,
|
|
2102
|
-
hideOutOfStockVariants:
|
|
2672
|
+
hideOutOfStockVariants: import_zod37.z.boolean().default(false),
|
|
2103
2673
|
/**
|
|
2104
2674
|
* The menu's own label per buyer locale (`selectLanguage`), for the whole-variant (`single`) and the
|
|
2105
2675
|
* product-group menus; `multiple` labels each option's menu by its name. Optional and additive
|
|
@@ -2110,30 +2680,30 @@ var CABVariantsSection = import_zod26.z.object({
|
|
|
2110
2680
|
* `selectLanguage` returning `''` — which a renderer's `??` fallback would show as an empty menu label.
|
|
2111
2681
|
* A label left with no entries reads as absent.
|
|
2112
2682
|
*/
|
|
2113
|
-
label:
|
|
2114
|
-
const filled = (0,
|
|
2115
|
-
return (0,
|
|
2683
|
+
label: import_zod37.z.record(import_zod37.z.string(), import_zod37.z.string()).transform((label2) => {
|
|
2684
|
+
const filled = (0, import_compat5.pickBy)(label2, (value) => value.trim() !== "");
|
|
2685
|
+
return (0, import_compat5.isEmpty)(filled) ? void 0 : filled;
|
|
2116
2686
|
}).optional().catch(void 0),
|
|
2117
|
-
name:
|
|
2118
|
-
sectionId:
|
|
2119
|
-
sectionType:
|
|
2120
|
-
selector:
|
|
2687
|
+
name: import_zod37.z.string().optional(),
|
|
2688
|
+
sectionId: import_zod37.z.uuid().default(() => (0, import_uuid13.v7)()),
|
|
2689
|
+
sectionType: import_zod37.z.literal(SectionType.variants).default(SectionType.variants),
|
|
2690
|
+
selector: import_zod37.z.enum((0, import_compat5.slice)(variantSelectors, 0, 3)).default(VariantSelector.menu),
|
|
2121
2691
|
/** `productGroup` is additive (REB-24817): a renderer without group support must render nothing for it. */
|
|
2122
|
-
variantMode:
|
|
2692
|
+
variantMode: import_zod37.z.enum(variantsModes).default(VariantsMode.multiple)
|
|
2123
2693
|
});
|
|
2124
2694
|
|
|
2125
2695
|
// src/schema/widgets/checkout-and-beyond/shared.ts
|
|
2126
|
-
var CABBorder =
|
|
2127
|
-
radius:
|
|
2128
|
-
style:
|
|
2129
|
-
width:
|
|
2696
|
+
var CABBorder = import_zod38.z.object({
|
|
2697
|
+
radius: import_zod38.z.enum(borderRadii).default(BorderRadius.base),
|
|
2698
|
+
style: import_zod38.z.enum(borderStyles).default(BorderStyle.none),
|
|
2699
|
+
width: import_zod38.z.enum(borderWidths).default(BorderWidth.base)
|
|
2130
2700
|
}).default({
|
|
2131
2701
|
radius: BorderRadius.base,
|
|
2132
2702
|
style: BorderStyle.none,
|
|
2133
2703
|
width: BorderWidth.base
|
|
2134
2704
|
});
|
|
2135
|
-
var CABSection =
|
|
2136
|
-
() =>
|
|
2705
|
+
var CABSection = import_zod38.z.lazy(
|
|
2706
|
+
() => import_zod38.z.discriminatedUnion("sectionType", [
|
|
2137
2707
|
CABBannerSection,
|
|
2138
2708
|
CABButtonSection,
|
|
2139
2709
|
CABCarouselSection,
|
|
@@ -2156,17 +2726,17 @@ var CABSection = import_zod27.z.lazy(
|
|
|
2156
2726
|
);
|
|
2157
2727
|
|
|
2158
2728
|
// src/schema/widgets/checkout-and-beyond/image.ts
|
|
2159
|
-
var CABImageSectionFields =
|
|
2729
|
+
var CABImageSectionFields = import_zod39.z.object({
|
|
2160
2730
|
...CABVariableFields,
|
|
2161
|
-
altText:
|
|
2731
|
+
altText: import_zod39.z.string().refine(checkForHTML, NO_HTML).default(""),
|
|
2162
2732
|
/**
|
|
2163
2733
|
* Image width÷height (e.g. `46` for the progress-bar fill); `null` renders at natural size. Any POSITIVE
|
|
2164
2734
|
* ratio — never limited to 1, but never `0`/negative either: a renderer dividing by it would get `Infinity`,
|
|
2165
2735
|
* and CSS `aspect-ratio` drops a negative value and silently reverts to natural size.
|
|
2166
2736
|
*/
|
|
2167
|
-
aspectRatio:
|
|
2168
|
-
border:
|
|
2169
|
-
buttonField:
|
|
2737
|
+
aspectRatio: import_zod39.z.number().positive().nullable().default(null),
|
|
2738
|
+
border: import_zod39.z.lazy(() => CABBorder),
|
|
2739
|
+
buttonField: import_zod39.z.enum(buttonFields).optional(),
|
|
2170
2740
|
/**
|
|
2171
2741
|
* `icon` renders `source` as a single `s-icon` by name (the uber-image path covers icons too), reading
|
|
2172
2742
|
* `iconSize`/`iconTone`. The other values are a harmless informational holdover from the previous
|
|
@@ -2185,30 +2755,30 @@ var CABImageSectionFields = import_zod28.z.object({
|
|
|
2185
2755
|
* behavior degraded gracefully and told us about it. The client-assembled half of the invariant was never
|
|
2186
2756
|
* the risky half.
|
|
2187
2757
|
*/
|
|
2188
|
-
category:
|
|
2758
|
+
category: import_zod39.z.enum(["gallery", "icon", "icons", "payment-methods", "secure-checkout"]).nullable().default(null),
|
|
2189
2759
|
/** `icon`-mode only: the `s-icon` `size`; `null` ⇒ the component default (`base`). Ignored by image treatments. */
|
|
2190
|
-
iconSize:
|
|
2760
|
+
iconSize: import_zod39.z.enum(iconSizes).nullable().default(null),
|
|
2191
2761
|
/** `icon`-mode only: the `s-icon` `tone`; `null` ⇒ the component default (`auto`). Ignored by image treatments. */
|
|
2192
|
-
iconTone:
|
|
2193
|
-
name:
|
|
2194
|
-
naturalHeight:
|
|
2195
|
-
naturalWidth:
|
|
2762
|
+
iconTone: import_zod39.z.enum(iconTones).nullable().default(null),
|
|
2763
|
+
name: import_zod39.z.string().optional(),
|
|
2764
|
+
naturalHeight: import_zod39.z.number().default(0),
|
|
2765
|
+
naturalWidth: import_zod39.z.number().default(0),
|
|
2196
2766
|
/**
|
|
2197
2767
|
* `contain` (the component default): dimensionless images render in s-image's 1/1 default frame, and
|
|
2198
2768
|
* `cover` would crop non-square art (payment badges lost their edges — 15993); `contain` letterboxes.
|
|
2199
2769
|
*/
|
|
2200
|
-
objectFit:
|
|
2201
|
-
sectionId:
|
|
2202
|
-
sectionType:
|
|
2770
|
+
objectFit: import_zod39.z.enum(objectFits).default(ObjectFit.contain),
|
|
2771
|
+
sectionId: import_zod39.z.uuid().default(() => (0, import_uuid14.v7)()),
|
|
2772
|
+
sectionType: import_zod39.z.literal(SectionType.image).default(SectionType.image),
|
|
2203
2773
|
/**
|
|
2204
2774
|
* An image URL or dynamic token, an empty default, or — when `category: 'icon'` — an icon NAME. Icon mode
|
|
2205
2775
|
* takes a name or `''` only, NOT a token: no renderer resolves a token to an icon today, so accepting one
|
|
2206
2776
|
* would promise a capability that doesn't exist. Widen the refine's carve-out to `DYNAMIC_TOKEN_REGEX` when a
|
|
2207
2777
|
* server-chosen tier icon actually needs it.
|
|
2208
2778
|
*/
|
|
2209
|
-
source:
|
|
2779
|
+
source: import_zod39.z.union([import_zod39.z.url(), import_zod39.z.literal(""), import_zod39.z.string().regex(DYNAMIC_TOKEN_REGEX), import_zod39.z.enum(iconNames)]).default(""),
|
|
2210
2780
|
thumbnails: CABImageThumbnails.optional(),
|
|
2211
|
-
width:
|
|
2781
|
+
width: import_zod39.z.number().default(100)
|
|
2212
2782
|
});
|
|
2213
2783
|
var iconNameSet = new Set(iconNames);
|
|
2214
2784
|
var isIconName = (source2) => iconNameSet.has(source2);
|
|
@@ -2359,7 +2929,7 @@ var convertContentBlockTextToV2 = (language3, text2 = literalText, textAlign = "
|
|
|
2359
2929
|
};
|
|
2360
2930
|
|
|
2361
2931
|
// src/schema/widgets/checkout-and-beyond/root.ts
|
|
2362
|
-
var
|
|
2932
|
+
var import_zod40 = require("zod");
|
|
2363
2933
|
|
|
2364
2934
|
// src/schema/widgets/checkout-and-beyond/uiLabels.ts
|
|
2365
2935
|
var UI_LABELS = {
|
|
@@ -2379,8 +2949,8 @@ var UI_LABELS = {
|
|
|
2379
2949
|
};
|
|
2380
2950
|
|
|
2381
2951
|
// src/schema/widgets/checkout-and-beyond/root.ts
|
|
2382
|
-
var localized = (fallback) =>
|
|
2383
|
-
var CABUILabels =
|
|
2952
|
+
var localized = (fallback) => import_zod40.z.record(import_zod40.z.string(), import_zod40.z.string()).default(() => ({ ...fallback })).transform((labels) => Object.keys(labels).length > 0 ? labels : { ...fallback });
|
|
2953
|
+
var CABUILabels = import_zod40.z.object({
|
|
2384
2954
|
currentPage: localized(UI_LABELS.currentPage),
|
|
2385
2955
|
guest: localized(UI_LABELS.guest),
|
|
2386
2956
|
loadingOptions: localized(UI_LABELS.loadingOptions),
|
|
@@ -2405,37 +2975,37 @@ var CABUILabels = import_zod29.z.object({
|
|
|
2405
2975
|
subscriptionOptions: { ...UI_LABELS.subscriptionOptions },
|
|
2406
2976
|
updating: { ...UI_LABELS.updating }
|
|
2407
2977
|
}));
|
|
2408
|
-
var TargetArea =
|
|
2409
|
-
fill:
|
|
2410
|
-
flip:
|
|
2411
|
-
icon:
|
|
2412
|
-
label:
|
|
2413
|
-
width:
|
|
2978
|
+
var TargetArea = import_zod40.z.object({
|
|
2979
|
+
fill: import_zod40.z.boolean().optional(),
|
|
2980
|
+
flip: import_zod40.z.enum(["both", "horizontal", "vertical"]).optional(),
|
|
2981
|
+
icon: import_zod40.z.string(),
|
|
2982
|
+
label: import_zod40.z.string(),
|
|
2983
|
+
width: import_zod40.z.string()
|
|
2414
2984
|
}).default(targetAreas[EditorMode.checkoutExtension][1]);
|
|
2415
|
-
var CABTracking =
|
|
2416
|
-
enableAttribution:
|
|
2417
|
-
enableSource:
|
|
2418
|
-
enableWidget:
|
|
2985
|
+
var CABTracking = import_zod40.z.object({
|
|
2986
|
+
enableAttribution: import_zod40.z.boolean().nullish().transform((value) => value ?? true),
|
|
2987
|
+
enableSource: import_zod40.z.boolean().nullish().transform((value) => value ?? true),
|
|
2988
|
+
enableWidget: import_zod40.z.boolean().nullish().transform((value) => value ?? true)
|
|
2419
2989
|
}).nullish().transform((value) => value ?? { enableAttribution: true, enableSource: true, enableWidget: true });
|
|
2420
|
-
var CABExperiment =
|
|
2421
|
-
elementId:
|
|
2422
|
-
experimentId:
|
|
2423
|
-
experimentType:
|
|
2424
|
-
selectedId:
|
|
2990
|
+
var CABExperiment = import_zod40.z.object({
|
|
2991
|
+
elementId: import_zod40.z.number(),
|
|
2992
|
+
experimentId: import_zod40.z.number(),
|
|
2993
|
+
experimentType: import_zod40.z.string(),
|
|
2994
|
+
selectedId: import_zod40.z.number()
|
|
2425
2995
|
});
|
|
2426
2996
|
var CABRootSection = CABLayoutSection.extend({
|
|
2427
|
-
editorMode:
|
|
2997
|
+
editorMode: import_zod40.z.enum(editorModes).default(EditorMode.checkoutExtension),
|
|
2428
2998
|
experiment: CABExperiment.optional(),
|
|
2429
2999
|
// Same rule as CABTracking above: the v1 converters pass raw legacy `previewMode` through, so a
|
|
2430
3000
|
// `null` must fall back rather than throw the widget; malformed values still throw.
|
|
2431
|
-
previewMode:
|
|
2432
|
-
storeId:
|
|
3001
|
+
previewMode: import_zod40.z.boolean().nullish().transform((value) => value ?? false),
|
|
3002
|
+
storeId: import_zod40.z.number().nullable().default(null),
|
|
2433
3003
|
targetArea: TargetArea.nullable(),
|
|
2434
3004
|
tracking: CABTracking,
|
|
2435
|
-
type:
|
|
3005
|
+
type: import_zod40.z.enum(widgetTypes).default(WidgetType.ui_extension_content_block),
|
|
2436
3006
|
uiLabels: CABUILabels,
|
|
2437
|
-
version:
|
|
2438
|
-
widgetId:
|
|
3007
|
+
version: import_zod40.z.literal(2).default(2),
|
|
3008
|
+
widgetId: import_zod40.z.number().nullable().default(null)
|
|
2439
3009
|
});
|
|
2440
3010
|
|
|
2441
3011
|
// src/transforms/v1Location.ts
|
|
@@ -3928,172 +4498,10 @@ var convertOfferToV2 = ({ id, name, settings }) => {
|
|
|
3928
4498
|
var parseShielded = (schema, raw, transform = (input) => input) => schema.parse(transform(convertNumericObjects(deepCamelCase(raw))));
|
|
3929
4499
|
|
|
3930
4500
|
// src/transforms/postPurchase/convertMessagePreview.ts
|
|
3931
|
-
var
|
|
4501
|
+
var import_zod47 = require("zod");
|
|
3932
4502
|
|
|
3933
4503
|
// src/transforms/postPurchase/convertCalloutBlock.ts
|
|
3934
|
-
var
|
|
3935
|
-
|
|
3936
|
-
// src/schema/widgets/post-purchase-offer/postPurchaseBlocks.ts
|
|
3937
|
-
var import_compat4 = require("es-toolkit/compat");
|
|
3938
|
-
var import_uuid14 = require("uuid");
|
|
3939
|
-
var import_zod31 = require("zod");
|
|
3940
|
-
|
|
3941
|
-
// src/schema/widgets/post-purchase-offer/constants.ts
|
|
3942
|
-
var import_zod30 = require("zod");
|
|
3943
|
-
var blockTypes = [
|
|
3944
|
-
"callout_banner",
|
|
3945
|
-
"image",
|
|
3946
|
-
"image_content",
|
|
3947
|
-
"pay_button",
|
|
3948
|
-
"product_information",
|
|
3949
|
-
"separator",
|
|
3950
|
-
"text",
|
|
3951
|
-
"timer"
|
|
3952
|
-
];
|
|
3953
|
-
var blockType = import_zod30.z.enum(blockTypes);
|
|
3954
|
-
var BlockType = blockType.enum;
|
|
3955
|
-
|
|
3956
|
-
// src/schema/widgets/post-purchase-offer/postPurchaseBlocks.ts
|
|
3957
|
-
var TextAlignment2 = import_zod31.z.union([import_zod31.z.enum(["leading", "center", "trailing"]), import_zod31.z.unknown().transform(() => "leading")]);
|
|
3958
|
-
var TextSize = import_zod31.z.union([
|
|
3959
|
-
import_zod31.z.enum(["xsmall", "small", "base", "default", "medium", "large", "xlarge"]),
|
|
3960
|
-
import_zod31.z.unknown().transform(() => "medium")
|
|
3961
|
-
]);
|
|
3962
|
-
var CalloutBannerBlock = import_zod31.z.object({
|
|
3963
|
-
id: import_zod31.z.string().optional().default(() => (0, import_uuid14.v4)()),
|
|
3964
|
-
name: import_zod31.z.string().optional(),
|
|
3965
|
-
settings: import_zod31.z.object({
|
|
3966
|
-
superTitle: import_zod31.z.union([import_zod31.z.string(), TiptapDocument]).default(() => "Limited-time Offer"),
|
|
3967
|
-
title: import_zod31.z.union([import_zod31.z.string(), TiptapDocument]).default(() => "Add this customer favorite to your order")
|
|
3968
|
-
}),
|
|
3969
|
-
styles: import_zod31.z.object({
|
|
3970
|
-
superTitleEmphasized: import_zod31.z.boolean().default(false),
|
|
3971
|
-
superTitleSize: TextSize.default("large"),
|
|
3972
|
-
textAlignment: TextAlignment2.default("center"),
|
|
3973
|
-
titleEmphasized: import_zod31.z.boolean().default(true),
|
|
3974
|
-
titleSize: TextSize.default("large")
|
|
3975
|
-
}),
|
|
3976
|
-
type: import_zod31.z.literal(BlockType.callout_banner).default(BlockType.callout_banner)
|
|
3977
|
-
});
|
|
3978
|
-
var ImageBlock = import_zod31.z.object({
|
|
3979
|
-
id: import_zod31.z.string().optional().default(() => (0, import_uuid14.v4)()),
|
|
3980
|
-
name: import_zod31.z.string().optional(),
|
|
3981
|
-
settings: import_zod31.z.union([
|
|
3982
|
-
import_zod31.z.object({
|
|
3983
|
-
/** This isn't used in the post-purchase offer widget */
|
|
3984
|
-
alt: import_zod31.z.string().optional().default(""),
|
|
3985
|
-
image: import_zod31.z.union([import_zod31.z.literal(""), import_zod31.z.url()]).default(""),
|
|
3986
|
-
imageSize: import_zod31.z.number().default(20),
|
|
3987
|
-
imageType: import_zod31.z.enum(["URL", "UPLOAD"]).default("URL")
|
|
3988
|
-
}),
|
|
3989
|
-
import_zod31.z.array(import_zod31.z.never()).transform(() => ({}))
|
|
3990
|
-
]),
|
|
3991
|
-
type: import_zod31.z.literal(BlockType.image).default(BlockType.image)
|
|
3992
|
-
});
|
|
3993
|
-
var ImageContentBlock = import_zod31.z.object({
|
|
3994
|
-
id: import_zod31.z.string().optional().default(() => (0, import_uuid14.v4)()),
|
|
3995
|
-
name: import_zod31.z.string().optional(),
|
|
3996
|
-
settings: import_zod31.z.object({
|
|
3997
|
-
alt: import_zod31.z.string().optional().default(""),
|
|
3998
|
-
description: import_zod31.z.union([import_zod31.z.string(), TiptapDocument, import_zod31.z.null()]).default(
|
|
3999
|
-
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
|
|
4000
|
-
),
|
|
4001
|
-
descriptionSize: TextSize.default("medium"),
|
|
4002
|
-
horizontalAlignment: TextAlignment2.default("leading"),
|
|
4003
|
-
image: import_zod31.z.union([import_zod31.z.literal(""), import_zod31.z.url()]).default(""),
|
|
4004
|
-
imagePlacement: import_zod31.z.enum(["bottom", "left", "right", "top"]).optional().default("left"),
|
|
4005
|
-
imageSize: import_zod31.z.number().default(20),
|
|
4006
|
-
superTitle: import_zod31.z.union([import_zod31.z.string(), TiptapDocument]).default("Lorem Ipsum!"),
|
|
4007
|
-
superTitleSize: TextSize.default("medium"),
|
|
4008
|
-
/** This isn't configurable in the admin-nextjs editor */
|
|
4009
|
-
swapContent: import_zod31.z.boolean().optional().default(false),
|
|
4010
|
-
title: import_zod31.z.union([import_zod31.z.string(), TiptapDocument]).nullable().default("Lorem ipsum dolor sit amet"),
|
|
4011
|
-
titleSize: TextSize.default("medium")
|
|
4012
|
-
}),
|
|
4013
|
-
type: import_zod31.z.literal(BlockType.image_content).default(BlockType.image_content)
|
|
4014
|
-
});
|
|
4015
|
-
var PayButtonBlock = import_zod31.z.object({
|
|
4016
|
-
id: import_zod31.z.string().optional().default(() => (0, import_uuid14.v4)()),
|
|
4017
|
-
name: import_zod31.z.string().optional(),
|
|
4018
|
-
settings: import_zod31.z.union([
|
|
4019
|
-
import_zod31.z.object({
|
|
4020
|
-
label: import_zod31.z.string().default("Pay Now")
|
|
4021
|
-
}),
|
|
4022
|
-
import_zod31.z.array(import_zod31.z.never()).transform(() => ({
|
|
4023
|
-
label: "Pay Now"
|
|
4024
|
-
}))
|
|
4025
|
-
]),
|
|
4026
|
-
styles: import_zod31.z.union([
|
|
4027
|
-
import_zod31.z.object({
|
|
4028
|
-
buttonWidth: import_zod31.z.number().min(10).max(100).default(50)
|
|
4029
|
-
}),
|
|
4030
|
-
import_zod31.z.array(import_zod31.z.never()).transform(() => ({
|
|
4031
|
-
buttonWidth: 50
|
|
4032
|
-
}))
|
|
4033
|
-
]),
|
|
4034
|
-
type: import_zod31.z.literal(BlockType.pay_button).default(BlockType.pay_button)
|
|
4035
|
-
});
|
|
4036
|
-
var ProductInformationBlock = import_zod31.z.object({
|
|
4037
|
-
/** This isn't configurable in the admin-nextjs editor */
|
|
4038
|
-
hideProductImage: import_zod31.z.boolean().optional().default(false),
|
|
4039
|
-
id: import_zod31.z.string().optional().default(() => (0, import_uuid14.v4)()),
|
|
4040
|
-
name: import_zod31.z.string().optional(),
|
|
4041
|
-
type: import_zod31.z.literal(BlockType.product_information).default(BlockType.product_information)
|
|
4042
|
-
});
|
|
4043
|
-
var SeparatorBlock = import_zod31.z.object({
|
|
4044
|
-
id: import_zod31.z.string().optional().default(() => (0, import_uuid14.v4)()),
|
|
4045
|
-
name: import_zod31.z.string().optional(),
|
|
4046
|
-
type: import_zod31.z.literal(BlockType.separator).default(BlockType.separator)
|
|
4047
|
-
});
|
|
4048
|
-
var TextBlock = import_zod31.z.object({
|
|
4049
|
-
id: import_zod31.z.string().optional().default(() => (0, import_uuid14.v4)()),
|
|
4050
|
-
name: import_zod31.z.string().optional(),
|
|
4051
|
-
settings: import_zod31.z.object({
|
|
4052
|
-
description: import_zod31.z.union([import_zod31.z.string(), TiptapDocument]).optional().default(
|
|
4053
|
-
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
|
|
4054
|
-
),
|
|
4055
|
-
/** This isn't used in the post-purchase offer widget */
|
|
4056
|
-
descriptionSize: TextSize.default("medium"),
|
|
4057
|
-
horizontalAlignment: TextAlignment2.default("leading"),
|
|
4058
|
-
superTitle: import_zod31.z.union([import_zod31.z.string(), TiptapDocument]).default("Super Title"),
|
|
4059
|
-
/** This isn't used in the post-purchase offer widget */
|
|
4060
|
-
superTitleSize: TextSize.default("medium"),
|
|
4061
|
-
title: import_zod31.z.union([import_zod31.z.string(), TiptapDocument]).nullable().default("Lorem ipsum dolor sit amet."),
|
|
4062
|
-
/** This isn't used in the post-purchase offer widget */
|
|
4063
|
-
titleSize: TextSize.default("medium")
|
|
4064
|
-
}),
|
|
4065
|
-
type: import_zod31.z.literal(BlockType.text).default(BlockType.text)
|
|
4066
|
-
});
|
|
4067
|
-
var TimerBlock = import_zod31.z.object({
|
|
4068
|
-
id: import_zod31.z.string().optional().default(() => (0, import_uuid14.v4)()),
|
|
4069
|
-
name: import_zod31.z.string().optional(),
|
|
4070
|
-
settings: import_zod31.z.object({
|
|
4071
|
-
durationMinutes: import_zod31.z.number().min(0).default(10),
|
|
4072
|
-
durationSeconds: import_zod31.z.union([import_zod31.z.number().min(0), import_zod31.z.unknown().transform(() => 0)]).default(0),
|
|
4073
|
-
endOffer: import_zod31.z.boolean().default(true),
|
|
4074
|
-
title: import_zod31.z.union([import_zod31.z.string(), TiptapDocument]).default("Hurry \u2014 your special offer ends in:")
|
|
4075
|
-
}),
|
|
4076
|
-
styles: import_zod31.z.object({
|
|
4077
|
-
textAlignment: TextAlignment2.default("center"),
|
|
4078
|
-
timerBackgroundColor: import_zod31.z.enum(["info", "warning", "success", "critical"]).default("warning"),
|
|
4079
|
-
timerEmphasized: import_zod31.z.union([import_zod31.z.boolean(), import_zod31.z.unknown().transform(() => true)]).default(true),
|
|
4080
|
-
timerSize: TextSize.default("medium"),
|
|
4081
|
-
timerWidth: import_zod31.z.number().min(10).max(100).optional().default(100),
|
|
4082
|
-
titleEmphasized: import_zod31.z.union([import_zod31.z.boolean(), import_zod31.z.unknown().transform(() => true)]).default(false),
|
|
4083
|
-
titleSize: TextSize.default("medium")
|
|
4084
|
-
}),
|
|
4085
|
-
type: import_zod31.z.literal(BlockType.timer).default(BlockType.timer)
|
|
4086
|
-
});
|
|
4087
|
-
var PostPurchaseBlock = import_zod31.z.discriminatedUnion("type", [
|
|
4088
|
-
CalloutBannerBlock,
|
|
4089
|
-
ImageBlock,
|
|
4090
|
-
ImageContentBlock,
|
|
4091
|
-
PayButtonBlock,
|
|
4092
|
-
ProductInformationBlock,
|
|
4093
|
-
SeparatorBlock,
|
|
4094
|
-
TextBlock,
|
|
4095
|
-
TimerBlock
|
|
4096
|
-
]);
|
|
4504
|
+
var import_zod41 = require("zod");
|
|
4097
4505
|
|
|
4098
4506
|
// src/transforms/postPurchase/styledTextRun.ts
|
|
4099
4507
|
var sizes = {
|
|
@@ -4117,7 +4525,7 @@ var styledTextRun = (text2, emphasized, size) => ({
|
|
|
4117
4525
|
// src/transforms/postPurchase/convertCalloutBlock.ts
|
|
4118
4526
|
var fields = ["superTitle", "title"];
|
|
4119
4527
|
var Shell = CalloutBannerBlock.pick({ styles: true }).extend({
|
|
4120
|
-
settings:
|
|
4528
|
+
settings: import_zod41.z.object({ superTitle: import_zod41.z.unknown().optional(), title: import_zod41.z.unknown().optional() })
|
|
4121
4529
|
});
|
|
4122
4530
|
var convertCalloutBlock = (raw, report) => {
|
|
4123
4531
|
const omit = (detail) => {
|
|
@@ -4152,7 +4560,7 @@ var convertCalloutBlock = (raw, report) => {
|
|
|
4152
4560
|
};
|
|
4153
4561
|
|
|
4154
4562
|
// src/transforms/postPurchase/convertImageFrame.ts
|
|
4155
|
-
var
|
|
4563
|
+
var import_zod42 = require("zod");
|
|
4156
4564
|
|
|
4157
4565
|
// src/transforms/postPurchase/sizeImageSource.ts
|
|
4158
4566
|
var sizeImageSource = (source2, size) => {
|
|
@@ -4164,7 +4572,7 @@ var sizeImageSource = (source2, size) => {
|
|
|
4164
4572
|
};
|
|
4165
4573
|
|
|
4166
4574
|
// src/transforms/postPurchase/convertImageFrame.ts
|
|
4167
|
-
var Source =
|
|
4575
|
+
var Source = import_zod42.z.url().default("https://cdn.shopify.com/s/files/1/0605/0555/5177/files/placeholder.jpg?v=1657762972");
|
|
4168
4576
|
var DEFAULT_IMAGE_SIZE = 20;
|
|
4169
4577
|
var convertImageFrame = (raw) => {
|
|
4170
4578
|
const parsed = ImageBlock.shape.settings.options[0].safeParse(raw);
|
|
@@ -4210,7 +4618,7 @@ var convertImageBlock = (raw, report) => {
|
|
|
4210
4618
|
};
|
|
4211
4619
|
|
|
4212
4620
|
// src/transforms/postPurchase/convertImageContentBlock.ts
|
|
4213
|
-
var
|
|
4621
|
+
var import_zod44 = require("zod");
|
|
4214
4622
|
|
|
4215
4623
|
// src/transforms/postPurchase/convertImageContentText.ts
|
|
4216
4624
|
var fields2 = ["superTitle", "title", "description"];
|
|
@@ -4235,286 +4643,98 @@ var convertImageContentText = (settings, report) => {
|
|
|
4235
4643
|
} : text2;
|
|
4236
4644
|
const section = CABTextSection.safeParse({ content: { en: content } });
|
|
4237
4645
|
return section.success ? [section.data] : omit();
|
|
4238
|
-
});
|
|
4239
|
-
return CABLayoutSection.parse({ alignment: { horizontal }, sections });
|
|
4240
|
-
};
|
|
4241
|
-
|
|
4242
|
-
// src/transforms/postPurchase/imageContentSettings.ts
|
|
4243
|
-
var
|
|
4244
|
-
var ImageContentSettings = ImageContentBlock.shape.settings.pick({
|
|
4245
|
-
descriptionSize: true,
|
|
4246
|
-
horizontalAlignment: true,
|
|
4247
|
-
superTitleSize: true,
|
|
4248
|
-
swapContent: true,
|
|
4249
|
-
titleSize: true
|
|
4250
|
-
}).extend({
|
|
4251
|
-
alt:
|
|
4252
|
-
description:
|
|
4253
|
-
image:
|
|
4254
|
-
imagePlacement: ImageContentBlock.shape.settings.shape.imagePlacement.unwrap().nullable(),
|
|
4255
|
-
imageSize: ImageContentBlock.shape.settings.shape.imageSize.pipe(
|
|
4256
|
-
superTitle:
|
|
4257
|
-
title:
|
|
4258
|
-
});
|
|
4259
|
-
|
|
4260
|
-
// src/transforms/postPurchase/convertImageContentBlock.ts
|
|
4261
|
-
var Shell2 = import_zod35.z.object({ settings: ImageContentSettings, type: import_zod35.z.literal("image_content") });
|
|
4262
|
-
var PROPORTIONAL_BREAK_AT = 500;
|
|
4263
|
-
var convertImageContentBlock = (raw, report) => {
|
|
4264
|
-
const shell = Shell2.safeParse(raw);
|
|
4265
|
-
if (!shell.success) {
|
|
4266
|
-
report?.({ detail: "Unreadable post-purchase image-content block", kind: "section" });
|
|
4267
|
-
return [];
|
|
4268
|
-
}
|
|
4269
|
-
const settings = shell.data.settings;
|
|
4270
|
-
const alt = typeof settings.alt === "string" ? settings.alt : void 0;
|
|
4271
|
-
if (settings.alt !== void 0 && alt === void 0) {
|
|
4272
|
-
report?.({ detail: "Unreadable post-purchase image-content alt text", kind: "section" });
|
|
4273
|
-
}
|
|
4274
|
-
const image = convertImageFrame({ alt, image: settings.image, imageSize: settings.imageSize });
|
|
4275
|
-
if (!image) report?.({ detail: "Unreadable post-purchase image-content image", kind: "section" });
|
|
4276
|
-
const text2 = convertImageContentText(settings, report);
|
|
4277
|
-
const textFrame = CABLayoutSection.parse({ direction: "grid", grid: { columns: ["100%"] }, sections: [text2] });
|
|
4278
|
-
const placement = settings.imagePlacement ?? (settings.swapContent ? "right" : "left");
|
|
4279
|
-
const imageFirst = placement === "left" || placement === "top";
|
|
4280
|
-
const sections = imageFirst ? [image, textFrame] : [textFrame, image];
|
|
4281
|
-
const ordered = sections.filter((section) => section !== null);
|
|
4282
|
-
const inner = placement === "left" || placement === "right" ? CABLayoutSection.parse({
|
|
4283
|
-
sections: ordered,
|
|
4284
|
-
spacing: "loose",
|
|
4285
|
-
wrapping: {
|
|
4286
|
-
breakAt: settings.imageSize <= 1 ? PROPORTIONAL_BREAK_AT : settings.imageSize,
|
|
4287
|
-
maxPerLine: 2
|
|
4288
|
-
}
|
|
4289
|
-
}) : CABLayoutSection.parse({
|
|
4290
|
-
direction: "grid",
|
|
4291
|
-
grid: { columns: ["100%"] },
|
|
4292
|
-
sections: [CABLayoutSection.parse({ sections: ordered })],
|
|
4293
|
-
width: 95
|
|
4294
|
-
});
|
|
4295
|
-
return [CABLayoutSection.parse({ frame: "offer-content", sections: [inner], spacing: "none" })];
|
|
4296
|
-
};
|
|
4297
|
-
|
|
4298
|
-
// src/transforms/postPurchase/productCardPay.ts
|
|
4299
|
-
var import_es_toolkit6 = require("es-toolkit");
|
|
4300
|
-
var PAY_NOW = { en: "Pay Now" };
|
|
4301
|
-
var DECLINE_THIS_OFFER = { en: "Decline this offer" };
|
|
4302
|
-
var NOT_AVAILABLE_DEFAULTS = ["Not available"];
|
|
4303
|
-
var soldOutSlot = ({ language: language3 }) => labelSlot("soldOut", OFFER_LABELS.soldOut, language3.global.notAvailable, [], NOT_AVAILABLE_DEFAULTS);
|
|
4304
|
-
var productCardPay = (settings) => {
|
|
4305
|
-
const payNow = labelSlot("payNow", PAY_NOW, settings.language.global.payNow);
|
|
4306
|
-
const priced = settings.language.displayCtaPrice ? { ...payNow, content: (0, import_es_toolkit6.mapValues)(payNow.content, (label2) => `${label2} \xB7 {{total}}`) } : payNow;
|
|
4307
|
-
return [addToOrderButton("primary", [priced, soldOutSlot(settings)])];
|
|
4308
|
-
};
|
|
4309
|
-
var productCardDecline = ({ language: language3 }) => [
|
|
4310
|
-
{
|
|
4311
|
-
action: "declineOffer",
|
|
4312
|
-
buttonStyle: "secondary",
|
|
4313
|
-
sections: [labelSlot("declineOffer", DECLINE_THIS_OFFER, language3.global.declineThisOffer)],
|
|
4314
|
-
sectionType: "button"
|
|
4315
|
-
}
|
|
4316
|
-
];
|
|
4317
|
-
|
|
4318
|
-
// src/transforms/postPurchase/productCardSettings.ts
|
|
4319
|
-
var import_es_toolkit7 = require("es-toolkit");
|
|
4320
|
-
var import_zod38 = require("zod");
|
|
4321
|
-
|
|
4322
|
-
// src/schema/widgets/post-purchase-offer/postPurchaseSettings.ts
|
|
4323
|
-
var import_zod37 = require("zod");
|
|
4324
|
-
|
|
4325
|
-
// src/schema/widgets/post-purchase-offer/common.ts
|
|
4326
|
-
var import_compat5 = require("es-toolkit/compat");
|
|
4327
|
-
var import_zod36 = require("zod");
|
|
4328
|
-
var strictNumber = import_zod36.z.union([
|
|
4329
|
-
import_zod36.z.number(),
|
|
4330
|
-
import_zod36.z.string().transform((value) => (0, import_compat5.toNumber)((0, import_compat5.replace)((0, import_compat5.toString)(value), /[^0-9.]/g, "")) || 0),
|
|
4331
|
-
import_zod36.z.unknown().transform(() => 0)
|
|
4332
|
-
]);
|
|
4333
|
-
|
|
4334
|
-
// src/schema/widgets/post-purchase-offer/postPurchaseSettings.ts
|
|
4335
|
-
var PostPurchaseSettings = import_zod37.z.object({
|
|
4336
|
-
advance: import_zod37.z.object({ removePartialOrder: import_zod37.z.boolean().default(true) }).optional().default(() => ({ removePartialOrder: true })),
|
|
4337
|
-
blocks: import_zod37.z.union([import_zod37.z.array(PostPurchaseBlock), import_zod37.z.unknown().transform(() => [])]).default(() => [
|
|
4338
|
-
PostPurchaseBlock.parse({ settings: {}, styles: {}, type: BlockType.timer }),
|
|
4339
|
-
PostPurchaseBlock.parse({ settings: {}, styles: {}, type: BlockType.callout_banner }),
|
|
4340
|
-
PostPurchaseBlock.parse({ type: BlockType.product_information })
|
|
4341
|
-
]),
|
|
4342
|
-
columnLayout: import_zod37.z.boolean().optional(),
|
|
4343
|
-
discount: import_zod37.z.object({
|
|
4344
|
-
amount: strictNumber.default(30),
|
|
4345
|
-
shouldShowSavingText: import_zod37.z.boolean().optional().default(true),
|
|
4346
|
-
type: import_zod37.z.enum(["none", "fixed_amount", "percentage"]).default("none")
|
|
4347
|
-
}),
|
|
4348
|
-
discountedFrom: import_zod37.z.enum(["price", "compare_at_price"]).optional().default("price"),
|
|
4349
|
-
endpoint: import_zod37.z.string().optional(),
|
|
4350
|
-
integrations: import_zod37.z.object({
|
|
4351
|
-
judgeme: import_zod37.z.boolean().default(false),
|
|
4352
|
-
junip: import_zod37.z.boolean().optional().default(false),
|
|
4353
|
-
klaviyo: import_zod37.z.boolean().default(false),
|
|
4354
|
-
loox: import_zod37.z.boolean().default(false),
|
|
4355
|
-
okendo: import_zod37.z.boolean().default(false),
|
|
4356
|
-
opinew: import_zod37.z.boolean().optional().default(false),
|
|
4357
|
-
reviewsio: import_zod37.z.boolean().optional().default(false),
|
|
4358
|
-
stamped: import_zod37.z.boolean().default(false),
|
|
4359
|
-
yotpo: import_zod37.z.boolean().default(false)
|
|
4360
|
-
}),
|
|
4361
|
-
key: import_zod37.z.string().optional(),
|
|
4362
|
-
language: import_zod37.z.object({
|
|
4363
|
-
description: import_zod37.z.union([import_zod37.z.string(), import_zod37.z.unknown().transform(() => "")]).default(""),
|
|
4364
|
-
descriptionEnabled: import_zod37.z.boolean().optional().default(false),
|
|
4365
|
-
descriptionRte: import_zod37.z.object({
|
|
4366
|
-
content: import_zod37.z.array(import_zod37.z.unknown()),
|
|
4367
|
-
type: import_zod37.z.string()
|
|
4368
|
-
}).optional(),
|
|
4369
|
-
descriptionSpacing: import_zod37.z.enum(["none", "xtight", "tight", "default", "loose", "xloose"]).optional(),
|
|
4370
|
-
displayCtaPrice: import_zod37.z.boolean().default(true),
|
|
4371
|
-
global: import_zod37.z.object({
|
|
4372
|
-
declineAll: import_zod37.z.string().optional().default("Decline All"),
|
|
4373
|
-
declineThisOffer: import_zod37.z.string().default("Decline this offer"),
|
|
4374
|
-
free: import_zod37.z.string().optional().default("Free"),
|
|
4375
|
-
notAvailable: import_zod37.z.string().optional().default("Not available"),
|
|
4376
|
-
payNow: import_zod37.z.string().default("Pay Now"),
|
|
4377
|
-
payNowUpgradeToSubscription: import_zod37.z.string().optional().default("Upgrade to Subscription"),
|
|
4378
|
-
quantity: import_zod37.z.string().default("Quantity"),
|
|
4379
|
-
/** This isn't configurable in the admin-nextjs editor */
|
|
4380
|
-
recurringShipping: import_zod37.z.string().optional().default("Recurring shipping"),
|
|
4381
|
-
recurringSubtotal: import_zod37.z.string().default("Recurring subtotal"),
|
|
4382
|
-
reviewsPlural: import_zod37.z.string().optional().default("Reviews"),
|
|
4383
|
-
reviewsSingular: import_zod37.z.string().optional().default("Review"),
|
|
4384
|
-
save: import_zod37.z.union([import_zod37.z.string(), import_zod37.z.unknown().transform(() => "Save")]).optional().default("Save"),
|
|
4385
|
-
shipping: import_zod37.z.string().default("Shipping"),
|
|
4386
|
-
subscriptionOption: import_zod37.z.string().optional().default("Subscribe and Save"),
|
|
4387
|
-
subtotal: import_zod37.z.string().default("Subtotal"),
|
|
4388
|
-
taxes: import_zod37.z.string().default("Taxes"),
|
|
4389
|
-
total: import_zod37.z.string().default("Total")
|
|
4390
|
-
}).optional().default(() => ({
|
|
4391
|
-
declineAll: "Decline All",
|
|
4392
|
-
declineThisOffer: "Decline this offer",
|
|
4393
|
-
free: "Free",
|
|
4394
|
-
notAvailable: "Not available",
|
|
4395
|
-
payNow: "Pay Now",
|
|
4396
|
-
payNowUpgradeToSubscription: "Upgrade to Subscription",
|
|
4397
|
-
quantity: "Quantity",
|
|
4398
|
-
/** This isn't configurable in the admin-nextjs editor */
|
|
4399
|
-
recurringShipping: "Recurring shipping",
|
|
4400
|
-
recurringSubtotal: "Recurring subtotal",
|
|
4401
|
-
reviewsPlural: "Reviews",
|
|
4402
|
-
reviewsSingular: "Review",
|
|
4403
|
-
save: "Save",
|
|
4404
|
-
shipping: "Shipping",
|
|
4405
|
-
subscriptionOption: "Subscribe and Save",
|
|
4406
|
-
subtotal: "Subtotal",
|
|
4407
|
-
taxes: "Taxes",
|
|
4408
|
-
total: "Total"
|
|
4409
|
-
})),
|
|
4410
|
-
globalTranslation: import_zod37.z.string().optional().default("english")
|
|
4411
|
-
}),
|
|
4412
|
-
metafields: import_zod37.z.boolean().default(false),
|
|
4413
|
-
/** This isn't configurable in the admin-nextjs editor */
|
|
4414
|
-
offer: import_zod37.z.object({
|
|
4415
|
-
count: import_zod37.z.number().default(1)
|
|
4416
|
-
}),
|
|
4417
|
-
offersLayout: import_zod37.z.object({
|
|
4418
|
-
itemsPerPage: import_zod37.z.number().optional(),
|
|
4419
|
-
type: import_zod37.z.enum(["list", "grid", "carousel"]).default("list")
|
|
4420
|
-
}).optional().default({
|
|
4421
|
-
type: "list"
|
|
4422
|
-
}),
|
|
4423
|
-
/** This isn't configurable in the admin-nextjs editor */
|
|
4424
|
-
previewMode: import_zod37.z.boolean().default(false),
|
|
4425
|
-
productLimit: import_zod37.z.number().optional().default(1),
|
|
4426
|
-
productOptions: import_zod37.z.object({
|
|
4427
|
-
/** This isn't configurable in the admin-nextjs editor */
|
|
4428
|
-
hideOutOfStockVariants: import_zod37.z.boolean().optional().default(false),
|
|
4429
|
-
matchVariant: import_zod37.z.boolean().optional().default(true),
|
|
4430
|
-
showDeclineAll: import_zod37.z.enum(["above", "below", "both", "none"]).optional(),
|
|
4431
|
-
showShipping: import_zod37.z.boolean().optional().default(true),
|
|
4432
|
-
showSubtotal: import_zod37.z.boolean().optional().default(true),
|
|
4433
|
-
showTaxes: import_zod37.z.boolean().optional().default(true),
|
|
4434
|
-
showTotal: import_zod37.z.boolean().optional().default(true),
|
|
4435
|
-
showVariantSelectors: import_zod37.z.boolean().optional().default(true),
|
|
4436
|
-
variantSelectorDisplayMode: import_zod37.z.enum(["separate", "single"]).optional().default("separate")
|
|
4437
|
-
}),
|
|
4438
|
-
productType: import_zod37.z.union([import_zod37.z.enum(["one-time", "subscription", "both"]), import_zod37.z.literal("").transform(() => "one-time")]).default("one-time"),
|
|
4439
|
-
productTypeSelector: import_zod37.z.enum(["dropdown", "radio"]).optional().default("radio"),
|
|
4440
|
-
quantityInputs: import_zod37.z.object({
|
|
4441
|
-
defaultQuantity: import_zod37.z.union([import_zod37.z.number(), import_zod37.z.null().transform(() => 1)]).default(1),
|
|
4442
|
-
enabled: import_zod37.z.boolean().default(true),
|
|
4443
|
-
maxValue: import_zod37.z.union([import_zod37.z.number(), import_zod37.z.null().transform(() => 15)]).default(15),
|
|
4444
|
-
minValue: import_zod37.z.union([import_zod37.z.number().min(0), import_zod37.z.unknown().transform(() => 0)]).default(1)
|
|
4445
|
-
}),
|
|
4446
|
-
shipping: import_zod37.z.object({
|
|
4447
|
-
amount: strictNumber.default(10),
|
|
4448
|
-
/** This isn't configurable in the admin-nextjs editor */
|
|
4449
|
-
enabled: import_zod37.z.boolean().default(true),
|
|
4450
|
-
title: import_zod37.z.string().optional().default("Shipping Fees"),
|
|
4451
|
-
type: import_zod37.z.enum(["free", "fixed_amount"]).default("free")
|
|
4452
|
-
}),
|
|
4453
|
-
styles: import_zod37.z.object({
|
|
4454
|
-
starColor: import_zod37.z.string().optional().default("#fadb14"),
|
|
4455
|
-
starSize: import_zod37.z.union([import_zod37.z.enum(["small", "medium", "large"]), import_zod37.z.unknown().transform(() => "large")]).optional().default("large"),
|
|
4456
|
-
starStrokeColor: import_zod37.z.string().optional().default("#fadb14"),
|
|
4457
|
-
strokeWidth: import_zod37.z.string().optional().default("1")
|
|
4458
|
-
}).optional(),
|
|
4459
|
-
subImages: import_zod37.z.number().nullish().default(8),
|
|
4460
|
-
subscription: import_zod37.z.object({
|
|
4461
|
-
discount: import_zod37.z.object({
|
|
4462
|
-
amount: strictNumber.default(30),
|
|
4463
|
-
shouldShowSavingText: import_zod37.z.boolean().optional().default(true),
|
|
4464
|
-
type: import_zod37.z.enum(["none", "fixed_amount", "percentage"]).default("none")
|
|
4465
|
-
}),
|
|
4466
|
-
shipping: import_zod37.z.object({
|
|
4467
|
-
amount: strictNumber.default(1),
|
|
4468
|
-
/** This isn't configurable in the admin-nextjs editor */
|
|
4469
|
-
enabled: import_zod37.z.boolean().default(true),
|
|
4470
|
-
/** This isn't configurable in the admin-nextjs editor */
|
|
4471
|
-
recurringAmount: strictNumber.default(2),
|
|
4472
|
-
shippingTitle: import_zod37.z.string().default("Shipping Fees"),
|
|
4473
|
-
type: import_zod37.z.enum(["free", "fixed_amount"]).default("free")
|
|
4474
|
-
})
|
|
4475
|
-
}).optional().default({
|
|
4476
|
-
discount: {
|
|
4477
|
-
amount: 30,
|
|
4478
|
-
shouldShowSavingText: true,
|
|
4479
|
-
type: "none"
|
|
4480
|
-
},
|
|
4481
|
-
shipping: {
|
|
4482
|
-
amount: 1,
|
|
4483
|
-
/** This isn't configurable in the admin-nextjs editor */
|
|
4484
|
-
enabled: true,
|
|
4485
|
-
/** This isn't configurable in the admin-nextjs editor */
|
|
4486
|
-
recurringAmount: 2,
|
|
4487
|
-
shippingTitle: "Shipping Fees",
|
|
4488
|
-
type: "free"
|
|
4489
|
-
}
|
|
4490
|
-
}),
|
|
4491
|
-
subscriptionIsDefault: import_zod37.z.boolean().optional(),
|
|
4492
|
-
/** This isn't configurable in the admin-nextjs editor */
|
|
4493
|
-
template: import_zod37.z.string().optional().default(""),
|
|
4494
|
-
type: import_zod37.z.literal("shopify_post_purchase_extension").default("shopify_post_purchase_extension"),
|
|
4495
|
-
upgradeToSubscription: import_zod37.z.object({
|
|
4496
|
-
acceptButtonText: import_zod37.z.string().optional().default("Upgrade"),
|
|
4497
|
-
allow: import_zod37.z.boolean().optional().default(false),
|
|
4498
|
-
emailRefundNotice: import_zod37.z.boolean().optional().default(false),
|
|
4499
|
-
errorBannerText: import_zod37.z.string().optional().default("This subscription cannot be added - limit one per order")
|
|
4500
|
-
}).optional().default(() => ({
|
|
4501
|
-
acceptButtonText: "Upgrade",
|
|
4502
|
-
allow: false,
|
|
4503
|
-
emailRefundNotice: false,
|
|
4504
|
-
errorBannerText: "This subscription cannot be added - limit one per order"
|
|
4505
|
-
}))
|
|
4646
|
+
});
|
|
4647
|
+
return CABLayoutSection.parse({ alignment: { horizontal }, sections });
|
|
4648
|
+
};
|
|
4649
|
+
|
|
4650
|
+
// src/transforms/postPurchase/imageContentSettings.ts
|
|
4651
|
+
var import_zod43 = require("zod");
|
|
4652
|
+
var ImageContentSettings = ImageContentBlock.shape.settings.pick({
|
|
4653
|
+
descriptionSize: true,
|
|
4654
|
+
horizontalAlignment: true,
|
|
4655
|
+
superTitleSize: true,
|
|
4656
|
+
swapContent: true,
|
|
4657
|
+
titleSize: true
|
|
4658
|
+
}).extend({
|
|
4659
|
+
alt: import_zod43.z.unknown().optional(),
|
|
4660
|
+
description: import_zod43.z.unknown().optional(),
|
|
4661
|
+
image: import_zod43.z.unknown().optional(),
|
|
4662
|
+
imagePlacement: ImageContentBlock.shape.settings.shape.imagePlacement.unwrap().nullable(),
|
|
4663
|
+
imageSize: ImageContentBlock.shape.settings.shape.imageSize.pipe(import_zod43.z.number().positive()),
|
|
4664
|
+
superTitle: import_zod43.z.unknown().optional(),
|
|
4665
|
+
title: import_zod43.z.unknown().optional()
|
|
4506
4666
|
});
|
|
4507
4667
|
|
|
4668
|
+
// src/transforms/postPurchase/convertImageContentBlock.ts
|
|
4669
|
+
var Shell2 = import_zod44.z.object({ settings: ImageContentSettings, type: import_zod44.z.literal("image_content") });
|
|
4670
|
+
var PROPORTIONAL_BREAK_AT = 500;
|
|
4671
|
+
var convertImageContentBlock = (raw, report) => {
|
|
4672
|
+
const shell = Shell2.safeParse(raw);
|
|
4673
|
+
if (!shell.success) {
|
|
4674
|
+
report?.({ detail: "Unreadable post-purchase image-content block", kind: "section" });
|
|
4675
|
+
return [];
|
|
4676
|
+
}
|
|
4677
|
+
const settings = shell.data.settings;
|
|
4678
|
+
const alt = typeof settings.alt === "string" ? settings.alt : void 0;
|
|
4679
|
+
if (settings.alt !== void 0 && alt === void 0) {
|
|
4680
|
+
report?.({ detail: "Unreadable post-purchase image-content alt text", kind: "section" });
|
|
4681
|
+
}
|
|
4682
|
+
const image = convertImageFrame({ alt, image: settings.image, imageSize: settings.imageSize });
|
|
4683
|
+
if (!image) report?.({ detail: "Unreadable post-purchase image-content image", kind: "section" });
|
|
4684
|
+
const text2 = convertImageContentText(settings, report);
|
|
4685
|
+
const textFrame = CABLayoutSection.parse({ direction: "grid", grid: { columns: ["100%"] }, sections: [text2] });
|
|
4686
|
+
const placement = settings.imagePlacement ?? (settings.swapContent ? "right" : "left");
|
|
4687
|
+
const imageFirst = placement === "left" || placement === "top";
|
|
4688
|
+
const sections = imageFirst ? [image, textFrame] : [textFrame, image];
|
|
4689
|
+
const ordered = sections.filter((section) => section !== null);
|
|
4690
|
+
const inner = placement === "left" || placement === "right" ? CABLayoutSection.parse({
|
|
4691
|
+
sections: ordered,
|
|
4692
|
+
spacing: "loose",
|
|
4693
|
+
wrapping: {
|
|
4694
|
+
breakAt: settings.imageSize <= 1 ? PROPORTIONAL_BREAK_AT : settings.imageSize,
|
|
4695
|
+
maxPerLine: 2
|
|
4696
|
+
}
|
|
4697
|
+
}) : CABLayoutSection.parse({
|
|
4698
|
+
direction: "grid",
|
|
4699
|
+
grid: { columns: ["100%"] },
|
|
4700
|
+
sections: [CABLayoutSection.parse({ sections: ordered })],
|
|
4701
|
+
width: 95
|
|
4702
|
+
});
|
|
4703
|
+
return [CABLayoutSection.parse({ frame: "offer-content", sections: [inner], spacing: "none" })];
|
|
4704
|
+
};
|
|
4705
|
+
|
|
4706
|
+
// src/transforms/postPurchase/productCardPay.ts
|
|
4707
|
+
var import_es_toolkit6 = require("es-toolkit");
|
|
4708
|
+
var PAY_NOW = { en: "Pay Now" };
|
|
4709
|
+
var DECLINE_THIS_OFFER = { en: "Decline this offer" };
|
|
4710
|
+
var NOT_AVAILABLE_DEFAULTS = ["Not available"];
|
|
4711
|
+
var soldOutSlot = ({ language: language3 }) => labelSlot("soldOut", OFFER_LABELS.soldOut, language3.global.notAvailable, [], NOT_AVAILABLE_DEFAULTS);
|
|
4712
|
+
var productCardPay = (settings) => {
|
|
4713
|
+
const payNow = labelSlot("payNow", PAY_NOW, settings.language.global.payNow);
|
|
4714
|
+
const priced = settings.language.displayCtaPrice ? { ...payNow, content: (0, import_es_toolkit6.mapValues)(payNow.content, (label2) => `${label2} \xB7 {{total}}`) } : payNow;
|
|
4715
|
+
return [addToOrderButton("primary", [priced, soldOutSlot(settings)])];
|
|
4716
|
+
};
|
|
4717
|
+
var productCardDecline = ({ language: language3 }) => [
|
|
4718
|
+
{
|
|
4719
|
+
action: "declineOffer",
|
|
4720
|
+
buttonStyle: "secondary",
|
|
4721
|
+
sections: [labelSlot("declineOffer", DECLINE_THIS_OFFER, language3.global.declineThisOffer)],
|
|
4722
|
+
sectionType: "button"
|
|
4723
|
+
}
|
|
4724
|
+
];
|
|
4725
|
+
|
|
4508
4726
|
// src/transforms/postPurchase/productCardSettings.ts
|
|
4727
|
+
var import_es_toolkit7 = require("es-toolkit");
|
|
4728
|
+
var import_zod45 = require("zod");
|
|
4509
4729
|
var { shape } = PostPurchaseSettings;
|
|
4510
|
-
var Labels =
|
|
4730
|
+
var Labels = import_zod45.z.object(
|
|
4511
4731
|
(0, import_es_toolkit7.mapValues)(shape.language.shape.global.unwrap().unwrap().shape, (label2) => label2.catch(() => label2.parse(void 0)))
|
|
4512
4732
|
);
|
|
4513
|
-
var Language =
|
|
4733
|
+
var Language = import_zod45.z.object({
|
|
4514
4734
|
displayCtaPrice: shape.language.shape.displayCtaPrice.catch(true),
|
|
4515
4735
|
global: Labels.catch(() => Labels.parse({}))
|
|
4516
4736
|
});
|
|
4517
|
-
var Fields =
|
|
4737
|
+
var Fields = import_zod45.z.object({
|
|
4518
4738
|
discount: shape.discount.catch(() => shape.discount.parse({})),
|
|
4519
4739
|
language: Language.catch(() => Language.parse({})),
|
|
4520
4740
|
productOptions: shape.productOptions.catch(() => shape.productOptions.parse({})),
|
|
@@ -4798,7 +5018,7 @@ var convertSeparatorBlock = (raw, report) => {
|
|
|
4798
5018
|
};
|
|
4799
5019
|
|
|
4800
5020
|
// src/transforms/postPurchase/convertTextBlock.ts
|
|
4801
|
-
var
|
|
5021
|
+
var import_zod46 = require("zod");
|
|
4802
5022
|
var fields3 = ["superTitle", "title", "description"];
|
|
4803
5023
|
var styles = {
|
|
4804
5024
|
description: [{ attrs: { color: "base", fontSize: "small" }, type: "textStyle" }],
|
|
@@ -4806,13 +5026,13 @@ var styles = {
|
|
|
4806
5026
|
title: [{ type: "bold" }, { attrs: { color: "base", fontSize: "large" }, type: "textStyle" }]
|
|
4807
5027
|
};
|
|
4808
5028
|
var settingsSchema = TextBlock.shape.settings;
|
|
4809
|
-
var Shell3 =
|
|
5029
|
+
var Shell3 = import_zod46.z.object({
|
|
4810
5030
|
settings: settingsSchema.pick({ horizontalAlignment: true }).extend({
|
|
4811
|
-
description:
|
|
4812
|
-
superTitle:
|
|
4813
|
-
title:
|
|
5031
|
+
description: import_zod46.z.unknown().optional(),
|
|
5032
|
+
superTitle: import_zod46.z.unknown().optional(),
|
|
5033
|
+
title: import_zod46.z.unknown().optional()
|
|
4814
5034
|
}),
|
|
4815
|
-
type:
|
|
5035
|
+
type: import_zod46.z.literal("text")
|
|
4816
5036
|
});
|
|
4817
5037
|
var convertTextBlock = (raw, report) => {
|
|
4818
5038
|
const shell = Shell3.safeParse(raw);
|
|
@@ -4884,11 +5104,11 @@ var convertTimerBlock = (raw, report) => {
|
|
|
4884
5104
|
};
|
|
4885
5105
|
|
|
4886
5106
|
// src/transforms/postPurchase/convertMessagePreview.ts
|
|
4887
|
-
var MessageWidget =
|
|
4888
|
-
blocks:
|
|
4889
|
-
type:
|
|
5107
|
+
var MessageWidget = import_zod47.z.object({
|
|
5108
|
+
blocks: import_zod47.z.array(import_zod47.z.unknown()).min(1),
|
|
5109
|
+
type: import_zod47.z.literal(WidgetType.shopify_post_purchase_extension)
|
|
4890
5110
|
});
|
|
4891
|
-
var BlockType2 =
|
|
5111
|
+
var BlockType2 = import_zod47.z.object({ type: import_zod47.z.string() });
|
|
4892
5112
|
var converters = {
|
|
4893
5113
|
callout_banner: convertCalloutBlock,
|
|
4894
5114
|
image: convertImageBlock,
|
|
@@ -5400,6 +5620,12 @@ var reportUnreadableVerdict = (metadata, report) => {
|
|
|
5400
5620
|
if (RuleVerdict.safeParse(metadata).success || isDefinitiveRuleAnswer(metadata)) return;
|
|
5401
5621
|
report?.({ detail: "rule verdict lacks readable custom.shouldShow", kind: "ruleVerdict" });
|
|
5402
5622
|
};
|
|
5623
|
+
var withReviews = (product, integrations, report) => {
|
|
5624
|
+
const { reviews: engineReviews, ...rest } = product;
|
|
5625
|
+
const reviews = projectOfferProductReviews(integrations, product, report);
|
|
5626
|
+
if (reviews !== void 0) return { ...rest, reviews };
|
|
5627
|
+
return engineReviews === void 0 ? product : rest;
|
|
5628
|
+
};
|
|
5403
5629
|
var dedupeById = (products) => (0, import_es_toolkit8.uniqBy)(products, (product) => product.id);
|
|
5404
5630
|
var MAX_REQUEST_LINE_BYTES = 32e3;
|
|
5405
5631
|
var requestLineBytes = (path, search) => new TextEncoder().encode(`GET ${path}?${search} HTTP/1.1`).length;
|
|
@@ -5426,7 +5652,9 @@ var fetchDataSourceResults = async (input, ctx) => {
|
|
|
5426
5652
|
if (input.limit === 0) reportUnreadableVerdict(metadata, ctx.reportDrift);
|
|
5427
5653
|
if (input.limit !== 0 && (upstream != null && (typeof upstream !== "object" || Array.isArray(upstream)) || raw.data != null && !Array.isArray(raw.data)))
|
|
5428
5654
|
ctx.reportDrift?.({ detail: "data-source products payload is not an array", kind: "dataSource" });
|
|
5429
|
-
const products = dedupeById(rawProducts.filter((product) => keepValidProduct(product, ctx.reportDrift)))
|
|
5655
|
+
const products = dedupeById(rawProducts.filter((product) => keepValidProduct(product, ctx.reportDrift))).map(
|
|
5656
|
+
(product) => withReviews(product, input.integrations, ctx.reportDrift)
|
|
5657
|
+
);
|
|
5430
5658
|
return {
|
|
5431
5659
|
metadata,
|
|
5432
5660
|
/** B2B sessions filter by the company-location catalog server-side (the client bypasses its market hide). */
|
|
@@ -5436,7 +5664,7 @@ var fetchDataSourceResults = async (input, ctx) => {
|
|
|
5436
5664
|
};
|
|
5437
5665
|
|
|
5438
5666
|
// src/server/adsEngine.ts
|
|
5439
|
-
var
|
|
5667
|
+
var import_zod48 = require("zod");
|
|
5440
5668
|
var SUPPLY_KEY = { production: "AQF5RKLR", staging: "Z56LQ7PS" };
|
|
5441
5669
|
var OFFER_LIMIT = 4;
|
|
5442
5670
|
var SUPPORTED_COUNTRIES = /* @__PURE__ */ new Set(["US", "CA", "GB"]);
|
|
@@ -5449,30 +5677,30 @@ var transactionItems = (input) => (input.transactionItems?.map(({ id, priceCents
|
|
|
5449
5677
|
title,
|
|
5450
5678
|
type
|
|
5451
5679
|
})) ?? input.cart.items.map(({ productId: productId2, quantity: quantity3 }) => ({ id: productId2, quantity: quantity3 }))).slice(0, MAX_TRANSACTION_ITEMS);
|
|
5452
|
-
var AdsEngineOffer =
|
|
5680
|
+
var AdsEngineOffer = import_zod48.z.object({
|
|
5453
5681
|
/** Pill-style value prop ("Get $45 Cashback"). Carried through the parse; the card does not render it yet (REB-24429 — pill design pending). */
|
|
5454
|
-
callout:
|
|
5455
|
-
click_url:
|
|
5456
|
-
cta:
|
|
5682
|
+
callout: import_zod48.z.string().catch(""),
|
|
5683
|
+
click_url: import_zod48.z.string(),
|
|
5684
|
+
cta: import_zod48.z.string(),
|
|
5457
5685
|
/** `omitempty` on the ad server — a bid without it must not fail the parse and drop the whole batch (composeOffer falls back to 'No Thanks'). */
|
|
5458
|
-
decline_cta:
|
|
5459
|
-
decline_url:
|
|
5460
|
-
description:
|
|
5686
|
+
decline_cta: import_zod48.z.string().catch(""),
|
|
5687
|
+
decline_url: import_zod48.z.string(),
|
|
5688
|
+
description: import_zod48.z.string(),
|
|
5461
5689
|
/** Short legal disclosure (FDIC / auto-renewal / FTC-affiliation lines). Rendered subdued under the CTAs. */
|
|
5462
|
-
disclaimer:
|
|
5690
|
+
disclaimer: import_zod48.z.string().catch(""),
|
|
5463
5691
|
/** Long legal text behind the disclosure toggle in the composed card (REB-24429). */
|
|
5464
|
-
extended_disclaimer:
|
|
5465
|
-
headline:
|
|
5466
|
-
id:
|
|
5692
|
+
extended_disclaimer: import_zod48.z.string().catch(""),
|
|
5693
|
+
headline: import_zod48.z.string(),
|
|
5694
|
+
id: import_zod48.z.string(),
|
|
5467
5695
|
/** Advertiser-supplied image alt; the composed card falls back to the stripped headline when empty. */
|
|
5468
|
-
image_alt:
|
|
5469
|
-
image_url:
|
|
5696
|
+
image_alt: import_zod48.z.string().catch(""),
|
|
5697
|
+
image_url: import_zod48.z.string().optional(),
|
|
5470
5698
|
/** The serving network's own privacy page (Falcon, REB-24744); the card prefers it over the widget setting. A bad value drops only this field, never the offer. */
|
|
5471
|
-
privacy_url:
|
|
5472
|
-
view_url:
|
|
5699
|
+
privacy_url: import_zod48.z.string().optional().catch(void 0),
|
|
5700
|
+
view_url: import_zod48.z.string()
|
|
5473
5701
|
});
|
|
5474
|
-
var AdsEngineResponse =
|
|
5475
|
-
offers:
|
|
5702
|
+
var AdsEngineResponse = import_zod48.z.object({
|
|
5703
|
+
offers: import_zod48.z.array(import_zod48.z.unknown()).default([]).transform(
|
|
5476
5704
|
(offers) => offers.flatMap((offer) => {
|
|
5477
5705
|
const result = AdsEngineOffer.safeParse(offer);
|
|
5478
5706
|
return result.success ? [result.data] : [];
|
|
@@ -5484,8 +5712,8 @@ var AdsEngineResponse = import_zod41.z.object({
|
|
|
5484
5712
|
* offers-testing fixture on a test store forces it, REB-24467). Both optional: an older engine or a
|
|
5485
5713
|
* non-JSON body must not fail the parse and drop the offers.
|
|
5486
5714
|
*/
|
|
5487
|
-
request_id:
|
|
5488
|
-
testing:
|
|
5715
|
+
request_id: import_zod48.z.string().optional().catch(void 0),
|
|
5716
|
+
testing: import_zod48.z.boolean().optional().catch(void 0)
|
|
5489
5717
|
});
|
|
5490
5718
|
var adsHost = (host) => `offers.${host}`;
|
|
5491
5719
|
var isTestingRequest = (input, isProduction) => !isProduction || !!input.testing || input.customerEmail?.toLowerCase() === TEST_CUSTOMER_EMAIL;
|
|
@@ -5801,7 +6029,6 @@ var fetchMonetizeOffers = async (input, ctx, prefetched) => {
|
|
|
5801
6029
|
|
|
5802
6030
|
// src/server/salvageSections.ts
|
|
5803
6031
|
var import_uuid16 = require("uuid");
|
|
5804
|
-
var STUB_SECTION_TYPE = "unknown";
|
|
5805
6032
|
var knownSectionTypes = new Set(sectionTypes);
|
|
5806
6033
|
var hasSectionsArray = (raw) => typeof raw === "object" && raw !== null && Array.isArray(raw.sections);
|
|
5807
6034
|
var stubSection = (raw, report) => {
|
|
@@ -5814,7 +6041,7 @@ var stubSection = (raw, report) => {
|
|
|
5814
6041
|
});
|
|
5815
6042
|
return {
|
|
5816
6043
|
sectionId: typeof rawId === "string" && rawId ? rawId : (0, import_uuid16.v7)(),
|
|
5817
|
-
sectionType: typeof original === "string" && !knownSectionTypes.has(original) ? original :
|
|
6044
|
+
sectionType: typeof original === "string" && !knownSectionTypes.has(original) ? original : SALVAGED_SECTION_TYPE
|
|
5818
6045
|
};
|
|
5819
6046
|
};
|
|
5820
6047
|
var salvageSection = (raw, report) => {
|
|
@@ -5957,13 +6184,13 @@ var convertWidgetSettings = async (input, ctx) => {
|
|
|
5957
6184
|
};
|
|
5958
6185
|
|
|
5959
6186
|
// src/server/giftWidgets.ts
|
|
5960
|
-
var
|
|
5961
|
-
var SettingsNumber =
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
]).pipe(
|
|
5965
|
-
var SgwpMilestoneSchema =
|
|
5966
|
-
selectable_product_quantity: SettingsNumber.pipe(
|
|
6187
|
+
var import_zod49 = require("zod");
|
|
6188
|
+
var SettingsNumber = import_zod49.z.union([
|
|
6189
|
+
import_zod49.z.number(),
|
|
6190
|
+
import_zod49.z.string().trim().regex(/^-?\d+(\.\d+)?$/)
|
|
6191
|
+
]).pipe(import_zod49.z.coerce.number());
|
|
6192
|
+
var SgwpMilestoneSchema = import_zod49.z.object({
|
|
6193
|
+
selectable_product_quantity: SettingsNumber.pipe(import_zod49.z.number().int().nonnegative()),
|
|
5967
6194
|
unlock_price: SettingsNumber
|
|
5968
6195
|
});
|
|
5969
6196
|
var fetchGiftWidgetSettings = async (widgetId, shop, ctx) => unwrapData(await ctx.fetchUpstream("/api/v1/widgets/settings", { id: String(widgetId), shop }, { host: ctx.host }));
|
|
@@ -5974,7 +6201,7 @@ var readDataSourcePath = (settings) => {
|
|
|
5974
6201
|
var readMilestones = (settings, report) => {
|
|
5975
6202
|
const raw = settings && typeof settings === "object" ? settings.milestones : void 0;
|
|
5976
6203
|
if (raw == null) return [];
|
|
5977
|
-
const parsed =
|
|
6204
|
+
const parsed = import_zod49.z.array(SgwpMilestoneSchema).safeParse(raw);
|
|
5978
6205
|
if (parsed.success) return parsed.data;
|
|
5979
6206
|
report?.({
|
|
5980
6207
|
detail: [
|
|
@@ -6089,16 +6316,16 @@ var validateGifts = async (input, ctx) => {
|
|
|
6089
6316
|
|
|
6090
6317
|
// src/server/normalizePostPurchaseProduct.ts
|
|
6091
6318
|
var import_compat7 = require("es-toolkit/compat");
|
|
6092
|
-
var
|
|
6319
|
+
var import_zod53 = require("zod");
|
|
6093
6320
|
|
|
6094
6321
|
// src/schema/postPurchaseProductSettings.ts
|
|
6095
|
-
var
|
|
6322
|
+
var import_zod51 = require("zod");
|
|
6096
6323
|
|
|
6097
6324
|
// src/schema/postPurchaseProductSource.ts
|
|
6098
|
-
var
|
|
6099
|
-
var PostPurchaseAmount =
|
|
6100
|
-
var PostPurchaseProductId =
|
|
6101
|
-
var PostPurchaseVariantId =
|
|
6325
|
+
var import_zod50 = require("zod");
|
|
6326
|
+
var PostPurchaseAmount = import_zod50.z.string().regex(/^\d+(?:\.\d+)?$/).refine((value) => Number.isFinite(Number(value)));
|
|
6327
|
+
var PostPurchaseProductId = import_zod50.z.number().int().positive();
|
|
6328
|
+
var PostPurchaseVariantId = import_zod50.z.number().int().positive();
|
|
6102
6329
|
var ProductBase = OfferProduct.pick({ description: true, id: true, image: true, title: true }).extend({
|
|
6103
6330
|
description: OfferProduct.shape.description.nullable(),
|
|
6104
6331
|
id: PostPurchaseProductId
|
|
@@ -6106,51 +6333,51 @@ var ProductBase = OfferProduct.pick({ description: true, id: true, image: true,
|
|
|
6106
6333
|
var SourceVariant = OfferProduct.shape.variants.element.pick({ id: true, title: true }).extend({
|
|
6107
6334
|
compareAtPrice: PostPurchaseAmount.nullable(),
|
|
6108
6335
|
id: PostPurchaseVariantId,
|
|
6109
|
-
imageId:
|
|
6110
|
-
inventoryManagement:
|
|
6111
|
-
inventoryPolicy:
|
|
6112
|
-
inventoryQuantity:
|
|
6113
|
-
option1:
|
|
6114
|
-
option2:
|
|
6115
|
-
option3:
|
|
6336
|
+
imageId: import_zod50.z.number().int().nonnegative().nullish(),
|
|
6337
|
+
inventoryManagement: import_zod50.z.string().nullable(),
|
|
6338
|
+
inventoryPolicy: import_zod50.z.string(),
|
|
6339
|
+
inventoryQuantity: import_zod50.z.number(),
|
|
6340
|
+
option1: import_zod50.z.unknown().optional(),
|
|
6341
|
+
option2: import_zod50.z.unknown().optional(),
|
|
6342
|
+
option3: import_zod50.z.unknown().optional(),
|
|
6116
6343
|
price: PostPurchaseAmount,
|
|
6117
6344
|
productId: PostPurchaseProductId,
|
|
6118
|
-
sellingPlanAllocations:
|
|
6345
|
+
sellingPlanAllocations: import_zod50.z.unknown().optional()
|
|
6119
6346
|
});
|
|
6120
6347
|
var Product2 = ProductBase.extend({
|
|
6121
|
-
images:
|
|
6122
|
-
|
|
6348
|
+
images: import_zod50.z.array(
|
|
6349
|
+
import_zod50.z.object({ alt: import_zod50.z.string().optional().catch(void 0), id: import_zod50.z.number().int().positive(), src: import_zod50.z.string() })
|
|
6123
6350
|
).nullish(),
|
|
6124
|
-
metadata:
|
|
6125
|
-
productQuantity:
|
|
6126
|
-
|
|
6127
|
-
|
|
6351
|
+
metadata: import_zod50.z.object({
|
|
6352
|
+
productQuantity: import_zod50.z.union([
|
|
6353
|
+
import_zod50.z.number().int().positive(),
|
|
6354
|
+
import_zod50.z.string().regex(/^[1-9]\d*$/).transform(Number)
|
|
6128
6355
|
]).optional()
|
|
6129
6356
|
}).optional(),
|
|
6130
|
-
metafields:
|
|
6131
|
-
options:
|
|
6132
|
-
productGroupVariants:
|
|
6357
|
+
metafields: import_zod50.z.unknown().optional(),
|
|
6358
|
+
options: import_zod50.z.unknown().optional(),
|
|
6359
|
+
productGroupVariants: import_zod50.z.array(import_zod50.z.unknown()).default([]),
|
|
6133
6360
|
// REB-25048: the v2 data source flags a subscription-only product here and sends no selling plan groups
|
|
6134
|
-
requiresSellingPlan:
|
|
6135
|
-
selectedVariant:
|
|
6136
|
-
sellingPlanGroups:
|
|
6361
|
+
requiresSellingPlan: import_zod50.z.boolean().nullish(),
|
|
6362
|
+
selectedVariant: import_zod50.z.unknown().optional(),
|
|
6363
|
+
sellingPlanGroups: import_zod50.z.array(
|
|
6137
6364
|
OfferProduct.shape.sellingPlanGroups.unwrap().element.extend({
|
|
6138
|
-
discountAmount:
|
|
6139
|
-
discountType:
|
|
6140
|
-
id:
|
|
6141
|
-
requiresSellingPlan:
|
|
6142
|
-
sellingPlans:
|
|
6365
|
+
discountAmount: import_zod50.z.unknown().optional(),
|
|
6366
|
+
discountType: import_zod50.z.unknown().optional(),
|
|
6367
|
+
id: import_zod50.z.unknown().optional(),
|
|
6368
|
+
requiresSellingPlan: import_zod50.z.boolean().default(false),
|
|
6369
|
+
sellingPlans: import_zod50.z.unknown().optional()
|
|
6143
6370
|
})
|
|
6144
6371
|
).default([]),
|
|
6145
|
-
variants:
|
|
6372
|
+
variants: import_zod50.z.array(SourceVariant)
|
|
6146
6373
|
});
|
|
6147
|
-
var PostPurchaseProductSource =
|
|
6148
|
-
data:
|
|
6149
|
-
metadata:
|
|
6374
|
+
var PostPurchaseProductSource = import_zod50.z.object({
|
|
6375
|
+
data: import_zod50.z.array(Product2),
|
|
6376
|
+
metadata: import_zod50.z.object({ widget: import_zod50.z.record(import_zod50.z.string(), import_zod50.z.unknown()).default({}) }).default({ widget: {} })
|
|
6150
6377
|
});
|
|
6151
6378
|
|
|
6152
6379
|
// src/schema/postPurchaseProductSettings.ts
|
|
6153
|
-
var amount =
|
|
6380
|
+
var amount = import_zod51.z.union([import_zod51.z.number().nonnegative(), PostPurchaseAmount.transform(Number)]);
|
|
6154
6381
|
var PostPurchaseProductSettings = PostPurchaseSettings.pick({
|
|
6155
6382
|
discountedFrom: true,
|
|
6156
6383
|
language: true,
|
|
@@ -6162,18 +6389,18 @@ var PostPurchaseProductSettings = PostPurchaseSettings.pick({
|
|
|
6162
6389
|
subscriptionIsDefault: true,
|
|
6163
6390
|
upgradeToSubscription: true
|
|
6164
6391
|
}).extend({
|
|
6165
|
-
advance:
|
|
6166
|
-
blocks:
|
|
6392
|
+
advance: import_zod51.z.unknown().default({}),
|
|
6393
|
+
blocks: import_zod51.z.array(import_zod51.z.unknown()).optional(),
|
|
6167
6394
|
discount: PostPurchaseSettings.shape.discount.extend({ amount: amount.default(30) }),
|
|
6168
|
-
integrations:
|
|
6395
|
+
integrations: import_zod51.z.unknown().default({}),
|
|
6169
6396
|
shipping: PostPurchaseSettings.shape.shipping.extend({ amount: amount.default(10) }),
|
|
6170
|
-
styles:
|
|
6397
|
+
styles: import_zod51.z.unknown().default({}),
|
|
6171
6398
|
subImages: PostPurchaseSettings.shape.subImages.catch(null),
|
|
6172
|
-
subscription:
|
|
6399
|
+
subscription: import_zod51.z.unknown().default(PostPurchaseSettings.shape.subscription.parse(void 0))
|
|
6173
6400
|
});
|
|
6174
6401
|
|
|
6175
6402
|
// src/server/readPostPurchaseProductSource.ts
|
|
6176
|
-
var
|
|
6403
|
+
var import_zod52 = require("zod");
|
|
6177
6404
|
|
|
6178
6405
|
// src/server/postPurchaseResponseDrift.ts
|
|
6179
6406
|
var heard = /* @__PURE__ */ new WeakMap();
|
|
@@ -6199,9 +6426,9 @@ var requiresOwnSellingPlan = (product) => product.requiresSellingPlan === true;
|
|
|
6199
6426
|
var requiresUnsuppliedSellingPlan = (product) => requiresOwnSellingPlan(product) && !product.sellingPlanGroups?.length;
|
|
6200
6427
|
|
|
6201
6428
|
// src/server/readPostPurchaseProductSource.ts
|
|
6202
|
-
var Envelope = PostPurchaseProductSource.extend({ data:
|
|
6429
|
+
var Envelope = PostPurchaseProductSource.extend({ data: import_zod52.z.array(import_zod52.z.unknown()) });
|
|
6203
6430
|
var Product3 = PostPurchaseProductSource.shape.data.element;
|
|
6204
|
-
var Identified =
|
|
6431
|
+
var Identified = import_zod52.z.object({ id: PostPurchaseProductId });
|
|
6205
6432
|
var readPostPurchaseProductSource = (response, report) => {
|
|
6206
6433
|
const { data, metadata } = Envelope.parse(deepCamelCase(response));
|
|
6207
6434
|
const drift = [];
|
|
@@ -6236,9 +6463,9 @@ var normalizePostPurchaseSource = (settings, response, report) => {
|
|
|
6236
6463
|
const original = PostPurchaseProductSettings.parse(deepCamelCase(settings));
|
|
6237
6464
|
const { dropped, metadata, products } = readPostPurchaseProductSource(response, report);
|
|
6238
6465
|
const overrides = Object.fromEntries(Object.entries(metadata.widget).filter(([key]) => key in original));
|
|
6239
|
-
const discount =
|
|
6466
|
+
const discount = import_zod53.z.object({ type: import_zod53.z.string() }).safeParse(overrides.discount);
|
|
6240
6467
|
if (discount.success && discount.data.type === "fixed") {
|
|
6241
|
-
overrides.discount = { ...
|
|
6468
|
+
overrides.discount = { ...import_zod53.z.record(import_zod53.z.string(), import_zod53.z.unknown()).parse(overrides.discount), type: "fixed_amount" };
|
|
6242
6469
|
}
|
|
6243
6470
|
const effective = PostPurchaseProductSettings.parse((0, import_compat7.merge)({}, original, overrides));
|
|
6244
6471
|
const data = products.map(({ product }) => product);
|
|
@@ -6275,52 +6502,52 @@ var postPurchasePlanDiscountPercentage = (price, adjustment) => {
|
|
|
6275
6502
|
};
|
|
6276
6503
|
|
|
6277
6504
|
// src/schema/postPurchasePlanCatalog.ts
|
|
6278
|
-
var
|
|
6505
|
+
var import_zod56 = require("zod");
|
|
6279
6506
|
|
|
6280
6507
|
// src/schema/postPurchasePlanAdjustment.ts
|
|
6281
|
-
var
|
|
6508
|
+
var import_zod55 = require("zod");
|
|
6282
6509
|
|
|
6283
6510
|
// src/schema/postPurchaseDiscount.ts
|
|
6284
|
-
var
|
|
6285
|
-
var Discount =
|
|
6286
|
-
amount:
|
|
6287
|
-
title:
|
|
6288
|
-
type:
|
|
6511
|
+
var import_zod54 = require("zod");
|
|
6512
|
+
var Discount = import_zod54.z.object({
|
|
6513
|
+
amount: import_zod54.z.number().nonnegative(),
|
|
6514
|
+
title: import_zod54.z.string(),
|
|
6515
|
+
type: import_zod54.z.enum(["none", "fixed_amount", "percentage"])
|
|
6289
6516
|
});
|
|
6290
6517
|
var validPostPurchaseDiscount = (discount) => discount.type !== "percentage" || discount.amount <= 100;
|
|
6291
6518
|
var PostPurchaseDiscount = Discount.refine(validPostPurchaseDiscount);
|
|
6292
6519
|
|
|
6293
6520
|
// src/schema/postPurchasePlanAdjustment.ts
|
|
6294
|
-
var PostPurchasePlanAdjustment =
|
|
6521
|
+
var PostPurchasePlanAdjustment = import_zod55.z.object({
|
|
6295
6522
|
amount: PostPurchaseDiscount.shape.amount,
|
|
6296
|
-
type:
|
|
6523
|
+
type: import_zod55.z.enum(["percentage", "fixed_amount", "price"])
|
|
6297
6524
|
}).refine(({ amount: amount2, type }) => type === "price" || validPostPurchaseDiscount({ amount: amount2, type }));
|
|
6298
6525
|
|
|
6299
6526
|
// src/schema/postPurchasePlanCatalog.ts
|
|
6300
|
-
var PostPurchasePlanOption =
|
|
6527
|
+
var PostPurchasePlanOption = import_zod56.z.object({
|
|
6301
6528
|
adjustment: PostPurchasePlanAdjustment.optional(),
|
|
6302
6529
|
/** cab-checkout's `discountPercentage`: the plan's own whole-percent saving on the regular price (`{{subscriptionDiscount}}`). */
|
|
6303
|
-
discountPercentage:
|
|
6304
|
-
id:
|
|
6305
|
-
intervalFrequency:
|
|
6306
|
-
intervalLabel:
|
|
6307
|
-
name:
|
|
6530
|
+
discountPercentage: import_zod56.z.number().int().min(0).max(100).optional(),
|
|
6531
|
+
id: import_zod56.z.number().int().positive(),
|
|
6532
|
+
intervalFrequency: import_zod56.z.string().regex(/^[1-9]\d*$/).optional(),
|
|
6533
|
+
intervalLabel: import_zod56.z.string().min(1),
|
|
6534
|
+
name: import_zod56.z.string().min(1)
|
|
6308
6535
|
});
|
|
6309
|
-
var PostPurchasePlanCatalog =
|
|
6310
|
-
plans:
|
|
6311
|
-
productId:
|
|
6312
|
-
requiresSellingPlan:
|
|
6313
|
-
variantId:
|
|
6536
|
+
var PostPurchasePlanCatalog = import_zod56.z.object({
|
|
6537
|
+
plans: import_zod56.z.array(PostPurchasePlanOption),
|
|
6538
|
+
productId: import_zod56.z.number().int().positive(),
|
|
6539
|
+
requiresSellingPlan: import_zod56.z.boolean(),
|
|
6540
|
+
variantId: import_zod56.z.number().int().positive()
|
|
6314
6541
|
});
|
|
6315
6542
|
|
|
6316
6543
|
// src/server/postPurchaseLegacyPlans.ts
|
|
6317
|
-
var
|
|
6544
|
+
var import_zod58 = require("zod");
|
|
6318
6545
|
|
|
6319
6546
|
// src/server/postPurchasePlanAdjustment.ts
|
|
6320
|
-
var
|
|
6321
|
-
var SourceAdjustment =
|
|
6547
|
+
var import_zod57 = require("zod");
|
|
6548
|
+
var SourceAdjustment = import_zod57.z.object({
|
|
6322
6549
|
amount: PostPurchaseProductSettings.shape.discount.shape.amount.unwrap(),
|
|
6323
|
-
type:
|
|
6550
|
+
type: import_zod57.z.enum(["percentage", "fixed_amount", "amount", "price", "none", "fixed"])
|
|
6324
6551
|
});
|
|
6325
6552
|
var readPostPurchasePlanAdjustment = (raw) => {
|
|
6326
6553
|
const source2 = SourceAdjustment.parse(raw);
|
|
@@ -6339,13 +6566,13 @@ var readPostPurchasePlanAdjustment = (raw) => {
|
|
|
6339
6566
|
var Plan = PostPurchasePlanOption.pick({ id: true, name: true }).extend({
|
|
6340
6567
|
orderIntervalFrequency: PostPurchasePlanOption.shape.intervalFrequency.unwrap(),
|
|
6341
6568
|
orderIntervalUnitType: PostPurchasePlanOption.shape.intervalLabel,
|
|
6342
|
-
shopifyVariantId:
|
|
6569
|
+
shopifyVariantId: import_zod58.z.string().regex(/^[1-9]\d*$/).nullish()
|
|
6343
6570
|
});
|
|
6344
|
-
var Group =
|
|
6345
|
-
discountAmount:
|
|
6346
|
-
discountType:
|
|
6347
|
-
id:
|
|
6348
|
-
sellingPlans:
|
|
6571
|
+
var Group = import_zod58.z.object({
|
|
6572
|
+
discountAmount: import_zod58.z.unknown(),
|
|
6573
|
+
discountType: import_zod58.z.unknown(),
|
|
6574
|
+
id: import_zod58.z.number().int().positive(),
|
|
6575
|
+
sellingPlans: import_zod58.z.array(import_zod58.z.object({ shopifyVariantId: Plan.shape.shopifyVariantId }).passthrough())
|
|
6349
6576
|
});
|
|
6350
6577
|
var readPostPurchaseLegacyPlans = (raw, variantId) => {
|
|
6351
6578
|
const group = Group.pick({ id: true, sellingPlans: true }).parse(raw);
|
|
@@ -6366,22 +6593,22 @@ var readPostPurchaseLegacyPlans = (raw, variantId) => {
|
|
|
6366
6593
|
};
|
|
6367
6594
|
|
|
6368
6595
|
// src/server/postPurchaseModernPlans.ts
|
|
6369
|
-
var
|
|
6370
|
-
var Groups =
|
|
6371
|
-
|
|
6372
|
-
id:
|
|
6373
|
-
sellingPlans:
|
|
6596
|
+
var import_zod59 = require("zod");
|
|
6597
|
+
var Groups = import_zod59.z.array(
|
|
6598
|
+
import_zod59.z.object({
|
|
6599
|
+
id: import_zod59.z.string().min(1),
|
|
6600
|
+
sellingPlans: import_zod59.z.unknown()
|
|
6374
6601
|
})
|
|
6375
6602
|
);
|
|
6376
|
-
var PostPurchasePlanAllocations =
|
|
6603
|
+
var PostPurchasePlanAllocations = import_zod59.z.array(import_zod59.z.object({ sellingPlanGroupId: import_zod59.z.string().min(1) }));
|
|
6377
6604
|
var Allocations = PostPurchasePlanAllocations.default([]);
|
|
6378
|
-
var Plans =
|
|
6605
|
+
var Plans = import_zod59.z.array(
|
|
6379
6606
|
PostPurchasePlanOption.pick({ id: true, name: true }).extend({
|
|
6380
|
-
options:
|
|
6381
|
-
priceAdjustments:
|
|
6607
|
+
options: import_zod59.z.array(import_zod59.z.object({ value: import_zod59.z.string().min(1) })).min(1),
|
|
6608
|
+
priceAdjustments: import_zod59.z.array(import_zod59.z.unknown())
|
|
6382
6609
|
})
|
|
6383
6610
|
);
|
|
6384
|
-
var FirstAdjustment =
|
|
6611
|
+
var FirstAdjustment = import_zod59.z.object({
|
|
6385
6612
|
value: PostPurchaseProductSettings.shape.discount.shape.amount.unwrap(),
|
|
6386
6613
|
valueType: PostPurchasePlanAdjustment.shape.type
|
|
6387
6614
|
});
|
|
@@ -6439,72 +6666,45 @@ var projectPostPurchasePlanCatalog = (normalized, report) => {
|
|
|
6439
6666
|
};
|
|
6440
6667
|
|
|
6441
6668
|
// src/schema/postPurchaseSubscriptionProduct.ts
|
|
6442
|
-
var
|
|
6669
|
+
var import_zod64 = require("zod");
|
|
6443
6670
|
|
|
6444
6671
|
// src/schema/postPurchaseProduct.ts
|
|
6445
|
-
var
|
|
6672
|
+
var import_zod63 = require("zod");
|
|
6446
6673
|
|
|
6447
6674
|
// src/schema/postPurchaseProductDisplay.ts
|
|
6448
|
-
var
|
|
6675
|
+
var import_zod61 = require("zod");
|
|
6449
6676
|
|
|
6450
6677
|
// src/schema/postPurchaseProductGallery.ts
|
|
6451
|
-
var
|
|
6452
|
-
var PostPurchaseProductGallery =
|
|
6678
|
+
var import_zod60 = require("zod");
|
|
6679
|
+
var PostPurchaseProductGallery = import_zod60.z.object({
|
|
6453
6680
|
/**
|
|
6454
6681
|
* Show the thumbnail row: the product had more than one image before `images` was capped at the
|
|
6455
6682
|
* sub-image limit, and that limit allows at least one thumbnail. It stays true when the cap leaves one
|
|
6456
6683
|
* image (legacy checks the count before slicing). Older replies omit it; fall back to `images.length > 1`.
|
|
6457
6684
|
*/
|
|
6458
|
-
hasMultiple:
|
|
6459
|
-
images:
|
|
6460
|
-
|
|
6461
|
-
description:
|
|
6462
|
-
id:
|
|
6463
|
-
source:
|
|
6464
|
-
thumbnail:
|
|
6685
|
+
hasMultiple: import_zod60.z.boolean().optional(),
|
|
6686
|
+
images: import_zod60.z.array(
|
|
6687
|
+
import_zod60.z.object({
|
|
6688
|
+
description: import_zod60.z.string(),
|
|
6689
|
+
id: import_zod60.z.number().int().positive(),
|
|
6690
|
+
source: import_zod60.z.string(),
|
|
6691
|
+
thumbnail: import_zod60.z.string()
|
|
6465
6692
|
})
|
|
6466
6693
|
),
|
|
6467
|
-
selectedImageId:
|
|
6468
|
-
});
|
|
6469
|
-
|
|
6470
|
-
// src/schema/postPurchaseProductReviews.ts
|
|
6471
|
-
var import_zod54 = require("zod");
|
|
6472
|
-
var decimal = import_zod54.z.union([
|
|
6473
|
-
import_zod54.z.number(),
|
|
6474
|
-
import_zod54.z.string().regex(/^\d+(?:\.\d+)?$/).transform(Number)
|
|
6475
|
-
]);
|
|
6476
|
-
var PostPurchaseCommonReviewRating = import_zod54.z.object({ value: decimal.pipe(import_zod54.z.number().min(0).max(5)) });
|
|
6477
|
-
var PostPurchaseKlaviyoReviewRating = PostPurchaseCommonReviewRating.extend({
|
|
6478
|
-
// Legacy validates key presence, then displays the raw value on five stars without rescaling.
|
|
6479
|
-
scale_max: import_zod54.z.unknown().nonoptional(),
|
|
6480
|
-
scale_min: import_zod54.z.unknown().nonoptional()
|
|
6481
|
-
});
|
|
6482
|
-
var PostPurchaseReviewCount = import_zod54.z.string().regex(/^\d+(?:\.\d+)?$/).transform(Number).pipe(import_zod54.z.number().int().nonnegative());
|
|
6483
|
-
var PostPurchaseReviewStyles = PostPurchaseSettings.shape.styles.unwrap().extend({
|
|
6484
|
-
strokeWidth: decimal.pipe(import_zod54.z.number().nonnegative()).default(1)
|
|
6485
|
-
}).prefault({});
|
|
6486
|
-
var PostPurchaseProductReviews = import_zod54.z.object({
|
|
6487
|
-
color: import_zod54.z.string(),
|
|
6488
|
-
rating: import_zod54.z.number().positive().max(5),
|
|
6489
|
-
reviewCount: import_zod54.z.number().int().nonnegative(),
|
|
6490
|
-
reviewsPlural: import_zod54.z.string(),
|
|
6491
|
-
reviewsSingular: import_zod54.z.string(),
|
|
6492
|
-
size: import_zod54.z.enum(["small", "medium", "large"]),
|
|
6493
|
-
strokeColor: import_zod54.z.string(),
|
|
6494
|
-
strokeWidth: import_zod54.z.number().nonnegative()
|
|
6694
|
+
selectedImageId: import_zod60.z.number().int().positive().optional()
|
|
6495
6695
|
});
|
|
6496
6696
|
|
|
6497
6697
|
// src/schema/postPurchaseProductDisplay.ts
|
|
6498
6698
|
var language = PostPurchaseSettings.shape.language;
|
|
6499
|
-
var PostPurchasePrimaryImageSource =
|
|
6699
|
+
var PostPurchasePrimaryImageSource = import_zod61.z.string().default(
|
|
6500
6700
|
"https://cdn.shopify.com/shopifycloud/shopify/assets/no-image-2048-5e88c1b20e087fb7bbe9a3771824e743c244f437e4f8ba93bbf7b11b53f7824c.gif"
|
|
6501
6701
|
);
|
|
6502
|
-
var PostPurchaseProductDisplay =
|
|
6702
|
+
var PostPurchaseProductDisplay = import_zod61.z.object({
|
|
6503
6703
|
descriptionDocument: TiptapDocument.optional(),
|
|
6504
6704
|
discountedFrom: PostPurchaseSettings.shape.discountedFrom,
|
|
6505
6705
|
gallery: PostPurchaseProductGallery.optional(),
|
|
6506
6706
|
language: language.pick({ description: true, descriptionEnabled: true }),
|
|
6507
|
-
primaryImage:
|
|
6707
|
+
primaryImage: import_zod61.z.object({ description: import_zod61.z.string(), source: import_zod61.z.string() }),
|
|
6508
6708
|
productOptions: PostPurchaseSettings.shape.productOptions.pick({
|
|
6509
6709
|
showDeclineAll: true,
|
|
6510
6710
|
showShipping: true,
|
|
@@ -6519,16 +6719,16 @@ var PostPurchaseProductDisplay = import_zod55.z.object({
|
|
|
6519
6719
|
});
|
|
6520
6720
|
|
|
6521
6721
|
// src/schema/postPurchaseSubscription.ts
|
|
6522
|
-
var
|
|
6523
|
-
var PostPurchaseSubscriptionTerms =
|
|
6722
|
+
var import_zod62 = require("zod");
|
|
6723
|
+
var PostPurchaseSubscriptionTerms = import_zod62.z.object({
|
|
6524
6724
|
adjustment: PostPurchasePlanAdjustment.optional(),
|
|
6525
|
-
initialShippingPrice:
|
|
6526
|
-
intervalLabel:
|
|
6527
|
-
name:
|
|
6528
|
-
recurringShippingPrice:
|
|
6529
|
-
shippingOption:
|
|
6725
|
+
initialShippingPrice: import_zod62.z.number().nonnegative(),
|
|
6726
|
+
intervalLabel: import_zod62.z.string().min(1),
|
|
6727
|
+
name: import_zod62.z.string().min(1),
|
|
6728
|
+
recurringShippingPrice: import_zod62.z.number().nonnegative(),
|
|
6729
|
+
shippingOption: import_zod62.z.object({ presentmentTitle: import_zod62.z.string(), title: import_zod62.z.string() }),
|
|
6530
6730
|
/** A switch to subscription (STS): the one subscription that charges no initial shipping (L122). */
|
|
6531
|
-
sts:
|
|
6731
|
+
sts: import_zod62.z.literal(true).optional()
|
|
6532
6732
|
});
|
|
6533
6733
|
|
|
6534
6734
|
// src/schema/postPurchaseProduct.ts
|
|
@@ -6538,52 +6738,52 @@ var PostPurchaseVariant = OfferProduct.shape.variants.element.pick({ id: true, t
|
|
|
6538
6738
|
id: PostPurchaseVariantId,
|
|
6539
6739
|
price: PostPurchaseAmount
|
|
6540
6740
|
});
|
|
6541
|
-
var PreparedPostPurchaseProduct =
|
|
6741
|
+
var PreparedPostPurchaseProduct = import_zod63.z.object({
|
|
6542
6742
|
display: PostPurchaseProductDisplay,
|
|
6543
|
-
labels:
|
|
6743
|
+
labels: import_zod63.z.object({
|
|
6544
6744
|
declineAll: global.declineAll,
|
|
6545
|
-
free:
|
|
6745
|
+
free: import_zod63.z.string(),
|
|
6546
6746
|
notAvailable: global.notAvailable,
|
|
6547
|
-
payNow:
|
|
6548
|
-
quantity:
|
|
6747
|
+
payNow: import_zod63.z.string(),
|
|
6748
|
+
quantity: import_zod63.z.string(),
|
|
6549
6749
|
recurringShipping: global.recurringShipping,
|
|
6550
6750
|
recurringSubtotal: global.recurringSubtotal,
|
|
6551
|
-
save:
|
|
6552
|
-
shipping:
|
|
6553
|
-
subtotal:
|
|
6554
|
-
taxes:
|
|
6555
|
-
total:
|
|
6751
|
+
save: import_zod63.z.string(),
|
|
6752
|
+
shipping: import_zod63.z.string(),
|
|
6753
|
+
subtotal: import_zod63.z.string(),
|
|
6754
|
+
taxes: import_zod63.z.string(),
|
|
6755
|
+
total: import_zod63.z.string()
|
|
6556
6756
|
}),
|
|
6557
6757
|
product: OfferProduct.pick({ description: true, id: true, image: true, title: true }).extend({
|
|
6558
6758
|
description: OfferProduct.shape.description.nullable(),
|
|
6559
6759
|
id: PostPurchaseProductId,
|
|
6560
6760
|
variant: PostPurchaseVariant
|
|
6561
6761
|
}),
|
|
6562
|
-
selection:
|
|
6762
|
+
selection: import_zod63.z.object({
|
|
6563
6763
|
productId: PostPurchaseProductId,
|
|
6564
|
-
quantity:
|
|
6565
|
-
sellingPlanId:
|
|
6764
|
+
quantity: import_zod63.z.number().int().positive(),
|
|
6765
|
+
sellingPlanId: import_zod63.z.number().int().positive().optional(),
|
|
6566
6766
|
variantId: PostPurchaseVariantId
|
|
6567
6767
|
}),
|
|
6568
|
-
status:
|
|
6569
|
-
terms:
|
|
6768
|
+
status: import_zod63.z.literal("prepared"),
|
|
6769
|
+
terms: import_zod63.z.object({
|
|
6570
6770
|
discount: PostPurchaseDiscount,
|
|
6571
|
-
shipping:
|
|
6572
|
-
amount:
|
|
6573
|
-
title:
|
|
6574
|
-
type:
|
|
6771
|
+
shipping: import_zod63.z.object({
|
|
6772
|
+
amount: import_zod63.z.number().nonnegative(),
|
|
6773
|
+
title: import_zod63.z.string(),
|
|
6774
|
+
type: import_zod63.z.enum(["free", "fixed_amount"])
|
|
6575
6775
|
}),
|
|
6576
6776
|
subscription: PostPurchaseSubscriptionTerms.optional()
|
|
6577
6777
|
})
|
|
6578
6778
|
});
|
|
6579
|
-
var PostPurchasePreparation =
|
|
6779
|
+
var PostPurchasePreparation = import_zod63.z.discriminatedUnion("status", [
|
|
6580
6780
|
PreparedPostPurchaseProduct,
|
|
6581
|
-
|
|
6781
|
+
import_zod63.z.object({ reason: import_zod63.z.string(), status: import_zod63.z.literal("unsupported") })
|
|
6582
6782
|
]);
|
|
6583
6783
|
|
|
6584
6784
|
// src/schema/postPurchaseSubscriptionProduct.ts
|
|
6585
6785
|
var PreparedPostPurchaseSubscription = PreparedPostPurchaseProduct.extend({
|
|
6586
|
-
selection: PreparedPostPurchaseProduct.shape.selection.extend({ sellingPlanId:
|
|
6786
|
+
selection: PreparedPostPurchaseProduct.shape.selection.extend({ sellingPlanId: import_zod64.z.number().int().positive() }),
|
|
6587
6787
|
terms: PreparedPostPurchaseProduct.shape.terms.extend({
|
|
6588
6788
|
subscription: PostPurchaseSubscriptionTerms
|
|
6589
6789
|
}).refine(
|
|
@@ -6643,7 +6843,7 @@ var subscriptionUnavailable = (normalized, plan, allowCollection, quantity3) =>
|
|
|
6643
6843
|
};
|
|
6644
6844
|
|
|
6645
6845
|
// src/server/postPurchaseProductDisplay.ts
|
|
6646
|
-
var
|
|
6846
|
+
var import_zod66 = require("zod");
|
|
6647
6847
|
|
|
6648
6848
|
// src/server/postPurchasePrimaryImage.ts
|
|
6649
6849
|
var postPurchasePrimaryImage = (product) => {
|
|
@@ -6669,7 +6869,7 @@ var postPurchaseProductGallery = (product, limit) => {
|
|
|
6669
6869
|
};
|
|
6670
6870
|
|
|
6671
6871
|
// src/transforms/postPurchase/convertDescriptionRte.ts
|
|
6672
|
-
var
|
|
6872
|
+
var import_zod65 = require("zod");
|
|
6673
6873
|
var alignments = { center: "center", left: "start", right: "end" };
|
|
6674
6874
|
var colors = ["critical", "subdued", "success", "warning"];
|
|
6675
6875
|
var sizes2 = ["extraSmall", "small", "medium", "large", "extraLarge"];
|
|
@@ -6681,19 +6881,19 @@ var spacings2 = {
|
|
|
6681
6881
|
xloose: "extraLoose",
|
|
6682
6882
|
xtight: "extraTight"
|
|
6683
6883
|
};
|
|
6684
|
-
var Block =
|
|
6685
|
-
attrs:
|
|
6686
|
-
content:
|
|
6687
|
-
type:
|
|
6688
|
-
});
|
|
6689
|
-
var Run =
|
|
6690
|
-
var Inline =
|
|
6691
|
-
attrs:
|
|
6692
|
-
color:
|
|
6693
|
-
emphasis:
|
|
6694
|
-
size:
|
|
6884
|
+
var Block = import_zod65.z.object({
|
|
6885
|
+
attrs: import_zod65.z.object({ alignment: import_zod65.z.enum(["left", "center", "right"]).optional().catch(void 0) }).catch({}),
|
|
6886
|
+
content: import_zod65.z.array(import_zod65.z.unknown()).catch([]),
|
|
6887
|
+
type: import_zod65.z.literal("ShopifyTextBlock")
|
|
6888
|
+
});
|
|
6889
|
+
var Run = import_zod65.z.object({ marks: import_zod65.z.array(import_zod65.z.unknown()).catch([]), text: import_zod65.z.string().min(1), type: import_zod65.z.literal("text") });
|
|
6890
|
+
var Inline = import_zod65.z.object({
|
|
6891
|
+
attrs: import_zod65.z.object({
|
|
6892
|
+
color: import_zod65.z.enum(colors).optional().catch(void 0),
|
|
6893
|
+
emphasis: import_zod65.z.array(import_zod65.z.unknown()).catch([]),
|
|
6894
|
+
size: import_zod65.z.enum(sizes2).optional().catch(void 0)
|
|
6695
6895
|
}),
|
|
6696
|
-
type:
|
|
6896
|
+
type: import_zod65.z.literal("ShopifyTextInline")
|
|
6697
6897
|
});
|
|
6698
6898
|
var marks = (raw) => {
|
|
6699
6899
|
const found = raw.map((mark) => Inline.safeParse(mark)).find(({ success }) => success)?.data;
|
|
@@ -6726,7 +6926,7 @@ var convertDescriptionRte = (rte, spacing) => TiptapDocument.parse({
|
|
|
6726
6926
|
});
|
|
6727
6927
|
|
|
6728
6928
|
// src/server/postPurchaseProductDisplay.ts
|
|
6729
|
-
var ResponseLanguage =
|
|
6929
|
+
var ResponseLanguage = import_zod66.z.object({ description: PostPurchaseProductDisplay.shape.responseDescription }).default({ description: "" });
|
|
6730
6930
|
var projectPostPurchaseProductDisplay = (effective, metadata, product) => PostPurchaseProductDisplay.parse({
|
|
6731
6931
|
descriptionDocument: effective.language.descriptionRte && convertDescriptionRte(effective.language.descriptionRte, effective.language.descriptionSpacing),
|
|
6732
6932
|
discountedFrom: effective.discountedFrom,
|
|
@@ -6738,146 +6938,6 @@ var projectPostPurchaseProductDisplay = (effective, metadata, product) => PostPu
|
|
|
6738
6938
|
shouldShowSavingText: effective.discount.shouldShowSavingText
|
|
6739
6939
|
});
|
|
6740
6940
|
|
|
6741
|
-
// src/server/postPurchaseReviewData.ts
|
|
6742
|
-
var import_zod65 = require("zod");
|
|
6743
|
-
|
|
6744
|
-
// src/server/postPurchaseJudgeMeReviews.ts
|
|
6745
|
-
var import_zod62 = require("zod");
|
|
6746
|
-
|
|
6747
|
-
// src/server/postPurchaseReviewFields.ts
|
|
6748
|
-
var import_zod61 = require("zod");
|
|
6749
|
-
var Field = import_zod61.z.object({ key: import_zod61.z.string(), namespace: import_zod61.z.string(), value: import_zod61.z.unknown().optional() });
|
|
6750
|
-
var reviewFields = (raw) => {
|
|
6751
|
-
const fields4 = import_zod61.z.array(import_zod61.z.unknown()).parse(raw).flatMap((field) => {
|
|
6752
|
-
const parsed = Field.safeParse(field);
|
|
6753
|
-
return parsed.success ? [parsed.data] : [];
|
|
6754
|
-
});
|
|
6755
|
-
return (namespace, key) => fields4.find((field) => field.namespace === namespace && field.key === key);
|
|
6756
|
-
};
|
|
6757
|
-
var ReviewFieldError = class extends Error {
|
|
6758
|
-
constructor(field) {
|
|
6759
|
-
super(`Unreadable review field ${field}`);
|
|
6760
|
-
this.field = field;
|
|
6761
|
-
}
|
|
6762
|
-
};
|
|
6763
|
-
var readReviewField = (field, read) => {
|
|
6764
|
-
try {
|
|
6765
|
-
return read(field.value);
|
|
6766
|
-
} catch {
|
|
6767
|
-
throw new ReviewFieldError(`${field.namespace}.${field.key}`);
|
|
6768
|
-
}
|
|
6769
|
-
};
|
|
6770
|
-
|
|
6771
|
-
// src/server/postPurchaseJudgeMeReviews.ts
|
|
6772
|
-
var readJudgeMeReviews = (find) => {
|
|
6773
|
-
const field = find("judgeme", "badge");
|
|
6774
|
-
if (!field) return null;
|
|
6775
|
-
return readReviewField(field, (value) => {
|
|
6776
|
-
const html = import_zod62.z.string().parse(value);
|
|
6777
|
-
const rating = html.match(/data-average-rating=['"](\d+(?:\.\d+)?)['"]/);
|
|
6778
|
-
const count = html.match(/data-number-of-reviews=['"](\d+)['"]/);
|
|
6779
|
-
if (!rating || !count) throw new Error("Unreadable Judge.me attributes");
|
|
6780
|
-
return {
|
|
6781
|
-
rating: PostPurchaseCommonReviewRating.parse({ value: rating[1] }).value,
|
|
6782
|
-
reviewCount: PostPurchaseReviewCount.parse(count[1])
|
|
6783
|
-
};
|
|
6784
|
-
});
|
|
6785
|
-
};
|
|
6786
|
-
|
|
6787
|
-
// src/server/postPurchaseOkendoReviews.ts
|
|
6788
|
-
var import_zod63 = require("zod");
|
|
6789
|
-
var Summary = import_zod63.z.object({
|
|
6790
|
-
reviewAverageValue: PostPurchaseCommonReviewRating.shape.value,
|
|
6791
|
-
reviewCount: import_zod63.z.union([PostPurchaseProductReviews.shape.reviewCount, PostPurchaseReviewCount])
|
|
6792
|
-
});
|
|
6793
|
-
var readOkendoReviews = (find) => {
|
|
6794
|
-
const field = find("okendo", "summaryData");
|
|
6795
|
-
if (!field) return null;
|
|
6796
|
-
const summary = readReviewField(field, (value) => Summary.parse(JSON.parse(import_zod63.z.string().parse(value))));
|
|
6797
|
-
return { rating: summary.reviewAverageValue, reviewCount: summary.reviewCount };
|
|
6798
|
-
};
|
|
6799
|
-
|
|
6800
|
-
// src/server/postPurchaseScalarReviews.ts
|
|
6801
|
-
var import_zod64 = require("zod");
|
|
6802
|
-
var readScalarReviews = (find, namespace, ratingKey, countKey) => {
|
|
6803
|
-
const rating = find(namespace, ratingKey);
|
|
6804
|
-
const count = find(namespace, countKey);
|
|
6805
|
-
if (!rating || !count) return null;
|
|
6806
|
-
return {
|
|
6807
|
-
rating: readReviewField(
|
|
6808
|
-
rating,
|
|
6809
|
-
(value) => PostPurchaseCommonReviewRating.parse({ value: import_zod64.z.string().parse(value) }).value
|
|
6810
|
-
),
|
|
6811
|
-
reviewCount: readReviewField(count, (value) => PostPurchaseReviewCount.parse(value))
|
|
6812
|
-
};
|
|
6813
|
-
};
|
|
6814
|
-
|
|
6815
|
-
// src/server/postPurchaseReviewData.ts
|
|
6816
|
-
var readStandardReviews = (find) => {
|
|
6817
|
-
const rating = find("reviews", "rating");
|
|
6818
|
-
const count = find("reviews", "rating_count");
|
|
6819
|
-
if (!rating || !count) return null;
|
|
6820
|
-
return {
|
|
6821
|
-
rating: readReviewField(rating, (raw) => {
|
|
6822
|
-
const value = import_zod65.z.string().parse(raw);
|
|
6823
|
-
return PostPurchaseCommonReviewRating.parse(/^\d+(?:\.\d+)?$/.test(value) ? { value } : JSON.parse(value)).value;
|
|
6824
|
-
}),
|
|
6825
|
-
reviewCount: readReviewField(count, (value) => PostPurchaseReviewCount.parse(value))
|
|
6826
|
-
};
|
|
6827
|
-
};
|
|
6828
|
-
var readPostPurchaseReviewData = (provider, find) => {
|
|
6829
|
-
if (provider === "yotpo") return readScalarReviews(find, "yotpo", "reviews_average", "reviews_count");
|
|
6830
|
-
if (provider === "stamped") return readScalarReviews(find, "stamped", "reviews_average", "reviews_count");
|
|
6831
|
-
if (provider === "judgeme") return readJudgeMeReviews(find);
|
|
6832
|
-
if (provider === "okendo") return readOkendoReviews(find);
|
|
6833
|
-
if (provider === "opinew") return readScalarReviews(find, "opinew_metafields", "reviews_average", "reviews_count");
|
|
6834
|
-
if (provider === "reviewsio")
|
|
6835
|
-
return readScalarReviews(find, "reviewscouk", "rating", "total") ?? readStandardReviews(find);
|
|
6836
|
-
if (provider === "loox") return readScalarReviews(find, "loox", "avg_rating", "num_reviews");
|
|
6837
|
-
if (provider === "junip") return readScalarReviews(find, "junip", "rating_average", "rating_count");
|
|
6838
|
-
const rating = find("reviews", "rating");
|
|
6839
|
-
const count = find("reviews", "rating_count");
|
|
6840
|
-
if (!rating || !count) return null;
|
|
6841
|
-
return {
|
|
6842
|
-
rating: readReviewField(
|
|
6843
|
-
rating,
|
|
6844
|
-
(value) => PostPurchaseKlaviyoReviewRating.parse(JSON.parse(import_zod65.z.string().parse(value))).value
|
|
6845
|
-
),
|
|
6846
|
-
reviewCount: readReviewField(count, (value) => PostPurchaseReviewCount.parse(value))
|
|
6847
|
-
};
|
|
6848
|
-
};
|
|
6849
|
-
|
|
6850
|
-
// src/server/postPurchaseReviewProvider.ts
|
|
6851
|
-
var import_zod66 = require("zod");
|
|
6852
|
-
var IntegrationInput = import_zod66.z.record(import_zod66.z.string(), import_zod66.z.unknown()).prefault({});
|
|
6853
|
-
var precedence = [
|
|
6854
|
-
"klaviyo",
|
|
6855
|
-
"judgeme",
|
|
6856
|
-
"junip",
|
|
6857
|
-
"loox",
|
|
6858
|
-
"okendo",
|
|
6859
|
-
"opinew",
|
|
6860
|
-
"reviewsio",
|
|
6861
|
-
"stamped",
|
|
6862
|
-
"yotpo"
|
|
6863
|
-
];
|
|
6864
|
-
var ReviewsIoFlag = import_zod66.z.preprocess((value) => {
|
|
6865
|
-
if (typeof value === "string") {
|
|
6866
|
-
const flag = value.toLowerCase();
|
|
6867
|
-
if (flag === "true" || flag === "yes") return true;
|
|
6868
|
-
if (flag === "false" || flag === "no") return false;
|
|
6869
|
-
}
|
|
6870
|
-
return value;
|
|
6871
|
-
}, PostPurchaseSettings.shape.integrations.shape.reviewsio);
|
|
6872
|
-
var selectPostPurchaseReviewProvider = (raw) => {
|
|
6873
|
-
const integrations = IntegrationInput.parse(raw);
|
|
6874
|
-
for (const provider of precedence) {
|
|
6875
|
-
const schema = provider === "reviewsio" ? ReviewsIoFlag : PostPurchaseSettings.shape.integrations.shape[provider];
|
|
6876
|
-
if (schema.parse(integrations[provider])) return provider;
|
|
6877
|
-
}
|
|
6878
|
-
return null;
|
|
6879
|
-
};
|
|
6880
|
-
|
|
6881
6941
|
// src/server/postPurchaseReviews.ts
|
|
6882
6942
|
var projectPostPurchaseReviews = (settings, { id: productId2, metafields }, report) => {
|
|
6883
6943
|
try {
|