@nextblock-cms/ecom 0.8.6 → 0.8.11

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 (277) hide show
  1. package/index.cjs.js +1 -1
  2. package/index.es.js +136 -533
  3. package/lib/CurrencyProvider.cjs.js +1 -0
  4. package/lib/CurrencyProvider.es.js +99 -0
  5. package/lib/cart-store.cjs.js +1 -0
  6. package/{cart-store.es.js → lib/cart-store.es.js} +13 -13
  7. package/lib/components/AccountNavigationMenu.cjs.js +1 -0
  8. package/lib/components/AccountNavigationMenu.es.js +44 -0
  9. package/lib/components/AddToCartButton.cjs.js +1 -0
  10. package/{AddToCartButton-ffE0DhHu.js → lib/components/AddToCartButton.es.js} +14 -13
  11. package/lib/components/Cart.cjs.js +1 -0
  12. package/lib/components/Cart.es.js +148 -0
  13. package/lib/components/CartDrawer.cjs.js +1 -0
  14. package/{components → lib/components}/CartDrawer.es.js +15 -14
  15. package/{components → lib/components}/CartIcon.cjs.js +1 -1
  16. package/{components → lib/components}/CartIcon.es.js +1 -0
  17. package/lib/components/Checkout.cjs.js +1 -0
  18. package/{components → lib/components}/Checkout.es.js +330 -363
  19. package/lib/components/CouponForm.cjs.js +1 -0
  20. package/lib/components/CouponForm.es.js +136 -0
  21. package/lib/components/CurrencySwitcher.cjs.js +1 -0
  22. package/{components → lib/components}/CurrencySwitcher.es.js +5 -4
  23. package/lib/components/CustomerProfileForm.cjs.js +1 -0
  24. package/lib/components/CustomerProfileForm.es.js +355 -0
  25. package/lib/components/FeaturedProduct.cjs.js +1 -0
  26. package/{components → lib/components}/FeaturedProduct.es.js +9 -8
  27. package/lib/components/InvoiceDocument.cjs.js +1 -0
  28. package/lib/components/InvoiceDocument.es.js +196 -0
  29. package/lib/components/InvoiceViewerShell.cjs.js +29 -0
  30. package/lib/components/InvoiceViewerShell.es.js +100 -0
  31. package/lib/components/ProductCard.cjs.js +1 -0
  32. package/lib/components/ProductCard.es.js +119 -0
  33. package/lib/components/ProductDetailsLayout.cjs.js +1 -0
  34. package/lib/components/ProductDetailsLayout.es.js +361 -0
  35. package/lib/components/ProductGallery.cjs.js +1 -0
  36. package/lib/components/ProductGallery.es.js +41 -0
  37. package/lib/components/ProductGrid.cjs.js +1 -0
  38. package/lib/components/ProductGrid.es.js +19 -0
  39. package/lib/components/ShippingEstimator.cjs.js +1 -0
  40. package/lib/components/ShippingEstimator.es.js +125 -0
  41. package/lib/components/SubscriptionSelector.cjs.js +1 -0
  42. package/lib/components/SubscriptionSelector.es.js +140 -0
  43. package/lib/countries.cjs.js +1 -0
  44. package/lib/countries.es.js +77 -0
  45. package/lib/coupon-server.cjs.js +1 -0
  46. package/{coupon-server-DUKVtyYs.js → lib/coupon-server.es.js} +68 -82
  47. package/lib/coupons.cjs.js +1 -0
  48. package/lib/coupons.es.js +17 -0
  49. package/lib/currency-store.cjs.js +1 -0
  50. package/lib/currency-store.es.js +27 -0
  51. package/lib/currency-sync.cjs.js +1 -0
  52. package/lib/currency-sync.es.js +180 -0
  53. package/lib/customer-addresses.cjs.js +1 -0
  54. package/lib/customer-addresses.es.js +116 -0
  55. package/lib/customer-orders.cjs.js +1 -0
  56. package/lib/customer-orders.es.js +45 -0
  57. package/lib/customer.cjs.js +1 -0
  58. package/{customer-C3xccjUg.js → lib/customer.es.js} +15 -14
  59. package/lib/export-helpers.cjs.js +1 -0
  60. package/lib/export-helpers.es.js +56 -0
  61. package/lib/factory.cjs.js +1 -0
  62. package/lib/factory.es.js +8 -0
  63. package/lib/freemius-coupons.cjs.js +1 -0
  64. package/lib/freemius-coupons.es.js +272 -0
  65. package/lib/freemius-order-sync.cjs.js +1 -0
  66. package/lib/freemius-order-sync.es.js +284 -0
  67. package/lib/inventory-settings.cjs.js +1 -0
  68. package/lib/inventory-settings.es.js +86 -0
  69. package/lib/invoice-server.cjs.js +33 -0
  70. package/lib/invoice-server.es.js +141 -0
  71. package/lib/invoice-ui.cjs.js +1 -0
  72. package/lib/invoice-ui.es.js +71 -0
  73. package/lib/invoice.cjs.js +1 -0
  74. package/lib/invoice.es.js +102 -0
  75. package/lib/order-inventory.cjs.js +61 -0
  76. package/lib/order-inventory.es.js +128 -0
  77. package/lib/order-tax-details.cjs.js +1 -0
  78. package/lib/order-tax-details.es.js +164 -0
  79. package/lib/pages/cms/coupons/CouponEditorForm.cjs.js +1 -0
  80. package/lib/pages/cms/coupons/CouponEditorForm.es.js +189 -0
  81. package/lib/pages/cms/coupons/CouponsPage.cjs.js +5 -0
  82. package/lib/pages/cms/coupons/CouponsPage.es.js +171 -0
  83. package/lib/pages/cms/coupons/CreateCouponDialog.cjs.js +1 -0
  84. package/lib/pages/cms/coupons/CreateCouponDialog.es.js +35 -0
  85. package/lib/pages/cms/coupons/EditCouponPage.cjs.js +1 -0
  86. package/lib/pages/cms/coupons/EditCouponPage.es.js +48 -0
  87. package/lib/pages/cms/coupons/ProductScopePicker.cjs.js +1 -0
  88. package/lib/pages/cms/coupons/ProductScopePicker.es.js +120 -0
  89. package/lib/pages/cms/coupons/actions.cjs.js +1 -0
  90. package/lib/pages/cms/coupons/actions.es.js +128 -0
  91. package/lib/pages/cms/coupons/product-options.cjs.js +1 -0
  92. package/lib/pages/cms/coupons/product-options.es.js +27 -0
  93. package/lib/pages/cms/orders/ExportReportsDialog.cjs.js +1 -0
  94. package/lib/pages/cms/orders/ExportReportsDialog.es.js +130 -0
  95. package/lib/pages/cms/orders/OrderDetailPage.cjs.js +1 -0
  96. package/lib/pages/cms/orders/OrderDetailPage.es.js +137 -0
  97. package/lib/pages/cms/orders/OrderPrintButton.cjs.js +1 -0
  98. package/lib/pages/cms/orders/OrderPrintButton.es.js +22 -0
  99. package/lib/pages/cms/orders/OrderStatusForm.cjs.js +1 -0
  100. package/lib/pages/cms/orders/OrderStatusForm.es.js +71 -0
  101. package/lib/pages/cms/orders/OrdersPage.cjs.js +1 -0
  102. package/lib/pages/cms/orders/OrdersPage.es.js +104 -0
  103. package/lib/pages/cms/orders/actions.cjs.js +7 -0
  104. package/lib/pages/cms/orders/actions.es.js +71 -0
  105. package/lib/pages/cms/orders/export-actions.cjs.js +1 -0
  106. package/lib/pages/cms/orders/export-actions.es.js +27 -0
  107. package/lib/pages/cms/orders/server-actions.cjs.js +1 -0
  108. package/lib/pages/cms/orders/server-actions.es.js +55 -0
  109. package/lib/pages/cms/payments/PaymentsClient.cjs.js +1 -0
  110. package/lib/pages/cms/payments/PaymentsClient.es.js +188 -0
  111. package/lib/pages/cms/payments/PaymentsPage.cjs.js +1 -0
  112. package/lib/pages/cms/payments/PaymentsPage.es.js +29 -0
  113. package/lib/pages/cms/payments/actions.cjs.js +1 -0
  114. package/lib/pages/cms/payments/actions.es.js +23 -0
  115. package/lib/pages/cms/payments/queries.cjs.js +1 -0
  116. package/lib/pages/cms/payments/queries.es.js +30 -0
  117. package/lib/pages/cms/products/ProductsPage.cjs.js +1 -0
  118. package/lib/pages/cms/products/ProductsPage.es.js +46 -0
  119. package/lib/pages/cms/products/_id_/edit/EditProductPage.cjs.js +1 -0
  120. package/lib/pages/cms/products/_id_/edit/EditProductPage.es.js +156 -0
  121. package/lib/pages/cms/products/actions.cjs.js +44 -0
  122. package/lib/pages/cms/products/actions.es.js +175 -0
  123. package/lib/pages/cms/products/attributes/AttributeManagementPage.cjs.js +1 -0
  124. package/lib/pages/cms/products/attributes/AttributeManagementPage.es.js +48 -0
  125. package/lib/pages/cms/products/attributes/components/AttributeManager.cjs.js +1 -0
  126. package/lib/pages/cms/products/attributes/components/AttributeManager.es.js +291 -0
  127. package/lib/pages/cms/products/categories/CategoryManagementPage.cjs.js +1 -0
  128. package/lib/pages/cms/products/categories/CategoryManagementPage.es.js +36 -0
  129. package/lib/pages/cms/products/categories/components/CategoryManager.cjs.js +1 -0
  130. package/lib/pages/cms/products/categories/components/CategoryManager.es.js +263 -0
  131. package/lib/pages/cms/products/components/CopyProductFromLanguage.cjs.js +1 -0
  132. package/lib/pages/cms/products/components/CopyProductFromLanguage.es.js +114 -0
  133. package/lib/pages/cms/products/components/CurrencyPriceFields.cjs.js +1 -0
  134. package/lib/pages/cms/products/components/CurrencyPriceFields.es.js +107 -0
  135. package/lib/pages/cms/products/components/DeleteProductButton.cjs.js +1 -0
  136. package/lib/pages/cms/products/components/DeleteProductButton.es.js +48 -0
  137. package/lib/pages/cms/products/components/FreemiusPricingDashboard.cjs.js +1 -0
  138. package/lib/pages/cms/products/components/FreemiusPricingDashboard.es.js +86 -0
  139. package/lib/pages/cms/products/components/ProductCategorySelector.cjs.js +1 -0
  140. package/lib/pages/cms/products/components/ProductCategorySelector.es.js +160 -0
  141. package/lib/pages/cms/products/components/ProductForm.cjs.js +1 -0
  142. package/lib/pages/cms/products/components/ProductForm.es.js +702 -0
  143. package/lib/pages/cms/products/components/ProductMediaManager.cjs.js +1 -0
  144. package/lib/pages/cms/products/components/ProductMediaManager.es.js +104 -0
  145. package/lib/pages/cms/products/components/ProductsBulkTable.cjs.js +1 -0
  146. package/lib/pages/cms/products/components/ProductsBulkTable.es.js +228 -0
  147. package/lib/pages/cms/products/components/SaleScheduleFields.cjs.js +1 -0
  148. package/lib/pages/cms/products/components/SaleScheduleFields.es.js +137 -0
  149. package/lib/pages/cms/products/components/SyncFreemiusButton.cjs.js +1 -0
  150. package/lib/pages/cms/products/components/SyncFreemiusButton.es.js +36 -0
  151. package/lib/pages/cms/products/components/SyncFreemiusPricingButton.cjs.js +1 -0
  152. package/lib/pages/cms/products/components/SyncFreemiusPricingButton.es.js +40 -0
  153. package/lib/pages/cms/products/components/VariationsEditor.cjs.js +1 -0
  154. package/lib/pages/cms/products/components/VariationsEditor.es.js +408 -0
  155. package/lib/pages/cms/products/inventory/InventoryPage.cjs.js +1 -0
  156. package/lib/pages/cms/products/inventory/InventoryPage.es.js +16 -0
  157. package/lib/pages/cms/products/inventory/InventoryTableClient.cjs.js +2 -0
  158. package/lib/pages/cms/products/inventory/InventoryTableClient.es.js +214 -0
  159. package/lib/pages/cms/products/inventory/actions.cjs.js +3 -0
  160. package/lib/pages/cms/products/inventory/actions.es.js +95 -0
  161. package/lib/pages/cms/products/new/NewProductPage.cjs.js +1 -0
  162. package/lib/pages/cms/products/new/NewProductPage.es.js +76 -0
  163. package/lib/pages/cms/products/product-price-sync.cjs.js +1 -0
  164. package/lib/pages/cms/products/product-price-sync.es.js +98 -0
  165. package/lib/pages/cms/products/server-actions.cjs.js +1 -0
  166. package/lib/pages/cms/products/server-actions.es.js +193 -0
  167. package/lib/pages/cms/shipping/ShippingPage.cjs.js +5 -0
  168. package/lib/pages/cms/shipping/ShippingPage.es.js +211 -0
  169. package/lib/pages/cms/shipping/components/RateForm.cjs.js +1 -0
  170. package/lib/pages/cms/shipping/components/RateForm.es.js +441 -0
  171. package/lib/pages/cms/shipping/components/ZoneForm.cjs.js +1 -0
  172. package/lib/pages/cms/shipping/components/ZoneForm.es.js +228 -0
  173. package/lib/pages/cms/shipping/server-actions.cjs.js +1 -0
  174. package/lib/pages/cms/shipping/server-actions.es.js +159 -0
  175. package/lib/pages/cms/taxes/TaxesPage.cjs.js +1 -0
  176. package/lib/pages/cms/taxes/TaxesPage.es.js +172 -0
  177. package/lib/pages/cms/taxes/actions.cjs.js +1 -0
  178. package/lib/pages/cms/taxes/actions.es.js +57 -0
  179. package/lib/pages/cms/taxes/components/TaxRateForm.cjs.js +1 -0
  180. package/lib/pages/cms/taxes/components/TaxRateForm.es.js +100 -0
  181. package/lib/product-actions.cjs.js +237 -0
  182. package/lib/product-actions.es.js +524 -0
  183. package/lib/product-context.cjs.js +1 -0
  184. package/lib/product-context.es.js +16 -0
  185. package/lib/product-schema.cjs.js +1 -0
  186. package/lib/product-schema.es.js +134 -0
  187. package/lib/providers/freemius.cjs.js +5 -0
  188. package/lib/providers/freemius.es.js +538 -0
  189. package/lib/providers/stripe.cjs.js +1 -0
  190. package/lib/providers/stripe.es.js +473 -0
  191. package/lib/server-actions/coupon-actions.cjs.js +1 -0
  192. package/lib/server-actions/coupon-actions.es.js +23 -0
  193. package/lib/server-actions/customer-actions.cjs.js +1 -0
  194. package/lib/server-actions/customer-actions.es.js +30 -0
  195. package/lib/server-actions/product-actions.cjs.js +1 -0
  196. package/{server-actions → lib/server-actions}/product-actions.es.js +5 -4
  197. package/lib/server-actions/shipping-actions.cjs.js +1 -0
  198. package/{shipping-actions-BnHjlo2q.js → lib/server-actions/shipping-actions.es.js} +9 -7
  199. package/lib/server-actions/tax-actions.cjs.js +1 -0
  200. package/lib/server-actions/tax-actions.es.js +40 -0
  201. package/lib/shared-inventory.cjs.js +15 -0
  202. package/lib/shared-inventory.es.js +171 -0
  203. package/lib/shipping/resolver.cjs.js +7 -0
  204. package/lib/shipping/resolver.es.js +62 -0
  205. package/lib/shipping-rate-currency.cjs.js +1 -0
  206. package/lib/shipping-rate-currency.es.js +72 -0
  207. package/lib/states.cjs.js +1 -0
  208. package/{states-DlHJezQ1.js → lib/states.es.js} +27 -100
  209. package/lib/stripe/checkout.cjs.js +1 -0
  210. package/lib/stripe/checkout.es.js +182 -0
  211. package/lib/stripe/client.cjs.js +1 -0
  212. package/lib/stripe/client.es.js +7 -0
  213. package/lib/stripe/order-sync.cjs.js +1 -0
  214. package/lib/stripe/order-sync.es.js +130 -0
  215. package/lib/stripe/webhooks.cjs.js +1 -0
  216. package/lib/stripe/webhooks.es.js +30 -0
  217. package/lib/tax-calculation.cjs.js +1 -0
  218. package/lib/tax-calculation.es.js +101 -0
  219. package/lib/trials.cjs.js +1 -0
  220. package/{trials-RDcRAZKx.js → lib/trials.es.js} +9 -9
  221. package/{use-cart.es.js → lib/use-cart.es.js} +1 -0
  222. package/lib/zod-config.cjs.js +1 -0
  223. package/lib/zod-config.es.js +6 -0
  224. package/package.json +6 -6
  225. package/server.cjs.js +1 -110
  226. package/server.es.js +178 -6052
  227. package/AddToCartButton-DsSEH9yp.cjs +0 -1
  228. package/CouponForm-BI_5SBHQ.js +0 -152
  229. package/CouponForm-D_uu2bLP.cjs +0 -1
  230. package/CurrencyProvider-Cg-Q6ucj.cjs +0 -1
  231. package/CurrencyProvider-OzlRN96V.js +0 -120
  232. package/CurrencyProvider.cjs.js +0 -1
  233. package/CurrencyProvider.es.js +0 -10
  234. package/ProductDetailsLayout-BxJH_BxR.cjs +0 -1
  235. package/ProductDetailsLayout-Dg8dRTYp.js +0 -530
  236. package/ProductGrid-BdL7iglO.cjs +0 -1
  237. package/ProductGrid-D3AWM8sr.js +0 -130
  238. package/actions-AHmBrS5e.cjs +0 -48
  239. package/actions-j5fuSZX-.js +0 -820
  240. package/cart-store.cjs.js +0 -1
  241. package/components/Cart.cjs.js +0 -1
  242. package/components/Cart.es.js +0 -259
  243. package/components/CartDrawer.cjs.js +0 -1
  244. package/components/Checkout.cjs.js +0 -1
  245. package/components/CurrencySwitcher.cjs.js +0 -1
  246. package/components/FeaturedProduct.cjs.js +0 -1
  247. package/components/ProductDetailsLayout.cjs.js +0 -1
  248. package/components/ProductDetailsLayout.es.js +0 -19
  249. package/components/ProductGrid.cjs.js +0 -1
  250. package/components/ProductGrid.es.js +0 -6
  251. package/coupon-server-C9ySm3I5.cjs +0 -1
  252. package/customer-C-UPvrYN.cjs +0 -1
  253. package/invoice-ui-CAnJPu6n.cjs +0 -29
  254. package/invoice-ui-DtpbTJE1.js +0 -2886
  255. package/product-actions-CONBF8i6.cjs +0 -251
  256. package/product-actions-DjlIWCMH.js +0 -691
  257. package/resolver-Fz_FKsfX.cjs +0 -7
  258. package/resolver-cfrCaHpE.js +0 -128
  259. package/server-actions/product-actions.cjs.js +0 -1
  260. package/shipping-actions-D6zt20gg.cjs +0 -1
  261. package/states-CWYRxV4B.cjs +0 -1
  262. package/tax-calculation-Dab89aHd.js +0 -181
  263. package/tax-calculation-MkDKOEkL.cjs +0 -1
  264. package/trials-DvZaOtNy.cjs +0 -1
  265. /package/{components → lib/components}/SimpleTiptapRenderer.cjs.js +0 -0
  266. /package/{components → lib/components}/SimpleTiptapRenderer.es.js +0 -0
  267. /package/{currency-constants.cjs.js → lib/currency-constants.cjs.js} +0 -0
  268. /package/{currency-constants.es.js → lib/currency-constants.es.js} +0 -0
  269. /package/{currency-rest-client-uolJxUkL.cjs → lib/currency-rest-client.cjs.js} +0 -0
  270. /package/{currency-rest-client-CwoqdgAP.js → lib/currency-rest-client.es.js} +0 -0
  271. /package/{currency.cjs.js → lib/currency.cjs.js} +0 -0
  272. /package/{currency.es.js → lib/currency.es.js} +0 -0
  273. /package/{types.cjs.js → lib/types.cjs.js} +0 -0
  274. /package/{types.es.js → lib/types.es.js} +0 -0
  275. /package/{use-cart.cjs.js → lib/use-cart.cjs.js} +0 -0
  276. /package/{variation-utils.cjs.js → lib/variation-utils.cjs.js} +0 -0
  277. /package/{variation-utils.es.js → lib/variation-utils.es.js} +0 -0
@@ -0,0 +1,524 @@
1
+ import { deleteMediaFiles as b } from "@nextblock-cms/utils/server";
2
+ import { syncSharedInventoryForSavedProduct as v } from "./shared-inventory.es.js";
3
+ import { normalizeCurrencyCode as E } from "@nextblock-cms/utils";
4
+ const g = (e) => Math.round(e * 100);
5
+ function h(e) {
6
+ return Object.entries(e || {}).reduce(
7
+ (t, [i, r]) => (typeof r == "number" && Number.isFinite(r) && r >= 0 && (t[E(i)] = g(r)), t),
8
+ {}
9
+ );
10
+ }
11
+ function F(e) {
12
+ return (e || []).map((t) => ({
13
+ id: t.id,
14
+ sku: t.sku,
15
+ upc: t.upc ?? null,
16
+ price: g(t.price),
17
+ sale_price: typeof t.sale_price == "number" && !isNaN(t.sale_price) ? g(t.sale_price) : null,
18
+ prices: h(t.prices),
19
+ sale_prices: h(t.sale_prices),
20
+ sale_start_at: t.sale_start_at ?? null,
21
+ sale_end_at: t.sale_end_at ?? null,
22
+ stock_quantity: t.stock_quantity,
23
+ main_media_id: t.main_media_id ?? null,
24
+ attribute_term_ids: t.attribute_term_ids
25
+ }));
26
+ }
27
+ function j(e, t) {
28
+ const r = e.product_type === "digital" && e.payment_provider === "freemius" ? Math.max(0, Number(e.trial_period_days ?? 0)) : 0;
29
+ return {
30
+ id: t,
31
+ product_type: e.product_type,
32
+ payment_provider: e.payment_provider,
33
+ title: e.title,
34
+ slug: e.slug,
35
+ sku: e.sku,
36
+ upc: e.upc ?? null,
37
+ stock: e.stock,
38
+ status: e.status,
39
+ short_description: e.short_description ?? null,
40
+ description_json: e.description_json ?? null,
41
+ metadata: {},
42
+ price: g(e.price),
43
+ sale_price: typeof e.sale_price == "number" && !isNaN(e.sale_price) ? g(e.sale_price) : null,
44
+ prices: h(e.prices),
45
+ sale_prices: h(e.sale_prices),
46
+ sale_start_at: e.sale_start_at ?? null,
47
+ sale_end_at: e.sale_end_at ?? null,
48
+ freemius_plan_id: e.freemius_plan_id ?? null,
49
+ freemius_product_id: e.freemius_product_id ?? null,
50
+ trial_period_days: r,
51
+ trial_requires_payment_method: r > 0 ? e.trial_requires_payment_method ?? !1 : !1,
52
+ is_taxable: e.is_taxable,
53
+ language_id: e.language_id,
54
+ translation_group_id: e.translation_group_id || void 0,
55
+ variants: F(e.variants)
56
+ };
57
+ }
58
+ async function x(e, t, i) {
59
+ const { error: r } = await e.from("products").update({
60
+ is_taxable: i,
61
+ updated_at: (/* @__PURE__ */ new Date()).toISOString()
62
+ }).eq("id", t);
63
+ if (r)
64
+ throw r;
65
+ }
66
+ async function P(e, t, i) {
67
+ const r = (/* @__PURE__ */ new Date()).toISOString(), { data: c } = await e.from("products").select("sku, sale_price, sale_prices").eq("id", t).maybeSingle(), s = c?.sku ?? i.sku, { data: a } = await e.from("products").select("id").eq("sku", s), d = (a ?? []).map((o) => o.id);
68
+ d.length === 0 && d.push(t);
69
+ const { error: n } = await e.from("products").update({
70
+ sale_price: c?.sale_price ?? null,
71
+ sale_prices: c?.sale_prices ?? null,
72
+ sale_start_at: i.sale_start_at ?? null,
73
+ sale_end_at: i.sale_end_at ?? null,
74
+ updated_at: r
75
+ }).in("id", d);
76
+ if (n)
77
+ throw n;
78
+ const _ = i.variants ?? [];
79
+ if (_.length === 0)
80
+ return;
81
+ const { data: l } = await e.from("product_variants").select("sku, sale_price, sale_prices").eq("product_id", t), u = new Map(
82
+ (l ?? []).map((o) => [o.sku, o])
83
+ );
84
+ for (const o of _) {
85
+ const p = u.get(o.sku);
86
+ if (!p)
87
+ continue;
88
+ const { error: m } = await e.from("product_variants").update({
89
+ sale_price: p.sale_price ?? null,
90
+ sale_prices: p.sale_prices ?? null,
91
+ sale_start_at: o.sale_start_at ?? null,
92
+ sale_end_at: o.sale_end_at ?? null,
93
+ updated_at: r
94
+ }).eq("sku", o.sku).in("product_id", d);
95
+ if (m)
96
+ throw m;
97
+ }
98
+ }
99
+ async function R(e, {
100
+ page: t = 1,
101
+ limit: i = 10,
102
+ search: r = "",
103
+ languageId: c,
104
+ categoryId: s
105
+ } = {}) {
106
+ const a = (t - 1) * i, d = a + i - 1;
107
+ let n = e.from("products").select(
108
+ "id, title, sku, upc, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at, is_taxable, product_type, payment_provider, short_description, stock, status, slug, language_id, translation_group_id, freemius_product_id, freemius_plan_id, trial_period_days, trial_requires_payment_method, product_media(media(file_path, object_key)), product_variants(id, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at), freemius_plans(id, name, title, freemius_pricing(id, license_quota, api_monthly_price, api_annual_price, api_lifetime_price, override_monthly_price, override_annual_price, override_lifetime_price, is_active)), product_categories(category:categories(id, name, slug, description, name_translations, description_translations))",
109
+ { count: "exact" }
110
+ ).range(a, d).order("created_at", { ascending: !1 });
111
+ if (c && (n = n.eq("language_id", c)), s) {
112
+ const { data: _, error: l } = await e.from("product_categories").select("product_id").eq("category_id", s);
113
+ if (l)
114
+ return { data: [], error: l, count: 0 };
115
+ const u = (_ || []).map((o) => o.product_id).filter(Boolean);
116
+ if (u.length === 0)
117
+ return { data: [], error: null, count: 0 };
118
+ n = n.in("id", u);
119
+ }
120
+ return r && (n = n.or(`title.ilike.%${r}%,sku.ilike.%${r}%`)), n;
121
+ }
122
+ async function T(e, t) {
123
+ return e.from("products").select(
124
+ `
125
+ *,
126
+ languages (
127
+ code
128
+ ),
129
+ product_media (
130
+ media_id,
131
+ sort_order,
132
+ media (
133
+ id,
134
+ file_path,
135
+ object_key,
136
+ file_name,
137
+ blur_data_url,
138
+ width,
139
+ height
140
+ )
141
+ ),
142
+ product_variants (
143
+ id,
144
+ sku,
145
+ upc,
146
+ main_media_id,
147
+ price,
148
+ prices,
149
+ sale_price,
150
+ sale_prices,
151
+ sale_start_at,
152
+ sale_end_at,
153
+ scheduled_price,
154
+ scheduled_prices,
155
+ scheduled_price_at,
156
+ stock_quantity,
157
+ media:main_media_id (
158
+ id,
159
+ file_path,
160
+ object_key,
161
+ description
162
+ ),
163
+ variant_attribute_mapping (
164
+ attribute_term_id,
165
+ product_attribute_terms (
166
+ id,
167
+ attribute_id,
168
+ value,
169
+ slug,
170
+ sort_order,
171
+ value_translations,
172
+ product_attributes (
173
+ id,
174
+ name,
175
+ slug,
176
+ name_translations
177
+ )
178
+ )
179
+ )
180
+ ),
181
+ freemius_plans (
182
+ id,
183
+ name,
184
+ title,
185
+ freemius_pricing (
186
+ id,
187
+ license_quota,
188
+ api_monthly_price,
189
+ api_annual_price,
190
+ api_lifetime_price,
191
+ override_monthly_price,
192
+ override_annual_price,
193
+ override_lifetime_price,
194
+ is_active
195
+ )
196
+ ),
197
+ product_categories (
198
+ category:categories (
199
+ id,
200
+ name,
201
+ slug,
202
+ description,
203
+ name_translations,
204
+ description_translations
205
+ )
206
+ )
207
+ `
208
+ ).eq("id", t).single();
209
+ }
210
+ async function N(e, t, i) {
211
+ const { data: r, error: c } = await e.from("products").select(
212
+ `
213
+ *,
214
+ languages (
215
+ id,
216
+ code,
217
+ is_default
218
+ ),
219
+ product_media (
220
+ media_id,
221
+ sort_order,
222
+ media (
223
+ id,
224
+ file_path,
225
+ object_key,
226
+ file_name,
227
+ blur_data_url,
228
+ width,
229
+ height
230
+ )
231
+ ),
232
+ product_variants (
233
+ id,
234
+ sku,
235
+ upc,
236
+ main_media_id,
237
+ price,
238
+ prices,
239
+ sale_price,
240
+ sale_prices,
241
+ sale_start_at,
242
+ sale_end_at,
243
+ scheduled_price,
244
+ scheduled_prices,
245
+ scheduled_price_at,
246
+ stock_quantity,
247
+ media:main_media_id (
248
+ id,
249
+ file_path,
250
+ object_key,
251
+ description
252
+ ),
253
+ variant_attribute_mapping (
254
+ attribute_term_id,
255
+ product_attribute_terms (
256
+ id,
257
+ attribute_id,
258
+ value,
259
+ slug,
260
+ sort_order,
261
+ value_translations,
262
+ product_attributes (
263
+ id,
264
+ name,
265
+ slug,
266
+ name_translations
267
+ )
268
+ )
269
+ )
270
+ ),
271
+ freemius_plans (
272
+ id,
273
+ name,
274
+ title,
275
+ freemius_pricing (
276
+ id,
277
+ license_quota,
278
+ api_monthly_price,
279
+ api_annual_price,
280
+ api_lifetime_price,
281
+ override_monthly_price,
282
+ override_annual_price,
283
+ override_lifetime_price,
284
+ is_active
285
+ )
286
+ ),
287
+ product_categories (
288
+ category:categories (
289
+ id,
290
+ name,
291
+ slug,
292
+ description,
293
+ name_translations,
294
+ description_translations
295
+ )
296
+ )
297
+ `
298
+ ).eq("slug", t);
299
+ if (c)
300
+ return { data: null, error: c };
301
+ if (!r || r.length === 0)
302
+ return { data: null, error: { message: "Product not found", code: "PGRST116" } };
303
+ let s = null;
304
+ return i && (s = r.find((a) => (Array.isArray(a.languages) ? a.languages[0] : a.languages)?.code === i)), s || (s = r.find((a) => (Array.isArray(a.languages) ? a.languages[0] : a.languages)?.is_default)), s || (s = r.find((a) => (Array.isArray(a.languages) ? a.languages[0] : a.languages)?.code === "en")), s || (s = r[0]), { data: s, error: null };
305
+ }
306
+ async function $(e, t) {
307
+ const { data: i, error: r } = await e.rpc("upsert_product_with_variants", {
308
+ product_payload: j(t)
309
+ });
310
+ if (r || !i) throw r || new Error("Failed to create product");
311
+ if (t.product_media && t.product_media.length > 0) {
312
+ const s = t.product_media.map((a, d) => ({
313
+ product_id: i,
314
+ media_id: a.media_id,
315
+ sort_order: d
316
+ }));
317
+ await e.from("product_media").insert(s);
318
+ } else t.media_id && await e.from("product_media").insert({
319
+ product_id: i,
320
+ media_id: t.media_id,
321
+ sort_order: 0
322
+ });
323
+ await x(e, i, t.is_taxable), await P(e, i, t), await v(i, t), t.category_ids !== void 0 && await S(e, i, t.category_ids);
324
+ const { data: c } = await e.from("products").select("*").eq("id", i).single();
325
+ return c;
326
+ }
327
+ async function D(e, t, i) {
328
+ const { data: r } = await e.from("product_media").select("media_id").eq("product_id", t), c = r?.map((o) => o.media_id) || [], { data: s, error: a } = await e.rpc("upsert_product_with_variants", {
329
+ product_payload: j(i, t)
330
+ });
331
+ if (a || !s) throw a || new Error("Failed to update product");
332
+ if (i.product_media) {
333
+ if (await e.from("product_media").delete().eq("product_id", t), i.product_media.length > 0) {
334
+ const o = i.product_media.map((p, m) => ({
335
+ product_id: t,
336
+ media_id: p.media_id,
337
+ sort_order: m
338
+ }));
339
+ await e.from("product_media").insert(o);
340
+ }
341
+ } else i.media_id && (await e.from("product_media").delete().eq("product_id", t), await e.from("product_media").insert({
342
+ product_id: t,
343
+ media_id: i.media_id,
344
+ sort_order: 0
345
+ }));
346
+ await x(e, s, i.is_taxable), await P(e, s, i);
347
+ const d = i.product_media ? i.product_media.map((o) => o.media_id) : i.media_id ? [i.media_id] : [], n = i.explicitly_removed_media_ids || [], _ = c.filter((o) => !d.includes(o)), l = Array.from(/* @__PURE__ */ new Set([..._, ...n]));
348
+ if (l.length > 0)
349
+ for (const o of l) {
350
+ const { count: p } = await e.from("product_media").select("*", { count: "exact", head: !0 }).eq("media_id", o);
351
+ if (p && p > 0) continue;
352
+ const { count: m } = await e.from("posts").select("*", { count: "exact", head: !0 }).eq("feature_image_id", o);
353
+ if (m && m > 0) continue;
354
+ const { count: y } = await e.from("logos").select("*", { count: "exact", head: !0 }).eq("media_id", o);
355
+ if (y && y > 0) continue;
356
+ const { count: w } = await e.from("product_variants").select("*", { count: "exact", head: !0 }).eq("main_media_id", o);
357
+ if (w && w > 0) continue;
358
+ const { data: f } = await e.from("media").select("object_key, variants").eq("id", o).single();
359
+ if (f) {
360
+ const q = [f.object_key];
361
+ f.variants && Array.isArray(f.variants) && f.variants.forEach((k) => {
362
+ k.objectKey && q.push(k.objectKey);
363
+ }), await b(q), await e.from("media").delete().eq("id", o);
364
+ }
365
+ }
366
+ await v(s, i), i.category_ids !== void 0 && await S(e, t, i.category_ids);
367
+ const { data: u } = await e.from("products").select("*").eq("id", s).single();
368
+ return u;
369
+ }
370
+ async function B(e, t) {
371
+ const { error: i } = await e.from("products").delete().eq("id", t);
372
+ if (i) throw i;
373
+ return !0;
374
+ }
375
+ async function U(e, t, i) {
376
+ const { data: r, error: c } = await e.from("products").select("*").eq("id", i).single();
377
+ if (c || !r)
378
+ throw new Error(c?.message || "Source product not found");
379
+ const { data: s, error: a } = await e.from("products").select("language_id").eq("id", t).single();
380
+ if (a || !s)
381
+ throw new Error(a?.message || "Target product not found");
382
+ const { error: d } = await e.from("products").update({
383
+ title: r.title,
384
+ short_description: r.short_description,
385
+ description_json: r.description_json
386
+ }).eq("id", t);
387
+ if (d) throw d;
388
+ const { data: n, error: _ } = await e.from("blocks").select("*").eq("product_id", i).order("order", { ascending: !0 });
389
+ if (_) throw _;
390
+ if (await e.from("blocks").delete().eq("product_id", t), n && n.length > 0) {
391
+ const u = n.map((p) => {
392
+ const { id: m, created_at: y, updated_at: w, ...f } = p;
393
+ return {
394
+ ...f,
395
+ product_id: t,
396
+ language_id: s.language_id
397
+ };
398
+ }), { error: o } = await e.from("blocks").insert(u);
399
+ if (o) throw o;
400
+ }
401
+ await e.from("product_drafts").delete().eq("product_id", t), await e.from("product_media").delete().eq("product_id", t);
402
+ const { data: l } = await e.from("product_media").select("media_id, sort_order").eq("product_id", i);
403
+ if (l && l.length > 0) {
404
+ const u = l.map((o) => ({
405
+ product_id: t,
406
+ media_id: o.media_id,
407
+ sort_order: o.sort_order
408
+ }));
409
+ await e.from("product_media").insert(u);
410
+ }
411
+ return { success: !0 };
412
+ }
413
+ async function z(e, t, i, r = [], c = []) {
414
+ const { data: s } = await e.from("languages").select("id").eq("code", i).single();
415
+ if (!s)
416
+ return { data: [], error: "Language not found" };
417
+ const a = [];
418
+ t.length > 0 && a.push(`translation_group_id.in.(${t.join(",")})`), r.length > 0 && a.push(`sku.in.(${r.map((_) => `"${_}"`).join(",")})`), c.length > 0 && a.push(`id.in.(${c.join(",")})`);
419
+ let d = e.from("products").select(`
420
+ id,
421
+ title,
422
+ sku,
423
+ price,
424
+ prices,
425
+ sale_price,
426
+ sale_prices,
427
+ sale_start_at,
428
+ sale_end_at,
429
+ scheduled_price,
430
+ scheduled_prices,
431
+ scheduled_price_at,
432
+ stock,
433
+ slug,
434
+ language_id,
435
+ product_type,
436
+ payment_provider,
437
+ freemius_product_id,
438
+ freemius_plan_id,
439
+ trial_period_days,
440
+ trial_requires_payment_method,
441
+ is_taxable,
442
+ product_media (
443
+ media (
444
+ file_path,
445
+ object_key
446
+ )
447
+ ),
448
+ product_variants (
449
+ id,
450
+ sku,
451
+ upc,
452
+ main_media_id,
453
+ price,
454
+ prices,
455
+ sale_price,
456
+ sale_prices,
457
+ sale_start_at,
458
+ sale_end_at,
459
+ scheduled_price,
460
+ scheduled_prices,
461
+ scheduled_price_at,
462
+ stock_quantity,
463
+ media:main_media_id (
464
+ file_path,
465
+ object_key,
466
+ description
467
+ ),
468
+ variant_attribute_mapping (
469
+ attribute_term_id,
470
+ product_attribute_terms (
471
+ id,
472
+ attribute_id,
473
+ value,
474
+ slug,
475
+ sort_order,
476
+ value_translations,
477
+ product_attributes (
478
+ id,
479
+ name,
480
+ slug,
481
+ name_translations
482
+ )
483
+ )
484
+ )
485
+ ),
486
+ translation_group_id
487
+ `).eq("language_id", s.id).eq("status", "active");
488
+ return a.length > 0 && (d = d.or(a.join(","))), await d.order("id");
489
+ }
490
+ async function S(e, t, i) {
491
+ const { data: r } = await e.from("products").select("translation_group_id").eq("id", t).single();
492
+ if (!r || !r.translation_group_id) {
493
+ if (await e.from("product_categories").delete().eq("product_id", t), i.length > 0) {
494
+ const a = i.map((d) => ({
495
+ product_id: t,
496
+ category_id: d
497
+ }));
498
+ await e.from("product_categories").insert(a);
499
+ }
500
+ return;
501
+ }
502
+ const { data: c } = await e.from("products").select("id").eq("translation_group_id", r.translation_group_id), s = c && c.length > 0 ? c.map((a) => a.id) : [t];
503
+ if (await e.from("product_categories").delete().in("product_id", s), i.length > 0) {
504
+ const a = [];
505
+ for (const d of s)
506
+ for (const n of i)
507
+ a.push({
508
+ product_id: d,
509
+ category_id: n
510
+ });
511
+ await e.from("product_categories").insert(a);
512
+ }
513
+ }
514
+ export {
515
+ U as copyProductFromLanguage,
516
+ $ as createProduct,
517
+ B as deleteProduct,
518
+ z as fetchTranslatedProductsForCartInternal,
519
+ T as getProduct,
520
+ N as getProductBySlug,
521
+ R as getProducts,
522
+ S as syncCategoriesForTranslationGroup,
523
+ D as updateProduct
524
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("react/jsx-runtime"),e=require("react"),r=e.createContext(void 0),c=({product:t,children:o})=>u.jsx(r.Provider,{value:{product:t},children:o}),n=()=>{const t=e.useContext(r);if(!t)throw new Error("useProduct must be used within a ProductProvider. Ensure the component is wrapped in a ProductProvider.");return t.product};exports.ProductProvider=c;exports.useProduct=n;
@@ -0,0 +1,16 @@
1
+ 'use client';
2
+ import { jsx as e } from "react/jsx-runtime";
3
+ import { createContext as n, useContext as u } from "react";
4
+ const t = n(void 0), i = ({
5
+ product: r,
6
+ children: o
7
+ }) => /* @__PURE__ */ e(t.Provider, { value: { product: r }, children: o }), s = () => {
8
+ const r = u(t);
9
+ if (!r)
10
+ throw new Error("useProduct must be used within a ProductProvider. Ensure the component is wrapped in a ProductProvider.");
11
+ return r.product;
12
+ };
13
+ export {
14
+ i as ProductProvider,
15
+ s as useProduct
16
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("./zod-config.cjs.js");const e=require("zod"),u=e.z.enum(["physical","digital"]).or(e.z.literal("")).refine(r=>r!=="",{message:"Product type is required"}).transform(r=>r),s=e.z.record(e.z.string().regex(/^[A-Z]{3}$/,"Currency code must be ISO 4217"),e.z.coerce.number().min(0,"Prices must be non-negative")),l=e.z.record(e.z.string().regex(/^[A-Z]{3}$/,"Currency code must be ISO 4217"),e.z.coerce.number().min(0,"Sale prices must be non-negative").nullable()),n=e.z.string().trim().refine(r=>r===""||!Number.isNaN(Date.parse(r)),{message:"Must be a valid date and time"}).transform(r=>r===""?null:r).nullable().optional();function o(r,a){if(!r||!a)return!0;const t=Date.parse(r),i=Date.parse(a);return Number.isNaN(t)||Number.isNaN(i)?!0:t<i}const c=e.z.object({attribute_id:e.z.string().uuid(),attribute_name:e.z.string(),term_id:e.z.string().uuid(),term_value:e.z.string(),term_slug:e.z.string().optional()}),m=e.z.object({id:e.z.string().uuid().optional(),combination_key:e.z.string().min(1),sku:e.z.string().min(1,"Variant SKU is required"),upc:e.z.string().optional().nullable(),price:e.z.coerce.number().min(0,"Variant price must be non-negative"),prices:s.default({}),sale_price:e.z.coerce.number().min(0,"Variant sale price must be non-negative").optional().nullable(),sale_prices:l.default({}),sale_start_at:n,sale_end_at:n,stock_quantity:e.z.coerce.number().int().min(0,"Variant stock must be a non-negative integer"),main_media_id:e.z.string().uuid().optional().nullable(),main_image_url:e.z.string().optional().nullable(),attribute_term_ids:e.z.array(e.z.string().uuid()).min(1),selected_options:e.z.array(c).min(1),label:e.z.string().min(1)}).refine(r=>r.sale_price===null||r.sale_price===void 0||r.sale_price<=r.price,{message:"Variant sale price cannot exceed the regular price",path:["sale_price"]}).refine(r=>Object.entries(r.sale_prices||{}).every(([a,t])=>{if(t==null)return!0;const i=r.prices?.[a];return typeof i=="number"?t<=i:!0}),{message:"Variant sale prices cannot exceed regular prices",path:["sale_prices"]}).refine(r=>o(r.sale_start_at,r.sale_end_at),{message:"Sale end must be after the sale start",path:["sale_end_at"]}),p=e.z.object({attribute_id:e.z.string().uuid(),term_ids:e.z.array(e.z.string().uuid())}),d=e.z.object({product_type:u,payment_provider:e.z.enum(["stripe","freemius"]),title:e.z.string().min(1,"Title is required"),slug:e.z.string().min(1,"Slug is required").regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/,"Slug must be lowercase alphanumeric with hyphens"),sku:e.z.string().min(1,"SKU is required"),upc:e.z.string().optional().nullable(),price:e.z.coerce.number().min(0,"Price must be non-negative"),prices:s.default({}),sale_price:e.z.coerce.number().min(0,"Sale price must be non-negative").optional().nullable(),sale_prices:l.default({}),sale_start_at:n,sale_end_at:n,stock:e.z.coerce.number().int().min(0,"Stock must be a non-negative integer"),meta_title:e.z.string().optional().nullable(),meta_description:e.z.string().optional().nullable(),short_description:e.z.string().optional(),description_json:e.z.any().optional(),freemius_plan_id:e.z.string().optional(),freemius_product_id:e.z.string().optional(),trial_period_days:e.z.coerce.number().int().min(0,"Trial period must be zero or greater").default(0),trial_requires_payment_method:e.z.boolean().default(!1),media_id:e.z.string().optional(),product_media:e.z.array(e.z.object({media_id:e.z.string()})).optional(),category_ids:e.z.array(e.z.string().uuid()).optional(),is_taxable:e.z.boolean(),status:e.z.enum(["draft","active","archived"]),language_id:e.z.coerce.number().int().min(1,"Language is required"),translation_group_id:e.z.string().uuid().optional().or(e.z.literal("")).transform(r=>r===""?void 0:r),explicitly_removed_media_ids:e.z.array(e.z.string()).optional(),variation_attributes:e.z.array(p).optional(),variants:e.z.array(m).optional()}).refine(r=>r.sale_price===null||r.sale_price===void 0||r.sale_price<=r.price,{message:"Sale price cannot exceed the regular price",path:["sale_price"]}).refine(r=>Object.entries(r.sale_prices||{}).every(([a,t])=>{if(t==null)return!0;const i=r.prices?.[a];return typeof i=="number"?t<=i:!0}),{message:"Sale prices cannot exceed regular prices",path:["sale_prices"]}).refine(r=>o(r.sale_start_at,r.sale_end_at),{message:"Sale end must be after the sale start",path:["sale_end_at"]});exports.productSchema=d;
@@ -0,0 +1,134 @@
1
+ import "./zod-config.es.js";
2
+ import { z as e } from "zod";
3
+ const u = e.enum(["physical", "digital"]).or(e.literal("")).refine((r) => r !== "", {
4
+ message: "Product type is required"
5
+ }).transform((r) => r), s = e.record(
6
+ e.string().regex(/^[A-Z]{3}$/, "Currency code must be ISO 4217"),
7
+ e.coerce.number().min(0, "Prices must be non-negative")
8
+ ), l = e.record(
9
+ e.string().regex(/^[A-Z]{3}$/, "Currency code must be ISO 4217"),
10
+ e.coerce.number().min(0, "Sale prices must be non-negative").nullable()
11
+ ), n = e.string().trim().refine((r) => r === "" || !Number.isNaN(Date.parse(r)), {
12
+ message: "Must be a valid date and time"
13
+ }).transform((r) => r === "" ? null : r).nullable().optional();
14
+ function o(r, a) {
15
+ if (!r || !a)
16
+ return !0;
17
+ const t = Date.parse(r), i = Date.parse(a);
18
+ return Number.isNaN(t) || Number.isNaN(i) ? !0 : t < i;
19
+ }
20
+ const c = e.object({
21
+ attribute_id: e.string().uuid(),
22
+ attribute_name: e.string(),
23
+ term_id: e.string().uuid(),
24
+ term_value: e.string(),
25
+ term_slug: e.string().optional()
26
+ }), m = e.object({
27
+ id: e.string().uuid().optional(),
28
+ combination_key: e.string().min(1),
29
+ sku: e.string().min(1, "Variant SKU is required"),
30
+ upc: e.string().optional().nullable(),
31
+ price: e.coerce.number().min(0, "Variant price must be non-negative"),
32
+ prices: s.default({}),
33
+ sale_price: e.coerce.number().min(0, "Variant sale price must be non-negative").optional().nullable(),
34
+ sale_prices: l.default({}),
35
+ sale_start_at: n,
36
+ sale_end_at: n,
37
+ stock_quantity: e.coerce.number().int().min(0, "Variant stock must be a non-negative integer"),
38
+ main_media_id: e.string().uuid().optional().nullable(),
39
+ main_image_url: e.string().optional().nullable(),
40
+ attribute_term_ids: e.array(e.string().uuid()).min(1),
41
+ selected_options: e.array(c).min(1),
42
+ label: e.string().min(1)
43
+ }).refine(
44
+ (r) => r.sale_price === null || r.sale_price === void 0 || r.sale_price <= r.price,
45
+ {
46
+ message: "Variant sale price cannot exceed the regular price",
47
+ path: ["sale_price"]
48
+ }
49
+ ).refine(
50
+ (r) => Object.entries(r.sale_prices || {}).every(([a, t]) => {
51
+ if (t == null)
52
+ return !0;
53
+ const i = r.prices?.[a];
54
+ return typeof i == "number" ? t <= i : !0;
55
+ }),
56
+ {
57
+ message: "Variant sale prices cannot exceed regular prices",
58
+ path: ["sale_prices"]
59
+ }
60
+ ).refine(
61
+ (r) => o(r.sale_start_at, r.sale_end_at),
62
+ {
63
+ message: "Sale end must be after the sale start",
64
+ path: ["sale_end_at"]
65
+ }
66
+ ), p = e.object({
67
+ attribute_id: e.string().uuid(),
68
+ term_ids: e.array(e.string().uuid())
69
+ }), g = e.object({
70
+ product_type: u,
71
+ payment_provider: e.enum(["stripe", "freemius"]),
72
+ title: e.string().min(1, "Title is required"),
73
+ slug: e.string().min(1, "Slug is required").regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "Slug must be lowercase alphanumeric with hyphens"),
74
+ sku: e.string().min(1, "SKU is required"),
75
+ upc: e.string().optional().nullable(),
76
+ price: e.coerce.number().min(0, "Price must be non-negative"),
77
+ prices: s.default({}),
78
+ sale_price: e.coerce.number().min(0, "Sale price must be non-negative").optional().nullable(),
79
+ sale_prices: l.default({}),
80
+ sale_start_at: n,
81
+ sale_end_at: n,
82
+ stock: e.coerce.number().int().min(0, "Stock must be a non-negative integer"),
83
+ meta_title: e.string().optional().nullable(),
84
+ meta_description: e.string().optional().nullable(),
85
+ short_description: e.string().optional(),
86
+ description_json: e.any().optional(),
87
+ // Using any for Tiptap JSON structure
88
+ freemius_plan_id: e.string().optional(),
89
+ // ID from Freemius Dashboard
90
+ freemius_product_id: e.string().optional(),
91
+ // Product or App ID from Freemius Dashboard
92
+ trial_period_days: e.coerce.number().int().min(0, "Trial period must be zero or greater").default(0),
93
+ trial_requires_payment_method: e.boolean().default(!1),
94
+ media_id: e.string().optional(),
95
+ // For the main product image (backward compat or single select)
96
+ product_media: e.array(e.object({
97
+ media_id: e.string()
98
+ // We can sort based on index in this array, or explicit sort_order from UI
99
+ })).optional(),
100
+ category_ids: e.array(e.string().uuid()).optional(),
101
+ is_taxable: e.boolean(),
102
+ status: e.enum(["draft", "active", "archived"]),
103
+ language_id: e.coerce.number().int().min(1, "Language is required"),
104
+ translation_group_id: e.string().uuid().optional().or(e.literal("")).transform((r) => r === "" ? void 0 : r),
105
+ explicitly_removed_media_ids: e.array(e.string()).optional(),
106
+ variation_attributes: e.array(p).optional(),
107
+ variants: e.array(m).optional()
108
+ }).refine(
109
+ (r) => r.sale_price === null || r.sale_price === void 0 || r.sale_price <= r.price,
110
+ {
111
+ message: "Sale price cannot exceed the regular price",
112
+ path: ["sale_price"]
113
+ }
114
+ ).refine(
115
+ (r) => Object.entries(r.sale_prices || {}).every(([a, t]) => {
116
+ if (t == null)
117
+ return !0;
118
+ const i = r.prices?.[a];
119
+ return typeof i == "number" ? t <= i : !0;
120
+ }),
121
+ {
122
+ message: "Sale prices cannot exceed regular prices",
123
+ path: ["sale_prices"]
124
+ }
125
+ ).refine(
126
+ (r) => o(r.sale_start_at, r.sale_end_at),
127
+ {
128
+ message: "Sale end must be after the sale start",
129
+ path: ["sale_end_at"]
130
+ }
131
+ );
132
+ export {
133
+ g as productSchema
134
+ };