@rebuy/rebuy 3.35.0 → 3.37.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 (42) hide show
  1. package/dist/index.cjs +799 -648
  2. package/dist/index.mjs +799 -648
  3. package/dist/schema/index.d.ts +4 -0
  4. package/dist/schema/postPurchaseGroup.d.ts +15 -0
  5. package/dist/schema/postPurchaseProduct.d.ts +102 -24
  6. package/dist/schema/postPurchaseProductCalculation.d.ts +87 -0
  7. package/dist/schema/postPurchaseProductCollectionView.d.ts +738 -3
  8. package/dist/schema/postPurchaseProductDisplay.d.ts +57 -16
  9. package/dist/schema/postPurchaseProductReviews.d.ts +36 -0
  10. package/dist/schema/postPurchaseProductView.d.ts +722 -0
  11. package/dist/schema/postPurchaseQuantity.d.ts +16 -3
  12. package/dist/schema/postPurchaseSubscriptionProduct.d.ts +98 -17
  13. package/dist/server/__fixtures__/postPurchaseGroup.d.ts +3 -0
  14. package/dist/server/__fixtures__/postPurchaseReviewProviders.d.ts +30 -0
  15. package/dist/server/__fixtures__/postPurchaseReviews.d.ts +67 -0
  16. package/dist/server/index.cjs +1014 -348
  17. package/dist/server/index.d.ts +13 -2
  18. package/dist/server/index.mjs +1014 -348
  19. package/dist/server/postPurchaseJudgeMeReviews.d.ts +6 -0
  20. package/dist/server/postPurchaseOkendoReviews.d.ts +6 -0
  21. package/dist/server/postPurchaseProductDisplay.d.ts +49 -7
  22. package/dist/server/postPurchaseReviewData.d.ts +7 -0
  23. package/dist/server/postPurchaseReviewFields.d.ts +7 -0
  24. package/dist/server/postPurchaseReviewProvider.d.ts +2 -0
  25. package/dist/server/postPurchaseReviews.d.ts +5 -0
  26. package/dist/server/postPurchaseScalarReviews.d.ts +6 -0
  27. package/dist/server/prepareNormalizedSubscription.d.ts +2 -2
  28. package/dist/server/preparePostPurchaseAdmissionView.d.ts +428 -0
  29. package/dist/server/preparePostPurchaseCollectionGroup.d.ts +468 -0
  30. package/dist/server/preparePostPurchaseCollectionView.d.ts +452 -0
  31. package/dist/server/preparePostPurchaseGroupAdmissionView.d.ts +469 -0
  32. package/dist/server/preparePostPurchaseGroupDefault.d.ts +469 -0
  33. package/dist/server/preparePostPurchaseGroupView.d.ts +468 -0
  34. package/dist/server/preparePostPurchaseMemberView.d.ts +1496 -0
  35. package/dist/server/preparePostPurchaseProduct.d.ts +8 -0
  36. package/dist/server/preparePostPurchaseQuantityAdmissionView.d.ts +450 -0
  37. package/dist/server/preparePostPurchaseQuantityView.d.ts +437 -0
  38. package/dist/server/preparePostPurchaseSubscription.d.ts +47 -5
  39. package/dist/server/preparePostPurchaseView.d.ts +8 -0
  40. package/dist/server/projectPostPurchaseProduct.d.ts +49 -6
  41. package/dist/transforms/postPurchase/convertDescriptionRte.d.ts +11 -0
  42. package/package.json +1 -1
@@ -0,0 +1,6 @@
1
+ import type { ReviewFields } from '../server/postPurchaseReviewFields';
2
+ /** Read attributes only; merchant badge HTML never enters the prepared display or section tree. */
3
+ export declare const readJudgeMeReviews: (find: ReviewFields) => {
4
+ rating: number;
5
+ reviewCount: number;
6
+ } | null;
@@ -0,0 +1,6 @@
1
+ import type { ReviewFields } from '../server/postPurchaseReviewFields';
2
+ /** Only the selected aggregate's two numeric members enter the prepared review display. */
3
+ export declare const readOkendoReviews: (find: ReviewFields) => {
4
+ rating: number;
5
+ reviewCount: number;
6
+ } | null;
@@ -1,19 +1,14 @@
1
1
  import type { PostPurchaseProductSettings } from '../schema/postPurchaseProductSettings';
2
2
  import type { PostPurchaseProductSource } from '../schema/postPurchaseProductSource';
3
3
  /**
4
- * Keep response-description provenance: it precedes merchant RTE even after settings are merged. Reviews
5
- * are Slice 26's addition (see `postPurchaseProductDisplay` schema); nothing here computes them yet.
4
+ * Keep response-description provenance: it precedes the merchant's rich description even after settings are merged.
5
+ * `projectPostPurchaseProduct` adds the reviews, which need the product's metafields and the drift reporter.
6
6
  */
7
7
  export declare const projectPostPurchaseProductDisplay: (effective: PostPurchaseProductSettings, metadata: PostPurchaseProductSource["metadata"], product: PostPurchaseProductSource["data"][number]) => {
8
8
  discountedFrom: "price" | "compare_at_price";
9
9
  language: {
10
10
  description: string;
11
11
  descriptionEnabled: boolean;
12
- descriptionRte?: {
13
- content: unknown[];
14
- type: string;
15
- } | undefined;
16
- descriptionSpacing?: "default" | "none" | "tight" | "loose" | "xtight" | "xloose" | undefined;
17
12
  };
18
13
  primaryImage: {
19
14
  description: string;
@@ -28,7 +23,54 @@ export declare const projectPostPurchaseProductDisplay: (effective: PostPurchase
28
23
  showDeclineAll?: "none" | "both" | "above" | "below" | undefined;
29
24
  };
30
25
  responseDescription: string;
26
+ reviews: {
27
+ color: string;
28
+ rating: number;
29
+ reviewCount: number;
30
+ reviewsPlural: string;
31
+ reviewsSingular: string;
32
+ size: "small" | "large" | "medium";
33
+ strokeColor: string;
34
+ strokeWidth: number;
35
+ } | null;
31
36
  shouldShowSavingText: boolean;
37
+ descriptionDocument?: {
38
+ attrs: {
39
+ blockSpacing?: "none" | "base" | "extraTight" | "tight" | "loose" | "extraLoose" | undefined;
40
+ };
41
+ content: never[] | {
42
+ attrs: {
43
+ textAlign?: "start" | "center" | "end" | undefined;
44
+ };
45
+ content: never[] | {
46
+ text: string;
47
+ type: "text";
48
+ marks?: never[] | ({
49
+ type: "bold";
50
+ } | {
51
+ type: "italic";
52
+ } | {
53
+ attrs: {
54
+ class: string | null;
55
+ href: string;
56
+ rel: string;
57
+ target: string;
58
+ };
59
+ type: "link";
60
+ } | {
61
+ type: "strike";
62
+ } | {
63
+ attrs: {
64
+ color: "success" | "warning" | "critical" | "base" | "decorative" | "subdued" | "accent";
65
+ fontSize: "small" | "base" | "large" | "medium" | "extraSmall" | "extraLarge" | "heading";
66
+ };
67
+ type: "textStyle";
68
+ })[] | undefined;
69
+ }[];
70
+ type: "paragraph";
71
+ }[];
72
+ type: "doc";
73
+ } | undefined;
32
74
  gallery?: {
33
75
  images: {
34
76
  description: string;
@@ -0,0 +1,7 @@
1
+ import type { ReviewFields } from '../server/postPurchaseReviewFields';
2
+ import type { selectPostPurchaseReviewProvider } from '../server/postPurchaseReviewProvider';
3
+ /** Selection is complete before reading data; a missing selected aggregate cannot fall through. */
4
+ export declare const readPostPurchaseReviewData: (provider: NonNullable<ReturnType<typeof selectPostPurchaseReviewProvider>>, find: ReviewFields) => {
5
+ rating: number;
6
+ reviewCount: number;
7
+ } | null;
@@ -0,0 +1,7 @@
1
+ /** Missing identity is unrelated data; a matched field retains its unknown or absent value. */
2
+ export declare const reviewFields: (raw: unknown) => (namespace: string, key: string) => {
3
+ key: string;
4
+ namespace: string;
5
+ value?: unknown;
6
+ } | undefined;
7
+ export type ReviewFields = ReturnType<typeof reviewFields>;
@@ -0,0 +1,2 @@
1
+ /** Stop at the first enabled flag; later malformed flags are not consumed. */
2
+ export declare const selectPostPurchaseReviewProvider: (raw: unknown) => "judgeme" | "junip" | "klaviyo" | "loox" | "okendo" | "opinew" | "reviewsio" | "stamped" | "yotpo" | null;
@@ -0,0 +1,5 @@
1
+ import { PostPurchaseProductReviews } from '../schema/postPurchaseProductReviews';
2
+ import type { PostPurchaseProductSettings } from '../schema/postPurchaseProductSettings';
3
+ import type { Reporter } from '../server/shared';
4
+ /** Reviews are optional display data; neither missing nor malformed aggregates invalidate the offer. */
5
+ export declare const projectPostPurchaseReviews: (settings: PostPurchaseProductSettings, metafields: unknown, report?: Reporter) => PostPurchaseProductReviews | null;
@@ -0,0 +1,6 @@
1
+ import type { ReviewFields } from '../server/postPurchaseReviewFields';
2
+ /** Pair absence is ordinary; invalid selected values throw to the single local recovery boundary. */
3
+ export declare const readScalarReviews: (find: ReviewFields, namespace: string, ratingKey: string, countKey: string) => {
4
+ rating: number;
5
+ reviewCount: number;
6
+ } | null;
@@ -4,7 +4,7 @@ import type { normalizePostPurchaseProduct } from '../server/normalizePostPurcha
4
4
  import type { PostPurchaseQuantity } from '../server/readPostPurchaseQuantity';
5
5
  import type { Reporter } from '../server/shared';
6
6
  /**
7
- * Preparation for one allocated plan with validated configured shipping and discount. `report` is kept in the
8
- * frozen position for Slice 26, whose review projection is the only consumer inside `projectPostPurchaseProduct`.
7
+ * Preparation for one allocated plan with validated configured shipping and discount; `report` receives
8
+ * unreadable-review drift.
9
9
  */
10
10
  export declare const prepareNormalizedSubscription: (normalized: ReturnType<typeof normalizePostPurchaseProduct>, report: Reporter | undefined, plan: PostPurchasePlanOption | undefined, quantity?: PostPurchaseQuantity, allowCollection?: boolean) => PostPurchasePreparation;
@@ -0,0 +1,428 @@
1
+ import type { PostPurchaseChoice } from '../schema/postPurchaseChoice';
2
+ import type { Reporter } from '../server/shared';
3
+ /** Private admission facts and public view share one effective configuration; no settings reread. */
4
+ export declare const preparePostPurchaseAdmissionView: (widgetId: number, settings: unknown, response: unknown, report?: Reporter, choice?: PostPurchaseChoice) => {
5
+ removePartialOrder: boolean;
6
+ view: {
7
+ preparation: {
8
+ labels: {
9
+ declineAll: string;
10
+ free: string;
11
+ payNow: string;
12
+ quantity: string;
13
+ recurringShipping: string;
14
+ recurringSubtotal: string;
15
+ save: string;
16
+ shipping: string;
17
+ subtotal: string;
18
+ taxes: string;
19
+ total: string;
20
+ };
21
+ product: {
22
+ title: string;
23
+ id: number;
24
+ variant: {
25
+ title: string;
26
+ compareAtPrice: string | null;
27
+ id: number;
28
+ price: string;
29
+ };
30
+ image?: {
31
+ src: string;
32
+ } | null | undefined;
33
+ description?: string | null | undefined;
34
+ };
35
+ selection: {
36
+ productId: number;
37
+ quantity: number;
38
+ variantId: number;
39
+ sellingPlanId?: number | undefined;
40
+ };
41
+ status: "prepared";
42
+ terms: {
43
+ discount: {
44
+ amount: number;
45
+ title: string;
46
+ type: "none" | "fixed_amount" | "percentage";
47
+ };
48
+ shipping: {
49
+ amount: number;
50
+ title: string;
51
+ type: "fixed_amount" | "free";
52
+ };
53
+ subscription?: {
54
+ initialShippingPrice: number;
55
+ intervalLabel: string;
56
+ name: string;
57
+ recurringShippingPrice: number;
58
+ shippingOption: {
59
+ presentmentTitle: string;
60
+ title: string;
61
+ };
62
+ adjustment?: {
63
+ amount: number;
64
+ type: "price" | "fixed_amount" | "percentage";
65
+ } | undefined;
66
+ } | undefined;
67
+ };
68
+ display: {
69
+ discountedFrom: "price" | "compare_at_price";
70
+ language: {
71
+ description: string;
72
+ descriptionEnabled: boolean;
73
+ };
74
+ primaryImage: {
75
+ description: string;
76
+ source: string;
77
+ };
78
+ productOptions: {
79
+ showShipping: boolean;
80
+ showSubtotal: boolean;
81
+ showTaxes: boolean;
82
+ showTotal: boolean;
83
+ showVariantSelectors: boolean;
84
+ showDeclineAll?: "none" | "both" | "above" | "below" | undefined;
85
+ };
86
+ responseDescription: string;
87
+ reviews: {
88
+ color: string;
89
+ rating: number;
90
+ reviewCount: number;
91
+ reviewsPlural: string;
92
+ reviewsSingular: string;
93
+ size: "small" | "large" | "medium";
94
+ strokeColor: string;
95
+ strokeWidth: number;
96
+ } | null;
97
+ shouldShowSavingText: boolean;
98
+ description: string | null;
99
+ descriptionDocument?: {
100
+ attrs: {
101
+ blockSpacing?: "none" | "base" | "extraTight" | "tight" | "loose" | "extraLoose" | undefined;
102
+ };
103
+ content: never[] | {
104
+ attrs: {
105
+ textAlign?: "start" | "center" | "end" | undefined;
106
+ };
107
+ content: never[] | {
108
+ text: string;
109
+ type: "text";
110
+ marks?: never[] | ({
111
+ type: "bold";
112
+ } | {
113
+ type: "italic";
114
+ } | {
115
+ attrs: {
116
+ class: string | null;
117
+ href: string;
118
+ rel: string;
119
+ target: string;
120
+ };
121
+ type: "link";
122
+ } | {
123
+ type: "strike";
124
+ } | {
125
+ attrs: {
126
+ color: "success" | "warning" | "critical" | "base" | "decorative" | "subdued" | "accent";
127
+ fontSize: "small" | "base" | "large" | "medium" | "extraSmall" | "extraLarge" | "heading";
128
+ };
129
+ type: "textStyle";
130
+ })[] | undefined;
131
+ }[];
132
+ type: "paragraph";
133
+ }[];
134
+ type: "doc";
135
+ } | undefined;
136
+ gallery?: {
137
+ images: {
138
+ description: string;
139
+ id: number;
140
+ source: string;
141
+ thumbnail: string;
142
+ }[];
143
+ selectedImageId?: number | undefined;
144
+ } | undefined;
145
+ };
146
+ };
147
+ sections: {
148
+ alignment: {
149
+ horizontal: "start" | "center" | "end";
150
+ vertical: "top" | "middle" | "bottom";
151
+ };
152
+ border: {
153
+ radius: "small" | "none" | "base" | "large" | "fullyRounded";
154
+ style: "none" | "base" | "dotted" | "dashed";
155
+ width: "base" | "medium" | "thick";
156
+ };
157
+ direction: "columns" | "rows" | "grid";
158
+ padding: "none" | "base" | "extraTight" | "tight" | "loose" | "extraLoose";
159
+ sectionId: string;
160
+ sections: never[] | import("..").CABSection[];
161
+ sectionType: "layout";
162
+ spacing: "none" | "base" | "extraTight" | "tight" | "loose" | "extraLoose";
163
+ width: number;
164
+ editorMode: "checkoutExtension" | "postPurchaseOffer" | "thankYouPage" | "orderStatusPage" | "ordersIndexPage" | "customerProfilePage";
165
+ previewMode: boolean;
166
+ storeId: number | null;
167
+ targetArea: {
168
+ icon: string;
169
+ label: string;
170
+ width: string;
171
+ fill?: boolean | undefined;
172
+ flip?: "vertical" | "horizontal" | "both" | undefined;
173
+ } | null;
174
+ tracking: {
175
+ enableAttribution: boolean;
176
+ enableSource: boolean;
177
+ enableWidget: boolean;
178
+ };
179
+ type: "product" | "bundle_builder" | "cart" | "cart_subscription" | "dynamic_bundle" | "gift_with_purchase" | "placeholder" | "pre_purchase" | "product_addon" | "product_upsell" | "recharge_checkout" | "recharge_customer_portal" | "recharge_post_purchase" | "shopify_checkout" | "shopify_checkout_extension" | "shopify_post_purchase" | "shopify_post_purchase_extension" | "switch_to_subscription" | "ui_extension_ad" | "ui_extension_button" | "ui_extension_content_block" | "ui_extension_line_item_editor" | "ui_extension_progress_bar";
180
+ uiLabels: {
181
+ currentPage: Record<string, string>;
182
+ guest: Record<string, string>;
183
+ loadingOptions: Record<string, string>;
184
+ nextPage: Record<string, string>;
185
+ offerCarousel: Record<string, string>;
186
+ offerDialog: Record<string, string>;
187
+ page: Record<string, string>;
188
+ previousPage: Record<string, string>;
189
+ selected: Record<string, string>;
190
+ subscriptionOptions: Record<string, string>;
191
+ updating: Record<string, string>;
192
+ };
193
+ version: 2;
194
+ widgetId: number | null;
195
+ buttonField?: "declineAllOffers" | "declineOffer" | "removeFromOrder" | "undoAddToOrder" | "activePage" | "addedToCart" | "addingToCart" | "addToCart" | "buttonLabel" | "destinationUrl" | "inactivePage" | "overlayContent" | "payNow" | "progressReached" | "progressRemaining" | "redirectToCheckout" | "showVariant" | "showVariants" | "soldOut" | "subscriptionOption" | "switchToOneTimePurchase" | "switchToSubscriptionNoDiscount" | "switchToSubscriptionWithDiscount" | undefined;
196
+ frame?: "callout" | "offer-content" | undefined;
197
+ grid?: {
198
+ columns: (string | number)[];
199
+ rows: (string | number)[];
200
+ } | undefined;
201
+ name?: string | undefined;
202
+ viewUrl?: string | undefined;
203
+ wrapping?: {
204
+ breakAt: number;
205
+ maxPerLine: number;
206
+ } | undefined;
207
+ mutators?: {
208
+ effect: "set_false" | "set_true" | "toggle";
209
+ variable: string;
210
+ when: {
211
+ operator: "is_empty" | "is_not_empty";
212
+ type: "content";
213
+ } | {
214
+ operator: "equals" | "greater_than" | "less_than";
215
+ type: "result_count";
216
+ value: number;
217
+ } | {
218
+ operator: "contains" | "does_not_contain";
219
+ type: "result_tag";
220
+ value: string;
221
+ } | {
222
+ event: "item_added" | "quantity_changed" | "variant_selected";
223
+ type: "event";
224
+ };
225
+ }[] | undefined;
226
+ variables?: ({
227
+ defaultValue: string;
228
+ name: string;
229
+ type: "text";
230
+ seed?: undefined;
231
+ } | {
232
+ defaultValue: number;
233
+ name: string;
234
+ type: "number";
235
+ seed?: undefined;
236
+ } | {
237
+ defaultValue: boolean;
238
+ name: string;
239
+ type: "boolean";
240
+ seed?: {
241
+ dataSourceId: number | null;
242
+ ruleset: {
243
+ exitIfMatched: boolean;
244
+ logic: {
245
+ rules: {
246
+ operator: "equals" | "greater_than" | "less_than" | "contains" | "does_not_contain" | "after" | "anything" | "before" | "contains_any" | "does_not_contain_any" | "does_not_equal";
247
+ products: never[] | unknown[];
248
+ type: "product" | "date" | "cart" | "cart_count" | "cart_item_count" | "cart_line_count" | "cart_subtotal" | "collection" | "customer" | "customer_order_count" | "customer_tag" | "customer_total_spent" | "product_tag" | "product_title" | "product_type" | "product_vendor";
249
+ value: string;
250
+ }[];
251
+ }[];
252
+ output: {
253
+ key: string;
254
+ type: "data_json";
255
+ value: string;
256
+ }[];
257
+ }[];
258
+ } | undefined;
259
+ })[] | undefined;
260
+ visibility?: {
261
+ variable: string;
262
+ visibleWhen: boolean;
263
+ } | undefined;
264
+ experiment?: {
265
+ elementId: number;
266
+ experimentId: number;
267
+ experimentType: string;
268
+ selectedId: number;
269
+ } | undefined;
270
+ };
271
+ groupCatalog?: {
272
+ memberProductId: number;
273
+ options: {
274
+ productId: number;
275
+ title: string;
276
+ variantCatalog: {
277
+ displayMode: "single" | "separate";
278
+ options: {
279
+ name: string;
280
+ values: string[];
281
+ id: number;
282
+ position: number;
283
+ }[];
284
+ productId: number;
285
+ showSelectors: boolean;
286
+ variants: {
287
+ available: boolean;
288
+ id: number;
289
+ title: string;
290
+ option1?: string | undefined;
291
+ option2?: string | null | undefined;
292
+ option3?: string | null | undefined;
293
+ imageId?: number | null | undefined;
294
+ }[];
295
+ };
296
+ }[];
297
+ } | undefined;
298
+ initialVariant?: {
299
+ variantId: number;
300
+ } | undefined;
301
+ planCatalog?: {
302
+ plans: {
303
+ id: number;
304
+ intervalLabel: string;
305
+ name: string;
306
+ adjustment?: {
307
+ amount: number;
308
+ type: "price" | "fixed_amount" | "percentage";
309
+ } | undefined;
310
+ intervalFrequency?: string | undefined;
311
+ }[];
312
+ productId: number;
313
+ requiresSellingPlan: boolean;
314
+ variantId: number;
315
+ } | null | undefined;
316
+ purchaseOptions?: {
317
+ defaultChoice: {
318
+ mode: "one-time";
319
+ } | {
320
+ mode: "subscription";
321
+ sellingPlanId: number;
322
+ };
323
+ modes: ("one-time" | "subscription")[];
324
+ selector: "radio" | "dropdown";
325
+ } | undefined;
326
+ variantCatalog?: {
327
+ displayMode: "single" | "separate";
328
+ options: {
329
+ name: string;
330
+ values: string[];
331
+ id: number;
332
+ position: number;
333
+ }[];
334
+ productId: number;
335
+ showSelectors: boolean;
336
+ variants: {
337
+ available: boolean;
338
+ id: number;
339
+ title: string;
340
+ option1?: string | undefined;
341
+ option2?: string | null | undefined;
342
+ option3?: string | null | undefined;
343
+ imageId?: number | null | undefined;
344
+ }[];
345
+ } | undefined;
346
+ } | {
347
+ preparation: {
348
+ reason: string;
349
+ status: "unsupported";
350
+ };
351
+ sections: null;
352
+ groupCatalog?: {
353
+ memberProductId: number;
354
+ options: {
355
+ productId: number;
356
+ title: string;
357
+ variantCatalog: {
358
+ displayMode: "single" | "separate";
359
+ options: {
360
+ name: string;
361
+ values: string[];
362
+ id: number;
363
+ position: number;
364
+ }[];
365
+ productId: number;
366
+ showSelectors: boolean;
367
+ variants: {
368
+ available: boolean;
369
+ id: number;
370
+ title: string;
371
+ option1?: string | undefined;
372
+ option2?: string | null | undefined;
373
+ option3?: string | null | undefined;
374
+ imageId?: number | null | undefined;
375
+ }[];
376
+ };
377
+ }[];
378
+ } | undefined;
379
+ initialVariant?: {
380
+ variantId: number;
381
+ } | undefined;
382
+ planCatalog?: {
383
+ plans: {
384
+ id: number;
385
+ intervalLabel: string;
386
+ name: string;
387
+ adjustment?: {
388
+ amount: number;
389
+ type: "price" | "fixed_amount" | "percentage";
390
+ } | undefined;
391
+ intervalFrequency?: string | undefined;
392
+ }[];
393
+ productId: number;
394
+ requiresSellingPlan: boolean;
395
+ variantId: number;
396
+ } | null | undefined;
397
+ purchaseOptions?: {
398
+ defaultChoice: {
399
+ mode: "one-time";
400
+ } | {
401
+ mode: "subscription";
402
+ sellingPlanId: number;
403
+ };
404
+ modes: ("one-time" | "subscription")[];
405
+ selector: "radio" | "dropdown";
406
+ } | undefined;
407
+ variantCatalog?: {
408
+ displayMode: "single" | "separate";
409
+ options: {
410
+ name: string;
411
+ values: string[];
412
+ id: number;
413
+ position: number;
414
+ }[];
415
+ productId: number;
416
+ showSelectors: boolean;
417
+ variants: {
418
+ available: boolean;
419
+ id: number;
420
+ title: string;
421
+ option1?: string | undefined;
422
+ option2?: string | null | undefined;
423
+ option3?: string | null | undefined;
424
+ imageId?: number | null | undefined;
425
+ }[];
426
+ } | undefined;
427
+ };
428
+ };