medusa-storefront-data 1.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/dist/cookies.d.ts +2 -2
  2. package/dist/cookies.d.ts.map +1 -1
  3. package/dist/edge.d.ts +3 -0
  4. package/dist/edge.d.ts.map +1 -0
  5. package/dist/edge.js +1 -0
  6. package/dist/middleware.d.ts +3 -0
  7. package/dist/middleware.d.ts.map +1 -0
  8. package/dist/middleware.js +1 -0
  9. package/dist/server/cart.d.ts +9 -5
  10. package/dist/server/cart.d.ts.map +1 -1
  11. package/dist/server/cart.js +164 -194
  12. package/dist/server/categories.d.ts +3 -2
  13. package/dist/server/categories.d.ts.map +1 -1
  14. package/dist/server/categories.js +14 -51
  15. package/dist/server/collections.d.ts.map +1 -1
  16. package/dist/server/collections.js +16 -61
  17. package/dist/server/contact.d.ts +34 -0
  18. package/dist/server/contact.d.ts.map +1 -0
  19. package/dist/server/contact.js +57 -0
  20. package/dist/server/customer.d.ts +7 -7
  21. package/dist/server/customer.d.ts.map +1 -1
  22. package/dist/server/customer.js +96 -145
  23. package/dist/server/dynamic-config.d.ts.map +1 -1
  24. package/dist/server/dynamic-config.js +38 -12
  25. package/dist/server/fulfillment.d.ts +4 -3
  26. package/dist/server/fulfillment.d.ts.map +1 -1
  27. package/dist/server/fulfillment.js +16 -41
  28. package/dist/server/guest.d.ts +35 -63
  29. package/dist/server/guest.d.ts.map +1 -1
  30. package/dist/server/guest.js +81 -202
  31. package/dist/server/home.d.ts +15 -0
  32. package/dist/server/home.d.ts.map +1 -0
  33. package/dist/server/home.js +45 -0
  34. package/dist/server/index.d.ts +2 -0
  35. package/dist/server/index.d.ts.map +1 -1
  36. package/dist/server/index.js +2 -0
  37. package/dist/server/locale-actions.d.ts +1 -1
  38. package/dist/server/locale-actions.d.ts.map +1 -1
  39. package/dist/server/locale-actions.js +8 -13
  40. package/dist/server/locales.d.ts +2 -4
  41. package/dist/server/locales.d.ts.map +1 -1
  42. package/dist/server/locales.js +5 -13
  43. package/dist/server/orders.d.ts +5 -11
  44. package/dist/server/orders.d.ts.map +1 -1
  45. package/dist/server/orders.js +126 -267
  46. package/dist/server/payment-details.d.ts +4 -4
  47. package/dist/server/payment-details.d.ts.map +1 -1
  48. package/dist/server/payment-details.js +17 -42
  49. package/dist/server/payment.d.ts +2 -1
  50. package/dist/server/payment.d.ts.map +1 -1
  51. package/dist/server/payment.js +9 -21
  52. package/dist/server/pincode.d.ts +7 -0
  53. package/dist/server/pincode.d.ts.map +1 -0
  54. package/dist/server/pincode.js +30 -0
  55. package/dist/server/products.d.ts +15 -19
  56. package/dist/server/products.d.ts.map +1 -1
  57. package/dist/server/products.js +47 -178
  58. package/dist/server/regions.d.ts +1 -1
  59. package/dist/server/regions.d.ts.map +1 -1
  60. package/dist/server/regions.js +6 -3
  61. package/dist/server/returns.d.ts +4 -4
  62. package/dist/server/returns.d.ts.map +1 -1
  63. package/dist/server/returns.js +50 -154
  64. package/dist/server/swaps.d.ts +7 -6
  65. package/dist/server/swaps.d.ts.map +1 -1
  66. package/dist/server/swaps.js +23 -57
  67. package/dist/server/variants.d.ts.map +1 -1
  68. package/dist/server/variants.js +11 -22
  69. package/dist/server/wishlist.d.ts +11 -0
  70. package/dist/server/wishlist.d.ts.map +1 -0
  71. package/dist/server/wishlist.js +49 -0
  72. package/dist/util/get-locale-header.d.ts +1 -1
  73. package/dist/util/revalidate-cart.d.ts +2 -0
  74. package/dist/util/revalidate-cart.d.ts.map +1 -0
  75. package/dist/util/revalidate-cart.js +8 -0
  76. package/dist/util/sort-products.d.ts +3 -0
  77. package/dist/util/sort-products.d.ts.map +1 -0
  78. package/dist/util/sort-products.js +1 -0
  79. package/dist/util/store-client.d.ts +13 -0
  80. package/dist/util/store-client.d.ts.map +1 -0
  81. package/dist/util/store-client.js +77 -0
  82. package/package.json +95 -37
  83. package/src/edge.ts +2 -0
  84. package/src/middleware.ts +2 -2
  85. package/src/server/cart.ts +214 -267
  86. package/src/server/categories.ts +19 -72
  87. package/src/server/collections.ts +25 -82
  88. package/src/server/contact.ts +92 -0
  89. package/src/server/customer.ts +146 -190
  90. package/src/server/dynamic-config.ts +38 -12
  91. package/src/server/fulfillment.ts +27 -53
  92. package/src/server/guest.ts +159 -276
  93. package/src/server/home.ts +68 -0
  94. package/src/server/index.ts +1 -0
  95. package/src/server/locale-actions.ts +8 -15
  96. package/src/server/locales.ts +6 -18
  97. package/src/server/orders.ts +167 -337
  98. package/src/server/payment-details.ts +24 -52
  99. package/src/server/payment.ts +8 -28
  100. package/src/server/pincode.ts +49 -0
  101. package/src/server/products.ts +72 -235
  102. package/src/server/regions.ts +10 -6
  103. package/src/server/returns.ts +75 -189
  104. package/src/server/swaps.ts +94 -123
  105. package/src/server/variants.ts +9 -28
  106. package/src/server/wishlist.ts +1 -1
  107. package/src/util/revalidate-cart.ts +10 -0
  108. package/src/util/sort-products.ts +2 -47
  109. package/src/util/store-client.ts +93 -0
  110. package/src/services/middleware.ts +0 -54
@@ -3,11 +3,32 @@ import { sdk } from "../config";
3
3
  import medusaError from "../util/medusa-error";
4
4
  import { revalidateTag, revalidatePath } from "next/cache";
5
5
  import { redirect } from "next/navigation";
6
+ import { headers as nextHeaders } from "next/headers";
6
7
  import { getAuthHeaders, getCacheOptions, getCacheTag, getCartId, removeCartId, setCartId, getHoldCartId, setBuyNowCartId, removeBuyNowCartId, } from "../cookies";
7
8
  import { getRegion } from "./regions";
9
+ function normalizeCartEmail(email) {
10
+ if (typeof email !== "string")
11
+ return undefined;
12
+ const normalized = email.trim().toLowerCase();
13
+ return normalized || undefined;
14
+ }
15
+ function isValidCartEmail(email) {
16
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
17
+ }
8
18
  import { getLocale } from "./locale-actions";
9
19
  import { retrieveCustomer } from "./customer";
20
+ import { medusaCartCreate, medusaCartRetrieve, medusaCartUpdate, medusaCartAddLineItem, medusaCartUpdateLineItem, medusaCartRemoveLineItem, medusaCartApplyPromotions, medusaCartAddShippingMethod, medusaCartComplete, medusaCartSkipMerge, medusaCartDelete, medusaCartList, medusaShippingOptionsList, MEDUSA_STORE_CART_DETAIL_FIELDS, } from "medusa-services/cart";
21
+ import { medusaCustomerCreateAddress, medusaCustomerRetrieve, medusaCustomerUpdateAddress, } from "medusa-services/customer";
22
+ import { medusaPaymentSessionInitiate } from "medusa-services/payment";
23
+ import { getStoreCartClientOptions } from "../util/store-client";
24
+ import { revalidateCartTags } from "../util/revalidate-cart";
10
25
  import { cache } from "react";
26
+ function throwCartError(error) {
27
+ if (error && typeof error === "object" && "response" in error) {
28
+ medusaError(error);
29
+ }
30
+ throw error instanceof Error ? error : new Error(String(error));
31
+ }
11
32
  /**
12
33
  * Retrieves a cart by its ID. If no ID is provided, it will use the cart ID from the cookies.
13
34
  * @param cartId - optional - The ID of the cart to retrieve.
@@ -20,20 +41,16 @@ export const retrieveCart = cache(async (cartId, fields) => {
20
41
  // If we're not explicitly asking for a specific cartId and we have an active cart
21
42
  if (!cartId && id) {
22
43
  try {
23
- const headerList = await headers();
44
+ const headerList = await nextHeaders();
24
45
  const pathname = headerList.get("x-pathname") || headerList.get("referer") || "";
25
46
  // Skip metadata check if we are clearly in checkout to avoid extra API call
26
47
  if (!pathname.includes("/checkout")) {
27
- const currentCart = await sdk.client
28
- .fetch(`/store/carts/${id}`, {
29
- method: "GET",
30
- query: { fields: "metadata" },
31
- headers: await getAuthHeaders(),
32
- cache: "no-store",
33
- })
48
+ const options = await getStoreCartClientOptions();
49
+ const currentCart = await medusaCartRetrieve(id, options, { fields: "metadata" })
34
50
  .then(({ cart }) => cart)
35
51
  .catch(() => null);
36
- if (currentCart?.metadata?.is_buy_now || currentCart?.metadata?.is_reorder) {
52
+ const cartMeta = currentCart?.metadata;
53
+ if (cartMeta?.is_buy_now || cartMeta?.is_reorder) {
37
54
  await removeBuyNowCartId();
38
55
  id = await getCartId(); // Re-fetch ID which will now fall back to the real main cart
39
56
  revalidateTag("carts");
@@ -44,12 +61,11 @@ export const retrieveCart = cache(async (cartId, fields) => {
44
61
  // Silent fail
45
62
  }
46
63
  }
47
- fields ??=
48
- "*items, *region, *items.product, *items.product.thumbnail, *items.product.images, *items.product.options, *items.product.variants, +items.product.variants.inventory_quantity, +items.product.variants.manage_inventory, +items.product.variants.allow_backorder, *items.product.variants.options, *items.variant, +items.variant.inventory_quantity, +items.variant.manage_inventory, +items.variant.allow_backorder, *items.variant.images, *items.variant.product, *items.variant.product.thumbnail, *items.variant.product.images, *items.variant.options, *items.thumbnail, *items.metadata, +items.total, +items.adjustments, *promotions, +shipping_methods.name, +shipping_methods.adjustments";
64
+ fields ??= MEDUSA_STORE_CART_DETAIL_FIELDS;
49
65
  if (!id) {
50
66
  return null;
51
67
  }
52
- const headers = {
68
+ const authHeaders = {
53
69
  ...(await getAuthHeaders()),
54
70
  };
55
71
  const next = {
@@ -61,7 +77,7 @@ export const retrieveCart = cache(async (cartId, fields) => {
61
77
  query: {
62
78
  fields,
63
79
  },
64
- headers,
80
+ headers: authHeaders,
65
81
  next,
66
82
  cache: "no-store",
67
83
  })
@@ -76,19 +92,20 @@ export async function getOrSetCart(countryCode) {
76
92
  throw new Error(`Region not found for country code: ${countryCode}`);
77
93
  }
78
94
  let cart = await retrieveCart(undefined, "id,region_id");
79
- const headers = {
80
- ...(await getAuthHeaders()),
81
- };
95
+ const options = await getStoreCartClientOptions();
82
96
  if (!cart) {
83
97
  const locale = await getLocale();
84
- const cartResp = await sdk.store.cart.create({ region_id: region.id, locale: locale || undefined }, {}, headers);
85
- cart = cartResp.cart;
98
+ const { cart: createdCart } = await medusaCartCreate(options, {
99
+ region_id: region.id,
100
+ locale: locale || undefined,
101
+ });
102
+ cart = createdCart;
86
103
  await setCartId(cart.id);
87
104
  const cartCacheTag = await getCacheTag("carts");
88
105
  revalidateTag(cartCacheTag);
89
106
  }
90
107
  if (cart && cart?.region_id !== region.id) {
91
- await sdk.store.cart.update(cart.id, { region_id: region.id }, {}, headers);
108
+ await medusaCartUpdate(cart.id, { region_id: region.id }, options);
92
109
  const cartCacheTag = await getCacheTag("carts");
93
110
  revalidateTag(cartCacheTag);
94
111
  }
@@ -99,19 +116,15 @@ export async function updateCart(data) {
99
116
  if (!cartId) {
100
117
  throw new Error("No existing cart found, please create one before updating");
101
118
  }
102
- const headers = {
103
- ...(await getAuthHeaders()),
104
- };
105
- return sdk.store.cart
106
- .update(cartId, data, {}, headers)
107
- .then(async ({ cart }) => {
108
- const cartCacheTag = await getCacheTag("carts");
109
- revalidateTag(cartCacheTag);
110
- const fulfillmentCacheTag = await getCacheTag("fulfillment");
111
- revalidateTag(fulfillmentCacheTag);
119
+ try {
120
+ const options = await getStoreCartClientOptions();
121
+ const { cart } = await medusaCartUpdate(cartId, data, options);
122
+ await revalidateCartTags();
112
123
  return cart;
113
- })
114
- .catch(medusaError);
124
+ }
125
+ catch (e) {
126
+ throwCartError(e);
127
+ }
115
128
  }
116
129
  export async function addToCart({ variantId, quantity, countryCode, }) {
117
130
  if (!variantId) {
@@ -121,21 +134,14 @@ export async function addToCart({ variantId, quantity, countryCode, }) {
121
134
  if (!cart) {
122
135
  throw new Error("Error retrieving or creating cart");
123
136
  }
124
- const headers = {
125
- ...(await getAuthHeaders()),
126
- };
127
- await sdk.store.cart
128
- .createLineItem(cart.id, {
129
- variant_id: variantId,
130
- quantity,
131
- }, {}, headers)
132
- .then(async () => {
133
- const cartCacheTag = await getCacheTag("carts");
134
- revalidateTag(cartCacheTag);
135
- const fulfillmentCacheTag = await getCacheTag("fulfillment");
136
- revalidateTag(fulfillmentCacheTag);
137
- })
138
- .catch(medusaError);
137
+ try {
138
+ const options = await getStoreCartClientOptions();
139
+ await medusaCartAddLineItem(cart.id, { variant_id: variantId, quantity }, options);
140
+ await revalidateCartTags();
141
+ }
142
+ catch (e) {
143
+ throwCartError(e);
144
+ }
139
145
  }
140
146
  export async function buyNow({ variantId, quantity, countryCode, }) {
141
147
  if (!variantId) {
@@ -145,36 +151,26 @@ export async function buyNow({ variantId, quantity, countryCode, }) {
145
151
  if (!region) {
146
152
  throw new Error(`Region not found for country code: ${countryCode}`);
147
153
  }
148
- const headers = {
149
- ...(await getAuthHeaders()),
150
- };
154
+ const options = await getStoreCartClientOptions();
151
155
  const locale = await getLocale();
152
156
  // 1. Create a NEW cart regardless of existing one
153
- const cartResp = await sdk.store.cart.create({
157
+ const { cart } = await medusaCartCreate(options, {
154
158
  region_id: region.id,
155
159
  locale: locale || undefined,
156
- metadata: { is_buy_now: true }
157
- }, {}, headers);
158
- const cart = cartResp.cart;
160
+ metadata: { is_buy_now: true },
161
+ });
159
162
  // Save the new cart id in "buy_now_cart_id" cookie
160
163
  await removeBuyNowCartId();
161
164
  await setBuyNowCartId(cart.id);
162
165
  // Ensure this new cart is not merged with existing ones
163
166
  try {
164
- await sdk.client.fetch(`/store/carts/merge/skip`, {
165
- method: "POST",
166
- body: { cart_id: cart.id },
167
- headers,
168
- });
167
+ await medusaCartSkipMerge(cart.id, options);
169
168
  }
170
169
  catch (e) {
171
170
  console.error("Failed to skip cart merge for buy now cart:", e);
172
171
  }
173
172
  // 2. Add the item to this new cart
174
- await sdk.store.cart.createLineItem(cart.id, {
175
- variant_id: variantId,
176
- quantity,
177
- }, {}, headers);
173
+ await medusaCartAddLineItem(cart.id, { variant_id: variantId, quantity }, options);
178
174
  // 3. (REMOVED: No longer overwriting the main cart ID, because getCartId handles buy_now_cart_id priority)
179
175
  // 4. OPTIMIZATION: If user is logged in and has addresses, auto-fill and skip to payment
180
176
  const customer = await retrieveCustomer().catch(() => null);
@@ -183,7 +179,7 @@ export async function buyNow({ variantId, quantity, countryCode, }) {
183
179
  if (defaultAddress) {
184
180
  try {
185
181
  // Set addresses
186
- await sdk.store.cart.update(cart.id, {
182
+ await medusaCartUpdate(cart.id, {
187
183
  shipping_address: {
188
184
  first_name: defaultAddress.first_name,
189
185
  last_name: defaultAddress.last_name,
@@ -208,16 +204,12 @@ export async function buyNow({ variantId, quantity, countryCode, }) {
208
204
  phone: defaultAddress.phone,
209
205
  company: defaultAddress.company,
210
206
  },
211
- email: customer.email
212
- }, {}, headers);
207
+ email: customer?.email ?? "",
208
+ }, options);
213
209
  // Fetch and set first shipping method
214
- const { shipping_options } = await sdk.client.fetch("/store/shipping-options", {
215
- query: { cart_id: cart.id },
216
- headers,
217
- cache: "no-store",
218
- });
210
+ const { shipping_options } = await medusaShippingOptionsList(cart.id, options);
219
211
  if (shipping_options?.length > 0) {
220
- await sdk.store.cart.addShippingMethod(cart.id, { option_id: shipping_options[0].id }, {}, headers);
212
+ await medusaCartAddShippingMethod(cart.id, shipping_options[0].id, options);
221
213
  skipToPayment = true;
222
214
  }
223
215
  }
@@ -245,18 +237,14 @@ export async function updateLineItem({ lineId, quantity, }) {
245
237
  if (!cartId) {
246
238
  throw new Error("Missing cart ID when updating line item");
247
239
  }
248
- const headers = {
249
- ...(await getAuthHeaders()),
250
- };
251
- await sdk.store.cart
252
- .updateLineItem(cartId, lineId, { quantity }, {}, headers)
253
- .then(async () => {
254
- const cartCacheTag = await getCacheTag("carts");
255
- revalidateTag(cartCacheTag);
256
- const fulfillmentCacheTag = await getCacheTag("fulfillment");
257
- revalidateTag(fulfillmentCacheTag);
258
- })
259
- .catch(medusaError);
240
+ try {
241
+ const options = await getStoreCartClientOptions();
242
+ await medusaCartUpdateLineItem(cartId, lineId, { quantity }, options);
243
+ await revalidateCartTags();
244
+ }
245
+ catch (e) {
246
+ throwCartError(e);
247
+ }
260
248
  }
261
249
  export async function deleteLineItem(lineId) {
262
250
  if (!lineId) {
@@ -266,18 +254,14 @@ export async function deleteLineItem(lineId) {
266
254
  if (!cartId) {
267
255
  throw new Error("Missing cart ID when deleting line item");
268
256
  }
269
- const headers = {
270
- ...(await getAuthHeaders()),
271
- };
272
- await sdk.store.cart
273
- .deleteLineItem(cartId, lineId, {}, headers)
274
- .then(async () => {
275
- const cartCacheTag = await getCacheTag("carts");
276
- revalidateTag(cartCacheTag);
277
- const fulfillmentCacheTag = await getCacheTag("fulfillment");
278
- revalidateTag(fulfillmentCacheTag);
279
- })
280
- .catch(medusaError);
257
+ try {
258
+ const options = await getStoreCartClientOptions();
259
+ await medusaCartRemoveLineItem(cartId, lineId, options);
260
+ await revalidateCartTags();
261
+ }
262
+ catch (e) {
263
+ throwCartError(e);
264
+ }
281
265
  }
282
266
  export async function updateLineItemVariant({ lineId, variantId, quantity, countryCode, }) {
283
267
  if (!lineId) {
@@ -296,26 +280,23 @@ export async function updateLineItemVariant({ lineId, variantId, quantity, count
296
280
  });
297
281
  }
298
282
  export async function setShippingMethod({ cartId, shippingMethodId, }) {
299
- const headers = {
300
- ...(await getAuthHeaders()),
301
- };
302
- return sdk.store.cart
303
- .addShippingMethod(cartId, { option_id: shippingMethodId }, {}, headers)
304
- .then(async () => {
283
+ try {
284
+ const options = await getStoreCartClientOptions();
285
+ await medusaCartAddShippingMethod(cartId, shippingMethodId, options);
305
286
  const cartCacheTag = await getCacheTag("carts");
306
287
  revalidateTag(cartCacheTag);
307
- })
308
- .catch(medusaError);
288
+ }
289
+ catch (e) {
290
+ throwCartError(e);
291
+ }
309
292
  }
310
293
  /**
311
294
  * Sets a shipping method silently without triggering a full page revalidation.
312
295
  */
313
296
  export async function setShippingMethodSilently({ cartId, shippingMethodId, }) {
314
- const headers = {
315
- ...(await getAuthHeaders()),
316
- };
317
297
  try {
318
- await sdk.store.cart.addShippingMethod(cartId, { option_id: shippingMethodId }, {}, headers);
298
+ const options = await getStoreCartClientOptions();
299
+ await medusaCartAddShippingMethod(cartId, shippingMethodId, options);
319
300
  return { success: true };
320
301
  }
321
302
  catch (e) {
@@ -323,9 +304,6 @@ export async function setShippingMethodSilently({ cartId, shippingMethodId, }) {
323
304
  }
324
305
  }
325
306
  export async function initiatePaymentSession(cart, data) {
326
- const headers = {
327
- ...(await getAuthHeaders()),
328
- };
329
307
  // 1. RE-FETCH cart with NO CACHE to ensure we have the latest data from the DB
330
308
  const latestCart = await retrieveCart(cart.id);
331
309
  if (!latestCart)
@@ -372,12 +350,16 @@ export async function initiatePaymentSession(cart, data) {
372
350
  addressUpdates.billing_address = cleanAddress(latestCart.billing_address) || cleanAddress(latestCart.shipping_address);
373
351
  }
374
352
  if (Object.keys(addressUpdates).length > 0) {
375
- await sdk.store.cart.update(latestCart.id, addressUpdates, {}, headers);
353
+ const options = await getStoreCartClientOptions();
354
+ await medusaCartUpdate(latestCart.id, addressUpdates, options);
376
355
  }
377
356
  }
378
- // 3. Final re-fetch (direct SDK call to bypass any lib-level cache)
379
- const cartResponse = await sdk.store.cart.retrieve(cart.id, { fields: "*shipping_address,*billing_address" }, headers);
380
- const finalCart = cartResponse.cart;
357
+ // 3. Final re-fetch (direct call to bypass any lib-level cache)
358
+ const options = await getStoreCartClientOptions();
359
+ const { cart: finalCartRaw } = await medusaCartRetrieve(cart.id, options, {
360
+ fields: "*shipping_address,*billing_address",
361
+ });
362
+ const finalCart = finalCartRaw;
381
363
  // 4. PRE-FLIGHT VALIDATION: Only strictly block for Razorpay, be more lenient for COD
382
364
  const isRazorpayProvider = data.provider_id.includes("razorpay");
383
365
  const displayPhone = finalCart.shipping_address?.phone || finalCart.billing_address?.phone || phone;
@@ -401,36 +383,35 @@ export async function initiatePaymentSession(cart, data) {
401
383
  }
402
384
  }
403
385
  };
404
- return sdk.store.payment
405
- .initiatePaymentSession(finalCart, enhancedData, {}, headers)
406
- .then(async (resp) => {
386
+ try {
387
+ await medusaPaymentSessionInitiate(finalCart.id, enhancedData, options);
388
+ const { cart: refreshedCart } = await medusaCartRetrieve(finalCart.id, options, {
389
+ fields: `${MEDUSA_STORE_CART_DETAIL_FIELDS}, *payment_collection, *payment_collection.payment_sessions`,
390
+ });
407
391
  const cartCacheTag = await getCacheTag("carts");
408
392
  revalidateTag(cartCacheTag);
409
- return resp;
410
- })
411
- .catch((e) => {
393
+ return refreshedCart;
394
+ }
395
+ catch (e) {
412
396
  const errorMsg = e.message || e.response?.data?.message || "Unknown error";
413
- throw new Error(`Razorpay Initialization Failed: ${errorMsg}`);
414
- });
397
+ const label = isRazorpayProvider ? "Razorpay" : "Payment";
398
+ throw new Error(`${label} initialization failed: ${errorMsg}`);
399
+ }
415
400
  }
416
401
  export async function applyPromotions(codes) {
417
402
  const cartId = await getCartId();
418
403
  if (!cartId) {
419
404
  throw new Error("No existing cart found");
420
405
  }
421
- const headers = {
422
- ...(await getAuthHeaders()),
423
- };
424
- return sdk.store.cart
425
- .update(cartId, { promo_codes: codes }, {}, headers)
426
- .then(async ({ cart }) => {
427
- const cartCacheTag = await getCacheTag("carts");
428
- revalidateTag(cartCacheTag);
429
- const fulfillmentCacheTag = await getCacheTag("fulfillment");
430
- revalidateTag(fulfillmentCacheTag);
406
+ try {
407
+ const options = await getStoreCartClientOptions();
408
+ const { cart } = await medusaCartApplyPromotions(cartId, codes, options);
409
+ await revalidateCartTags();
431
410
  return cart;
432
- })
433
- .catch(medusaError);
411
+ }
412
+ catch (e) {
413
+ throwCartError(e);
414
+ }
434
415
  }
435
416
  export async function applyGiftCard(code) {
436
417
  // const cartId = getCartId()
@@ -516,26 +497,24 @@ export async function setAddresses(currentState, formData) {
516
497
  };
517
498
  const data = {
518
499
  shipping_address: shippingAddress,
519
- email: formData.get("email"),
500
+ email: normalizeCartEmail(formData.get("email")),
520
501
  };
502
+ if (data.email && !isValidCartEmail(data.email)) {
503
+ throw new Error("Please enter a valid email address.");
504
+ }
521
505
  // Save address to customer profile if logged in
522
506
  const authHeaders = await getAuthHeaders();
523
507
  if (authHeaders && "authorization" in authHeaders) {
524
508
  try {
525
- // Fetch current customer to check if address already exists
526
- const { customer } = await sdk.client.fetch(`/store/customers/me`, {
527
- method: "GET",
528
- query: { fields: "*addresses" },
529
- headers: authHeaders,
530
- cache: "no-store",
531
- });
509
+ const options = await getStoreCartClientOptions();
510
+ const { customer } = await medusaCustomerRetrieve(options, { fields: "*addresses" });
532
511
  const addressExists = customer?.addresses?.some((a) => a.address_1 === shippingAddress.address_1 &&
533
512
  a.postal_code === shippingAddress.postal_code &&
534
513
  a.city === shippingAddress.city &&
535
514
  a.first_name === shippingAddress.first_name &&
536
515
  a.last_name === shippingAddress.last_name);
537
516
  if (!addressExists) {
538
- await sdk.store.customer.createAddress(shippingAddress, {}, authHeaders);
517
+ await medusaCustomerCreateAddress(shippingAddress, options);
539
518
  const customerCacheTag = await getCacheTag("customers");
540
519
  revalidateTag(customerCacheTag);
541
520
  }
@@ -580,19 +559,19 @@ export async function placeOrder(cartId) {
580
559
  if (!id) {
581
560
  throw new Error("No existing cart found when placing an order");
582
561
  }
583
- const headers = {
584
- ...(await getAuthHeaders()),
585
- };
586
- const cartRes = await sdk.store.cart
587
- .complete(id, {}, headers)
588
- .then(async (cartRes) => {
562
+ let cartRes;
563
+ try {
564
+ const options = await getStoreCartClientOptions();
565
+ cartRes = await medusaCartComplete(id, options);
589
566
  const cartCacheTag = await getCacheTag("carts");
590
567
  revalidateTag(cartCacheTag);
591
- return cartRes;
592
- })
593
- .catch(medusaError);
568
+ }
569
+ catch (e) {
570
+ throwCartError(e);
571
+ }
594
572
  if (cartRes?.type === "order") {
595
- const countryCode = cartRes.order.shipping_address?.country_code?.toLowerCase();
573
+ const order = cartRes.order;
574
+ const countryCode = order.shipping_address?.country_code?.toLowerCase();
596
575
  const orderCacheTag = await getCacheTag("orders");
597
576
  revalidateTag(orderCacheTag);
598
577
  // NEW LOGIC: Check if we just completed a Buy Now cart
@@ -608,7 +587,7 @@ export async function placeOrder(cartId) {
608
587
  // Regular checkout: clear the main cart
609
588
  await removeCartId();
610
589
  }
611
- redirect(`/${countryCode}/order/${cartRes?.order.id}/confirmed`);
590
+ redirect(`/${countryCode}/order/${order.id}/confirmed`);
612
591
  }
613
592
  return cartRes.cart;
614
593
  }
@@ -651,9 +630,6 @@ export async function listCartOptions() {
651
630
  }
652
631
  export async function addCustomerAddressToCart(currentState, formData) {
653
632
  try {
654
- const headers = {
655
- ...(await getAuthHeaders()),
656
- };
657
633
  const shippingCountryCode = formData.get("shipping_address.country_code")?.toLowerCase() || "in";
658
634
  // Parse address data from formData (which uses shipping_address. prefix)
659
635
  const addressData = {
@@ -676,11 +652,12 @@ export async function addCustomerAddressToCart(currentState, formData) {
676
652
  // 1. Add/Update Customer Address Book
677
653
  // We try/catch this separately so if it fails (e.g. user not logged in), we still try to proceed with checkout
678
654
  try {
655
+ const options = await getStoreCartClientOptions();
679
656
  if (addressId) {
680
- await sdk.store.customer.updateAddress(addressId, addressData, {}, headers);
657
+ await medusaCustomerUpdateAddress(addressId, addressData, options);
681
658
  }
682
659
  else {
683
- await sdk.store.customer.createAddress(addressData, {}, headers);
660
+ await medusaCustomerCreateAddress(addressData, options);
684
661
  }
685
662
  const customerCacheTag = await getCacheTag("customers");
686
663
  revalidateTag(customerCacheTag);
@@ -707,8 +684,11 @@ export async function addCustomerAddressToCart(currentState, formData) {
707
684
  country_code: addressData.country_code,
708
685
  phone: addressData.phone,
709
686
  },
710
- email: formData.get("email"),
687
+ email: normalizeCartEmail(formData.get("email")),
711
688
  };
689
+ if (cartData.email && !isValidCartEmail(cartData.email)) {
690
+ throw new Error("Please enter a valid email address.");
691
+ }
712
692
  const sameAsBilling = formData.get("same_as_billing");
713
693
  if (sameAsBilling === "on") {
714
694
  cartData.billing_address = cartData.shipping_address;
@@ -735,15 +715,17 @@ export async function updateAddressSilently(data) {
735
715
  if (!cartId)
736
716
  return;
737
717
  try {
738
- const headers = {
739
- ...(await getAuthHeaders()),
740
- };
741
- await sdk.store.cart.update(cartId, data, {}, headers);
718
+ const payload = { ...data };
719
+ if (payload.email !== undefined) {
720
+ payload.email = normalizeCartEmail(payload.email);
721
+ if (payload.email && !isValidCartEmail(payload.email)) {
722
+ return { success: false, error: "Invalid email address." };
723
+ }
724
+ }
725
+ const options = await getStoreCartClientOptions();
726
+ await medusaCartUpdate(cartId, payload, options);
742
727
  // Revalidate tags to ensure CartTotals gets new shipping info
743
- const cartCacheTag = await getCacheTag("carts");
744
- revalidateTag(cartCacheTag);
745
- const fulfillmentCacheTag = await getCacheTag("fulfillment");
746
- revalidateTag(fulfillmentCacheTag);
728
+ await revalidateCartTags();
747
729
  return { success: true };
748
730
  }
749
731
  catch (e) {
@@ -758,10 +740,8 @@ export async function updateCartMetadataSilently(metadata) {
758
740
  if (!cartId)
759
741
  return;
760
742
  try {
761
- const headers = {
762
- ...(await getAuthHeaders()),
763
- };
764
- await sdk.store.cart.update(cartId, { metadata }, {}, headers);
743
+ const options = await getStoreCartClientOptions();
744
+ await medusaCartUpdate(cartId, { metadata }, options);
765
745
  // We intentionally DO NOT call revalidateTag here to prevent page refresh loops
766
746
  return { success: true };
767
747
  }
@@ -770,31 +750,25 @@ export async function updateCartMetadataSilently(metadata) {
770
750
  }
771
751
  }
772
752
  export async function getAbandonedCarts() {
773
- const headers = {
774
- ...(await getAuthHeaders()),
775
- };
753
+ const authHeaders = await getAuthHeaders();
776
754
  // If no authorization, return empty arrays
777
- if (!headers["authorization"]) {
755
+ if (!("authorization" in authHeaders)) {
778
756
  return { buyNowCarts: [], reorderCarts: [] };
779
757
  }
780
758
  try {
781
- // Just fetch all carts for the customer and filter locally
782
- const res = await sdk.client.fetch(`/store/carts`, {
783
- method: "GET",
784
- query: {
785
- fields: "*items, *items.product, *items.product.thumbnail, *items.variant, *items.metadata, +total",
786
- },
787
- headers,
788
- cache: "no-store",
759
+ const options = await getStoreCartClientOptions();
760
+ const res = await medusaCartList(options, {
761
+ fields: "*items, *items.product, *items.product.thumbnail, *items.variant, *items.metadata, +total",
789
762
  }).catch(() => null);
790
763
  let buyNowCarts = [];
791
764
  let reorderCarts = [];
792
765
  if (res && res.carts) {
793
- // Filter out the main active cart
794
766
  const currentCartId = await getCartId();
795
- const filteredCarts = res.carts.filter(c => c.id !== currentCartId);
796
- buyNowCarts = filteredCarts.filter(c => c.metadata?.is_buy_now === true);
797
- reorderCarts = filteredCarts.filter(c => c.metadata?.is_reorder === true);
767
+ const carts = res.carts;
768
+ const filteredCarts = carts.filter((c) => c.id !== currentCartId);
769
+ const meta = (c) => c.metadata;
770
+ buyNowCarts = filteredCarts.filter((c) => meta(c)?.is_buy_now === true);
771
+ reorderCarts = filteredCarts.filter((c) => meta(c)?.is_reorder === true);
798
772
  }
799
773
  return { buyNowCarts, reorderCarts };
800
774
  }
@@ -810,13 +784,9 @@ export async function resumeAbandonedCart(cartId, countryCode) {
810
784
  redirect(`/${countryCode}/checkout?cart_id=${cartId}`);
811
785
  }
812
786
  export async function deleteCart(cartId) {
813
- const headers = await getAuthHeaders();
814
787
  try {
815
- await sdk.client.fetch(`/store/carts/${cartId}`, {
816
- method: "DELETE",
817
- headers,
818
- cache: "no-store",
819
- });
788
+ const options = await getStoreCartClientOptions();
789
+ await medusaCartDelete(cartId, options);
820
790
  revalidateTag("carts");
821
791
  return { success: true };
822
792
  }
@@ -1,3 +1,4 @@
1
- export declare const listCategories: (query?: Record<string, any>) => Promise<any[]>;
2
- export declare const getCategoryByHandle: (categoryHandle: string[]) => Promise<any>;
1
+ import { HttpTypes } from "@medusajs/types";
2
+ export declare const listCategories: (query?: Record<string, any>) => Promise<HttpTypes.StoreProductCategory[]>;
3
+ export declare const getCategoryByHandle: (categoryHandle: string[]) => Promise<HttpTypes.StoreProductCategory | null>;
3
4
  //# sourceMappingURL=categories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"categories.d.ts","sourceRoot":"","sources":["../../src/server/categories.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc,GAAU,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,mBAsC/D,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAU,gBAAgB,MAAM,EAAE,iBAiDjE,CAAA"}
1
+ {"version":3,"file":"categories.d.ts","sourceRoot":"","sources":["../../src/server/categories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAI3C,eAAO,MAAM,cAAc,GAAU,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,8CAW/D,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAU,gBAAgB,MAAM,EAAE,mDAuBjE,CAAA"}