@rovela-ai/sdk 0.4.0 → 0.4.1

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 (976) hide show
  1. package/dist/checkout/server/create-checkout-session.d.ts +10 -1
  2. package/dist/checkout/server/create-checkout-session.d.ts.map +1 -1
  3. package/dist/checkout/server/create-checkout-session.js +28 -17
  4. package/dist/checkout/server/create-checkout-session.js.map +1 -1
  5. package/dist/checkout/server/handle-webhook.js +22 -2
  6. package/dist/checkout/server/handle-webhook.js.map +1 -1
  7. package/dist/checkout/server/order-service.d.ts +7 -1
  8. package/dist/checkout/server/order-service.d.ts.map +1 -1
  9. package/dist/checkout/server/order-service.js +59 -12
  10. package/dist/checkout/server/order-service.js.map +1 -1
  11. package/package.json +1 -1
  12. package/dist/admin/api/accept-invite.d.ts +0 -65
  13. package/dist/admin/api/accept-invite.d.ts.map +0 -1
  14. package/dist/admin/api/accept-invite.js +0 -115
  15. package/dist/admin/api/accept-invite.js.map +0 -1
  16. package/dist/admin/api/auth.d.ts +0 -32
  17. package/dist/admin/api/auth.d.ts.map +0 -1
  18. package/dist/admin/api/auth.js +0 -37
  19. package/dist/admin/api/auth.js.map +0 -1
  20. package/dist/admin/api/categories.d.ts +0 -68
  21. package/dist/admin/api/categories.d.ts.map +0 -1
  22. package/dist/admin/api/categories.js +0 -266
  23. package/dist/admin/api/categories.js.map +0 -1
  24. package/dist/admin/api/check.d.ts +0 -38
  25. package/dist/admin/api/check.d.ts.map +0 -1
  26. package/dist/admin/api/check.js +0 -49
  27. package/dist/admin/api/check.js.map +0 -1
  28. package/dist/admin/api/customers.d.ts +0 -77
  29. package/dist/admin/api/customers.d.ts.map +0 -1
  30. package/dist/admin/api/customers.js +0 -219
  31. package/dist/admin/api/customers.js.map +0 -1
  32. package/dist/admin/api/forgot-password.d.ts +0 -39
  33. package/dist/admin/api/forgot-password.d.ts.map +0 -1
  34. package/dist/admin/api/forgot-password.js +0 -66
  35. package/dist/admin/api/forgot-password.js.map +0 -1
  36. package/dist/admin/api/index.d.ts +0 -109
  37. package/dist/admin/api/index.d.ts.map +0 -1
  38. package/dist/admin/api/index.js +0 -128
  39. package/dist/admin/api/index.js.map +0 -1
  40. package/dist/admin/api/linked-customer.d.ts +0 -32
  41. package/dist/admin/api/linked-customer.d.ts.map +0 -1
  42. package/dist/admin/api/linked-customer.js +0 -45
  43. package/dist/admin/api/linked-customer.js.map +0 -1
  44. package/dist/admin/api/me.d.ts +0 -72
  45. package/dist/admin/api/me.d.ts.map +0 -1
  46. package/dist/admin/api/me.js +0 -177
  47. package/dist/admin/api/me.js.map +0 -1
  48. package/dist/admin/api/orders.d.ts +0 -91
  49. package/dist/admin/api/orders.d.ts.map +0 -1
  50. package/dist/admin/api/orders.js +0 -390
  51. package/dist/admin/api/orders.js.map +0 -1
  52. package/dist/admin/api/products-bulk.d.ts +0 -38
  53. package/dist/admin/api/products-bulk.d.ts.map +0 -1
  54. package/dist/admin/api/products-bulk.js +0 -135
  55. package/dist/admin/api/products-bulk.js.map +0 -1
  56. package/dist/admin/api/products-stats.d.ts +0 -34
  57. package/dist/admin/api/products-stats.d.ts.map +0 -1
  58. package/dist/admin/api/products-stats.js +0 -43
  59. package/dist/admin/api/products-stats.js.map +0 -1
  60. package/dist/admin/api/products.d.ts +0 -104
  61. package/dist/admin/api/products.d.ts.map +0 -1
  62. package/dist/admin/api/products.js +0 -491
  63. package/dist/admin/api/products.js.map +0 -1
  64. package/dist/admin/api/refund.d.ts +0 -29
  65. package/dist/admin/api/refund.d.ts.map +0 -1
  66. package/dist/admin/api/refund.js +0 -142
  67. package/dist/admin/api/refund.js.map +0 -1
  68. package/dist/admin/api/reset-password.d.ts +0 -49
  69. package/dist/admin/api/reset-password.d.ts.map +0 -1
  70. package/dist/admin/api/reset-password.js +0 -99
  71. package/dist/admin/api/reset-password.js.map +0 -1
  72. package/dist/admin/api/return.d.ts +0 -47
  73. package/dist/admin/api/return.d.ts.map +0 -1
  74. package/dist/admin/api/return.js +0 -186
  75. package/dist/admin/api/return.js.map +0 -1
  76. package/dist/admin/api/settings.d.ts +0 -49
  77. package/dist/admin/api/settings.d.ts.map +0 -1
  78. package/dist/admin/api/settings.js +0 -201
  79. package/dist/admin/api/settings.js.map +0 -1
  80. package/dist/admin/api/setup-guide.d.ts +0 -78
  81. package/dist/admin/api/setup-guide.d.ts.map +0 -1
  82. package/dist/admin/api/setup-guide.js +0 -235
  83. package/dist/admin/api/setup-guide.js.map +0 -1
  84. package/dist/admin/api/setup.d.ts +0 -60
  85. package/dist/admin/api/setup.d.ts.map +0 -1
  86. package/dist/admin/api/setup.js +0 -126
  87. package/dist/admin/api/setup.js.map +0 -1
  88. package/dist/admin/api/shipping.d.ts +0 -287
  89. package/dist/admin/api/shipping.d.ts.map +0 -1
  90. package/dist/admin/api/shipping.js +0 -746
  91. package/dist/admin/api/shipping.js.map +0 -1
  92. package/dist/admin/api/stats.d.ts +0 -43
  93. package/dist/admin/api/stats.d.ts.map +0 -1
  94. package/dist/admin/api/stats.js +0 -92
  95. package/dist/admin/api/stats.js.map +0 -1
  96. package/dist/admin/api/stripe-status.d.ts +0 -39
  97. package/dist/admin/api/stripe-status.d.ts.map +0 -1
  98. package/dist/admin/api/stripe-status.js +0 -99
  99. package/dist/admin/api/stripe-status.js.map +0 -1
  100. package/dist/admin/api/tax-zones.d.ts +0 -97
  101. package/dist/admin/api/tax-zones.d.ts.map +0 -1
  102. package/dist/admin/api/tax-zones.js +0 -265
  103. package/dist/admin/api/tax-zones.js.map +0 -1
  104. package/dist/admin/api/users.d.ts +0 -142
  105. package/dist/admin/api/users.d.ts.map +0 -1
  106. package/dist/admin/api/users.js +0 -355
  107. package/dist/admin/api/users.js.map +0 -1
  108. package/dist/admin/components/AdminAcceptInviteForm.d.ts +0 -3
  109. package/dist/admin/components/AdminAcceptInviteForm.d.ts.map +0 -1
  110. package/dist/admin/components/AdminAcceptInviteForm.js +0 -137
  111. package/dist/admin/components/AdminAcceptInviteForm.js.map +0 -1
  112. package/dist/admin/components/AdminAccountPage.d.ts +0 -10
  113. package/dist/admin/components/AdminAccountPage.d.ts.map +0 -1
  114. package/dist/admin/components/AdminAccountPage.js +0 -126
  115. package/dist/admin/components/AdminAccountPage.js.map +0 -1
  116. package/dist/admin/components/AdminBarBanner.d.ts +0 -2
  117. package/dist/admin/components/AdminBarBanner.d.ts.map +0 -1
  118. package/dist/admin/components/AdminBarBanner.js +0 -266
  119. package/dist/admin/components/AdminBarBanner.js.map +0 -1
  120. package/dist/admin/components/AdminForgotPasswordForm.d.ts +0 -8
  121. package/dist/admin/components/AdminForgotPasswordForm.d.ts.map +0 -1
  122. package/dist/admin/components/AdminForgotPasswordForm.js +0 -59
  123. package/dist/admin/components/AdminForgotPasswordForm.js.map +0 -1
  124. package/dist/admin/components/AdminGuard.d.ts +0 -40
  125. package/dist/admin/components/AdminGuard.d.ts.map +0 -1
  126. package/dist/admin/components/AdminGuard.js +0 -94
  127. package/dist/admin/components/AdminGuard.js.map +0 -1
  128. package/dist/admin/components/AdminLayout.d.ts +0 -40
  129. package/dist/admin/components/AdminLayout.d.ts.map +0 -1
  130. package/dist/admin/components/AdminLayout.js +0 -39
  131. package/dist/admin/components/AdminLayout.js.map +0 -1
  132. package/dist/admin/components/AdminLoginForm.d.ts +0 -18
  133. package/dist/admin/components/AdminLoginForm.d.ts.map +0 -1
  134. package/dist/admin/components/AdminLoginForm.js +0 -61
  135. package/dist/admin/components/AdminLoginForm.js.map +0 -1
  136. package/dist/admin/components/AdminNav.d.ts +0 -44
  137. package/dist/admin/components/AdminNav.d.ts.map +0 -1
  138. package/dist/admin/components/AdminNav.js +0 -175
  139. package/dist/admin/components/AdminNav.js.map +0 -1
  140. package/dist/admin/components/AdminResetPasswordForm.d.ts +0 -12
  141. package/dist/admin/components/AdminResetPasswordForm.d.ts.map +0 -1
  142. package/dist/admin/components/AdminResetPasswordForm.js +0 -134
  143. package/dist/admin/components/AdminResetPasswordForm.js.map +0 -1
  144. package/dist/admin/components/AdminSelect.d.ts +0 -47
  145. package/dist/admin/components/AdminSelect.d.ts.map +0 -1
  146. package/dist/admin/components/AdminSelect.js +0 -71
  147. package/dist/admin/components/AdminSelect.js.map +0 -1
  148. package/dist/admin/components/AdminSetupForm.d.ts +0 -28
  149. package/dist/admin/components/AdminSetupForm.d.ts.map +0 -1
  150. package/dist/admin/components/AdminSetupForm.js +0 -85
  151. package/dist/admin/components/AdminSetupForm.js.map +0 -1
  152. package/dist/admin/components/AdminToast.d.ts +0 -31
  153. package/dist/admin/components/AdminToast.d.ts.map +0 -1
  154. package/dist/admin/components/AdminToast.js +0 -83
  155. package/dist/admin/components/AdminToast.js.map +0 -1
  156. package/dist/admin/components/AdminUserMenu.d.ts +0 -14
  157. package/dist/admin/components/AdminUserMenu.d.ts.map +0 -1
  158. package/dist/admin/components/AdminUserMenu.js +0 -34
  159. package/dist/admin/components/AdminUserMenu.js.map +0 -1
  160. package/dist/admin/components/CategoryForm.d.ts +0 -30
  161. package/dist/admin/components/CategoryForm.d.ts.map +0 -1
  162. package/dist/admin/components/CategoryForm.js +0 -152
  163. package/dist/admin/components/CategoryForm.js.map +0 -1
  164. package/dist/admin/components/CategorySelect.d.ts +0 -32
  165. package/dist/admin/components/CategorySelect.d.ts.map +0 -1
  166. package/dist/admin/components/CategorySelect.js +0 -139
  167. package/dist/admin/components/CategorySelect.js.map +0 -1
  168. package/dist/admin/components/CustomerDetails.d.ts +0 -15
  169. package/dist/admin/components/CustomerDetails.d.ts.map +0 -1
  170. package/dist/admin/components/CustomerDetails.js +0 -177
  171. package/dist/admin/components/CustomerDetails.js.map +0 -1
  172. package/dist/admin/components/CustomerTable.d.ts +0 -13
  173. package/dist/admin/components/CustomerTable.d.ts.map +0 -1
  174. package/dist/admin/components/CustomerTable.js +0 -112
  175. package/dist/admin/components/CustomerTable.js.map +0 -1
  176. package/dist/admin/components/DeleteConfirmDialog.d.ts +0 -56
  177. package/dist/admin/components/DeleteConfirmDialog.d.ts.map +0 -1
  178. package/dist/admin/components/DeleteConfirmDialog.js +0 -46
  179. package/dist/admin/components/DeleteConfirmDialog.js.map +0 -1
  180. package/dist/admin/components/ExampleContentBanner.d.ts +0 -2
  181. package/dist/admin/components/ExampleContentBanner.d.ts.map +0 -1
  182. package/dist/admin/components/ExampleContentBanner.js +0 -153
  183. package/dist/admin/components/ExampleContentBanner.js.map +0 -1
  184. package/dist/admin/components/InventoryEditor.d.ts +0 -15
  185. package/dist/admin/components/InventoryEditor.d.ts.map +0 -1
  186. package/dist/admin/components/InventoryEditor.js +0 -86
  187. package/dist/admin/components/InventoryEditor.js.map +0 -1
  188. package/dist/admin/components/InviteUserDialog.d.ts +0 -3
  189. package/dist/admin/components/InviteUserDialog.d.ts.map +0 -1
  190. package/dist/admin/components/InviteUserDialog.js +0 -126
  191. package/dist/admin/components/InviteUserDialog.js.map +0 -1
  192. package/dist/admin/components/LogoUpload.d.ts +0 -22
  193. package/dist/admin/components/LogoUpload.d.ts.map +0 -1
  194. package/dist/admin/components/LogoUpload.js +0 -210
  195. package/dist/admin/components/LogoUpload.js.map +0 -1
  196. package/dist/admin/components/LowStockAlert.d.ts +0 -11
  197. package/dist/admin/components/LowStockAlert.d.ts.map +0 -1
  198. package/dist/admin/components/LowStockAlert.js +0 -33
  199. package/dist/admin/components/LowStockAlert.js.map +0 -1
  200. package/dist/admin/components/OrderDetails.d.ts +0 -14
  201. package/dist/admin/components/OrderDetails.d.ts.map +0 -1
  202. package/dist/admin/components/OrderDetails.js +0 -210
  203. package/dist/admin/components/OrderDetails.js.map +0 -1
  204. package/dist/admin/components/OrderStatusChart.d.ts +0 -21
  205. package/dist/admin/components/OrderStatusChart.d.ts.map +0 -1
  206. package/dist/admin/components/OrderStatusChart.js +0 -61
  207. package/dist/admin/components/OrderStatusChart.js.map +0 -1
  208. package/dist/admin/components/OrderTable.d.ts +0 -13
  209. package/dist/admin/components/OrderTable.d.ts.map +0 -1
  210. package/dist/admin/components/OrderTable.js +0 -117
  211. package/dist/admin/components/OrderTable.js.map +0 -1
  212. package/dist/admin/components/PaymentSettings.d.ts +0 -13
  213. package/dist/admin/components/PaymentSettings.d.ts.map +0 -1
  214. package/dist/admin/components/PaymentSettings.js +0 -117
  215. package/dist/admin/components/PaymentSettings.js.map +0 -1
  216. package/dist/admin/components/PeriodSelector.d.ts +0 -9
  217. package/dist/admin/components/PeriodSelector.d.ts.map +0 -1
  218. package/dist/admin/components/PeriodSelector.js +0 -19
  219. package/dist/admin/components/PeriodSelector.js.map +0 -1
  220. package/dist/admin/components/PermissionsMatrix.d.ts +0 -8
  221. package/dist/admin/components/PermissionsMatrix.d.ts.map +0 -1
  222. package/dist/admin/components/PermissionsMatrix.js +0 -70
  223. package/dist/admin/components/PermissionsMatrix.js.map +0 -1
  224. package/dist/admin/components/PrimaryMetricsRow.d.ts +0 -11
  225. package/dist/admin/components/PrimaryMetricsRow.d.ts.map +0 -1
  226. package/dist/admin/components/PrimaryMetricsRow.js +0 -73
  227. package/dist/admin/components/PrimaryMetricsRow.js.map +0 -1
  228. package/dist/admin/components/ProductForm.d.ts +0 -18
  229. package/dist/admin/components/ProductForm.d.ts.map +0 -1
  230. package/dist/admin/components/ProductForm.js +0 -251
  231. package/dist/admin/components/ProductForm.js.map +0 -1
  232. package/dist/admin/components/ProductTable.d.ts +0 -14
  233. package/dist/admin/components/ProductTable.d.ts.map +0 -1
  234. package/dist/admin/components/ProductTable.js +0 -384
  235. package/dist/admin/components/ProductTable.js.map +0 -1
  236. package/dist/admin/components/RecentOrders.d.ts +0 -11
  237. package/dist/admin/components/RecentOrders.d.ts.map +0 -1
  238. package/dist/admin/components/RecentOrders.js +0 -63
  239. package/dist/admin/components/RecentOrders.js.map +0 -1
  240. package/dist/admin/components/RefundDialog.d.ts +0 -17
  241. package/dist/admin/components/RefundDialog.d.ts.map +0 -1
  242. package/dist/admin/components/RefundDialog.js +0 -90
  243. package/dist/admin/components/RefundDialog.js.map +0 -1
  244. package/dist/admin/components/RevenueChart.d.ts +0 -23
  245. package/dist/admin/components/RevenueChart.d.ts.map +0 -1
  246. package/dist/admin/components/RevenueChart.js +0 -75
  247. package/dist/admin/components/RevenueChart.js.map +0 -1
  248. package/dist/admin/components/SEOPreview.d.ts +0 -33
  249. package/dist/admin/components/SEOPreview.d.ts.map +0 -1
  250. package/dist/admin/components/SEOPreview.js +0 -30
  251. package/dist/admin/components/SEOPreview.js.map +0 -1
  252. package/dist/admin/components/SecondaryMetricsRow.d.ts +0 -14
  253. package/dist/admin/components/SecondaryMetricsRow.d.ts.map +0 -1
  254. package/dist/admin/components/SecondaryMetricsRow.js +0 -45
  255. package/dist/admin/components/SecondaryMetricsRow.js.map +0 -1
  256. package/dist/admin/components/SetupGuide.d.ts +0 -4
  257. package/dist/admin/components/SetupGuide.d.ts.map +0 -1
  258. package/dist/admin/components/SetupGuide.js +0 -244
  259. package/dist/admin/components/SetupGuide.js.map +0 -1
  260. package/dist/admin/components/ShippingSettings.d.ts +0 -3
  261. package/dist/admin/components/ShippingSettings.d.ts.map +0 -1
  262. package/dist/admin/components/ShippingSettings.js +0 -553
  263. package/dist/admin/components/ShippingSettings.js.map +0 -1
  264. package/dist/admin/components/StatsCards.d.ts +0 -18
  265. package/dist/admin/components/StatsCards.d.ts.map +0 -1
  266. package/dist/admin/components/StatsCards.js +0 -71
  267. package/dist/admin/components/StatsCards.js.map +0 -1
  268. package/dist/admin/components/StoreSettings.d.ts +0 -19
  269. package/dist/admin/components/StoreSettings.d.ts.map +0 -1
  270. package/dist/admin/components/StoreSettings.js +0 -149
  271. package/dist/admin/components/StoreSettings.js.map +0 -1
  272. package/dist/admin/components/TagInput.d.ts +0 -29
  273. package/dist/admin/components/TagInput.d.ts.map +0 -1
  274. package/dist/admin/components/TagInput.js +0 -69
  275. package/dist/admin/components/TagInput.js.map +0 -1
  276. package/dist/admin/components/TaxSettings.d.ts +0 -12
  277. package/dist/admin/components/TaxSettings.d.ts.map +0 -1
  278. package/dist/admin/components/TaxSettings.js +0 -272
  279. package/dist/admin/components/TaxSettings.js.map +0 -1
  280. package/dist/admin/components/UsersTable.d.ts +0 -3
  281. package/dist/admin/components/UsersTable.d.ts.map +0 -1
  282. package/dist/admin/components/UsersTable.js +0 -388
  283. package/dist/admin/components/UsersTable.js.map +0 -1
  284. package/dist/admin/components/VariantManager.d.ts +0 -44
  285. package/dist/admin/components/VariantManager.d.ts.map +0 -1
  286. package/dist/admin/components/VariantManager.js +0 -324
  287. package/dist/admin/components/VariantManager.js.map +0 -1
  288. package/dist/admin/components/index.d.ts +0 -69
  289. package/dist/admin/components/index.d.ts.map +0 -1
  290. package/dist/admin/components/index.js +0 -86
  291. package/dist/admin/components/index.js.map +0 -1
  292. package/dist/admin/config.d.ts +0 -51
  293. package/dist/admin/config.d.ts.map +0 -1
  294. package/dist/admin/config.js +0 -224
  295. package/dist/admin/config.js.map +0 -1
  296. package/dist/admin/hooks/fetchAdminApi.d.ts +0 -65
  297. package/dist/admin/hooks/fetchAdminApi.d.ts.map +0 -1
  298. package/dist/admin/hooks/fetchAdminApi.js +0 -96
  299. package/dist/admin/hooks/fetchAdminApi.js.map +0 -1
  300. package/dist/admin/hooks/index.d.ts +0 -24
  301. package/dist/admin/hooks/index.d.ts.map +0 -1
  302. package/dist/admin/hooks/index.js +0 -19
  303. package/dist/admin/hooks/index.js.map +0 -1
  304. package/dist/admin/hooks/useAdminAuth.d.ts +0 -25
  305. package/dist/admin/hooks/useAdminAuth.d.ts.map +0 -1
  306. package/dist/admin/hooks/useAdminAuth.js +0 -183
  307. package/dist/admin/hooks/useAdminAuth.js.map +0 -1
  308. package/dist/admin/hooks/useAdminCategories.d.ts +0 -9
  309. package/dist/admin/hooks/useAdminCategories.d.ts.map +0 -1
  310. package/dist/admin/hooks/useAdminCategories.js +0 -112
  311. package/dist/admin/hooks/useAdminCategories.js.map +0 -1
  312. package/dist/admin/hooks/useAdminCustomers.d.ts +0 -3
  313. package/dist/admin/hooks/useAdminCustomers.d.ts.map +0 -1
  314. package/dist/admin/hooks/useAdminCustomers.js +0 -110
  315. package/dist/admin/hooks/useAdminCustomers.js.map +0 -1
  316. package/dist/admin/hooks/useAdminMe.d.ts +0 -31
  317. package/dist/admin/hooks/useAdminMe.d.ts.map +0 -1
  318. package/dist/admin/hooks/useAdminMe.js +0 -78
  319. package/dist/admin/hooks/useAdminMe.js.map +0 -1
  320. package/dist/admin/hooks/useAdminOrders.d.ts +0 -3
  321. package/dist/admin/hooks/useAdminOrders.d.ts.map +0 -1
  322. package/dist/admin/hooks/useAdminOrders.js +0 -118
  323. package/dist/admin/hooks/useAdminOrders.js.map +0 -1
  324. package/dist/admin/hooks/useAdminPermissions.d.ts +0 -3
  325. package/dist/admin/hooks/useAdminPermissions.d.ts.map +0 -1
  326. package/dist/admin/hooks/useAdminPermissions.js +0 -51
  327. package/dist/admin/hooks/useAdminPermissions.js.map +0 -1
  328. package/dist/admin/hooks/useAdminProductMetrics.d.ts +0 -3
  329. package/dist/admin/hooks/useAdminProductMetrics.d.ts.map +0 -1
  330. package/dist/admin/hooks/useAdminProductMetrics.js +0 -32
  331. package/dist/admin/hooks/useAdminProductMetrics.js.map +0 -1
  332. package/dist/admin/hooks/useAdminProducts.d.ts +0 -3
  333. package/dist/admin/hooks/useAdminProducts.d.ts.map +0 -1
  334. package/dist/admin/hooks/useAdminProducts.js +0 -132
  335. package/dist/admin/hooks/useAdminProducts.js.map +0 -1
  336. package/dist/admin/hooks/useAdminSession.d.ts +0 -23
  337. package/dist/admin/hooks/useAdminSession.d.ts.map +0 -1
  338. package/dist/admin/hooks/useAdminSession.js +0 -117
  339. package/dist/admin/hooks/useAdminSession.js.map +0 -1
  340. package/dist/admin/hooks/useAdminStats.d.ts +0 -47
  341. package/dist/admin/hooks/useAdminStats.d.ts.map +0 -1
  342. package/dist/admin/hooks/useAdminStats.js +0 -128
  343. package/dist/admin/hooks/useAdminStats.js.map +0 -1
  344. package/dist/admin/hooks/useAdminUsers.d.ts +0 -3
  345. package/dist/admin/hooks/useAdminUsers.d.ts.map +0 -1
  346. package/dist/admin/hooks/useAdminUsers.js +0 -177
  347. package/dist/admin/hooks/useAdminUsers.js.map +0 -1
  348. package/dist/admin/hooks/useLinkedCustomerStatus.d.ts +0 -3
  349. package/dist/admin/hooks/useLinkedCustomerStatus.d.ts.map +0 -1
  350. package/dist/admin/hooks/useLinkedCustomerStatus.js +0 -48
  351. package/dist/admin/hooks/useLinkedCustomerStatus.js.map +0 -1
  352. package/dist/admin/hooks/useSetupGuide.d.ts +0 -45
  353. package/dist/admin/hooks/useSetupGuide.d.ts.map +0 -1
  354. package/dist/admin/hooks/useSetupGuide.js +0 -60
  355. package/dist/admin/hooks/useSetupGuide.js.map +0 -1
  356. package/dist/admin/index.d.ts +0 -66
  357. package/dist/admin/index.d.ts.map +0 -1
  358. package/dist/admin/index.js +0 -144
  359. package/dist/admin/index.js.map +0 -1
  360. package/dist/admin/permissions.d.ts +0 -79
  361. package/dist/admin/permissions.d.ts.map +0 -1
  362. package/dist/admin/permissions.js +0 -182
  363. package/dist/admin/permissions.js.map +0 -1
  364. package/dist/admin/server/admin-invite.d.ts +0 -122
  365. package/dist/admin/server/admin-invite.d.ts.map +0 -1
  366. package/dist/admin/server/admin-invite.js +0 -235
  367. package/dist/admin/server/admin-invite.js.map +0 -1
  368. package/dist/admin/server/admin-password-reset.d.ts +0 -87
  369. package/dist/admin/server/admin-password-reset.d.ts.map +0 -1
  370. package/dist/admin/server/admin-password-reset.js +0 -220
  371. package/dist/admin/server/admin-password-reset.js.map +0 -1
  372. package/dist/admin/server/admin-self-service.d.ts +0 -86
  373. package/dist/admin/server/admin-self-service.d.ts.map +0 -1
  374. package/dist/admin/server/admin-self-service.js +0 -188
  375. package/dist/admin/server/admin-self-service.js.map +0 -1
  376. package/dist/admin/server/admin-service.d.ts +0 -131
  377. package/dist/admin/server/admin-service.d.ts.map +0 -1
  378. package/dist/admin/server/admin-service.js +0 -278
  379. package/dist/admin/server/admin-service.js.map +0 -1
  380. package/dist/admin/server/admin-session.d.ts +0 -173
  381. package/dist/admin/server/admin-session.d.ts.map +0 -1
  382. package/dist/admin/server/admin-session.js +0 -272
  383. package/dist/admin/server/admin-session.js.map +0 -1
  384. package/dist/admin/server/index.d.ts +0 -17
  385. package/dist/admin/server/index.d.ts.map +0 -1
  386. package/dist/admin/server/index.js +0 -39
  387. package/dist/admin/server/index.js.map +0 -1
  388. package/dist/admin/server/user-management.d.ts +0 -221
  389. package/dist/admin/server/user-management.d.ts.map +0 -1
  390. package/dist/admin/server/user-management.js +0 -838
  391. package/dist/admin/server/user-management.js.map +0 -1
  392. package/dist/admin/types.d.ts +0 -1161
  393. package/dist/admin/types.d.ts.map +0 -1
  394. package/dist/admin/types.js +0 -10
  395. package/dist/admin/types.js.map +0 -1
  396. package/dist/auth/api/auth.d.ts +0 -9
  397. package/dist/auth/api/auth.d.ts.map +0 -1
  398. package/dist/auth/api/auth.js +0 -9
  399. package/dist/auth/api/auth.js.map +0 -1
  400. package/dist/auth/api/forgot-password.d.ts +0 -41
  401. package/dist/auth/api/forgot-password.d.ts.map +0 -1
  402. package/dist/auth/api/forgot-password.js +0 -65
  403. package/dist/auth/api/forgot-password.js.map +0 -1
  404. package/dist/auth/api/index.d.ts +0 -37
  405. package/dist/auth/api/index.d.ts.map +0 -1
  406. package/dist/auth/api/index.js +0 -44
  407. package/dist/auth/api/index.js.map +0 -1
  408. package/dist/auth/api/register.d.ts +0 -41
  409. package/dist/auth/api/register.d.ts.map +0 -1
  410. package/dist/auth/api/register.js +0 -99
  411. package/dist/auth/api/register.js.map +0 -1
  412. package/dist/auth/api/request-refund.d.ts +0 -38
  413. package/dist/auth/api/request-refund.d.ts.map +0 -1
  414. package/dist/auth/api/request-refund.js +0 -142
  415. package/dist/auth/api/request-refund.js.map +0 -1
  416. package/dist/auth/api/request-return.d.ts +0 -39
  417. package/dist/auth/api/request-return.d.ts.map +0 -1
  418. package/dist/auth/api/request-return.js +0 -109
  419. package/dist/auth/api/request-return.js.map +0 -1
  420. package/dist/auth/api/resend-verification.d.ts +0 -41
  421. package/dist/auth/api/resend-verification.d.ts.map +0 -1
  422. package/dist/auth/api/resend-verification.js +0 -68
  423. package/dist/auth/api/resend-verification.js.map +0 -1
  424. package/dist/auth/api/reset-password.d.ts +0 -67
  425. package/dist/auth/api/reset-password.d.ts.map +0 -1
  426. package/dist/auth/api/reset-password.js +0 -106
  427. package/dist/auth/api/reset-password.js.map +0 -1
  428. package/dist/auth/api/verify-email.d.ts +0 -47
  429. package/dist/auth/api/verify-email.d.ts.map +0 -1
  430. package/dist/auth/api/verify-email.js +0 -90
  431. package/dist/auth/api/verify-email.js.map +0 -1
  432. package/dist/auth/components/AuthGuard.d.ts +0 -52
  433. package/dist/auth/components/AuthGuard.d.ts.map +0 -1
  434. package/dist/auth/components/AuthGuard.js +0 -109
  435. package/dist/auth/components/AuthGuard.js.map +0 -1
  436. package/dist/auth/components/ForgotPasswordForm.d.ts +0 -15
  437. package/dist/auth/components/ForgotPasswordForm.d.ts.map +0 -1
  438. package/dist/auth/components/ForgotPasswordForm.js +0 -43
  439. package/dist/auth/components/ForgotPasswordForm.js.map +0 -1
  440. package/dist/auth/components/Label.d.ts +0 -19
  441. package/dist/auth/components/Label.d.ts.map +0 -1
  442. package/dist/auth/components/Label.js +0 -18
  443. package/dist/auth/components/Label.js.map +0 -1
  444. package/dist/auth/components/ResetPasswordForm.d.ts +0 -18
  445. package/dist/auth/components/ResetPasswordForm.d.ts.map +0 -1
  446. package/dist/auth/components/ResetPasswordForm.js +0 -87
  447. package/dist/auth/components/ResetPasswordForm.js.map +0 -1
  448. package/dist/auth/components/SignInForm.d.ts +0 -21
  449. package/dist/auth/components/SignInForm.d.ts.map +0 -1
  450. package/dist/auth/components/SignInForm.js +0 -61
  451. package/dist/auth/components/SignInForm.js.map +0 -1
  452. package/dist/auth/components/SignUpForm.d.ts +0 -18
  453. package/dist/auth/components/SignUpForm.d.ts.map +0 -1
  454. package/dist/auth/components/SignUpForm.js +0 -78
  455. package/dist/auth/components/SignUpForm.js.map +0 -1
  456. package/dist/auth/components/UserMenu.d.ts +0 -18
  457. package/dist/auth/components/UserMenu.d.ts.map +0 -1
  458. package/dist/auth/components/UserMenu.js +0 -73
  459. package/dist/auth/components/UserMenu.js.map +0 -1
  460. package/dist/auth/components/VerifyEmailNotice.d.ts +0 -20
  461. package/dist/auth/components/VerifyEmailNotice.d.ts.map +0 -1
  462. package/dist/auth/components/VerifyEmailNotice.js +0 -57
  463. package/dist/auth/components/VerifyEmailNotice.js.map +0 -1
  464. package/dist/auth/components/index.d.ts +0 -15
  465. package/dist/auth/components/index.d.ts.map +0 -1
  466. package/dist/auth/components/index.js +0 -14
  467. package/dist/auth/components/index.js.map +0 -1
  468. package/dist/auth/config.d.ts +0 -52
  469. package/dist/auth/config.d.ts.map +0 -1
  470. package/dist/auth/config.js +0 -243
  471. package/dist/auth/config.js.map +0 -1
  472. package/dist/auth/hooks/index.d.ts +0 -7
  473. package/dist/auth/hooks/index.d.ts.map +0 -1
  474. package/dist/auth/hooks/index.js +0 -7
  475. package/dist/auth/hooks/index.js.map +0 -1
  476. package/dist/auth/hooks/useAuth.d.ts +0 -30
  477. package/dist/auth/hooks/useAuth.d.ts.map +0 -1
  478. package/dist/auth/hooks/useAuth.js +0 -251
  479. package/dist/auth/hooks/useAuth.js.map +0 -1
  480. package/dist/auth/index.d.ts +0 -55
  481. package/dist/auth/index.d.ts.map +0 -1
  482. package/dist/auth/index.js +0 -67
  483. package/dist/auth/index.js.map +0 -1
  484. package/dist/auth/server/customer-service.d.ts +0 -140
  485. package/dist/auth/server/customer-service.d.ts.map +0 -1
  486. package/dist/auth/server/customer-service.js +0 -266
  487. package/dist/auth/server/customer-service.js.map +0 -1
  488. package/dist/auth/server/customer-session.d.ts +0 -79
  489. package/dist/auth/server/customer-session.d.ts.map +0 -1
  490. package/dist/auth/server/customer-session.js +0 -103
  491. package/dist/auth/server/customer-session.js.map +0 -1
  492. package/dist/auth/server/email-sender.d.ts +0 -64
  493. package/dist/auth/server/email-sender.d.ts.map +0 -1
  494. package/dist/auth/server/email-sender.js +0 -106
  495. package/dist/auth/server/email-sender.js.map +0 -1
  496. package/dist/auth/server/index.d.ts +0 -14
  497. package/dist/auth/server/index.d.ts.map +0 -1
  498. package/dist/auth/server/index.js +0 -17
  499. package/dist/auth/server/index.js.map +0 -1
  500. package/dist/auth/server/password-reset-service.d.ts +0 -87
  501. package/dist/auth/server/password-reset-service.d.ts.map +0 -1
  502. package/dist/auth/server/password-reset-service.js +0 -203
  503. package/dist/auth/server/password-reset-service.js.map +0 -1
  504. package/dist/auth/server/password.d.ts +0 -58
  505. package/dist/auth/server/password.d.ts.map +0 -1
  506. package/dist/auth/server/password.js +0 -85
  507. package/dist/auth/server/password.js.map +0 -1
  508. package/dist/auth/server/verification-service.d.ts +0 -88
  509. package/dist/auth/server/verification-service.d.ts.map +0 -1
  510. package/dist/auth/server/verification-service.js +0 -231
  511. package/dist/auth/server/verification-service.js.map +0 -1
  512. package/dist/auth/types.d.ts +0 -311
  513. package/dist/auth/types.d.ts.map +0 -1
  514. package/dist/auth/types.js +0 -7
  515. package/dist/auth/types.js.map +0 -1
  516. package/dist/cart/CartProvider.d.ts +0 -65
  517. package/dist/cart/CartProvider.d.ts.map +0 -1
  518. package/dist/cart/CartProvider.js +0 -96
  519. package/dist/cart/CartProvider.js.map +0 -1
  520. package/dist/cart/components/AddToCartButton.d.ts +0 -77
  521. package/dist/cart/components/AddToCartButton.d.ts.map +0 -1
  522. package/dist/cart/components/AddToCartButton.js +0 -122
  523. package/dist/cart/components/AddToCartButton.js.map +0 -1
  524. package/dist/cart/components/CartDrawer.d.ts +0 -71
  525. package/dist/cart/components/CartDrawer.d.ts.map +0 -1
  526. package/dist/cart/components/CartDrawer.js +0 -117
  527. package/dist/cart/components/CartDrawer.js.map +0 -1
  528. package/dist/cart/components/CartIcon.d.ts +0 -36
  529. package/dist/cart/components/CartIcon.d.ts.map +0 -1
  530. package/dist/cart/components/CartIcon.js +0 -68
  531. package/dist/cart/components/CartIcon.js.map +0 -1
  532. package/dist/cart/components/CartItem.d.ts +0 -52
  533. package/dist/cart/components/CartItem.d.ts.map +0 -1
  534. package/dist/cart/components/CartItem.js +0 -55
  535. package/dist/cart/components/CartItem.js.map +0 -1
  536. package/dist/cart/components/CartSummary.d.ts +0 -43
  537. package/dist/cart/components/CartSummary.d.ts.map +0 -1
  538. package/dist/cart/components/CartSummary.js +0 -60
  539. package/dist/cart/components/CartSummary.js.map +0 -1
  540. package/dist/cart/components/QuantitySelector.d.ts +0 -39
  541. package/dist/cart/components/QuantitySelector.d.ts.map +0 -1
  542. package/dist/cart/components/QuantitySelector.js +0 -85
  543. package/dist/cart/components/QuantitySelector.js.map +0 -1
  544. package/dist/cart/components/index.d.ts +0 -18
  545. package/dist/cart/components/index.d.ts.map +0 -1
  546. package/dist/cart/components/index.js +0 -12
  547. package/dist/cart/components/index.js.map +0 -1
  548. package/dist/cart/index.d.ts +0 -109
  549. package/dist/cart/index.d.ts.map +0 -1
  550. package/dist/cart/index.js +0 -115
  551. package/dist/cart/index.js.map +0 -1
  552. package/dist/cart/store.d.ts +0 -150
  553. package/dist/cart/store.d.ts.map +0 -1
  554. package/dist/cart/store.js +0 -315
  555. package/dist/cart/store.js.map +0 -1
  556. package/dist/checkout/api/checkout.js +0 -112
  557. package/dist/checkout/api/checkout.js.map +0 -1
  558. package/dist/checkout/api/countries.d.ts +0 -17
  559. package/dist/checkout/api/countries.d.ts.map +0 -1
  560. package/dist/checkout/api/countries.js +0 -38
  561. package/dist/checkout/api/countries.js.map +0 -1
  562. package/dist/checkout/api/index.js +0 -11
  563. package/dist/checkout/api/index.js.map +0 -1
  564. package/dist/checkout/api/payment-status.d.ts +0 -45
  565. package/dist/checkout/api/payment-status.d.ts.map +0 -1
  566. package/dist/checkout/api/payment-status.js +0 -104
  567. package/dist/checkout/api/payment-status.js.map +0 -1
  568. package/dist/checkout/api/shipping.d.ts +0 -34
  569. package/dist/checkout/api/shipping.d.ts.map +0 -1
  570. package/dist/checkout/api/shipping.js +0 -247
  571. package/dist/checkout/api/shipping.js.map +0 -1
  572. package/dist/checkout/api/webhook.js +0 -55
  573. package/dist/checkout/api/webhook.js.map +0 -1
  574. package/dist/checkout/components/CheckoutButton.d.ts +0 -55
  575. package/dist/checkout/components/CheckoutButton.d.ts.map +0 -1
  576. package/dist/checkout/components/CheckoutButton.js +0 -132
  577. package/dist/checkout/components/CheckoutButton.js.map +0 -1
  578. package/dist/checkout/components/CheckoutFlow.d.ts +0 -53
  579. package/dist/checkout/components/CheckoutFlow.d.ts.map +0 -1
  580. package/dist/checkout/components/CheckoutFlow.js +0 -286
  581. package/dist/checkout/components/CheckoutFlow.js.map +0 -1
  582. package/dist/checkout/components/CheckoutSuccess.d.ts +0 -29
  583. package/dist/checkout/components/CheckoutSuccess.d.ts.map +0 -1
  584. package/dist/checkout/components/CheckoutSuccess.js +0 -49
  585. package/dist/checkout/components/CheckoutSuccess.js.map +0 -1
  586. package/dist/checkout/components/OrderSummary.d.ts +0 -37
  587. package/dist/checkout/components/OrderSummary.d.ts.map +0 -1
  588. package/dist/checkout/components/OrderSummary.js +0 -71
  589. package/dist/checkout/components/OrderSummary.js.map +0 -1
  590. package/dist/checkout/components/ShippingForm.d.ts +0 -30
  591. package/dist/checkout/components/ShippingForm.d.ts.map +0 -1
  592. package/dist/checkout/components/ShippingForm.js +0 -185
  593. package/dist/checkout/components/ShippingForm.js.map +0 -1
  594. package/dist/checkout/components/ShippingOptions.d.ts +0 -51
  595. package/dist/checkout/components/ShippingOptions.d.ts.map +0 -1
  596. package/dist/checkout/components/ShippingOptions.js +0 -93
  597. package/dist/checkout/components/ShippingOptions.js.map +0 -1
  598. package/dist/checkout/components/index.d.ts +0 -12
  599. package/dist/checkout/components/index.d.ts.map +0 -1
  600. package/dist/checkout/components/index.js +0 -12
  601. package/dist/checkout/components/index.js.map +0 -1
  602. package/dist/checkout/constants.d.ts +0 -244
  603. package/dist/checkout/constants.d.ts.map +0 -1
  604. package/dist/checkout/constants.js +0 -119
  605. package/dist/checkout/constants.js.map +0 -1
  606. package/dist/checkout/hooks/index.d.ts +0 -9
  607. package/dist/checkout/hooks/index.d.ts.map +0 -1
  608. package/dist/checkout/hooks/index.js +0 -8
  609. package/dist/checkout/hooks/index.js.map +0 -1
  610. package/dist/checkout/hooks/useCheckout.d.ts +0 -38
  611. package/dist/checkout/hooks/useCheckout.d.ts.map +0 -1
  612. package/dist/checkout/hooks/useCheckout.js +0 -134
  613. package/dist/checkout/hooks/useCheckout.js.map +0 -1
  614. package/dist/checkout/hooks/usePaymentStatus.d.ts +0 -42
  615. package/dist/checkout/hooks/usePaymentStatus.d.ts.map +0 -1
  616. package/dist/checkout/hooks/usePaymentStatus.js +0 -71
  617. package/dist/checkout/hooks/usePaymentStatus.js.map +0 -1
  618. package/dist/checkout/index.js +0 -135
  619. package/dist/checkout/index.js.map +0 -1
  620. package/dist/checkout/server/coupons.d.ts +0 -91
  621. package/dist/checkout/server/coupons.d.ts.map +0 -1
  622. package/dist/checkout/server/coupons.js +0 -192
  623. package/dist/checkout/server/coupons.js.map +0 -1
  624. package/dist/checkout/server/index.js +0 -10
  625. package/dist/checkout/server/index.js.map +0 -1
  626. package/dist/checkout/stripe/client.d.ts +0 -74
  627. package/dist/checkout/stripe/client.d.ts.map +0 -1
  628. package/dist/checkout/stripe/client.js +0 -175
  629. package/dist/checkout/stripe/client.js.map +0 -1
  630. package/dist/checkout/stripe/index.d.ts +0 -7
  631. package/dist/checkout/stripe/index.d.ts.map +0 -1
  632. package/dist/checkout/stripe/index.js +0 -7
  633. package/dist/checkout/stripe/index.js.map +0 -1
  634. package/dist/checkout/types.d.ts +0 -489
  635. package/dist/checkout/types.d.ts.map +0 -1
  636. package/dist/checkout/types.js +0 -8
  637. package/dist/checkout/types.js.map +0 -1
  638. package/dist/core/StoreSettingsProvider.d.ts +0 -107
  639. package/dist/core/StoreSettingsProvider.d.ts.map +0 -1
  640. package/dist/core/StoreSettingsProvider.js +0 -200
  641. package/dist/core/StoreSettingsProvider.js.map +0 -1
  642. package/dist/core/api/index.d.ts +0 -7
  643. package/dist/core/api/index.d.ts.map +0 -1
  644. package/dist/core/api/index.js +0 -7
  645. package/dist/core/api/index.js.map +0 -1
  646. package/dist/core/api/settings.d.ts +0 -42
  647. package/dist/core/api/settings.d.ts.map +0 -1
  648. package/dist/core/api/settings.js +0 -74
  649. package/dist/core/api/settings.js.map +0 -1
  650. package/dist/core/config.d.ts +0 -270
  651. package/dist/core/config.d.ts.map +0 -1
  652. package/dist/core/config.js +0 -80
  653. package/dist/core/config.js.map +0 -1
  654. package/dist/core/cookie-consent/CookieBanner.d.ts +0 -2
  655. package/dist/core/cookie-consent/CookieBanner.d.ts.map +0 -1
  656. package/dist/core/cookie-consent/CookieBanner.js +0 -243
  657. package/dist/core/cookie-consent/CookieBanner.js.map +0 -1
  658. package/dist/core/cookie-consent/CookieConsentProvider.d.ts +0 -53
  659. package/dist/core/cookie-consent/CookieConsentProvider.d.ts.map +0 -1
  660. package/dist/core/cookie-consent/CookieConsentProvider.js +0 -162
  661. package/dist/core/cookie-consent/CookieConsentProvider.js.map +0 -1
  662. package/dist/core/cookie-consent/CookiePreferencesLink.d.ts +0 -15
  663. package/dist/core/cookie-consent/CookiePreferencesLink.d.ts.map +0 -1
  664. package/dist/core/cookie-consent/CookiePreferencesLink.js +0 -12
  665. package/dist/core/cookie-consent/CookiePreferencesLink.js.map +0 -1
  666. package/dist/core/cookie-consent/index.d.ts +0 -17
  667. package/dist/core/cookie-consent/index.d.ts.map +0 -1
  668. package/dist/core/cookie-consent/index.js +0 -16
  669. package/dist/core/cookie-consent/index.js.map +0 -1
  670. package/dist/core/cookie-consent/types.d.ts +0 -31
  671. package/dist/core/cookie-consent/types.d.ts.map +0 -1
  672. package/dist/core/cookie-consent/types.js +0 -10
  673. package/dist/core/cookie-consent/types.js.map +0 -1
  674. package/dist/core/cookie-consent/useCookieConsent.d.ts +0 -14
  675. package/dist/core/cookie-consent/useCookieConsent.d.ts.map +0 -1
  676. package/dist/core/cookie-consent/useCookieConsent.js +0 -25
  677. package/dist/core/cookie-consent/useCookieConsent.js.map +0 -1
  678. package/dist/core/db/client.d.ts +0 -39
  679. package/dist/core/db/client.d.ts.map +0 -1
  680. package/dist/core/db/client.js +0 -86
  681. package/dist/core/db/client.js.map +0 -1
  682. package/dist/core/db/index.d.ts +0 -11
  683. package/dist/core/db/index.d.ts.map +0 -1
  684. package/dist/core/db/index.js +0 -36
  685. package/dist/core/db/index.js.map +0 -1
  686. package/dist/core/db/queries.d.ts +0 -1427
  687. package/dist/core/db/queries.d.ts.map +0 -1
  688. package/dist/core/db/queries.js +0 -1932
  689. package/dist/core/db/queries.js.map +0 -1
  690. package/dist/core/db/schema.d.ts +0 -3462
  691. package/dist/core/db/schema.d.ts.map +0 -1
  692. package/dist/core/db/schema.js +0 -495
  693. package/dist/core/db/schema.js.map +0 -1
  694. package/dist/core/index.d.ts +0 -22
  695. package/dist/core/index.d.ts.map +0 -1
  696. package/dist/core/index.js +0 -43
  697. package/dist/core/index.js.map +0 -1
  698. package/dist/core/server/index.d.ts +0 -18
  699. package/dist/core/server/index.d.ts.map +0 -1
  700. package/dist/core/server/index.js +0 -47
  701. package/dist/core/server/index.js.map +0 -1
  702. package/dist/core/types.d.ts +0 -246
  703. package/dist/core/types.d.ts.map +0 -1
  704. package/dist/core/types.js +0 -8
  705. package/dist/core/types.js.map +0 -1
  706. package/dist/core/utils.d.ts +0 -147
  707. package/dist/core/utils.d.ts.map +0 -1
  708. package/dist/core/utils.js +0 -309
  709. package/dist/core/utils.js.map +0 -1
  710. package/dist/emails/config.d.ts +0 -69
  711. package/dist/emails/config.d.ts.map +0 -1
  712. package/dist/emails/config.js +0 -147
  713. package/dist/emails/config.js.map +0 -1
  714. package/dist/emails/index.d.ts +0 -85
  715. package/dist/emails/index.d.ts.map +0 -1
  716. package/dist/emails/index.js +0 -110
  717. package/dist/emails/index.js.map +0 -1
  718. package/dist/emails/send/admin-auth.d.ts +0 -94
  719. package/dist/emails/send/admin-auth.d.ts.map +0 -1
  720. package/dist/emails/send/admin-auth.js +0 -118
  721. package/dist/emails/send/admin-auth.js.map +0 -1
  722. package/dist/emails/send/auth.d.ts +0 -91
  723. package/dist/emails/send/auth.d.ts.map +0 -1
  724. package/dist/emails/send/auth.js +0 -130
  725. package/dist/emails/send/auth.js.map +0 -1
  726. package/dist/emails/send/index.d.ts +0 -12
  727. package/dist/emails/send/index.d.ts.map +0 -1
  728. package/dist/emails/send/index.js +0 -18
  729. package/dist/emails/send/index.js.map +0 -1
  730. package/dist/emails/send/orders.d.ts +0 -186
  731. package/dist/emails/send/orders.d.ts.map +0 -1
  732. package/dist/emails/send/orders.js +0 -258
  733. package/dist/emails/send/orders.js.map +0 -1
  734. package/dist/emails/sender.d.ts +0 -72
  735. package/dist/emails/sender.d.ts.map +0 -1
  736. package/dist/emails/sender.js +0 -116
  737. package/dist/emails/sender.js.map +0 -1
  738. package/dist/emails/templates/admin-invite.d.ts +0 -40
  739. package/dist/emails/templates/admin-invite.d.ts.map +0 -1
  740. package/dist/emails/templates/admin-invite.js +0 -62
  741. package/dist/emails/templates/admin-invite.js.map +0 -1
  742. package/dist/emails/templates/base.d.ts +0 -109
  743. package/dist/emails/templates/base.d.ts.map +0 -1
  744. package/dist/emails/templates/base.js +0 -334
  745. package/dist/emails/templates/base.js.map +0 -1
  746. package/dist/emails/templates/email-verification.d.ts +0 -28
  747. package/dist/emails/templates/email-verification.d.ts.map +0 -1
  748. package/dist/emails/templates/email-verification.js +0 -52
  749. package/dist/emails/templates/email-verification.js.map +0 -1
  750. package/dist/emails/templates/index.d.ts +0 -16
  751. package/dist/emails/templates/index.d.ts.map +0 -1
  752. package/dist/emails/templates/index.js +0 -28
  753. package/dist/emails/templates/index.js.map +0 -1
  754. package/dist/emails/templates/order-cancelled.d.ts +0 -30
  755. package/dist/emails/templates/order-cancelled.d.ts.map +0 -1
  756. package/dist/emails/templates/order-cancelled.js +0 -83
  757. package/dist/emails/templates/order-cancelled.js.map +0 -1
  758. package/dist/emails/templates/order-confirmation.d.ts +0 -36
  759. package/dist/emails/templates/order-confirmation.d.ts.map +0 -1
  760. package/dist/emails/templates/order-confirmation.js +0 -174
  761. package/dist/emails/templates/order-confirmation.js.map +0 -1
  762. package/dist/emails/templates/order-delivered.d.ts +0 -31
  763. package/dist/emails/templates/order-delivered.d.ts.map +0 -1
  764. package/dist/emails/templates/order-delivered.js +0 -100
  765. package/dist/emails/templates/order-delivered.js.map +0 -1
  766. package/dist/emails/templates/order-shipped.d.ts +0 -32
  767. package/dist/emails/templates/order-shipped.d.ts.map +0 -1
  768. package/dist/emails/templates/order-shipped.js +0 -83
  769. package/dist/emails/templates/order-shipped.js.map +0 -1
  770. package/dist/emails/templates/password-reset.d.ts +0 -27
  771. package/dist/emails/templates/password-reset.d.ts.map +0 -1
  772. package/dist/emails/templates/password-reset.js +0 -51
  773. package/dist/emails/templates/password-reset.js.map +0 -1
  774. package/dist/emails/templates/refund-processed.d.ts +0 -32
  775. package/dist/emails/templates/refund-processed.d.ts.map +0 -1
  776. package/dist/emails/templates/refund-processed.js +0 -92
  777. package/dist/emails/templates/refund-processed.js.map +0 -1
  778. package/dist/emails/templates/welcome.d.ts +0 -27
  779. package/dist/emails/templates/welcome.d.ts.map +0 -1
  780. package/dist/emails/templates/welcome.js +0 -52
  781. package/dist/emails/templates/welcome.js.map +0 -1
  782. package/dist/emails/types.d.ts +0 -229
  783. package/dist/emails/types.d.ts.map +0 -1
  784. package/dist/emails/types.js +0 -7
  785. package/dist/emails/types.js.map +0 -1
  786. package/dist/emails/utils.d.ts +0 -94
  787. package/dist/emails/utils.d.ts.map +0 -1
  788. package/dist/emails/utils.js +0 -218
  789. package/dist/emails/utils.js.map +0 -1
  790. package/dist/index.js +0 -73
  791. package/dist/index.js.map +0 -1
  792. package/dist/media/api/delete.d.ts +0 -43
  793. package/dist/media/api/delete.d.ts.map +0 -1
  794. package/dist/media/api/delete.js +0 -124
  795. package/dist/media/api/delete.js.map +0 -1
  796. package/dist/media/api/index.d.ts +0 -17
  797. package/dist/media/api/index.d.ts.map +0 -1
  798. package/dist/media/api/index.js +0 -17
  799. package/dist/media/api/index.js.map +0 -1
  800. package/dist/media/api/presign.d.ts +0 -38
  801. package/dist/media/api/presign.d.ts.map +0 -1
  802. package/dist/media/api/presign.js +0 -130
  803. package/dist/media/api/presign.js.map +0 -1
  804. package/dist/media/components/DropZone.d.ts +0 -18
  805. package/dist/media/components/DropZone.d.ts.map +0 -1
  806. package/dist/media/components/DropZone.js +0 -107
  807. package/dist/media/components/DropZone.js.map +0 -1
  808. package/dist/media/components/ImageGalleryUpload.d.ts +0 -21
  809. package/dist/media/components/ImageGalleryUpload.d.ts.map +0 -1
  810. package/dist/media/components/ImageGalleryUpload.js +0 -193
  811. package/dist/media/components/ImageGalleryUpload.js.map +0 -1
  812. package/dist/media/components/ImageUpload.d.ts +0 -17
  813. package/dist/media/components/ImageUpload.d.ts.map +0 -1
  814. package/dist/media/components/ImageUpload.js +0 -89
  815. package/dist/media/components/ImageUpload.js.map +0 -1
  816. package/dist/media/components/index.d.ts +0 -10
  817. package/dist/media/components/index.d.ts.map +0 -1
  818. package/dist/media/components/index.js +0 -9
  819. package/dist/media/components/index.js.map +0 -1
  820. package/dist/media/config.d.ts +0 -83
  821. package/dist/media/config.d.ts.map +0 -1
  822. package/dist/media/config.js +0 -189
  823. package/dist/media/config.js.map +0 -1
  824. package/dist/media/hooks/index.d.ts +0 -8
  825. package/dist/media/hooks/index.d.ts.map +0 -1
  826. package/dist/media/hooks/index.js +0 -7
  827. package/dist/media/hooks/index.js.map +0 -1
  828. package/dist/media/hooks/useUpload.d.ts +0 -32
  829. package/dist/media/hooks/useUpload.d.ts.map +0 -1
  830. package/dist/media/hooks/useUpload.js +0 -260
  831. package/dist/media/hooks/useUpload.js.map +0 -1
  832. package/dist/media/index.d.ts +0 -57
  833. package/dist/media/index.d.ts.map +0 -1
  834. package/dist/media/index.js +0 -68
  835. package/dist/media/index.js.map +0 -1
  836. package/dist/media/server/delete.d.ts +0 -59
  837. package/dist/media/server/delete.d.ts.map +0 -1
  838. package/dist/media/server/delete.js +0 -176
  839. package/dist/media/server/delete.js.map +0 -1
  840. package/dist/media/server/index.d.ts +0 -10
  841. package/dist/media/server/index.d.ts.map +0 -1
  842. package/dist/media/server/index.js +0 -13
  843. package/dist/media/server/index.js.map +0 -1
  844. package/dist/media/server/presign.d.ts +0 -57
  845. package/dist/media/server/presign.d.ts.map +0 -1
  846. package/dist/media/server/presign.js +0 -112
  847. package/dist/media/server/presign.js.map +0 -1
  848. package/dist/media/server/r2-client.d.ts +0 -30
  849. package/dist/media/server/r2-client.d.ts.map +0 -1
  850. package/dist/media/server/r2-client.js +0 -76
  851. package/dist/media/server/r2-client.js.map +0 -1
  852. package/dist/media/types.d.ts +0 -316
  853. package/dist/media/types.d.ts.map +0 -1
  854. package/dist/media/types.js +0 -95
  855. package/dist/media/types.js.map +0 -1
  856. package/dist/products/api/categories.d.ts +0 -29
  857. package/dist/products/api/categories.d.ts.map +0 -1
  858. package/dist/products/api/categories.js +0 -46
  859. package/dist/products/api/categories.js.map +0 -1
  860. package/dist/products/api/index.d.ts +0 -24
  861. package/dist/products/api/index.d.ts.map +0 -1
  862. package/dist/products/api/index.js +0 -24
  863. package/dist/products/api/index.js.map +0 -1
  864. package/dist/products/api/product.d.ts +0 -36
  865. package/dist/products/api/product.d.ts.map +0 -1
  866. package/dist/products/api/product.js +0 -67
  867. package/dist/products/api/product.js.map +0 -1
  868. package/dist/products/api/products.d.ts +0 -41
  869. package/dist/products/api/products.d.ts.map +0 -1
  870. package/dist/products/api/products.js +0 -99
  871. package/dist/products/api/products.js.map +0 -1
  872. package/dist/products/components/CategoryNav.d.ts +0 -51
  873. package/dist/products/components/CategoryNav.d.ts.map +0 -1
  874. package/dist/products/components/CategoryNav.js +0 -110
  875. package/dist/products/components/CategoryNav.js.map +0 -1
  876. package/dist/products/components/ProductBreadcrumb.d.ts +0 -52
  877. package/dist/products/components/ProductBreadcrumb.d.ts.map +0 -1
  878. package/dist/products/components/ProductBreadcrumb.js +0 -73
  879. package/dist/products/components/ProductBreadcrumb.js.map +0 -1
  880. package/dist/products/components/ProductCard.d.ts +0 -54
  881. package/dist/products/components/ProductCard.d.ts.map +0 -1
  882. package/dist/products/components/ProductCard.js +0 -72
  883. package/dist/products/components/ProductCard.js.map +0 -1
  884. package/dist/products/components/ProductDetails.d.ts +0 -63
  885. package/dist/products/components/ProductDetails.d.ts.map +0 -1
  886. package/dist/products/components/ProductDetails.js +0 -137
  887. package/dist/products/components/ProductDetails.js.map +0 -1
  888. package/dist/products/components/ProductFilters.d.ts +0 -70
  889. package/dist/products/components/ProductFilters.d.ts.map +0 -1
  890. package/dist/products/components/ProductFilters.js +0 -125
  891. package/dist/products/components/ProductFilters.js.map +0 -1
  892. package/dist/products/components/ProductGallery.d.ts +0 -30
  893. package/dist/products/components/ProductGallery.d.ts.map +0 -1
  894. package/dist/products/components/ProductGallery.js +0 -91
  895. package/dist/products/components/ProductGallery.js.map +0 -1
  896. package/dist/products/components/ProductGrid.d.ts +0 -50
  897. package/dist/products/components/ProductGrid.d.ts.map +0 -1
  898. package/dist/products/components/ProductGrid.js +0 -81
  899. package/dist/products/components/ProductGrid.js.map +0 -1
  900. package/dist/products/components/ProductSearch.d.ts +0 -43
  901. package/dist/products/components/ProductSearch.d.ts.map +0 -1
  902. package/dist/products/components/ProductSearch.js +0 -97
  903. package/dist/products/components/ProductSearch.js.map +0 -1
  904. package/dist/products/components/ProductSort.d.ts +0 -43
  905. package/dist/products/components/ProductSort.d.ts.map +0 -1
  906. package/dist/products/components/ProductSort.js +0 -59
  907. package/dist/products/components/ProductSort.js.map +0 -1
  908. package/dist/products/components/VariantSelector.d.ts +0 -43
  909. package/dist/products/components/VariantSelector.d.ts.map +0 -1
  910. package/dist/products/components/VariantSelector.js +0 -147
  911. package/dist/products/components/VariantSelector.js.map +0 -1
  912. package/dist/products/components/index.d.ts +0 -20
  913. package/dist/products/components/index.d.ts.map +0 -1
  914. package/dist/products/components/index.js +0 -15
  915. package/dist/products/components/index.js.map +0 -1
  916. package/dist/products/hooks/index.d.ts +0 -10
  917. package/dist/products/hooks/index.d.ts.map +0 -1
  918. package/dist/products/hooks/index.js +0 -8
  919. package/dist/products/hooks/index.js.map +0 -1
  920. package/dist/products/hooks/useCategories.d.ts +0 -56
  921. package/dist/products/hooks/useCategories.d.ts.map +0 -1
  922. package/dist/products/hooks/useCategories.js +0 -126
  923. package/dist/products/hooks/useCategories.js.map +0 -1
  924. package/dist/products/hooks/useProduct.d.ts +0 -44
  925. package/dist/products/hooks/useProduct.d.ts.map +0 -1
  926. package/dist/products/hooks/useProduct.js +0 -87
  927. package/dist/products/hooks/useProduct.js.map +0 -1
  928. package/dist/products/hooks/useProductAttributes.d.ts +0 -59
  929. package/dist/products/hooks/useProductAttributes.d.ts.map +0 -1
  930. package/dist/products/hooks/useProductAttributes.js +0 -125
  931. package/dist/products/hooks/useProductAttributes.js.map +0 -1
  932. package/dist/products/hooks/useProducts.d.ts +0 -67
  933. package/dist/products/hooks/useProducts.d.ts.map +0 -1
  934. package/dist/products/hooks/useProducts.js +0 -131
  935. package/dist/products/hooks/useProducts.js.map +0 -1
  936. package/dist/products/index.d.ts +0 -69
  937. package/dist/products/index.d.ts.map +0 -1
  938. package/dist/products/index.js +0 -79
  939. package/dist/products/index.js.map +0 -1
  940. package/dist/shipping/index.d.ts +0 -8
  941. package/dist/shipping/index.d.ts.map +0 -1
  942. package/dist/shipping/index.js +0 -8
  943. package/dist/shipping/index.js.map +0 -1
  944. package/dist/shipping/shippo.d.ts +0 -77
  945. package/dist/shipping/shippo.d.ts.map +0 -1
  946. package/dist/shipping/shippo.js +0 -280
  947. package/dist/shipping/shippo.js.map +0 -1
  948. package/dist/theme/ThemeProvider.d.ts +0 -70
  949. package/dist/theme/ThemeProvider.d.ts.map +0 -1
  950. package/dist/theme/ThemeProvider.js +0 -75
  951. package/dist/theme/ThemeProvider.js.map +0 -1
  952. package/dist/theme/colors.d.ts +0 -134
  953. package/dist/theme/colors.d.ts.map +0 -1
  954. package/dist/theme/colors.js +0 -214
  955. package/dist/theme/colors.js.map +0 -1
  956. package/dist/theme/defaults.d.ts +0 -133
  957. package/dist/theme/defaults.d.ts.map +0 -1
  958. package/dist/theme/defaults.js +0 -210
  959. package/dist/theme/defaults.js.map +0 -1
  960. package/dist/theme/fonts.d.ts +0 -28
  961. package/dist/theme/fonts.d.ts.map +0 -1
  962. package/dist/theme/fonts.js +0 -55
  963. package/dist/theme/fonts.js.map +0 -1
  964. package/dist/theme/generator.d.ts +0 -43
  965. package/dist/theme/generator.d.ts.map +0 -1
  966. package/dist/theme/generator.js +0 -272
  967. package/dist/theme/generator.js.map +0 -1
  968. package/dist/theme/hooks.d.ts +0 -110
  969. package/dist/theme/hooks.d.ts.map +0 -1
  970. package/dist/theme/hooks.js +0 -101
  971. package/dist/theme/hooks.js.map +0 -1
  972. package/dist/theme/index.d.ts +0 -23
  973. package/dist/theme/index.d.ts.map +0 -1
  974. package/dist/theme/index.js +0 -30
  975. package/dist/theme/index.js.map +0 -1
  976. /package/dist/admin/{styles/admin-theme.css → admin-theme.css} +0 -0
@@ -1,1932 +0,0 @@
1
- /**
2
- * @rovela/sdk/core/db/queries
3
- *
4
- * Type-safe query helpers for e-commerce stores
5
- * Each store has its own database (via Neon branches) - no tenant filtering needed
6
- */
7
- import { eq, and, or, desc, asc, ilike, sql, inArray, isNull, isNotNull } from 'drizzle-orm';
8
- import { getDb } from './client';
9
- import * as schema from './schema';
10
- /**
11
- * Find products with filtering, sorting, and pagination
12
- */
13
- export async function findProducts(options = {}) {
14
- const db = getDb();
15
- const conditions = [];
16
- if (options.categoryId) {
17
- conditions.push(eq(schema.products.categoryId, options.categoryId));
18
- }
19
- if (options.status) {
20
- conditions.push(eq(schema.products.status, options.status));
21
- }
22
- if (options.search) {
23
- conditions.push(ilike(schema.products.name, `%${options.search}%`));
24
- }
25
- if (options.outOfStock) {
26
- conditions.push(buildOutOfStockCondition());
27
- }
28
- if (options.onSale) {
29
- conditions.push(sql `${schema.products.comparePrice} IS NOT NULL AND ${schema.products.comparePrice} > ${schema.products.price}`);
30
- }
31
- if (options.tags && options.tags.length > 0) {
32
- // JSONB array-overlap check: `tags ?| array['t1','t2']` returns true when
33
- // ANY tag in the column matches ANY of the provided tags. Powered by the
34
- // default GIN index on jsonb columns when present.
35
- conditions.push(sql `${schema.products.tags} ?| ${options.tags}`);
36
- }
37
- // Determine sort order
38
- let orderBy;
39
- switch (options.sort) {
40
- case 'price-asc':
41
- orderBy = asc(schema.products.price);
42
- break;
43
- case 'price-desc':
44
- orderBy = desc(schema.products.price);
45
- break;
46
- case 'name':
47
- orderBy = asc(schema.products.name);
48
- break;
49
- case 'newest':
50
- default:
51
- orderBy = desc(schema.products.createdAt);
52
- }
53
- const query = db
54
- .select()
55
- .from(schema.products)
56
- .where(conditions.length > 0 ? and(...conditions) : undefined)
57
- .orderBy(orderBy);
58
- if (options.limit) {
59
- query.limit(options.limit);
60
- }
61
- if (options.offset) {
62
- query.offset(options.offset);
63
- }
64
- return query;
65
- }
66
- /**
67
- * Find a single product by slug
68
- */
69
- export async function findProductBySlug(slug) {
70
- const db = getDb();
71
- const result = await db
72
- .select()
73
- .from(schema.products)
74
- .where(eq(schema.products.slug, slug))
75
- .limit(1);
76
- return result[0] || null;
77
- }
78
- /**
79
- * Find a single product by ID
80
- */
81
- export async function findProductById(id) {
82
- const db = getDb();
83
- const result = await db
84
- .select()
85
- .from(schema.products)
86
- .where(eq(schema.products.id, id))
87
- .limit(1);
88
- return result[0] || null;
89
- }
90
- /**
91
- * Get product variants for a product
92
- */
93
- export async function findProductVariants(productId) {
94
- const db = getDb();
95
- return db
96
- .select()
97
- .from(schema.productVariants)
98
- .where(eq(schema.productVariants.productId, productId));
99
- }
100
- /**
101
- * Count total products matching filters
102
- */
103
- export async function countProducts(options = {}) {
104
- const db = getDb();
105
- const conditions = [];
106
- if (options.categoryId) {
107
- conditions.push(eq(schema.products.categoryId, options.categoryId));
108
- }
109
- if (options.status) {
110
- conditions.push(eq(schema.products.status, options.status));
111
- }
112
- if (options.search) {
113
- conditions.push(ilike(schema.products.name, `%${options.search}%`));
114
- }
115
- if (options.outOfStock) {
116
- conditions.push(buildOutOfStockCondition());
117
- }
118
- const result = await db
119
- .select({ count: sql `count(*)` })
120
- .from(schema.products)
121
- .where(conditions.length > 0 ? and(...conditions) : undefined);
122
- return Number(result[0]?.count || 0);
123
- }
124
- /**
125
- * Build the SQL condition for "effectively out of stock":
126
- * - non-variant products: trackInventory=true AND inventory <= 0
127
- * - variant products: no variant exists with inventory > 0
128
- *
129
- * Reused by both `findProducts` (the OOS chip filter) and the OOS metric card.
130
- * The variant subquery uses `product_variants_product_id_idx` (already in schema)
131
- * so it's an index lookup, not a scan.
132
- */
133
- function buildOutOfStockCondition() {
134
- return or(and(eq(schema.products.hasVariants, false), eq(schema.products.trackInventory, true), sql `${schema.products.inventory} <= 0`), and(eq(schema.products.hasVariants, true), sql `NOT EXISTS (
135
- SELECT 1 FROM ${schema.productVariants} pv
136
- WHERE pv.product_id = ${schema.products.id} AND pv.inventory > 0
137
- )`));
138
- }
139
- // =============================================================================
140
- // Product Metrics & Inventory Aggregation (admin product list page)
141
- // =============================================================================
142
- /**
143
- * For products with `hasVariants=true`, the parent `products.inventory` column
144
- * is unused — inventory lives on `product_variants`. This helper returns a
145
- * Map of `productId → effectiveInventory` for an arbitrary set of variant
146
- * product IDs. The page-list handler calls this for the products it just
147
- * returned and merges the sums into each row before responding to the client.
148
- *
149
- * Empty input → empty map. Single SQL query, GROUP BY product_id.
150
- */
151
- export async function getInventoryByProductIds(productIds) {
152
- if (productIds.length === 0)
153
- return new Map();
154
- const db = getDb();
155
- const rows = await db
156
- .select({
157
- productId: schema.productVariants.productId,
158
- total: sql `COALESCE(SUM(${schema.productVariants.inventory}), 0)`,
159
- })
160
- .from(schema.productVariants)
161
- .where(inArray(schema.productVariants.productId, productIds))
162
- .groupBy(schema.productVariants.productId);
163
- const result = new Map();
164
- for (const r of rows) {
165
- result.set(r.productId, Number(r.total) || 0);
166
- }
167
- return result;
168
- }
169
- /**
170
- * Count of products in `status='active'`. Drives the "Active products"
171
- * metric card on the admin product list page.
172
- */
173
- export async function getActiveProductCount() {
174
- const db = getDb();
175
- const result = await db
176
- .select({ count: sql `count(*)` })
177
- .from(schema.products)
178
- .where(eq(schema.products.status, 'active'));
179
- return Number(result[0]?.count || 0);
180
- }
181
- /**
182
- * Count of *active* products that are effectively out of stock. Excludes
183
- * drafts / archived (they're irrelevant noise on the product list view).
184
- *
185
- * Uses the same OOS condition as the chip filter (single source of truth).
186
- */
187
- export async function getOutOfStockProductCount() {
188
- const db = getDb();
189
- const result = await db
190
- .select({ count: sql `count(*)` })
191
- .from(schema.products)
192
- .where(and(eq(schema.products.status, 'active'), buildOutOfStockCondition()));
193
- return Number(result[0]?.count || 0);
194
- }
195
- /**
196
- * Best-selling product over the last `days` window, by units sold.
197
- *
198
- * Counts only orders that actually moved revenue: `paid`, `shipped`,
199
- * `delivered`. Excludes pending (might fail), cancelled, refunded, and
200
- * return_requested (not yet finalized).
201
- *
202
- * Returns null when no qualifying orders exist in the window — the UI
203
- * renders an empty state rather than a broken card.
204
- */
205
- export async function getBestSellerProduct(days = 30) {
206
- const db = getDb();
207
- const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
208
- const rows = await db
209
- .select({
210
- id: schema.products.id,
211
- name: schema.products.name,
212
- unitsSold: sql `SUM(${schema.orderItems.quantity})`,
213
- revenue: sql `SUM(${schema.orderItems.quantity} * ${schema.orderItems.price})`,
214
- })
215
- .from(schema.orderItems)
216
- .innerJoin(schema.orders, eq(schema.orders.id, schema.orderItems.orderId))
217
- .innerJoin(schema.products, eq(schema.products.id, schema.orderItems.productId))
218
- .where(and(inArray(schema.orders.status, ['paid', 'shipped', 'delivered']), sql `${schema.orders.createdAt} >= ${since}`))
219
- .groupBy(schema.products.id, schema.products.name)
220
- .orderBy(desc(sql `SUM(${schema.orderItems.quantity})`))
221
- .limit(1);
222
- const row = rows[0];
223
- if (!row)
224
- return null;
225
- return {
226
- id: row.id,
227
- name: row.name,
228
- unitsSold: Number(row.unitsSold) || 0,
229
- revenue: String(row.revenue ?? '0'),
230
- };
231
- }
232
- /**
233
- * Best-selling products in the last N days, capped to `limit`.
234
- *
235
- * Same SQL shape as `getBestSellerProduct` (paid+shipped+delivered window,
236
- * ordered by units sold desc) but returns up to `limit` rows. Used by the
237
- * Best Sellers homepage section card. Returns an empty array when no
238
- * qualifying orders exist — callers MUST hide their UI when length === 0
239
- * (don't render an empty rail).
240
- *
241
- * `order_items_product_id_idx` covers the JOIN; cost is the same as the
242
- * existing single-row helper.
243
- */
244
- export async function getBestSellers(days = 30, limit = 8) {
245
- const db = getDb();
246
- const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
247
- const rows = await db
248
- .select({
249
- id: schema.products.id,
250
- slug: schema.products.slug,
251
- name: schema.products.name,
252
- price: schema.products.price,
253
- comparePrice: schema.products.comparePrice,
254
- images: schema.products.images,
255
- unitsSold: sql `SUM(${schema.orderItems.quantity})`,
256
- })
257
- .from(schema.orderItems)
258
- .innerJoin(schema.orders, eq(schema.orders.id, schema.orderItems.orderId))
259
- .innerJoin(schema.products, eq(schema.products.id, schema.orderItems.productId))
260
- .where(and(inArray(schema.orders.status, ['paid', 'shipped', 'delivered']), eq(schema.products.status, 'active'), sql `${schema.orders.createdAt} >= ${since}`))
261
- .groupBy(schema.products.id, schema.products.slug, schema.products.name, schema.products.price, schema.products.comparePrice, schema.products.images)
262
- .orderBy(desc(sql `SUM(${schema.orderItems.quantity})`))
263
- .limit(limit);
264
- return rows.map((row) => ({
265
- id: row.id,
266
- slug: row.slug,
267
- name: row.name,
268
- price: row.price,
269
- comparePrice: row.comparePrice,
270
- images: (row.images ?? []),
271
- unitsSold: Number(row.unitsSold) || 0,
272
- }));
273
- }
274
- /**
275
- * Most-popular products by distinct buyer count (last N days), capped.
276
- *
277
- * Different from best sellers — best sellers is units sold (revenue lens);
278
- * this is buyer reach (how many distinct customers bought it). Used by the
279
- * Most Popular homepage section card. Same JOIN path; same status window.
280
- *
281
- * Excludes guest orders (`customer_id IS NULL`) so we count real distinct
282
- * buyers, not anonymous sessions. Returns empty array when no data — UI
283
- * must hide.
284
- */
285
- export async function getMostPopularProducts(days = 30, limit = 8) {
286
- const db = getDb();
287
- const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
288
- const rows = await db
289
- .select({
290
- id: schema.products.id,
291
- slug: schema.products.slug,
292
- name: schema.products.name,
293
- price: schema.products.price,
294
- comparePrice: schema.products.comparePrice,
295
- images: schema.products.images,
296
- buyerCount: sql `COUNT(DISTINCT ${schema.orders.customerId})`,
297
- })
298
- .from(schema.orderItems)
299
- .innerJoin(schema.orders, eq(schema.orders.id, schema.orderItems.orderId))
300
- .innerJoin(schema.products, eq(schema.products.id, schema.orderItems.productId))
301
- .where(and(inArray(schema.orders.status, ['paid', 'shipped', 'delivered']), eq(schema.products.status, 'active'), isNotNull(schema.orders.customerId), sql `${schema.orders.createdAt} >= ${since}`))
302
- .groupBy(schema.products.id, schema.products.slug, schema.products.name, schema.products.price, schema.products.comparePrice, schema.products.images)
303
- .orderBy(desc(sql `COUNT(DISTINCT ${schema.orders.customerId})`))
304
- .limit(limit);
305
- return rows.map((row) => ({
306
- id: row.id,
307
- slug: row.slug,
308
- name: row.name,
309
- price: row.price,
310
- comparePrice: row.comparePrice,
311
- images: (row.images ?? []),
312
- buyerCount: Number(row.buyerCount) || 0,
313
- }));
314
- }
315
- /**
316
- * Distinct-buyer count for a single product within the last N hours.
317
- *
318
- * Powers the "X people bought this in the last 24h" social-proof card on
319
- * PDPs. Server-only — caller MUST cache via Server Component + ISR
320
- * (`revalidate: 300`); calling this per page view is a perf trap.
321
- *
322
- * Returns 0 when no qualifying orders exist. UI gates on a `minThreshold`
323
- * (default 5) — never render "1 person bought this" (awkward + reads as
324
- * dead store).
325
- */
326
- export async function getProductRecentBuyerCount(productId, hours = 24) {
327
- const db = getDb();
328
- const since = new Date(Date.now() - hours * 60 * 60 * 1000);
329
- const rows = await db
330
- .select({
331
- count: sql `COUNT(DISTINCT ${schema.orders.customerId})`,
332
- })
333
- .from(schema.orderItems)
334
- .innerJoin(schema.orders, eq(schema.orders.id, schema.orderItems.orderId))
335
- .where(and(eq(schema.orderItems.productId, productId), inArray(schema.orders.status, ['paid', 'shipped', 'delivered']), isNotNull(schema.orders.customerId), sql `${schema.orders.createdAt} >= ${since}`));
336
- return Number(rows[0]?.count ?? 0);
337
- }
338
- /**
339
- * Check whether a customer has purchased a specific product.
340
- *
341
- * Powers the verified-purchase badge on the C2 reviews card. Returns true
342
- * iff the customer has at least one paid+shipped+delivered order containing
343
- * the product (variant-agnostic — buying any variant counts).
344
- *
345
- * Uses EXISTS for short-circuit evaluation; cheap even on large order
346
- * histories. Index `order_items_product_id_idx` covers the inner lookup;
347
- * `orders_customer_id_idx` covers the join.
348
- */
349
- export async function hasCustomerPurchasedProduct(customerId, productId) {
350
- const db = getDb();
351
- const rows = await db
352
- .select({
353
- hit: sql `1`,
354
- })
355
- .from(schema.orderItems)
356
- .innerJoin(schema.orders, eq(schema.orders.id, schema.orderItems.orderId))
357
- .where(and(eq(schema.orderItems.productId, productId), eq(schema.orders.customerId, customerId), inArray(schema.orders.status, ['paid', 'shipped', 'delivered'])))
358
- .limit(1);
359
- return rows.length > 0;
360
- }
361
- // =============================================================================
362
- // Categories
363
- // =============================================================================
364
- /**
365
- * Find all categories
366
- */
367
- export async function findCategories() {
368
- const db = getDb();
369
- return db
370
- .select()
371
- .from(schema.categories)
372
- .orderBy(asc(schema.categories.order), asc(schema.categories.name));
373
- }
374
- /**
375
- * Find a category by slug
376
- */
377
- export async function findCategoryBySlug(slug) {
378
- const db = getDb();
379
- const result = await db
380
- .select()
381
- .from(schema.categories)
382
- .where(eq(schema.categories.slug, slug))
383
- .limit(1);
384
- return result[0] || null;
385
- }
386
- /**
387
- * Find orders with filtering and pagination
388
- */
389
- export async function findOrders(options = {}) {
390
- const db = getDb();
391
- const conditions = [];
392
- if (options.status) {
393
- conditions.push(eq(schema.orders.status, options.status));
394
- }
395
- if (options.customerId) {
396
- conditions.push(eq(schema.orders.customerId, options.customerId));
397
- }
398
- const query = db
399
- .select()
400
- .from(schema.orders)
401
- .where(conditions.length > 0 ? and(...conditions) : undefined)
402
- .orderBy(desc(schema.orders.createdAt));
403
- if (options.limit) {
404
- query.limit(options.limit);
405
- }
406
- if (options.offset) {
407
- query.offset(options.offset);
408
- }
409
- return query;
410
- }
411
- /**
412
- * Find order by ID with items (includes product images)
413
- */
414
- export async function findOrderById(id) {
415
- const db = getDb();
416
- const order = await db
417
- .select()
418
- .from(schema.orders)
419
- .where(eq(schema.orders.id, id))
420
- .limit(1);
421
- if (!order[0])
422
- return null;
423
- // Join order_items with products to get images
424
- const itemsWithProducts = await db
425
- .select({
426
- id: schema.orderItems.id,
427
- orderId: schema.orderItems.orderId,
428
- productId: schema.orderItems.productId,
429
- variantId: schema.orderItems.variantId,
430
- name: schema.orderItems.name,
431
- price: schema.orderItems.price,
432
- quantity: schema.orderItems.quantity,
433
- attributes: schema.orderItems.attributes,
434
- createdAt: schema.orderItems.createdAt,
435
- // Get product images (JSONB array)
436
- productImages: schema.products.images,
437
- })
438
- .from(schema.orderItems)
439
- .leftJoin(schema.products, eq(schema.orderItems.productId, schema.products.id))
440
- .where(eq(schema.orderItems.orderId, id));
441
- // Map items to include the first product image
442
- const items = itemsWithProducts.map((item) => {
443
- const images = item.productImages;
444
- return {
445
- id: item.id,
446
- orderId: item.orderId,
447
- productId: item.productId,
448
- variantId: item.variantId,
449
- name: item.name,
450
- price: item.price,
451
- quantity: item.quantity,
452
- attributes: item.attributes,
453
- createdAt: item.createdAt,
454
- // Add first image from product
455
- image: images && images.length > 0 ? images[0] : null,
456
- };
457
- });
458
- return {
459
- ...order[0],
460
- items,
461
- };
462
- }
463
- /**
464
- * Get order items for an order
465
- */
466
- export async function findOrderItems(orderId) {
467
- const db = getDb();
468
- return db
469
- .select()
470
- .from(schema.orderItems)
471
- .where(eq(schema.orderItems.orderId, orderId));
472
- }
473
- // =============================================================================
474
- // Customers
475
- // =============================================================================
476
- /**
477
- * Find customer by email
478
- */
479
- export async function findCustomerByEmail(email) {
480
- const db = getDb();
481
- const result = await db
482
- .select()
483
- .from(schema.customers)
484
- .where(eq(schema.customers.email, email.toLowerCase()))
485
- .limit(1);
486
- return result[0] || null;
487
- }
488
- /**
489
- * Find customer by ID
490
- */
491
- export async function findCustomerById(id) {
492
- const db = getDb();
493
- const result = await db
494
- .select()
495
- .from(schema.customers)
496
- .where(eq(schema.customers.id, id))
497
- .limit(1);
498
- return result[0] || null;
499
- }
500
- /**
501
- * Find all customers with pagination
502
- */
503
- export async function findCustomers(options = {}) {
504
- const db = getDb();
505
- const conditions = [];
506
- if (options.search) {
507
- conditions.push(ilike(schema.customers.email, `%${options.search}%`));
508
- }
509
- const query = db
510
- .select()
511
- .from(schema.customers)
512
- .where(conditions.length > 0 ? and(...conditions) : undefined)
513
- .orderBy(desc(schema.customers.createdAt));
514
- if (options.limit) {
515
- query.limit(options.limit);
516
- }
517
- if (options.offset) {
518
- query.offset(options.offset);
519
- }
520
- return query;
521
- }
522
- // =============================================================================
523
- // Store Admins
524
- // =============================================================================
525
- /**
526
- * Find admin by email
527
- */
528
- export async function findAdminByEmail(email) {
529
- const db = getDb();
530
- const result = await db
531
- .select()
532
- .from(schema.storeAdmins)
533
- .where(eq(schema.storeAdmins.email, email.toLowerCase()))
534
- .limit(1);
535
- return result[0] || null;
536
- }
537
- // =============================================================================
538
- // Admin Stats
539
- // =============================================================================
540
- /**
541
- * Get store statistics for admin dashboard
542
- */
543
- export async function getStoreStats() {
544
- const db = getDb();
545
- const [productCount, orderCount, customerCount, revenue] = await Promise.all([
546
- // Total products
547
- db
548
- .select({ count: sql `count(*)` })
549
- .from(schema.products)
550
- .where(eq(schema.products.status, 'active')),
551
- // Total orders — same status filter as revenue so the two metrics tell
552
- // the same story. Counting cancelled/refunded/pending here would inflate
553
- // the number relative to revenue and confuse merchants.
554
- db
555
- .select({ count: sql `count(*)` })
556
- .from(schema.orders)
557
- .where(inArray(schema.orders.status, ['paid', 'shipped', 'delivered'])),
558
- // Total customers
559
- db
560
- .select({ count: sql `count(*)` })
561
- .from(schema.customers),
562
- // Total revenue (paid orders only)
563
- db
564
- .select({ total: sql `COALESCE(SUM(total), 0)` })
565
- .from(schema.orders)
566
- .where(inArray(schema.orders.status, ['paid', 'shipped', 'delivered'])),
567
- ]);
568
- return {
569
- products: Number(productCount[0]?.count || 0),
570
- orders: Number(orderCount[0]?.count || 0),
571
- customers: Number(customerCount[0]?.count || 0),
572
- revenue: Number(revenue[0]?.total || 0),
573
- };
574
- }
575
- // =============================================================================
576
- // Period-scoped store stats (for time-window selector)
577
- // =============================================================================
578
- /**
579
- * Same shape as `getStoreStats()` but scoped to a window of `days` ago to now.
580
- * Powers the "Today / 7d / 30d / 90d" selector on the admin dashboard. Both
581
- * Orders and Revenue use the same status filter (paid + shipped + delivered)
582
- * so they tell the same story.
583
- *
584
- * Note: `products` and `customers` here mean *new* products created in the
585
- * window and *new* customers registered in the window — this is what makes
586
- * the period-vs-prior-period delta meaningful. For the absolute "how many
587
- * active products do I have" use `getStoreStats()`.
588
- */
589
- export async function getStoreStatsForPeriod(startDate, endDate) {
590
- const db = getDb();
591
- const [orderRow, revenueRow, productRow, customerRow] = await Promise.all([
592
- db
593
- .select({ count: sql `count(*)` })
594
- .from(schema.orders)
595
- .where(and(inArray(schema.orders.status, ['paid', 'shipped', 'delivered']), sql `${schema.orders.createdAt} >= ${startDate.toISOString()}`, sql `${schema.orders.createdAt} < ${endDate.toISOString()}`)),
596
- db
597
- .select({ total: sql `COALESCE(SUM(total), 0)` })
598
- .from(schema.orders)
599
- .where(and(inArray(schema.orders.status, ['paid', 'shipped', 'delivered']), sql `${schema.orders.createdAt} >= ${startDate.toISOString()}`, sql `${schema.orders.createdAt} < ${endDate.toISOString()}`)),
600
- db
601
- .select({ count: sql `count(*)` })
602
- .from(schema.products)
603
- .where(and(eq(schema.products.status, 'active'), sql `${schema.products.createdAt} >= ${startDate.toISOString()}`, sql `${schema.products.createdAt} < ${endDate.toISOString()}`)),
604
- db
605
- .select({ count: sql `count(*)` })
606
- .from(schema.customers)
607
- .where(and(sql `${schema.customers.createdAt} >= ${startDate.toISOString()}`, sql `${schema.customers.createdAt} < ${endDate.toISOString()}`)),
608
- ]);
609
- return {
610
- orders: Number(orderRow[0]?.count || 0),
611
- revenue: Number(revenueRow[0]?.total || 0),
612
- newProducts: Number(productRow[0]?.count || 0),
613
- newCustomers: Number(customerRow[0]?.count || 0),
614
- };
615
- }
616
- /**
617
- * Count of refunded orders in the window. Used to compute refund rate.
618
- */
619
- export async function getRefundedOrdersCount(startDate, endDate) {
620
- const db = getDb();
621
- const result = await db
622
- .select({ count: sql `count(*)` })
623
- .from(schema.orders)
624
- .where(and(eq(schema.orders.status, 'refunded'), sql `${schema.orders.createdAt} >= ${startDate.toISOString()}`, sql `${schema.orders.createdAt} < ${endDate.toISOString()}`));
625
- return Number(result[0]?.count || 0);
626
- }
627
- /**
628
- * Count of all orders in the window (any status, used as the denominator
629
- * for refund rate so the rate isn't artificially inflated by excluding
630
- * pending/cancelled). Cancelled orders DO count here — they represent
631
- * customer behavior even if they don't represent revenue.
632
- */
633
- async function getTotalOrdersInPeriod(startDate, endDate) {
634
- const db = getDb();
635
- const result = await db
636
- .select({ count: sql `count(*)` })
637
- .from(schema.orders)
638
- .where(and(sql `${schema.orders.createdAt} >= ${startDate.toISOString()}`, sql `${schema.orders.createdAt} < ${endDate.toISOString()}`));
639
- return Number(result[0]?.count || 0);
640
- }
641
- function pctDelta(current, previous) {
642
- if (previous === 0)
643
- return null;
644
- return (current - previous) / previous;
645
- }
646
- /**
647
- * Build the full dashboard summary in a single round-trip. Runs eight
648
- * parallel queries (current period + previous period × four metrics) and
649
- * computes derived ratios + deltas in-process. Total wall-clock ~30–50ms
650
- * on a warm Neon connection.
651
- */
652
- export async function getDashboardSummary(periodDays = 30) {
653
- // Anchor windows to UTC midnight so day boundaries are stable.
654
- const now = new Date();
655
- const todayUtc = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
656
- // `endDate` is the start of tomorrow (exclusive upper bound) so today's
657
- // orders are included.
658
- const endDate = new Date(todayUtc);
659
- endDate.setUTCDate(endDate.getUTCDate() + 1);
660
- const currentStart = new Date(todayUtc);
661
- currentStart.setUTCDate(currentStart.getUTCDate() - (periodDays - 1));
662
- const previousEnd = new Date(currentStart);
663
- const previousStart = new Date(currentStart);
664
- previousStart.setUTCDate(previousStart.getUTCDate() - periodDays);
665
- const [currentStats, previousStats, currentTotalOrders, previousTotalOrders, currentRefunded, previousRefunded, bestSeller,] = await Promise.all([
666
- getStoreStatsForPeriod(currentStart, endDate),
667
- getStoreStatsForPeriod(previousStart, previousEnd),
668
- getTotalOrdersInPeriod(currentStart, endDate),
669
- getTotalOrdersInPeriod(previousStart, previousEnd),
670
- getRefundedOrdersCount(currentStart, endDate),
671
- getRefundedOrdersCount(previousStart, previousEnd),
672
- getBestSellerProduct(periodDays),
673
- ]);
674
- const currentAov = currentStats.orders > 0 ? currentStats.revenue / currentStats.orders : 0;
675
- const previousAov = previousStats.orders > 0 ? previousStats.revenue / previousStats.orders : 0;
676
- const currentRefundRate = currentTotalOrders > 0 ? currentRefunded / currentTotalOrders : 0;
677
- const previousRefundRate = previousTotalOrders > 0 ? previousRefunded / previousTotalOrders : 0;
678
- return {
679
- periodDays,
680
- current: {
681
- revenue: currentStats.revenue,
682
- orders: currentStats.orders,
683
- newCustomers: currentStats.newCustomers,
684
- newProducts: currentStats.newProducts,
685
- aov: currentAov,
686
- refundRate: currentRefundRate,
687
- bestSeller,
688
- },
689
- previous: {
690
- revenue: previousStats.revenue,
691
- orders: previousStats.orders,
692
- newCustomers: previousStats.newCustomers,
693
- newProducts: previousStats.newProducts,
694
- aov: previousAov,
695
- refundRate: previousRefundRate,
696
- },
697
- deltas: {
698
- revenue: pctDelta(currentStats.revenue, previousStats.revenue),
699
- orders: pctDelta(currentStats.orders, previousStats.orders),
700
- aov: pctDelta(currentAov, previousAov),
701
- refundRate: pctDelta(currentRefundRate, previousRefundRate),
702
- customers: pctDelta(currentStats.newCustomers, previousStats.newCustomers),
703
- },
704
- };
705
- }
706
- /**
707
- * Get low stock products (inventory < threshold)
708
- */
709
- export async function getLowStockProducts(threshold = 10) {
710
- const db = getDb();
711
- // Get products with variants that have low stock
712
- const lowStockVariants = await db
713
- .select({
714
- product: schema.products,
715
- variant: schema.productVariants,
716
- })
717
- .from(schema.productVariants)
718
- .innerJoin(schema.products, eq(schema.productVariants.productId, schema.products.id))
719
- .where(and(eq(schema.products.status, 'active'), sql `${schema.productVariants.inventory} < ${threshold}`))
720
- .orderBy(asc(schema.productVariants.inventory));
721
- return lowStockVariants;
722
- }
723
- /**
724
- * Get recent orders
725
- */
726
- export async function getRecentOrders(limit = 5) {
727
- const db = getDb();
728
- return db
729
- .select()
730
- .from(schema.orders)
731
- .orderBy(desc(schema.orders.createdAt))
732
- .limit(limit);
733
- }
734
- // =============================================================================
735
- // Order Mutations (for checkout module)
736
- // =============================================================================
737
- /**
738
- * Create a new order
739
- */
740
- export async function createOrder(data) {
741
- const db = getDb();
742
- const [order] = await db
743
- .insert(schema.orders)
744
- .values(data)
745
- .returning();
746
- return order;
747
- }
748
- /**
749
- * Create order items for an order
750
- */
751
- export async function createOrderItems(items) {
752
- const db = getDb();
753
- if (items.length === 0) {
754
- return [];
755
- }
756
- return db.insert(schema.orderItems).values(items).returning();
757
- }
758
- /**
759
- * Update order status
760
- */
761
- export async function updateOrderStatus(orderId, status) {
762
- const db = getDb();
763
- const [order] = await db
764
- .update(schema.orders)
765
- .set({ status, updatedAt: new Date() })
766
- .where(eq(schema.orders.id, orderId))
767
- .returning();
768
- return order || null;
769
- }
770
- /**
771
- * Update order shipping information (for Shippo integration)
772
- */
773
- export async function updateOrderShipping(orderId, shippingData) {
774
- const db = getDb();
775
- const [order] = await db
776
- .update(schema.orders)
777
- .set({
778
- ...shippingData,
779
- updatedAt: new Date(),
780
- })
781
- .where(eq(schema.orders.id, orderId))
782
- .returning();
783
- return order || null;
784
- }
785
- /**
786
- * Find order by Stripe Payment Intent ID
787
- * Used for idempotency in webhook handling
788
- */
789
- export async function findOrderByPaymentIntent(paymentIntentId) {
790
- const db = getDb();
791
- const [order] = await db
792
- .select()
793
- .from(schema.orders)
794
- .where(eq(schema.orders.stripePaymentIntentId, paymentIntentId))
795
- .limit(1);
796
- return order || null;
797
- }
798
- /**
799
- * Update order refund amount (for partial refund tracking)
800
- * Adds the refund amount to the existing refund total
801
- */
802
- export async function updateOrderRefundAmount(orderId, refundAmountCents) {
803
- const db = getDb();
804
- const refundAmountDecimal = (refundAmountCents / 100).toFixed(2);
805
- const [order] = await db
806
- .update(schema.orders)
807
- .set({
808
- refundAmount: sql `COALESCE(${schema.orders.refundAmount}, 0) + ${refundAmountDecimal}`,
809
- updatedAt: new Date(),
810
- })
811
- .where(eq(schema.orders.id, orderId))
812
- .returning();
813
- return order || null;
814
- }
815
- /**
816
- * Update order receipt information (for Stripe receipt URL)
817
- */
818
- export async function updateOrderReceipt(orderId, receiptData) {
819
- const db = getDb();
820
- const [order] = await db
821
- .update(schema.orders)
822
- .set({
823
- ...receiptData,
824
- updatedAt: new Date(),
825
- })
826
- .where(eq(schema.orders.id, orderId))
827
- .returning();
828
- return order || null;
829
- }
830
- /**
831
- * Update order with return request
832
- * Sets status to 'return_requested' and stores the return reason
833
- */
834
- export async function updateOrderReturnRequest(orderId, returnReason) {
835
- const db = getDb();
836
- const [order] = await db
837
- .update(schema.orders)
838
- .set({
839
- status: 'return_requested',
840
- returnReason,
841
- updatedAt: new Date(),
842
- })
843
- .where(eq(schema.orders.id, orderId))
844
- .returning();
845
- return order || null;
846
- }
847
- /**
848
- * Clear order return request
849
- * Sets status back to 'delivered' and clears the return reason
850
- */
851
- export async function clearOrderReturnRequest(orderId) {
852
- const db = getDb();
853
- const [order] = await db
854
- .update(schema.orders)
855
- .set({
856
- status: 'delivered',
857
- returnReason: null,
858
- updatedAt: new Date(),
859
- })
860
- .where(eq(schema.orders.id, orderId))
861
- .returning();
862
- return order || null;
863
- }
864
- // =============================================================================
865
- // Product CRUD (for admin module)
866
- // =============================================================================
867
- /**
868
- * Create a new product
869
- */
870
- export async function createProduct(data) {
871
- const db = getDb();
872
- const [product] = await db
873
- .insert(schema.products)
874
- .values(data)
875
- .returning();
876
- return product;
877
- }
878
- /**
879
- * Update a product by ID
880
- */
881
- export async function updateProduct(id, data) {
882
- const db = getDb();
883
- const [product] = await db
884
- .update(schema.products)
885
- .set({ ...data, updatedAt: new Date() })
886
- .where(eq(schema.products.id, id))
887
- .returning();
888
- return product || null;
889
- }
890
- /**
891
- * Archive a product by ID (soft delete).
892
- * Sets status to 'archived' instead of deleting to preserve order history.
893
- * Use hardDeleteProduct() for permanent deletion if needed.
894
- */
895
- export async function deleteProduct(id) {
896
- const result = await updateProduct(id, { status: 'archived' });
897
- return result !== null;
898
- }
899
- /**
900
- * Permanently delete a product by ID.
901
- * WARNING: This will fail if there are order_items referencing this product.
902
- * Use deleteProduct() (soft delete) for most cases.
903
- */
904
- export async function hardDeleteProduct(id) {
905
- const db = getDb();
906
- const result = await db
907
- .delete(schema.products)
908
- .where(eq(schema.products.id, id))
909
- .returning({ id: schema.products.id });
910
- return result.length > 0;
911
- }
912
- // =============================================================================
913
- // Product Variant CRUD (for admin module)
914
- // =============================================================================
915
- /**
916
- * Create a new product variant
917
- */
918
- export async function createProductVariant(data) {
919
- const db = getDb();
920
- const [variant] = await db
921
- .insert(schema.productVariants)
922
- .values(data)
923
- .returning();
924
- return variant;
925
- }
926
- /**
927
- * Update a product variant by ID
928
- */
929
- export async function updateProductVariant(id, data) {
930
- const db = getDb();
931
- const [variant] = await db
932
- .update(schema.productVariants)
933
- .set(data)
934
- .where(eq(schema.productVariants.id, id))
935
- .returning();
936
- return variant || null;
937
- }
938
- /**
939
- * Delete a product variant by ID
940
- */
941
- export async function deleteProductVariant(id) {
942
- const db = getDb();
943
- const result = await db
944
- .delete(schema.productVariants)
945
- .where(eq(schema.productVariants.id, id))
946
- .returning({ id: schema.productVariants.id });
947
- return result.length > 0;
948
- }
949
- /**
950
- * Update variant inventory
951
- */
952
- export async function updateVariantInventory(id, inventory) {
953
- const db = getDb();
954
- await db
955
- .update(schema.productVariants)
956
- .set({ inventory })
957
- .where(eq(schema.productVariants.id, id));
958
- }
959
- /**
960
- * Find a variant by ID
961
- */
962
- export async function findVariantById(id) {
963
- const db = getDb();
964
- const [variant] = await db
965
- .select()
966
- .from(schema.productVariants)
967
- .where(eq(schema.productVariants.id, id))
968
- .limit(1);
969
- return variant || null;
970
- }
971
- // =============================================================================
972
- // Category CRUD (for admin module)
973
- // =============================================================================
974
- /**
975
- * Find a category by ID
976
- */
977
- export async function findCategoryById(id) {
978
- const db = getDb();
979
- const [category] = await db
980
- .select()
981
- .from(schema.categories)
982
- .where(eq(schema.categories.id, id))
983
- .limit(1);
984
- return category || null;
985
- }
986
- /**
987
- * Create a new category
988
- */
989
- export async function createCategory(data) {
990
- const db = getDb();
991
- const [category] = await db
992
- .insert(schema.categories)
993
- .values(data)
994
- .returning();
995
- return category;
996
- }
997
- /**
998
- * Update a category by ID
999
- */
1000
- export async function updateCategory(id, data) {
1001
- const db = getDb();
1002
- const [category] = await db
1003
- .update(schema.categories)
1004
- .set(data)
1005
- .where(eq(schema.categories.id, id))
1006
- .returning();
1007
- return category || null;
1008
- }
1009
- /**
1010
- * Delete a category by ID
1011
- */
1012
- export async function deleteCategory(id) {
1013
- const db = getDb();
1014
- const result = await db
1015
- .delete(schema.categories)
1016
- .where(eq(schema.categories.id, id))
1017
- .returning({ id: schema.categories.id });
1018
- return result.length > 0;
1019
- }
1020
- /**
1021
- * Count categories
1022
- */
1023
- export async function countCategories() {
1024
- const db = getDb();
1025
- const result = await db
1026
- .select({ count: sql `count(*)` })
1027
- .from(schema.categories);
1028
- return Number(result[0]?.count || 0);
1029
- }
1030
- // =============================================================================
1031
- // Customer Queries (for admin module)
1032
- // =============================================================================
1033
- /**
1034
- * Count customers with optional search
1035
- */
1036
- export async function countCustomers(options = {}) {
1037
- const db = getDb();
1038
- const conditions = [];
1039
- if (options.search) {
1040
- conditions.push(ilike(schema.customers.email, `%${options.search}%`));
1041
- }
1042
- const result = await db
1043
- .select({ count: sql `count(*)` })
1044
- .from(schema.customers)
1045
- .where(conditions.length > 0 ? and(...conditions) : undefined);
1046
- return Number(result[0]?.count || 0);
1047
- }
1048
- /**
1049
- * Find orders for a specific customer
1050
- */
1051
- export async function findCustomerOrders(customerId) {
1052
- const db = getDb();
1053
- return db
1054
- .select()
1055
- .from(schema.orders)
1056
- .where(eq(schema.orders.customerId, customerId))
1057
- .orderBy(desc(schema.orders.createdAt));
1058
- }
1059
- /**
1060
- * Claim guest orders by email when a customer registers.
1061
- * Updates all orders with matching email and null customerId to the new customer.
1062
- *
1063
- * @param email - Email address (will be lowercased)
1064
- * @param customerId - New customer ID to assign
1065
- * @returns Number of orders claimed
1066
- */
1067
- export async function claimGuestOrders(email, customerId) {
1068
- const db = getDb();
1069
- const result = await db
1070
- .update(schema.orders)
1071
- .set({ customerId, updatedAt: new Date() })
1072
- .where(and(eq(schema.orders.email, email.toLowerCase().trim()), isNull(schema.orders.customerId)))
1073
- .returning({ id: schema.orders.id });
1074
- return result.length;
1075
- }
1076
- /**
1077
- * Delete (anonymize) a customer by ID.
1078
- *
1079
- * This is a SOFT DELETE that anonymizes customer data instead of removing the record.
1080
- * This approach:
1081
- * - Preserves order history integrity (orders reference customerId)
1082
- * - Complies with GDPR "right to erasure" through anonymization
1083
- * - Prevents login by invalidating passwordHash
1084
- * - Keeps the record for audit trail purposes
1085
- *
1086
- * Related tokens (verification, password reset) are auto-deleted via CASCADE.
1087
- *
1088
- * @param id - Customer UUID
1089
- * @returns true if customer was found and anonymized, false if not found
1090
- */
1091
- export async function deleteCustomer(id) {
1092
- const db = getDb();
1093
- // Anonymize customer data instead of hard delete
1094
- const result = await db
1095
- .update(schema.customers)
1096
- .set({
1097
- email: `deleted_${Date.now()}@anonymized.local`,
1098
- name: null,
1099
- passwordHash: 'DELETED', // Prevents login
1100
- emailVerified: null,
1101
- stripeCustomerId: null,
1102
- })
1103
- .where(eq(schema.customers.id, id))
1104
- .returning({ id: schema.customers.id });
1105
- return result.length > 0;
1106
- }
1107
- // =============================================================================
1108
- // Order Queries (for admin module)
1109
- // =============================================================================
1110
- /**
1111
- * Count orders with optional status filter
1112
- */
1113
- export async function countOrders(options = {}) {
1114
- const db = getDb();
1115
- const conditions = [];
1116
- if (options.status) {
1117
- conditions.push(eq(schema.orders.status, options.status));
1118
- }
1119
- const result = await db
1120
- .select({ count: sql `count(*)` })
1121
- .from(schema.orders)
1122
- .where(conditions.length > 0 ? and(...conditions) : undefined);
1123
- return Number(result[0]?.count || 0);
1124
- }
1125
- /**
1126
- * Get revenue by period (for analytics).
1127
- *
1128
- * Returns one row per calendar day in the window, **including days with zero
1129
- * revenue**. The SQL GROUP BY only emits rows where orders exist, which made
1130
- * the chart skip empty days and look discontinuous (e.g., a Friday-only seller
1131
- * showed 5 floating points instead of 30). Fill happens in-process, so the
1132
- * chart can render a continuous line without the consumer thinking about it.
1133
- *
1134
- * Date format is `YYYY-MM-DD` in UTC (matches Postgres `DATE()` output).
1135
- */
1136
- export async function getRevenueByPeriod(days) {
1137
- const db = getDb();
1138
- // Normalize to UTC midnight so the day boundaries match Postgres DATE()
1139
- // and our in-process fill loop produces stable keys.
1140
- const now = new Date();
1141
- const todayUtc = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
1142
- const startDate = new Date(todayUtc);
1143
- startDate.setUTCDate(startDate.getUTCDate() - days);
1144
- const result = await db
1145
- .select({
1146
- date: sql `DATE(${schema.orders.createdAt})`,
1147
- revenue: sql `COALESCE(SUM(${schema.orders.total}), 0)`,
1148
- })
1149
- .from(schema.orders)
1150
- .where(and(inArray(schema.orders.status, ['paid', 'shipped', 'delivered']), sql `${schema.orders.createdAt} >= ${startDate.toISOString()}`))
1151
- .groupBy(sql `DATE(${schema.orders.createdAt})`)
1152
- .orderBy(sql `DATE(${schema.orders.createdAt})`);
1153
- // Index actual revenue rows by date for O(1) lookup during fill.
1154
- const revenueByDate = new Map();
1155
- for (const row of result) {
1156
- revenueByDate.set(String(row.date), Number(row.revenue));
1157
- }
1158
- // Walk every day from startDate through today and emit a row for each —
1159
- // empty days get revenue=0 so the chart renders a continuous line.
1160
- const filled = [];
1161
- const cursor = new Date(startDate);
1162
- while (cursor <= todayUtc) {
1163
- const key = cursor.toISOString().slice(0, 10);
1164
- filled.push({ date: key, revenue: revenueByDate.get(key) ?? 0 });
1165
- cursor.setUTCDate(cursor.getUTCDate() + 1);
1166
- }
1167
- return filled;
1168
- }
1169
- /**
1170
- * Get orders by status count (for analytics)
1171
- */
1172
- export async function getOrdersByStatus() {
1173
- const db = getDb();
1174
- const result = await db
1175
- .select({
1176
- status: schema.orders.status,
1177
- count: sql `count(*)`,
1178
- })
1179
- .from(schema.orders)
1180
- .groupBy(schema.orders.status);
1181
- return result.map((r) => ({
1182
- status: r.status,
1183
- count: Number(r.count),
1184
- }));
1185
- }
1186
- /**
1187
- * Find store settings.
1188
- * Returns null if no settings exist (first time access).
1189
- * Each store has only one settings row.
1190
- */
1191
- export async function findSettings() {
1192
- const db = getDb();
1193
- const [settings] = await db
1194
- .select()
1195
- .from(schema.storeSettings)
1196
- .limit(1);
1197
- if (!settings)
1198
- return null;
1199
- return {
1200
- storeName: settings.storeName,
1201
- storeEmail: settings.storeEmail,
1202
- logoUrl: settings.logoUrl,
1203
- storeCurrency: settings.storeCurrency,
1204
- storeTimezone: settings.storeTimezone,
1205
- taxIncludedInPrices: settings.taxIncludedInPrices,
1206
- shippingEnabled: settings.shippingEnabled,
1207
- freeShippingThreshold: settings.freeShippingThreshold
1208
- ? Number(settings.freeShippingThreshold)
1209
- : null,
1210
- shippingCountries: settings.shippingCountries,
1211
- // Auth configuration
1212
- guestCheckout: settings.guestCheckout,
1213
- customerAccounts: settings.customerAccounts,
1214
- // Shippo fields
1215
- shippingMode: settings.shippingMode,
1216
- shippoApiKey: settings.shippoApiKey,
1217
- shippoTestMode: settings.shippoTestMode,
1218
- shippoFromAddress: settings.shippoFromAddress,
1219
- shippoDefaultParcel: settings.shippoDefaultParcel,
1220
- // Discount/promotion configuration
1221
- promotionCodesEnabled: settings.promotionCodesEnabled,
1222
- // Cookie consent banner (R021)
1223
- cookieBannerEnabled: settings.cookieBannerEnabled,
1224
- };
1225
- }
1226
- /**
1227
- * Upsert (create or update) store settings.
1228
- * Each store has only one settings row.
1229
- */
1230
- export async function upsertSettings(data) {
1231
- const db = getDb();
1232
- // Check if settings exist
1233
- const existing = await db
1234
- .select({ id: schema.storeSettings.id })
1235
- .from(schema.storeSettings)
1236
- .limit(1);
1237
- const values = {
1238
- storeName: data.storeName ?? undefined,
1239
- storeEmail: data.storeEmail ?? undefined,
1240
- logoUrl: data.logoUrl ?? undefined,
1241
- storeCurrency: data.storeCurrency ?? undefined,
1242
- storeTimezone: data.storeTimezone ?? undefined,
1243
- taxIncludedInPrices: data.taxIncludedInPrices ?? undefined,
1244
- shippingEnabled: data.shippingEnabled ?? undefined,
1245
- freeShippingThreshold: data.freeShippingThreshold !== null && data.freeShippingThreshold !== undefined
1246
- ? String(data.freeShippingThreshold)
1247
- : undefined,
1248
- shippingCountries: data.shippingCountries ?? undefined,
1249
- // Auth configuration
1250
- guestCheckout: data.guestCheckout ?? undefined,
1251
- customerAccounts: data.customerAccounts ?? undefined,
1252
- // Shippo carrier integration
1253
- shippingMode: data.shippingMode ?? undefined,
1254
- shippoApiKey: data.shippoApiKey ?? undefined,
1255
- shippoTestMode: data.shippoTestMode ?? undefined,
1256
- shippoFromAddress: data.shippoFromAddress ?? undefined,
1257
- shippoDefaultParcel: data.shippoDefaultParcel ?? undefined,
1258
- // Discount/promotion configuration
1259
- promotionCodesEnabled: data.promotionCodesEnabled ?? undefined,
1260
- // Cookie consent banner (R021)
1261
- cookieBannerEnabled: data.cookieBannerEnabled ?? undefined,
1262
- updatedAt: new Date(),
1263
- };
1264
- let result;
1265
- if (existing.length > 0) {
1266
- // Update existing
1267
- [result] = await db
1268
- .update(schema.storeSettings)
1269
- .set(values)
1270
- .where(eq(schema.storeSettings.id, existing[0].id))
1271
- .returning();
1272
- }
1273
- else {
1274
- // Insert new
1275
- [result] = await db
1276
- .insert(schema.storeSettings)
1277
- .values(values)
1278
- .returning();
1279
- }
1280
- return {
1281
- storeName: result.storeName,
1282
- storeEmail: result.storeEmail,
1283
- logoUrl: result.logoUrl,
1284
- storeCurrency: result.storeCurrency,
1285
- storeTimezone: result.storeTimezone,
1286
- taxIncludedInPrices: result.taxIncludedInPrices,
1287
- shippingEnabled: result.shippingEnabled,
1288
- freeShippingThreshold: result.freeShippingThreshold
1289
- ? Number(result.freeShippingThreshold)
1290
- : null,
1291
- shippingCountries: result.shippingCountries,
1292
- // Auth configuration
1293
- guestCheckout: result.guestCheckout,
1294
- customerAccounts: result.customerAccounts,
1295
- // Shippo fields
1296
- shippingMode: result.shippingMode,
1297
- shippoApiKey: result.shippoApiKey,
1298
- shippoTestMode: result.shippoTestMode,
1299
- shippoFromAddress: result.shippoFromAddress,
1300
- shippoDefaultParcel: result.shippoDefaultParcel,
1301
- // Discount/promotion configuration
1302
- promotionCodesEnabled: result.promotionCodesEnabled,
1303
- // Cookie consent banner (R021)
1304
- cookieBannerEnabled: result.cookieBannerEnabled,
1305
- };
1306
- }
1307
- /**
1308
- * Find all shipping carriers
1309
- */
1310
- export async function findShippingCarriers() {
1311
- const db = getDb();
1312
- const carriers = await db
1313
- .select()
1314
- .from(schema.shippingCarriers)
1315
- .orderBy(asc(schema.shippingCarriers.sortOrder), asc(schema.shippingCarriers.name));
1316
- return carriers.map((carrier) => ({
1317
- id: carrier.id,
1318
- name: carrier.name,
1319
- code: carrier.code,
1320
- description: carrier.description,
1321
- isActive: carrier.isActive,
1322
- sortOrder: carrier.sortOrder,
1323
- createdAt: carrier.createdAt,
1324
- updatedAt: carrier.updatedAt,
1325
- }));
1326
- }
1327
- /**
1328
- * Find active shipping carriers only
1329
- */
1330
- export async function findActiveShippingCarriers() {
1331
- const db = getDb();
1332
- const carriers = await db
1333
- .select()
1334
- .from(schema.shippingCarriers)
1335
- .where(eq(schema.shippingCarriers.isActive, true))
1336
- .orderBy(asc(schema.shippingCarriers.sortOrder), asc(schema.shippingCarriers.name));
1337
- return carriers.map((carrier) => ({
1338
- id: carrier.id,
1339
- name: carrier.name,
1340
- code: carrier.code,
1341
- description: carrier.description,
1342
- isActive: carrier.isActive,
1343
- sortOrder: carrier.sortOrder,
1344
- createdAt: carrier.createdAt,
1345
- updatedAt: carrier.updatedAt,
1346
- }));
1347
- }
1348
- /**
1349
- * Find a shipping carrier by ID
1350
- */
1351
- export async function findShippingCarrierById(id) {
1352
- const db = getDb();
1353
- const [carrier] = await db
1354
- .select()
1355
- .from(schema.shippingCarriers)
1356
- .where(eq(schema.shippingCarriers.id, id))
1357
- .limit(1);
1358
- if (!carrier)
1359
- return null;
1360
- return {
1361
- id: carrier.id,
1362
- name: carrier.name,
1363
- code: carrier.code,
1364
- description: carrier.description,
1365
- isActive: carrier.isActive,
1366
- sortOrder: carrier.sortOrder,
1367
- createdAt: carrier.createdAt,
1368
- updatedAt: carrier.updatedAt,
1369
- };
1370
- }
1371
- /**
1372
- * Create a new shipping carrier
1373
- */
1374
- export async function createShippingCarrier(data) {
1375
- const db = getDb();
1376
- const [carrier] = await db
1377
- .insert(schema.shippingCarriers)
1378
- .values({
1379
- name: data.name,
1380
- code: data.code,
1381
- description: data.description || null,
1382
- isActive: data.isActive ?? true,
1383
- sortOrder: data.sortOrder ?? 0,
1384
- })
1385
- .returning();
1386
- return carrier;
1387
- }
1388
- /**
1389
- * Update a shipping carrier
1390
- */
1391
- export async function updateShippingCarrier(id, data) {
1392
- const db = getDb();
1393
- const [carrier] = await db
1394
- .update(schema.shippingCarriers)
1395
- .set({ ...data, updatedAt: new Date() })
1396
- .where(eq(schema.shippingCarriers.id, id))
1397
- .returning();
1398
- return carrier || null;
1399
- }
1400
- /**
1401
- * Delete a shipping carrier (cascades to zones and rates)
1402
- */
1403
- export async function deleteShippingCarrier(id) {
1404
- const db = getDb();
1405
- const result = await db
1406
- .delete(schema.shippingCarriers)
1407
- .where(eq(schema.shippingCarriers.id, id))
1408
- .returning({ id: schema.shippingCarriers.id });
1409
- return result.length > 0;
1410
- }
1411
- /**
1412
- * Find all carriers with their zones and rates (full hierarchy for admin UI)
1413
- */
1414
- export async function findCarriersWithZonesAndRates() {
1415
- const carriers = await findShippingCarriers();
1416
- const zones = await findShippingZones();
1417
- // Group zones by carrier
1418
- const zonesByCarrier = new Map();
1419
- for (const zone of zones) {
1420
- if (!zone.carrierId)
1421
- continue;
1422
- const existing = zonesByCarrier.get(zone.carrierId) || [];
1423
- existing.push(zone);
1424
- zonesByCarrier.set(zone.carrierId, existing);
1425
- }
1426
- return carriers.map((carrier) => ({
1427
- ...carrier,
1428
- zones: zonesByCarrier.get(carrier.id) || [],
1429
- }));
1430
- }
1431
- /**
1432
- * Find all shipping zones with their rates and carrier info
1433
- */
1434
- export async function findShippingZones() {
1435
- const db = getDb();
1436
- // Get all zones with carrier info via join
1437
- const zonesWithCarriers = await db
1438
- .select({
1439
- zone: schema.shippingZones,
1440
- carrier: {
1441
- id: schema.shippingCarriers.id,
1442
- name: schema.shippingCarriers.name,
1443
- code: schema.shippingCarriers.code,
1444
- },
1445
- })
1446
- .from(schema.shippingZones)
1447
- .leftJoin(schema.shippingCarriers, eq(schema.shippingZones.carrierId, schema.shippingCarriers.id))
1448
- .orderBy(asc(schema.shippingZones.sortOrder), asc(schema.shippingZones.name));
1449
- // Get all rates
1450
- const rates = await db
1451
- .select()
1452
- .from(schema.shippingRates)
1453
- .orderBy(asc(schema.shippingRates.sortOrder), asc(schema.shippingRates.name));
1454
- // Group rates by zone
1455
- const ratesByZone = new Map();
1456
- for (const rate of rates) {
1457
- const existing = ratesByZone.get(rate.zoneId) || [];
1458
- existing.push(rate);
1459
- ratesByZone.set(rate.zoneId, existing);
1460
- }
1461
- // Combine zones with their rates and carrier info
1462
- return zonesWithCarriers.map(({ zone, carrier }) => ({
1463
- id: zone.id,
1464
- carrierId: zone.carrierId,
1465
- carrier: carrier ? {
1466
- id: carrier.id,
1467
- name: carrier.name,
1468
- code: carrier.code,
1469
- } : undefined,
1470
- name: zone.name,
1471
- countries: zone.countries || [],
1472
- isActive: zone.isActive,
1473
- sortOrder: zone.sortOrder,
1474
- createdAt: zone.createdAt,
1475
- updatedAt: zone.updatedAt,
1476
- rates: (ratesByZone.get(zone.id) || []).map((rate) => ({
1477
- id: rate.id,
1478
- name: rate.name,
1479
- description: rate.description,
1480
- price: Number(rate.price),
1481
- minOrderAmount: rate.minOrderAmount ? Number(rate.minOrderAmount) : null,
1482
- maxOrderAmount: rate.maxOrderAmount ? Number(rate.maxOrderAmount) : null,
1483
- estimatedDays: rate.estimatedDays,
1484
- isActive: rate.isActive,
1485
- sortOrder: rate.sortOrder,
1486
- })),
1487
- }));
1488
- }
1489
- /**
1490
- * Find active shipping zones only
1491
- */
1492
- export async function findActiveShippingZones() {
1493
- const allZones = await findShippingZones();
1494
- return allZones.filter((zone) => zone.isActive);
1495
- }
1496
- /**
1497
- * Find a shipping zone by ID
1498
- */
1499
- export async function findShippingZoneById(id) {
1500
- const zones = await findShippingZones();
1501
- return zones.find((z) => z.id === id) || null;
1502
- }
1503
- /**
1504
- * Create a new shipping zone under a carrier
1505
- */
1506
- export async function createShippingZone(data) {
1507
- const db = getDb();
1508
- const [zone] = await db
1509
- .insert(schema.shippingZones)
1510
- .values({
1511
- carrierId: data.carrierId,
1512
- name: data.name,
1513
- countries: data.countries,
1514
- isActive: data.isActive ?? true,
1515
- sortOrder: data.sortOrder ?? 0,
1516
- })
1517
- .returning();
1518
- return zone;
1519
- }
1520
- /**
1521
- * Update a shipping zone
1522
- */
1523
- export async function updateShippingZone(id, data) {
1524
- const db = getDb();
1525
- const [zone] = await db
1526
- .update(schema.shippingZones)
1527
- .set({ ...data, updatedAt: new Date() })
1528
- .where(eq(schema.shippingZones.id, id))
1529
- .returning();
1530
- return zone || null;
1531
- }
1532
- /**
1533
- * Delete a shipping zone (cascades to rates)
1534
- */
1535
- export async function deleteShippingZone(id) {
1536
- const db = getDb();
1537
- const result = await db
1538
- .delete(schema.shippingZones)
1539
- .where(eq(schema.shippingZones.id, id))
1540
- .returning({ id: schema.shippingZones.id });
1541
- return result.length > 0;
1542
- }
1543
- /**
1544
- * Create a shipping rate for a zone
1545
- */
1546
- export async function createShippingRate(data) {
1547
- const db = getDb();
1548
- const [rate] = await db
1549
- .insert(schema.shippingRates)
1550
- .values({
1551
- zoneId: data.zoneId,
1552
- name: data.name,
1553
- description: data.description || null,
1554
- price: String(data.price),
1555
- minOrderAmount: data.minOrderAmount !== undefined ? String(data.minOrderAmount) : null,
1556
- maxOrderAmount: data.maxOrderAmount !== undefined ? String(data.maxOrderAmount) : null,
1557
- estimatedDays: data.estimatedDays || null,
1558
- isActive: data.isActive ?? true,
1559
- sortOrder: data.sortOrder ?? 0,
1560
- })
1561
- .returning();
1562
- return rate;
1563
- }
1564
- /**
1565
- * Update a shipping rate
1566
- */
1567
- export async function updateShippingRate(id, data) {
1568
- const db = getDb();
1569
- const updateData = {};
1570
- if (data.name !== undefined)
1571
- updateData.name = data.name;
1572
- if (data.description !== undefined)
1573
- updateData.description = data.description;
1574
- if (data.price !== undefined)
1575
- updateData.price = String(data.price);
1576
- if (data.minOrderAmount !== undefined)
1577
- updateData.minOrderAmount = data.minOrderAmount !== null ? String(data.minOrderAmount) : null;
1578
- if (data.maxOrderAmount !== undefined)
1579
- updateData.maxOrderAmount = data.maxOrderAmount !== null ? String(data.maxOrderAmount) : null;
1580
- if (data.estimatedDays !== undefined)
1581
- updateData.estimatedDays = data.estimatedDays;
1582
- if (data.isActive !== undefined)
1583
- updateData.isActive = data.isActive;
1584
- if (data.sortOrder !== undefined)
1585
- updateData.sortOrder = data.sortOrder;
1586
- const [rate] = await db
1587
- .update(schema.shippingRates)
1588
- .set(updateData)
1589
- .where(eq(schema.shippingRates.id, id))
1590
- .returning();
1591
- return rate || null;
1592
- }
1593
- /**
1594
- * Delete a shipping rate
1595
- */
1596
- export async function deleteShippingRate(id) {
1597
- const db = getDb();
1598
- const result = await db
1599
- .delete(schema.shippingRates)
1600
- .where(eq(schema.shippingRates.id, id))
1601
- .returning({ id: schema.shippingRates.id });
1602
- return result.length > 0;
1603
- }
1604
- /**
1605
- * Find shipping rates applicable to a specific country and order amount.
1606
- * Used during checkout to determine which shipping options to show.
1607
- *
1608
- * @param country - ISO country code (e.g., 'US', 'CA')
1609
- * @param orderAmount - Order subtotal in dollars
1610
- * @returns Array of applicable shipping rates with carrier info
1611
- */
1612
- export async function findShippingRatesForCountry(country, orderAmount) {
1613
- const zones = await findActiveShippingZones();
1614
- const applicableRates = [];
1615
- for (const zone of zones) {
1616
- // Skip zones without a carrier (shouldn't happen, but defensive)
1617
- if (!zone.carrier)
1618
- continue;
1619
- // Check if zone covers this country
1620
- // '*' means all countries (international catch-all)
1621
- const coversCountry = zone.countries.includes('*') || zone.countries.includes(country.toUpperCase());
1622
- if (!coversCountry)
1623
- continue;
1624
- // Get active rates that match the order amount
1625
- for (const rate of zone.rates) {
1626
- if (!rate.isActive)
1627
- continue;
1628
- // Check min/max order amount constraints
1629
- if (rate.minOrderAmount !== null && orderAmount < rate.minOrderAmount)
1630
- continue;
1631
- if (rate.maxOrderAmount !== null && orderAmount > rate.maxOrderAmount)
1632
- continue;
1633
- applicableRates.push({
1634
- id: rate.id,
1635
- carrierId: zone.carrierId,
1636
- carrierName: zone.carrier.name,
1637
- carrierCode: zone.carrier.code,
1638
- zoneName: zone.name,
1639
- name: rate.name,
1640
- description: rate.description,
1641
- price: rate.price,
1642
- estimatedDays: rate.estimatedDays,
1643
- });
1644
- }
1645
- }
1646
- return applicableRates;
1647
- }
1648
- /**
1649
- * Find shipping options for checkout grouped by carrier.
1650
- * This is the main function used by the pre-checkout flow.
1651
- *
1652
- * @param country - ISO country code (e.g., 'US', 'CA')
1653
- * @param orderAmount - Order subtotal in dollars
1654
- * @returns Shipping options grouped by carrier
1655
- */
1656
- export async function findShippingOptionsForCountry(country, orderAmount) {
1657
- const rates = await findShippingRatesForCountry(country, orderAmount);
1658
- // Group by carrier
1659
- const carrierMap = new Map();
1660
- for (const rate of rates) {
1661
- let group = carrierMap.get(rate.carrierId);
1662
- if (!group) {
1663
- group = {
1664
- carrier: {
1665
- id: rate.carrierId,
1666
- name: rate.carrierName,
1667
- code: rate.carrierCode,
1668
- },
1669
- options: [],
1670
- };
1671
- carrierMap.set(rate.carrierId, group);
1672
- }
1673
- group.options.push({
1674
- id: rate.id,
1675
- carrierId: rate.carrierId,
1676
- carrierName: rate.carrierName,
1677
- carrierCode: rate.carrierCode,
1678
- name: rate.name,
1679
- description: rate.description ?? undefined,
1680
- price: rate.price,
1681
- estimatedDays: rate.estimatedDays ?? undefined,
1682
- source: 'manual',
1683
- });
1684
- }
1685
- // Convert to array and sort by carrier name
1686
- return Array.from(carrierMap.values()).sort((a, b) => a.carrier.name.localeCompare(b.carrier.name));
1687
- }
1688
- /**
1689
- * Find all tax zones ordered by priority (sortOrder ascending)
1690
- */
1691
- export async function findTaxZones() {
1692
- const db = getDb();
1693
- const zones = await db
1694
- .select()
1695
- .from(schema.taxZones)
1696
- .orderBy(asc(schema.taxZones.sortOrder), asc(schema.taxZones.name));
1697
- return zones.map((zone) => ({
1698
- id: zone.id,
1699
- name: zone.name,
1700
- countries: zone.countries || [],
1701
- states: zone.states || [],
1702
- taxRate: Number(zone.taxRate),
1703
- isActive: zone.isActive,
1704
- sortOrder: zone.sortOrder,
1705
- createdAt: zone.createdAt,
1706
- updatedAt: zone.updatedAt,
1707
- }));
1708
- }
1709
- /**
1710
- * Find only active tax zones
1711
- */
1712
- export async function findActiveTaxZones() {
1713
- const allZones = await findTaxZones();
1714
- return allZones.filter((zone) => zone.isActive);
1715
- }
1716
- /**
1717
- * Find a tax zone by ID
1718
- */
1719
- export async function findTaxZoneById(id) {
1720
- const zones = await findTaxZones();
1721
- return zones.find((z) => z.id === id) || null;
1722
- }
1723
- /**
1724
- * Create a new tax zone
1725
- */
1726
- export async function createTaxZone(data) {
1727
- const db = getDb();
1728
- const [zone] = await db
1729
- .insert(schema.taxZones)
1730
- .values({
1731
- name: data.name,
1732
- countries: data.countries.map((c) => c.toUpperCase()),
1733
- states: (data.states || []).map((s) => s.toUpperCase()),
1734
- taxRate: String(data.taxRate),
1735
- isActive: data.isActive ?? true,
1736
- sortOrder: data.sortOrder ?? 0,
1737
- })
1738
- .returning();
1739
- return zone;
1740
- }
1741
- /**
1742
- * Update a tax zone
1743
- */
1744
- export async function updateTaxZone(id, data) {
1745
- const db = getDb();
1746
- const updateData = { updatedAt: new Date() };
1747
- if (data.name !== undefined)
1748
- updateData.name = data.name;
1749
- if (data.countries !== undefined)
1750
- updateData.countries = data.countries.map((c) => c.toUpperCase());
1751
- if (data.states !== undefined)
1752
- updateData.states = data.states.map((s) => s.toUpperCase());
1753
- if (data.taxRate !== undefined)
1754
- updateData.taxRate = String(data.taxRate);
1755
- if (data.isActive !== undefined)
1756
- updateData.isActive = data.isActive;
1757
- if (data.sortOrder !== undefined)
1758
- updateData.sortOrder = data.sortOrder;
1759
- const [zone] = await db
1760
- .update(schema.taxZones)
1761
- .set(updateData)
1762
- .where(eq(schema.taxZones.id, id))
1763
- .returning();
1764
- return zone || null;
1765
- }
1766
- /**
1767
- * Delete a tax zone
1768
- */
1769
- export async function deleteTaxZone(id) {
1770
- const db = getDb();
1771
- const result = await db
1772
- .delete(schema.taxZones)
1773
- .where(eq(schema.taxZones.id, id))
1774
- .returning({ id: schema.taxZones.id });
1775
- return result.length > 0;
1776
- }
1777
- /**
1778
- * Find the applicable tax rate for a given address.
1779
- * Returns the first matching zone based on priority (sortOrder).
1780
- *
1781
- * Matching logic:
1782
- * 1. For US addresses: Match country='US' AND state matches (if zone has states)
1783
- * 2. For non-US addresses: Match country only
1784
- * 3. Wildcard '*' in countries matches any country
1785
- *
1786
- * @param country - ISO-2 country code (e.g., 'US', 'FR')
1787
- * @param state - State/province code for US (e.g., 'CA', 'NY')
1788
- * @returns Tax rate info or null if no matching zone
1789
- */
1790
- export async function findTaxRateForAddress(country, state) {
1791
- const zones = await findActiveTaxZones();
1792
- const upperCountry = country.toUpperCase();
1793
- const upperState = state?.toUpperCase() || '';
1794
- for (const zone of zones) {
1795
- // Check if zone covers this country
1796
- const hasWildcard = zone.countries.includes('*');
1797
- const hasCountry = zone.countries.includes(upperCountry);
1798
- if (!hasWildcard && !hasCountry)
1799
- continue;
1800
- // For US addresses: If zone has specific states, require state match
1801
- if (upperCountry === 'US' && zone.states.length > 0) {
1802
- if (!upperState || !zone.states.includes(upperState)) {
1803
- continue; // Zone requires specific US states that don't match
1804
- }
1805
- }
1806
- // Found a matching zone
1807
- return {
1808
- zoneId: zone.id,
1809
- zoneName: zone.name,
1810
- taxRate: zone.taxRate,
1811
- };
1812
- }
1813
- return null; // No matching tax zone
1814
- }
1815
- /**
1816
- * Runtime self-heal for the `onboarding` column. Stores generated before this
1817
- * column shipped don't have it; this idempotent migration adds it on first
1818
- * call and caches success in-process so subsequent calls are no-ops.
1819
- *
1820
- * Same pattern as the analytics JSONB self-heal documented in CLAUDE.md §27.
1821
- * No fleet rollout needed — the column appears on each store's first hit
1822
- * to the setup-guide endpoint or the writeback hooks.
1823
- */
1824
- let onboardingColumnEnsured = false;
1825
- export async function ensureOnboardingColumn() {
1826
- if (onboardingColumnEnsured)
1827
- return;
1828
- const db = getDb();
1829
- try {
1830
- await db.execute(sql `
1831
- ALTER TABLE store_settings
1832
- ADD COLUMN IF NOT EXISTS onboarding jsonb NOT NULL DEFAULT '{}'::jsonb
1833
- `);
1834
- onboardingColumnEnsured = true;
1835
- }
1836
- catch (err) {
1837
- // Don't poison the cache on transient failures — try again next call.
1838
- console.error('[ensureOnboardingColumn] migration failed:', err);
1839
- throw err;
1840
- }
1841
- }
1842
- /**
1843
- * Read the onboarding JSONB. Returns `{}` when the row is missing or the
1844
- * column hasn't been initialized yet (legacy stores). Always safe to call.
1845
- */
1846
- export async function getOnboardingState() {
1847
- await ensureOnboardingColumn();
1848
- const db = getDb();
1849
- const rows = await db
1850
- .select({ onboarding: schema.storeSettings.onboarding })
1851
- .from(schema.storeSettings)
1852
- .limit(1);
1853
- return (rows[0]?.onboarding ?? {});
1854
- }
1855
- /**
1856
- * Set or clear a single key on the onboarding JSONB. Uses `jsonb_set` so it
1857
- * never clobbers other keys written by parallel requests. Safe to call
1858
- * fire-and-forget from mutating API routes (products POST/PUT, settings PUT).
1859
- */
1860
- export async function setOnboardingFlag(key, value) {
1861
- await ensureOnboardingColumn();
1862
- const db = getDb();
1863
- // jsonb_set with create_missing=true so the column starts at '{}' and
1864
- // gradually accretes keys. We JSON-stringify the value first so that
1865
- // booleans, numbers, strings, and null all round-trip with their proper
1866
- // JSONB types. Earlier versions used `to_jsonb(value::text)::jsonb`
1867
- // which incorrectly produced JSONB string `"true"` for boolean true —
1868
- // breaking strict-equality reads in the GET handler so the setup-guide
1869
- // tasks never marked complete.
1870
- const jsonValue = JSON.stringify(value);
1871
- await db.execute(sql `
1872
- UPDATE store_settings
1873
- SET onboarding = jsonb_set(
1874
- COALESCE(onboarding, '{}'::jsonb),
1875
- ${sql.raw(`'{${String(key)}}'`)},
1876
- ${jsonValue}::jsonb,
1877
- true
1878
- )
1879
- `);
1880
- }
1881
- /**
1882
- * Aggregated signal counts used by the setup-guide GET handler. One round-trip
1883
- * via Promise.all instead of four sequential queries.
1884
- */
1885
- export async function getSetupGuideSignals() {
1886
- await ensureOnboardingColumn();
1887
- const db = getDb();
1888
- const [products, shipping, tax, admins, settings] = await Promise.all([
1889
- db
1890
- .select({ count: sql `count(*)` })
1891
- .from(schema.products),
1892
- db
1893
- .select({ count: sql `count(*)` })
1894
- .from(schema.shippingZones)
1895
- .where(eq(schema.shippingZones.isActive, true)),
1896
- db
1897
- .select({ count: sql `count(*)` })
1898
- .from(schema.taxZones)
1899
- .where(eq(schema.taxZones.isActive, true)),
1900
- db
1901
- .select({ count: sql `count(*)` })
1902
- .from(schema.storeAdmins),
1903
- db
1904
- .select({
1905
- logoUrl: schema.storeSettings.logoUrl,
1906
- // `analytics` is self-healed by the pixel cards (see CLAUDE.md §27);
1907
- // we read it via raw SQL so the SDK works on stores where the
1908
- // column doesn't exist yet — the COALESCE keeps that path safe.
1909
- analytics: sql `COALESCE(
1910
- (SELECT analytics FROM store_settings LIMIT 1),
1911
- '{}'::jsonb
1912
- )`,
1913
- onboarding: schema.storeSettings.onboarding,
1914
- })
1915
- .from(schema.storeSettings)
1916
- .limit(1),
1917
- ]);
1918
- return {
1919
- productCount: Number(products[0]?.count || 0),
1920
- shippingZonesCount: Number(shipping[0]?.count || 0),
1921
- taxZonesCount: Number(tax[0]?.count || 0),
1922
- adminCount: Number(admins[0]?.count || 0),
1923
- storeSettings: settings[0]
1924
- ? {
1925
- logoUrl: settings[0].logoUrl ?? null,
1926
- analytics: settings[0].analytics ?? {},
1927
- onboarding: settings[0].onboarding ?? {},
1928
- }
1929
- : null,
1930
- };
1931
- }
1932
- //# sourceMappingURL=queries.js.map