@kasuvia/sdk 0.0.2 → 0.0.4

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 (67) hide show
  1. package/dist/hooks/index.d.mts +429 -0
  2. package/dist/hooks/index.d.ts +429 -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.d.mts +250 -1161
  8. package/dist/index.d.ts +250 -1161
  9. package/dist/index.js +1544 -2359
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.mjs +1527 -2258
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/sdk-context-Cy51kEKT.d.mts +565 -0
  14. package/dist/sdk-context-Cy51kEKT.d.ts +565 -0
  15. package/package.json +6 -2
  16. package/src/config/index.ts +10 -91
  17. package/src/constants.ts +13 -0
  18. package/src/context/sdk-context.tsx +70 -0
  19. package/src/graphql/collections.graphql.ts +2 -10
  20. package/src/graphql/products.graphql.ts +215 -65
  21. package/src/graphql/wishlist.graphql.ts +7 -6
  22. package/src/hooks/index.ts +2 -0
  23. package/src/hooks/use-auth.ts +82 -158
  24. package/src/hooks/use-bespoke-availability.ts +25 -8
  25. package/src/hooks/use-cart.ts +222 -119
  26. package/src/hooks/use-cms.ts +179 -86
  27. package/src/hooks/use-collections.ts +52 -15
  28. package/src/hooks/use-consultation-stream.ts +4 -3
  29. package/src/hooks/use-consultations.ts +120 -51
  30. package/src/hooks/use-countries.ts +35 -13
  31. package/src/hooks/use-currencies.ts +26 -13
  32. package/src/hooks/use-google-translate.ts +22 -8
  33. package/src/hooks/use-languages.ts +40 -20
  34. package/src/hooks/use-mobile.ts +23 -0
  35. package/src/hooks/use-order-stream.ts +9 -5
  36. package/src/hooks/use-orders.ts +99 -44
  37. package/src/hooks/use-payment.ts +108 -40
  38. package/src/hooks/use-products.ts +251 -53
  39. package/src/hooks/use-service-booking.ts +152 -90
  40. package/src/hooks/use-states.ts +35 -15
  41. package/src/hooks/use-wishlist.ts +92 -91
  42. package/src/index.ts +26 -30
  43. package/src/services/auth.service.ts +209 -167
  44. package/src/services/bespoke.service.ts +12 -4
  45. package/src/services/cart.service.ts +172 -70
  46. package/src/services/cms.service.ts +70 -35
  47. package/src/services/collection.service.ts +22 -5
  48. package/src/services/config.service.ts +34 -14
  49. package/src/services/consultation.service.ts +72 -18
  50. package/src/services/logistics.service.ts +35 -11
  51. package/src/services/notifications.service.ts +27 -12
  52. package/src/services/order.service.ts +74 -15
  53. package/src/services/payment.service.ts +86 -31
  54. package/src/services/product.service.ts +279 -39
  55. package/src/services/service-booking.service.ts +98 -26
  56. package/src/services/wishlist.service.ts +69 -25
  57. package/src/types/auth/index.ts +6 -4
  58. package/src/types/business/index.ts +7 -2
  59. package/src/types/payments/index.ts +3 -3
  60. package/src/types/services/index.ts +2 -5
  61. package/src/types/store/index.ts +38 -3
  62. package/src/utils/error-handler.ts +10 -5
  63. package/src/utils/storage.ts +48 -26
  64. package/src/utils/validators.ts +85 -0
  65. package/src/client/authClient.ts +0 -135
  66. package/src/client/graphqlClient.ts +0 -53
  67. package/src/client/httpClient.ts +0 -298
@@ -2,13 +2,11 @@
2
2
  * Cart Service
3
3
  *
4
4
  * Handles cart operations for both guest and authenticated users.
5
+ * Stateless - all configuration passed as parameters.
5
6
  */
6
- import { storeManagementAxios, getOrCreateGuestSessionId, getGuestSessionId, clearGuestSessionId } from '../client/httpClient'
7
+ import type { SdkConfig } from '../config'
7
8
  import type { CartItem, CartResponse } from '../types/store'
8
9
 
9
- const GUEST_SESSION_COOKIE = "luxe_guest_sid"
10
- const GUEST_CART_TTL_DAYS = 7
11
-
12
10
  function parseItems(items: CartItem[]): CartItem[] {
13
11
  return items.map((item) => ({
14
12
  ...item,
@@ -22,14 +20,19 @@ function parseItems(items: CartItem[]): CartItem[] {
22
20
  /**
23
21
  * Fetch guest cart from backend (Redis-backed).
24
22
  */
25
- export async function getGuestCart(): Promise<CartItem[]> {
26
- const sid = getGuestSessionId()
27
- if (!sid) return []
23
+ export async function getGuestCart(config: SdkConfig, guestSessionId: string): Promise<CartItem[]> {
24
+ if (!guestSessionId) return []
28
25
 
29
26
  try {
30
- const { data } = await storeManagementAxios.get<CartResponse>("cart/", {
31
- headers: { "X-Guest-Session": sid },
27
+ const response = await fetch(`${config.backendUrls.store}/cart/`, {
28
+ headers: {
29
+ "X-Storefront-Key": config.storefrontApiKey,
30
+ "X-Business-ID": config.businessId,
31
+ "X-Guest-Session": guestSessionId
32
+ },
32
33
  })
34
+ if (!response.ok) return []
35
+ const data = await response.json()
33
36
  return parseItems(data.items || [])
34
37
  } catch {
35
38
  return []
@@ -39,9 +42,8 @@ export async function getGuestCart(): Promise<CartItem[]> {
39
42
  /**
40
43
  * Add item to guest cart (Redis-backed).
41
44
  */
42
- export async function addToGuestCart(item: CartItem): Promise<CartItem[]> {
43
- const sid = getOrCreateGuestSessionId()
44
- if (!sid) return []
45
+ export async function addToGuestCart(config: SdkConfig, guestSessionId: string, item: CartItem): Promise<CartItem[]> {
46
+ if (!guestSessionId) return []
45
47
 
46
48
  const payload = {
47
49
  product_id: item.product_id,
@@ -59,9 +61,18 @@ export async function addToGuestCart(item: CartItem): Promise<CartItem[]> {
59
61
  is_bespoke: item.is_bespoke,
60
62
  }
61
63
 
62
- const { data } = await storeManagementAxios.post<CartResponse>("cart/", payload, {
63
- headers: { "X-Guest-Session": sid },
64
+ const response = await fetch(`${config.backendUrls.store}/cart/`, {
65
+ method: 'POST',
66
+ headers: {
67
+ 'Content-Type': 'application/json',
68
+ "X-Storefront-Key": config.storefrontApiKey,
69
+ "X-Business-ID": config.businessId,
70
+ "X-Guest-Session": guestSessionId
71
+ },
72
+ body: JSON.stringify(payload),
64
73
  })
74
+ if (!response.ok) return []
75
+ const data = await response.json()
65
76
  return parseItems(data.items || [])
66
77
  }
67
78
 
@@ -69,51 +80,82 @@ export async function addToGuestCart(item: CartItem): Promise<CartItem[]> {
69
80
  * Update quantity of a guest cart item.
70
81
  */
71
82
  export async function updateGuestCartItemQuantity(
83
+ config: SdkConfig,
84
+ guestSessionId: string,
72
85
  itemId: string,
73
86
  quantity: number
74
87
  ): Promise<CartItem[]> {
75
- const sid = getGuestSessionId()
76
- if (!sid) return []
77
-
78
- const { data } = await storeManagementAxios.patch<CartResponse>(
79
- `cart/${itemId}`,
80
- { quantity },
81
- { headers: { "X-Guest-Session": sid } }
82
- )
88
+ if (!guestSessionId) return []
89
+
90
+ const response = await fetch(`${config.backendUrls.store}/cart/${itemId}`, {
91
+ method: 'PATCH',
92
+ headers: {
93
+ 'Content-Type': 'application/json',
94
+ "X-Storefront-Key": config.storefrontApiKey,
95
+ "X-Business-ID": config.businessId,
96
+ "X-Guest-Session": guestSessionId
97
+ },
98
+ body: JSON.stringify({ quantity }),
99
+ })
100
+ if (!response.ok) return []
101
+ const data = await response.json()
83
102
  return parseItems(data.items || [])
84
103
  }
85
104
 
86
105
  /**
87
106
  * Remove an item from the guest cart.
88
107
  */
89
- export async function removeFromGuestCart(itemId: string): Promise<CartItem[]> {
90
- const sid = getGuestSessionId()
91
- if (!sid) return []
108
+ export async function removeFromGuestCart(
109
+ config: SdkConfig,
110
+ guestSessionId: string,
111
+ itemId: string
112
+ ): Promise<CartItem[]> {
113
+ if (!guestSessionId) return []
92
114
 
93
- await storeManagementAxios.delete(`cart/${itemId}`, {
94
- headers: { "X-Guest-Session": sid },
115
+ await fetch(`${config.backendUrls.store}/cart/${itemId}`, {
116
+ method: 'DELETE',
117
+ headers: {
118
+ "X-Storefront-Key": config.storefrontApiKey,
119
+ "X-Business-ID": config.businessId,
120
+ "X-Guest-Session": guestSessionId
121
+ },
95
122
  })
96
123
 
97
- return getGuestCart()
124
+ return getGuestCart(config, guestSessionId)
98
125
  }
99
126
 
100
127
  /**
101
128
  * Clear the entire guest cart.
102
129
  */
103
- export async function clearGuestCart(): Promise<void> {
104
- const sid = getGuestSessionId()
105
- if (!sid) return
130
+ export async function clearGuestCart(config: SdkConfig, guestSessionId: string): Promise<void> {
131
+ if (!guestSessionId) return
106
132
 
107
- await storeManagementAxios.delete("cart/clear", {
108
- headers: { "X-Guest-Session": sid },
133
+ await fetch(`${config.backendUrls.store}/cart/clear`, {
134
+ method: 'DELETE',
135
+ headers: {
136
+ "X-Storefront-Key": config.storefrontApiKey,
137
+ "X-Business-ID": config.businessId,
138
+ "X-Guest-Session": guestSessionId
139
+ },
109
140
  })
110
141
  }
111
142
 
112
143
  /**
113
144
  * Fetch authenticated user's cart from backend.
114
145
  */
115
- export async function getCart(): Promise<CartResponse> {
116
- const { data } = await storeManagementAxios.get<CartResponse>("cart/")
146
+ export async function getCart(config: SdkConfig, accessToken?: string | null): Promise<CartResponse> {
147
+ if (!accessToken) {
148
+ return { id: '', items: [], subtotal: 0, total: 0, product_type: 'physical' } as any;
149
+ }
150
+ const response = await fetch(`${config.backendUrls.store}/cart/`, {
151
+ headers: {
152
+ "Authorization": `Bearer ${accessToken}`,
153
+ "X-Storefront-Key": config.storefrontApiKey,
154
+ "X-Business-ID": config.businessId,
155
+ },
156
+ })
157
+ if (!response.ok) throw new Error('Failed to fetch cart')
158
+ const data = await response.json()
117
159
  const parsedItems = parseItems(data.items || [])
118
160
  return { ...data, items: parsedItems }
119
161
  }
@@ -121,19 +163,34 @@ export async function getCart(): Promise<CartResponse> {
121
163
  /**
122
164
  * Add item to authenticated user's cart.
123
165
  */
124
- export async function addToCart(item: {
125
- product_id: string
126
- product_slug: string
127
- product_name: string
128
- image?: string
129
- variant_id?: string
130
- variant_attributes?: string
131
- unit_price: number
132
- quantity: number
133
- custom_measurements?: string
134
- is_bespoke: boolean
135
- }): Promise<CartResponse> {
136
- const { data } = await storeManagementAxios.post<CartResponse>("cart/", item)
166
+ export async function addToCart(
167
+ config: SdkConfig,
168
+ accessToken: string,
169
+ item: {
170
+ product_id: string
171
+ product_slug: string
172
+ product_name: string
173
+ image?: string
174
+ variant_id?: string
175
+ variant_attributes?: string
176
+ unit_price: number
177
+ quantity: number
178
+ custom_measurements?: string
179
+ is_bespoke: boolean
180
+ }
181
+ ): Promise<CartResponse> {
182
+ const response = await fetch(`${config.backendUrls.store}/cart/`, {
183
+ method: 'POST',
184
+ headers: {
185
+ 'Content-Type': 'application/json',
186
+ "Authorization": `Bearer ${accessToken}`,
187
+ "X-Storefront-Key": config.storefrontApiKey,
188
+ "X-Business-ID": config.businessId,
189
+ },
190
+ body: JSON.stringify(item),
191
+ })
192
+ if (!response.ok) throw new Error('Failed to add to cart')
193
+ const data = await response.json()
137
194
  const parsedItems = parseItems(data.items || [])
138
195
  return { ...data, items: parsedItems }
139
196
  }
@@ -142,13 +199,23 @@ export async function addToCart(item: {
142
199
  * Update item quantity in authenticated user's cart.
143
200
  */
144
201
  export async function updateCartItem(
202
+ config: SdkConfig,
203
+ accessToken: string,
145
204
  itemId: string,
146
205
  quantity: number
147
206
  ): Promise<CartResponse> {
148
- const { data } = await storeManagementAxios.patch<CartResponse>(
149
- `cart/${itemId}`,
150
- { quantity }
151
- )
207
+ const response = await fetch(`${config.backendUrls.store}/cart/${itemId}`, {
208
+ method: 'PATCH',
209
+ headers: {
210
+ 'Content-Type': 'application/json',
211
+ "Authorization": `Bearer ${accessToken}`,
212
+ "X-Storefront-Key": config.storefrontApiKey,
213
+ "X-Business-ID": config.businessId,
214
+ },
215
+ body: JSON.stringify({ quantity }),
216
+ })
217
+ if (!response.ok) throw new Error('Failed to update cart item')
218
+ const data = await response.json()
152
219
  const parsedItems = parseItems(data.items || [])
153
220
  return { ...data, items: parsedItems }
154
221
  }
@@ -156,27 +223,48 @@ export async function updateCartItem(
156
223
  /**
157
224
  * Remove item from authenticated user's cart.
158
225
  */
159
- export async function removeFromCart(itemId: string): Promise<CartResponse> {
160
- await storeManagementAxios.delete(`cart/${itemId}`)
161
- return getCart()
226
+ export async function removeFromCart(
227
+ config: SdkConfig,
228
+ accessToken: string,
229
+ itemId: string
230
+ ): Promise<CartResponse> {
231
+ await fetch(`${config.backendUrls.store}/cart/${itemId}`, {
232
+ method: 'DELETE',
233
+ headers: {
234
+ "Authorization": `Bearer ${accessToken}`,
235
+ "X-Storefront-Key": config.storefrontApiKey,
236
+ "X-Business-ID": config.businessId,
237
+ },
238
+ })
239
+ return getCart(config, accessToken)
162
240
  }
163
241
 
164
242
  /**
165
243
  * Clear authenticated user's cart.
166
244
  */
167
- export async function clearCart(): Promise<void> {
168
- await storeManagementAxios.delete("cart/clear")
245
+ export async function clearCart(config: SdkConfig, accessToken: string): Promise<void> {
246
+ await fetch(`${config.backendUrls.store}/cart/clear`, {
247
+ method: 'DELETE',
248
+ headers: {
249
+ "Authorization": `Bearer ${accessToken}`,
250
+ "X-Storefront-Key": config.storefrontApiKey,
251
+ "X-Business-ID": config.businessId,
252
+ },
253
+ })
169
254
  }
170
255
 
171
256
  /**
172
257
  * Merge guest cart (from Redis) into authenticated user's DB cart.
173
258
  */
174
- export async function mergeGuestCart(): Promise<CartResponse> {
175
- const sid = getGuestSessionId()
176
- const guestItems = sid ? await getGuestCart() : []
259
+ export async function mergeGuestCart(
260
+ config: SdkConfig,
261
+ accessToken: string,
262
+ guestSessionId: string
263
+ ): Promise<CartResponse> {
264
+ const guestItems = guestSessionId ? await getGuestCart(config, guestSessionId) : []
177
265
 
178
266
  if (guestItems.length === 0) {
179
- return getCart()
267
+ return getCart(config, accessToken)
180
268
  }
181
269
 
182
270
  const payloadItems = guestItems.map((item) => ({
@@ -198,24 +286,38 @@ export async function mergeGuestCart(): Promise<CartResponse> {
198
286
  is_bespoke: item.is_bespoke,
199
287
  }))
200
288
 
201
- const { data } = await storeManagementAxios.post<CartResponse>(
202
- "cart/merge",
203
- { items: payloadItems },
204
- sid ? { headers: { "X-Guest-Session": sid } } : {}
205
- )
289
+ const headers: Record<string, string> = {
290
+ 'Content-Type': 'application/json',
291
+ "Authorization": `Bearer ${accessToken}`,
292
+ "X-Storefront-Key": config.storefrontApiKey,
293
+ "X-Business-ID": config.businessId,
294
+ }
295
+ if (guestSessionId) {
296
+ headers["X-Guest-Session"] = guestSessionId
297
+ }
206
298
 
207
- clearGuestSessionId()
299
+ const response = await fetch(`${config.backendUrls.store}/cart/merge`, {
300
+ method: 'POST',
301
+ headers,
302
+ body: JSON.stringify({ items: payloadItems }),
303
+ })
304
+ if (!response.ok) throw new Error('Failed to merge guest cart')
305
+ const data = await response.json()
208
306
  return { ...data, items: parseItems(data.items || []) }
209
307
  }
210
308
 
211
309
  /**
212
310
  * Convenience wrapper: merge guest cart if it has items (called post-login).
213
311
  */
214
- export async function mergeGuestCartIfPresent(): Promise<void> {
312
+ export async function mergeGuestCartIfPresent(
313
+ config: SdkConfig,
314
+ accessToken: string,
315
+ guestSessionId: string
316
+ ): Promise<void> {
215
317
  try {
216
- const guestItems = await getGuestCart()
318
+ const guestItems = await getGuestCart(config, guestSessionId)
217
319
  if (guestItems.length === 0) return
218
- await mergeGuestCart()
320
+ await mergeGuestCart(config, accessToken, guestSessionId)
219
321
  } catch (error) {
220
322
  console.warn("[Cart] Failed to merge guest cart:", error)
221
323
  }
@@ -3,9 +3,9 @@
3
3
  *
4
4
  * Handles CMS model and entry operations using the kasuvia-cms SDK endpoints.
5
5
  * Protected by X-Storefront-Key and X-Business-ID headers.
6
+ * Stateless - all configuration passed as parameters.
6
7
  */
7
- import { cmsAxios } from '../client/httpClient'
8
- import { getRuntimeConfig } from '../config'
8
+ import type { SdkConfig } from '../config'
9
9
  import type {
10
10
  CmsEntry,
11
11
  CmsEntryListResponse,
@@ -19,23 +19,26 @@ import type {
19
19
  * Requires public_api.read permission on the model.
20
20
  */
21
21
  export async function listCmsEntries(
22
+ config: SdkConfig,
22
23
  modelSlug: string,
23
24
  params?: ListCmsEntriesParams
24
25
  ): Promise<CmsEntryListResponse> {
25
- const config = getRuntimeConfig()
26
- const { businessId } = config
26
+ const queryParams = new URLSearchParams()
27
+ queryParams.set('page', (params?.page || 1).toString())
28
+ queryParams.set('page_size', (params?.page_size || 50).toString())
27
29
 
28
- const response = await cmsAxios.get<CmsEntryListResponse>(
29
- `/sdk/${businessId}/${modelSlug}/entries`,
30
+ const response = await fetch(
31
+ `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries?${queryParams.toString()}`,
30
32
  {
31
- params: {
32
- page: params?.page || 1,
33
- page_size: params?.page_size || 50,
33
+ headers: {
34
+ "X-Storefront-Key": config.storefrontApiKey,
35
+ "X-Business-ID": config.businessId,
34
36
  },
35
37
  }
36
38
  )
37
39
 
38
- return response.data
40
+ if (!response.ok) throw new Error('Failed to list CMS entries')
41
+ return response.json()
39
42
  }
40
43
 
41
44
  /**
@@ -43,17 +46,22 @@ export async function listCmsEntries(
43
46
  * Requires public_api.read permission on the model.
44
47
  */
45
48
  export async function getCmsEntry(
49
+ config: SdkConfig,
46
50
  modelSlug: string,
47
51
  entryId: string
48
52
  ): Promise<CmsEntry> {
49
- const config = getRuntimeConfig()
50
- const { businessId } = config
51
-
52
- const response = await cmsAxios.get<CmsEntry>(
53
- `/sdk/${businessId}/${modelSlug}/entries/${entryId}`
53
+ const response = await fetch(
54
+ `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries/${entryId}`,
55
+ {
56
+ headers: {
57
+ "X-Storefront-Key": config.storefrontApiKey,
58
+ "X-Business-ID": config.businessId,
59
+ },
60
+ }
54
61
  )
55
62
 
56
- return response.data
63
+ if (!response.ok) throw new Error('Failed to get CMS entry')
64
+ return response.json()
57
65
  }
58
66
 
59
67
  /**
@@ -61,18 +69,27 @@ export async function getCmsEntry(
61
69
  * Requires public_api.create permission on the model.
62
70
  */
63
71
  export async function createCmsEntry(
72
+ config: SdkConfig,
73
+ accessToken: string,
64
74
  modelSlug: string,
65
75
  params: CreateCmsEntryParams
66
76
  ): Promise<CmsEntry> {
67
- const config = getRuntimeConfig()
68
- const { businessId } = config
69
-
70
- const response = await cmsAxios.post<CmsEntry>(
71
- `/sdk/${businessId}/${modelSlug}/entries`,
72
- params
77
+ const response = await fetch(
78
+ `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries`,
79
+ {
80
+ method: 'POST',
81
+ headers: {
82
+ 'Content-Type': 'application/json',
83
+ "Authorization": `Bearer ${accessToken}`,
84
+ "X-Storefront-Key": config.storefrontApiKey,
85
+ "X-Business-ID": config.businessId,
86
+ },
87
+ body: JSON.stringify(params),
88
+ }
73
89
  )
74
90
 
75
- return response.data
91
+ if (!response.ok) throw new Error('Failed to create CMS entry')
92
+ return response.json()
76
93
  }
77
94
 
78
95
  /**
@@ -80,19 +97,28 @@ export async function createCmsEntry(
80
97
  * Requires public_api.update permission on the model.
81
98
  */
82
99
  export async function updateCmsEntry(
100
+ config: SdkConfig,
101
+ accessToken: string,
83
102
  modelSlug: string,
84
103
  entryId: string,
85
104
  params: UpdateCmsEntryParams
86
105
  ): Promise<CmsEntry> {
87
- const config = getRuntimeConfig()
88
- const { businessId } = config
89
-
90
- const response = await cmsAxios.put<CmsEntry>(
91
- `/sdk/${businessId}/${modelSlug}/entries/${entryId}`,
92
- params
106
+ const response = await fetch(
107
+ `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries/${entryId}`,
108
+ {
109
+ method: 'PUT',
110
+ headers: {
111
+ 'Content-Type': 'application/json',
112
+ "Authorization": `Bearer ${accessToken}`,
113
+ "X-Storefront-Key": config.storefrontApiKey,
114
+ "X-Business-ID": config.businessId,
115
+ },
116
+ body: JSON.stringify(params),
117
+ }
93
118
  )
94
119
 
95
- return response.data
120
+ if (!response.ok) throw new Error('Failed to update CMS entry')
121
+ return response.json()
96
122
  }
97
123
 
98
124
  /**
@@ -100,13 +126,22 @@ export async function updateCmsEntry(
100
126
  * Requires public_api.delete permission on the model.
101
127
  */
102
128
  export async function deleteCmsEntry(
129
+ config: SdkConfig,
130
+ accessToken: string,
103
131
  modelSlug: string,
104
132
  entryId: string
105
133
  ): Promise<void> {
106
- const config = getRuntimeConfig()
107
- const { businessId } = config
108
-
109
- await cmsAxios.delete(
110
- `/sdk/${businessId}/${modelSlug}/entries/${entryId}`
134
+ const response = await fetch(
135
+ `${config.backendUrls.cms}/sdk/${config.businessId}/${modelSlug}/entries/${entryId}`,
136
+ {
137
+ method: 'DELETE',
138
+ headers: {
139
+ "Authorization": `Bearer ${accessToken}`,
140
+ "X-Storefront-Key": config.storefrontApiKey,
141
+ "X-Business-ID": config.businessId,
142
+ },
143
+ }
111
144
  )
145
+
146
+ if (!response.ok) throw new Error('Failed to delete CMS entry')
112
147
  }
@@ -2,9 +2,11 @@
2
2
  * Collection Service
3
3
  *
4
4
  * Handles collection operations using GraphQL.
5
+ * Stateless - all configuration passed as parameters.
5
6
  */
6
- import { getGraphQLClient } from '../client/graphqlClient'
7
+ import { GraphQLClient } from 'graphql-request'
7
8
  import type { Collection, PaginatedResponse, ListParams } from '../types/store'
9
+ import type { SdkConfig } from '../config'
8
10
 
9
11
  const GET_STOREFRONT_COLLECTIONS = `
10
12
  query GetStorefrontCollections($page: Int!, $pageSize: Int!) {
@@ -15,7 +17,7 @@ const GET_STOREFRONT_COLLECTIONS = `
15
17
  name
16
18
  slug
17
19
  description
18
- image { url alt id }
20
+ image
19
21
  collection_type
20
22
  rules
21
23
  status
@@ -39,7 +41,7 @@ const GET_STOREFRONT_COLLECTION_BY_SLUG = `
39
41
  name
40
42
  slug
41
43
  description
42
- image { url alt id }
44
+ image
43
45
  collection_type
44
46
  rules
45
47
  status
@@ -50,13 +52,27 @@ const GET_STOREFRONT_COLLECTION_BY_SLUG = `
50
52
  }
51
53
  `
52
54
 
55
+ /**
56
+ * Create GraphQL client with provided config
57
+ */
58
+ function createGraphQLClient(config: SdkConfig): GraphQLClient {
59
+ const headers: Record<string, string> = {
60
+ 'Content-Type': 'application/json',
61
+ 'Accept': 'application/json',
62
+ 'X-Storefront-Key': config.storefrontApiKey,
63
+ 'X-Business-ID': config.businessId,
64
+ }
65
+ return new GraphQLClient(`${config.backendUrls.store}/graphql`, { headers })
66
+ }
67
+
53
68
  /**
54
69
  * Fetch paginated active collections for the storefront.
55
70
  */
56
71
  export async function getStorefrontCollections(
72
+ config: SdkConfig,
57
73
  params?: ListParams
58
74
  ): Promise<PaginatedResponse<Collection>> {
59
- const client = getGraphQLClient()
75
+ const client = createGraphQLClient(config)
60
76
  const variables = {
61
77
  page: params?.page || 1,
62
78
  pageSize: params?.pageSize || 20,
@@ -69,9 +85,10 @@ export async function getStorefrontCollections(
69
85
  * Fetch a single collection by its slug.
70
86
  */
71
87
  export async function getStorefrontCollectionBySlug(
88
+ config: SdkConfig,
72
89
  slug: string
73
90
  ): Promise<Collection> {
74
- const client = getGraphQLClient()
91
+ const client = createGraphQLClient(config)
75
92
  const data = await client.request(GET_STOREFRONT_COLLECTION_BY_SLUG, { slug })
76
93
  return data.storefront_collection_by_slug
77
94
  }
@@ -2,37 +2,57 @@
2
2
  * Config Service
3
3
  *
4
4
  * Handles configuration endpoints (languages, currencies, locales, business config).
5
+ * Stateless - all configuration passed as parameters.
5
6
  */
6
- import { paymentAxios, publicStoreAxios } from '../client/httpClient'
7
+ import type { SdkConfig } from '../config'
7
8
  import type { BackendLanguage, SupportedLanguagesResponse, SupportedCurrenciesResponse } from '../types/payments'
8
9
  import type { BusinessConfig } from '../types/business'
9
10
 
10
11
  /**
11
12
  * Fetch supported languages from the payment system.
12
- * Resolves to: {luxePaymentBackendUrl}/config/supported-languages
13
+ * Resolves to: {kasuviaPaymentBackendUrl}/config/supported-languages
13
14
  */
14
- export async function getSupportedLanguages(): Promise<SupportedLanguagesResponse> {
15
- const { data } = await paymentAxios.get<SupportedLanguagesResponse>('/config/supported-languages')
16
- return data
15
+ export async function getSupportedLanguages(config: SdkConfig): Promise<SupportedLanguagesResponse> {
16
+ const response = await fetch(`${config.backendUrls.payment}/config/supported-languages`, {
17
+ headers: {
18
+ "X-Storefront-Key": config.storefrontApiKey,
19
+ "X-Business-ID": config.businessId,
20
+ },
21
+ })
22
+ if (!response.ok) throw new Error('Failed to get supported languages')
23
+ return response.json()
17
24
  }
18
25
 
19
26
  /**
20
27
  * Fetch supported currencies from the payment system.
21
- * Resolves to: {luxePaymentBackendUrl}/config/supported-currencies
28
+ * Resolves to: {kasuviaPaymentBackendUrl}/config/supported-currencies
22
29
  */
23
- export async function getSupportedCurrencies(): Promise<SupportedCurrenciesResponse> {
24
- const { data } = await paymentAxios.get<SupportedCurrenciesResponse>('/config/supported-currencies')
25
- return data
30
+ export async function getSupportedCurrencies(config: SdkConfig): Promise<SupportedCurrenciesResponse> {
31
+ const response = await fetch(`${config.backendUrls.payment}/config/supported-currencies`, {
32
+ headers: {
33
+ "X-Storefront-Key": config.storefrontApiKey,
34
+ "X-Business-ID": config.businessId,
35
+ },
36
+ })
37
+ if (!response.ok) throw new Error('Failed to get supported currencies')
38
+ return response.json()
26
39
  }
27
40
 
28
41
  /**
29
42
  * Fetch the business's public configuration, including store_currency.
30
- * Uses publicStoreAxios (X-Storefront-Key + X-Business-ID — no user JWT required).
31
- * Resolves to: {luxeStoreBackendUrl}/business/profile
43
+ * Uses storefront API key header (X-Storefront-Key).
44
+ * Resolves to: {kasuviaAuthBackendUrl}/internal/businesses/{business_id}/
45
+ * This endpoint is designed for storefronts to fetch business config using their storefront API key.
32
46
  */
33
- export async function getBusinessConfig(): Promise<BusinessConfig> {
34
- const { data } = await publicStoreAxios.get<BusinessConfig>('business/profile')
35
- return data
47
+ export async function getBusinessConfig(config: SdkConfig): Promise<BusinessConfig> {
48
+ const response = await fetch(`${config.backendUrls.auth}/internal/businesses/${config.businessId}/`, {
49
+ headers: {
50
+ "X-Storefront-Key": config.storefrontApiKey,
51
+ "X-Business-ID": config.businessId,
52
+ },
53
+ })
54
+ if (!response.ok) throw new Error('Failed to get business config')
55
+ return response.json()
36
56
  }
37
57
 
38
58
  export const configService = {