@kasuvia/sdk 0.0.2 → 0.0.5

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 (77) hide show
  1. package/dist/hooks/index.d.mts +430 -0
  2. package/dist/hooks/index.d.ts +430 -0
  3. package/dist/hooks/index.js +3073 -0
  4. package/dist/hooks/index.js.map +1 -0
  5. package/dist/hooks/index.mjs +2962 -0
  6. package/dist/hooks/index.mjs.map +1 -0
  7. package/dist/index-CxNLI4nw.d.ts +786 -0
  8. package/dist/index-CzVMyUs4.d.mts +492 -0
  9. package/dist/index-CzVMyUs4.d.ts +492 -0
  10. package/dist/index-Dowl5224.d.mts +786 -0
  11. package/dist/index.d.mts +48 -1739
  12. package/dist/index.d.ts +48 -1739
  13. package/dist/index.js +1544 -2359
  14. package/dist/index.js.map +1 -1
  15. package/dist/index.mjs +1527 -2258
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/sdk-context-BuarJbeb.d.ts +75 -0
  18. package/dist/sdk-context-Db8kf1Tv.d.mts +75 -0
  19. package/dist/services/index.d.mts +2 -0
  20. package/dist/services/index.d.ts +2 -0
  21. package/dist/services/index.js +2369 -0
  22. package/dist/services/index.js.map +1 -0
  23. package/dist/services/index.mjs +2252 -0
  24. package/dist/services/index.mjs.map +1 -0
  25. package/package.json +11 -2
  26. package/src/config/index.ts +10 -91
  27. package/src/constants.ts +13 -0
  28. package/src/context/sdk-context.tsx +70 -0
  29. package/src/graphql/collections.graphql.ts +2 -10
  30. package/src/graphql/products.graphql.ts +215 -65
  31. package/src/graphql/wishlist.graphql.ts +7 -6
  32. package/src/hooks/index.ts +2 -0
  33. package/src/hooks/use-auth.ts +82 -158
  34. package/src/hooks/use-bespoke-availability.ts +25 -8
  35. package/src/hooks/use-cart.ts +222 -119
  36. package/src/hooks/use-cms.ts +179 -86
  37. package/src/hooks/use-collections.ts +52 -15
  38. package/src/hooks/use-consultation-stream.ts +4 -3
  39. package/src/hooks/use-consultations.ts +120 -51
  40. package/src/hooks/use-countries.ts +35 -13
  41. package/src/hooks/use-currencies.ts +26 -13
  42. package/src/hooks/use-google-translate.ts +22 -8
  43. package/src/hooks/use-languages.ts +40 -20
  44. package/src/hooks/use-mobile.ts +23 -0
  45. package/src/hooks/use-order-stream.ts +9 -5
  46. package/src/hooks/use-orders.ts +99 -44
  47. package/src/hooks/use-payment.ts +108 -40
  48. package/src/hooks/use-products.ts +251 -53
  49. package/src/hooks/use-service-booking.ts +152 -90
  50. package/src/hooks/use-states.ts +35 -15
  51. package/src/hooks/use-wishlist.ts +92 -91
  52. package/src/index.ts +26 -30
  53. package/src/services/auth.service.ts +209 -167
  54. package/src/services/bespoke.service.ts +12 -4
  55. package/src/services/cart.service.ts +172 -70
  56. package/src/services/cms.service.ts +70 -35
  57. package/src/services/collection.service.ts +22 -5
  58. package/src/services/config.service.ts +34 -14
  59. package/src/services/consultation.service.ts +72 -18
  60. package/src/services/logistics.service.ts +35 -11
  61. package/src/services/notifications.service.ts +27 -12
  62. package/src/services/order.service.ts +74 -15
  63. package/src/services/payment.service.ts +86 -31
  64. package/src/services/product.service.ts +279 -39
  65. package/src/services/service-booking.service.ts +98 -26
  66. package/src/services/wishlist.service.ts +69 -25
  67. package/src/types/auth/index.ts +6 -4
  68. package/src/types/business/index.ts +7 -2
  69. package/src/types/payments/index.ts +3 -3
  70. package/src/types/services/index.ts +2 -5
  71. package/src/types/store/index.ts +38 -3
  72. package/src/utils/error-handler.ts +10 -5
  73. package/src/utils/storage.ts +48 -26
  74. package/src/utils/validators.ts +85 -0
  75. package/src/client/authClient.ts +0 -135
  76. package/src/client/graphqlClient.ts +0 -53
  77. package/src/client/httpClient.ts +0 -298
package/dist/index.js CHANGED
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,45 +15,34 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // src/index.ts
31
21
  var index_exports = {};
32
22
  __export(index_exports, {
33
- AuthCtx: () => AuthCtx,
34
- AuthProvider: () => AuthProvider,
35
- CartCtx: () => CartCtx,
36
- CartProvider: () => CartProvider,
37
23
  InvalidBaseURLError: () => InvalidBaseURLError,
24
+ STORAGE_KEYS: () => STORAGE_KEYS,
25
+ SdkProvider: () => SdkProvider,
26
+ ServiceLocationTypeEnum: () => ServiceLocationTypeEnum,
27
+ ServiceRecurringIntervalEnum: () => ServiceRecurringIntervalEnum,
28
+ ServiceTypeEnum: () => ServiceTypeEnum,
38
29
  acceptQuote: () => acceptQuote,
39
30
  addToCart: () => addToCart,
40
31
  addToGuestCart: () => addToGuestCart,
41
32
  addToWishlist: () => addToWishlist,
42
33
  approveDeliverable: () => approveDeliverable,
43
- authAxios: () => authAxios,
44
34
  bespokeService: () => bespokeService,
45
35
  bookAppointment: () => bookAppointment,
46
36
  buildDeliveryAddress: () => buildDeliveryAddress,
47
- buildFullName: () => buildFullName,
37
+ buildFullName: () => buildFullName2,
48
38
  cancelAppointment: () => cancelAppointment,
49
39
  cancelOrder: () => cancelOrder,
50
40
  checkAvailability: () => checkAvailability,
51
41
  checkInWishlist: () => checkInWishlist,
52
42
  clearCart: () => clearCart,
53
43
  clearGuestCart: () => clearGuestCart,
54
- clearGuestSessionId: () => clearGuestSessionId,
55
- cmsAxios: () => cmsAxios,
56
- collectionKeys: () => collectionKeys,
44
+ clearTokens: () => clearTokens,
57
45
  configService: () => configService,
58
- configureHttpClients: () => configureHttpClients,
59
46
  consultationService: () => consultationService,
60
47
  createCmsEntry: () => createCmsEntry,
61
48
  createConsultation: () => createConsultation,
@@ -69,7 +56,6 @@ __export(index_exports, {
69
56
  getAppointments: () => getAppointments,
70
57
  getAuthUser: () => getAuthUser,
71
58
  getAvailableSlots: () => getAvailableSlots,
72
- getBackendUrl: () => getBackendUrl,
73
59
  getBusinessConfig: () => getBusinessConfig,
74
60
  getCacheTier: () => getCacheTier,
75
61
  getCart: () => getCart,
@@ -77,43 +63,36 @@ __export(index_exports, {
77
63
  getCmsEntry: () => getCmsEntry,
78
64
  getConsultation: () => getConsultation,
79
65
  getConsultations: () => getConsultations,
80
- getCountries: () => getCountries,
81
66
  getCustomerDisplayName: () => getCustomerDisplayName,
82
67
  getDeliverables: () => getDeliverables,
83
68
  getErrorMessage: () => getErrorMessage,
84
69
  getFeaturedProducts: () => getFeaturedProducts,
85
- getGraphQLClient: () => getGraphQLClient,
86
70
  getGuestCart: () => getGuestCart,
87
71
  getGuestCartCount: () => getGuestCartCount,
88
72
  getGuestCartProductType: () => getGuestCartProductType,
89
73
  getGuestCartSubtotal: () => getGuestCartSubtotal,
90
- getGuestSessionId: () => getGuestSessionId,
91
74
  getLatestProducts: () => getLatestProducts,
75
+ getLowStockProducts: () => getLowStockProducts,
92
76
  getMe: () => getMe,
93
77
  getNewProducts: () => getNewProducts,
94
- getOrCreateGuestSessionId: () => getOrCreateGuestSessionId,
78
+ getOnSaleProducts: () => getOnSaleProducts,
95
79
  getOrders: () => getOrders,
96
80
  getPopularProducts: () => getPopularProducts,
97
81
  getRecommendedProducts: () => getRecommendedProducts,
98
- getRuntimeConfig: () => getRuntimeConfig,
99
82
  getSellerShippingAddress: () => getSellerShippingAddress,
100
83
  getShippingRates: () => getShippingRates,
101
- getStates: () => getStates,
84
+ getStoredTokens: () => getStoredTokens,
102
85
  getStorefrontCollectionBySlug: () => getStorefrontCollectionBySlug,
103
86
  getStorefrontCollections: () => getStorefrontCollections,
104
87
  getStorefrontProductBySlug: () => getStorefrontProductBySlug,
105
88
  getStorefrontProducts: () => getStorefrontProducts,
106
89
  getStorefrontUrl: () => getStorefrontUrl,
107
90
  getSupportedCurrencies: () => getSupportedCurrencies,
108
- getSupportedCurrenciesList: () => getSupportedCurrenciesList,
109
91
  getSupportedLanguages: () => getSupportedLanguages,
110
- getSupportedLanguagesList: () => getSupportedLanguagesList,
111
92
  getTransactionStatus: () => getTransactionStatus,
112
93
  getWishlist: () => getWishlist,
113
94
  googleTranslate: () => googleTranslate,
114
- initSdk: () => initSdk,
115
95
  initiatePayment: () => initiatePayment,
116
- isInitialized: () => isInitialized,
117
96
  listCmsEntries: () => listCmsEntries,
118
97
  localStore: () => localStore,
119
98
  logger: () => logger,
@@ -124,10 +103,7 @@ __export(index_exports, {
124
103
  mergeGuestCart: () => mergeGuestCart,
125
104
  mergeGuestCartIfPresent: () => mergeGuestCartIfPresent,
126
105
  notificationsService: () => notificationsService,
127
- paymentAxios: () => paymentAxios,
128
106
  paymentService: () => paymentService,
129
- productKeys: () => productKeys,
130
- publicStoreAxios: () => publicStoreAxios,
131
107
  refreshToken: () => refreshToken,
132
108
  registerCustomer: () => registerCustomer,
133
109
  rejectQuote: () => rejectQuote,
@@ -137,8 +113,6 @@ __export(index_exports, {
137
113
  removeProductFromWishlist: () => removeProductFromWishlist,
138
114
  requestQuote: () => requestQuote,
139
115
  requestRevision: () => requestRevision,
140
- resetConfig: () => resetConfig,
141
- resetGraphQLClient: () => resetGraphQLClient,
142
116
  sanitizeBaseUrl: () => sanitizeBaseUrl,
143
117
  sendContactConfirmation: () => sendContactConfirmation,
144
118
  sendContactEmail: () => sendContactEmail,
@@ -148,647 +122,65 @@ __export(index_exports, {
148
122
  setEnvironmentMode: () => setEnvironmentMode,
149
123
  setLoggerEnvironmentMode: () => setLoggerEnvironmentMode,
150
124
  silentRefresh: () => silentRefresh,
151
- splitFullName: () => splitFullName,
152
- storeManagementAxios: () => storeManagementAxios,
125
+ splitFullName: () => splitFullName2,
153
126
  storeTokens: () => storeTokens,
154
- tokenStore: () => tokenStore,
155
127
  trackOrder: () => trackOrder,
156
128
  updateCartItem: () => updateCartItem,
157
129
  updateCmsEntry: () => updateCmsEntry,
158
130
  updateGuestCartItemQuantity: () => updateGuestCartItemQuantity,
159
131
  updateProfile: () => updateProfile,
160
- useAcceptQuote: () => useAcceptQuote,
161
- useAddToWishlist: () => useAddToWishlist,
162
- useAppointment: () => useAppointment,
163
- useAppointments: () => useAppointments,
164
- useApproveDeliverable: () => useApproveDeliverable,
165
- useAuth: () => useAuth,
166
- useAuthUser: () => useAuthUser,
167
- useAvailableSlots: () => useAvailableSlots,
168
- useBespokeAvailability: () => useBespokeAvailability,
169
- useBookAppointment: () => useBookAppointment,
170
- useCancelAppointment: () => useCancelAppointment,
171
- useCancelOrder: () => useCancelOrder,
172
- useCart: () => useCart,
173
- useCheckInWishlist: () => useCheckInWishlist,
174
- useCmsEntries: () => useCmsEntries,
175
- useCmsEntry: () => useCmsEntry,
176
- useConsultation: () => useConsultation,
177
- useConsultationStream: () => useConsultationStream,
178
- useConsultations: () => useConsultations,
179
- useCountries: () => useCountries,
180
- useCreateCmsEntry: () => useCreateCmsEntry,
181
- useCreateConsultation: () => useCreateConsultation,
182
- useCreateDVA: () => useCreateDVA,
183
- useCreateOrder: () => useCreateOrder,
184
- useCurrencies: () => useCurrencies,
185
- useDeleteCmsEntry: () => useDeleteCmsEntry,
186
- useDeliverables: () => useDeliverables,
187
- useFeaturedProducts: () => useFeaturedProducts,
188
- useFindOrder: () => useFindOrder,
189
- useGoogleTranslate: () => useGoogleTranslate,
190
- useInitiatePayment: () => useInitiatePayment,
191
- useIsMounted: () => useIsMounted,
192
- useLatestProducts: () => useLatestProducts,
193
- useLogin: () => useLogin,
194
- useLogout: () => useLogout,
195
- useNewProducts: () => useNewProducts,
196
- useOrder: () => useOrder,
197
- useOrderStream: () => useOrderStream,
198
- useOrderTracking: () => useOrderTracking,
199
- useOrders: () => useOrders,
200
- useOrdersList: () => useOrdersList,
201
- usePollTransactionStatus: () => usePollTransactionStatus,
202
- usePopularProducts: () => usePopularProducts,
203
- useProduct: () => useProduct,
204
- useRecommendedProducts: () => useRecommendedProducts,
205
- useRegister: () => useRegister,
206
- useRejectQuote: () => useRejectQuote,
207
- useRemoveFromWishlist: () => useRemoveFromWishlist,
208
- useRemoveProductFromWishlist: () => useRemoveProductFromWishlist,
209
- useRequestRevision: () => useRequestRevision,
210
- useSendMessage: () => useSendMessage,
211
- useStates: () => useStates,
212
- useStorefrontCollection: () => useStorefrontCollection,
213
- useStorefrontCollections: () => useStorefrontCollections,
214
- useStorefrontProducts: () => useStorefrontProducts,
215
- useSupportedLanguages: () => useSupportedLanguages,
216
- useTransactionStatus: () => useTransactionStatus,
217
- useUpdateCmsEntry: () => useUpdateCmsEntry,
218
- useUpdateProfile: () => useUpdateProfile,
219
- useVerifyTransaction: () => useVerifyTransaction,
220
- useWishlist: () => useWishlist,
221
- useWishlistCount: () => useWishlistCount,
132
+ useSdkContext: () => useSdkContext,
133
+ validateConfirmPassword: () => validateConfirmPassword,
134
+ validateEmail: () => validateEmail,
135
+ validateMessage: () => validateMessage,
136
+ validateName: () => validateName,
137
+ validatePassword: () => validatePassword,
138
+ validateRequired: () => validateRequired,
222
139
  validateShippingAddress: () => validateShippingAddress,
223
140
  verifySocialToken: () => verifySocialToken,
224
- verifyTransaction: () => verifyTransaction,
225
- wishlistKeys: () => wishlistKeys
141
+ verifyTransaction: () => verifyTransaction
226
142
  });
227
143
  module.exports = __toCommonJS(index_exports);
228
144
 
229
- // src/utils/cache.ts
230
- var CACHE_TIERS = {
231
- none: { staleTime: 0, gcTime: 0 },
232
- infinity: { staleTime: Infinity, gcTime: 0 },
233
- low: { staleTime: 1e3 * 30, gcTime: 1e3 * 60 },
234
- // 30s / 1m
235
- medium: { staleTime: 1e3 * 60 * 5, gcTime: 1e3 * 60 * 10 },
236
- // 5m / 10m
237
- high: { staleTime: 1e3 * 60 * 30, gcTime: 1e3 * 60 * 60 }
238
- // 30m / 1h
239
- };
240
- var isDevelopment = true;
241
- function setEnvironmentMode(development) {
242
- isDevelopment = development;
145
+ // src/context/sdk-context.tsx
146
+ var import_react = require("react");
147
+ var import_jsx_runtime = require("react/jsx-runtime");
148
+ var SdkContext = (0, import_react.createContext)(null);
149
+ function SdkProvider({ config, accessToken, children }) {
150
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SdkContext.Provider, { value: { config, accessToken }, children });
243
151
  }
244
- var getCacheTier = (tier) => {
245
- if (isDevelopment) return CACHE_TIERS.none;
246
- return CACHE_TIERS[tier];
247
- };
248
-
249
- // src/utils/logger.ts
250
- var isDevelopment2 = true;
251
- function setLoggerEnvironmentMode(development) {
252
- isDevelopment2 = development;
152
+ function useSdkContext() {
153
+ return (0, import_react.useContext)(SdkContext);
253
154
  }
254
- var logger = {
255
- log: (...args) => {
256
- if (isDevelopment2) {
257
- console.log(...args);
258
- }
259
- },
260
- warn: (...args) => {
261
- if (isDevelopment2) {
262
- console.warn(...args);
263
- }
264
- },
265
- /**
266
- * Logs a warning to the console in development only.
267
- * Alias for warn() for Python logging compatibility.
268
- * In production, this is a no-op.
269
- */
270
- warning: (...args) => {
271
- if (isDevelopment2) {
272
- console.warn(...args);
273
- }
274
- },
275
- error: (...args) => {
276
- if (isDevelopment2) {
277
- console.error(...args);
278
- }
279
- },
280
- info: (...args) => {
281
- if (isDevelopment2) {
282
- console.info(...args);
283
- }
284
- },
285
- createScope: (scope) => ({
286
- log: (...args) => {
287
- if (isDevelopment2) {
288
- console.log(`[${scope}]`, ...args);
289
- }
290
- },
291
- warn: (...args) => {
292
- if (isDevelopment2) {
293
- console.warn(`[${scope}]`, ...args);
294
- }
295
- },
296
- warning: (...args) => {
297
- if (isDevelopment2) {
298
- console.warn(`[${scope}]`, ...args);
299
- }
300
- },
301
- error: (...args) => {
302
- if (isDevelopment2) {
303
- console.error(`[${scope}]`, ...args);
304
- }
305
- },
306
- info: (...args) => {
307
- if (isDevelopment2) {
308
- console.info(`[${scope}]`, ...args);
309
- }
310
- }
311
- })
312
- };
313
155
 
314
- // src/utils/sanitize-url.ts
315
- var InvalidBaseURLError = class extends Error {
316
- constructor(message) {
317
- super(message);
318
- this.name = "InvalidBaseURLError";
319
- }
156
+ // src/constants.ts
157
+ var STORAGE_KEYS = {
158
+ ACCESS_TOKEN: "kasuvia_access_token",
159
+ REFRESH_TOKEN: "kasuvia_refresh_token",
160
+ CHECKOUT_STATE: "kasuvia_checkout_state",
161
+ ORDERS_LINKED: "kasuvia_orders_linked",
162
+ STOREFRONT_STATE: "storefront_state_v3"
320
163
  };
321
- var ALLOWED_SCHEMES = /* @__PURE__ */ new Set(["http:", "https:", "ws:", "wss:"]);
322
- function sanitizeBaseUrl(url, name = "URL") {
323
- if (url == null) {
324
- throw new InvalidBaseURLError(`${name} is not set`);
325
- }
326
- const cleaned0 = url.trim();
327
- if (!cleaned0) {
328
- throw new InvalidBaseURLError(`${name} is empty`);
329
- }
330
- const cleaned = cleaned0.replace(/\/+$/, "");
331
- let parsed;
332
- try {
333
- parsed = new URL(cleaned);
334
- } catch {
335
- throw new InvalidBaseURLError(
336
- `${name} must start with http://, https://, ws://, or wss://, got: ${url}`
337
- );
338
- }
339
- if (!ALLOWED_SCHEMES.has(parsed.protocol)) {
340
- throw new InvalidBaseURLError(
341
- `${name} must start with http://, https://, ws://, or wss://, got: ${url}`
342
- );
343
- }
344
- if (!parsed.hostname) {
345
- throw new InvalidBaseURLError(`${name} is missing a host: ${url}`);
346
- }
347
- if (parsed.search || parsed.hash) {
348
- throw new InvalidBaseURLError(
349
- `${name} should not contain a query or fragment: ${url}`
350
- );
351
- }
352
- return cleaned;
353
- }
354
-
355
- // src/utils/customer.ts
356
- function buildFullName(firstname, lastname) {
357
- const name = [firstname, lastname].filter(Boolean).join(" ").trim();
358
- return name || void 0;
359
- }
360
- function splitFullName(fullName) {
361
- if (!fullName?.trim()) return { firstname: "", lastname: "" };
362
- const parts = fullName.trim().split(/\s+/);
363
- return {
364
- firstname: parts[0] ?? "",
365
- lastname: parts.slice(1).join(" ")
366
- };
367
- }
368
- function getCustomerDisplayName(user) {
369
- const fromParts = buildFullName(user.firstname, user.lastname);
370
- return fromParts || user.full_name || user.email.split("@")[0];
371
- }
372
- function getStorefrontUrl(businessId, customDomain) {
373
- if (customDomain && customDomain.trim()) {
374
- const cleanDomain = customDomain.trim().replace(/^https?:\/\//, "");
375
- return `https://${cleanDomain}`;
376
- }
377
- const cleanBid = (businessId || "store").toLowerCase().trim();
378
- return `https://${cleanBid}.kasuvia.com`;
379
- }
380
-
381
- // src/utils/checkout.ts
382
- function buildDeliveryAddress(customer, location) {
383
- return {
384
- first_name: customer.first_name,
385
- last_name: customer.last_name,
386
- phone: customer.phone,
387
- ...location
388
- };
389
- }
390
- function getCheckoutCustomerName(customer) {
391
- return buildFullName(customer.first_name, customer.last_name) ?? customer.email.split("@")[0];
392
- }
393
- function enrichCompletedOrder(order, options) {
394
- const customerName = getCheckoutCustomerName(options.customer);
395
- return {
396
- ...order,
397
- customerName: order.customerName || customerName,
398
- customerEmail: order.customerEmail || options.customer.email,
399
- shippingAddress: order.shippingAddress ?? (options.productType === "physical" && options.location ? buildDeliveryAddress(options.customer, options.location) : void 0),
400
- bespokeBrief: order.bespokeBrief ?? options.bespokeBrief
401
- };
402
- }
403
-
404
- // src/utils/error-handler.ts
405
- var import_axios = __toESM(require("axios"));
406
- function getErrorMessage(error, fallback = "Something went wrong") {
407
- if (import_axios.default.isAxiosError(error)) {
408
- return error.response?.data?.detail || error.response?.data?.message || error.message || fallback;
409
- }
410
- if (error instanceof Error) {
411
- return error.message;
412
- }
413
- return fallback;
414
- }
415
-
416
- // src/config/index.ts
417
- var runtimeConfig = null;
418
- var BACKEND_URLS = {
419
- auth: "https://127.0.0.1:8000/api/v1",
420
- store: "https://127.0.0.1:8001/api/v1",
421
- payment: "https://127.0.0.1:8002/api/v1",
422
- notifications: "https://127.0.0.1:8007/api/v1",
423
- cms: "https://127.0.0.1:8009/api/v1"
424
- };
425
- function initSdk(config) {
426
- runtimeConfig = {
427
- businessId: config.businessId,
428
- storefrontApiKey: config.storefrontApiKey
429
- };
430
- const isDevelopment3 = typeof window === "undefined" && globalThis.process?.env?.NODE_ENV === "development";
431
- setEnvironmentMode(isDevelopment3);
432
- setLoggerEnvironmentMode(isDevelopment3);
433
- logger.log("SDK initialized with businessId:", config.businessId);
434
- }
435
- function getRuntimeConfig() {
436
- if (!runtimeConfig) {
437
- throw new Error("SDK not initialized. Call initSdk() before using SDK functions.");
438
- }
439
- return runtimeConfig;
440
- }
441
- function getBackendUrl(service) {
442
- return BACKEND_URLS[service];
443
- }
444
- function isInitialized() {
445
- return runtimeConfig !== null;
446
- }
447
- function resetConfig() {
448
- runtimeConfig = null;
449
- }
450
-
451
- // src/client/httpClient.ts
452
- var import_axios3 = __toESM(require("axios"));
453
-
454
- // src/client/authClient.ts
455
- var import_axios2 = __toESM(require("axios"));
456
- var _accessToken = null;
457
- var _isRefreshing = false;
458
- var _pendingQueue = [];
459
- function getStorageKey() {
460
- if (!isInitialized()) return "kasuvia-sf-anon-refresh";
461
- const config = getRuntimeConfig();
462
- return `kasuvia-sf-${config.businessId}-refresh`;
463
- }
464
- function drainQueue(error, newToken = null) {
465
- _pendingQueue.forEach(({ resolve, reject }) => {
466
- if (newToken) resolve(newToken);
467
- else reject(error);
468
- });
469
- _pendingQueue = [];
470
- }
471
- var tokenStore = {
472
- getAccessToken: () => _accessToken,
473
- setAccessToken: (token) => {
474
- _accessToken = token;
475
- },
476
- getRefreshToken: () => {
477
- if (typeof window === "undefined") return null;
478
- const key = getStorageKey();
479
- return localStorage.getItem(key) || sessionStorage.getItem(key);
480
- },
481
- setRefreshToken: (token, remember = true) => {
482
- if (typeof window === "undefined") return;
483
- const key = getStorageKey();
484
- localStorage.removeItem(key);
485
- sessionStorage.removeItem(key);
486
- if (token) {
487
- const store = remember ? localStorage : sessionStorage;
488
- store.setItem(key, token);
489
- }
490
- },
491
- clearAll: () => {
492
- _accessToken = null;
493
- if (typeof window !== "undefined") {
494
- const key = getStorageKey();
495
- localStorage.removeItem(key);
496
- sessionStorage.removeItem(key);
497
- }
498
- },
499
- hasSession: () => {
500
- if (typeof window === "undefined") return false;
501
- const key = getStorageKey();
502
- return !!(localStorage.getItem(key) || sessionStorage.getItem(key));
503
- },
504
- isPersistent: () => {
505
- if (typeof window === "undefined") return true;
506
- const key = getStorageKey();
507
- return !!localStorage.getItem(key);
508
- }
509
- };
510
- var refreshAxios = import_axios2.default.create({
511
- baseURL: getBackendUrl("auth"),
512
- headers: {
513
- "Content-Type": "application/json",
514
- Accept: "application/json"
515
- },
516
- withCredentials: true,
517
- timeout: 3e4
518
- });
519
- async function refreshToken() {
520
- if (_isRefreshing) {
521
- return new Promise((resolve, reject) => {
522
- _pendingQueue.push({ resolve, reject });
523
- });
524
- }
525
- _isRefreshing = true;
526
- const refresh = tokenStore.getRefreshToken();
527
- if (!refresh) {
528
- _isRefreshing = false;
529
- tokenStore.clearAll();
530
- throw new Error("[kasuvia SDK] No refresh token available");
531
- }
532
- try {
533
- const { data } = await refreshAxios.post("/auth/token/refresh/", { refresh });
534
- const newAccess = data.access;
535
- tokenStore.setAccessToken(newAccess);
536
- if (data.refresh) {
537
- tokenStore.setRefreshToken(data.refresh, tokenStore.isPersistent());
538
- }
539
- drainQueue(null, newAccess);
540
- return newAccess;
541
- } catch (err) {
542
- drainQueue(err);
543
- tokenStore.clearAll();
544
- throw err;
545
- } finally {
546
- _isRefreshing = false;
547
- }
548
- }
549
-
550
- // src/client/httpClient.ts
551
- var _guestSessionId = null;
552
- function getOrCreateGuestSessionId() {
553
- if (_guestSessionId) return _guestSessionId;
554
- const storageKey = isInitialized() ? `kasuvia-guest-${getRuntimeConfig().businessId}` : "kasuvia-guest-anon";
555
- if (typeof window !== "undefined") {
556
- _guestSessionId = sessionStorage.getItem(storageKey) || crypto.randomUUID();
557
- sessionStorage.setItem(storageKey, _guestSessionId);
558
- } else {
559
- _guestSessionId = crypto.randomUUID();
560
- }
561
- return _guestSessionId;
562
- }
563
- function getGuestSessionId() {
564
- if (!_guestSessionId && typeof window !== "undefined") {
565
- const storageKey = isInitialized() ? `kasuvia-guest-${getRuntimeConfig().businessId}` : "kasuvia-guest-anon";
566
- _guestSessionId = sessionStorage.getItem(storageKey);
567
- }
568
- return _guestSessionId;
569
- }
570
- function clearGuestSessionId() {
571
- _guestSessionId = null;
572
- if (typeof window !== "undefined") {
573
- const storageKey = isInitialized() ? `kasuvia-guest-${getRuntimeConfig().businessId}` : "kasuvia-guest-anon";
574
- sessionStorage.removeItem(storageKey);
575
- }
576
- }
577
- var storeManagementAxios = import_axios3.default.create({
578
- baseURL: getBackendUrl("store"),
579
- headers: {
580
- "Content-Type": "application/json",
581
- Accept: "application/json"
582
- },
583
- timeout: 3e4
584
- });
585
- storeManagementAxios.interceptors.request.use((cfg) => {
586
- const config = getRuntimeConfig();
587
- const token = tokenStore.getAccessToken();
588
- if (token) {
589
- cfg.headers = cfg.headers ?? {};
590
- cfg.headers["Authorization"] = `Bearer ${token}`;
591
- }
592
- cfg.headers = cfg.headers ?? {};
593
- cfg.headers["X-Storefront-Key"] = config.storefrontApiKey;
594
- cfg.headers["X-Business-ID"] = config.businessId;
595
- if (!token) {
596
- const sid = getOrCreateGuestSessionId();
597
- if (sid) cfg.headers["X-Guest-Session"] = sid;
598
- }
599
- return cfg;
600
- });
601
- storeManagementAxios.interceptors.response.use(
602
- (res) => res,
603
- async (err) => {
604
- const originalRequest = err.config;
605
- if (!originalRequest) return Promise.reject(err);
606
- const status = err.response?.status;
607
- const isUnauthorized = status === 401;
608
- const isRefreshEndpoint = originalRequest.url?.includes("/auth/token/refresh/");
609
- const alreadyRetried = originalRequest._retry === true;
610
- if (isUnauthorized && isRefreshEndpoint) {
611
- tokenStore.clearAll();
612
- return Promise.reject(err);
613
- }
614
- if (!isUnauthorized || alreadyRetried) return Promise.reject(err);
615
- try {
616
- const newToken = await refreshToken();
617
- originalRequest._retry = true;
618
- if (originalRequest.headers) {
619
- originalRequest.headers["Authorization"] = `Bearer ${newToken}`;
620
- }
621
- return storeManagementAxios(originalRequest);
622
- } catch (refreshErr) {
623
- tokenStore.clearAll();
624
- return Promise.reject(refreshErr);
625
- }
626
- }
627
- );
628
- var publicStoreAxios = import_axios3.default.create({
629
- baseURL: getBackendUrl("store"),
630
- headers: {
631
- "Content-Type": "application/json",
632
- Accept: "application/json"
633
- },
634
- timeout: 3e4
635
- });
636
- publicStoreAxios.interceptors.request.use((cfg) => {
637
- const config = getRuntimeConfig();
638
- cfg.headers = cfg.headers ?? {};
639
- cfg.headers["X-Storefront-Key"] = config.storefrontApiKey;
640
- cfg.headers["X-Business-ID"] = config.businessId;
641
- return cfg;
642
- });
643
- publicStoreAxios.interceptors.response.use(
644
- (res) => res,
645
- (err) => Promise.reject(err)
646
- );
647
- var authAxios = import_axios3.default.create({
648
- baseURL: getBackendUrl("auth"),
649
- headers: {
650
- "Content-Type": "application/json",
651
- Accept: "application/json"
652
- },
653
- withCredentials: true,
654
- timeout: 3e4
655
- });
656
- authAxios.interceptors.request.use((cfg) => {
657
- const config = getRuntimeConfig();
658
- const token = tokenStore.getAccessToken();
659
- if (token) {
660
- cfg.headers = cfg.headers ?? {};
661
- cfg.headers["Authorization"] = `Bearer ${token}`;
662
- }
663
- cfg.headers = cfg.headers ?? {};
664
- cfg.headers["X-Storefront-Key"] = config.storefrontApiKey;
665
- cfg.headers["X-Business-ID"] = config.businessId;
666
- return cfg;
667
- });
668
- authAxios.interceptors.response.use(
669
- (res) => res,
670
- async (err) => {
671
- const originalRequest = err.config;
672
- if (!originalRequest) return Promise.reject(err);
673
- const status = err.response?.status;
674
- const isUnauthorized = status === 401;
675
- const isRefreshEndpoint = originalRequest.url?.includes("/auth/token/refresh/");
676
- const alreadyRetried = originalRequest._retry === true;
677
- if (isUnauthorized && isRefreshEndpoint) {
678
- tokenStore.clearAll();
679
- return Promise.reject(err);
680
- }
681
- if (!isUnauthorized || alreadyRetried) return Promise.reject(err);
682
- try {
683
- const newToken = await refreshToken();
684
- originalRequest._retry = true;
685
- if (originalRequest.headers) {
686
- originalRequest.headers["Authorization"] = `Bearer ${newToken}`;
687
- }
688
- return authAxios(originalRequest);
689
- } catch (refreshErr) {
690
- tokenStore.clearAll();
691
- return Promise.reject(refreshErr);
692
- }
693
- }
694
- );
695
- var paymentAxios = import_axios3.default.create({
696
- baseURL: getBackendUrl("payment"),
697
- headers: {
698
- "Content-Type": "application/json",
699
- Accept: "application/json"
700
- },
701
- timeout: 3e4
702
- });
703
- paymentAxios.interceptors.request.use((cfg) => {
704
- const config = getRuntimeConfig();
705
- cfg.headers = cfg.headers ?? {};
706
- cfg.headers["X-Storefront-Key"] = config.storefrontApiKey;
707
- cfg.headers["X-Business-ID"] = config.businessId;
708
- return cfg;
709
- });
710
- paymentAxios.interceptors.response.use(
711
- (res) => res,
712
- (err) => Promise.reject(err)
713
- );
714
- var notificationsAxios = import_axios3.default.create({
715
- baseURL: getBackendUrl("notifications"),
716
- headers: {
717
- "Content-Type": "application/json",
718
- Accept: "application/json"
719
- },
720
- timeout: 3e4
721
- });
722
- notificationsAxios.interceptors.response.use(
723
- (res) => res,
724
- (err) => Promise.reject(err)
725
- );
726
- var cmsAxios = import_axios3.default.create({
727
- baseURL: getBackendUrl("cms"),
728
- headers: {
729
- "Content-Type": "application/json",
730
- Accept: "application/json"
731
- },
732
- timeout: 3e4
733
- });
734
- cmsAxios.interceptors.request.use((cfg) => {
735
- const config = getRuntimeConfig();
736
- cfg.headers = cfg.headers ?? {};
737
- cfg.headers["X-Storefront-Key"] = config.storefrontApiKey;
738
- cfg.headers["X-Business-ID"] = config.businessId;
739
- return cfg;
740
- });
741
- cmsAxios.interceptors.response.use(
742
- (res) => res,
743
- (err) => Promise.reject(err)
744
- );
745
- var refreshAxios2 = import_axios3.default.create({
746
- baseURL: getBackendUrl("auth"),
747
- headers: {
748
- "Content-Type": "application/json",
749
- Accept: "application/json"
750
- },
751
- withCredentials: true,
752
- timeout: 3e4
753
- });
754
- function configureHttpClients() {
755
- if (!isInitialized()) return;
756
- const storeUrl = getBackendUrl("store");
757
- const authUrl = getBackendUrl("auth");
758
- const paymentUrl = getBackendUrl("payment");
759
- const notificationsUrl = getBackendUrl("notifications");
760
- const cmsUrl = getBackendUrl("cms");
761
- storeManagementAxios.defaults.baseURL = storeUrl;
762
- publicStoreAxios.defaults.baseURL = storeUrl;
763
- authAxios.defaults.baseURL = authUrl;
764
- paymentAxios.defaults.baseURL = paymentUrl;
765
- notificationsAxios.defaults.baseURL = notificationsUrl;
766
- cmsAxios.defaults.baseURL = cmsUrl;
767
- refreshAxios2.defaults.baseURL = authUrl;
768
- }
769
164
 
770
- // src/client/graphqlClient.ts
771
- var import_graphql_request = require("graphql-request");
772
- var GRAPHQL_URL = `${getBackendUrl("store")}/graphql`;
773
- function buildHeaders() {
774
- const headers = {
775
- "Content-Type": "application/json",
776
- Accept: "application/json"
777
- };
778
- if (isInitialized()) {
779
- const config = getRuntimeConfig();
780
- headers["X-Storefront-Key"] = config.storefrontApiKey;
781
- headers["X-Business-ID"] = config.businessId;
782
- }
783
- const token = tokenStore.getAccessToken();
784
- if (token) headers["Authorization"] = `Bearer ${token}`;
785
- return headers;
786
- }
787
- function getGraphQLClient() {
788
- return new import_graphql_request.GraphQLClient(GRAPHQL_URL, { headers: buildHeaders() });
789
- }
790
- function resetGraphQLClient() {
791
- }
165
+ // src/types/store/index.ts
166
+ var ServiceTypeEnum = /* @__PURE__ */ ((ServiceTypeEnum2) => {
167
+ ServiceTypeEnum2["APPOINTMENT"] = "appointment";
168
+ ServiceTypeEnum2["PROJECT"] = "project";
169
+ ServiceTypeEnum2["RECURRING"] = "recurring";
170
+ return ServiceTypeEnum2;
171
+ })(ServiceTypeEnum || {});
172
+ var ServiceLocationTypeEnum = /* @__PURE__ */ ((ServiceLocationTypeEnum2) => {
173
+ ServiceLocationTypeEnum2["REMOTE"] = "remote";
174
+ ServiceLocationTypeEnum2["PHYSICAL"] = "physical";
175
+ ServiceLocationTypeEnum2["BOTH"] = "both";
176
+ return ServiceLocationTypeEnum2;
177
+ })(ServiceLocationTypeEnum || {});
178
+ var ServiceRecurringIntervalEnum = /* @__PURE__ */ ((ServiceRecurringIntervalEnum2) => {
179
+ ServiceRecurringIntervalEnum2["WEEKLY"] = "weekly";
180
+ ServiceRecurringIntervalEnum2["MONTHLY"] = "monthly";
181
+ ServiceRecurringIntervalEnum2["YEARLY"] = "yearly";
182
+ return ServiceRecurringIntervalEnum2;
183
+ })(ServiceRecurringIntervalEnum || {});
792
184
 
793
185
  // src/services/cart.service.ts
794
186
  function parseItems(items) {
@@ -797,21 +189,25 @@ function parseItems(items) {
797
189
  variant_attributes: item.variant_attributes && typeof item.variant_attributes === "string" ? JSON.parse(item.variant_attributes) : item.variant_attributes
798
190
  }));
799
191
  }
800
- async function getGuestCart() {
801
- const sid = getGuestSessionId();
802
- if (!sid) return [];
192
+ async function getGuestCart(config, guestSessionId) {
193
+ if (!guestSessionId) return [];
803
194
  try {
804
- const { data } = await storeManagementAxios.get("cart/", {
805
- headers: { "X-Guest-Session": sid }
195
+ const response = await fetch(`${config.backendUrls.store}/cart/`, {
196
+ headers: {
197
+ "X-Storefront-Key": config.storefrontApiKey,
198
+ "X-Business-ID": config.businessId,
199
+ "X-Guest-Session": guestSessionId
200
+ }
806
201
  });
202
+ if (!response.ok) return [];
203
+ const data = await response.json();
807
204
  return parseItems(data.items || []);
808
205
  } catch {
809
206
  return [];
810
207
  }
811
208
  }
812
- async function addToGuestCart(item) {
813
- const sid = getOrCreateGuestSessionId();
814
- if (!sid) return [];
209
+ async function addToGuestCart(config, guestSessionId, item) {
210
+ if (!guestSessionId) return [];
815
211
  const payload = {
816
212
  product_id: item.product_id,
817
213
  product_slug: item.product_slug,
@@ -824,66 +220,132 @@ async function addToGuestCart(item) {
824
220
  custom_measurements: item.custom_measurements,
825
221
  is_bespoke: item.is_bespoke
826
222
  };
827
- const { data } = await storeManagementAxios.post("cart/", payload, {
828
- headers: { "X-Guest-Session": sid }
223
+ const response = await fetch(`${config.backendUrls.store}/cart/`, {
224
+ method: "POST",
225
+ headers: {
226
+ "Content-Type": "application/json",
227
+ "X-Storefront-Key": config.storefrontApiKey,
228
+ "X-Business-ID": config.businessId,
229
+ "X-Guest-Session": guestSessionId
230
+ },
231
+ body: JSON.stringify(payload)
829
232
  });
233
+ if (!response.ok) return [];
234
+ const data = await response.json();
830
235
  return parseItems(data.items || []);
831
236
  }
832
- async function updateGuestCartItemQuantity(itemId, quantity) {
833
- const sid = getGuestSessionId();
834
- if (!sid) return [];
835
- const { data } = await storeManagementAxios.patch(
836
- `cart/${itemId}`,
837
- { quantity },
838
- { headers: { "X-Guest-Session": sid } }
839
- );
237
+ async function updateGuestCartItemQuantity(config, guestSessionId, itemId, quantity) {
238
+ if (!guestSessionId) return [];
239
+ const response = await fetch(`${config.backendUrls.store}/cart/${itemId}`, {
240
+ method: "PATCH",
241
+ headers: {
242
+ "Content-Type": "application/json",
243
+ "X-Storefront-Key": config.storefrontApiKey,
244
+ "X-Business-ID": config.businessId,
245
+ "X-Guest-Session": guestSessionId
246
+ },
247
+ body: JSON.stringify({ quantity })
248
+ });
249
+ if (!response.ok) return [];
250
+ const data = await response.json();
840
251
  return parseItems(data.items || []);
841
252
  }
842
- async function removeFromGuestCart(itemId) {
843
- const sid = getGuestSessionId();
844
- if (!sid) return [];
845
- await storeManagementAxios.delete(`cart/${itemId}`, {
846
- headers: { "X-Guest-Session": sid }
253
+ async function removeFromGuestCart(config, guestSessionId, itemId) {
254
+ if (!guestSessionId) return [];
255
+ await fetch(`${config.backendUrls.store}/cart/${itemId}`, {
256
+ method: "DELETE",
257
+ headers: {
258
+ "X-Storefront-Key": config.storefrontApiKey,
259
+ "X-Business-ID": config.businessId,
260
+ "X-Guest-Session": guestSessionId
261
+ }
847
262
  });
848
- return getGuestCart();
263
+ return getGuestCart(config, guestSessionId);
849
264
  }
850
- async function clearGuestCart() {
851
- const sid = getGuestSessionId();
852
- if (!sid) return;
853
- await storeManagementAxios.delete("cart/clear", {
854
- headers: { "X-Guest-Session": sid }
265
+ async function clearGuestCart(config, guestSessionId) {
266
+ if (!guestSessionId) return;
267
+ await fetch(`${config.backendUrls.store}/cart/clear`, {
268
+ method: "DELETE",
269
+ headers: {
270
+ "X-Storefront-Key": config.storefrontApiKey,
271
+ "X-Business-ID": config.businessId,
272
+ "X-Guest-Session": guestSessionId
273
+ }
855
274
  });
856
275
  }
857
- async function getCart() {
858
- const { data } = await storeManagementAxios.get("cart/");
276
+ async function getCart(config, accessToken) {
277
+ if (!accessToken) {
278
+ return { id: "", items: [], subtotal: 0, total: 0, product_type: "physical" };
279
+ }
280
+ const response = await fetch(`${config.backendUrls.store}/cart/`, {
281
+ headers: {
282
+ "Authorization": `Bearer ${accessToken}`,
283
+ "X-Storefront-Key": config.storefrontApiKey,
284
+ "X-Business-ID": config.businessId
285
+ }
286
+ });
287
+ if (!response.ok) throw new Error("Failed to fetch cart");
288
+ const data = await response.json();
859
289
  const parsedItems = parseItems(data.items || []);
860
290
  return { ...data, items: parsedItems };
861
291
  }
862
- async function addToCart(item) {
863
- const { data } = await storeManagementAxios.post("cart/", item);
292
+ async function addToCart(config, accessToken, item) {
293
+ const response = await fetch(`${config.backendUrls.store}/cart/`, {
294
+ method: "POST",
295
+ headers: {
296
+ "Content-Type": "application/json",
297
+ "Authorization": `Bearer ${accessToken}`,
298
+ "X-Storefront-Key": config.storefrontApiKey,
299
+ "X-Business-ID": config.businessId
300
+ },
301
+ body: JSON.stringify(item)
302
+ });
303
+ if (!response.ok) throw new Error("Failed to add to cart");
304
+ const data = await response.json();
864
305
  const parsedItems = parseItems(data.items || []);
865
306
  return { ...data, items: parsedItems };
866
307
  }
867
- async function updateCartItem(itemId, quantity) {
868
- const { data } = await storeManagementAxios.patch(
869
- `cart/${itemId}`,
870
- { quantity }
871
- );
308
+ async function updateCartItem(config, accessToken, itemId, quantity) {
309
+ const response = await fetch(`${config.backendUrls.store}/cart/${itemId}`, {
310
+ method: "PATCH",
311
+ headers: {
312
+ "Content-Type": "application/json",
313
+ "Authorization": `Bearer ${accessToken}`,
314
+ "X-Storefront-Key": config.storefrontApiKey,
315
+ "X-Business-ID": config.businessId
316
+ },
317
+ body: JSON.stringify({ quantity })
318
+ });
319
+ if (!response.ok) throw new Error("Failed to update cart item");
320
+ const data = await response.json();
872
321
  const parsedItems = parseItems(data.items || []);
873
322
  return { ...data, items: parsedItems };
874
323
  }
875
- async function removeFromCart(itemId) {
876
- await storeManagementAxios.delete(`cart/${itemId}`);
877
- return getCart();
324
+ async function removeFromCart(config, accessToken, itemId) {
325
+ await fetch(`${config.backendUrls.store}/cart/${itemId}`, {
326
+ method: "DELETE",
327
+ headers: {
328
+ "Authorization": `Bearer ${accessToken}`,
329
+ "X-Storefront-Key": config.storefrontApiKey,
330
+ "X-Business-ID": config.businessId
331
+ }
332
+ });
333
+ return getCart(config, accessToken);
878
334
  }
879
- async function clearCart() {
880
- await storeManagementAxios.delete("cart/clear");
335
+ async function clearCart(config, accessToken) {
336
+ await fetch(`${config.backendUrls.store}/cart/clear`, {
337
+ method: "DELETE",
338
+ headers: {
339
+ "Authorization": `Bearer ${accessToken}`,
340
+ "X-Storefront-Key": config.storefrontApiKey,
341
+ "X-Business-ID": config.businessId
342
+ }
343
+ });
881
344
  }
882
- async function mergeGuestCart() {
883
- const sid = getGuestSessionId();
884
- const guestItems = sid ? await getGuestCart() : [];
345
+ async function mergeGuestCart(config, accessToken, guestSessionId) {
346
+ const guestItems = guestSessionId ? await getGuestCart(config, guestSessionId) : [];
885
347
  if (guestItems.length === 0) {
886
- return getCart();
348
+ return getCart(config, accessToken);
887
349
  }
888
350
  const payloadItems = guestItems.map((item) => ({
889
351
  product_id: item.product_id,
@@ -897,19 +359,29 @@ async function mergeGuestCart() {
897
359
  custom_measurements: typeof item.custom_measurements === "string" ? item.custom_measurements : JSON.stringify(item.custom_measurements ?? {}),
898
360
  is_bespoke: item.is_bespoke
899
361
  }));
900
- const { data } = await storeManagementAxios.post(
901
- "cart/merge",
902
- { items: payloadItems },
903
- sid ? { headers: { "X-Guest-Session": sid } } : {}
904
- );
905
- clearGuestSessionId();
362
+ const headers = {
363
+ "Content-Type": "application/json",
364
+ "Authorization": `Bearer ${accessToken}`,
365
+ "X-Storefront-Key": config.storefrontApiKey,
366
+ "X-Business-ID": config.businessId
367
+ };
368
+ if (guestSessionId) {
369
+ headers["X-Guest-Session"] = guestSessionId;
370
+ }
371
+ const response = await fetch(`${config.backendUrls.store}/cart/merge`, {
372
+ method: "POST",
373
+ headers,
374
+ body: JSON.stringify({ items: payloadItems })
375
+ });
376
+ if (!response.ok) throw new Error("Failed to merge guest cart");
377
+ const data = await response.json();
906
378
  return { ...data, items: parseItems(data.items || []) };
907
379
  }
908
- async function mergeGuestCartIfPresent() {
380
+ async function mergeGuestCartIfPresent(config, accessToken, guestSessionId) {
909
381
  try {
910
- const guestItems = await getGuestCart();
382
+ const guestItems = await getGuestCart(config, guestSessionId);
911
383
  if (guestItems.length === 0) return;
912
- await mergeGuestCart();
384
+ await mergeGuestCart(config, accessToken, guestSessionId);
913
385
  } catch (error) {
914
386
  console.warn("[Cart] Failed to merge guest cart:", error);
915
387
  }
@@ -983,88 +455,173 @@ function normaliseStorefrontOrder(raw) {
983
455
  guestName: raw.guest_name
984
456
  };
985
457
  }
986
- async function createOrder(payload) {
987
- const { data } = await storeManagementAxios.post("orders/storefront", payload);
458
+ async function createOrder(config, accessToken, payload) {
459
+ const response = await fetch(`${config.backendUrls.store}/orders/storefront`, {
460
+ method: "POST",
461
+ headers: {
462
+ "Content-Type": "application/json",
463
+ "Authorization": `Bearer ${accessToken}`,
464
+ "X-Storefront-Key": config.storefrontApiKey,
465
+ "X-Business-ID": config.businessId
466
+ },
467
+ body: JSON.stringify(payload)
468
+ });
469
+ if (!response.ok) throw new Error("Failed to create order");
470
+ const data = await response.json();
988
471
  return normaliseStorefrontOrder(data);
989
472
  }
990
- async function findOrder(params) {
991
- const { data } = await publicStoreAxios.get("orders/find/", { params });
473
+ async function findOrder(config, params) {
474
+ const queryParams = new URLSearchParams();
475
+ if (params.email) queryParams.set("email", params.email);
476
+ if (params.order_id) queryParams.set("order_id", params.order_id);
477
+ if (params.guest_token) queryParams.set("guest_token", params.guest_token);
478
+ const response = await fetch(`${config.backendUrls.store}/orders/find/?${queryParams.toString()}`, {
479
+ headers: {
480
+ "X-Storefront-Key": config.storefrontApiKey,
481
+ "X-Business-ID": config.businessId
482
+ }
483
+ });
484
+ if (!response.ok) throw new Error("Failed to find order");
485
+ const data = await response.json();
992
486
  return normaliseStorefrontOrder(data);
993
487
  }
994
- async function findOrderByToken(token) {
995
- const { data } = await publicStoreAxios.get("orders/find/", {
996
- params: { guest_token: token }
488
+ async function findOrderByToken(config, token) {
489
+ const response = await fetch(`${config.backendUrls.store}/orders/find/?guest_token=${token}`, {
490
+ headers: {
491
+ "X-Storefront-Key": config.storefrontApiKey,
492
+ "X-Business-ID": config.businessId
493
+ }
997
494
  });
495
+ if (!response.ok) throw new Error("Failed to find order by token");
496
+ const data = await response.json();
998
497
  return normaliseStorefrontOrder(data);
999
498
  }
1000
- async function getOrders(params) {
1001
- const { data } = await storeManagementAxios.get("orders/", { params });
499
+ async function getOrders(config, accessToken, params) {
500
+ const queryParams = new URLSearchParams();
501
+ if (params?.email) queryParams.set("email", params.email);
502
+ if (params?.page) queryParams.set("page", params.page.toString());
503
+ if (params?.page_size) queryParams.set("page_size", params.page_size.toString());
504
+ const response = await fetch(`${config.backendUrls.store}/orders/?${queryParams.toString()}`, {
505
+ headers: {
506
+ "Authorization": `Bearer ${accessToken}`,
507
+ "X-Storefront-Key": config.storefrontApiKey,
508
+ "X-Business-ID": config.businessId
509
+ }
510
+ });
511
+ if (!response.ok) throw new Error("Failed to get orders");
512
+ const data = await response.json();
1002
513
  const items = Array.isArray(data) ? data : data.items ?? [];
1003
514
  return items.map(normaliseStorefrontOrder);
1004
515
  }
1005
- async function cancelOrder(orderId, reason) {
1006
- const { data } = await storeManagementAxios.post(`orders/${orderId}/cancel/`, { reason });
516
+ async function cancelOrder(config, accessToken, orderId, reason) {
517
+ const response = await fetch(`${config.backendUrls.store}/orders/${orderId}/cancel/`, {
518
+ method: "POST",
519
+ headers: {
520
+ "Content-Type": "application/json",
521
+ "Authorization": `Bearer ${accessToken}`,
522
+ "X-Storefront-Key": config.storefrontApiKey,
523
+ "X-Business-ID": config.businessId
524
+ },
525
+ body: JSON.stringify({ reason })
526
+ });
527
+ if (!response.ok) throw new Error("Failed to cancel order");
528
+ const data = await response.json();
1007
529
  return normaliseStorefrontOrder(data);
1008
530
  }
1009
- async function trackOrder(orderId, token) {
1010
- const { data } = await publicStoreAxios.get(`orders/track/${orderId}`, {
1011
- params: token ? { token } : void 0
531
+ async function trackOrder(config, orderId, token) {
532
+ const queryParams = token ? `?token=${token}` : "";
533
+ const response = await fetch(`${config.backendUrls.store}/orders/track/${orderId}${queryParams}`, {
534
+ headers: {
535
+ "X-Storefront-Key": config.storefrontApiKey,
536
+ "X-Business-ID": config.businessId
537
+ }
1012
538
  });
539
+ if (!response.ok) throw new Error("Failed to track order");
540
+ const data = await response.json();
1013
541
  return normaliseStorefrontOrder(data);
1014
542
  }
1015
543
 
1016
544
  // src/services/auth.service.ts
1017
- async function loginCustomer(payload) {
1018
- const config = getRuntimeConfig();
1019
- const { data } = await authAxios.post("/auth/login/customer/", {
1020
- ...payload,
1021
- tenant_id: config.businessId
545
+ async function loginCustomer(config, payload) {
546
+ const response = await fetch(`${config.backendUrls.auth}/auth/login/customer/`, {
547
+ method: "POST",
548
+ headers: {
549
+ "Content-Type": "application/json",
550
+ "X-Storefront-Key": config.storefrontApiKey,
551
+ "X-Business-ID": config.businessId
552
+ },
553
+ body: JSON.stringify({
554
+ ...payload,
555
+ tenant_id: config.businessId
556
+ })
1022
557
  });
1023
- tokenStore.setAccessToken(data.access);
1024
- tokenStore.setRefreshToken(data.refresh);
1025
- resetGraphQLClient();
1026
- await mergeGuestCartIfPresent();
558
+ if (!response.ok) {
559
+ throw new Error("Login failed");
560
+ }
561
+ const data = await response.json();
1027
562
  return data;
1028
563
  }
1029
- async function registerCustomer(payload) {
1030
- const config = getRuntimeConfig();
1031
- const { data } = await authAxios.post("/auth/register/customer/", {
1032
- ...payload,
1033
- tenant_id: config.businessId
564
+ async function registerCustomer(config, payload) {
565
+ const response = await fetch(`${config.backendUrls.auth}/auth/register/customer/`, {
566
+ method: "POST",
567
+ headers: {
568
+ "Content-Type": "application/json",
569
+ "X-Storefront-Key": config.storefrontApiKey,
570
+ "X-Business-ID": config.businessId
571
+ },
572
+ body: JSON.stringify({
573
+ ...payload,
574
+ tenant_id: config.businessId
575
+ })
1034
576
  });
1035
- tokenStore.setAccessToken(data.access);
1036
- tokenStore.setRefreshToken(data.refresh);
1037
- resetGraphQLClient();
1038
- await mergeGuestCartIfPresent();
577
+ if (!response.ok) {
578
+ throw new Error("Registration failed");
579
+ }
580
+ const data = await response.json();
1039
581
  return data;
1040
582
  }
1041
- async function refreshToken2(refresh) {
1042
- const { data } = await refreshAxios2.post("/auth/token/refresh/", { refresh });
583
+ async function refreshToken(config, refresh) {
584
+ const response = await fetch(`${config.backendUrls.auth}/auth/token/refresh/`, {
585
+ method: "POST",
586
+ headers: {
587
+ "Content-Type": "application/json"
588
+ },
589
+ body: JSON.stringify({ refresh })
590
+ });
591
+ if (!response.ok) {
592
+ throw new Error("Token refresh failed");
593
+ }
594
+ const data = await response.json();
1043
595
  return data;
1044
596
  }
1045
- async function logout() {
1046
- const refresh = tokenStore.getRefreshToken();
597
+ async function logout(config, refresh) {
1047
598
  const payload = refresh ? { refresh } : {};
1048
599
  try {
1049
- await authAxios.post("/auth/logout/", payload);
600
+ await fetch(`${config.backendUrls.auth}/auth/logout/`, {
601
+ method: "POST",
602
+ headers: {
603
+ "Content-Type": "application/json"
604
+ },
605
+ body: JSON.stringify(payload)
606
+ });
1050
607
  } catch {
1051
- } finally {
1052
- tokenStore.clearAll();
1053
- resetGraphQLClient();
1054
608
  }
1055
609
  }
1056
- async function verifySocialToken(provider, token) {
1057
- const config = getRuntimeConfig();
1058
- const { data } = await authAxios.post(
1059
- `/auth/social/verify/${provider}/`,
1060
- {
610
+ async function verifySocialToken(config, provider, token) {
611
+ const response = await fetch(`${config.backendUrls.auth}/auth/social/verify/${provider}/`, {
612
+ method: "POST",
613
+ headers: {
614
+ "Content-Type": "application/json"
615
+ },
616
+ body: JSON.stringify({
1061
617
  id_token: token,
1062
618
  storefront_key: config.storefrontApiKey
1063
- }
1064
- );
1065
- tokenStore.setAccessToken(data.access);
1066
- tokenStore.setRefreshToken(data.refresh);
1067
- resetGraphQLClient();
619
+ })
620
+ });
621
+ if (!response.ok) {
622
+ throw new Error("Social token verification failed");
623
+ }
624
+ const data = await response.json();
1068
625
  return data;
1069
626
  }
1070
627
  function parseJwtPayload(token) {
@@ -1098,7 +655,7 @@ function mapAuthUserToCustomer(data, provider) {
1098
655
  firstname,
1099
656
  lastname,
1100
657
  phone,
1101
- full_name: buildFullName2(firstname, lastname),
658
+ full_name: buildFullName(firstname, lastname),
1102
659
  avatar: resolveAvatar(data.profile?.profile_picture),
1103
660
  provider: provider ?? resolveProvider(data)
1104
661
  };
@@ -1106,7 +663,7 @@ function mapAuthUserToCustomer(data, provider) {
1106
663
  function buildCustomerFromClaims(claims) {
1107
664
  const provider = claims.is_google_auth_enabled ? "google" : claims.is_facebook_auth_enabled ? "facebook" : "email";
1108
665
  const jwtFullName = String(claims.full_name ?? claims.name ?? "").trim() || void 0;
1109
- const { firstname: splitFirst, lastname: splitLast } = splitFullName2(jwtFullName);
666
+ const { firstname: splitFirst, lastname: splitLast } = splitFullName(jwtFullName);
1110
667
  return {
1111
668
  id: String(claims.user_id ?? claims.sub ?? ""),
1112
669
  email: String(claims.email ?? ""),
@@ -1118,86 +675,91 @@ function buildCustomerFromClaims(claims) {
1118
675
  provider
1119
676
  };
1120
677
  }
1121
- async function getMe() {
1122
- const { data } = await authAxios.get("/auth/profile/");
678
+ async function getMe(config, accessToken) {
679
+ if (!config || !accessToken) {
680
+ const response2 = await fetch("/api/auth/me", { credentials: "include" });
681
+ if (!response2.ok) throw new Error("Failed to fetch profile");
682
+ const data2 = await response2.json();
683
+ return data2.user;
684
+ }
685
+ const response = await fetch(`${config.backendUrls.auth}/auth/profile/`, {
686
+ headers: {
687
+ "Authorization": `Bearer ${accessToken}`
688
+ }
689
+ });
690
+ if (!response.ok) {
691
+ throw new Error("Failed to fetch profile");
692
+ }
693
+ const data = await response.json();
1123
694
  return mapAuthUserToCustomer(data);
1124
695
  }
1125
- async function getAuthUser() {
1126
- const { data } = await authAxios.get("/auth/profile/");
696
+ async function getAuthUser(config, accessToken) {
697
+ if (!config || !accessToken) {
698
+ const response2 = await fetch("/api/auth/me", { credentials: "include" });
699
+ if (!response2.ok) throw new Error("Failed to fetch auth user");
700
+ const data2 = await response2.json();
701
+ return data2.user;
702
+ }
703
+ const response = await fetch(`${config.backendUrls.auth}/auth/profile/`, {
704
+ headers: {
705
+ "Authorization": `Bearer ${accessToken}`
706
+ }
707
+ });
708
+ if (!response.ok) {
709
+ throw new Error("Failed to fetch auth user");
710
+ }
711
+ const data = await response.json();
1127
712
  return data;
1128
713
  }
1129
- async function updateProfile(payload) {
1130
- const { data } = await authAxios.put("/auth/profile/", payload);
1131
- return mapAuthUserToCustomer(data);
1132
- }
1133
- var refreshPromise = null;
1134
- function classifyError(error) {
1135
- const err = error;
1136
- const isNetworkError = !!(!err.response && (err.code === "ECONNABORTED" || err.code === "ERR_NETWORK" || err.message?.includes("Network Error")));
1137
- const isAuthError = !!(err.response?.status === 401 || err.response?.status === 403);
1138
- const isBlacklistedError = !!(err.response?.data?.detail === "Token is blacklisted" || err.message === "Token is blacklisted");
1139
- return { isNetworkError, isAuthError, isBlacklistedError };
1140
- }
1141
- async function retryWithBackoff(fn, maxRetries = 2, baseDelay = 1e3) {
1142
- let lastError;
1143
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
1144
- try {
1145
- return await fn();
1146
- } catch (error) {
1147
- lastError = error;
1148
- const { isNetworkError, isAuthError } = classifyError(error);
1149
- if (!isNetworkError || isAuthError) {
1150
- throw error;
1151
- }
1152
- if (attempt === maxRetries) {
1153
- throw error;
1154
- }
1155
- const delay = baseDelay * Math.pow(2, attempt);
1156
- await new Promise((resolve) => setTimeout(resolve, delay));
1157
- }
714
+ async function updateProfile(configOrPayload, accessTokenOrPayload, payloadParam) {
715
+ const isArg1Config = typeof configOrPayload === "object" && configOrPayload !== null && "businessId" in configOrPayload;
716
+ if (!isArg1Config) {
717
+ const payload2 = configOrPayload;
718
+ const response2 = await fetch("/api/auth/profile", {
719
+ method: "PUT",
720
+ headers: { "Content-Type": "application/json" },
721
+ credentials: "include",
722
+ body: JSON.stringify(payload2)
723
+ });
724
+ if (!response2.ok) throw new Error("Failed to update profile");
725
+ return response2.json();
1158
726
  }
1159
- throw lastError;
727
+ const config = configOrPayload;
728
+ const accessToken = accessTokenOrPayload;
729
+ const payload = payloadParam;
730
+ const response = await fetch(`${config.backendUrls.auth}/auth/profile/`, {
731
+ method: "PUT",
732
+ headers: {
733
+ "Content-Type": "application/json",
734
+ "Authorization": `Bearer ${accessToken}`
735
+ },
736
+ body: JSON.stringify(payload)
737
+ });
738
+ if (!response.ok) {
739
+ throw new Error("Failed to update profile");
740
+ }
741
+ const data = await response.json();
742
+ return mapAuthUserToCustomer(data);
1160
743
  }
1161
- async function silentRefresh() {
1162
- const refresh = tokenStore.getRefreshToken();
1163
- if (!refresh) return null;
1164
- if (refreshPromise) return refreshPromise;
1165
- refreshPromise = (async () => {
1166
- try {
1167
- const tokens = await retryWithBackoff(() => refreshToken2(refresh), 2, 1e3);
1168
- tokenStore.setAccessToken(tokens.access);
1169
- if (tokens.refresh) tokenStore.setRefreshToken(tokens.refresh, tokenStore.isPersistent());
1170
- const claims = parseJwtPayload(tokens.access);
1171
- const user = buildCustomerFromClaims(claims);
1172
- return { user, provider: user.provider };
1173
- } catch (error) {
1174
- const { isNetworkError, isAuthError, isBlacklistedError } = classifyError(error);
1175
- if (isNetworkError) {
1176
- logger.warn("[silentRefresh] Network error during token refresh (offline/CORS), clearing session:", error);
1177
- } else if (isBlacklistedError) {
1178
- logger.log("[silentRefresh] Token was blacklisted (likely from logout), clearing session");
1179
- } else if (isAuthError) {
1180
- logger.log("[silentRefresh] Token refresh failed with auth error (expired/invalid), clearing session");
1181
- } else {
1182
- logger.error("[silentRefresh] Unexpected error during token refresh, clearing session:", error);
1183
- }
1184
- tokenStore.clearAll();
744
+ async function silentRefresh(config, refresh) {
745
+ try {
746
+ const data = await refreshToken(config, refresh);
747
+ if (!data.access || !data.refresh) {
1185
748
  return null;
1186
- } finally {
1187
- refreshPromise = null;
1188
749
  }
1189
- })();
1190
- return refreshPromise;
1191
- }
1192
- function storeTokens(access, refresh, remember = true) {
1193
- tokenStore.setAccessToken(access);
1194
- tokenStore.setRefreshToken(refresh, remember);
750
+ const claims = parseJwtPayload(data.access);
751
+ const user = buildCustomerFromClaims(claims);
752
+ const provider = user.provider;
753
+ return { user, provider, newAccessToken: data.access, newRefreshToken: data.refresh };
754
+ } catch {
755
+ return null;
756
+ }
1195
757
  }
1196
- function buildFullName2(firstname, lastname) {
758
+ function buildFullName(firstname, lastname) {
1197
759
  if (firstname && lastname) return `${firstname} ${lastname}`;
1198
760
  return firstname || lastname || "";
1199
761
  }
1200
- function splitFullName2(fullName) {
762
+ function splitFullName(fullName) {
1201
763
  if (!fullName) return { firstname: "", lastname: "" };
1202
764
  const parts = fullName.trim().split(/\s+/);
1203
765
  if (parts.length === 1) {
@@ -1208,8 +770,39 @@ function splitFullName2(fullName) {
1208
770
  lastname: parts.slice(1).join(" ")
1209
771
  };
1210
772
  }
773
+ function storeTokens(accessToken, refreshToken2) {
774
+ if (typeof window !== "undefined") {
775
+ localStorage.setItem(STORAGE_KEYS.ACCESS_TOKEN, accessToken);
776
+ localStorage.setItem(STORAGE_KEYS.REFRESH_TOKEN, refreshToken2);
777
+ }
778
+ }
779
+ function clearTokens() {
780
+ if (typeof window !== "undefined") {
781
+ localStorage.removeItem(STORAGE_KEYS.ACCESS_TOKEN);
782
+ localStorage.removeItem(STORAGE_KEYS.REFRESH_TOKEN);
783
+ }
784
+ }
785
+ function getStoredTokens() {
786
+ if (typeof window === "undefined") {
787
+ return { accessToken: null, refreshToken: null };
788
+ }
789
+ return {
790
+ accessToken: localStorage.getItem(STORAGE_KEYS.ACCESS_TOKEN),
791
+ refreshToken: localStorage.getItem(STORAGE_KEYS.REFRESH_TOKEN)
792
+ };
793
+ }
1211
794
 
1212
795
  // src/services/product.service.ts
796
+ var import_graphql_request = require("graphql-request");
797
+ function createGraphQLClient(config) {
798
+ const headers = {
799
+ "Content-Type": "application/json",
800
+ "Accept": "application/json",
801
+ "X-Storefront-Key": config.storefrontApiKey,
802
+ "X-Business-ID": config.businessId
803
+ };
804
+ return new import_graphql_request.GraphQLClient(`${config.backendUrls.store}/graphql`, { headers });
805
+ }
1213
806
  var GET_STOREFRONT_PRODUCTS = `
1214
807
  query GetStorefrontProducts($page: Int!, $pageSize: Int!, $collectionSlug: String, $search: String) {
1215
808
  storefront_products(page: $page, pageSize: $pageSize, collectionSlug: $collectionSlug, search: $search) {
@@ -1226,7 +819,7 @@ var GET_STOREFRONT_PRODUCTS = `
1226
819
  is_bespoke
1227
820
  base_price
1228
821
  currency
1229
- images { url alt id }
822
+ images
1230
823
  tags
1231
824
  custom_fields { label unit required }
1232
825
  is_published
@@ -1249,7 +842,7 @@ var GET_STOREFRONT_PRODUCTS = `
1249
842
  sku
1250
843
  attributes
1251
844
  price
1252
- images { url alt id }
845
+ images
1253
846
  weight_kg
1254
847
  is_active
1255
848
  inventory {
@@ -1276,7 +869,7 @@ var GET_STOREFRONT_PRODUCTS = `
1276
869
  name
1277
870
  slug
1278
871
  description
1279
- image { url alt id }
872
+ image
1280
873
  collection_type
1281
874
  rules
1282
875
  status
@@ -1307,7 +900,7 @@ var GET_STOREFRONT_PRODUCT_BY_SLUG = `
1307
900
  is_bespoke
1308
901
  base_price
1309
902
  currency
1310
- images { url alt id }
903
+ images
1311
904
  tags
1312
905
  custom_fields { label unit required }
1313
906
  is_published
@@ -1330,7 +923,7 @@ var GET_STOREFRONT_PRODUCT_BY_SLUG = `
1330
923
  sku
1331
924
  attributes
1332
925
  price
1333
- images { url alt id }
926
+ images
1334
927
  weight_kg
1335
928
  is_active
1336
929
  inventory {
@@ -1357,7 +950,7 @@ var GET_STOREFRONT_PRODUCT_BY_SLUG = `
1357
950
  name
1358
951
  slug
1359
952
  description
1360
- image { url alt id }
953
+ image
1361
954
  collection_type
1362
955
  rules
1363
956
  status
@@ -1368,9 +961,173 @@ var GET_STOREFRONT_PRODUCT_BY_SLUG = `
1368
961
  }
1369
962
  }
1370
963
  `;
1371
- var GET_STOREFRONT_LATEST = `
1372
- query GetStorefrontLatest($page: Int!, $pageSize: Int!) {
1373
- storefront_latest(page: $page, pageSize: $pageSize) {
964
+ var GET_STOREFRONT_LATEST = `
965
+ query GetStorefrontLatest($page: Int!, $pageSize: Int!) {
966
+ storefront_latest(page: $page, pageSize: $pageSize) {
967
+ items {
968
+ id
969
+ business_id
970
+ name
971
+ slug
972
+ description
973
+ brand
974
+ product_type
975
+ requires_shipping
976
+ is_consumable
977
+ is_bespoke
978
+ base_price
979
+ currency
980
+ images
981
+ tags
982
+ custom_fields { label unit required }
983
+ is_published
984
+ is_featured
985
+ is_popular
986
+ is_new
987
+ is_temporary
988
+ digital_file_key
989
+ download_limit
990
+ download_expires_at
991
+ weight_kg
992
+ length_cm
993
+ width_cm
994
+ height_cm
995
+ created_at
996
+ updated_at
997
+ variants {
998
+ id
999
+ product_id
1000
+ sku
1001
+ attributes
1002
+ price
1003
+ images
1004
+ weight_kg
1005
+ is_active
1006
+ inventory {
1007
+ id
1008
+ product_id
1009
+ variant_id
1010
+ quantity
1011
+ reserved
1012
+ reorder_point
1013
+ reorder_quantity
1014
+ track_quantity
1015
+ allow_backorder
1016
+ available
1017
+ is_in_stock
1018
+ is_low_stock
1019
+ updated_at
1020
+ }
1021
+ created_at
1022
+ updated_at
1023
+ }
1024
+ collections {
1025
+ id
1026
+ business_id
1027
+ name
1028
+ slug
1029
+ description
1030
+ image
1031
+ collection_type
1032
+ rules
1033
+ status
1034
+ sort_order
1035
+ created_at
1036
+ updated_at
1037
+ }
1038
+ }
1039
+ total
1040
+ page
1041
+ page_size
1042
+ total_pages
1043
+ }
1044
+ }
1045
+ `;
1046
+ var GET_STOREFRONT_POPULAR = `
1047
+ query GetStorefrontPopular($page: Int!, $pageSize: Int!) {
1048
+ storefront_popular(page: $page, pageSize: $pageSize) {
1049
+ items {
1050
+ id
1051
+ business_id
1052
+ name
1053
+ slug
1054
+ description
1055
+ brand
1056
+ product_type
1057
+ requires_shipping
1058
+ is_consumable
1059
+ is_bespoke
1060
+ base_price
1061
+ currency
1062
+ images
1063
+ tags
1064
+ custom_fields { label unit required }
1065
+ is_published
1066
+ is_featured
1067
+ is_popular
1068
+ is_new
1069
+ is_temporary
1070
+ digital_file_key
1071
+ download_limit
1072
+ download_expires_at
1073
+ weight_kg
1074
+ length_cm
1075
+ width_cm
1076
+ height_cm
1077
+ created_at
1078
+ updated_at
1079
+ variants {
1080
+ id
1081
+ product_id
1082
+ sku
1083
+ attributes
1084
+ price
1085
+ images
1086
+ weight_kg
1087
+ is_active
1088
+ inventory {
1089
+ id
1090
+ product_id
1091
+ variant_id
1092
+ quantity
1093
+ reserved
1094
+ reorder_point
1095
+ reorder_quantity
1096
+ track_quantity
1097
+ allow_backorder
1098
+ available
1099
+ is_in_stock
1100
+ is_low_stock
1101
+ updated_at
1102
+ }
1103
+ created_at
1104
+ updated_at
1105
+ }
1106
+ collections {
1107
+ id
1108
+ business_id
1109
+ name
1110
+ slug
1111
+ description
1112
+ image
1113
+ collection_type
1114
+ rules
1115
+ status
1116
+ sort_order
1117
+ created_at
1118
+ updated_at
1119
+ }
1120
+ }
1121
+ total
1122
+ page
1123
+ page_size
1124
+ total_pages
1125
+ }
1126
+ }
1127
+ `;
1128
+ var GET_STOREFRONT_FEATURED = `
1129
+ query GetStorefrontFeatured($page: Int!, $pageSize: Int!) {
1130
+ storefront_featured(page: $page, pageSize: $pageSize) {
1374
1131
  items {
1375
1132
  id
1376
1133
  business_id
@@ -1384,7 +1141,7 @@ var GET_STOREFRONT_LATEST = `
1384
1141
  is_bespoke
1385
1142
  base_price
1386
1143
  currency
1387
- images { url alt id }
1144
+ images
1388
1145
  tags
1389
1146
  custom_fields { label unit required }
1390
1147
  is_published
@@ -1407,7 +1164,7 @@ var GET_STOREFRONT_LATEST = `
1407
1164
  sku
1408
1165
  attributes
1409
1166
  price
1410
- images { url alt id }
1167
+ images
1411
1168
  weight_kg
1412
1169
  is_active
1413
1170
  inventory {
@@ -1434,7 +1191,7 @@ var GET_STOREFRONT_LATEST = `
1434
1191
  name
1435
1192
  slug
1436
1193
  description
1437
- image { url alt id }
1194
+ image
1438
1195
  collection_type
1439
1196
  rules
1440
1197
  status
@@ -1450,9 +1207,9 @@ var GET_STOREFRONT_LATEST = `
1450
1207
  }
1451
1208
  }
1452
1209
  `;
1453
- var GET_STOREFRONT_POPULAR = `
1454
- query GetStorefrontPopular($page: Int!, $pageSize: Int!) {
1455
- storefront_popular(page: $page, pageSize: $pageSize) {
1210
+ var GET_STOREFRONT_NEW = `
1211
+ query GetStorefrontNew($page: Int!, $pageSize: Int!) {
1212
+ storefront_new(page: $page, pageSize: $pageSize) {
1456
1213
  items {
1457
1214
  id
1458
1215
  business_id
@@ -1466,7 +1223,10 @@ var GET_STOREFRONT_POPULAR = `
1466
1223
  is_bespoke
1467
1224
  base_price
1468
1225
  currency
1469
- images { url alt id }
1226
+ sale_price
1227
+ sale_start
1228
+ sale_end
1229
+ images
1470
1230
  tags
1471
1231
  custom_fields { label unit required }
1472
1232
  is_published
@@ -1489,7 +1249,7 @@ var GET_STOREFRONT_POPULAR = `
1489
1249
  sku
1490
1250
  attributes
1491
1251
  price
1492
- images { url alt id }
1252
+ images
1493
1253
  weight_kg
1494
1254
  is_active
1495
1255
  inventory {
@@ -1516,7 +1276,7 @@ var GET_STOREFRONT_POPULAR = `
1516
1276
  name
1517
1277
  slug
1518
1278
  description
1519
- image { url alt id }
1279
+ image
1520
1280
  collection_type
1521
1281
  rules
1522
1282
  status
@@ -1532,9 +1292,9 @@ var GET_STOREFRONT_POPULAR = `
1532
1292
  }
1533
1293
  }
1534
1294
  `;
1535
- var GET_STOREFRONT_FEATURED = `
1536
- query GetStorefrontFeatured($page: Int!, $pageSize: Int!) {
1537
- storefront_featured(page: $page, pageSize: $pageSize) {
1295
+ var GET_STOREFRONT_ON_SALE = `
1296
+ query GetStorefrontOnSale($page: Int!, $pageSize: Int!) {
1297
+ storefront_on_sale(page: $page, pageSize: $pageSize) {
1538
1298
  items {
1539
1299
  id
1540
1300
  business_id
@@ -1548,7 +1308,10 @@ var GET_STOREFRONT_FEATURED = `
1548
1308
  is_bespoke
1549
1309
  base_price
1550
1310
  currency
1551
- images { url alt id }
1311
+ sale_price
1312
+ sale_start
1313
+ sale_end
1314
+ images
1552
1315
  tags
1553
1316
  custom_fields { label unit required }
1554
1317
  is_published
@@ -1571,7 +1334,7 @@ var GET_STOREFRONT_FEATURED = `
1571
1334
  sku
1572
1335
  attributes
1573
1336
  price
1574
- images { url alt id }
1337
+ images
1575
1338
  weight_kg
1576
1339
  is_active
1577
1340
  inventory {
@@ -1598,7 +1361,7 @@ var GET_STOREFRONT_FEATURED = `
1598
1361
  name
1599
1362
  slug
1600
1363
  description
1601
- image { url alt id }
1364
+ image
1602
1365
  collection_type
1603
1366
  rules
1604
1367
  status
@@ -1614,9 +1377,9 @@ var GET_STOREFRONT_FEATURED = `
1614
1377
  }
1615
1378
  }
1616
1379
  `;
1617
- var GET_STOREFRONT_NEW = `
1618
- query GetStorefrontNew($page: Int!, $pageSize: Int!) {
1619
- storefront_new(page: $page, pageSize: $pageSize) {
1380
+ var GET_STOREFRONT_LOW_STOCK = `
1381
+ query GetStorefrontLowStock($page: Int!, $pageSize: Int!) {
1382
+ storefront_low_stock(page: $page, pageSize: $pageSize) {
1620
1383
  items {
1621
1384
  id
1622
1385
  business_id
@@ -1630,7 +1393,10 @@ var GET_STOREFRONT_NEW = `
1630
1393
  is_bespoke
1631
1394
  base_price
1632
1395
  currency
1633
- images { url alt id }
1396
+ sale_price
1397
+ sale_start
1398
+ sale_end
1399
+ images
1634
1400
  tags
1635
1401
  custom_fields { label unit required }
1636
1402
  is_published
@@ -1653,7 +1419,7 @@ var GET_STOREFRONT_NEW = `
1653
1419
  sku
1654
1420
  attributes
1655
1421
  price
1656
- images { url alt id }
1422
+ images
1657
1423
  weight_kg
1658
1424
  is_active
1659
1425
  inventory {
@@ -1680,7 +1446,7 @@ var GET_STOREFRONT_NEW = `
1680
1446
  name
1681
1447
  slug
1682
1448
  description
1683
- image { url alt id }
1449
+ image
1684
1450
  collection_type
1685
1451
  rules
1686
1452
  status
@@ -1712,7 +1478,7 @@ var GET_STOREFRONT_RECOMMENDED = `
1712
1478
  is_bespoke
1713
1479
  base_price
1714
1480
  currency
1715
- images { url alt id }
1481
+ images
1716
1482
  tags
1717
1483
  custom_fields { label unit required }
1718
1484
  is_published
@@ -1735,7 +1501,7 @@ var GET_STOREFRONT_RECOMMENDED = `
1735
1501
  sku
1736
1502
  attributes
1737
1503
  price
1738
- images { url alt id }
1504
+ images
1739
1505
  weight_kg
1740
1506
  is_active
1741
1507
  inventory {
@@ -1762,7 +1528,7 @@ var GET_STOREFRONT_RECOMMENDED = `
1762
1528
  name
1763
1529
  slug
1764
1530
  description
1765
- image { url alt id }
1531
+ image
1766
1532
  collection_type
1767
1533
  rules
1768
1534
  status
@@ -1778,8 +1544,8 @@ var GET_STOREFRONT_RECOMMENDED = `
1778
1544
  }
1779
1545
  }
1780
1546
  `;
1781
- async function getStorefrontProducts(params) {
1782
- const client = getGraphQLClient();
1547
+ async function getStorefrontProducts(config, params) {
1548
+ const client = createGraphQLClient(config);
1783
1549
  const variables = {
1784
1550
  page: params?.page || 1,
1785
1551
  pageSize: params?.pageSize || 20,
@@ -1789,13 +1555,13 @@ async function getStorefrontProducts(params) {
1789
1555
  const data = await client.request(GET_STOREFRONT_PRODUCTS, variables);
1790
1556
  return data.storefront_products;
1791
1557
  }
1792
- async function getStorefrontProductBySlug(slug) {
1793
- const client = getGraphQLClient();
1558
+ async function getStorefrontProductBySlug(config, slug) {
1559
+ const client = createGraphQLClient(config);
1794
1560
  const data = await client.request(GET_STOREFRONT_PRODUCT_BY_SLUG, { slug });
1795
1561
  return data.storefront_product_by_slug;
1796
1562
  }
1797
- async function getLatestProducts(params) {
1798
- const client = getGraphQLClient();
1563
+ async function getLatestProducts(config, params) {
1564
+ const client = createGraphQLClient(config);
1799
1565
  const variables = {
1800
1566
  page: params?.page || 1,
1801
1567
  pageSize: params?.pageSize || 4
@@ -1803,8 +1569,8 @@ async function getLatestProducts(params) {
1803
1569
  const data = await client.request(GET_STOREFRONT_LATEST, variables);
1804
1570
  return data.storefront_latest;
1805
1571
  }
1806
- async function getPopularProducts(params) {
1807
- const client = getGraphQLClient();
1572
+ async function getPopularProducts(config, params) {
1573
+ const client = createGraphQLClient(config);
1808
1574
  const variables = {
1809
1575
  page: params?.page || 1,
1810
1576
  pageSize: params?.pageSize || 4
@@ -1812,8 +1578,8 @@ async function getPopularProducts(params) {
1812
1578
  const data = await client.request(GET_STOREFRONT_POPULAR, variables);
1813
1579
  return data.storefront_popular;
1814
1580
  }
1815
- async function getFeaturedProducts(params) {
1816
- const client = getGraphQLClient();
1581
+ async function getFeaturedProducts(config, params) {
1582
+ const client = createGraphQLClient(config);
1817
1583
  const variables = {
1818
1584
  page: params?.page || 1,
1819
1585
  pageSize: params?.pageSize || 4
@@ -1821,8 +1587,8 @@ async function getFeaturedProducts(params) {
1821
1587
  const data = await client.request(GET_STOREFRONT_FEATURED, variables);
1822
1588
  return data.storefront_featured;
1823
1589
  }
1824
- async function getNewProducts(params) {
1825
- const client = getGraphQLClient();
1590
+ async function getNewProducts(config, params) {
1591
+ const client = createGraphQLClient(config);
1826
1592
  const variables = {
1827
1593
  page: params?.page || 1,
1828
1594
  pageSize: params?.pageSize || 4
@@ -1830,8 +1596,26 @@ async function getNewProducts(params) {
1830
1596
  const data = await client.request(GET_STOREFRONT_NEW, variables);
1831
1597
  return data.storefront_new;
1832
1598
  }
1833
- async function getRecommendedProducts(params) {
1834
- const client = getGraphQLClient();
1599
+ async function getOnSaleProducts(config, params) {
1600
+ const client = createGraphQLClient(config);
1601
+ const variables = {
1602
+ page: params?.page || 1,
1603
+ pageSize: params?.pageSize || 4
1604
+ };
1605
+ const data = await client.request(GET_STOREFRONT_ON_SALE, variables);
1606
+ return data.storefront_on_sale;
1607
+ }
1608
+ async function getLowStockProducts(config, params) {
1609
+ const client = createGraphQLClient(config);
1610
+ const variables = {
1611
+ page: params?.page || 1,
1612
+ pageSize: params?.pageSize || 4
1613
+ };
1614
+ const data = await client.request(GET_STOREFRONT_LOW_STOCK, variables);
1615
+ return data.storefront_low_stock;
1616
+ }
1617
+ async function getRecommendedProducts(config, params) {
1618
+ const client = createGraphQLClient(config);
1835
1619
  const variables = {
1836
1620
  page: params?.page || 1,
1837
1621
  pageSize: params?.pageSize || 4,
@@ -1842,6 +1626,7 @@ async function getRecommendedProducts(params) {
1842
1626
  }
1843
1627
 
1844
1628
  // src/services/collection.service.ts
1629
+ var import_graphql_request2 = require("graphql-request");
1845
1630
  var GET_STOREFRONT_COLLECTIONS = `
1846
1631
  query GetStorefrontCollections($page: Int!, $pageSize: Int!) {
1847
1632
  storefront_collections(page: $page, pageSize: $pageSize) {
@@ -1851,7 +1636,7 @@ var GET_STOREFRONT_COLLECTIONS = `
1851
1636
  name
1852
1637
  slug
1853
1638
  description
1854
- image { url alt id }
1639
+ image
1855
1640
  collection_type
1856
1641
  rules
1857
1642
  status
@@ -1874,7 +1659,7 @@ var GET_STOREFRONT_COLLECTION_BY_SLUG = `
1874
1659
  name
1875
1660
  slug
1876
1661
  description
1877
- image { url alt id }
1662
+ image
1878
1663
  collection_type
1879
1664
  rules
1880
1665
  status
@@ -1884,1501 +1669,889 @@ var GET_STOREFRONT_COLLECTION_BY_SLUG = `
1884
1669
  }
1885
1670
  }
1886
1671
  `;
1887
- async function getStorefrontCollections(params) {
1888
- const client = getGraphQLClient();
1889
- const variables = {
1890
- page: params?.page || 1,
1891
- pageSize: params?.pageSize || 20
1892
- };
1893
- const data = await client.request(GET_STOREFRONT_COLLECTIONS, variables);
1894
- return data.storefront_collections;
1895
- }
1896
- async function getStorefrontCollectionBySlug(slug) {
1897
- const client = getGraphQLClient();
1898
- const data = await client.request(GET_STOREFRONT_COLLECTION_BY_SLUG, { slug });
1899
- return data.storefront_collection_by_slug;
1900
- }
1901
-
1902
- // src/services/wishlist.service.ts
1903
- var GET_WISHLIST = `
1904
- query GetWishlist($page: Int!, $pageSize: Int!) {
1905
- wishlist(page: $page, pageSize: $pageSize) {
1906
- items {
1907
- id
1908
- product_id
1909
- notes
1910
- created_at
1911
- product_name
1912
- product_slug
1913
- product_price
1914
- product_image
1915
- }
1916
- total
1917
- page
1918
- page_size
1919
- total_pages
1920
- }
1921
- }
1922
- `;
1923
- var CHECK_IN_WISHLIST = `
1924
- query CheckInWishlist($productId: String!) {
1925
- check_in_wishlist(productId: $productId) {
1926
- in_wishlist
1927
- }
1928
- }
1929
- `;
1930
- async function getWishlist(params) {
1931
- const client = getGraphQLClient();
1932
- const variables = {
1933
- page: params?.page || 1,
1934
- pageSize: params?.pageSize || 20
1935
- };
1936
- const data = await client.request(GET_WISHLIST, variables);
1937
- return data.wishlist;
1938
- }
1939
- async function checkInWishlist(productId) {
1940
- const client = getGraphQLClient();
1941
- const data = await client.request(CHECK_IN_WISHLIST, { productId });
1942
- return data.check_in_wishlist;
1943
- }
1944
- async function addToWishlist(productId, notes) {
1945
- const { data } = await storeManagementAxios.post("wishlist/", {
1946
- product_id: productId,
1947
- notes: notes || void 0
1948
- });
1949
- return data;
1950
- }
1951
- async function removeFromWishlist(itemId) {
1952
- await storeManagementAxios.delete(`wishlist/${itemId}`);
1953
- }
1954
- async function removeProductFromWishlist(productId) {
1955
- await storeManagementAxios.delete(`wishlist/product/${productId}`);
1956
- }
1957
-
1958
- // src/services/payment.service.ts
1959
- async function createDedicatedAccount(request) {
1960
- const isValidUUID = (str) => {
1961
- const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1962
- return uuidRegex.test(str);
1963
- };
1964
- const { data } = await paymentAxios.post(
1965
- "payments/dedicated-account",
1966
- {
1967
- order_id: request.order_id && isValidUUID(request.order_id) ? request.order_id : void 0,
1968
- amount: request.amount,
1969
- customer_email: request.customer_email,
1970
- customer_name: request.customer_name,
1971
- currency: request.currency,
1972
- idempotency_key: request.idempotency_key
1973
- }
1974
- );
1975
- return data;
1976
- }
1977
- async function initiatePayment(request) {
1978
- const isValidUUID = (str) => {
1979
- const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1980
- return uuidRegex.test(str);
1981
- };
1982
- const validOrderId = request.order_id && isValidUUID(request.order_id) ? request.order_id : void 0;
1983
- const { data } = await paymentAxios.post("payments/storefront/initiate", {
1984
- amount: request.amount,
1985
- currency: request.currency,
1986
- order_id: validOrderId,
1987
- quote_id: request.quote_id,
1988
- metadata_json: {
1989
- customer_email: request.customer_email,
1990
- customer_name: request.customer_name ?? "",
1991
- order_id: validOrderId,
1992
- ...request.metadata ?? {}
1993
- },
1994
- idempotency_key: request.idempotency_key
1995
- });
1996
- return {
1997
- id: data.id,
1998
- gateway_ref: data.gateway_ref,
1999
- gateway: data.gateway,
2000
- status: data.status,
2001
- checkout_url: data.metadata_json?.checkout_url ?? ""
2002
- };
2003
- }
2004
- async function requestQuote(amount) {
2005
- const { data } = await paymentAxios.post("payments/quote", { amount });
2006
- return data;
2007
- }
2008
- async function verifyTransaction(reference) {
2009
- const { data } = await paymentAxios.post(
2010
- `payments/verify/${reference}`
2011
- );
2012
- return data;
2013
- }
2014
- async function getTransactionStatus(transactionId) {
2015
- const { data } = await paymentAxios.get(
2016
- `payments/transactions/${transactionId}`
2017
- );
2018
- return data;
2019
- }
2020
- var paymentService = {
2021
- createDedicatedAccount,
2022
- initiatePayment,
2023
- requestQuote,
2024
- verifyTransaction,
2025
- getTransactionStatus
2026
- };
2027
-
2028
- // src/services/consultation.service.ts
2029
- async function createConsultation(payload) {
2030
- const { data } = await storeManagementAxios.post("social/consultations/", payload);
2031
- return data;
2032
- }
2033
- async function getConsultations() {
2034
- const { data } = await storeManagementAxios.get("social/consultations/");
2035
- return data;
2036
- }
2037
- async function getConsultation(id) {
2038
- const { data } = await storeManagementAxios.get(`social/consultations/${id}`);
2039
- return data;
2040
- }
2041
- async function sendMessage(id, payload) {
2042
- await storeManagementAxios.post(`social/consultations/${id}/messages`, payload);
2043
- }
2044
- async function acceptQuote(id, payload) {
2045
- const { data } = await storeManagementAxios.post(`social/consultations/${id}/accept-quote`, payload);
2046
- return data;
2047
- }
2048
- async function rejectQuote(id, reason) {
2049
- const { data } = await storeManagementAxios.post(`social/consultations/${id}/reject-quote`, { reason });
2050
- return data;
2051
- }
2052
- var consultationService = {
2053
- createConsultation,
2054
- getConsultations,
2055
- getConsultation,
2056
- sendMessage,
2057
- acceptQuote,
2058
- rejectQuote
2059
- };
2060
-
2061
- // src/services/logistics.service.ts
2062
- async function getShippingRates(payload) {
2063
- const { data } = await storeManagementAxios.post(
2064
- "logistics/shipping/rates",
2065
- payload
2066
- );
2067
- return data;
2068
- }
2069
- async function getSellerShippingAddress() {
2070
- const { data } = await storeManagementAxios.get("logistics/shipping-address");
2071
- return data;
2072
- }
2073
- async function validateShippingAddress(payload) {
2074
- const { data } = await storeManagementAxios.post("logistics/shipping-address/validate", payload);
2075
- return data;
2076
- }
2077
- var logisticsService = {
2078
- getShippingRates,
2079
- getSellerShippingAddress,
2080
- validateShippingAddress
2081
- };
2082
-
2083
- // src/services/bespoke.service.ts
2084
- async function checkAvailability(product_id) {
2085
- const { data } = await storeManagementAxios.get(`bespoke/availability/${product_id}`);
2086
- return data;
2087
- }
2088
- var bespokeService = {
2089
- checkAvailability
2090
- };
2091
-
2092
- // src/services/service-booking.service.ts
2093
- async function getAvailableSlots(product_id, date_from, date_to) {
2094
- const { data } = await storeManagementAxios.get(
2095
- `service/available-slots/${product_id}`,
2096
- { params: { date_from, date_to } }
2097
- );
2098
- return data;
2099
- }
2100
- async function bookAppointment(payload) {
2101
- const { data } = await storeManagementAxios.post("service/appointments/", payload);
2102
- return data;
2103
- }
2104
- async function getAppointments() {
2105
- const { data } = await storeManagementAxios.get("service/bookings/my");
2106
- return data;
2107
- }
2108
- async function getAppointment(id) {
2109
- const { data } = await storeManagementAxios.get(`service/bookings/${id}`);
2110
- return data;
2111
- }
2112
- async function cancelAppointment(id) {
2113
- await storeManagementAxios.delete(`service/bookings/${id}`);
2114
- }
2115
- async function getDeliverables(order_id) {
2116
- const { data } = await storeManagementAxios.get(`service/projects/${order_id}/deliverables/`);
2117
- return data;
2118
- }
2119
- async function approveDeliverable(order_id, deliverable_id) {
2120
- const { data } = await storeManagementAxios.post(
2121
- `service/projects/${order_id}/deliverables/${deliverable_id}/approve`,
2122
- { approved: true }
2123
- );
2124
- return data;
2125
- }
2126
- async function requestRevision(order_id, deliverable_id, feedback) {
2127
- const { data } = await storeManagementAxios.post(
2128
- `service/projects/${order_id}/deliverables/${deliverable_id}/revision`,
2129
- { approved: false, feedback }
2130
- );
2131
- return data;
2132
- }
2133
- var serviceBookingService = {
2134
- getAvailableSlots,
2135
- bookAppointment,
2136
- getAppointments,
2137
- getAppointment,
2138
- cancelAppointment,
2139
- getDeliverables,
2140
- approveDeliverable,
2141
- requestRevision
2142
- };
2143
-
2144
- // src/services/notifications.service.ts
2145
- async function sendContactEmail(payload) {
2146
- const { data } = await notificationsAxios.post(
2147
- "contact/send-contact-email",
2148
- payload
2149
- );
2150
- return data;
2151
- }
2152
- async function sendContactConfirmation(payload) {
2153
- const { data } = await notificationsAxios.post(
2154
- "contact/send-contact-confirmation",
2155
- payload
2156
- );
2157
- return data;
2158
- }
2159
- var notificationsService = {
2160
- sendContactEmail,
2161
- sendContactConfirmation
2162
- };
2163
-
2164
- // src/services/app.service.ts
2165
- async function googleTranslate(text, target, source = "en") {
2166
- if (!text || target === source) return text;
2167
- try {
2168
- const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${source}&tl=${target}&dt=t&q=${encodeURIComponent(text)}`;
2169
- const res = await fetch(url);
2170
- const data = await res.json();
2171
- return (data?.[0] || []).map((s) => s[0]).join("");
2172
- } catch {
2173
- return text;
2174
- }
2175
- }
2176
-
2177
- // src/services/config.service.ts
2178
- async function getSupportedLanguages() {
2179
- const { data } = await paymentAxios.get("/config/supported-languages");
2180
- return data;
2181
- }
2182
- async function getSupportedCurrencies() {
2183
- const { data } = await paymentAxios.get("/config/supported-currencies");
2184
- return data;
2185
- }
2186
- async function getBusinessConfig() {
2187
- const { data } = await publicStoreAxios.get("business/profile");
2188
- return data;
2189
- }
2190
- var configService = {
2191
- getSupportedLanguages,
2192
- getSupportedCurrencies,
2193
- getBusinessConfig
2194
- };
2195
-
2196
- // src/services/cms.service.ts
2197
- async function listCmsEntries(modelSlug, params) {
2198
- const config = getRuntimeConfig();
2199
- const { businessId } = config;
2200
- const response = await cmsAxios.get(
2201
- `/sdk/${businessId}/${modelSlug}/entries`,
2202
- {
2203
- params: {
2204
- page: params?.page || 1,
2205
- page_size: params?.page_size || 50
2206
- }
2207
- }
2208
- );
2209
- return response.data;
2210
- }
2211
- async function getCmsEntry(modelSlug, entryId) {
2212
- const config = getRuntimeConfig();
2213
- const { businessId } = config;
2214
- const response = await cmsAxios.get(
2215
- `/sdk/${businessId}/${modelSlug}/entries/${entryId}`
2216
- );
2217
- return response.data;
2218
- }
2219
- async function createCmsEntry(modelSlug, params) {
2220
- const config = getRuntimeConfig();
2221
- const { businessId } = config;
2222
- const response = await cmsAxios.post(
2223
- `/sdk/${businessId}/${modelSlug}/entries`,
2224
- params
2225
- );
2226
- return response.data;
2227
- }
2228
- async function updateCmsEntry(modelSlug, entryId, params) {
2229
- const config = getRuntimeConfig();
2230
- const { businessId } = config;
2231
- const response = await cmsAxios.put(
2232
- `/sdk/${businessId}/${modelSlug}/entries/${entryId}`,
2233
- params
2234
- );
2235
- return response.data;
1672
+ function createGraphQLClient2(config) {
1673
+ const headers = {
1674
+ "Content-Type": "application/json",
1675
+ "Accept": "application/json",
1676
+ "X-Storefront-Key": config.storefrontApiKey,
1677
+ "X-Business-ID": config.businessId
1678
+ };
1679
+ return new import_graphql_request2.GraphQLClient(`${config.backendUrls.store}/graphql`, { headers });
2236
1680
  }
2237
- async function deleteCmsEntry(modelSlug, entryId) {
2238
- const config = getRuntimeConfig();
2239
- const { businessId } = config;
2240
- await cmsAxios.delete(
2241
- `/sdk/${businessId}/${modelSlug}/entries/${entryId}`
2242
- );
1681
+ async function getStorefrontCollections(config, params) {
1682
+ const client = createGraphQLClient2(config);
1683
+ const variables = {
1684
+ page: params?.page || 1,
1685
+ pageSize: params?.pageSize || 20
1686
+ };
1687
+ const data = await client.request(GET_STOREFRONT_COLLECTIONS, variables);
1688
+ return data.storefront_collections;
1689
+ }
1690
+ async function getStorefrontCollectionBySlug(config, slug) {
1691
+ const client = createGraphQLClient2(config);
1692
+ const data = await client.request(GET_STOREFRONT_COLLECTION_BY_SLUG, { slug });
1693
+ return data.storefront_collection_by_slug;
2243
1694
  }
2244
1695
 
2245
- // src/hooks/use-cart.ts
2246
- var import_react = __toESM(require("react"));
2247
- var import_react_query = require("@tanstack/react-query");
2248
- var import_axios4 = __toESM(require("axios"));
2249
- var CartCtx = import_react.default.createContext ? import_react.default.createContext(null) : null;
2250
- function CartProvider({ children }) {
2251
- const [isOpen, setIsOpen] = (0, import_react.useState)(false);
2252
- if (!CartCtx) return children;
2253
- return import_react.default.createElement(CartCtx.Provider, { value: { isOpen, setOpen: setIsOpen } }, children);
2254
- }
2255
- function useCart() {
2256
- const queryClient = (0, import_react_query.useQueryClient)();
2257
- const context = CartCtx ? (0, import_react.useContext)(CartCtx) : null;
2258
- const isOpen = context ? context.isOpen : false;
2259
- const setOpen = context ? context.setOpen : () => {
2260
- };
2261
- const [productTypeMismatch, setProductTypeMismatch] = (0, import_react.useState)(null);
2262
- const cartQuery = (0, import_react_query.useQuery)({
2263
- queryKey: ["cart"],
2264
- queryFn: getCart,
2265
- enabled: isInitialized()
2266
- });
2267
- const addToCartMutation = (0, import_react_query.useMutation)({
2268
- mutationFn: addToCart,
2269
- onSuccess: () => {
2270
- setProductTypeMismatch(null);
2271
- queryClient.invalidateQueries({ queryKey: ["cart"] });
2272
- },
2273
- onError: (error) => {
2274
- if (import_axios4.default.isAxiosError(error) && error.response?.status === 409) {
2275
- const responseData = error.response?.data;
2276
- const errorDetail = responseData?.detail;
2277
- if (errorDetail?.code === "CART_PRODUCT_TYPE_MISMATCH") {
2278
- setProductTypeMismatch({
2279
- message: errorDetail.message ?? "Your cart contains incompatible items.",
2280
- existing_type: errorDetail.existing_type ?? "physical",
2281
- new_type: errorDetail.new_type ?? "physical"
2282
- });
2283
- }
1696
+ // src/services/wishlist.service.ts
1697
+ var import_graphql_request3 = require("graphql-request");
1698
+ var GET_STOREFRONT_WISHLIST = `
1699
+ query GetStorefrontWishlist($page: Int!, $pageSize: Int!) {
1700
+ storefront_wishlist(page: $page, pageSize: $pageSize) {
1701
+ items {
1702
+ id
1703
+ product_id
1704
+ notes
1705
+ created_at
1706
+ product_name
1707
+ product_slug
1708
+ product_price
1709
+ currency
1710
+ product_image
2284
1711
  }
1712
+ total
1713
+ page
1714
+ page_size
1715
+ total_pages
2285
1716
  }
2286
- });
2287
- const updateCartItemMutation = (0, import_react_query.useMutation)({
2288
- mutationFn: ({ itemId, quantity }) => updateCartItem(itemId, quantity),
2289
- onSuccess: () => {
2290
- queryClient.invalidateQueries({ queryKey: ["cart"] });
2291
- }
2292
- });
2293
- const removeFromCartMutation = (0, import_react_query.useMutation)({
2294
- mutationFn: removeFromCart,
2295
- onSuccess: () => {
2296
- queryClient.invalidateQueries({ queryKey: ["cart"] });
2297
- }
2298
- });
2299
- const clearCartMutation = (0, import_react_query.useMutation)({
2300
- mutationFn: clearCart,
2301
- onSuccess: () => {
2302
- queryClient.invalidateQueries({ queryKey: ["cart"] });
2303
- }
2304
- });
2305
- const mergeGuestCartMutation = (0, import_react_query.useMutation)({
2306
- mutationFn: mergeGuestCartIfPresent,
2307
- onSuccess: () => {
2308
- queryClient.invalidateQueries({ queryKey: ["cart"] });
1717
+ }
1718
+ `;
1719
+ var CHECK_IN_STOREFRONT_WISHLIST = `
1720
+ query CheckInStorefrontWishlist($productId: String!) {
1721
+ check_in_storefront_wishlist(productId: $productId) {
1722
+ in_wishlist
2309
1723
  }
2310
- });
2311
- const addItem = (product, variantId, quantity = 1, customMeasurements) => {
2312
- const variant = variantId ? product.variants.find((v) => v.id === variantId) : void 0;
2313
- return addToCartMutation.mutate({
2314
- product_id: product.id,
2315
- product_slug: product.slug,
2316
- product_name: product.name,
2317
- image: product.images[0]?.url,
2318
- variant_id: variantId,
2319
- variant_attributes: variant?.attributes ? JSON.stringify(variant.attributes) : void 0,
2320
- unit_price: variant?.price ?? product.base_price,
2321
- quantity,
2322
- custom_measurements: customMeasurements ? JSON.stringify(customMeasurements) : void 0,
2323
- is_bespoke: product.is_bespoke
2324
- });
2325
- };
2326
- const items = cartQuery.data?.items || [];
2327
- const subtotal = cartQuery.data?.subtotal || 0;
2328
- const count = items.reduce((total, item) => total + item.quantity, 0);
2329
- const updateQty = (itemId, quantity) => {
2330
- updateCartItemMutation.mutate({ itemId, quantity });
2331
- };
2332
- const removeItem = (itemId) => {
2333
- removeFromCartMutation.mutate(itemId);
2334
- };
2335
- const handleClearCartAndAdd = () => {
2336
- clearCartMutation.mutate();
2337
- setProductTypeMismatch(null);
2338
- };
2339
- const handleKeepCurrentCart = () => {
2340
- setProductTypeMismatch(null);
2341
- };
2342
- return {
2343
- cart: cartQuery.data,
2344
- items,
2345
- count,
2346
- isOpen,
2347
- setOpen,
2348
- isLoading: cartQuery.isLoading,
2349
- error: cartQuery.error,
2350
- addToCart: addToCartMutation.mutate,
2351
- updateCartItem: updateCartItemMutation.mutate,
2352
- removeFromCart: removeFromCartMutation.mutate,
2353
- clearCart: clearCartMutation.mutate,
2354
- clear: clearCartMutation.mutate,
2355
- // Alias for storefront compatibility
2356
- mergeGuestCart: mergeGuestCartMutation.mutate,
2357
- addItem,
2358
- updateQty,
2359
- removeItem,
2360
- subtotal,
2361
- productTypeMismatch,
2362
- handleClearCartAndAdd,
2363
- handleKeepCurrentCart
1724
+ }
1725
+ `;
1726
+ function createGraphQLClient3(config, accessToken) {
1727
+ const headers = {
1728
+ "Content-Type": "application/json",
1729
+ "Accept": "application/json",
1730
+ "X-Storefront-Key": config.storefrontApiKey,
1731
+ "X-Business-ID": config.businessId
2364
1732
  };
1733
+ if (accessToken) {
1734
+ headers["Authorization"] = `Bearer ${accessToken}`;
1735
+ }
1736
+ return new import_graphql_request3.GraphQLClient(`${config.backendUrls.store}/graphql`, { headers });
2365
1737
  }
2366
-
2367
- // src/hooks/use-orders.ts
2368
- var import_react_query2 = require("@tanstack/react-query");
2369
- function useOrders(params) {
2370
- return (0, import_react_query2.useQuery)({
2371
- queryKey: ["orders", params],
2372
- queryFn: () => getOrders(params)
2373
- });
2374
- }
2375
- function useOrdersList(params) {
2376
- return useOrders(params);
2377
- }
2378
- function useFindOrder(params) {
2379
- return (0, import_react_query2.useQuery)({
2380
- queryKey: ["order", params],
2381
- queryFn: () => findOrder(params),
2382
- enabled: !!params.email && !!params.order_id
2383
- });
2384
- }
2385
- function useOrder(params) {
2386
- return useFindOrder(params);
2387
- }
2388
- function useOrderTracking(orderId, token) {
2389
- return (0, import_react_query2.useQuery)({
2390
- queryKey: ["order-tracking", orderId, token],
2391
- queryFn: () => trackOrder(orderId, token),
2392
- enabled: !!orderId,
2393
- refetchInterval: 3e4
2394
- // Refetch every 30 seconds for tracking updates
1738
+ async function getWishlist(config, accessToken, params) {
1739
+ const client = createGraphQLClient3(config, accessToken);
1740
+ const variables = {
1741
+ page: params?.page || 1,
1742
+ pageSize: params?.pageSize || 20
1743
+ };
1744
+ const data = await client.request(GET_STOREFRONT_WISHLIST, variables);
1745
+ return data.storefront_wishlist;
1746
+ }
1747
+ async function checkInWishlist(config, accessToken, productId) {
1748
+ const client = createGraphQLClient3(config, accessToken);
1749
+ const data = await client.request(CHECK_IN_STOREFRONT_WISHLIST, { productId });
1750
+ return data.check_in_storefront_wishlist;
1751
+ }
1752
+ async function addToWishlist(config, accessToken, productId, notes) {
1753
+ const response = await fetch(`${config.backendUrls.store}/wishlist/`, {
1754
+ method: "POST",
1755
+ headers: {
1756
+ "Content-Type": "application/json",
1757
+ "Authorization": `Bearer ${accessToken}`,
1758
+ "X-Storefront-Key": config.storefrontApiKey,
1759
+ "X-Business-ID": config.businessId
1760
+ },
1761
+ body: JSON.stringify({
1762
+ product_id: productId,
1763
+ notes: notes || void 0
1764
+ })
2395
1765
  });
1766
+ if (!response.ok) throw new Error("Failed to add to wishlist");
1767
+ return response.json();
2396
1768
  }
2397
- function useCreateOrder() {
2398
- const queryClient = (0, import_react_query2.useQueryClient)();
2399
- return (0, import_react_query2.useMutation)({
2400
- mutationFn: createOrder,
2401
- onSuccess: () => {
2402
- queryClient.invalidateQueries({ queryKey: ["orders"] });
1769
+ async function removeFromWishlist(config, accessToken, itemId) {
1770
+ const response = await fetch(`${config.backendUrls.store}/wishlist/${itemId}`, {
1771
+ method: "DELETE",
1772
+ headers: {
1773
+ "Authorization": `Bearer ${accessToken}`,
1774
+ "X-Storefront-Key": config.storefrontApiKey,
1775
+ "X-Business-ID": config.businessId
2403
1776
  }
2404
1777
  });
1778
+ if (!response.ok) throw new Error("Failed to remove from wishlist");
2405
1779
  }
2406
- function useCancelOrder() {
2407
- const queryClient = (0, import_react_query2.useQueryClient)();
2408
- return (0, import_react_query2.useMutation)({
2409
- mutationFn: ({ orderId, reason }) => cancelOrder(orderId, reason),
2410
- onSuccess: () => {
2411
- queryClient.invalidateQueries({ queryKey: ["orders"] });
1780
+ async function removeProductFromWishlist(config, accessToken, productId) {
1781
+ const response = await fetch(`${config.backendUrls.store}/wishlist/product/${productId}`, {
1782
+ method: "DELETE",
1783
+ headers: {
1784
+ "Authorization": `Bearer ${accessToken}`,
1785
+ "X-Storefront-Key": config.storefrontApiKey,
1786
+ "X-Business-ID": config.businessId
2412
1787
  }
2413
1788
  });
1789
+ if (!response.ok) throw new Error("Failed to remove product from wishlist");
2414
1790
  }
2415
1791
 
2416
- // src/hooks/use-auth.ts
2417
- var import_react2 = __toESM(require("react"));
2418
- var import_react_query3 = require("@tanstack/react-query");
2419
- var AuthCtx = import_react2.default.createContext ? import_react2.default.createContext(null) : null;
2420
- function AuthProvider({ children }) {
2421
- const [customer, setCustomer] = (0, import_react2.useState)(null);
2422
- const [isLoading, setIsLoading] = (0, import_react2.useState)(true);
2423
- const [isModalOpen, setIsModalOpen] = (0, import_react2.useState)(false);
2424
- (0, import_react2.useEffect)(() => {
2425
- let voided = false;
2426
- (async () => {
2427
- setIsLoading(true);
2428
- try {
2429
- const result = await silentRefresh();
2430
- if (!voided && result) {
2431
- setCustomer(result.user);
2432
- resetGraphQLClient();
2433
- }
2434
- } catch (error) {
2435
- logger.error("[AuthProvider] Session restore failed:", error);
2436
- if (!voided) setCustomer(null);
2437
- } finally {
2438
- if (!voided) setIsLoading(false);
2439
- }
2440
- })();
2441
- return () => {
2442
- voided = true;
2443
- };
2444
- }, []);
2445
- const openModal = (0, import_react2.useCallback)(() => setIsModalOpen(true), []);
2446
- const closeModal = (0, import_react2.useCallback)(() => {
2447
- setIsModalOpen(false);
2448
- if (typeof window !== "undefined" && (window.location.hash === "#login" || window.location.hash === "#signup")) {
2449
- window.history.replaceState(null, "", window.location.pathname + window.location.search);
2450
- }
2451
- }, []);
2452
- (0, import_react2.useEffect)(() => {
2453
- const handleHash = () => {
2454
- if (typeof window === "undefined") return;
2455
- if (window.location.hash === "#login" || window.location.hash === "#signup") {
2456
- if (!isLoading && customer) {
2457
- window.history.replaceState(null, "", window.location.pathname + window.location.search);
2458
- } else if (!isLoading && !customer) {
2459
- setIsModalOpen(true);
2460
- }
2461
- }
2462
- };
2463
- handleHash();
2464
- window.addEventListener("hashchange", handleHash);
2465
- return () => window.removeEventListener("hashchange", handleHash);
2466
- }, [customer, isLoading]);
2467
- (0, import_react2.useEffect)(() => {
2468
- resetGraphQLClient();
2469
- }, [customer]);
2470
- const handleLogout = (0, import_react2.useCallback)(async () => {
2471
- await logout();
2472
- setCustomer(null);
2473
- setIsModalOpen(false);
2474
- resetGraphQLClient();
2475
- }, []);
2476
- const value = {
2477
- customer,
2478
- isLoading,
2479
- isModalOpen,
2480
- openModal,
2481
- closeModal,
2482
- setCustomer,
2483
- logout: handleLogout
1792
+ // src/services/payment.service.ts
1793
+ async function createDedicatedAccount(config, accessToken, request) {
1794
+ const isValidUUID = (str) => {
1795
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1796
+ return uuidRegex.test(str);
2484
1797
  };
2485
- if (!AuthCtx) return children;
2486
- return import_react2.default.createElement(AuthCtx.Provider, { value }, children);
2487
- }
2488
- function useAuthUser() {
2489
- return (0, import_react_query3.useQuery)({
2490
- queryKey: ["auth-user"],
2491
- queryFn: getAuthUser,
2492
- enabled: !!tokenStore.getAccessToken()
2493
- });
2494
- }
2495
- function useLogin() {
2496
- const queryClient = (0, import_react_query3.useQueryClient)();
2497
- return (0, import_react_query3.useMutation)({
2498
- mutationFn: loginCustomer,
2499
- onSuccess: () => {
2500
- queryClient.invalidateQueries({ queryKey: ["auth-user"] });
2501
- queryClient.invalidateQueries({ queryKey: ["cart"] });
2502
- }
2503
- });
2504
- }
2505
- function useRegister() {
2506
- const queryClient = (0, import_react_query3.useQueryClient)();
2507
- return (0, import_react_query3.useMutation)({
2508
- mutationFn: registerCustomer,
2509
- onSuccess: () => {
2510
- queryClient.invalidateQueries({ queryKey: ["auth-user"] });
2511
- queryClient.invalidateQueries({ queryKey: ["cart"] });
2512
- }
2513
- });
2514
- }
2515
- function useUpdateProfile() {
2516
- const queryClient = (0, import_react_query3.useQueryClient)();
2517
- return (0, import_react_query3.useMutation)({
2518
- mutationFn: updateProfile,
2519
- onSuccess: () => {
2520
- queryClient.invalidateQueries({ queryKey: ["auth-user"] });
2521
- }
1798
+ const response = await fetch(`${config.backendUrls.payment}/payments/dedicated-account`, {
1799
+ method: "POST",
1800
+ headers: {
1801
+ "Content-Type": "application/json",
1802
+ "Authorization": `Bearer ${accessToken}`,
1803
+ "X-Storefront-Key": config.storefrontApiKey,
1804
+ "X-Business-ID": config.businessId
1805
+ },
1806
+ body: JSON.stringify({
1807
+ order_id: request.order_id && isValidUUID(request.order_id) ? request.order_id : void 0,
1808
+ amount: request.amount,
1809
+ customer_email: request.customer_email,
1810
+ customer_name: request.customer_name,
1811
+ currency: request.currency,
1812
+ idempotency_key: request.idempotency_key
1813
+ })
2522
1814
  });
1815
+ if (!response.ok) throw new Error("Failed to create dedicated account");
1816
+ const data = await response.json();
1817
+ return data;
2523
1818
  }
2524
- function useLogout() {
2525
- const queryClient = (0, import_react_query3.useQueryClient)();
2526
- return (0, import_react_query3.useMutation)({
2527
- mutationFn: logout,
2528
- onSuccess: () => {
2529
- queryClient.clear();
2530
- }
1819
+ async function initiatePayment(config, accessToken, request) {
1820
+ const isValidUUID = (str) => {
1821
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1822
+ return uuidRegex.test(str);
1823
+ };
1824
+ const validOrderId = request.order_id && isValidUUID(request.order_id) ? request.order_id : void 0;
1825
+ const response = await fetch(`${config.backendUrls.payment}/payments/storefront/initiate`, {
1826
+ method: "POST",
1827
+ headers: {
1828
+ "Content-Type": "application/json",
1829
+ "Authorization": `Bearer ${accessToken}`,
1830
+ "X-Storefront-Key": config.storefrontApiKey,
1831
+ "X-Business-ID": config.businessId
1832
+ },
1833
+ body: JSON.stringify({
1834
+ amount: request.amount,
1835
+ currency: request.currency,
1836
+ order_id: validOrderId,
1837
+ quote_id: request.quote_id,
1838
+ metadata_json: {
1839
+ customer_email: request.customer_email,
1840
+ customer_name: request.customer_name ?? "",
1841
+ order_id: validOrderId,
1842
+ ...request.metadata ?? {}
1843
+ },
1844
+ idempotency_key: request.idempotency_key
1845
+ })
2531
1846
  });
2532
- }
2533
- function useAuth() {
2534
- const context = AuthCtx ? (0, import_react2.useContext)(AuthCtx) : null;
2535
- if (context) return context;
2536
- const authUserQuery = useAuthUser();
2537
- const logoutMutation = useLogout();
1847
+ if (!response.ok) throw new Error("Failed to initiate payment");
1848
+ const data = await response.json();
2538
1849
  return {
2539
- customer: authUserQuery.data,
2540
- isLoading: authUserQuery.isLoading,
2541
- isModalOpen: false,
2542
- openModal: () => {
2543
- },
2544
- closeModal: () => {
2545
- },
2546
- setCustomer: () => {
2547
- },
2548
- logout: async () => {
2549
- await logoutMutation.mutateAsync();
2550
- }
1850
+ id: data.id,
1851
+ gateway_ref: data.gateway_ref,
1852
+ gateway: data.gateway,
1853
+ status: data.status,
1854
+ checkout_url: data.metadata_json?.checkout_url ?? ""
2551
1855
  };
2552
1856
  }
2553
-
2554
- // src/hooks/use-countries.ts
2555
- var import_react_query4 = require("@tanstack/react-query");
2556
- async function getCountries() {
2557
- const { data } = await authAxios.get("auth/countries/");
2558
- return data;
2559
- }
2560
- function useCountries() {
2561
- return (0, import_react_query4.useQuery)({
2562
- queryKey: ["countries"],
2563
- queryFn: () => getCountries(),
2564
- retry: 1,
2565
- refetchOnWindowFocus: false,
2566
- refetchOnReconnect: false,
2567
- staleTime: 24 * 60 * 60 * 1e3
2568
- // 24 hours
2569
- });
2570
- }
2571
-
2572
- // src/hooks/use-states.ts
2573
- var import_react_query5 = require("@tanstack/react-query");
2574
- async function getStates(countryIso) {
2575
- if (!countryIso) return [];
2576
- const { data } = await authAxios.get("auth/countries/", {
2577
- params: { iso: countryIso }
1857
+ async function requestQuote(config, amount) {
1858
+ const response = await fetch(`${config.backendUrls.payment}/payments/quote`, {
1859
+ method: "POST",
1860
+ headers: {
1861
+ "Content-Type": "application/json",
1862
+ "X-Storefront-Key": config.storefrontApiKey,
1863
+ "X-Business-ID": config.businessId
1864
+ },
1865
+ body: JSON.stringify({ amount })
2578
1866
  });
1867
+ if (!response.ok) throw new Error("Failed to request quote");
1868
+ const data = await response.json();
2579
1869
  return data;
2580
1870
  }
2581
- function useStates(countryIso) {
2582
- return (0, import_react_query5.useQuery)({
2583
- queryKey: ["states", countryIso],
2584
- queryFn: () => getStates(countryIso),
2585
- enabled: !!countryIso,
2586
- retry: 1,
2587
- refetchOnWindowFocus: false,
2588
- refetchOnReconnect: false,
2589
- staleTime: 24 * 60 * 60 * 1e3
2590
- // 24 hours
2591
- });
2592
- }
2593
-
2594
- // src/hooks/use-languages.ts
2595
- var import_react_query6 = require("@tanstack/react-query");
2596
- async function getSupportedLanguagesList() {
2597
- const data = await getSupportedLanguages();
2598
- return data.languages.map((language) => ({
2599
- code: language.code,
2600
- appCode: language.code,
2601
- label: language.label,
2602
- native: language.label,
2603
- flag: language.flag
2604
- }));
2605
- }
2606
- function useSupportedLanguages() {
2607
- return (0, import_react_query6.useQuery)({
2608
- queryKey: ["supported-languages"],
2609
- queryFn: () => getSupportedLanguagesList(),
2610
- enabled: isInitialized(),
2611
- retry: 1,
2612
- ...getCacheTier("high")
2613
- });
2614
- }
2615
-
2616
- // src/hooks/use-currencies.ts
2617
- var import_react_query7 = require("@tanstack/react-query");
2618
- async function getSupportedCurrenciesList() {
2619
- const data = await getSupportedCurrencies();
2620
- return data.currencies || [];
2621
- }
2622
- function useCurrencies() {
2623
- return (0, import_react_query7.useQuery)({
2624
- queryKey: ["supported-currencies"],
2625
- queryFn: () => getSupportedCurrenciesList(),
2626
- enabled: isInitialized(),
2627
- retry: 1,
2628
- ...getCacheTier("high")
2629
- });
1871
+ async function verifyTransaction(configOrReference, reference) {
1872
+ if (typeof configOrReference === "string") {
1873
+ const ref2 = configOrReference;
1874
+ const response2 = await fetch(`/api/payments/verify/${ref2}`, {
1875
+ method: "POST",
1876
+ headers: { "Content-Type": "application/json" }
1877
+ });
1878
+ if (!response2.ok) throw new Error("Failed to verify transaction");
1879
+ return response2.json();
1880
+ }
1881
+ const config = configOrReference;
1882
+ const ref = reference || "";
1883
+ const response = await fetch(`${config.backendUrls.payment}/payments/verify/${ref}`, {
1884
+ method: "POST",
1885
+ headers: {
1886
+ "Content-Type": "application/json",
1887
+ "X-Storefront-Key": config.storefrontApiKey,
1888
+ "X-Business-ID": config.businessId
1889
+ }
1890
+ });
1891
+ if (!response.ok) throw new Error("Failed to verify transaction");
1892
+ const data = await response.json();
1893
+ return data;
2630
1894
  }
2631
-
2632
- // src/hooks/use-bespoke-availability.ts
2633
- var import_react_query8 = require("@tanstack/react-query");
2634
- function useBespokeAvailability(product_id) {
2635
- return (0, import_react_query8.useQuery)({
2636
- queryKey: ["bespoke-availability", product_id],
2637
- queryFn: () => bespokeService.checkAvailability(product_id),
2638
- enabled: !!product_id,
2639
- retry: false
2640
- // Don't retry if no config exists (returns 404)
1895
+ async function getTransactionStatus(config, transactionId) {
1896
+ const response = await fetch(`${config.backendUrls.payment}/payments/transactions/${transactionId}`, {
1897
+ headers: {
1898
+ "X-Storefront-Key": config.storefrontApiKey,
1899
+ "X-Business-ID": config.businessId
1900
+ }
2641
1901
  });
1902
+ if (!response.ok) throw new Error("Failed to get transaction status");
1903
+ const data = await response.json();
1904
+ return data;
2642
1905
  }
2643
-
2644
- // src/hooks/use-collections.ts
2645
- var import_react_query9 = require("@tanstack/react-query");
2646
- var collectionKeys = {
2647
- all: ["core", "collections"],
2648
- list: (params) => ["core", "collections", "list", params ?? {}],
2649
- slug: (slug) => ["core", "collections", "slug", slug]
1906
+ var paymentService = {
1907
+ createDedicatedAccount,
1908
+ initiatePayment,
1909
+ requestQuote,
1910
+ verifyTransaction,
1911
+ getTransactionStatus
2650
1912
  };
2651
- function useStorefrontCollections(params) {
2652
- return (0, import_react_query9.useQuery)({
2653
- queryKey: collectionKeys.list(params),
2654
- queryFn: () => getStorefrontCollections(params),
2655
- // medium — collections change infrequently
2656
- ...getCacheTier("medium")
2657
- });
2658
- }
2659
- function useStorefrontCollection(slug) {
2660
- return (0, import_react_query9.useQuery)({
2661
- queryKey: collectionKeys.slug(slug),
2662
- queryFn: () => getStorefrontCollectionBySlug(slug),
2663
- // medium — collection details change infrequently
2664
- ...getCacheTier("medium"),
2665
- enabled: !!slug
2666
- });
2667
- }
2668
1913
 
2669
- // src/hooks/use-products.ts
2670
- var import_react_query10 = require("@tanstack/react-query");
2671
- var productKeys = {
2672
- all: ["products"],
2673
- list: (params) => [...productKeys.all, "list", params],
2674
- detail: (slug) => [...productKeys.all, "detail", slug],
2675
- recommended: (params) => [...productKeys.all, "recommended", params],
2676
- latest: (params) => [...productKeys.all, "latest", params],
2677
- popular: (params) => [...productKeys.all, "popular", params],
2678
- featured: (params) => [...productKeys.all, "featured", params],
2679
- new: (params) => [...productKeys.all, "new", params]
2680
- };
2681
- function useLatestProducts(params) {
2682
- return (0, import_react_query10.useQuery)({
2683
- queryKey: productKeys.latest(params),
2684
- queryFn: () => getLatestProducts(params),
2685
- // medium — latest products change infrequently
2686
- ...getCacheTier("medium")
2687
- });
2688
- }
2689
- function usePopularProducts(params) {
2690
- return (0, import_react_query10.useQuery)({
2691
- queryKey: productKeys.popular(params),
2692
- queryFn: () => getPopularProducts(params),
2693
- // medium — popular products change infrequently
2694
- ...getCacheTier("medium")
2695
- });
2696
- }
2697
- function useFeaturedProducts(params) {
2698
- return (0, import_react_query10.useQuery)({
2699
- queryKey: productKeys.featured(params),
2700
- queryFn: () => getFeaturedProducts(params),
2701
- // medium — featured products change infrequently
2702
- ...getCacheTier("medium")
1914
+ // src/services/consultation.service.ts
1915
+ async function createConsultation(config, accessToken, payload) {
1916
+ const response = await fetch(`${config.backendUrls.store}/social/consultations/`, {
1917
+ method: "POST",
1918
+ headers: {
1919
+ "Content-Type": "application/json",
1920
+ "Authorization": `Bearer ${accessToken}`,
1921
+ "X-Storefront-Key": config.storefrontApiKey,
1922
+ "X-Business-ID": config.businessId
1923
+ },
1924
+ body: JSON.stringify(payload)
2703
1925
  });
1926
+ if (!response.ok) throw new Error("Failed to create consultation");
1927
+ return response.json();
2704
1928
  }
2705
- function useNewProducts(params) {
2706
- return (0, import_react_query10.useQuery)({
2707
- queryKey: productKeys.new(params),
2708
- queryFn: () => getNewProducts(params),
2709
- // medium — new products change infrequently
2710
- ...getCacheTier("medium")
1929
+ async function getConsultations(config, accessToken) {
1930
+ const response = await fetch(`${config.backendUrls.store}/social/consultations/`, {
1931
+ headers: {
1932
+ "Authorization": `Bearer ${accessToken}`,
1933
+ "X-Storefront-Key": config.storefrontApiKey,
1934
+ "X-Business-ID": config.businessId
1935
+ }
2711
1936
  });
1937
+ if (!response.ok) throw new Error("Failed to get consultations");
1938
+ return response.json();
2712
1939
  }
2713
- function useStorefrontProducts(params) {
2714
- return (0, import_react_query10.useQuery)({
2715
- queryKey: productKeys.list(params),
2716
- queryFn: () => getStorefrontProducts(params),
2717
- // medium — product catalog changes infrequently
2718
- ...getCacheTier("medium")
1940
+ async function getConsultation(config, accessToken, id) {
1941
+ const response = await fetch(`${config.backendUrls.store}/social/consultations/${id}`, {
1942
+ headers: {
1943
+ "Authorization": `Bearer ${accessToken}`,
1944
+ "X-Storefront-Key": config.storefrontApiKey,
1945
+ "X-Business-ID": config.businessId
1946
+ }
2719
1947
  });
1948
+ if (!response.ok) throw new Error("Failed to get consultation");
1949
+ return response.json();
2720
1950
  }
2721
- function useProduct(slug) {
2722
- return (0, import_react_query10.useQuery)({
2723
- queryKey: productKeys.detail(slug),
2724
- queryFn: () => getStorefrontProductBySlug(slug),
2725
- // medium — product details change infrequently
2726
- ...getCacheTier("medium"),
2727
- enabled: !!slug
1951
+ async function sendMessage(config, accessToken, id, payload) {
1952
+ await fetch(`${config.backendUrls.store}/social/consultations/${id}/messages`, {
1953
+ method: "POST",
1954
+ headers: {
1955
+ "Content-Type": "application/json",
1956
+ "Authorization": `Bearer ${accessToken}`,
1957
+ "X-Storefront-Key": config.storefrontApiKey,
1958
+ "X-Business-ID": config.businessId
1959
+ },
1960
+ body: JSON.stringify(payload)
2728
1961
  });
2729
1962
  }
2730
- function useRecommendedProducts(params) {
2731
- return (0, import_react_query10.useQuery)({
2732
- queryKey: productKeys.recommended(params),
2733
- queryFn: () => getRecommendedProducts(params),
2734
- // medium — recommendations change infrequently
2735
- ...getCacheTier("medium")
1963
+ async function acceptQuote(config, accessToken, id, payload) {
1964
+ const response = await fetch(`${config.backendUrls.store}/social/consultations/${id}/accept-quote`, {
1965
+ method: "POST",
1966
+ headers: {
1967
+ "Content-Type": "application/json",
1968
+ "Authorization": `Bearer ${accessToken}`,
1969
+ "X-Storefront-Key": config.storefrontApiKey,
1970
+ "X-Business-ID": config.businessId
1971
+ },
1972
+ body: JSON.stringify(payload)
1973
+ });
1974
+ if (!response.ok) throw new Error("Failed to accept quote");
1975
+ return response.json();
1976
+ }
1977
+ async function rejectQuote(config, accessToken, id, reason) {
1978
+ const response = await fetch(`${config.backendUrls.store}/social/consultations/${id}/reject-quote`, {
1979
+ method: "POST",
1980
+ headers: {
1981
+ "Content-Type": "application/json",
1982
+ "Authorization": `Bearer ${accessToken}`,
1983
+ "X-Storefront-Key": config.storefrontApiKey,
1984
+ "X-Business-ID": config.businessId
1985
+ },
1986
+ body: JSON.stringify({ reason })
2736
1987
  });
1988
+ if (!response.ok) throw new Error("Failed to reject quote");
1989
+ return response.json();
2737
1990
  }
2738
-
2739
- // src/hooks/use-wishlist.ts
2740
- var import_react_query11 = require("@tanstack/react-query");
2741
- var wishlistKeys = {
2742
- all: ["wishlist"],
2743
- list: () => [...wishlistKeys.all, "list"],
2744
- check: (productId) => [...wishlistKeys.all, "check", productId]
1991
+ var consultationService = {
1992
+ createConsultation,
1993
+ getConsultations,
1994
+ getConsultation,
1995
+ sendMessage,
1996
+ acceptQuote,
1997
+ rejectQuote
2745
1998
  };
2746
- function useWishlist(params) {
2747
- return (0, import_react_query11.useQuery)({
2748
- queryKey: [...wishlistKeys.list(), params],
2749
- queryFn: () => getWishlist(params),
2750
- // medium — wishlist changes infrequently
2751
- ...getCacheTier("medium")
2752
- });
2753
- }
2754
- function useCheckInWishlist(productId) {
2755
- return (0, import_react_query11.useQuery)({
2756
- queryKey: wishlistKeys.check(productId),
2757
- queryFn: () => checkInWishlist(productId),
2758
- // low — wishlist check changes frequently
2759
- ...getCacheTier("low"),
2760
- enabled: !!productId
2761
- });
2762
- }
2763
- function useAddToWishlist() {
2764
- const queryClient = (0, import_react_query11.useQueryClient)();
2765
- return (0, import_react_query11.useMutation)({
2766
- mutationFn: ({ productId, notes }) => {
2767
- return addToWishlist(productId, notes);
1999
+
2000
+ // src/services/logistics.service.ts
2001
+ async function getShippingRates(config, payload) {
2002
+ const response = await fetch(`${config.backendUrls.store}/logistics/shipping/rates`, {
2003
+ method: "POST",
2004
+ headers: {
2005
+ "Content-Type": "application/json",
2006
+ "X-Storefront-Key": config.storefrontApiKey,
2007
+ "X-Business-ID": config.businessId
2768
2008
  },
2769
- onSuccess: () => {
2770
- queryClient.invalidateQueries({ queryKey: wishlistKeys.all });
2771
- queryClient.invalidateQueries({ queryKey: ["wishlist", "check"] });
2772
- }
2009
+ body: JSON.stringify(payload)
2773
2010
  });
2011
+ if (!response.ok) throw new Error("Failed to get shipping rates");
2012
+ return response.json();
2774
2013
  }
2775
- function useRemoveFromWishlist() {
2776
- const queryClient = (0, import_react_query11.useQueryClient)();
2777
- return (0, import_react_query11.useMutation)({
2778
- mutationFn: (itemId) => {
2779
- return removeFromWishlist(itemId);
2780
- },
2781
- onSuccess: () => {
2782
- queryClient.invalidateQueries({ queryKey: wishlistKeys.all });
2783
- queryClient.invalidateQueries({ queryKey: ["wishlist", "check"] });
2014
+ async function getSellerShippingAddress(config) {
2015
+ const response = await fetch(`${config.backendUrls.store}/logistics/shipping-address`, {
2016
+ headers: {
2017
+ "X-Storefront-Key": config.storefrontApiKey,
2018
+ "X-Business-ID": config.businessId
2784
2019
  }
2785
2020
  });
2021
+ if (!response.ok) throw new Error("Failed to get seller shipping address");
2022
+ return response.json();
2786
2023
  }
2787
- function useRemoveProductFromWishlist() {
2788
- const queryClient = (0, import_react_query11.useQueryClient)();
2789
- return (0, import_react_query11.useMutation)({
2790
- mutationFn: (productId) => {
2791
- return removeProductFromWishlist(productId);
2024
+ async function validateShippingAddress(config, payload) {
2025
+ const response = await fetch(`${config.backendUrls.store}/logistics/shipping-address/validate`, {
2026
+ method: "POST",
2027
+ headers: {
2028
+ "Content-Type": "application/json",
2029
+ "X-Storefront-Key": config.storefrontApiKey,
2030
+ "X-Business-ID": config.businessId
2792
2031
  },
2793
- onSuccess: () => {
2794
- queryClient.invalidateQueries({ queryKey: wishlistKeys.all });
2795
- queryClient.invalidateQueries({ queryKey: ["wishlist", "check"] });
2796
- }
2032
+ body: JSON.stringify(payload)
2797
2033
  });
2034
+ if (!response.ok) throw new Error("Failed to validate shipping address");
2035
+ return response.json();
2798
2036
  }
2799
- function useWishlistCount() {
2800
- const backendQuery = (0, import_react_query11.useQuery)({
2801
- queryKey: wishlistKeys.list(),
2802
- queryFn: () => getWishlist(),
2803
- // low — wishlist count changes frequently
2804
- ...getCacheTier("low"),
2805
- select: (data) => data.total
2806
- });
2807
- return backendQuery;
2808
- }
2037
+ var logisticsService = {
2038
+ getShippingRates,
2039
+ getSellerShippingAddress,
2040
+ validateShippingAddress
2041
+ };
2809
2042
 
2810
- // src/hooks/use-service-booking.ts
2811
- var import_react_query12 = require("@tanstack/react-query");
2812
- function useAvailableSlots(product_id, date_from, date_to) {
2813
- return (0, import_react_query12.useQuery)({
2814
- queryKey: ["available-slots", product_id, date_from, date_to],
2815
- queryFn: () => serviceBookingService.getAvailableSlots(product_id, date_from, date_to),
2816
- enabled: !!product_id && !!date_from && !!date_to
2043
+ // src/services/bespoke.service.ts
2044
+ async function checkAvailability(config, product_id) {
2045
+ const response = await fetch(`${config.backendUrls.store}/bespoke/availability/${product_id}`, {
2046
+ headers: {
2047
+ "X-Storefront-Key": config.storefrontApiKey,
2048
+ "X-Business-ID": config.businessId
2049
+ }
2817
2050
  });
2051
+ if (!response.ok) throw new Error("Failed to check bespoke availability");
2052
+ return response.json();
2818
2053
  }
2819
- function useBookAppointment() {
2820
- const queryClient = (0, import_react_query12.useQueryClient)();
2821
- return (0, import_react_query12.useMutation)({
2822
- mutationFn: serviceBookingService.bookAppointment,
2823
- onSuccess: () => {
2824
- queryClient.invalidateQueries({ queryKey: ["appointments"] });
2054
+ var bespokeService = {
2055
+ checkAvailability
2056
+ };
2057
+
2058
+ // src/services/service-booking.service.ts
2059
+ async function getAvailableSlots(config, product_id, date_from, date_to) {
2060
+ const response = await fetch(
2061
+ `${config.backendUrls.store}/service/available-slots/${product_id}?date_from=${date_from}&date_to=${date_to}`,
2062
+ {
2063
+ headers: {
2064
+ "X-Storefront-Key": config.storefrontApiKey,
2065
+ "X-Business-ID": config.businessId
2066
+ }
2825
2067
  }
2068
+ );
2069
+ if (!response.ok) throw new Error("Failed to get available slots");
2070
+ return response.json();
2071
+ }
2072
+ async function bookAppointment(config, accessToken, payload) {
2073
+ const response = await fetch(`${config.backendUrls.store}/service/appointments/`, {
2074
+ method: "POST",
2075
+ headers: {
2076
+ "Content-Type": "application/json",
2077
+ "Authorization": `Bearer ${accessToken}`,
2078
+ "X-Storefront-Key": config.storefrontApiKey,
2079
+ "X-Business-ID": config.businessId
2080
+ },
2081
+ body: JSON.stringify(payload)
2826
2082
  });
2083
+ if (!response.ok) throw new Error("Failed to book appointment");
2084
+ return response.json();
2827
2085
  }
2828
- function useAppointments() {
2829
- return (0, import_react_query12.useQuery)({
2830
- queryKey: ["appointments"],
2831
- queryFn: serviceBookingService.getAppointments
2086
+ async function getAppointments(config, accessToken) {
2087
+ const response = await fetch(`${config.backendUrls.store}/service/bookings/my`, {
2088
+ headers: {
2089
+ "Authorization": `Bearer ${accessToken}`,
2090
+ "X-Storefront-Key": config.storefrontApiKey,
2091
+ "X-Business-ID": config.businessId
2092
+ }
2832
2093
  });
2094
+ if (!response.ok) throw new Error("Failed to get appointments");
2095
+ return response.json();
2833
2096
  }
2834
- function useAppointment(id) {
2835
- return (0, import_react_query12.useQuery)({
2836
- queryKey: ["appointment", id],
2837
- queryFn: () => serviceBookingService.getAppointment(id),
2838
- enabled: !!id
2097
+ async function getAppointment(config, accessToken, id) {
2098
+ const response = await fetch(`${config.backendUrls.store}/service/bookings/${id}`, {
2099
+ headers: {
2100
+ "Authorization": `Bearer ${accessToken}`,
2101
+ "X-Storefront-Key": config.storefrontApiKey,
2102
+ "X-Business-ID": config.businessId
2103
+ }
2839
2104
  });
2105
+ if (!response.ok) throw new Error("Failed to get appointment");
2106
+ return response.json();
2840
2107
  }
2841
- function useCancelAppointment() {
2842
- const queryClient = (0, import_react_query12.useQueryClient)();
2843
- return (0, import_react_query12.useMutation)({
2844
- mutationFn: (id) => serviceBookingService.cancelAppointment(id),
2845
- onSuccess: () => {
2846
- queryClient.invalidateQueries({ queryKey: ["appointments"] });
2108
+ async function cancelAppointment(config, accessToken, id) {
2109
+ await fetch(`${config.backendUrls.store}/service/bookings/${id}`, {
2110
+ method: "DELETE",
2111
+ headers: {
2112
+ "Authorization": `Bearer ${accessToken}`,
2113
+ "X-Storefront-Key": config.storefrontApiKey,
2114
+ "X-Business-ID": config.businessId
2847
2115
  }
2848
2116
  });
2849
2117
  }
2850
- function useDeliverables(order_id) {
2851
- return (0, import_react_query12.useQuery)({
2852
- queryKey: ["deliverables", order_id],
2853
- queryFn: () => serviceBookingService.getDeliverables(order_id),
2854
- enabled: !!order_id
2118
+ async function getDeliverables(config, accessToken, order_id) {
2119
+ const response = await fetch(`${config.backendUrls.store}/service/projects/${order_id}/deliverables/`, {
2120
+ headers: {
2121
+ "Authorization": `Bearer ${accessToken}`,
2122
+ "X-Storefront-Key": config.storefrontApiKey,
2123
+ "X-Business-ID": config.businessId
2124
+ }
2855
2125
  });
2126
+ if (!response.ok) throw new Error("Failed to get deliverables");
2127
+ return response.json();
2856
2128
  }
2857
- function useApproveDeliverable(order_id, deliverable_id) {
2858
- const queryClient = (0, import_react_query12.useQueryClient)();
2859
- return (0, import_react_query12.useMutation)({
2860
- mutationFn: () => serviceBookingService.approveDeliverable(order_id, deliverable_id),
2861
- onSuccess: () => {
2862
- queryClient.invalidateQueries({ queryKey: ["deliverables", order_id] });
2129
+ async function approveDeliverable(config, accessToken, order_id, deliverable_id) {
2130
+ const response = await fetch(
2131
+ `${config.backendUrls.store}/service/projects/${order_id}/deliverables/${deliverable_id}/approve`,
2132
+ {
2133
+ method: "POST",
2134
+ headers: {
2135
+ "Content-Type": "application/json",
2136
+ "Authorization": `Bearer ${accessToken}`,
2137
+ "X-Storefront-Key": config.storefrontApiKey,
2138
+ "X-Business-ID": config.businessId
2139
+ },
2140
+ body: JSON.stringify({ approved: true })
2863
2141
  }
2864
- });
2142
+ );
2143
+ if (!response.ok) throw new Error("Failed to approve deliverable");
2144
+ return response.json();
2865
2145
  }
2866
- function useRequestRevision(order_id, deliverable_id) {
2867
- const queryClient = (0, import_react_query12.useQueryClient)();
2868
- return (0, import_react_query12.useMutation)({
2869
- mutationFn: (feedback) => serviceBookingService.requestRevision(order_id, deliverable_id, feedback),
2870
- onSuccess: () => {
2871
- queryClient.invalidateQueries({ queryKey: ["deliverables", order_id] });
2146
+ async function requestRevision(config, accessToken, order_id, deliverable_id, feedback) {
2147
+ const response = await fetch(
2148
+ `${config.backendUrls.store}/service/projects/${order_id}/deliverables/${deliverable_id}/revision`,
2149
+ {
2150
+ method: "POST",
2151
+ headers: {
2152
+ "Content-Type": "application/json",
2153
+ "Authorization": `Bearer ${accessToken}`,
2154
+ "X-Storefront-Key": config.storefrontApiKey,
2155
+ "X-Business-ID": config.businessId
2156
+ },
2157
+ body: JSON.stringify({ approved: false, feedback })
2872
2158
  }
2873
- });
2159
+ );
2160
+ if (!response.ok) throw new Error("Failed to request revision");
2161
+ return response.json();
2874
2162
  }
2163
+ var serviceBookingService = {
2164
+ getAvailableSlots,
2165
+ bookAppointment,
2166
+ getAppointments,
2167
+ getAppointment,
2168
+ cancelAppointment,
2169
+ getDeliverables,
2170
+ approveDeliverable,
2171
+ requestRevision
2172
+ };
2875
2173
 
2876
- // src/hooks/use-consultations.ts
2877
- var import_react_query13 = require("@tanstack/react-query");
2878
- function useConsultations() {
2879
- return (0, import_react_query13.useQuery)({
2880
- queryKey: ["consultations"],
2881
- queryFn: () => consultationService.getConsultations()
2882
- });
2883
- }
2884
- function useConsultation(id) {
2885
- return (0, import_react_query13.useQuery)({
2886
- queryKey: ["consultation", id],
2887
- queryFn: () => consultationService.getConsultation(id),
2888
- enabled: !!id
2174
+ // src/services/notifications.service.ts
2175
+ async function sendContactEmail(config, payload) {
2176
+ const response = await fetch(`${config.backendUrls.notifications}/contact/send-contact-email`, {
2177
+ method: "POST",
2178
+ headers: {
2179
+ "Content-Type": "application/json",
2180
+ "X-Storefront-Key": config.storefrontApiKey,
2181
+ "X-Business-ID": config.businessId
2182
+ },
2183
+ body: JSON.stringify(payload)
2184
+ });
2185
+ if (!response.ok) throw new Error("Failed to send contact email");
2186
+ return response.json();
2187
+ }
2188
+ async function sendContactConfirmation(config, payload) {
2189
+ const response = await fetch(`${config.backendUrls.notifications}/contact/send-contact-confirmation`, {
2190
+ method: "POST",
2191
+ headers: {
2192
+ "Content-Type": "application/json",
2193
+ "X-Storefront-Key": config.storefrontApiKey,
2194
+ "X-Business-ID": config.businessId
2195
+ },
2196
+ body: JSON.stringify(payload)
2889
2197
  });
2198
+ if (!response.ok) throw new Error("Failed to send contact confirmation");
2199
+ return response.json();
2890
2200
  }
2891
- function useCreateConsultation() {
2892
- const queryClient = (0, import_react_query13.useQueryClient)();
2893
- return (0, import_react_query13.useMutation)({
2894
- mutationFn: (payload) => consultationService.createConsultation(payload),
2895
- onSuccess: () => {
2896
- queryClient.invalidateQueries({ queryKey: ["consultations"] });
2897
- }
2898
- });
2201
+ var notificationsService = {
2202
+ sendContactEmail,
2203
+ sendContactConfirmation
2204
+ };
2205
+
2206
+ // src/services/app.service.ts
2207
+ async function googleTranslate(text, target, source = "en") {
2208
+ if (!text || target === source) return text;
2209
+ try {
2210
+ const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${source}&tl=${target}&dt=t&q=${encodeURIComponent(text)}`;
2211
+ const res = await fetch(url);
2212
+ const data = await res.json();
2213
+ return (data?.[0] || []).map((s) => s[0]).join("");
2214
+ } catch {
2215
+ return text;
2216
+ }
2899
2217
  }
2900
- function useSendMessage(consultationId) {
2901
- const queryClient = (0, import_react_query13.useQueryClient)();
2902
- return (0, import_react_query13.useMutation)({
2903
- mutationFn: (payload) => consultationService.sendMessage(consultationId, payload),
2904
- onSuccess: () => {
2905
- queryClient.invalidateQueries({ queryKey: ["consultation", consultationId] });
2218
+
2219
+ // src/services/config.service.ts
2220
+ async function getSupportedLanguages(config) {
2221
+ const response = await fetch(`${config.backendUrls.payment}/config/supported-languages`, {
2222
+ headers: {
2223
+ "X-Storefront-Key": config.storefrontApiKey,
2224
+ "X-Business-ID": config.businessId
2906
2225
  }
2907
2226
  });
2227
+ if (!response.ok) throw new Error("Failed to get supported languages");
2228
+ return response.json();
2908
2229
  }
2909
- function useAcceptQuote(consultationId) {
2910
- const queryClient = (0, import_react_query13.useQueryClient)();
2911
- return (0, import_react_query13.useMutation)({
2912
- mutationFn: (payload) => consultationService.acceptQuote(consultationId, payload),
2913
- onSuccess: () => {
2914
- queryClient.invalidateQueries({ queryKey: ["consultation", consultationId] });
2230
+ async function getSupportedCurrencies(config) {
2231
+ const response = await fetch(`${config.backendUrls.payment}/config/supported-currencies`, {
2232
+ headers: {
2233
+ "X-Storefront-Key": config.storefrontApiKey,
2234
+ "X-Business-ID": config.businessId
2915
2235
  }
2916
2236
  });
2237
+ if (!response.ok) throw new Error("Failed to get supported currencies");
2238
+ return response.json();
2917
2239
  }
2918
- function useRejectQuote(consultationId) {
2919
- const queryClient = (0, import_react_query13.useQueryClient)();
2920
- return (0, import_react_query13.useMutation)({
2921
- mutationFn: (reason) => consultationService.rejectQuote(consultationId, reason),
2922
- onSuccess: () => {
2923
- queryClient.invalidateQueries({ queryKey: ["consultation", consultationId] });
2240
+ async function getBusinessConfig(config) {
2241
+ const response = await fetch(`${config.backendUrls.auth}/internal/businesses/${config.businessId}/`, {
2242
+ headers: {
2243
+ "X-Storefront-Key": config.storefrontApiKey,
2244
+ "X-Business-ID": config.businessId
2924
2245
  }
2925
2246
  });
2247
+ if (!response.ok) throw new Error("Failed to get business config");
2248
+ return response.json();
2926
2249
  }
2927
-
2928
- // src/hooks/use-consultation-stream.ts
2929
- var import_react3 = require("react");
2930
- var import_fetch_event_source = require("@microsoft/fetch-event-source");
2931
- function useConsultationStream({
2932
- consultationId,
2933
- onMessage,
2934
- onQuote,
2935
- onStatusChange,
2936
- onError
2937
- }) {
2938
- const abortControllerRef = (0, import_react3.useRef)(null);
2939
- const [isConnected, setIsConnected] = (0, import_react3.useState)(false);
2940
- const [lastEvent, setLastEvent] = (0, import_react3.useState)(null);
2941
- (0, import_react3.useEffect)(() => {
2942
- if (!consultationId) {
2943
- return;
2944
- }
2945
- const abortController = new AbortController();
2946
- abortControllerRef.current = abortController;
2947
- const paymentUrl = getBackendUrl("payment");
2948
- const streamUrl = `${paymentUrl}/events/stream/consultation/${consultationId}`;
2949
- (0, import_fetch_event_source.fetchEventSource)(streamUrl, {
2950
- method: "GET",
2951
- signal: abortController.signal,
2952
- onmessage: (event) => {
2953
- try {
2954
- if (!event.data || event.data.trim() === "") {
2955
- return;
2956
- }
2957
- const data = JSON.parse(event.data);
2958
- logger.log("[ConsultationStream] Received event:", data);
2959
- setLastEvent(data);
2960
- if (data.event === "consultation.message") {
2961
- logger.log("[ConsultationStream] Message detected, calling onMessage");
2962
- if (onMessage) {
2963
- onMessage(data);
2964
- }
2965
- }
2966
- if (data.event === "consultation.quote") {
2967
- logger.log("[ConsultationStream] Quote detected, calling onQuote");
2968
- if (onQuote) {
2969
- onQuote(data);
2970
- }
2971
- }
2972
- if (data.event === "consultation.status") {
2973
- logger.log("[ConsultationStream] Status change detected, calling onStatusChange");
2974
- if (onStatusChange) {
2975
- onStatusChange(data);
2976
- }
2977
- }
2978
- } catch (error) {
2979
- logger.error("[ConsultationStream] Error parsing event:", error);
2980
- }
2981
- },
2982
- onerror: (error) => {
2983
- if (abortController.signal.aborted) {
2984
- logger.log("[ConsultationStream] Connection closed via AbortController");
2985
- return;
2986
- }
2987
- logger.error("[ConsultationStream] Connection error:", error);
2988
- setIsConnected(false);
2989
- if (onError) {
2990
- onError(error);
2991
- }
2992
- },
2993
- onopen: async (response) => {
2994
- if (response.ok && response.headers.get("content-type")?.includes("text/event-stream")) {
2995
- logger.log("[ConsultationStream] Connection established for consultation:", consultationId);
2996
- setIsConnected(true);
2997
- return;
2998
- }
2999
- throw new Error(`Unexpected response: ${response.status}`);
3000
- }
3001
- }).catch((error) => {
3002
- if (abortController.signal.aborted || error.name === "AbortError") {
3003
- return;
2250
+ var configService = {
2251
+ getSupportedLanguages,
2252
+ getSupportedCurrencies,
2253
+ getBusinessConfig
2254
+ };
2255
+
2256
+ // src/services/cms.service.ts
2257
+ async function listCmsEntries(config, modelSlug, params) {
2258
+ const queryParams = new URLSearchParams();
2259
+ queryParams.set("page", (params?.page || 1).toString());
2260
+ queryParams.set("page_size", (params?.page_size || 50).toString());
2261
+ const response = await fetch(
2262
+ `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries?${queryParams.toString()}`,
2263
+ {
2264
+ headers: {
2265
+ "X-Storefront-Key": config.storefrontApiKey,
2266
+ "X-Business-ID": config.businessId
3004
2267
  }
3005
- logger.error("[ConsultationStream] fetchEventSource failed:", error);
3006
- });
3007
- return () => {
3008
- abortController.abort();
3009
- setIsConnected(false);
3010
- };
3011
- }, [consultationId, onMessage, onQuote, onStatusChange, onError]);
3012
- return { isConnected, lastEvent };
2268
+ }
2269
+ );
2270
+ if (!response.ok) throw new Error("Failed to list CMS entries");
2271
+ return response.json();
3013
2272
  }
3014
-
3015
- // src/hooks/use-order-stream.ts
3016
- var import_react4 = require("react");
3017
- var import_fetch_event_source2 = require("@microsoft/fetch-event-source");
3018
- function useOrderStream({
3019
- orderId,
3020
- onPaymentComplete,
3021
- onDigitalReady,
3022
- onBespokeUpdate,
3023
- onConsultationUpdate,
3024
- onServiceBookingUpdate,
3025
- onError
3026
- }) {
3027
- const abortControllerRef = (0, import_react4.useRef)(null);
3028
- (0, import_react4.useEffect)(() => {
3029
- if (!orderId) {
3030
- return;
2273
+ async function getCmsEntry(config, modelSlug, entryId) {
2274
+ const response = await fetch(
2275
+ `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries/${entryId}`,
2276
+ {
2277
+ headers: {
2278
+ "X-Storefront-Key": config.storefrontApiKey,
2279
+ "X-Business-ID": config.businessId
2280
+ }
3031
2281
  }
3032
- const abortController = new AbortController();
3033
- abortControllerRef.current = abortController;
3034
- const paymentUrl = getBackendUrl("payment");
3035
- const streamUrl = `${paymentUrl}/events/stream/order/${encodeURIComponent(orderId)}`;
3036
- (0, import_fetch_event_source2.fetchEventSource)(streamUrl, {
3037
- method: "GET",
3038
- signal: abortController.signal,
3039
- onmessage: (event) => {
3040
- try {
3041
- if (!event.data || event.data.trim() === "") {
3042
- return;
3043
- }
3044
- const data = JSON.parse(event.data);
3045
- logger.log("[OrderStream] Received event:", data);
3046
- if (data.event === "payment.success") {
3047
- logger.log("[OrderStream] Payment success detected, calling onPaymentComplete");
3048
- if (onPaymentComplete) {
3049
- onPaymentComplete(data);
3050
- }
3051
- abortController.abort();
3052
- }
3053
- if (data.event === "digital.ready") {
3054
- logger.log("[OrderStream] Digital delivery ready detected, calling onDigitalReady");
3055
- if (onDigitalReady) {
3056
- onDigitalReady(data);
3057
- }
3058
- }
3059
- if (data.event === "bespoke.update") {
3060
- logger.log("[OrderStream] Bespoke update detected, calling onBespokeUpdate");
3061
- if (onBespokeUpdate) {
3062
- onBespokeUpdate(data);
3063
- }
3064
- }
3065
- if (data.event === "consultation.update") {
3066
- logger.log("[OrderStream] Consultation update detected, calling onConsultationUpdate");
3067
- if (onConsultationUpdate) {
3068
- onConsultationUpdate(data);
3069
- }
3070
- }
3071
- if (data.event === "service_booking.update") {
3072
- logger.log("[OrderStream] Service booking update detected, calling onServiceBookingUpdate");
3073
- if (onServiceBookingUpdate) {
3074
- onServiceBookingUpdate(data);
3075
- }
3076
- }
3077
- } catch (error) {
3078
- logger.error("[OrderStream] Error parsing event:", error);
3079
- }
2282
+ );
2283
+ if (!response.ok) throw new Error("Failed to get CMS entry");
2284
+ return response.json();
2285
+ }
2286
+ async function createCmsEntry(config, accessToken, modelSlug, params) {
2287
+ const response = await fetch(
2288
+ `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries`,
2289
+ {
2290
+ method: "POST",
2291
+ headers: {
2292
+ "Content-Type": "application/json",
2293
+ "Authorization": `Bearer ${accessToken}`,
2294
+ "X-Storefront-Key": config.storefrontApiKey,
2295
+ "X-Business-ID": config.businessId
3080
2296
  },
3081
- onerror: (error) => {
3082
- if (abortController.signal.aborted) {
3083
- logger.log("[OrderStream] Connection closed via AbortController");
3084
- return;
3085
- }
3086
- if (error.message?.includes("404") || error.message?.includes("Not Found")) {
3087
- logger.warn("[OrderStream] Stream endpoint unavailable for order:", orderId);
3088
- return;
3089
- }
3090
- logger.error("[OrderStream] Connection error:", error);
3091
- if (onError) {
3092
- onError(error);
3093
- }
2297
+ body: JSON.stringify(params)
2298
+ }
2299
+ );
2300
+ if (!response.ok) throw new Error("Failed to create CMS entry");
2301
+ return response.json();
2302
+ }
2303
+ async function updateCmsEntry(config, accessToken, modelSlug, entryId, params) {
2304
+ const response = await fetch(
2305
+ `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries/${entryId}`,
2306
+ {
2307
+ method: "PUT",
2308
+ headers: {
2309
+ "Content-Type": "application/json",
2310
+ "Authorization": `Bearer ${accessToken}`,
2311
+ "X-Storefront-Key": config.storefrontApiKey,
2312
+ "X-Business-ID": config.businessId
3094
2313
  },
3095
- onopen: async (response) => {
3096
- if (response.ok && response.headers.get("content-type")?.includes("text/event-stream")) {
3097
- logger.log("[OrderStream] Connection established for order:", orderId);
3098
- return;
3099
- }
3100
- if (response.status === 404) {
3101
- logger.warn("[OrderStream] Stream endpoint unavailable for order:", orderId);
3102
- return;
3103
- }
3104
- throw new Error(`Unexpected response: ${response.status}`);
3105
- }
3106
- }).catch((error) => {
3107
- if (abortController.signal.aborted || error.name === "AbortError") {
3108
- return;
2314
+ body: JSON.stringify(params)
2315
+ }
2316
+ );
2317
+ if (!response.ok) throw new Error("Failed to update CMS entry");
2318
+ return response.json();
2319
+ }
2320
+ async function deleteCmsEntry(config, accessToken, modelSlug, entryId) {
2321
+ const response = await fetch(
2322
+ `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries/${entryId}`,
2323
+ {
2324
+ method: "DELETE",
2325
+ headers: {
2326
+ "Authorization": `Bearer ${accessToken}`,
2327
+ "X-Storefront-Key": config.storefrontApiKey,
2328
+ "X-Business-ID": config.businessId
3109
2329
  }
3110
- logger.error("[OrderStream] fetchEventSource failed:", error);
3111
- });
3112
- return () => {
3113
- abortController.abort();
3114
- };
3115
- }, [orderId, onPaymentComplete, onDigitalReady, onBespokeUpdate, onConsultationUpdate, onServiceBookingUpdate, onError]);
3116
- return null;
2330
+ }
2331
+ );
2332
+ if (!response.ok) throw new Error("Failed to delete CMS entry");
3117
2333
  }
3118
2334
 
3119
- // src/hooks/use-is-mounted.ts
3120
- var import_react5 = require("react");
3121
- function useIsMounted() {
3122
- const [mounted, setMounted] = (0, import_react5.useState)(false);
3123
- (0, import_react5.useEffect)(() => {
3124
- setMounted(true);
3125
- }, []);
3126
- return mounted;
2335
+ // src/utils/cache.ts
2336
+ var CACHE_TIERS = {
2337
+ none: { staleTime: 0, gcTime: 0 },
2338
+ infinity: { staleTime: Infinity, gcTime: 0 },
2339
+ low: { staleTime: 1e3 * 30, gcTime: 1e3 * 60 },
2340
+ // 30s / 1m
2341
+ medium: { staleTime: 1e3 * 60 * 5, gcTime: 1e3 * 60 * 10 },
2342
+ // 5m / 10m
2343
+ high: { staleTime: 1e3 * 60 * 30, gcTime: 1e3 * 60 * 60 }
2344
+ // 30m / 1h
2345
+ };
2346
+ var isDevelopment = true;
2347
+ function setEnvironmentMode(development) {
2348
+ isDevelopment = development;
3127
2349
  }
2350
+ var getCacheTier = (tier) => {
2351
+ if (isDevelopment) return CACHE_TIERS.none;
2352
+ return CACHE_TIERS[tier];
2353
+ };
3128
2354
 
3129
- // src/hooks/use-google-translate.ts
3130
- var import_react6 = require("react");
3131
- var SCRIPT_ID = "google-translate-script";
3132
- var ELEMENT_ID = "google_translate_element";
3133
- function fireChange(googleCode) {
3134
- const combo = document.querySelector(".goog-te-combo");
3135
- if (combo) {
3136
- combo.value = googleCode;
3137
- combo.dispatchEvent(new Event("change"));
3138
- return true;
3139
- }
3140
- return false;
3141
- }
3142
- function useGoogleTranslate(appLang) {
3143
- const [isLoaded, setIsLoaded] = (0, import_react6.useState)(false);
3144
- const initRef = (0, import_react6.useRef)(false);
3145
- const { data: supportedLangs = [] } = useSupportedLanguages();
3146
- const clearCookies = (0, import_react6.useCallback)(() => {
3147
- if (typeof window === "undefined") return;
3148
- const domains = [
3149
- window.location.hostname,
3150
- "." + window.location.hostname,
3151
- "." + window.location.hostname.split(".").slice(-2).join(".")
3152
- ];
3153
- const path = "/";
3154
- document.cookie = `googtrans=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${path};`;
3155
- domains.forEach((domain) => {
3156
- document.cookie = `googtrans=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${path}; domain=${domain};`;
3157
- });
3158
- }, []);
3159
- const resetToEnglish = (0, import_react6.useCallback)(() => {
3160
- if (typeof window === "undefined") return;
3161
- const googtrans = document.cookie.split("; ").find((row) => row.startsWith("googtrans="))?.split("=")[1];
3162
- const domains = [
3163
- window.location.hostname,
3164
- "." + window.location.hostname,
3165
- window.location.hostname.split(".").slice(-2).join("."),
3166
- "." + window.location.hostname.split(".").slice(-2).join(".")
3167
- ];
3168
- const clear = (name) => {
3169
- document.cookie = `${name}=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
3170
- domains.forEach((d) => {
3171
- document.cookie = `${name}=; Path=/; Domain=${d}; Expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
3172
- });
3173
- };
3174
- clear("googtrans");
3175
- if (googtrans || document.documentElement.classList.contains("translated-ltr") || document.querySelector(".goog-te-banner-frame")) {
3176
- window.location.reload();
3177
- return;
2355
+ // src/utils/logger.ts
2356
+ var isDevelopment2 = true;
2357
+ function setLoggerEnvironmentMode(development) {
2358
+ isDevelopment2 = development;
2359
+ }
2360
+ var logger = {
2361
+ log: (...args) => {
2362
+ if (isDevelopment2) {
2363
+ console.log(...args);
3178
2364
  }
3179
- document.body.style.top = "0";
3180
- document.documentElement.classList.remove("translated-ltr", "translated-rtl");
3181
- const container = document.getElementById(":1.container");
3182
- if (container) container.style.display = "none";
3183
- }, []);
3184
- const changeLanguage = (0, import_react6.useCallback)((nextAppCode) => {
3185
- if (nextAppCode === "en") {
3186
- resetToEnglish();
3187
- return;
2365
+ },
2366
+ warn: (...args) => {
2367
+ if (isDevelopment2) {
2368
+ console.warn(...args);
3188
2369
  }
3189
- const googleCode = nextAppCode;
3190
- const container = document.getElementById(":1.container");
3191
- if (container) container.style.display = "block";
3192
- let tries = 0;
3193
- const tick = () => {
3194
- if (fireChange(googleCode)) return;
3195
- if (tries++ < 30) setTimeout(tick, 200);
3196
- };
3197
- tick();
3198
- }, [resetToEnglish]);
3199
- (0, import_react6.useEffect)(() => {
3200
- if (typeof window === "undefined") return;
3201
- if (appLang === "en" && !initRef.current) return;
3202
- if (initRef.current) return;
3203
- if (supportedLangs.length === 0) return;
3204
- initRef.current = true;
3205
- if (!document.getElementById(ELEMENT_ID)) {
3206
- const host = document.createElement("div");
3207
- host.id = ELEMENT_ID;
3208
- host.style.display = "none";
3209
- document.body.appendChild(host);
2370
+ },
2371
+ /**
2372
+ * Logs a warning to the console in development only.
2373
+ * Alias for warn() for Python logging compatibility.
2374
+ * In production, this is a no-op.
2375
+ */
2376
+ warning: (...args) => {
2377
+ if (isDevelopment2) {
2378
+ console.warn(...args);
3210
2379
  }
3211
- const includedLanguages = supportedLangs.map((l) => l.code).join(",");
3212
- window.googleTranslateElementInit = () => {
3213
- if (window.google?.translate?.TranslateElement) {
3214
- new window.google.translate.TranslateElement(
3215
- { pageLanguage: "en", includedLanguages, autoDisplay: false },
3216
- ELEMENT_ID
3217
- );
3218
- setIsLoaded(true);
3219
- }
3220
- };
3221
- if (!document.getElementById(SCRIPT_ID)) {
3222
- const script = document.createElement("script");
3223
- script.id = SCRIPT_ID;
3224
- script.src = "//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit";
3225
- script.async = true;
3226
- document.body.appendChild(script);
3227
- } else {
3228
- if (window.google?.translate) window.googleTranslateElementInit?.();
2380
+ },
2381
+ error: (...args) => {
2382
+ if (isDevelopment2) {
2383
+ console.error(...args);
3229
2384
  }
3230
- }, [appLang, supportedLangs]);
3231
- (0, import_react6.useEffect)(() => {
3232
- if (isLoaded || appLang === "en" && initRef.current) {
3233
- changeLanguage(appLang);
2385
+ },
2386
+ info: (...args) => {
2387
+ if (isDevelopment2) {
2388
+ console.info(...args);
3234
2389
  }
3235
- }, [appLang, isLoaded, changeLanguage]);
3236
- return { isLoaded };
3237
- }
3238
-
3239
- // src/hooks/use-payment.ts
3240
- var import_react_query14 = require("@tanstack/react-query");
3241
- function useCreateDVA() {
3242
- const queryClient = (0, import_react_query14.useQueryClient)();
3243
- return (0, import_react_query14.useMutation)({
3244
- mutationFn: (request) => paymentService.createDedicatedAccount(request),
3245
- onSuccess: () => {
3246
- queryClient.invalidateQueries({ queryKey: ["payment"] });
2390
+ },
2391
+ createScope: (scope) => ({
2392
+ log: (...args) => {
2393
+ if (isDevelopment2) {
2394
+ console.log(`[${scope}]`, ...args);
2395
+ }
2396
+ },
2397
+ warn: (...args) => {
2398
+ if (isDevelopment2) {
2399
+ console.warn(`[${scope}]`, ...args);
2400
+ }
2401
+ },
2402
+ warning: (...args) => {
2403
+ if (isDevelopment2) {
2404
+ console.warn(`[${scope}]`, ...args);
2405
+ }
2406
+ },
2407
+ error: (...args) => {
2408
+ if (isDevelopment2) {
2409
+ console.error(`[${scope}]`, ...args);
2410
+ }
2411
+ },
2412
+ info: (...args) => {
2413
+ if (isDevelopment2) {
2414
+ console.info(`[${scope}]`, ...args);
2415
+ }
3247
2416
  }
3248
- });
2417
+ })
2418
+ };
2419
+
2420
+ // src/utils/sanitize-url.ts
2421
+ var InvalidBaseURLError = class extends Error {
2422
+ constructor(message) {
2423
+ super(message);
2424
+ this.name = "InvalidBaseURLError";
2425
+ }
2426
+ };
2427
+ var ALLOWED_SCHEMES = /* @__PURE__ */ new Set(["http:", "https:", "ws:", "wss:"]);
2428
+ function sanitizeBaseUrl(url, name = "URL") {
2429
+ if (url == null) {
2430
+ throw new InvalidBaseURLError(`${name} is not set`);
2431
+ }
2432
+ const cleaned0 = url.trim();
2433
+ if (!cleaned0) {
2434
+ throw new InvalidBaseURLError(`${name} is empty`);
2435
+ }
2436
+ const cleaned = cleaned0.replace(/\/+$/, "");
2437
+ let parsed;
2438
+ try {
2439
+ parsed = new URL(cleaned);
2440
+ } catch {
2441
+ throw new InvalidBaseURLError(
2442
+ `${name} must start with http://, https://, ws://, or wss://, got: ${url}`
2443
+ );
2444
+ }
2445
+ if (!ALLOWED_SCHEMES.has(parsed.protocol)) {
2446
+ throw new InvalidBaseURLError(
2447
+ `${name} must start with http://, https://, ws://, or wss://, got: ${url}`
2448
+ );
2449
+ }
2450
+ if (!parsed.hostname) {
2451
+ throw new InvalidBaseURLError(`${name} is missing a host: ${url}`);
2452
+ }
2453
+ if (parsed.search || parsed.hash) {
2454
+ throw new InvalidBaseURLError(
2455
+ `${name} should not contain a query or fragment: ${url}`
2456
+ );
2457
+ }
2458
+ return cleaned;
3249
2459
  }
3250
- function useInitiatePayment() {
3251
- return (0, import_react_query14.useMutation)({
3252
- mutationFn: (request) => paymentService.initiatePayment(request)
3253
- });
2460
+
2461
+ // src/utils/customer.ts
2462
+ function buildFullName2(firstname, lastname) {
2463
+ const name = [firstname, lastname].filter(Boolean).join(" ").trim();
2464
+ return name || void 0;
3254
2465
  }
3255
- function useVerifyTransaction() {
3256
- return (0, import_react_query14.useMutation)({
3257
- mutationFn: (reference) => paymentService.verifyTransaction(reference)
3258
- });
2466
+ function splitFullName2(fullName) {
2467
+ if (!fullName?.trim()) return { firstname: "", lastname: "" };
2468
+ const parts = fullName.trim().split(/\s+/);
2469
+ return {
2470
+ firstname: parts[0] ?? "",
2471
+ lastname: parts.slice(1).join(" ")
2472
+ };
3259
2473
  }
3260
- function useTransactionStatus(transactionId, enabled = false) {
3261
- return (0, import_react_query14.useQuery)({
3262
- queryKey: ["transaction", "status", transactionId],
3263
- queryFn: () => paymentService.getTransactionStatus(transactionId),
3264
- enabled: isInitialized() && enabled,
3265
- ...getCacheTier("none"),
3266
- refetchInterval: 3e3
3267
- // Poll every 3 seconds
3268
- });
2474
+ function getCustomerDisplayName(user) {
2475
+ const fromParts = buildFullName2(user.firstname, user.lastname);
2476
+ return fromParts || user.full_name || user.email.split("@")[0];
3269
2477
  }
3270
- function usePollTransactionStatus(reference, enabled = false) {
3271
- return (0, import_react_query14.useQuery)({
3272
- queryKey: ["transaction", "poll", reference],
3273
- queryFn: () => paymentService.verifyTransaction(reference),
3274
- enabled: isInitialized() && enabled,
3275
- ...getCacheTier("none"),
3276
- refetchInterval: 2e3,
3277
- // Poll every 2 seconds
3278
- retry: 10
3279
- // Retry up to 10 times
3280
- });
2478
+ function getStorefrontUrl(businessId, customDomain) {
2479
+ if (customDomain && customDomain.trim()) {
2480
+ const cleanDomain = customDomain.trim().replace(/^https?:\/\//, "");
2481
+ return `https://${cleanDomain}`;
2482
+ }
2483
+ const cleanBid = (businessId || "store").toLowerCase().trim();
2484
+ return `https://${cleanBid}.kasuvia.com`;
3281
2485
  }
3282
2486
 
3283
- // src/hooks/use-cms.ts
3284
- var import_react_query15 = require("@tanstack/react-query");
3285
- function useCmsEntries(modelSlug, params) {
3286
- const query = (0, import_react_query15.useQuery)({
3287
- queryKey: ["cms-entries", modelSlug, params],
3288
- queryFn: () => listCmsEntries(modelSlug, params),
3289
- enabled: isInitialized() && !!modelSlug
3290
- });
3291
- return {
3292
- entries: query.data?.entries || [],
3293
- total: query.data?.total || 0,
3294
- page: query.data?.page || 1,
3295
- page_size: query.data?.page_size || 50,
3296
- isLoading: query.isLoading,
3297
- error: query.error,
3298
- refetch: query.refetch
3299
- };
3300
- }
3301
- function useCmsEntry(modelSlug, entryId) {
3302
- const query = (0, import_react_query15.useQuery)({
3303
- queryKey: ["cms-entry", modelSlug, entryId],
3304
- queryFn: () => getCmsEntry(modelSlug, entryId),
3305
- enabled: isInitialized() && !!modelSlug && !!entryId
3306
- });
2487
+ // src/utils/checkout.ts
2488
+ function buildDeliveryAddress(customer, location) {
3307
2489
  return {
3308
- entry: query.data,
3309
- isLoading: query.isLoading,
3310
- error: query.error,
3311
- refetch: query.refetch
2490
+ first_name: customer.first_name,
2491
+ last_name: customer.last_name,
2492
+ phone: customer.phone,
2493
+ ...location
3312
2494
  };
3313
2495
  }
3314
- function useCreateCmsEntry(modelSlug) {
3315
- const queryClient = (0, import_react_query15.useQueryClient)();
3316
- const mutation = (0, import_react_query15.useMutation)({
3317
- mutationFn: (params) => createCmsEntry(modelSlug, params),
3318
- onSuccess: () => {
3319
- queryClient.invalidateQueries({ queryKey: ["cms-entries", modelSlug] });
3320
- }
3321
- });
3322
- return {
3323
- createEntry: mutation.mutate,
3324
- isLoading: mutation.isPending,
3325
- error: mutation.error
3326
- };
2496
+ function getCheckoutCustomerName(customer) {
2497
+ return buildFullName2(customer.first_name, customer.last_name) ?? customer.email.split("@")[0];
3327
2498
  }
3328
- function useUpdateCmsEntry(modelSlug) {
3329
- const queryClient = (0, import_react_query15.useQueryClient)();
3330
- const mutation = (0, import_react_query15.useMutation)({
3331
- mutationFn: ({ entryId, params }) => updateCmsEntry(modelSlug, entryId, params),
3332
- onSuccess: () => {
3333
- queryClient.invalidateQueries({ queryKey: ["cms-entries", modelSlug] });
3334
- queryClient.invalidateQueries({ queryKey: ["cms-entry", modelSlug] });
3335
- }
3336
- });
2499
+ function enrichCompletedOrder(order, options) {
2500
+ const customerName = getCheckoutCustomerName(options.customer);
3337
2501
  return {
3338
- updateEntry: (entryId, params) => mutation.mutate({ entryId, params }),
3339
- isLoading: mutation.isPending,
3340
- error: mutation.error
2502
+ ...order,
2503
+ customerName: order.customerName || customerName,
2504
+ customerEmail: order.customerEmail || options.customer.email,
2505
+ shippingAddress: order.shippingAddress ?? (options.productType === "physical" && options.location ? buildDeliveryAddress(options.customer, options.location) : void 0),
2506
+ bespokeBrief: order.bespokeBrief ?? options.bespokeBrief
3341
2507
  };
3342
2508
  }
3343
- function useDeleteCmsEntry(modelSlug) {
3344
- const queryClient = (0, import_react_query15.useQueryClient)();
3345
- const mutation = (0, import_react_query15.useMutation)({
3346
- mutationFn: (entryId) => deleteCmsEntry(modelSlug, entryId),
3347
- onSuccess: () => {
3348
- queryClient.invalidateQueries({ queryKey: ["cms-entries", modelSlug] });
3349
- queryClient.invalidateQueries({ queryKey: ["cms-entry", modelSlug] });
3350
- }
3351
- });
3352
- return {
3353
- deleteEntry: mutation.mutate,
3354
- isLoading: mutation.isPending,
3355
- error: mutation.error
3356
- };
2509
+
2510
+ // src/utils/error-handler.ts
2511
+ function getErrorMessage(error, fallback = "Something went wrong") {
2512
+ if (error instanceof Error) {
2513
+ return error.message;
2514
+ }
2515
+ if (error instanceof Response) {
2516
+ return `HTTP ${error.status}: ${error.statusText}`;
2517
+ }
2518
+ if (typeof error === "object" && error !== null) {
2519
+ const err = error;
2520
+ return err.detail || err.message || fallback;
2521
+ }
2522
+ return fallback;
3357
2523
  }
3358
2524
 
3359
2525
  // src/utils/storage.ts
3360
- function getPrefixedKey(key) {
3361
- const config = getRuntimeConfig();
3362
- const bid = config.businessId;
3363
- const cleanKey = key.startsWith("luxe_") ? key.substring(5) : key;
3364
- return bid ? `luxe-sf-${bid}-${cleanKey}` : `luxe-sf-anon-${cleanKey}`;
2526
+ function getPrefixedKey(businessId, key) {
2527
+ const cleanKey = key.startsWith("kasuvia_") ? key.substring(5) : key;
2528
+ return businessId ? `kasuvia-sf-${businessId}-${cleanKey}` : `kasuvia-sf-anon-${cleanKey}`;
3365
2529
  }
3366
2530
  var sessionStore = {
3367
- get: (key) => {
2531
+ get: (businessIdOrKey, key) => {
3368
2532
  if (typeof window === "undefined") return null;
3369
- return sessionStorage.getItem(getPrefixedKey(key));
2533
+ const bId = key ? businessIdOrKey : "";
2534
+ const k = key || businessIdOrKey;
2535
+ return sessionStorage.getItem(getPrefixedKey(bId, k));
3370
2536
  },
3371
- set: (key, value) => {
2537
+ set: (businessIdOrKey, keyOrVal, val) => {
3372
2538
  if (typeof window === "undefined") return;
3373
- sessionStorage.setItem(getPrefixedKey(key), value);
2539
+ const bId = val !== void 0 ? businessIdOrKey : "";
2540
+ const k = val !== void 0 ? keyOrVal : businessIdOrKey;
2541
+ const v = val !== void 0 ? val : keyOrVal;
2542
+ sessionStorage.setItem(getPrefixedKey(bId, k), v);
3374
2543
  },
3375
- remove: (key) => {
2544
+ remove: (businessIdOrKey, key) => {
3376
2545
  if (typeof window === "undefined") return;
3377
- sessionStorage.removeItem(getPrefixedKey(key));
2546
+ const bId = key ? businessIdOrKey : "";
2547
+ const k = key || businessIdOrKey;
2548
+ sessionStorage.removeItem(getPrefixedKey(bId, k));
3378
2549
  },
3379
- getJSON: (key) => {
2550
+ getJSON: (businessIdOrKey, key) => {
3380
2551
  if (typeof window === "undefined") return null;
3381
- const value = sessionStorage.getItem(getPrefixedKey(key));
2552
+ const bId = key ? businessIdOrKey : "";
2553
+ const k = key || businessIdOrKey;
2554
+ const value = sessionStorage.getItem(getPrefixedKey(bId, k));
3382
2555
  if (!value) return null;
3383
2556
  try {
3384
2557
  return JSON.parse(value);
@@ -3386,27 +2559,39 @@ var sessionStore = {
3386
2559
  return null;
3387
2560
  }
3388
2561
  },
3389
- setJSON: (key, value) => {
2562
+ setJSON: (businessIdOrKey, keyOrVal, val) => {
3390
2563
  if (typeof window === "undefined") return;
3391
- sessionStorage.setItem(getPrefixedKey(key), JSON.stringify(value));
2564
+ const bId = val !== void 0 ? businessIdOrKey : "";
2565
+ const k = val !== void 0 ? keyOrVal : businessIdOrKey;
2566
+ const v = val !== void 0 ? val : keyOrVal;
2567
+ sessionStorage.setItem(getPrefixedKey(bId, k), JSON.stringify(v));
3392
2568
  }
3393
2569
  };
3394
2570
  var localStore = {
3395
- get: (key) => {
2571
+ get: (businessIdOrKey, key) => {
3396
2572
  if (typeof window === "undefined") return null;
3397
- return localStorage.getItem(getPrefixedKey(key));
2573
+ const bId = key ? businessIdOrKey : "";
2574
+ const k = key || businessIdOrKey;
2575
+ return localStorage.getItem(getPrefixedKey(bId, k));
3398
2576
  },
3399
- set: (key, value) => {
2577
+ set: (businessIdOrKey, keyOrVal, val) => {
3400
2578
  if (typeof window === "undefined") return;
3401
- localStorage.setItem(getPrefixedKey(key), value);
2579
+ const bId = val !== void 0 ? businessIdOrKey : "";
2580
+ const k = val !== void 0 ? keyOrVal : businessIdOrKey;
2581
+ const v = val !== void 0 ? val : keyOrVal;
2582
+ localStorage.setItem(getPrefixedKey(bId, k), v);
3402
2583
  },
3403
- remove: (key) => {
2584
+ remove: (businessIdOrKey, key) => {
3404
2585
  if (typeof window === "undefined") return;
3405
- localStorage.removeItem(getPrefixedKey(key));
2586
+ const bId = key ? businessIdOrKey : "";
2587
+ const k = key || businessIdOrKey;
2588
+ localStorage.removeItem(getPrefixedKey(bId, k));
3406
2589
  },
3407
- getJSON: (key) => {
2590
+ getJSON: (businessIdOrKey, key) => {
3408
2591
  if (typeof window === "undefined") return null;
3409
- const value = localStorage.getItem(getPrefixedKey(key));
2592
+ const bId = key ? businessIdOrKey : "";
2593
+ const k = key || businessIdOrKey;
2594
+ const value = localStorage.getItem(getPrefixedKey(bId, k));
3410
2595
  if (!value) return null;
3411
2596
  try {
3412
2597
  return JSON.parse(value);
@@ -3414,24 +2599,98 @@ var localStore = {
3414
2599
  return null;
3415
2600
  }
3416
2601
  },
3417
- setJSON: (key, value) => {
2602
+ setJSON: (businessIdOrKey, keyOrVal, val) => {
3418
2603
  if (typeof window === "undefined") return;
3419
- localStorage.setItem(getPrefixedKey(key), JSON.stringify(value));
2604
+ const bId = val !== void 0 ? businessIdOrKey : "";
2605
+ const k = val !== void 0 ? keyOrVal : businessIdOrKey;
2606
+ const v = val !== void 0 ? val : keyOrVal;
2607
+ localStorage.setItem(getPrefixedKey(bId, k), JSON.stringify(v));
3420
2608
  }
3421
2609
  };
2610
+
2611
+ // src/utils/validators.ts
2612
+ function validateEmail(email) {
2613
+ if (!email || email.trim() === "") {
2614
+ return "Email is required";
2615
+ }
2616
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
2617
+ if (!emailRegex.test(email)) {
2618
+ return "Please enter a valid email address";
2619
+ }
2620
+ return null;
2621
+ }
2622
+ function validatePassword(password) {
2623
+ if (!password || password.trim() === "") {
2624
+ return "Password is required";
2625
+ }
2626
+ if (password.length < 8) {
2627
+ return "Password must be at least 8 characters";
2628
+ }
2629
+ if (password.length > 72) {
2630
+ return "Password cannot exceed 72 characters";
2631
+ }
2632
+ if (!/[A-Z]/.test(password)) {
2633
+ return "Password must contain at least one uppercase letter";
2634
+ }
2635
+ if (!/[a-z]/.test(password)) {
2636
+ return "Password must contain at least one lowercase letter";
2637
+ }
2638
+ if (!/[0-9]/.test(password)) {
2639
+ return "Password must contain at least one number";
2640
+ }
2641
+ return null;
2642
+ }
2643
+ function validateName(name, fieldName = "Name") {
2644
+ if (!name || name.trim() === "") {
2645
+ return `${fieldName} is required`;
2646
+ }
2647
+ if (name.trim().length < 2) {
2648
+ return `${fieldName} must be at least 2 characters`;
2649
+ }
2650
+ if (name.trim().length > 50) {
2651
+ return `${fieldName} cannot exceed 50 characters`;
2652
+ }
2653
+ const nameRegex = /^[a-zA-Z\s\-'\u00C0-\u017F]+$/;
2654
+ if (!nameRegex.test(name.trim())) {
2655
+ return `${fieldName} can only contain letters, spaces, hyphens, and apostrophes`;
2656
+ }
2657
+ return null;
2658
+ }
2659
+ function validateRequired(value, fieldName) {
2660
+ if (!value || value.trim() === "") {
2661
+ return `${fieldName} is required`;
2662
+ }
2663
+ return null;
2664
+ }
2665
+ function validateConfirmPassword(password, confirmPassword) {
2666
+ if (!confirmPassword) return null;
2667
+ if (confirmPassword !== password) {
2668
+ return "Passwords do not match";
2669
+ }
2670
+ return null;
2671
+ }
2672
+ function validateMessage(message) {
2673
+ if (!message || message.trim() === "") {
2674
+ return "Message is required";
2675
+ }
2676
+ if (message.trim().length < 10) {
2677
+ return "Message must be at least 10 characters";
2678
+ }
2679
+ return null;
2680
+ }
3422
2681
  // Annotate the CommonJS export names for ESM import in node:
3423
2682
  0 && (module.exports = {
3424
- AuthCtx,
3425
- AuthProvider,
3426
- CartCtx,
3427
- CartProvider,
3428
2683
  InvalidBaseURLError,
2684
+ STORAGE_KEYS,
2685
+ SdkProvider,
2686
+ ServiceLocationTypeEnum,
2687
+ ServiceRecurringIntervalEnum,
2688
+ ServiceTypeEnum,
3429
2689
  acceptQuote,
3430
2690
  addToCart,
3431
2691
  addToGuestCart,
3432
2692
  addToWishlist,
3433
2693
  approveDeliverable,
3434
- authAxios,
3435
2694
  bespokeService,
3436
2695
  bookAppointment,
3437
2696
  buildDeliveryAddress,
@@ -3442,11 +2701,8 @@ var localStore = {
3442
2701
  checkInWishlist,
3443
2702
  clearCart,
3444
2703
  clearGuestCart,
3445
- clearGuestSessionId,
3446
- cmsAxios,
3447
- collectionKeys,
2704
+ clearTokens,
3448
2705
  configService,
3449
- configureHttpClients,
3450
2706
  consultationService,
3451
2707
  createCmsEntry,
3452
2708
  createConsultation,
@@ -3460,7 +2716,6 @@ var localStore = {
3460
2716
  getAppointments,
3461
2717
  getAuthUser,
3462
2718
  getAvailableSlots,
3463
- getBackendUrl,
3464
2719
  getBusinessConfig,
3465
2720
  getCacheTier,
3466
2721
  getCart,
@@ -3468,43 +2723,36 @@ var localStore = {
3468
2723
  getCmsEntry,
3469
2724
  getConsultation,
3470
2725
  getConsultations,
3471
- getCountries,
3472
2726
  getCustomerDisplayName,
3473
2727
  getDeliverables,
3474
2728
  getErrorMessage,
3475
2729
  getFeaturedProducts,
3476
- getGraphQLClient,
3477
2730
  getGuestCart,
3478
2731
  getGuestCartCount,
3479
2732
  getGuestCartProductType,
3480
2733
  getGuestCartSubtotal,
3481
- getGuestSessionId,
3482
2734
  getLatestProducts,
2735
+ getLowStockProducts,
3483
2736
  getMe,
3484
2737
  getNewProducts,
3485
- getOrCreateGuestSessionId,
2738
+ getOnSaleProducts,
3486
2739
  getOrders,
3487
2740
  getPopularProducts,
3488
2741
  getRecommendedProducts,
3489
- getRuntimeConfig,
3490
2742
  getSellerShippingAddress,
3491
2743
  getShippingRates,
3492
- getStates,
2744
+ getStoredTokens,
3493
2745
  getStorefrontCollectionBySlug,
3494
2746
  getStorefrontCollections,
3495
2747
  getStorefrontProductBySlug,
3496
2748
  getStorefrontProducts,
3497
2749
  getStorefrontUrl,
3498
2750
  getSupportedCurrencies,
3499
- getSupportedCurrenciesList,
3500
2751
  getSupportedLanguages,
3501
- getSupportedLanguagesList,
3502
2752
  getTransactionStatus,
3503
2753
  getWishlist,
3504
2754
  googleTranslate,
3505
- initSdk,
3506
2755
  initiatePayment,
3507
- isInitialized,
3508
2756
  listCmsEntries,
3509
2757
  localStore,
3510
2758
  logger,
@@ -3515,10 +2763,7 @@ var localStore = {
3515
2763
  mergeGuestCart,
3516
2764
  mergeGuestCartIfPresent,
3517
2765
  notificationsService,
3518
- paymentAxios,
3519
2766
  paymentService,
3520
- productKeys,
3521
- publicStoreAxios,
3522
2767
  refreshToken,
3523
2768
  registerCustomer,
3524
2769
  rejectQuote,
@@ -3528,8 +2773,6 @@ var localStore = {
3528
2773
  removeProductFromWishlist,
3529
2774
  requestQuote,
3530
2775
  requestRevision,
3531
- resetConfig,
3532
- resetGraphQLClient,
3533
2776
  sanitizeBaseUrl,
3534
2777
  sendContactConfirmation,
3535
2778
  sendContactEmail,
@@ -3540,79 +2783,21 @@ var localStore = {
3540
2783
  setLoggerEnvironmentMode,
3541
2784
  silentRefresh,
3542
2785
  splitFullName,
3543
- storeManagementAxios,
3544
2786
  storeTokens,
3545
- tokenStore,
3546
2787
  trackOrder,
3547
2788
  updateCartItem,
3548
2789
  updateCmsEntry,
3549
2790
  updateGuestCartItemQuantity,
3550
2791
  updateProfile,
3551
- useAcceptQuote,
3552
- useAddToWishlist,
3553
- useAppointment,
3554
- useAppointments,
3555
- useApproveDeliverable,
3556
- useAuth,
3557
- useAuthUser,
3558
- useAvailableSlots,
3559
- useBespokeAvailability,
3560
- useBookAppointment,
3561
- useCancelAppointment,
3562
- useCancelOrder,
3563
- useCart,
3564
- useCheckInWishlist,
3565
- useCmsEntries,
3566
- useCmsEntry,
3567
- useConsultation,
3568
- useConsultationStream,
3569
- useConsultations,
3570
- useCountries,
3571
- useCreateCmsEntry,
3572
- useCreateConsultation,
3573
- useCreateDVA,
3574
- useCreateOrder,
3575
- useCurrencies,
3576
- useDeleteCmsEntry,
3577
- useDeliverables,
3578
- useFeaturedProducts,
3579
- useFindOrder,
3580
- useGoogleTranslate,
3581
- useInitiatePayment,
3582
- useIsMounted,
3583
- useLatestProducts,
3584
- useLogin,
3585
- useLogout,
3586
- useNewProducts,
3587
- useOrder,
3588
- useOrderStream,
3589
- useOrderTracking,
3590
- useOrders,
3591
- useOrdersList,
3592
- usePollTransactionStatus,
3593
- usePopularProducts,
3594
- useProduct,
3595
- useRecommendedProducts,
3596
- useRegister,
3597
- useRejectQuote,
3598
- useRemoveFromWishlist,
3599
- useRemoveProductFromWishlist,
3600
- useRequestRevision,
3601
- useSendMessage,
3602
- useStates,
3603
- useStorefrontCollection,
3604
- useStorefrontCollections,
3605
- useStorefrontProducts,
3606
- useSupportedLanguages,
3607
- useTransactionStatus,
3608
- useUpdateCmsEntry,
3609
- useUpdateProfile,
3610
- useVerifyTransaction,
3611
- useWishlist,
3612
- useWishlistCount,
2792
+ useSdkContext,
2793
+ validateConfirmPassword,
2794
+ validateEmail,
2795
+ validateMessage,
2796
+ validateName,
2797
+ validatePassword,
2798
+ validateRequired,
3613
2799
  validateShippingAddress,
3614
2800
  verifySocialToken,
3615
- verifyTransaction,
3616
- wishlistKeys
2801
+ verifyTransaction
3617
2802
  });
3618
2803
  //# sourceMappingURL=index.js.map