@rebuy/rebuy 3.26.0 → 3.27.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.
@@ -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>;
@@ -15,6 +15,61 @@ export declare const PostPurchaseShadowSelectionSchema: z.ZodDiscriminatedUnion<
15
15
  verdict: z.ZodLiteral<"skip">;
16
16
  }, z.core.$strip>], "verdict">;
17
17
  export type PostPurchaseShadowSelection = z.infer<typeof PostPurchaseShadowSelectionSchema>;
18
+ /**
19
+ * The shadow report's fields WITHOUT the status/differences cross-field refinements below — the derivable
20
+ * base. `PostPurchaseShadowReportSchema` was a plain `ZodObject` before those refinements were added, and
21
+ * zod 4 rejects `.omit()`/`.pick()`/`.partial()` on an object schema carrying checks (see
22
+ * `src/schema/widgets/checkout-and-beyond/image.ts:74-82` for the same tradeoff): a consumer already
23
+ * deriving from the published schema would start throwing at module-eval. Derive from this instead when
24
+ * you need the unavailable three; everything that parses a wire report uses
25
+ * {@link PostPurchaseShadowReportSchema}.
26
+ */
27
+ export declare const PostPurchaseShadowReportFields: z.ZodObject<{
28
+ differences: z.ZodArray<z.ZodEnum<{
29
+ entry: "entry";
30
+ verdict: "verdict";
31
+ targeting: "targeting";
32
+ "incomplete-capture": "incomplete-capture";
33
+ "unsupported-configuration": "unsupported-configuration";
34
+ }>>;
35
+ legacySelection: z.ZodDiscriminatedUnion<[z.ZodObject<{
36
+ entry: z.ZodObject<{
37
+ blockId: z.ZodNumber;
38
+ blockIndex: z.ZodString;
39
+ blockParentIndex: z.ZodString;
40
+ flowId: z.ZodNumber;
41
+ sectionId: z.ZodNumber;
42
+ widgetId: z.ZodNumber;
43
+ widgetTraffic: z.ZodNumber;
44
+ }, z.core.$strip>;
45
+ verdict: z.ZodLiteral<"render">;
46
+ }, z.core.$strip>, z.ZodObject<{
47
+ verdict: z.ZodLiteral<"skip">;
48
+ }, z.core.$strip>], "verdict">;
49
+ phase: z.ZodLiteral<"shouldRender">;
50
+ sampleId: z.ZodString;
51
+ serverSelection: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
52
+ entry: z.ZodObject<{
53
+ blockId: z.ZodNumber;
54
+ blockIndex: z.ZodString;
55
+ blockParentIndex: z.ZodString;
56
+ flowId: z.ZodNumber;
57
+ sectionId: z.ZodNumber;
58
+ widgetId: z.ZodNumber;
59
+ widgetTraffic: z.ZodNumber;
60
+ }, z.core.$strip>;
61
+ verdict: z.ZodLiteral<"render">;
62
+ }, z.core.$strip>, z.ZodObject<{
63
+ verdict: z.ZodLiteral<"skip">;
64
+ }, z.core.$strip>], "verdict">>;
65
+ status: z.ZodEnum<{
66
+ match: "match";
67
+ diverged: "diverged";
68
+ incomplete: "incomplete";
69
+ }>;
70
+ targetingFlowIds: z.ZodArray<z.ZodNumber>;
71
+ workflowPhase: z.ZodLiteral<"decide">;
72
+ }, z.core.$strip>;
18
73
  /**
19
74
  * A shadow comparison between the legacy client-side selection and the Decider's own — wire-only. The
20
75
  * sampled request/capture shape (`ShadowSampleSchema` upstream, with its Flow-listing and product data)
@@ -22,8 +77,8 @@ export type PostPurchaseShadowSelection = z.infer<typeof PostPurchaseShadowSelec
22
77
  */
23
78
  export declare const PostPurchaseShadowReportSchema: z.ZodObject<{
24
79
  differences: z.ZodArray<z.ZodEnum<{
25
- verdict: "verdict";
26
80
  entry: "entry";
81
+ verdict: "verdict";
27
82
  targeting: "targeting";
28
83
  "incomplete-capture": "incomplete-capture";
29
84
  "unsupported-configuration": "unsupported-configuration";
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  export declare const POST_PURCHASE_SKIP_LIMIT = 32;
3
3
  /** This request's verified reads, not a claim about the path of a competing committed winner. */
4
- export declare const PostPurchaseSkipTrace: z.ZodArray<z.ZodObject<{
4
+ export declare const PostPurchaseSkipTraceSchema: z.ZodArray<z.ZodObject<{
5
5
  entry: z.ZodObject<{
6
6
  blockId: z.ZodNumber;
7
7
  blockIndex: z.ZodString;
@@ -16,4 +16,4 @@ export declare const PostPurchaseSkipTrace: z.ZodArray<z.ZodObject<{
16
16
  "no-eligible-subscription": "no-eligible-subscription";
17
17
  }>;
18
18
  }, z.core.$strip>>;
19
- export type PostPurchaseSkipTrace = z.infer<typeof PostPurchaseSkipTrace>;
19
+ export type PostPurchaseSkipTrace = z.infer<typeof PostPurchaseSkipTraceSchema>;
@@ -270,6 +270,7 @@ export declare const WidgetSettingsInputSchema: z.ZodObject<{
270
270
  monetize: z.ZodOptional<z.ZodObject<{
271
271
  language: z.ZodOptional<z.ZodString>;
272
272
  currency: z.ZodOptional<z.ZodString>;
273
+ sessionId: z.ZodOptional<z.ZodString>;
273
274
  cart: z.ZodObject<{
274
275
  attributes: z.ZodOptional<z.ZodArray<z.ZodObject<{
275
276
  key: z.ZodString;
@@ -304,7 +305,6 @@ export declare const WidgetSettingsInputSchema: z.ZodObject<{
304
305
  order_status: "order_status";
305
306
  thank_you_page: "thank_you_page";
306
307
  }>;
307
- sessionId: z.ZodOptional<z.ZodString>;
308
308
  timezone: z.ZodOptional<z.ZodString>;
309
309
  transactionId: z.ZodOptional<z.ZodString>;
310
310
  transactionItems: z.ZodOptional<z.ZodArray<z.ZodObject<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rebuy/rebuy",
3
- "version": "3.26.0",
3
+ "version": "3.27.0",
4
4
  "description": "Shared zod schemas, legacy-to-CAB widget transforms, and server orchestrators for Rebuy's Shopify consumers (rebuy-api, admin-nextjs, rebuy-shopify-extensions)",
5
5
  "license": "MIT",
6
6
  "author": "Rebuy, Inc.",