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
@@ -1,8 +1,14 @@
1
1
  "use server"
2
2
 
3
+ import type { FetchArgs } from "@medusajs/js-sdk"
3
4
  import { sdk } from "../config"
4
5
  import { HttpTypes } from "@medusajs/types"
5
6
  import { getAuthHeaders, getCacheOptions } from "../cookies"
7
+ import {
8
+ medusaShippingOptionCalculate,
9
+ medusaShiprocketServiceability,
10
+ } from "medusa-services/fulfillment"
11
+ import { getStoreCartClientOptions } from "../util/store-client"
6
12
 
7
13
  export const listCartShippingMethods = async (cartId: string) => {
8
14
  const headers = {
@@ -24,7 +30,7 @@ export const listCartShippingMethods = async (cartId: string) => {
24
30
  headers,
25
31
  next,
26
32
  cache: "force-cache",
27
- }
33
+ } as FetchArgs & { next?: typeof next; cache?: RequestCache }
28
34
  )
29
35
  .then(({ shipping_options }) => shipping_options)
30
36
  .catch(() => {
@@ -37,61 +43,29 @@ export const calculatePriceForShippingOption = async (
37
43
  cartId: string,
38
44
  data?: Record<string, unknown>
39
45
  ) => {
40
- const headers = {
41
- ...(await getAuthHeaders()),
42
- }
43
-
44
- const next = {
45
- ...(await getCacheOptions("fulfillment")),
46
- }
47
-
48
- const body = { cart_id: cartId, data }
49
-
50
- if (data) {
51
- body.data = data
52
- }
53
-
54
- return sdk.client
55
- .fetch<{ shipping_option: HttpTypes.StoreCartShippingOption }>(
56
- `/store/shipping-options/${optionId}/calculate`,
57
- {
58
- method: "POST",
59
- body,
60
- headers,
61
- next,
62
- }
46
+ try {
47
+ const options = await getStoreCartClientOptions()
48
+ const { shipping_option } = await medusaShippingOptionCalculate(
49
+ optionId,
50
+ cartId,
51
+ options,
52
+ data
63
53
  )
64
- .then(({ shipping_option }) => shipping_option)
65
- .catch((e) => {
66
- return null
67
- })
54
+ return shipping_option as unknown as HttpTypes.StoreCartShippingOption
55
+ } catch (e) {
56
+ return null
57
+ }
68
58
  }
69
59
 
70
60
  export const getShiprocketServiceability = async (pincode: string, variant_id: string, cod: number = 0) => {
71
- const headers = {
72
- ...(await getAuthHeaders()),
73
- }
74
-
75
- return sdk.client
76
- .fetch<any>(
77
- `/store/shiprocket/serviceability`,
78
- {
79
- method: "GET",
80
- query: {
81
- pincode,
82
- variant_id,
83
- cod: cod.toString(),
84
- },
85
- headers,
86
- cache: "no-store",
87
- }
61
+ try {
62
+ const options = await getStoreCartClientOptions()
63
+ return await medusaShiprocketServiceability(
64
+ { pincode, variant_id, cod },
65
+ options
88
66
  )
89
- .then((data) => data)
90
- .catch(async (e) => {
91
- if (e.response) {
92
- const errorData = await e.response.json()
93
- throw new Error(errorData.message || "Failed to check serviceability")
94
- }
95
- throw e
96
- })
67
+ } catch {
68
+ // Missing variant dimensions or Shiprocket unavailable — checkout must continue.
69
+ return null
70
+ }
97
71
  }
@@ -1,333 +1,216 @@
1
1
  "use server"
2
2
 
3
+ import {
4
+ medusaGuestOrderCancelSimple,
5
+ medusaGuestOrderInvoice,
6
+ medusaGuestOrderList,
7
+ medusaGuestOrderRetrieve,
8
+ medusaGuestOtpRequest,
9
+ medusaGuestOtpVerify,
10
+ type GuestReturnItem,
11
+ } from "medusa-services/guest"
12
+ import { medusaGuestOrderReorder } from "medusa-services/orders"
13
+ import { medusaReturnCreateGuest } from "medusa-services/returns"
3
14
  import { cookies, headers } from "next/headers"
4
- import { getGuestAuthHeaders } from "../cookies"
5
- import { sdk } from "../config"
15
+ import {
16
+ getStoreClientOptions,
17
+ getStoreClientOptionsWithToken,
18
+ } from "../util/store-client"
19
+ import { retrieveOrder } from "./orders"
20
+
21
+ async function resolveGuestToken(token?: string): Promise<string | null> {
22
+ if (token) return token
6
23
 
7
- const BACKEND_URL = process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL || "http://localhost:9000"
8
- const PUBLISHABLE_KEY = process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY
24
+ const headersStore = await headers()
25
+ const authHeader = headersStore.get("authorization")
26
+ const headerToken = authHeader?.startsWith("Bearer ") ? authHeader.split(" ")[1] : undefined
27
+ if (headerToken) return headerToken
28
+
29
+ const cookieStore = await cookies()
30
+ return cookieStore.get("_medusa_guest_jwt")?.value ?? null
31
+ }
9
32
 
10
33
  /**
11
34
  * Compatibility wrapper for sendOTP
12
35
  */
13
36
  export async function sendOTP(email: string, type: string = "email_verification") {
14
- const res = await requestGuestOTP(email)
15
- // The previous project expected a token or success.
16
- // We return a dummy token if successful because the UI checks for it.
17
- if (res.success) {
18
- return { success: true, token: "otp_sent_successfully" }
19
- }
20
- return res
37
+ const options = await getStoreClientOptions()
38
+ const res = await medusaGuestOtpRequest(email, options)
39
+ if (res.success) {
40
+ return { success: true, token: "otp_sent_successfully" }
41
+ }
42
+ return res
21
43
  }
22
44
 
23
45
  /**
24
46
  * Compatibility wrapper for verifyOTP
25
47
  */
26
48
  export async function verifyOTP(email: string, token: string, otp: string) {
27
- // The previous implementation used 3 args, but guest.ts uses 2.
28
- // We ignore the mid 'token' as per user's working code.
29
- return await verifyGuestOTP(email, otp)
49
+ return verifyGuestOTP(email, otp)
30
50
  }
31
51
 
32
- import { retrieveOrder } from "./orders"
33
-
34
52
  /**
35
53
  * Compatibility wrapper for listGuestOrders
36
54
  */
37
55
  export async function listGuestOrders(token: string) {
38
- const res = await getGuestOrders(token)
39
- if (!res.success) {
40
- throw new Error(res.error || "Failed to fetch orders")
41
- }
42
-
43
- // Fetch full details for each order to ensure latest fulfillment_status is available
44
- // because the custom list endpoint might not return all fields correctly.
45
- const fullOrders = await Promise.all(
46
- (res.orders || []).map(async (order: any) => {
47
- try {
48
- return await retrieveOrder(order.id)
49
- } catch (e) {
50
- return order
51
- }
52
- })
53
- )
56
+ const res = await getGuestOrders(token)
57
+ if (!res.success) {
58
+ throw new Error(res.error || "Failed to fetch orders")
59
+ }
60
+
61
+ const fullOrders = await Promise.all(
62
+ (res.orders || []).map(async (order: { id?: string }) => {
63
+ try {
64
+ return await retrieveOrder(order.id!)
65
+ } catch {
66
+ return order
67
+ }
68
+ })
69
+ )
54
70
 
55
- return { orders: fullOrders, count: fullOrders.length }
71
+ return { orders: fullOrders, count: fullOrders.length }
56
72
  }
57
73
 
58
74
  export async function requestGuestOTP(email: string) {
59
- const headers: Record<string, string> = {
60
- "Content-Type": "application/json",
61
- }
62
- if (PUBLISHABLE_KEY) headers["x-publishable-api-key"] = PUBLISHABLE_KEY
63
-
64
- try {
65
- const res = await fetch(`${BACKEND_URL}/store/otp/request`, {
66
- method: "POST",
67
- headers,
68
- body: JSON.stringify({ email }),
69
- cache: "no-store",
70
- })
71
-
72
- if (!res.ok) {
73
- const errorData = await res.json().catch(() => ({}))
74
- throw new Error(errorData.message || "Failed to send OTP")
75
- }
76
- return { success: true }
77
- } catch (error: any) {
78
- return { success: false, error: error.message }
79
- }
75
+ const options = await getStoreClientOptions()
76
+ return medusaGuestOtpRequest(email, options)
80
77
  }
81
78
 
82
79
  export async function verifyGuestOTP(email: string, otp: string) {
83
- const headers: Record<string, string> = {
84
- "Content-Type": "application/json",
85
- }
86
- if (PUBLISHABLE_KEY) headers["x-publishable-api-key"] = PUBLISHABLE_KEY
87
-
88
- try {
89
- const res = await fetch(`${BACKEND_URL}/store/otp/verify`, {
90
- method: "POST",
91
- headers,
92
- body: JSON.stringify({ email, otp }),
93
- cache: "no-store",
94
- })
80
+ const options = await getStoreClientOptions()
81
+ const res = await medusaGuestOtpVerify(email, otp, options)
95
82
 
96
- if (!res.ok) {
97
- const errorData = await res.json().catch(() => ({}))
98
- throw new Error(errorData.message || "Failed to verify OTP")
99
- }
100
-
101
- const data = await res.json()
102
-
103
- if (data.token) {
104
- const cookieStore = await cookies()
105
- cookieStore.set("_medusa_guest_jwt", data.token, {
106
- httpOnly: true,
107
- secure: process.env.NODE_ENV === "production",
108
- maxAge: 60 * 60 * 24, // 1 day
109
- path: "/",
110
- })
111
- } else {
112
- throw new Error("No token returned")
113
- }
83
+ if (res.success && res.token) {
84
+ const cookieStore = await cookies()
85
+ cookieStore.set("_medusa_guest_jwt", res.token, {
86
+ httpOnly: true,
87
+ secure: process.env.NODE_ENV === "production",
88
+ maxAge: 60 * 60 * 24,
89
+ path: "/",
90
+ })
91
+ }
114
92
 
115
- return { success: true, token: data.token }
116
- } catch (error: any) {
117
- return { success: false, error: error.message }
118
- }
93
+ return res
119
94
  }
120
95
 
121
96
  export async function logoutGuest() {
122
- const cookieStore = await cookies()
123
- cookieStore.set("_medusa_guest_jwt", "", {
124
- maxAge: -1,
125
- path: "/",
126
- })
127
- return { success: true }
97
+ const cookieStore = await cookies()
98
+ cookieStore.set("_medusa_guest_jwt", "", {
99
+ maxAge: -1,
100
+ path: "/",
101
+ })
102
+ return { success: true }
128
103
  }
129
104
 
130
105
  export async function getGuestOrders(token?: string) {
131
- const cookieStore = await cookies()
132
- const headersStore = await headers()
133
- const authHeader = headersStore.get("authorization")
134
- const headerToken = authHeader?.startsWith("Bearer ") ? authHeader.split(" ")[1] : undefined
135
-
136
- const authToken = token || headerToken || cookieStore.get("_medusa_guest_jwt")?.value
137
- if (!authToken) return { success: false, error: "Unauthorized" }
138
-
139
- const requestHeaders: Record<string, string> = {
140
- "Authorization": `Bearer ${authToken}`
141
- }
142
- if (PUBLISHABLE_KEY) requestHeaders["x-publishable-api-key"] = PUBLISHABLE_KEY
143
-
144
- try {
145
- const response = await sdk.client.fetch<any>(`/store/guest-orders`, {
146
- method: "GET",
147
- headers: requestHeaders,
148
- query: {
149
- fields: "id,display_id,status,fulfillment_status,payment_status,created_at,currency_code,total,subtotal,tax_total,shipping_total,discount_total,metadata,email,*items,*items.variant,*items.variant.product"
150
- },
151
- cache: "no-store",
152
- })
153
-
154
- return { success: true, orders: response.orders || [] }
155
- } catch (error: any) {
156
- return { success: false, error: error.message }
157
- }
106
+ const authToken = await resolveGuestToken(token)
107
+ if (!authToken) return { success: false, error: "Unauthorized" }
108
+
109
+ try {
110
+ const options = await getStoreClientOptions()
111
+ const response = await medusaGuestOrderList(authToken, options)
112
+ return { success: true, orders: response.orders || [] }
113
+ } catch (error) {
114
+ return {
115
+ success: false,
116
+ error: error instanceof Error ? error.message : String(error),
117
+ }
118
+ }
158
119
  }
159
120
 
160
121
  export async function getGuestOrder(id: string, token?: string) {
161
- const cookieStore = await cookies()
162
- const headersStore = await headers()
163
- const authHeader = headersStore.get("authorization")
164
- const headerToken = authHeader?.startsWith("Bearer ") ? authHeader.split(" ")[1] : undefined
122
+ const authToken = await resolveGuestToken(token)
123
+ if (!authToken) return { success: false, error: "Unauthorized" }
165
124
 
166
- const authToken = token || headerToken || cookieStore.get("_medusa_guest_jwt")?.value
167
- if (!authToken) return { success: false, error: "Unauthorized" }
125
+ try {
126
+ const options = await getStoreClientOptions()
127
+ const response = await medusaGuestOrderRetrieve(id, authToken, options)
168
128
 
169
- const requestHeaders: Record<string, string> = {
170
- "Authorization": `Bearer ${authToken}`
129
+ if (response.order) {
130
+ return { success: true, order: response.order }
171
131
  }
172
- if (PUBLISHABLE_KEY) requestHeaders["x-publishable-api-key"] = PUBLISHABLE_KEY
173
-
174
- try {
175
- const response = await sdk.client.fetch<any>(`/store/orders/${id}`, {
176
- method: "GET",
177
- headers: requestHeaders,
178
- query: {
179
- fields: "*payment_collections.payments,*items,*items.metadata,*items.variant,*items.variant.images,*items.variant.product,*items.variant.product.thumbnail,*items.variant.product.images,*items.product,*items.product.thumbnail,*items.product.images,*fulfillments,*fulfillments.items,*fulfillments.location_id,*returns,*returns.items,*cart,*shipping_address,*billing_address,*region,*shipping_methods"
180
- },
181
- cache: "no-store"
182
- })
183
-
184
- if (response.order) {
185
- return { success: true, order: response.order }
186
- } else {
187
- return { success: false, error: "Order not found" }
188
- }
189
- } catch (error: any) {
190
- return { success: false, error: error.message }
132
+ return { success: false, error: "Order not found" }
133
+ } catch (error) {
134
+ return {
135
+ success: false,
136
+ error: error instanceof Error ? error.message : String(error),
191
137
  }
138
+ }
192
139
  }
193
140
 
194
141
  export async function cancelGuestOrder(orderId: string, token?: string) {
195
- const authHeaders = await getGuestAuthHeaders()
196
- const authToken = token || (authHeaders as any).authorization?.split(" ")[1]
197
-
198
- if (!authToken) return { success: false, error: "Unauthorized" }
199
-
200
- const requestHeaders: Record<string, string> = {
201
- "Authorization": `Bearer ${authToken}`
202
- }
203
- if (PUBLISHABLE_KEY) requestHeaders["x-publishable-api-key"] = PUBLISHABLE_KEY
204
-
205
- try {
206
- const response = await fetch(`${BACKEND_URL}/store/guest-orders/${orderId}/cancel`, {
207
- method: "POST",
208
- headers: {
209
- "Content-Type": "application/json",
210
- ...requestHeaders
211
- },
212
- cache: "no-store",
213
- })
214
-
215
- if (!response.ok) {
216
- const errorData = await response.json().catch(() => ({}))
217
- throw new Error(errorData.message || "Failed to cancel order")
218
- }
142
+ const authToken = await resolveGuestToken(token)
143
+ if (!authToken) return { success: false, error: "Unauthorized" }
219
144
 
220
- return { success: true }
221
- } catch (error: any) {
222
- return { success: false, error: error.message }
145
+ try {
146
+ const options = await getStoreClientOptions()
147
+ await medusaGuestOrderCancelSimple(orderId, authToken, options)
148
+ return { success: true }
149
+ } catch (error) {
150
+ return {
151
+ success: false,
152
+ error: error instanceof Error ? error.message : String(error),
223
153
  }
154
+ }
224
155
  }
225
156
 
226
157
  export async function getGuestOrderInvoice(orderId: string, token?: string) {
227
- const authHeaders = await getGuestAuthHeaders()
228
- const authToken = token || (authHeaders as any).authorization?.split(" ")[1]
229
-
230
- if (!authToken) return { success: false, error: "Unauthorized" }
231
-
232
- const requestHeaders: Record<string, string> = {
233
- "Authorization": `Bearer ${authToken}`
234
- }
235
- if (PUBLISHABLE_KEY) requestHeaders["x-publishable-api-key"] = PUBLISHABLE_KEY
236
-
237
- try {
238
- const response = await fetch(`${BACKEND_URL}/store/guest/invoice/download/${orderId}`, {
239
- method: "GET",
240
- headers: requestHeaders,
241
- cache: "no-store",
242
- })
243
-
244
- if (!response.ok) {
245
- const errorData = await response.json().catch(() => ({}))
246
- throw new Error(errorData.message || "Failed to get invoice")
247
- }
248
-
249
- const contentType = response.headers.get("content-type")
250
- if (contentType && contentType.includes("application/pdf")) {
251
- const arrayBuffer = await response.arrayBuffer()
252
- const base64 = Buffer.from(arrayBuffer).toString('base64')
253
- return { success: true, type: 'pdf', data: base64 }
254
- } else {
255
- const data = await response.json()
256
- return { success: true, type: 'json', data }
257
- }
258
-
259
- } catch (error: any) {
260
- return { success: false, error: error.message }
261
- }
158
+ const authToken = await resolveGuestToken(token)
159
+ if (!authToken) return { success: false, error: "Unauthorized" }
160
+
161
+ try {
162
+ const options = await getStoreClientOptions()
163
+ const result = await medusaGuestOrderInvoice(orderId, authToken, options)
164
+ return { success: true, ...result }
165
+ } catch (error) {
166
+ return {
167
+ success: false,
168
+ error: error instanceof Error ? error.message : String(error),
169
+ }
170
+ }
262
171
  }
263
172
 
264
173
  export async function guestReorder(orderId: string, token?: string) {
265
- const authHeaders = await getGuestAuthHeaders()
266
- const authToken = token || (authHeaders as any).authorization?.split(" ")[1]
267
-
268
- if (!authToken) return { success: false, error: "Unauthorized" }
269
-
270
- const requestHeaders: Record<string, string> = {
271
- "Authorization": `Bearer ${authToken}`
272
- }
273
- if (PUBLISHABLE_KEY) requestHeaders["x-publishable-api-key"] = PUBLISHABLE_KEY
274
-
275
- try {
276
- const response = await fetch(`${BACKEND_URL}/store/guest-orders/${orderId}/reorder`, {
277
- method: "POST",
278
- headers: {
279
- "Content-Type": "application/json",
280
- ...requestHeaders
281
- },
282
- cache: "no-store",
283
- })
284
-
285
- if (!response.ok) {
286
- const errorData = await response.json().catch(() => ({}))
287
- throw new Error(errorData.message || "Failed to reorder")
288
- }
289
-
290
- const data = await response.json()
291
- return { success: true, data }
292
- } catch (error: any) {
293
- return { success: false, error: error.message }
294
- }
174
+ const authToken = await resolveGuestToken(token)
175
+ if (!authToken) return { success: false, error: "Unauthorized" }
176
+
177
+ try {
178
+ const options = await getStoreClientOptionsWithToken(authToken)
179
+ const result = await medusaGuestOrderReorder(orderId, options)
180
+ if (!result.ok) {
181
+ throw new Error(
182
+ typeof result.data.message === "string"
183
+ ? result.data.message
184
+ : "Failed to reorder"
185
+ )
186
+ }
187
+ return { success: true, data: result.data }
188
+ } catch (error) {
189
+ return {
190
+ success: false,
191
+ error: error instanceof Error ? error.message : String(error),
192
+ }
193
+ }
295
194
  }
296
195
 
297
- export async function createGuestReturn(orderId: string, items: { id: string, quantity: number }[], reason_id?: string, note?: string, token?: string) {
298
- const authHeaders = await getGuestAuthHeaders()
299
- const authToken = token || (authHeaders as any).authorization?.split(" ")[1]
300
-
301
- if (!authToken) return { success: false, error: "Unauthorized" }
302
-
303
- const requestHeaders: Record<string, string> = {
304
- "Authorization": `Bearer ${authToken}`
305
- }
306
- if (PUBLISHABLE_KEY) requestHeaders["x-publishable-api-key"] = PUBLISHABLE_KEY
307
-
308
- try {
309
- const response = await fetch(`${BACKEND_URL}/store/guest-orders/${orderId}/returns`, {
310
- method: "POST",
311
- headers: {
312
- "Content-Type": "application/json",
313
- ...requestHeaders
314
- },
315
- body: JSON.stringify({
316
- items,
317
- reason_id,
318
- note
319
- }),
320
- cache: "no-store",
321
- })
322
-
323
- if (!response.ok) {
324
- const errorData = await response.json().catch(() => ({}))
325
- throw new Error(errorData.message || "Failed to create return request")
326
- }
327
-
328
- const data = await response.json()
329
- return { success: true, data }
330
- } catch (error: any) {
331
- return { success: false, error: error.message }
332
- }
196
+ export async function createGuestReturn(
197
+ orderId: string,
198
+ items: GuestReturnItem[],
199
+ reason_id?: string,
200
+ note?: string,
201
+ token?: string
202
+ ) {
203
+ const authToken = await resolveGuestToken(token)
204
+ if (!authToken) return { success: false, error: "Unauthorized" }
205
+
206
+ try {
207
+ const options = await getStoreClientOptionsWithToken(authToken)
208
+ const data = await medusaReturnCreateGuest(orderId, { items, reason_id, note }, options)
209
+ return { success: true, data }
210
+ } catch (error) {
211
+ return {
212
+ success: false,
213
+ error: error instanceof Error ? error.message : String(error),
214
+ }
215
+ }
333
216
  }
@@ -0,0 +1,68 @@
1
+ "use server";
2
+
3
+ import { listCollections } from "./collections";
4
+ import { listCategories } from "./categories";
5
+ import { listProductsWithSort, getProductsByTag } from "./products";
6
+ import { getRegion } from "./regions";
7
+ import { getTestimonialsFromConfig } from "./dynamic-config";
8
+ import { fetchRatings } from "medusa-reviews-logic/server";
9
+
10
+ export type HomePageData = {
11
+ region: Awaited<ReturnType<typeof getRegion>>;
12
+ collections: Array<Record<string, unknown>>;
13
+ categories: unknown[];
14
+ newArrivals: unknown[];
15
+ bestsellers: unknown[];
16
+ testimonials: unknown | null;
17
+ ratings: unknown[];
18
+ };
19
+
20
+ /**
21
+ * Parallel home page data loader (replaces per-page Promise.all boilerplate).
22
+ */
23
+ export async function loadHomePageData(countryCode: string): Promise<HomePageData | null> {
24
+ const region = await getRegion(countryCode);
25
+ if (!region) return null;
26
+
27
+ const [
28
+ collectionsResult,
29
+ categoriesResult,
30
+ newArrivalsResult,
31
+ bestsellersResult,
32
+ testimonialsData,
33
+ allRatings,
34
+ ] = await Promise.all([
35
+ listCollections({ fields: "id, handle, title, metadata" }).catch(() => ({
36
+ collections: [],
37
+ })),
38
+ listCategories({ limit: 50 }).catch(() => []),
39
+ listProductsWithSort({
40
+ page: 1,
41
+ queryParams: { limit: 8 },
42
+ sortBy: "created_at",
43
+ countryCode,
44
+ }).catch(() => ({ response: { products: [] } })),
45
+ getProductsByTag({
46
+ tagValue: "bestseller",
47
+ limit: 10,
48
+ countryCode,
49
+ }).catch(() => []),
50
+ getTestimonialsFromConfig().catch(() => null),
51
+ fetchRatings(),
52
+ ]);
53
+
54
+ const collections =
55
+ (collectionsResult as { collections?: unknown[] }).collections ?? [];
56
+ const newArrivals =
57
+ (newArrivalsResult as { response?: { products?: unknown[] } }).response?.products ?? [];
58
+
59
+ return {
60
+ region,
61
+ collections: collections as Array<Record<string, unknown>>,
62
+ categories: categoriesResult ?? [],
63
+ newArrivals,
64
+ bestsellers: bestsellersResult ?? [],
65
+ testimonials: testimonialsData,
66
+ ratings: allRatings ?? [],
67
+ };
68
+ }
@@ -19,3 +19,4 @@ export * from "./returns"
19
19
  export * from "./swaps"
20
20
  export * from "./variants"
21
21
  export * from "./wishlist"
22
+ export * from "./home"