@rebuy/rebuy 3.26.0 → 3.28.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.
Files changed (51) hide show
  1. package/dist/index.cjs +902 -750
  2. package/dist/index.mjs +901 -749
  3. package/dist/schema/checkout-and-beyond/constants.cjs +5 -0
  4. package/dist/schema/checkout-and-beyond/constants.mjs +5 -0
  5. package/dist/schema/checkout-and-beyond/index.cjs +97 -68
  6. package/dist/schema/checkout-and-beyond/index.mjs +97 -68
  7. package/dist/schema/index.d.ts +6 -0
  8. package/dist/schema/postPurchaseEligibility.d.ts +2 -2
  9. package/dist/schema/postPurchaseExitPolicy.d.ts +20 -0
  10. package/dist/schema/postPurchaseIdentity.d.ts +9 -0
  11. package/dist/schema/postPurchaseOrderDecision.d.ts +10 -0
  12. package/dist/schema/postPurchasePolicy.d.ts +62 -0
  13. package/dist/schema/postPurchaseSelection.d.ts +29 -0
  14. package/dist/schema/postPurchaseSession.d.ts +112 -0
  15. package/dist/schema/postPurchaseSessionClose.d.ts +25 -0
  16. package/dist/schema/postPurchaseShadow.d.ts +56 -1
  17. package/dist/schema/postPurchaseSkipTrace.d.ts +2 -2
  18. package/dist/schema/widget-data.cjs +160 -135
  19. package/dist/schema/widget-data.mjs +160 -135
  20. package/dist/schema/widgetData.d.ts +24 -0
  21. package/dist/schema/widgets/checkout-and-beyond/banner.d.ts +8 -0
  22. package/dist/schema/widgets/checkout-and-beyond/carousel.d.ts +8 -0
  23. package/dist/schema/widgets/checkout-and-beyond/cartLine.d.ts +8 -0
  24. package/dist/schema/widgets/checkout-and-beyond/common.d.ts +13 -1
  25. package/dist/schema/widgets/checkout-and-beyond/index.d.ts +1 -0
  26. package/dist/schema/widgets/checkout-and-beyond/layout.d.ts +17 -1
  27. package/dist/schema/widgets/checkout-and-beyond/offers.d.ts +8 -0
  28. package/dist/schema/widgets/checkout-and-beyond/progressBar.d.ts +8 -0
  29. package/dist/schema/widgets/checkout-and-beyond/reviews.d.ts +2 -0
  30. package/dist/schema/widgets/checkout-and-beyond/root.d.ts +8 -0
  31. package/dist/schema/widgets/checkout-and-beyond/separator.d.ts +192 -0
  32. package/dist/schema/widgets/checkout-and-beyond/shared.d.ts +2 -1
  33. package/dist/schema/widgets/contentBlock.d.ts +8 -0
  34. package/dist/schema/widgets/lineItemEditor.d.ts +8 -0
  35. package/dist/schema/widgets/post-purchase-offer/constants.d.ts +2 -2
  36. package/dist/schema/widgets/rebuyButton.d.ts +8 -0
  37. package/dist/server/index.cjs +601 -188
  38. package/dist/server/index.mjs +601 -188
  39. package/dist/server/requestSchemas.d.ts +1 -1
  40. package/dist/transforms/index.cjs +481 -59
  41. package/dist/transforms/index.d.ts +2 -0
  42. package/dist/transforms/index.mjs +481 -59
  43. package/dist/transforms/postPurchase/convertCalloutBlock.d.ts +8 -0
  44. package/dist/transforms/postPurchase/convertMessagePreview.d.ts +8 -0
  45. package/dist/transforms/postPurchase/convertPayButtonBlock.d.ts +4 -0
  46. package/dist/transforms/postPurchase/convertSeparatorBlock.d.ts +4 -0
  47. package/dist/transforms/postPurchase/convertTextBlock.d.ts +4 -0
  48. package/dist/transforms/postPurchase/convertTimerBlock.d.ts +4 -0
  49. package/dist/transforms/postPurchase/styledTextRun.d.ts +3 -0
  50. package/dist/transforms/postPurchase/types.d.ts +8 -0
  51. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  // src/schema/widgets/checkout-and-beyond/banner.ts
2
- import { z as z20 } from "zod";
2
+ import { z as z21 } from "zod";
3
3
 
4
4
  // src/schema/widgets/checkout-and-beyond/common.ts
5
5
  var freezeEnum = (values) => Object.freeze(Object.fromEntries(values.map((v) => [v, v])));
@@ -108,6 +108,8 @@ var languageKeys = [
108
108
  "zh"
109
109
  ];
110
110
  var LanguageKey = freezeEnum(languageKeys);
111
+ var layoutFrames = ["callout", "offer-content"];
112
+ var LayoutFrame = freezeEnum(layoutFrames);
111
113
  var mutatorEvents = ["item_added", "quantity_changed", "variant_selected"];
112
114
  var MutatorEvent = freezeEnum(mutatorEvents);
113
115
  var objectFits = ["cover", "contain"];
@@ -152,6 +154,7 @@ var sectionTypes = [
152
154
  "progressBar",
153
155
  "quantity",
154
156
  "reviews",
157
+ "separator",
155
158
  "text",
156
159
  "variants"
157
160
  ];
@@ -205,11 +208,11 @@ var widgetTypes = [
205
208
  var WidgetType = freezeEnum(widgetTypes);
206
209
 
207
210
  // src/schema/widgets/checkout-and-beyond/layout.ts
208
- import { v7 as uuidv712 } from "uuid";
209
- import { z as z19 } from "zod";
211
+ import { v7 as uuidv713 } from "uuid";
212
+ import { z as z20 } from "zod";
210
213
 
211
214
  // src/schema/widgets/checkout-and-beyond/shared.ts
212
- import { z as z18 } from "zod";
215
+ import { z as z19 } from "zod";
213
216
 
214
217
  // src/schema/widgets/checkout-and-beyond/button.ts
215
218
  import { v7 as uuidv73 } from "uuid";
@@ -1358,35 +1361,46 @@ var CABReviewsSection = z16.object({
1358
1361
  name: z16.string().optional(),
1359
1362
  sectionId: z16.uuid().default(() => uuidv710()),
1360
1363
  sectionType: z16.literal(SectionType.reviews).default(SectionType.reviews),
1361
- size: z16.enum(reviewsSizes).default(ReviewsSize.default)
1364
+ size: z16.enum(reviewsSizes).default(ReviewsSize.default),
1365
+ strokeColor: z16.string().default("#fadb14"),
1366
+ strokeWidth: z16.number().nonnegative().default(0)
1362
1367
  });
1363
1368
 
1364
- // src/schema/widgets/checkout-and-beyond/variants.ts
1365
- import { slice } from "es-toolkit/compat";
1369
+ // src/schema/widgets/checkout-and-beyond/separator.ts
1366
1370
  import { v7 as uuidv711 } from "uuid";
1367
1371
  import { z as z17 } from "zod";
1368
- var CABVariantsSection = z17.object({
1372
+ var CABSeparatorSection = z17.object({
1369
1373
  ...CABVariableFields,
1370
- hideOutOfStockVariants: z17.boolean().default(false),
1371
- name: z17.string().optional(),
1372
1374
  sectionId: z17.uuid().default(() => uuidv711()),
1373
- sectionType: z17.literal(SectionType.variants).default(SectionType.variants),
1374
- selector: z17.enum(slice(variantSelectors, 0, 3)).default(VariantSelector.menu),
1375
- variantMode: z17.enum(variantModes).default(VariantMode.multiple)
1375
+ sectionType: z17.literal(SectionType.separator).default(SectionType.separator)
1376
+ });
1377
+
1378
+ // src/schema/widgets/checkout-and-beyond/variants.ts
1379
+ import { slice } from "es-toolkit/compat";
1380
+ import { v7 as uuidv712 } from "uuid";
1381
+ import { z as z18 } from "zod";
1382
+ var CABVariantsSection = z18.object({
1383
+ ...CABVariableFields,
1384
+ hideOutOfStockVariants: z18.boolean().default(false),
1385
+ name: z18.string().optional(),
1386
+ sectionId: z18.uuid().default(() => uuidv712()),
1387
+ sectionType: z18.literal(SectionType.variants).default(SectionType.variants),
1388
+ selector: z18.enum(slice(variantSelectors, 0, 3)).default(VariantSelector.menu),
1389
+ variantMode: z18.enum(variantModes).default(VariantMode.multiple)
1376
1390
  });
1377
1391
 
1378
1392
  // src/schema/widgets/checkout-and-beyond/shared.ts
1379
- var CABBorder = z18.object({
1380
- radius: z18.enum(borderRadii).default(BorderRadius.base),
1381
- style: z18.enum(borderStyles).default(BorderStyle.none),
1382
- width: z18.enum(borderWidths).default(BorderWidth.base)
1393
+ var CABBorder = z19.object({
1394
+ radius: z19.enum(borderRadii).default(BorderRadius.base),
1395
+ style: z19.enum(borderStyles).default(BorderStyle.none),
1396
+ width: z19.enum(borderWidths).default(BorderWidth.base)
1383
1397
  }).default({
1384
1398
  radius: BorderRadius.base,
1385
1399
  style: BorderStyle.none,
1386
1400
  width: BorderWidth.base
1387
1401
  });
1388
- var CABSection = z18.lazy(
1389
- () => z18.discriminatedUnion("sectionType", [
1402
+ var CABSection = z19.lazy(
1403
+ () => z19.discriminatedUnion("sectionType", [
1390
1404
  CABBannerSection,
1391
1405
  CABButtonSection,
1392
1406
  CABCarouselSection,
@@ -1402,46 +1416,57 @@ var CABSection = z18.lazy(
1402
1416
  CABProgressBarSection,
1403
1417
  CABQuantitySection,
1404
1418
  CABReviewsSection,
1419
+ CABSeparatorSection,
1405
1420
  CABTextSection,
1406
1421
  CABVariantsSection
1407
1422
  ])
1408
1423
  );
1409
1424
 
1410
1425
  // src/schema/widgets/checkout-and-beyond/layout.ts
1411
- var GridItem = z19.union([z19.literal("auto"), z19.literal("fill"), z19.string().regex(/^\d+%$/), z19.number()]);
1412
- var CABLayoutSection = z19.object({
1426
+ var GridItem = z20.union([z20.literal("auto"), z20.literal("fill"), z20.string().regex(/^\d+%$/), z20.number()]);
1427
+ var CABLayoutWrapping = z20.object({
1428
+ breakAt: z20.number().positive(),
1429
+ maxPerLine: z20.number().int().positive()
1430
+ });
1431
+ var CABLayoutSection = z20.object({
1413
1432
  ...CABVariableFields,
1414
- alignment: z19.object({
1415
- horizontal: z19.enum(horizontalAlignments).default(HorizontalAlignment.start),
1416
- vertical: z19.enum(verticalAlignments).default(VerticalAlignment.top)
1433
+ alignment: z20.object({
1434
+ horizontal: z20.enum(horizontalAlignments).default(HorizontalAlignment.start),
1435
+ vertical: z20.enum(verticalAlignments).default(VerticalAlignment.top)
1417
1436
  }).default({
1418
1437
  horizontal: HorizontalAlignment.start,
1419
1438
  vertical: VerticalAlignment.top
1420
1439
  }),
1421
- border: z19.lazy(() => CABBorder),
1422
- buttonField: z19.enum(buttonFields).optional(),
1423
- direction: z19.enum(directions).default(Direction.rows),
1424
- grid: z19.object({
1425
- columns: z19.union([z19.array(GridItem), z19.undefined()]).default(() => ["auto"]),
1426
- rows: z19.union([z19.array(GridItem), z19.undefined()]).default(() => ["auto"])
1440
+ border: z20.lazy(() => CABBorder),
1441
+ buttonField: z20.enum(buttonFields).optional(),
1442
+ direction: z20.enum(directions).default(Direction.rows),
1443
+ /**
1444
+ * Platform chrome around the section, not a layout behavior: `callout` is a subdued box with block borders
1445
+ * (the legacy post-purchase callout banner), `offer-content` the post-purchase offer's own content card.
1446
+ */
1447
+ frame: z20.enum(layoutFrames).optional(),
1448
+ grid: z20.object({
1449
+ columns: z20.union([z20.array(GridItem), z20.undefined()]).default(() => ["auto"]),
1450
+ rows: z20.union([z20.array(GridItem), z20.undefined()]).default(() => ["auto"])
1427
1451
  }).default({ columns: ["auto"], rows: ["auto"] }).optional(),
1428
- name: z19.string().optional(),
1429
- padding: z19.enum(spacings).default(Spacing.none),
1430
- sectionId: z19.uuid().default(() => uuidv712()),
1431
- sections: z19.union([z19.array(z19.lazy(() => CABSection)), z19.strictObject({}).transform(() => [])]).default(() => []),
1432
- sectionType: z19.literal(SectionType.layout).default(SectionType.layout),
1433
- spacing: z19.enum(spacings).default(Spacing.base),
1452
+ name: z20.string().optional(),
1453
+ padding: z20.enum(spacings).default(Spacing.none),
1454
+ sectionId: z20.uuid().default(() => uuidv713()),
1455
+ sections: z20.union([z20.array(z20.lazy(() => CABSection)), z20.strictObject({}).transform(() => [])]).default(() => []),
1456
+ sectionType: z20.literal(SectionType.layout).default(SectionType.layout),
1457
+ spacing: z20.enum(spacings).default(Spacing.base),
1434
1458
  /** Fire-and-forget impression pixel POSTed once when the section is shown (e.g. a Monetize offer view). */
1435
- viewUrl: z19.string().optional(),
1436
- width: z19.number().default(100)
1459
+ viewUrl: z20.string().optional(),
1460
+ width: z20.number().default(100),
1461
+ wrapping: CABLayoutWrapping.optional()
1437
1462
  });
1438
1463
 
1439
1464
  // src/schema/widgets/checkout-and-beyond/banner.ts
1440
- var CABBannerSection = z20.lazy(
1465
+ var CABBannerSection = z21.lazy(
1441
1466
  () => CABLayoutSection.omit({ sectionType: true }).extend({
1442
- buttonField: z20.enum(buttonFields).optional(),
1443
- color: z20.enum(bannerColors).default("info"),
1444
- dismissible: z20.boolean().default(true),
1467
+ buttonField: z21.enum(buttonFields).optional(),
1468
+ color: z21.enum(bannerColors).default("info"),
1469
+ dismissible: z21.boolean().default(true),
1445
1470
  /**
1446
1471
  * The `s-banner` heading — localized content (a buyer can see a merchant-composed banner). Absent OR
1447
1472
  * blank ⇒ no heading; the renderer emits no heading slot for `''` rather than an empty one.
@@ -1457,8 +1482,8 @@ var CABBannerSection = z20.lazy(
1457
1482
  * not a 500. Nothing emits `heading` yet; the first converter that maps merchant banner copy into it
1458
1483
  * either strips first or teaches `normalizeTextContent` to strip this field.
1459
1484
  */
1460
- heading: z20.record(z20.string(), z20.string().refine(checkForHTML, NO_HTML)).optional(),
1461
- sectionType: z20.literal(SectionType.banner).default(SectionType.banner)
1485
+ heading: z21.record(z21.string(), z21.string().refine(checkForHTML, NO_HTML)).optional(),
1486
+ sectionType: z21.literal(SectionType.banner).default(SectionType.banner)
1462
1487
  })
1463
1488
  );
1464
1489
 
@@ -1695,7 +1720,7 @@ var OFFER_LABELS = {
1695
1720
  };
1696
1721
 
1697
1722
  // src/schema/widgets/checkout-and-beyond/root.ts
1698
- import { z as z21 } from "zod";
1723
+ import { z as z22 } from "zod";
1699
1724
 
1700
1725
  // src/schema/widgets/checkout-and-beyond/uiLabels.ts
1701
1726
  var UI_LABELS = {
@@ -1715,8 +1740,8 @@ var UI_LABELS = {
1715
1740
  };
1716
1741
 
1717
1742
  // src/schema/widgets/checkout-and-beyond/root.ts
1718
- var localized = (fallback) => z21.record(z21.string(), z21.string()).default(() => ({ ...fallback })).transform((labels) => Object.keys(labels).length > 0 ? labels : { ...fallback });
1719
- var CABUILabels = z21.object({
1743
+ var localized = (fallback) => z22.record(z22.string(), z22.string()).default(() => ({ ...fallback })).transform((labels) => Object.keys(labels).length > 0 ? labels : { ...fallback });
1744
+ var CABUILabels = z22.object({
1720
1745
  currentPage: localized(UI_LABELS.currentPage),
1721
1746
  guest: localized(UI_LABELS.guest),
1722
1747
  loadingOptions: localized(UI_LABELS.loadingOptions),
@@ -1741,37 +1766,37 @@ var CABUILabels = z21.object({
1741
1766
  subscriptionOptions: { ...UI_LABELS.subscriptionOptions },
1742
1767
  updating: { ...UI_LABELS.updating }
1743
1768
  }));
1744
- var TargetArea = z21.object({
1745
- fill: z21.boolean().optional(),
1746
- flip: z21.enum(["both", "horizontal", "vertical"]).optional(),
1747
- icon: z21.string(),
1748
- label: z21.string(),
1749
- width: z21.string()
1769
+ var TargetArea = z22.object({
1770
+ fill: z22.boolean().optional(),
1771
+ flip: z22.enum(["both", "horizontal", "vertical"]).optional(),
1772
+ icon: z22.string(),
1773
+ label: z22.string(),
1774
+ width: z22.string()
1750
1775
  }).default(targetAreas[EditorMode.checkoutExtension][1]);
1751
- var CABTracking = z21.object({
1752
- enableAttribution: z21.boolean().nullish().transform((value) => value ?? true),
1753
- enableSource: z21.boolean().nullish().transform((value) => value ?? true),
1754
- enableWidget: z21.boolean().nullish().transform((value) => value ?? true)
1776
+ var CABTracking = z22.object({
1777
+ enableAttribution: z22.boolean().nullish().transform((value) => value ?? true),
1778
+ enableSource: z22.boolean().nullish().transform((value) => value ?? true),
1779
+ enableWidget: z22.boolean().nullish().transform((value) => value ?? true)
1755
1780
  }).nullish().transform((value) => value ?? { enableAttribution: true, enableSource: true, enableWidget: true });
1756
- var CABExperiment = z21.object({
1757
- elementId: z21.number(),
1758
- experimentId: z21.number(),
1759
- experimentType: z21.string(),
1760
- selectedId: z21.number()
1781
+ var CABExperiment = z22.object({
1782
+ elementId: z22.number(),
1783
+ experimentId: z22.number(),
1784
+ experimentType: z22.string(),
1785
+ selectedId: z22.number()
1761
1786
  });
1762
1787
  var CABRootSection = CABLayoutSection.extend({
1763
- editorMode: z21.enum(editorModes).default(EditorMode.checkoutExtension),
1788
+ editorMode: z22.enum(editorModes).default(EditorMode.checkoutExtension),
1764
1789
  experiment: CABExperiment.optional(),
1765
1790
  // Same rule as CABTracking above: the v1 converters pass raw legacy `previewMode` through, so a
1766
1791
  // `null` must fall back rather than throw the widget; malformed values still throw.
1767
- previewMode: z21.boolean().nullish().transform((value) => value ?? false),
1768
- storeId: z21.number().nullable().default(null),
1792
+ previewMode: z22.boolean().nullish().transform((value) => value ?? false),
1793
+ storeId: z22.number().nullable().default(null),
1769
1794
  targetArea: TargetArea.nullable(),
1770
1795
  tracking: CABTracking,
1771
- type: z21.enum(widgetTypes).default(WidgetType.ui_extension_content_block),
1796
+ type: z22.enum(widgetTypes).default(WidgetType.ui_extension_content_block),
1772
1797
  uiLabels: CABUILabels,
1773
- version: z21.literal(2).default(2),
1774
- widgetId: z21.number().nullable().default(null)
1798
+ version: z22.literal(2).default(2),
1799
+ widgetId: z22.number().nullable().default(null)
1775
1800
  });
1776
1801
 
1777
1802
  // src/schema/widgets/checkout-and-beyond/switchLabels.ts
@@ -1915,6 +1940,7 @@ export {
1915
1940
  CABImageSectionFields,
1916
1941
  CABIntegrations,
1917
1942
  CABLayoutSection,
1943
+ CABLayoutWrapping,
1918
1944
  CABMonetizeAds,
1919
1945
  CABMonetizeSection,
1920
1946
  CABNumberVariable,
@@ -1932,6 +1958,7 @@ export {
1932
1958
  CABRuleset,
1933
1959
  CABRulesetEntry,
1934
1960
  CABSection,
1961
+ CABSeparatorSection,
1935
1962
  CABTextSection,
1936
1963
  CABTextTier,
1937
1964
  CABTextVariable,
@@ -1966,6 +1993,7 @@ export {
1966
1993
  IconTone,
1967
1994
  InlineTextSizeName,
1968
1995
  LanguageKey,
1996
+ LayoutFrame,
1969
1997
  MutatorEvent,
1970
1998
  NO_HTML,
1971
1999
  OFFER_LABELS,
@@ -2044,6 +2072,7 @@ export {
2044
2072
  isTextType,
2045
2073
  isVariantsType,
2046
2074
  languageKeys,
2075
+ layoutFrames,
2047
2076
  mutatorEvents,
2048
2077
  objectFits,
2049
2078
  offersDirections,
@@ -2,7 +2,13 @@ export * from './cabShopConfig';
2
2
  export * from './metadata';
3
3
  export * from './offerProduct';
4
4
  export * from './postPurchaseEligibility';
5
+ export * from './postPurchaseExitPolicy';
5
6
  export * from './postPurchaseIdentity';
7
+ export * from './postPurchaseOrderDecision';
8
+ export * from './postPurchasePolicy';
9
+ export * from './postPurchaseSelection';
10
+ export * from './postPurchaseSession';
11
+ export * from './postPurchaseSessionClose';
6
12
  export * from './postPurchaseShadow';
7
13
  export * from './postPurchaseSkipTrace';
8
14
  export * from './product';
@@ -5,8 +5,8 @@ import { z } from 'zod';
5
5
  * — that half is Offer/product-specific and stays out of this Slice. Only the skip-reason vocabulary a
6
6
  * skip trace records travels with the Decision contract.
7
7
  */
8
- export declare const PostPurchaseSkipReason: z.ZodEnum<{
8
+ export declare const PostPurchaseSkipReasonSchema: z.ZodEnum<{
9
9
  empty: "empty";
10
10
  "no-eligible-subscription": "no-eligible-subscription";
11
11
  }>;
12
- export type PostPurchaseSkipReason = z.infer<typeof PostPurchaseSkipReason>;
12
+ export type PostPurchaseSkipReason = z.infer<typeof PostPurchaseSkipReasonSchema>;
@@ -0,0 +1,20 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Whether an additional delay applies when the session's client leaves after close, and why — projected
4
+ * from the admitted purchase's snapshot when one exists, else from the selected Flow. `unavailable` when
5
+ * neither could be resolved; a failed projection never undoes closure or blocks the purchase it followed.
6
+ *
7
+ * Both branches are `.strict()`: a producer that resolved a real delay but mis-set `status` must get a
8
+ * 4xx, not have `delayMs`/`source` silently stripped down to a bare `{ status: 'unavailable' }`.
9
+ */
10
+ export declare const ExitPolicySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
11
+ status: z.ZodLiteral<"unavailable">;
12
+ }, z.core.$strict>, z.ZodObject<{
13
+ delayMs: z.ZodNumber;
14
+ source: z.ZodEnum<{
15
+ admitted: "admitted";
16
+ "selected-flow": "selected-flow";
17
+ }>;
18
+ status: z.ZodLiteral<"available">;
19
+ }, z.core.$strict>], "status">;
20
+ export type ExitPolicy = z.infer<typeof ExitPolicySchema>;
@@ -1,11 +1,14 @@
1
1
  import { z } from 'zod';
2
2
  export declare const PostPurchaseTimestampSchema: z.ZodNumber;
3
3
  export declare const PostPurchaseOrderIdSchema: z.ZodString;
4
+ /** Expects a pre-lowercased domain — Shopify shop slugs are always lowercase, so this doesn't normalize case. */
4
5
  export declare const ShopifyDomainSchema: z.ZodString;
5
6
  export declare const DecideRequestSchema: z.ZodObject<{
6
7
  checkoutToken: z.ZodString;
7
8
  shop: z.ZodString;
8
9
  }, z.core.$strip>;
10
+ /** Shared with any post-purchase contract that carries the id of the app that opened it. */
11
+ export declare const PostPurchaseAppIdSchema: z.ZodString;
9
12
  /** A Decision entry: which Flow and node in its tree, which Split (widgetTraffic share) and Widget won. */
10
13
  export declare const DecisionEntrySchema: z.ZodObject<{
11
14
  blockId: z.ZodNumber;
@@ -16,3 +19,9 @@ export declare const DecisionEntrySchema: z.ZodObject<{
16
19
  widgetId: z.ZodNumber;
17
20
  widgetTraffic: z.ZodNumber;
18
21
  }, z.core.$strip>;
22
+ export type DecideRequest = z.infer<typeof DecideRequestSchema>;
23
+ export type DecisionEntry = z.infer<typeof DecisionEntrySchema>;
24
+ export type PostPurchaseAppId = z.infer<typeof PostPurchaseAppIdSchema>;
25
+ export type PostPurchaseOrderId = z.infer<typeof PostPurchaseOrderIdSchema>;
26
+ export type PostPurchaseTimestamp = z.infer<typeof PostPurchaseTimestampSchema>;
27
+ export type ShopifyDomain = z.infer<typeof ShopifyDomainSchema>;
@@ -0,0 +1,10 @@
1
+ import { z } from 'zod';
2
+ /** Which side may still write this order's session-decision row: the session that claimed it first, or the release-authority sweep once nothing claims it. */
3
+ export declare const OrderDecisionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
4
+ owner: z.ZodLiteral<"session">;
5
+ sessionId: z.ZodString;
6
+ }, z.core.$strip>, z.ZodObject<{
7
+ owner: z.ZodLiteral<"release">;
8
+ sessionId: z.ZodNull;
9
+ }, z.core.$strip>], "owner">;
10
+ export type OrderDecision = z.infer<typeof OrderDecisionSchema>;
@@ -0,0 +1,62 @@
1
+ import { z } from 'zod';
2
+ export declare const HoldSettingSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
3
+ durationMinutes: z.ZodNumber;
4
+ enabled: z.ZodLiteral<true>;
5
+ }, z.core.$strip>, z.ZodObject<{
6
+ durationMinutes: z.ZodNull;
7
+ enabled: z.ZodLiteral<false>;
8
+ }, z.core.$strip>], "enabled">;
9
+ /** What the shop and its Flow each configure for the post-purchase hold, before either is applied. */
10
+ export declare const TimingSettingsSchema: z.ZodObject<{
11
+ flowHold: z.ZodDiscriminatedUnion<[z.ZodObject<{
12
+ durationMinutes: z.ZodNumber;
13
+ enabled: z.ZodLiteral<true>;
14
+ }, z.core.$strip>, z.ZodObject<{
15
+ durationMinutes: z.ZodNull;
16
+ enabled: z.ZodLiteral<false>;
17
+ }, z.core.$strip>], "enabled">;
18
+ shopHold: z.ZodDiscriminatedUnion<[z.ZodObject<{
19
+ durationMinutes: z.ZodNumber;
20
+ enabled: z.ZodLiteral<true>;
21
+ }, z.core.$strip>, z.ZodObject<{
22
+ durationMinutes: z.ZodNull;
23
+ enabled: z.ZodLiteral<false>;
24
+ }, z.core.$strip>], "enabled">;
25
+ }, z.core.$strip>;
26
+ /**
27
+ * The hold resolved for one session, captured once and never recomputed: the shop hold overrides the
28
+ * Flow hold, which overrides the native (order-only) deadline. `sessionDeadline` still takes the earlier
29
+ * of the estimated native deadline and `startedAt + durationMinutes`, so a configured hold only ever
30
+ * shortens the window, never extends it past the native estimate.
31
+ *
32
+ * The refine below enforces that precedence rather than merely documenting it: `source` and
33
+ * `durationMinutes` must match whichever hold the shop-over-flow-over-native rule actually selects, so a
34
+ * snapshot claiming `source: 'flow'` while the shop hold is enabled — or carrying a duration under
35
+ * `source: 'native'` — can't parse. Since a resolved snapshot is captured once and never recomputed, a
36
+ * contradictory one would otherwise stay durable for the session's whole lifetime.
37
+ */
38
+ export declare const SessionPolicySchema: z.ZodObject<{
39
+ flowHold: z.ZodDiscriminatedUnion<[z.ZodObject<{
40
+ durationMinutes: z.ZodNumber;
41
+ enabled: z.ZodLiteral<true>;
42
+ }, z.core.$strip>, z.ZodObject<{
43
+ durationMinutes: z.ZodNull;
44
+ enabled: z.ZodLiteral<false>;
45
+ }, z.core.$strip>], "enabled">;
46
+ shopHold: z.ZodDiscriminatedUnion<[z.ZodObject<{
47
+ durationMinutes: z.ZodNumber;
48
+ enabled: z.ZodLiteral<true>;
49
+ }, z.core.$strip>, z.ZodObject<{
50
+ durationMinutes: z.ZodNull;
51
+ enabled: z.ZodLiteral<false>;
52
+ }, z.core.$strip>], "enabled">;
53
+ durationMinutes: z.ZodNullable<z.ZodNumber>;
54
+ source: z.ZodEnum<{
55
+ shop: "shop";
56
+ flow: "flow";
57
+ native: "native";
58
+ }>;
59
+ }, z.core.$strip>;
60
+ export type HoldSetting = z.infer<typeof HoldSettingSchema>;
61
+ export type TimingSettings = z.infer<typeof TimingSettingsSchema>;
62
+ export type SessionPolicy = z.infer<typeof SessionPolicySchema>;
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Selection evidence only — a distinct issuer and purpose from Shopify's own post-purchase token or from
4
+ * purchase admission, so a selection claim can never be replayed as either.
5
+ */
6
+ export declare const SelectionClaimsSchema: z.ZodObject<{
7
+ checkoutToken: z.ZodString;
8
+ shop: z.ZodString;
9
+ appId: z.ZodString;
10
+ entry: z.ZodObject<{
11
+ blockId: z.ZodNumber;
12
+ blockIndex: z.ZodString;
13
+ blockParentIndex: z.ZodString;
14
+ flowId: z.ZodNumber;
15
+ sectionId: z.ZodNumber;
16
+ widgetId: z.ZodNumber;
17
+ widgetTraffic: z.ZodNumber;
18
+ }, z.core.$strip>;
19
+ iss: z.ZodLiteral<"rebuy-api">;
20
+ purpose: z.ZodLiteral<"post-purchase-selection">;
21
+ }, z.core.$strip>;
22
+ /** What starts a session: the checkout identity, plus a selection token carried forward from `shouldRender`. */
23
+ export declare const SessionStartRequestSchema: z.ZodObject<{
24
+ checkoutToken: z.ZodString;
25
+ shop: z.ZodString;
26
+ selectionToken: z.ZodOptional<z.ZodString>;
27
+ }, z.core.$strict>;
28
+ export type SelectionClaims = z.infer<typeof SelectionClaimsSchema>;
29
+ export type SessionStartRequest = z.infer<typeof SessionStartRequestSchema>;
@@ -0,0 +1,112 @@
1
+ import { z } from 'zod';
2
+ /** One checkout's session identity — the Decide identity plus which app opened it. */
3
+ export declare const SessionIdentitySchema: z.ZodObject<{
4
+ checkoutToken: z.ZodString;
5
+ shop: z.ZodString;
6
+ appId: z.ZodString;
7
+ }, z.core.$strip>;
8
+ /** The order this session anchors to, and the source its native-deadline estimate came from. */
9
+ export declare const SessionOrderTimingSchema: z.ZodObject<{
10
+ nativeDeadline: z.ZodNumber;
11
+ orderCreatedAt: z.ZodNumber;
12
+ orderId: z.ZodString;
13
+ timingSource: z.ZodLiteral<"shopify-order-created-at">;
14
+ }, z.core.$strip>;
15
+ /**
16
+ * A session once every field that gates rendering — order anchor, entry, policy, deadline — is set. The
17
+ * three refines enforce the only ordering that makes a session coherent: it can't start before the order
18
+ * it anchors to was created, its resolved deadline can't sit before the moment it started, and — per the
19
+ * "only ever shortens the window" invariant `postPurchasePolicy.ts` documents — that deadline can never
20
+ * exceed the native (order-only) one.
21
+ */
22
+ export declare const ReadySessionTimingSchema: z.ZodObject<{
23
+ nativeDeadline: z.ZodNumber;
24
+ orderCreatedAt: z.ZodNumber;
25
+ orderId: z.ZodString;
26
+ timingSource: z.ZodLiteral<"shopify-order-created-at">;
27
+ deadline: z.ZodNumber;
28
+ entry: z.ZodObject<{
29
+ blockId: z.ZodNumber;
30
+ blockIndex: z.ZodString;
31
+ blockParentIndex: z.ZodString;
32
+ flowId: z.ZodNumber;
33
+ sectionId: z.ZodNumber;
34
+ widgetId: z.ZodNumber;
35
+ widgetTraffic: z.ZodNumber;
36
+ }, z.core.$strip>;
37
+ policySnapshot: z.ZodObject<{
38
+ flowHold: z.ZodDiscriminatedUnion<[z.ZodObject<{
39
+ durationMinutes: z.ZodNumber;
40
+ enabled: z.ZodLiteral<true>;
41
+ }, z.core.$strip>, z.ZodObject<{
42
+ durationMinutes: z.ZodNull;
43
+ enabled: z.ZodLiteral<false>;
44
+ }, z.core.$strip>], "enabled">;
45
+ shopHold: z.ZodDiscriminatedUnion<[z.ZodObject<{
46
+ durationMinutes: z.ZodNumber;
47
+ enabled: z.ZodLiteral<true>;
48
+ }, z.core.$strip>, z.ZodObject<{
49
+ durationMinutes: z.ZodNull;
50
+ enabled: z.ZodLiteral<false>;
51
+ }, z.core.$strip>], "enabled">;
52
+ durationMinutes: z.ZodNullable<z.ZodNumber>;
53
+ source: z.ZodEnum<{
54
+ shop: "shop";
55
+ flow: "flow";
56
+ native: "native";
57
+ }>;
58
+ }, z.core.$strip>;
59
+ startedAt: z.ZodNumber;
60
+ }, z.core.$strip>;
61
+ /** The `/session/start` response: not purchase admission, just the recorded native timing. */
62
+ export declare const SessionStartResponseSchema: z.ZodObject<{
63
+ data: z.ZodObject<{
64
+ phase: z.ZodLiteral<"render">;
65
+ serverNow: z.ZodNumber;
66
+ session: z.ZodObject<{
67
+ nativeDeadline: z.ZodNumber;
68
+ orderCreatedAt: z.ZodNumber;
69
+ orderId: z.ZodString;
70
+ timingSource: z.ZodLiteral<"shopify-order-created-at">;
71
+ deadline: z.ZodNumber;
72
+ entry: z.ZodObject<{
73
+ blockId: z.ZodNumber;
74
+ blockIndex: z.ZodString;
75
+ blockParentIndex: z.ZodString;
76
+ flowId: z.ZodNumber;
77
+ sectionId: z.ZodNumber;
78
+ widgetId: z.ZodNumber;
79
+ widgetTraffic: z.ZodNumber;
80
+ }, z.core.$strip>;
81
+ policySnapshot: z.ZodObject<{
82
+ flowHold: z.ZodDiscriminatedUnion<[z.ZodObject<{
83
+ durationMinutes: z.ZodNumber;
84
+ enabled: z.ZodLiteral<true>;
85
+ }, z.core.$strip>, z.ZodObject<{
86
+ durationMinutes: z.ZodNull;
87
+ enabled: z.ZodLiteral<false>;
88
+ }, z.core.$strip>], "enabled">;
89
+ shopHold: z.ZodDiscriminatedUnion<[z.ZodObject<{
90
+ durationMinutes: z.ZodNumber;
91
+ enabled: z.ZodLiteral<true>;
92
+ }, z.core.$strip>, z.ZodObject<{
93
+ durationMinutes: z.ZodNull;
94
+ enabled: z.ZodLiteral<false>;
95
+ }, z.core.$strip>], "enabled">;
96
+ durationMinutes: z.ZodNullable<z.ZodNumber>;
97
+ source: z.ZodEnum<{
98
+ shop: "shop";
99
+ flow: "flow";
100
+ native: "native";
101
+ }>;
102
+ }, z.core.$strip>;
103
+ startedAt: z.ZodNumber;
104
+ }, z.core.$strip>;
105
+ workflowPhase: z.ZodLiteral<"start">;
106
+ }, z.core.$strip>;
107
+ successful: z.ZodLiteral<true>;
108
+ }, z.core.$strip>;
109
+ export type ReadySessionTiming = z.infer<typeof ReadySessionTimingSchema>;
110
+ export type SessionIdentity = z.infer<typeof SessionIdentitySchema>;
111
+ export type SessionOrderTiming = z.infer<typeof SessionOrderTimingSchema>;
112
+ export type SessionStartResponse = z.infer<typeof SessionStartResponseSchema>;
@@ -0,0 +1,25 @@
1
+ import { z } from 'zod';
2
+ /** The durable record of when a session ended — recording closure, never undoing admitted work. */
3
+ export declare const SessionClosureSchema: z.ZodObject<{
4
+ closedAt: z.ZodNumber;
5
+ status: z.ZodLiteral<"closed">;
6
+ }, z.core.$strip>;
7
+ /**
8
+ * `/session/close` needs only the checkout identity that opened the session, not the app id — `.strict()`
9
+ * so an app id (or any other unknown field) on this public, unauthenticated surface is a 4xx, matching
10
+ * `SessionStartRequestSchema`, rather than being silently stripped.
11
+ */
12
+ export declare const SessionCloseRequestSchema: z.ZodObject<{
13
+ checkoutToken: z.ZodString;
14
+ shop: z.ZodString;
15
+ }, z.core.$strict>;
16
+ export declare const SessionCloseResponseSchema: z.ZodObject<{
17
+ data: z.ZodObject<{
18
+ closedAt: z.ZodNumber;
19
+ status: z.ZodLiteral<"closed">;
20
+ }, z.core.$strip>;
21
+ successful: z.ZodLiteral<true>;
22
+ }, z.core.$strip>;
23
+ export type SessionClosure = z.infer<typeof SessionClosureSchema>;
24
+ export type SessionCloseRequest = z.infer<typeof SessionCloseRequestSchema>;
25
+ export type SessionCloseResponse = z.infer<typeof SessionCloseResponseSchema>;