@wix/headless-stores 0.0.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 (150) hide show
  1. package/astro/actions/package.json +4 -0
  2. package/cjs/dist/astro/actions/custom-checkout.d.ts +50 -0
  3. package/cjs/dist/astro/actions/custom-checkout.js +53 -0
  4. package/cjs/dist/astro/actions/index.d.ts +1 -0
  5. package/cjs/dist/astro/actions/index.js +1 -0
  6. package/cjs/dist/data-component-tags.d.ts +8 -0
  7. package/cjs/dist/data-component-tags.js +9 -0
  8. package/cjs/dist/enums/index.d.ts +2 -0
  9. package/cjs/dist/enums/index.js +2 -0
  10. package/cjs/dist/enums/social-platform-enums.d.ts +25 -0
  11. package/cjs/dist/enums/social-platform-enums.js +27 -0
  12. package/cjs/dist/enums/sort-enums.d.ts +17 -0
  13. package/cjs/dist/enums/sort-enums.js +18 -0
  14. package/cjs/dist/react/Category.d.ts +242 -0
  15. package/cjs/dist/react/Category.js +235 -0
  16. package/cjs/dist/react/CategoryList.d.ts +107 -0
  17. package/cjs/dist/react/CategoryList.js +91 -0
  18. package/cjs/dist/react/Choice.d.ts +211 -0
  19. package/cjs/dist/react/Choice.js +213 -0
  20. package/cjs/dist/react/Option.d.ts +242 -0
  21. package/cjs/dist/react/Option.js +346 -0
  22. package/cjs/dist/react/Product.d.ts +1065 -0
  23. package/cjs/dist/react/Product.js +1157 -0
  24. package/cjs/dist/react/ProductList.d.ts +400 -0
  25. package/cjs/dist/react/ProductList.js +368 -0
  26. package/cjs/dist/react/core/CategoryList.d.ts +194 -0
  27. package/cjs/dist/react/core/CategoryList.js +180 -0
  28. package/cjs/dist/react/core/Product.d.ts +225 -0
  29. package/cjs/dist/react/core/Product.js +190 -0
  30. package/cjs/dist/react/core/ProductList.d.ts +235 -0
  31. package/cjs/dist/react/core/ProductList.js +217 -0
  32. package/cjs/dist/react/core/ProductListFilters.d.ts +138 -0
  33. package/cjs/dist/react/core/ProductListFilters.js +242 -0
  34. package/cjs/dist/react/core/ProductListPagination.d.ts +49 -0
  35. package/cjs/dist/react/core/ProductListPagination.js +41 -0
  36. package/cjs/dist/react/core/ProductListSort.d.ts +19 -0
  37. package/cjs/dist/react/core/ProductListSort.js +52 -0
  38. package/cjs/dist/react/core/ProductModifiers.d.ts +416 -0
  39. package/cjs/dist/react/core/ProductModifiers.js +413 -0
  40. package/cjs/dist/react/core/ProductVariantSelector.d.ts +313 -0
  41. package/cjs/dist/react/core/ProductVariantSelector.js +291 -0
  42. package/cjs/dist/react/core/SelectedVariant.d.ts +230 -0
  43. package/cjs/dist/react/core/SelectedVariant.js +269 -0
  44. package/cjs/dist/react/index.d.ts +6 -0
  45. package/cjs/dist/react/index.js +6 -0
  46. package/cjs/dist/react/types.d.ts +8 -0
  47. package/cjs/dist/react/types.js +9 -0
  48. package/cjs/dist/server-actions/custom-checkout-action.d.ts +49 -0
  49. package/cjs/dist/server-actions/custom-checkout-action.js +64 -0
  50. package/cjs/dist/server-actions/index.d.ts +1 -0
  51. package/cjs/dist/server-actions/index.js +1 -0
  52. package/cjs/dist/services/buy-now-service.d.ts +346 -0
  53. package/cjs/dist/services/buy-now-service.js +197 -0
  54. package/cjs/dist/services/categories-list-service.d.ts +164 -0
  55. package/cjs/dist/services/categories-list-service.js +148 -0
  56. package/cjs/dist/services/index.d.ts +5 -0
  57. package/cjs/dist/services/index.js +5 -0
  58. package/cjs/dist/services/pay-now-service.d.ts +214 -0
  59. package/cjs/dist/services/pay-now-service.js +156 -0
  60. package/cjs/dist/services/product-modifiers-service.d.ts +34 -0
  61. package/cjs/dist/services/product-modifiers-service.js +107 -0
  62. package/cjs/dist/services/product-service.d.ts +177 -0
  63. package/cjs/dist/services/product-service.js +190 -0
  64. package/cjs/dist/services/products-list-search-service.d.ts +1 -0
  65. package/cjs/dist/services/products-list-search-service.js +1 -0
  66. package/cjs/dist/services/products-list-service.d.ts +429 -0
  67. package/cjs/dist/services/products-list-service.js +893 -0
  68. package/cjs/dist/services/selected-variant-service.d.ts +66 -0
  69. package/cjs/dist/services/selected-variant-service.js +527 -0
  70. package/cjs/dist/utils/index.d.ts +1 -0
  71. package/cjs/dist/utils/index.js +30 -0
  72. package/cjs/dist/utils/url-params.d.ts +73 -0
  73. package/cjs/dist/utils/url-params.js +114 -0
  74. package/cjs/package.json +3 -0
  75. package/dist/astro/actions/custom-checkout.d.ts +50 -0
  76. package/dist/astro/actions/custom-checkout.js +53 -0
  77. package/dist/astro/actions/index.d.ts +1 -0
  78. package/dist/astro/actions/index.js +1 -0
  79. package/dist/data-component-tags.d.ts +8 -0
  80. package/dist/data-component-tags.js +9 -0
  81. package/dist/enums/index.d.ts +2 -0
  82. package/dist/enums/index.js +2 -0
  83. package/dist/enums/social-platform-enums.d.ts +25 -0
  84. package/dist/enums/social-platform-enums.js +27 -0
  85. package/dist/enums/sort-enums.d.ts +17 -0
  86. package/dist/enums/sort-enums.js +18 -0
  87. package/dist/react/Category.d.ts +242 -0
  88. package/dist/react/Category.js +235 -0
  89. package/dist/react/CategoryList.d.ts +107 -0
  90. package/dist/react/CategoryList.js +91 -0
  91. package/dist/react/Choice.d.ts +211 -0
  92. package/dist/react/Choice.js +213 -0
  93. package/dist/react/Option.d.ts +242 -0
  94. package/dist/react/Option.js +346 -0
  95. package/dist/react/Product.d.ts +1065 -0
  96. package/dist/react/Product.js +1157 -0
  97. package/dist/react/ProductList.d.ts +400 -0
  98. package/dist/react/ProductList.js +368 -0
  99. package/dist/react/core/CategoryList.d.ts +194 -0
  100. package/dist/react/core/CategoryList.js +180 -0
  101. package/dist/react/core/Product.d.ts +225 -0
  102. package/dist/react/core/Product.js +190 -0
  103. package/dist/react/core/ProductList.d.ts +235 -0
  104. package/dist/react/core/ProductList.js +217 -0
  105. package/dist/react/core/ProductListFilters.d.ts +138 -0
  106. package/dist/react/core/ProductListFilters.js +242 -0
  107. package/dist/react/core/ProductListPagination.d.ts +49 -0
  108. package/dist/react/core/ProductListPagination.js +41 -0
  109. package/dist/react/core/ProductListSort.d.ts +19 -0
  110. package/dist/react/core/ProductListSort.js +52 -0
  111. package/dist/react/core/ProductModifiers.d.ts +416 -0
  112. package/dist/react/core/ProductModifiers.js +413 -0
  113. package/dist/react/core/ProductVariantSelector.d.ts +313 -0
  114. package/dist/react/core/ProductVariantSelector.js +291 -0
  115. package/dist/react/core/SelectedVariant.d.ts +230 -0
  116. package/dist/react/core/SelectedVariant.js +269 -0
  117. package/dist/react/index.d.ts +6 -0
  118. package/dist/react/index.js +6 -0
  119. package/dist/react/types.d.ts +8 -0
  120. package/dist/react/types.js +9 -0
  121. package/dist/server-actions/custom-checkout-action.d.ts +49 -0
  122. package/dist/server-actions/custom-checkout-action.js +64 -0
  123. package/dist/server-actions/index.d.ts +1 -0
  124. package/dist/server-actions/index.js +1 -0
  125. package/dist/services/buy-now-service.d.ts +346 -0
  126. package/dist/services/buy-now-service.js +197 -0
  127. package/dist/services/categories-list-service.d.ts +164 -0
  128. package/dist/services/categories-list-service.js +148 -0
  129. package/dist/services/index.d.ts +5 -0
  130. package/dist/services/index.js +5 -0
  131. package/dist/services/pay-now-service.d.ts +214 -0
  132. package/dist/services/pay-now-service.js +156 -0
  133. package/dist/services/product-modifiers-service.d.ts +34 -0
  134. package/dist/services/product-modifiers-service.js +107 -0
  135. package/dist/services/product-service.d.ts +177 -0
  136. package/dist/services/product-service.js +190 -0
  137. package/dist/services/products-list-search-service.d.ts +0 -0
  138. package/dist/services/products-list-search-service.js +1 -0
  139. package/dist/services/products-list-service.d.ts +429 -0
  140. package/dist/services/products-list-service.js +893 -0
  141. package/dist/services/selected-variant-service.d.ts +66 -0
  142. package/dist/services/selected-variant-service.js +527 -0
  143. package/dist/utils/index.d.ts +1 -0
  144. package/dist/utils/index.js +30 -0
  145. package/dist/utils/url-params.d.ts +73 -0
  146. package/dist/utils/url-params.js +114 -0
  147. package/package.json +89 -0
  148. package/react/package.json +4 -0
  149. package/server-actions/package.json +4 -0
  150. package/services/package.json +4 -0
@@ -0,0 +1,346 @@
1
+ import { type Signal } from '@wix/services-definitions/core-services/signals';
2
+ /**
3
+ * Service definition for the Buy Now service.
4
+ * This defines the reactive API contract for managing buy now functionality.
5
+ *
6
+ * @constant
7
+ */
8
+ export declare const BuyNowServiceDefinition: string & {
9
+ __api: {
10
+ /** Function to redirect to checkout with the current product */
11
+ redirectToCheckout: () => Promise<void>;
12
+ /** Reactive signal indicating if a checkout redirect is in progress */
13
+ loadingSignal: Signal<boolean>;
14
+ /** Reactive signal containing any error message, or null if no error */
15
+ errorSignal: Signal<string | null>;
16
+ /** Reactive signal indicating if the product is in stock */
17
+ inStockSignal: Signal<boolean>;
18
+ /** Reactive signal indicating if pre-order is available */
19
+ preOrderAvailableSignal: Signal<boolean>;
20
+ /** The name of the product */
21
+ productName: string;
22
+ /** The price of the product as a string */
23
+ price: string;
24
+ /** The currency code for the product price */
25
+ currency: string;
26
+ };
27
+ __config: {};
28
+ isServiceDefinition?: boolean;
29
+ } & {
30
+ /** Function to redirect to checkout with the current product */
31
+ redirectToCheckout: () => Promise<void>;
32
+ /** Reactive signal indicating if a checkout redirect is in progress */
33
+ loadingSignal: Signal<boolean>;
34
+ /** Reactive signal containing any error message, or null if no error */
35
+ errorSignal: Signal<string | null>;
36
+ /** Reactive signal indicating if the product is in stock */
37
+ inStockSignal: Signal<boolean>;
38
+ /** Reactive signal indicating if pre-order is available */
39
+ preOrderAvailableSignal: Signal<boolean>;
40
+ /** The name of the product */
41
+ productName: string;
42
+ /** The price of the product as a string */
43
+ price: string;
44
+ /** The currency code for the product price */
45
+ currency: string;
46
+ };
47
+ /**
48
+ * Configuration interface for the Buy Now service.
49
+ * Contains all the product information needed to initialize the buy now functionality.
50
+ *
51
+ * @interface BuyNowServiceConfig
52
+ */
53
+ export interface BuyNowServiceConfig {
54
+ /** The unique product ID */
55
+ productId: string;
56
+ /** The optional variant ID if a specific variant is selected */
57
+ variantId?: string;
58
+ /** The display name of the product */
59
+ productName: string;
60
+ /** The price of the product as a string */
61
+ price: string;
62
+ /** The currency code for the product price */
63
+ currency: string;
64
+ /** Whether the product is currently in stock */
65
+ inStock: boolean;
66
+ /** Whether pre-order is available for this product */
67
+ preOrderAvailable: boolean;
68
+ }
69
+ /**
70
+ * Implementation of the Buy Now service that manages buy now functionality.
71
+ * This service provides signals for loading state, stock status, and error handling,
72
+ * along with a method to redirect directly to checkout.
73
+ *
74
+ * @example
75
+ * ```tsx
76
+ * import { BuyNowServiceImplementation, BuyNowServiceDefinition } from '@wix/stores/services';
77
+ * import { useService } from '@wix/services-manager-react';
78
+ *
79
+ * function BuyNowComponent({ buyNowConfig }) {
80
+ * return (
81
+ * <ServiceProvider services={createServicesMap([
82
+ * [BuyNowServiceDefinition, BuyNowServiceImplementation.withConfig(buyNowConfig)]
83
+ * ])}>
84
+ * <BuyNowButton />
85
+ * </ServiceProvider>
86
+ * );
87
+ * }
88
+ *
89
+ * function BuyNowButton() {
90
+ * const buyNowService = useService(BuyNowServiceDefinition);
91
+ * const isLoading = buyNowService.loadingSignal.get();
92
+ * const error = buyNowService.errorSignal.get();
93
+ * const inStock = buyNowService.inStockSignal.get();
94
+ *
95
+ * const handleBuyNow = async () => {
96
+ * await buyNowService.redirectToCheckout();
97
+ * };
98
+ *
99
+ * return (
100
+ * <div>
101
+ * {error && <div className="error">{error}</div>}
102
+ * <button
103
+ * onClick={handleBuyNow}
104
+ * disabled={!inStock || isLoading}
105
+ * className={`buy-now-btn ${!inStock ? 'out-of-stock' : ''}`}
106
+ * >
107
+ * {isLoading ? 'Processing...' :
108
+ * !inStock ? 'Out of Stock' :
109
+ * `Buy Now - ${buyNowService.currency}${buyNowService.price}`}
110
+ * </button>
111
+ * </div>
112
+ * );
113
+ * }
114
+ * ```
115
+ */
116
+ export declare const BuyNowServiceImplementation: import("@wix/services-definitions").ServiceFactory<string & {
117
+ __api: {
118
+ /** Function to redirect to checkout with the current product */
119
+ redirectToCheckout: () => Promise<void>;
120
+ /** Reactive signal indicating if a checkout redirect is in progress */
121
+ loadingSignal: Signal<boolean>;
122
+ /** Reactive signal containing any error message, or null if no error */
123
+ errorSignal: Signal<string | null>;
124
+ /** Reactive signal indicating if the product is in stock */
125
+ inStockSignal: Signal<boolean>;
126
+ /** Reactive signal indicating if pre-order is available */
127
+ preOrderAvailableSignal: Signal<boolean>;
128
+ /** The name of the product */
129
+ productName: string;
130
+ /** The price of the product as a string */
131
+ price: string;
132
+ /** The currency code for the product price */
133
+ currency: string;
134
+ };
135
+ __config: {};
136
+ isServiceDefinition?: boolean;
137
+ } & {
138
+ /** Function to redirect to checkout with the current product */
139
+ redirectToCheckout: () => Promise<void>;
140
+ /** Reactive signal indicating if a checkout redirect is in progress */
141
+ loadingSignal: Signal<boolean>;
142
+ /** Reactive signal containing any error message, or null if no error */
143
+ errorSignal: Signal<string | null>;
144
+ /** Reactive signal indicating if the product is in stock */
145
+ inStockSignal: Signal<boolean>;
146
+ /** Reactive signal indicating if pre-order is available */
147
+ preOrderAvailableSignal: Signal<boolean>;
148
+ /** The name of the product */
149
+ productName: string;
150
+ /** The price of the product as a string */
151
+ price: string;
152
+ /** The currency code for the product price */
153
+ currency: string;
154
+ }, {
155
+ productId: string;
156
+ variantId?: string;
157
+ productName: string;
158
+ price: string;
159
+ currency: string;
160
+ inStock: boolean;
161
+ preOrderAvailable: boolean;
162
+ }>;
163
+ /**
164
+ * Loads buy now service initial data from the Wix Stores API for SSR initialization.
165
+ * This function is designed to be used during Server-Side Rendering (SSR) to preload
166
+ * product data required for the buy now functionality.
167
+ *
168
+ * @param {string} productSlug - The product slug to load data for
169
+ * @param {string} [variantId] - Optional variant ID if a specific variant should be used
170
+ * @returns {Promise} Promise that resolves to the buy now service configuration data
171
+ *
172
+ * @example
173
+ * ```astro
174
+ * ---
175
+ * // Astro page example - pages/product/[slug].astro
176
+ * import { loadBuyNowServiceInitialData } from '@wix/stores/services';
177
+ * import { BuyNow } from '@wix/stores/components';
178
+ *
179
+ * const { slug } = Astro.params;
180
+ * const variantId = Astro.url.searchParams.get('variant');
181
+ *
182
+ * // Load buy now data during SSR
183
+ * const buyNowData = await loadBuyNowServiceInitialData(slug, variantId);
184
+ * ---
185
+ *
186
+ * <BuyNow.BuyNow buyNowConfig={buyNowData.BuyNow}>
187
+ * {({ redirectToCheckout, isLoading, inStock, price, currency }) => (
188
+ * <button onClick={redirectToCheckout} disabled={!inStock || isLoading}>
189
+ * {isLoading ? 'Loading...' : `Buy Now ${currency}${price}`}
190
+ * </button>
191
+ * )}
192
+ * </BuyNow.BuyNow>
193
+ * ```
194
+ *
195
+ * @example
196
+ * ```tsx
197
+ * // Next.js page example
198
+ * import { GetServerSideProps } from 'next';
199
+ * import { loadBuyNowServiceInitialData } from '@wix/stores/services';
200
+ *
201
+ * export const getServerSideProps: GetServerSideProps = async ({ params, query }) => {
202
+ * const slug = params?.slug as string;
203
+ * const variantId = query.variant as string | undefined;
204
+ *
205
+ * const buyNowData = await loadBuyNowServiceInitialData(slug, variantId);
206
+ *
207
+ * return {
208
+ * props: {
209
+ * buyNowData,
210
+ * },
211
+ * };
212
+ * };
213
+ * ```
214
+ */
215
+ export declare const loadBuyNowServiceInitialData: (productSlug: string, variantId?: string) => Promise<{
216
+ [BuyNowServiceDefinition]: {
217
+ productId: string;
218
+ productName: string;
219
+ price: string;
220
+ currency: string;
221
+ variantId: string | null | undefined;
222
+ inStock: boolean | undefined;
223
+ preOrderAvailable: boolean | undefined;
224
+ };
225
+ }>;
226
+ /**
227
+ * Helper function to create a buy now service binding with configuration.
228
+ * This function simplifies the process of binding the buy now service with its configuration
229
+ * and allows for additional configuration overrides.
230
+ *
231
+ * @template T - Type of the services configurations object
232
+ * @param {T} servicesConfigs - Object containing service configurations
233
+ * @param {Partial<BuyNowServiceConfig>} [additionalConfig={}] - Additional configuration to override defaults
234
+ * @returns Tuple containing service definition, implementation, and merged configuration
235
+ *
236
+ * @example
237
+ * ```tsx
238
+ * import { buyNowServiceBinding, loadBuyNowServiceInitialData } from '@wix/stores/services';
239
+ *
240
+ * // Load initial data
241
+ * const initialData = await loadBuyNowServiceInitialData('my-product-slug');
242
+ *
243
+ * // Create service binding with additional config
244
+ * const buyNowBinding = buyNowServiceBinding(initialData, {
245
+ * inStock: false, // Override stock status
246
+ * });
247
+ *
248
+ * // Use in service provider
249
+ * const services = createServicesMap([buyNowBinding]);
250
+ * ```
251
+ */
252
+ export declare const buyNowServiceBinding: <T extends {
253
+ [key: string]: Awaited<ReturnType<typeof loadBuyNowServiceInitialData>>[typeof BuyNowServiceDefinition];
254
+ }>(servicesConfigs: T, additionalConfig?: Partial<BuyNowServiceConfig>) => readonly [string & {
255
+ __api: {
256
+ /** Function to redirect to checkout with the current product */
257
+ redirectToCheckout: () => Promise<void>;
258
+ /** Reactive signal indicating if a checkout redirect is in progress */
259
+ loadingSignal: Signal<boolean>;
260
+ /** Reactive signal containing any error message, or null if no error */
261
+ errorSignal: Signal<string | null>;
262
+ /** Reactive signal indicating if the product is in stock */
263
+ inStockSignal: Signal<boolean>;
264
+ /** Reactive signal indicating if pre-order is available */
265
+ preOrderAvailableSignal: Signal<boolean>;
266
+ /** The name of the product */
267
+ productName: string;
268
+ /** The price of the product as a string */
269
+ price: string;
270
+ /** The currency code for the product price */
271
+ currency: string;
272
+ };
273
+ __config: {};
274
+ isServiceDefinition?: boolean;
275
+ } & {
276
+ /** Function to redirect to checkout with the current product */
277
+ redirectToCheckout: () => Promise<void>;
278
+ /** Reactive signal indicating if a checkout redirect is in progress */
279
+ loadingSignal: Signal<boolean>;
280
+ /** Reactive signal containing any error message, or null if no error */
281
+ errorSignal: Signal<string | null>;
282
+ /** Reactive signal indicating if the product is in stock */
283
+ inStockSignal: Signal<boolean>;
284
+ /** Reactive signal indicating if pre-order is available */
285
+ preOrderAvailableSignal: Signal<boolean>;
286
+ /** The name of the product */
287
+ productName: string;
288
+ /** The price of the product as a string */
289
+ price: string;
290
+ /** The currency code for the product price */
291
+ currency: string;
292
+ }, import("@wix/services-definitions").ServiceFactory<string & {
293
+ __api: {
294
+ /** Function to redirect to checkout with the current product */
295
+ redirectToCheckout: () => Promise<void>;
296
+ /** Reactive signal indicating if a checkout redirect is in progress */
297
+ loadingSignal: Signal<boolean>;
298
+ /** Reactive signal containing any error message, or null if no error */
299
+ errorSignal: Signal<string | null>;
300
+ /** Reactive signal indicating if the product is in stock */
301
+ inStockSignal: Signal<boolean>;
302
+ /** Reactive signal indicating if pre-order is available */
303
+ preOrderAvailableSignal: Signal<boolean>;
304
+ /** The name of the product */
305
+ productName: string;
306
+ /** The price of the product as a string */
307
+ price: string;
308
+ /** The currency code for the product price */
309
+ currency: string;
310
+ };
311
+ __config: {};
312
+ isServiceDefinition?: boolean;
313
+ } & {
314
+ /** Function to redirect to checkout with the current product */
315
+ redirectToCheckout: () => Promise<void>;
316
+ /** Reactive signal indicating if a checkout redirect is in progress */
317
+ loadingSignal: Signal<boolean>;
318
+ /** Reactive signal containing any error message, or null if no error */
319
+ errorSignal: Signal<string | null>;
320
+ /** Reactive signal indicating if the product is in stock */
321
+ inStockSignal: Signal<boolean>;
322
+ /** Reactive signal indicating if pre-order is available */
323
+ preOrderAvailableSignal: Signal<boolean>;
324
+ /** The name of the product */
325
+ productName: string;
326
+ /** The price of the product as a string */
327
+ price: string;
328
+ /** The currency code for the product price */
329
+ currency: string;
330
+ }, {
331
+ productId: string;
332
+ variantId?: string;
333
+ productName: string;
334
+ price: string;
335
+ currency: string;
336
+ inStock: boolean;
337
+ preOrderAvailable: boolean;
338
+ }>, {
339
+ productId: string;
340
+ variantId?: string;
341
+ productName: string;
342
+ price: string;
343
+ currency: string;
344
+ inStock: boolean;
345
+ preOrderAvailable: boolean;
346
+ }];
@@ -0,0 +1,197 @@
1
+ import { defineService, implementService } from '@wix/services-definitions';
2
+ import { SignalsServiceDefinition, } from '@wix/services-definitions/core-services/signals';
3
+ import { getCheckoutUrlForProduct } from '../utils/index.js';
4
+ import { getProductBySlug } from '@wix/auto_sdk_stores_products-v-3';
5
+ /**
6
+ * Service definition for the Buy Now service.
7
+ * This defines the reactive API contract for managing buy now functionality.
8
+ *
9
+ * @constant
10
+ */
11
+ export const BuyNowServiceDefinition = defineService('BuyNow');
12
+ /**
13
+ * Implementation of the Buy Now service that manages buy now functionality.
14
+ * This service provides signals for loading state, stock status, and error handling,
15
+ * along with a method to redirect directly to checkout.
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * import { BuyNowServiceImplementation, BuyNowServiceDefinition } from '@wix/stores/services';
20
+ * import { useService } from '@wix/services-manager-react';
21
+ *
22
+ * function BuyNowComponent({ buyNowConfig }) {
23
+ * return (
24
+ * <ServiceProvider services={createServicesMap([
25
+ * [BuyNowServiceDefinition, BuyNowServiceImplementation.withConfig(buyNowConfig)]
26
+ * ])}>
27
+ * <BuyNowButton />
28
+ * </ServiceProvider>
29
+ * );
30
+ * }
31
+ *
32
+ * function BuyNowButton() {
33
+ * const buyNowService = useService(BuyNowServiceDefinition);
34
+ * const isLoading = buyNowService.loadingSignal.get();
35
+ * const error = buyNowService.errorSignal.get();
36
+ * const inStock = buyNowService.inStockSignal.get();
37
+ *
38
+ * const handleBuyNow = async () => {
39
+ * await buyNowService.redirectToCheckout();
40
+ * };
41
+ *
42
+ * return (
43
+ * <div>
44
+ * {error && <div className="error">{error}</div>}
45
+ * <button
46
+ * onClick={handleBuyNow}
47
+ * disabled={!inStock || isLoading}
48
+ * className={`buy-now-btn ${!inStock ? 'out-of-stock' : ''}`}
49
+ * >
50
+ * {isLoading ? 'Processing...' :
51
+ * !inStock ? 'Out of Stock' :
52
+ * `Buy Now - ${buyNowService.currency}${buyNowService.price}`}
53
+ * </button>
54
+ * </div>
55
+ * );
56
+ * }
57
+ * ```
58
+ */
59
+ export const BuyNowServiceImplementation = implementService.withConfig()(BuyNowServiceDefinition, ({ getService, config }) => {
60
+ const signalsService = getService(SignalsServiceDefinition);
61
+ const loadingSignal = signalsService.signal(false);
62
+ const errorSignal = signalsService.signal(null);
63
+ const inStockSignal = signalsService.signal(config.inStock);
64
+ const preOrderAvailableSignal = signalsService.signal(config.preOrderAvailable);
65
+ return {
66
+ redirectToCheckout: async () => {
67
+ loadingSignal.set(true);
68
+ try {
69
+ const checkoutUrl = await getCheckoutUrlForProduct(config.productId, config.variantId);
70
+ window.location.href = checkoutUrl;
71
+ }
72
+ catch (error) {
73
+ errorSignal.set(error.toString());
74
+ loadingSignal.set(false);
75
+ }
76
+ },
77
+ loadingSignal,
78
+ errorSignal,
79
+ inStockSignal,
80
+ preOrderAvailableSignal,
81
+ productName: config.productName,
82
+ price: config.price,
83
+ currency: config.currency,
84
+ };
85
+ });
86
+ /**
87
+ * Loads buy now service initial data from the Wix Stores API for SSR initialization.
88
+ * This function is designed to be used during Server-Side Rendering (SSR) to preload
89
+ * product data required for the buy now functionality.
90
+ *
91
+ * @param {string} productSlug - The product slug to load data for
92
+ * @param {string} [variantId] - Optional variant ID if a specific variant should be used
93
+ * @returns {Promise} Promise that resolves to the buy now service configuration data
94
+ *
95
+ * @example
96
+ * ```astro
97
+ * ---
98
+ * // Astro page example - pages/product/[slug].astro
99
+ * import { loadBuyNowServiceInitialData } from '@wix/stores/services';
100
+ * import { BuyNow } from '@wix/stores/components';
101
+ *
102
+ * const { slug } = Astro.params;
103
+ * const variantId = Astro.url.searchParams.get('variant');
104
+ *
105
+ * // Load buy now data during SSR
106
+ * const buyNowData = await loadBuyNowServiceInitialData(slug, variantId);
107
+ * ---
108
+ *
109
+ * <BuyNow.BuyNow buyNowConfig={buyNowData.BuyNow}>
110
+ * {({ redirectToCheckout, isLoading, inStock, price, currency }) => (
111
+ * <button onClick={redirectToCheckout} disabled={!inStock || isLoading}>
112
+ * {isLoading ? 'Loading...' : `Buy Now ${currency}${price}`}
113
+ * </button>
114
+ * )}
115
+ * </BuyNow.BuyNow>
116
+ * ```
117
+ *
118
+ * @example
119
+ * ```tsx
120
+ * // Next.js page example
121
+ * import { GetServerSideProps } from 'next';
122
+ * import { loadBuyNowServiceInitialData } from '@wix/stores/services';
123
+ *
124
+ * export const getServerSideProps: GetServerSideProps = async ({ params, query }) => {
125
+ * const slug = params?.slug as string;
126
+ * const variantId = query.variant as string | undefined;
127
+ *
128
+ * const buyNowData = await loadBuyNowServiceInitialData(slug, variantId);
129
+ *
130
+ * return {
131
+ * props: {
132
+ * buyNowData,
133
+ * },
134
+ * };
135
+ * };
136
+ * ```
137
+ */
138
+ export const loadBuyNowServiceInitialData = async (productSlug, variantId) => {
139
+ const res = await getProductBySlug(productSlug, {
140
+ fields: ['CURRENCY'],
141
+ });
142
+ const product = res.product;
143
+ const selectedVariant = variantId
144
+ ? product.variantsInfo?.variants?.find((v) => v._id === variantId)
145
+ : product.variantsInfo?.variants?.[0];
146
+ const price = selectedVariant?.price?.actualPrice?.amount ??
147
+ product.actualPriceRange?.minValue?.amount;
148
+ const inStock = selectedVariant?.inventoryStatus?.inStock;
149
+ const preOrderAvailable = selectedVariant?.inventoryStatus?.preorderEnabled;
150
+ return {
151
+ [BuyNowServiceDefinition]: {
152
+ productId: product._id,
153
+ productName: product.name,
154
+ price: price,
155
+ currency: product.currency,
156
+ variantId: selectedVariant?._id,
157
+ inStock,
158
+ preOrderAvailable,
159
+ },
160
+ };
161
+ };
162
+ /**
163
+ * Helper function to create a buy now service binding with configuration.
164
+ * This function simplifies the process of binding the buy now service with its configuration
165
+ * and allows for additional configuration overrides.
166
+ *
167
+ * @template T - Type of the services configurations object
168
+ * @param {T} servicesConfigs - Object containing service configurations
169
+ * @param {Partial<BuyNowServiceConfig>} [additionalConfig={}] - Additional configuration to override defaults
170
+ * @returns Tuple containing service definition, implementation, and merged configuration
171
+ *
172
+ * @example
173
+ * ```tsx
174
+ * import { buyNowServiceBinding, loadBuyNowServiceInitialData } from '@wix/stores/services';
175
+ *
176
+ * // Load initial data
177
+ * const initialData = await loadBuyNowServiceInitialData('my-product-slug');
178
+ *
179
+ * // Create service binding with additional config
180
+ * const buyNowBinding = buyNowServiceBinding(initialData, {
181
+ * inStock: false, // Override stock status
182
+ * });
183
+ *
184
+ * // Use in service provider
185
+ * const services = createServicesMap([buyNowBinding]);
186
+ * ```
187
+ */
188
+ export const buyNowServiceBinding = (servicesConfigs, additionalConfig = {}) => {
189
+ return [
190
+ BuyNowServiceDefinition,
191
+ BuyNowServiceImplementation,
192
+ {
193
+ ...servicesConfigs[BuyNowServiceDefinition],
194
+ ...additionalConfig,
195
+ },
196
+ ];
197
+ };