@shophost/rest-api 2.0.32 → 2.0.34

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 (348) hide show
  1. package/package.json +13 -14
  2. package/src/app.js +53 -1
  3. package/src/app.js.map +1 -0
  4. package/src/core/auth/auth.schema.js +41 -1
  5. package/src/core/auth/auth.schema.js.map +1 -0
  6. package/src/core/auth/auth.util.js +44 -1
  7. package/src/core/auth/auth.util.js.map +1 -0
  8. package/src/core/auth/better-auth.lib.js +100 -1
  9. package/src/core/auth/better-auth.lib.js.map +1 -0
  10. package/src/core/auth/generate-password-hash.util.d.ts +3 -0
  11. package/src/core/auth/generate-password-hash.util.js +30 -1
  12. package/src/core/auth/generate-password-hash.util.js.map +1 -0
  13. package/src/core/auth/headers.schema.js +22 -1
  14. package/src/core/auth/headers.schema.js.map +1 -0
  15. package/src/core/auth/user.schema.js +30 -1
  16. package/src/core/auth/user.schema.js.map +1 -0
  17. package/src/core/db/__generated__/client/browser.d.ts +128 -0
  18. package/src/core/db/__generated__/client/browser.js +18 -1
  19. package/src/core/db/__generated__/client/browser.js.map +1 -0
  20. package/src/core/db/__generated__/client/client.d.ts +143 -0
  21. package/src/core/db/__generated__/client/client.js +35 -1
  22. package/src/core/db/__generated__/client/client.js.map +1 -0
  23. package/src/core/db/__generated__/client/commonInputTypes.js +11 -1
  24. package/src/core/db/__generated__/client/commonInputTypes.js.map +1 -0
  25. package/src/core/db/__generated__/client/enums.js +200 -1
  26. package/src/core/db/__generated__/client/enums.js.map +1 -0
  27. package/src/core/db/__generated__/client/internal/class.d.ts +343 -0
  28. package/src/core/db/__generated__/client/internal/class.js +55 -1
  29. package/src/core/db/__generated__/client/internal/class.js.map +1 -0
  30. package/src/core/db/__generated__/client/internal/prismaNamespace.d.ts +234 -0
  31. package/src/core/db/__generated__/client/internal/prismaNamespace.js +541 -1
  32. package/src/core/db/__generated__/client/internal/prismaNamespace.js.map +1 -0
  33. package/src/core/db/__generated__/client/internal/prismaNamespaceBrowser.d.ts +15 -0
  34. package/src/core/db/__generated__/client/internal/prismaNamespaceBrowser.js +512 -1
  35. package/src/core/db/__generated__/client/internal/prismaNamespaceBrowser.js.map +1 -0
  36. package/src/core/db/__generated__/client/models/Account.d.ts +633 -0
  37. package/src/core/db/__generated__/client/models/Account.js +2 -1
  38. package/src/core/db/__generated__/client/models/Account.js.map +1 -0
  39. package/src/core/db/__generated__/client/models/Address.d.ts +706 -0
  40. package/src/core/db/__generated__/client/models/Address.js +2 -1
  41. package/src/core/db/__generated__/client/models/Address.js.map +1 -0
  42. package/src/core/db/__generated__/client/models/Campaign.d.ts +643 -0
  43. package/src/core/db/__generated__/client/models/Campaign.js +2 -1
  44. package/src/core/db/__generated__/client/models/Campaign.js.map +1 -0
  45. package/src/core/db/__generated__/client/models/ClosingTimes.d.ts +639 -0
  46. package/src/core/db/__generated__/client/models/ClosingTimes.js +2 -1
  47. package/src/core/db/__generated__/client/models/ClosingTimes.js.map +1 -0
  48. package/src/core/db/__generated__/client/models/File.d.ts +757 -0
  49. package/src/core/db/__generated__/client/models/File.js +2 -1
  50. package/src/core/db/__generated__/client/models/File.js.map +1 -0
  51. package/src/core/db/__generated__/client/models/Invitation.d.ts +633 -0
  52. package/src/core/db/__generated__/client/models/Invitation.js +2 -1
  53. package/src/core/db/__generated__/client/models/Invitation.js.map +1 -0
  54. package/src/core/db/__generated__/client/models/LegalEntity.d.ts +657 -0
  55. package/src/core/db/__generated__/client/models/LegalEntity.js +2 -1
  56. package/src/core/db/__generated__/client/models/LegalEntity.js.map +1 -0
  57. package/src/core/db/__generated__/client/models/Manufacturer.d.ts +684 -0
  58. package/src/core/db/__generated__/client/models/Manufacturer.js +2 -1
  59. package/src/core/db/__generated__/client/models/Manufacturer.js.map +1 -0
  60. package/src/core/db/__generated__/client/models/ManufacturerTranslation.d.ts +633 -0
  61. package/src/core/db/__generated__/client/models/ManufacturerTranslation.js +2 -1
  62. package/src/core/db/__generated__/client/models/ManufacturerTranslation.js.map +1 -0
  63. package/src/core/db/__generated__/client/models/Member.d.ts +633 -0
  64. package/src/core/db/__generated__/client/models/Member.js +2 -1
  65. package/src/core/db/__generated__/client/models/Member.js.map +1 -0
  66. package/src/core/db/__generated__/client/models/Modifier.d.ts +667 -0
  67. package/src/core/db/__generated__/client/models/Modifier.js +2 -1
  68. package/src/core/db/__generated__/client/models/Modifier.js.map +1 -0
  69. package/src/core/db/__generated__/client/models/ModifierGroup.d.ts +691 -0
  70. package/src/core/db/__generated__/client/models/ModifierGroup.js +2 -1
  71. package/src/core/db/__generated__/client/models/ModifierGroup.js.map +1 -0
  72. package/src/core/db/__generated__/client/models/ModifierGroupTranslation.d.ts +633 -0
  73. package/src/core/db/__generated__/client/models/ModifierGroupTranslation.js +2 -1
  74. package/src/core/db/__generated__/client/models/ModifierGroupTranslation.js.map +1 -0
  75. package/src/core/db/__generated__/client/models/OpeningTimes.d.ts +639 -0
  76. package/src/core/db/__generated__/client/models/OpeningTimes.js +2 -1
  77. package/src/core/db/__generated__/client/models/OpeningTimes.js.map +1 -0
  78. package/src/core/db/__generated__/client/models/Order.d.ts +705 -0
  79. package/src/core/db/__generated__/client/models/Order.js +2 -1
  80. package/src/core/db/__generated__/client/models/Order.js.map +1 -0
  81. package/src/core/db/__generated__/client/models/OrderItem.d.ts +691 -0
  82. package/src/core/db/__generated__/client/models/OrderItem.js +2 -1
  83. package/src/core/db/__generated__/client/models/OrderItem.js.map +1 -0
  84. package/src/core/db/__generated__/client/models/OrderItemTranslation.d.ts +633 -0
  85. package/src/core/db/__generated__/client/models/OrderItemTranslation.js +2 -1
  86. package/src/core/db/__generated__/client/models/OrderItemTranslation.js.map +1 -0
  87. package/src/core/db/__generated__/client/models/Organization.d.ts +816 -0
  88. package/src/core/db/__generated__/client/models/Organization.js +2 -1
  89. package/src/core/db/__generated__/client/models/Organization.js.map +1 -0
  90. package/src/core/db/__generated__/client/models/OrganizationConfiguration.d.ts +681 -0
  91. package/src/core/db/__generated__/client/models/OrganizationConfiguration.js +2 -1
  92. package/src/core/db/__generated__/client/models/OrganizationConfiguration.js.map +1 -0
  93. package/src/core/db/__generated__/client/models/Payment.d.ts +673 -0
  94. package/src/core/db/__generated__/client/models/Payment.js +2 -1
  95. package/src/core/db/__generated__/client/models/Payment.js.map +1 -0
  96. package/src/core/db/__generated__/client/models/PaymentSession.d.ts +643 -0
  97. package/src/core/db/__generated__/client/models/PaymentSession.js +2 -1
  98. package/src/core/db/__generated__/client/models/PaymentSession.js.map +1 -0
  99. package/src/core/db/__generated__/client/models/Product.d.ts +751 -0
  100. package/src/core/db/__generated__/client/models/Product.js +2 -1
  101. package/src/core/db/__generated__/client/models/Product.js.map +1 -0
  102. package/src/core/db/__generated__/client/models/ProductCategory.d.ts +694 -0
  103. package/src/core/db/__generated__/client/models/ProductCategory.js +2 -1
  104. package/src/core/db/__generated__/client/models/ProductCategory.js.map +1 -0
  105. package/src/core/db/__generated__/client/models/ProductCategoryTranslation.d.ts +633 -0
  106. package/src/core/db/__generated__/client/models/ProductCategoryTranslation.js +2 -1
  107. package/src/core/db/__generated__/client/models/ProductCategoryTranslation.js.map +1 -0
  108. package/src/core/db/__generated__/client/models/ProductSnapshot.d.ts +669 -0
  109. package/src/core/db/__generated__/client/models/ProductSnapshot.js +2 -1
  110. package/src/core/db/__generated__/client/models/ProductSnapshot.js.map +1 -0
  111. package/src/core/db/__generated__/client/models/ProductTranslation.d.ts +633 -0
  112. package/src/core/db/__generated__/client/models/ProductTranslation.js +2 -1
  113. package/src/core/db/__generated__/client/models/ProductTranslation.js.map +1 -0
  114. package/src/core/db/__generated__/client/models/Reservation.d.ts +655 -0
  115. package/src/core/db/__generated__/client/models/Reservation.js +2 -1
  116. package/src/core/db/__generated__/client/models/Reservation.js.map +1 -0
  117. package/src/core/db/__generated__/client/models/Session.d.ts +633 -0
  118. package/src/core/db/__generated__/client/models/Session.js +2 -1
  119. package/src/core/db/__generated__/client/models/Session.js.map +1 -0
  120. package/src/core/db/__generated__/client/models/ShippingMethod.d.ts +684 -0
  121. package/src/core/db/__generated__/client/models/ShippingMethod.js +2 -1
  122. package/src/core/db/__generated__/client/models/ShippingMethod.js.map +1 -0
  123. package/src/core/db/__generated__/client/models/ShippingZone.d.ts +643 -0
  124. package/src/core/db/__generated__/client/models/ShippingZone.js +2 -1
  125. package/src/core/db/__generated__/client/models/ShippingZone.js.map +1 -0
  126. package/src/core/db/__generated__/client/models/User.d.ts +741 -0
  127. package/src/core/db/__generated__/client/models/User.js +2 -1
  128. package/src/core/db/__generated__/client/models/User.js.map +1 -0
  129. package/src/core/db/__generated__/client/models/Verification.d.ts +597 -0
  130. package/src/core/db/__generated__/client/models/Verification.js +2 -1
  131. package/src/core/db/__generated__/client/models/Verification.js.map +1 -0
  132. package/src/core/db/__generated__/client/models.js +2 -1
  133. package/src/core/db/__generated__/client/models.js.map +1 -0
  134. package/src/core/db/index.js +2 -1
  135. package/src/core/db/index.js.map +1 -0
  136. package/src/core/exceptions/http-exception.js +9 -1
  137. package/src/core/exceptions/http-exception.js.map +1 -0
  138. package/src/core/hono/hono.js +123 -1
  139. package/src/core/hono/hono.js.map +1 -0
  140. package/src/core/lib/prisma.js +11 -1
  141. package/src/core/lib/prisma.js.map +1 -0
  142. package/src/core/logging/pino.js +5 -1
  143. package/src/core/logging/pino.js.map +1 -0
  144. package/src/core/notifications/email.service.d.ts +15 -0
  145. package/src/core/notifications/email.service.js +116 -1
  146. package/src/core/notifications/email.service.js.map +1 -0
  147. package/src/core/openapi/openapi.lib.js +26 -1
  148. package/src/core/openapi/openapi.lib.js.map +1 -0
  149. package/src/core/types/google-maps.types.js +2 -1
  150. package/src/core/types/google-maps.types.js.map +1 -0
  151. package/src/core/utils/currency.util.js +11 -1
  152. package/src/core/utils/currency.util.js.map +1 -0
  153. package/src/core/utils/env.util.js +8 -1
  154. package/src/core/utils/env.util.js.map +1 -0
  155. package/src/core/utils/object.util.d.ts +10 -0
  156. package/src/core/utils/object.util.js +39 -1
  157. package/src/core/utils/object.util.js.map +1 -0
  158. package/src/core/utils/translations.util.js +2 -0
  159. package/src/core/utils/translations.util.js.map +1 -0
  160. package/src/core/utils/zod.util.d.ts +12 -0
  161. package/src/core/utils/zod.util.js +85 -1
  162. package/src/core/utils/zod.util.js.map +1 -0
  163. package/src/db.js +3 -1
  164. package/src/db.js.map +1 -0
  165. package/src/features/access/access.handler.js +91 -1
  166. package/src/features/access/access.handler.js.map +1 -0
  167. package/src/features/access/access.route.js +220 -1
  168. package/src/features/access/access.route.js.map +1 -0
  169. package/src/features/access/access.schema.js +108 -1
  170. package/src/features/access/access.schema.js.map +1 -0
  171. package/src/features/access/access.service.js +294 -1
  172. package/src/features/access/access.service.js.map +1 -0
  173. package/src/features/cart/cart.handler.js +17 -1
  174. package/src/features/cart/cart.handler.js.map +1 -0
  175. package/src/features/cart/cart.route.js +32 -1
  176. package/src/features/cart/cart.route.js.map +1 -0
  177. package/src/features/cart/cart.schema.js +39 -1
  178. package/src/features/cart/cart.schema.js.map +1 -0
  179. package/src/features/cart/cart.service.d.ts +7 -0
  180. package/src/features/cart/cart.service.js +97 -1
  181. package/src/features/cart/cart.service.js.map +1 -0
  182. package/src/features/cart/cart.util.js +76 -1
  183. package/src/features/cart/cart.util.js.map +1 -0
  184. package/src/features/file/file.handler.js +23 -1
  185. package/src/features/file/file.handler.js.map +1 -0
  186. package/src/features/file/file.route.js +34 -1
  187. package/src/features/file/file.route.js.map +1 -0
  188. package/src/features/file/file.schema.js +77 -1
  189. package/src/features/file/file.schema.js.map +1 -0
  190. package/src/features/file/file.service.d.ts +6 -0
  191. package/src/features/file/file.service.js +66 -1
  192. package/src/features/file/file.service.js.map +1 -0
  193. package/src/features/health/health.handler.js +10 -1
  194. package/src/features/health/health.handler.js.map +1 -0
  195. package/src/features/health/health.route.js +25 -1
  196. package/src/features/health/health.route.js.map +1 -0
  197. package/src/features/index.js +16 -1
  198. package/src/features/index.js.map +1 -0
  199. package/src/features/location/location.handler.js +25 -1
  200. package/src/features/location/location.handler.js.map +1 -0
  201. package/src/features/location/location.route.js +56 -1
  202. package/src/features/location/location.route.js.map +1 -0
  203. package/src/features/location/location.schema.js +50 -1
  204. package/src/features/location/location.schema.js.map +1 -0
  205. package/src/features/location/location.service.d.ts +3 -0
  206. package/src/features/location/location.service.js +141 -1
  207. package/src/features/location/location.service.js.map +1 -0
  208. package/src/features/manufacturer/manufacturer.handler.js +53 -1
  209. package/src/features/manufacturer/manufacturer.handler.js.map +1 -0
  210. package/src/features/manufacturer/manufacturer.route.js +97 -1
  211. package/src/features/manufacturer/manufacturer.route.js.map +1 -0
  212. package/src/features/manufacturer/manufacturer.schema.js +125 -1
  213. package/src/features/manufacturer/manufacturer.schema.js.map +1 -0
  214. package/src/features/manufacturer/manufacturer.service.d.ts +19 -0
  215. package/src/features/manufacturer/manufacturer.service.js +190 -1
  216. package/src/features/manufacturer/manufacturer.service.js.map +1 -0
  217. package/src/features/order/emails/order-confirmation.email.js +229 -1
  218. package/src/features/order/emails/order-confirmation.email.js.map +1 -0
  219. package/src/features/order/emails/order-notification.email.js +229 -1
  220. package/src/features/order/emails/order-notification.email.js.map +1 -0
  221. package/src/features/order/fulfilment.schema.js +3 -1
  222. package/src/features/order/fulfilment.schema.js.map +1 -0
  223. package/src/features/order/order.handler.js +54 -1
  224. package/src/features/order/order.handler.js.map +1 -0
  225. package/src/features/order/order.route.js +111 -1
  226. package/src/features/order/order.route.js.map +1 -0
  227. package/src/features/order/order.schema.js +158 -1
  228. package/src/features/order/order.schema.js.map +1 -0
  229. package/src/features/order/order.service.d.ts +15 -0
  230. package/src/features/order/order.service.js +306 -1
  231. package/src/features/order/order.service.js.map +1 -0
  232. package/src/features/order/recipient.schema.js +38 -1
  233. package/src/features/order/recipient.schema.js.map +1 -0
  234. package/src/features/organization/legal-entity.schema.js +83 -1
  235. package/src/features/organization/legal-entity.schema.js.map +1 -0
  236. package/src/features/organization/organization-configuration.schema.js +115 -1
  237. package/src/features/organization/organization-configuration.schema.js.map +1 -0
  238. package/src/features/organization/organization.handler.js +48 -1
  239. package/src/features/organization/organization.handler.js.map +1 -0
  240. package/src/features/organization/organization.route.js +84 -1
  241. package/src/features/organization/organization.route.js.map +1 -0
  242. package/src/features/organization/organization.schema.js +64 -1
  243. package/src/features/organization/organization.schema.js.map +1 -0
  244. package/src/features/organization/organization.service.d.ts +15 -0
  245. package/src/features/organization/organization.service.js +334 -1
  246. package/src/features/organization/organization.service.js.map +1 -0
  247. package/src/features/payment/payment.handler.js +16 -1
  248. package/src/features/payment/payment.handler.js.map +1 -0
  249. package/src/features/payment/payment.route.js +22 -1
  250. package/src/features/payment/payment.route.js.map +1 -0
  251. package/src/features/payment/payment.schema.js +46 -1
  252. package/src/features/payment/payment.schema.js.map +1 -0
  253. package/src/features/payment/payment.service.js +100 -1
  254. package/src/features/payment/payment.service.js.map +1 -0
  255. package/src/features/payment/stripe.service.js +164 -1
  256. package/src/features/payment/stripe.service.js.map +1 -0
  257. package/src/features/product/product-modifier.schema.js +84 -1
  258. package/src/features/product/product-modifier.schema.js.map +1 -0
  259. package/src/features/product/product.handler.js +87 -1
  260. package/src/features/product/product.handler.js.map +1 -0
  261. package/src/features/product/product.route.js +179 -1
  262. package/src/features/product/product.route.js.map +1 -0
  263. package/src/features/product/product.schema.js +143 -1
  264. package/src/features/product/product.schema.js.map +1 -0
  265. package/src/features/product/product.service.d.ts +25 -0
  266. package/src/features/product/product.service.js +440 -1
  267. package/src/features/product/product.service.js.map +1 -0
  268. package/src/features/product-category/product-category.handler.js +59 -1
  269. package/src/features/product-category/product-category.handler.js.map +1 -0
  270. package/src/features/product-category/product-category.route.js +139 -1
  271. package/src/features/product-category/product-category.route.js.map +1 -0
  272. package/src/features/product-category/product-category.schema.js +86 -1
  273. package/src/features/product-category/product-category.schema.js.map +1 -0
  274. package/src/features/product-category/product-category.service.d.ts +22 -0
  275. package/src/features/product-category/product-category.service.js +220 -1
  276. package/src/features/product-category/product-category.service.js.map +1 -0
  277. package/src/features/reservation/emails/reservation-cancellation.email.js +82 -1
  278. package/src/features/reservation/emails/reservation-cancellation.email.js.map +1 -0
  279. package/src/features/reservation/emails/reservation-confirmation.email.js +82 -1
  280. package/src/features/reservation/emails/reservation-confirmation.email.js.map +1 -0
  281. package/src/features/reservation/emails/reservation-notification.email.js +93 -1
  282. package/src/features/reservation/emails/reservation-notification.email.js.map +1 -0
  283. package/src/features/reservation/reservation.handler.js +65 -1
  284. package/src/features/reservation/reservation.handler.js.map +1 -0
  285. package/src/features/reservation/reservation.route.js +167 -1
  286. package/src/features/reservation/reservation.route.js.map +1 -0
  287. package/src/features/reservation/reservation.schema.js +51 -1
  288. package/src/features/reservation/reservation.schema.js.map +1 -0
  289. package/src/features/reservation/reservation.service.d.ts +18 -0
  290. package/src/features/reservation/reservation.service.js +231 -1
  291. package/src/features/reservation/reservation.service.js.map +1 -0
  292. package/src/features/shipping/shipping.handler.js +32 -1
  293. package/src/features/shipping/shipping.handler.js.map +1 -0
  294. package/src/features/shipping/shipping.route.js +51 -1
  295. package/src/features/shipping/shipping.route.js.map +1 -0
  296. package/src/features/shipping/shipping.service.d.ts +7 -0
  297. package/src/features/shipping/shipping.service.js +96 -1
  298. package/src/features/shipping/shipping.service.js.map +1 -0
  299. package/src/features/shipping-method/shipping-method.handler.js +60 -1
  300. package/src/features/shipping-method/shipping-method.handler.js.map +1 -0
  301. package/src/features/shipping-method/shipping-method.route.js +144 -1
  302. package/src/features/shipping-method/shipping-method.route.js.map +1 -0
  303. package/src/features/shipping-method/shipping-method.schema.js +48 -1
  304. package/src/features/shipping-method/shipping-method.schema.js.map +1 -0
  305. package/src/features/shipping-method/shipping-method.service.d.ts +25 -0
  306. package/src/features/shipping-method/shipping-method.service.js +229 -1
  307. package/src/features/shipping-method/shipping-method.service.js.map +1 -0
  308. package/src/features/shipping-method/shipping-zone.schema.js +31 -1
  309. package/src/features/shipping-method/shipping-zone.schema.js.map +1 -0
  310. package/src/features/webhook/webhook.handler.js +50 -1
  311. package/src/features/webhook/webhook.handler.js.map +1 -0
  312. package/src/features/webhook/webhook.route.js +33 -1
  313. package/src/features/webhook/webhook.route.js.map +1 -0
  314. package/src/index.js +6 -1
  315. package/src/index.js.map +1 -0
  316. package/src/integrations/next.js +82 -1
  317. package/src/integrations/next.js.map +1 -0
  318. package/src/schemas/address.schema.d.ts +8 -0
  319. package/src/schemas/address.schema.js +112 -1
  320. package/src/schemas/address.schema.js.map +1 -0
  321. package/src/schemas/currency.schema.d.ts +42 -0
  322. package/src/schemas/currency.schema.js +118 -1
  323. package/src/schemas/currency.schema.js.map +1 -0
  324. package/src/schemas/error.schema.js +12 -1
  325. package/src/schemas/error.schema.js.map +1 -0
  326. package/src/schemas/index.js +29 -1
  327. package/src/schemas/index.js.map +1 -0
  328. package/src/schemas/locales.schema.js +238 -1
  329. package/src/schemas/locales.schema.js.map +1 -0
  330. package/src/schemas/number.schema.js +29 -1
  331. package/src/schemas/number.schema.js.map +1 -0
  332. package/src/schemas/pagination.schema.js +54 -1
  333. package/src/schemas/pagination.schema.js.map +1 -0
  334. package/src/schemas/params.schema.js +20 -1
  335. package/src/schemas/params.schema.js.map +1 -0
  336. package/src/schemas/queries.schema.js +6 -1
  337. package/src/schemas/queries.schema.js.map +1 -0
  338. package/src/test/global-setup.js +37 -1
  339. package/src/test/global-setup.js.map +1 -0
  340. package/src/test/integration/api-fixtures.js +160 -1
  341. package/src/test/integration/api-fixtures.js.map +1 -0
  342. package/src/test/integration/seed.js +368 -1
  343. package/src/test/integration/seed.js.map +1 -0
  344. package/src/test/integration/test-helpers.js +154 -1
  345. package/src/test/integration/test-helpers.js.map +1 -0
  346. package/src/test/setup-test-env.js +7 -1
  347. package/src/test/setup-test-env.js.map +1 -0
  348. package/scripts/minify.mjs +0 -123
@@ -1 +1,143 @@
1
- import{z as e}from"@hono/zod-openapi";import{validateRequiredForDefaultLocale as o}from"../../core/utils/zod.util";import{locale as i}from"../../schemas/locales.schema";import{optionalNumber as t,requiredNumber as a}from"../../schemas/number.schema";import{FileSchema as r}from"../file/file.schema";import{ProductCategorySchema as c}from"../product-category/product-category.schema";import{CreateOrUpdateModifierGroupSchema as s,LocalizedModifierGroupSchema as n,ModifierGroupSchema as p}from"./product-modifier.schema";export const ProductSchema=e.object({id:e.string().cuid().openapi({example:"clf9876543210abcdef",description:"ID of the product"}),slug:e.string().optional().openapi({example:"premium-watch",description:"Unique slug for the product"}),sku:e.string().optional().openapi({example:"PRM-WATCH-01",description:"Stock Keeping Unit identifier"}),basePrice:a,discountedBasePrice:t,currency:e.string().openapi({example:"USD",description:"Currency code for pricing"}),images:e.array(r).optional().openapi({description:"List of product images"}),modifierGroups:e.array(p).optional().openapi({description:"List of product modifier groups"}),categories:e.array(c).openapi({example:["cju0z9k4z0000l1qg5z1z1z"],description:"IDs of associated product categories"}),manufacturerId:e.string().cuid().nullable().optional().openapi({description:"ID of associated manufacturer"}),createdAt:e.date(),publishedAt:e.date().nullable().optional(),translations:e.array(e.object({locale:i,title:e.coerce.string().optional().openapi({example:"Premium Watch",description:"Product name in specified locale"}),description:e.string().nullable().optional().openapi({example:"High-quality premium watch",description:"Product description in specified locale"})})).optional(),metadata:e.record(e.string().min(1,"Key cannot be empty").max(50,"Key too long").regex(/^[a-zA-Z][a-zA-Z0-9_-]*$/,"Key must start with letter and contain only letters, numbers, underscore, or dash"),e.string().min(1,"Value cannot be empty").max(200,"Value too long")).optional().nullable()}).openapi("Product");export const LocalizedProductSchema=ProductSchema.extend({title:e.string().default(""),description:e.string().nullable().default(""),modifierGroups:e.array(n),categories:e.array(e.object({id:e.string().cuid().openapi({example:"cju0z9k4z0000l1qg5z1z1z",description:"ID of the product category"})})).default([])}).omit({translations:!0}).openapi("LocalizedProduct");const d=ProductSchema.pick({slug:!0,sku:!0,basePrice:!0,discountedBasePrice:!0,currency:!0,images:!0,manufacturerId:!0,translations:!0,metadata:!0}).extend({defaultLocale:e.string().min(1,"Default locale is required").openapi({example:"en-US",description:"Default translation locale"}),modifierGroups:e.array(s).optional().openapi({description:"List of product modifier groups"}),categories:e.array(e.string()).optional().openapi({example:["cju0z9k4z0000l1qg5z1z1z"],description:"IDs of associated product categories"})});export const CreateProductSchema=d.superRefine((i,t)=>(null!==i.discountedBasePrice&&void 0!==i.discountedBasePrice&&i.discountedBasePrice>i.basePrice&&t.addIssue({code:e.ZodIssueCode.custom,path:["discountedBasePrice"],message:"Discounted price cannot exceed base price"}),o("title")(i,t))).openapi("CreateProduct");export const UpdateProductSchema=d.partial().superRefine((i,t)=>(null!==i.discountedBasePrice&&void 0!==i.discountedBasePrice&&i.basePrice&&i.discountedBasePrice>i.basePrice&&t.addIssue({code:e.ZodIssueCode.custom,path:["discountedBasePrice"],message:"Discounted price cannot exceed base price"}),o("title")(i,t))).openapi("UpdateProduct");
1
+ import { z } from "@hono/zod-openapi";
2
+ import { validateRequiredForDefaultLocale } from "../../core/utils/zod.util";
3
+ import { locale } from "../../schemas/locales.schema";
4
+ import { optionalNumber, requiredNumber } from "../../schemas/number.schema";
5
+ import { FileSchema } from "../file/file.schema";
6
+ import { ProductCategorySchema } from "../product-category/product-category.schema";
7
+ import { CreateOrUpdateModifierGroupSchema, LocalizedModifierGroupSchema, ModifierGroupSchema, } from "./product-modifier.schema";
8
+ export const ProductSchema = z
9
+ .object({
10
+ id: z.string().cuid().openapi({
11
+ example: "clf9876543210abcdef",
12
+ description: "ID of the product",
13
+ }),
14
+ slug: z.string().optional().openapi({
15
+ example: "premium-watch",
16
+ description: "Unique slug for the product",
17
+ }),
18
+ sku: z.string().optional().openapi({
19
+ example: "PRM-WATCH-01",
20
+ description: "Stock Keeping Unit identifier",
21
+ }),
22
+ basePrice: requiredNumber,
23
+ discountedBasePrice: optionalNumber,
24
+ currency: z.string().openapi({
25
+ example: "USD",
26
+ description: "Currency code for pricing",
27
+ }),
28
+ images: z.array(FileSchema).optional().openapi({
29
+ description: "List of product images",
30
+ }),
31
+ modifierGroups: z.array(ModifierGroupSchema).optional().openapi({
32
+ description: "List of product modifier groups",
33
+ }),
34
+ categories: z.array(ProductCategorySchema).openapi({
35
+ example: ["cju0z9k4z0000l1qg5z1z1z"],
36
+ description: "IDs of associated product categories",
37
+ }),
38
+ manufacturerId: z.string().cuid().nullable().optional().openapi({
39
+ description: "ID of associated manufacturer",
40
+ }),
41
+ createdAt: z.date(),
42
+ publishedAt: z.date().nullable().optional(),
43
+ translations: z
44
+ .array(z.object({
45
+ locale,
46
+ title: z.coerce.string().optional().openapi({
47
+ example: "Premium Watch",
48
+ description: "Product name in specified locale",
49
+ }),
50
+ description: z.string().nullable().optional().openapi({
51
+ example: "High-quality premium watch",
52
+ description: "Product description in specified locale",
53
+ }),
54
+ }))
55
+ .optional(),
56
+ metadata: z
57
+ .record(z
58
+ .string()
59
+ .min(1, "Key cannot be empty")
60
+ .max(50, "Key too long")
61
+ .regex(/^[a-zA-Z][a-zA-Z0-9_-]*$/, "Key must start with letter and contain only letters, numbers, underscore, or dash"), z.string().min(1, "Value cannot be empty").max(200, "Value too long"))
62
+ .optional()
63
+ .nullable(),
64
+ })
65
+ .openapi("Product");
66
+ export const LocalizedProductSchema = ProductSchema.extend({
67
+ title: z.string().default(""),
68
+ description: z.string().nullable().default(""),
69
+ modifierGroups: z.array(LocalizedModifierGroupSchema),
70
+ categories: z
71
+ .array(z.object({
72
+ id: z.string().cuid().openapi({
73
+ example: "cju0z9k4z0000l1qg5z1z1z",
74
+ description: "ID of the product category",
75
+ }),
76
+ }))
77
+ .default([]),
78
+ })
79
+ .omit({
80
+ translations: true,
81
+ })
82
+ .openapi("LocalizedProduct");
83
+ const BaseProductFormData = ProductSchema.pick({
84
+ slug: true,
85
+ sku: true,
86
+ basePrice: true,
87
+ discountedBasePrice: true,
88
+ currency: true,
89
+ images: true,
90
+ manufacturerId: true,
91
+ translations: true,
92
+ metadata: true,
93
+ }).extend({
94
+ defaultLocale: z.string().min(1, "Default locale is required").openapi({
95
+ example: "en-US",
96
+ description: "Default translation locale",
97
+ }),
98
+ modifierGroups: z
99
+ .array(CreateOrUpdateModifierGroupSchema)
100
+ .optional()
101
+ .openapi({
102
+ description: "List of product modifier groups",
103
+ }),
104
+ categories: z
105
+ .array(z.string())
106
+ .optional()
107
+ .openapi({
108
+ example: ["cju0z9k4z0000l1qg5z1z1z"],
109
+ description: "IDs of associated product categories",
110
+ }),
111
+ });
112
+ export const CreateProductSchema = BaseProductFormData.superRefine((data, ctx) => {
113
+ // Check if discountedBasePrice is greater than basePrice
114
+ if (data.discountedBasePrice !== null &&
115
+ data.discountedBasePrice !== undefined &&
116
+ data.discountedBasePrice > data.basePrice) {
117
+ ctx.addIssue({
118
+ code: z.ZodIssueCode.custom,
119
+ path: ["discountedBasePrice"],
120
+ message: "Discounted price cannot exceed base price",
121
+ });
122
+ }
123
+ // Existing validation for default locale
124
+ return validateRequiredForDefaultLocale("title")(data, ctx);
125
+ }).openapi("CreateProduct");
126
+ export const UpdateProductSchema = BaseProductFormData.partial()
127
+ .superRefine((data, ctx) => {
128
+ // Check if discountedBasePrice is greater than basePrice
129
+ if (data.discountedBasePrice !== null &&
130
+ data.discountedBasePrice !== undefined &&
131
+ data.basePrice &&
132
+ data.discountedBasePrice > data.basePrice) {
133
+ ctx.addIssue({
134
+ code: z.ZodIssueCode.custom,
135
+ path: ["discountedBasePrice"],
136
+ message: "Discounted price cannot exceed base price",
137
+ });
138
+ }
139
+ // Existing validation for default locale
140
+ return validateRequiredForDefaultLocale("title")(data, ctx);
141
+ })
142
+ .openapi("UpdateProduct");
143
+ //# sourceMappingURL=product.schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product.schema.js","sourceRoot":"","sources":["../../../../../../packages/rest-api/src/features/product/product.schema.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,14 @@ import { CreateProductSchema, UpdateProductSchema } from "../../schemas";
4
4
  declare class ProductService {
5
5
  private readonly prisma;
6
6
  constructor(prisma: PrismaClientType);
7
+ /**
8
+ * Find a product by ID and organization ID
9
+ * @throws HttpException with 404 status if product is not found
10
+ */
7
11
  private findProduct;
12
+ /**
13
+ * Create a new product
14
+ */
8
15
  createProduct(organizationId: string, userId: string, body: z.infer<typeof CreateProductSchema>): Promise<{
9
16
  id: string;
10
17
  basePrice: number;
@@ -63,6 +70,9 @@ declare class ProductService {
63
70
  }[] | undefined;
64
71
  metadata?: Record<string, string> | null | undefined;
65
72
  }>;
73
+ /**
74
+ * Get a product by ID
75
+ */
66
76
  getProduct(organizationId: string, id: string, query: {
67
77
  locale?: string | null;
68
78
  published?: boolean;
@@ -160,6 +170,9 @@ declare class ProductService {
160
170
  }[] | undefined;
161
171
  metadata?: Record<string, string> | null | undefined;
162
172
  }>;
173
+ /**
174
+ * Get a paginated list of products
175
+ */
163
176
  getProducts(organizationId: string, query: {
164
177
  page?: number;
165
178
  limit?: number;
@@ -282,6 +295,9 @@ declare class ProductService {
282
295
  metadata?: Record<string, string> | null | undefined;
283
296
  }[];
284
297
  }>;
298
+ /**
299
+ * Get products by category
300
+ */
285
301
  getProductsByCategory(organizationId: string, categoryId: string, query: {
286
302
  page?: number;
287
303
  limit?: number;
@@ -356,6 +372,9 @@ declare class ProductService {
356
372
  metadata?: Record<string, string> | null | undefined;
357
373
  }[];
358
374
  }>;
375
+ /**
376
+ * Update a product
377
+ */
359
378
  updateProduct(organizationId: string, id: string, userId: string, body: z.infer<typeof UpdateProductSchema>): Promise<{
360
379
  id: string;
361
380
  basePrice: number;
@@ -414,6 +433,9 @@ declare class ProductService {
414
433
  }[] | undefined;
415
434
  metadata?: Record<string, string> | null | undefined;
416
435
  }>;
436
+ /**
437
+ * Update product status (publish/unpublish)
438
+ */
417
439
  updateProductStatus(organizationId: string, id: string, operation: "publish" | "unpublish", userId: string): Promise<{
418
440
  id: string;
419
441
  basePrice: number;
@@ -472,6 +494,9 @@ declare class ProductService {
472
494
  }[] | undefined;
473
495
  metadata?: Record<string, string> | null | undefined;
474
496
  }>;
497
+ /**
498
+ * Delete a product (soft delete)
499
+ */
475
500
  deleteProduct(organizationId: string, id: string, userId: string): Promise<void>;
476
501
  }
477
502
  export { ProductService };
@@ -1 +1,440 @@
1
- import{__awaiter as e}from"tslib";import{z as t}from"@hono/zod-openapi";import{HttpException as i}from"../../core/exceptions/http-exception";import{flattenTranslationData as a}from"../../core/utils/zod.util";import{LocalizedProductSchema as r,PaginationMetaSchema as s,ProductSchema as d}from"../../schemas";class o{constructor(e){this.prisma=e}findProduct(t,a,r){return e(this,void 0,void 0,function*(){const e=yield this.prisma.product.findUnique({where:{id:t,organizationId:a,deletedAt:null},include:null==r?void 0:r.include});if(!e)throw new i(404,"Product not found");return e})}createProduct(t,i,a){return e(this,void 0,void 0,function*(){const r=yield this.prisma.$transaction(r=>e(this,void 0,void 0,function*(){var e,s;const d=yield r.product.create({data:Object.assign(Object.assign({slug:a.slug,sku:a.sku,basePrice:a.basePrice,discountedBasePrice:a.discountedBasePrice,currency:a.currency,organizationId:t,manufacturerId:a.manufacturerId,createdBy:i,translations:{create:a.translations},images:{connect:null===(e=a.images)||void 0===e?void 0:e.map(e=>({id:e.id}))},modifierGroups:{create:null===(s=a.modifierGroups)||void 0===s?void 0:s.map(e=>({selectMin:e.selectMin,selectMax:e.selectMax,translations:{create:e.translations},modifiers:{create:e.modifiers}}))}},a.categories?{categories:{connect:a.categories.map(e=>({id:e}))}}:void 0),{metadata:a.metadata||{}}),include:{translations:!0,images:!0,categories:{include:{translations:!0}},modifierGroups:{include:{translations:!0,modifiers:!0}}}}),o=yield r.productSnapshot.create({data:{productId:d.id,data:d,createdBy:i}});return yield r.product.update({where:{id:d.id},data:{latestSnapshotId:o.id}}),d}));return d.parse(r)})}getProduct(t,i,s){return e(this,void 0,void 0,function*(){const{locale:e}=s,o=yield this.findProduct(i,t,Object.assign(Object.assign({},s.published&&{publishedAt:{not:null}}),{include:{translations:!e||{where:{locale:e}},images:!0,categories:{include:{translations:!e||{where:{locale:e}}}},modifierGroups:{include:{translations:!e||{where:{locale:e}},modifiers:!0}}}}));return e?r.parse(a(o)):d.parse(o)})}getProducts(i,o){return e(this,void 0,void 0,function*(){const{page:e=1,limit:n=10,search:l,locale:c,published:u}=o,[p,m]=yield this.prisma.product.paginate({orderBy:{createdAt:"desc"},where:Object.assign(Object.assign({organizationId:i,deletedAt:null},l&&{translations:{some:{title:{contains:l,mode:"insensitive"}}}}),u&&{publishedAt:{not:null}}),include:{translations:!c||{where:{locale:c}},images:!0,categories:{include:{translations:!c||{where:{locale:c}}}},modifierGroups:{include:{translations:!c||{where:{locale:c}},modifiers:!0}}}}).withPages({page:e,limit:n});if(!c)return t.object({meta:s,list:t.array(d)}).parse({meta:m,list:p});const h=p.map(e=>a(e));return t.object({meta:s,list:t.array(r)}).parse({meta:m,list:h})})}getProductsByCategory(i,r,o){return e(this,void 0,void 0,function*(){const{page:e=1,limit:n=10,search:l,locale:c}=o,[u,p]=yield this.prisma.product.paginate({orderBy:{createdAt:"desc"},where:Object.assign({organizationId:i,deletedAt:null,categories:{some:{id:r}}},l&&{translations:{some:{title:{contains:l,mode:"insensitive"}}}}),include:{translations:!c||{where:{locale:c}},images:!0,categories:{include:{translations:!c||{where:{locale:c}}}},modifierGroups:{include:{translations:!c||{where:{locale:c}},modifiers:!0}}}}).withPages({page:e,limit:n}),m=c?u.map(e=>d.parse(a(e))):u.map(e=>d.parse(e));return t.object({meta:s,list:t.array(d)}).parse({meta:p,list:m})})}updateProduct(t,i,a,r){return e(this,void 0,void 0,function*(){yield this.findProduct(i,t);const s=yield this.prisma.$transaction(s=>e(this,void 0,void 0,function*(){var e,d,o;const n=yield s.product.update({where:{id:i,organizationId:t,deletedAt:null},data:{slug:r.slug,sku:r.sku,basePrice:r.basePrice,discountedBasePrice:r.discountedBasePrice,currency:r.currency,manufacturerId:r.manufacturerId,updatedBy:a,translations:{deleteMany:{},create:r.translations||[]},images:{set:(null===(e=r.images)||void 0===e?void 0:e.map(e=>({id:e.id})))||[]},modifierGroups:{deleteMany:{},create:null===(d=r.modifierGroups)||void 0===d?void 0:d.map(e=>({selectMin:e.selectMin,selectMax:e.selectMax,translations:{create:e.translations},modifiers:{create:e.modifiers}}))},categories:{set:(null===(o=r.categories)||void 0===o?void 0:o.map(e=>({id:e})))||[]},metadata:r.metadata||{}},include:{translations:!0,images:!0,categories:{include:{translations:!0}},modifierGroups:{include:{translations:!0,modifiers:!0}}}}),l=yield s.productSnapshot.create({data:{productId:n.id,data:n,createdBy:a}});return yield s.product.update({where:{id:n.id},data:{latestSnapshotId:l.id}}),n}));return d.parse(s)})}updateProductStatus(t,i,a,r){return e(this,void 0,void 0,function*(){yield this.findProduct(i,t);const e=yield this.prisma.product.update({where:{id:i,organizationId:t,deletedAt:null},data:{publishedAt:"publish"===a?new Date:null,publishedBy:"publish"===a?r:null,updatedBy:r},include:{translations:!0,images:!0,categories:{include:{translations:!0}},modifierGroups:{include:{translations:!0,modifiers:!0}}}});return d.parse(e)})}deleteProduct(t,i,a){return e(this,void 0,void 0,function*(){yield this.findProduct(i,t),yield this.prisma.product.update({where:{id:i,organizationId:t,deletedAt:null},data:{deletedAt:new Date,deletedBy:a}})})}}export{o as ProductService};
1
+ import { __awaiter } from "tslib";
2
+ import { z } from "@hono/zod-openapi";
3
+ import { HttpException } from "../../core/exceptions/http-exception";
4
+ import { flattenTranslationData } from "../../core/utils/zod.util";
5
+ import { LocalizedProductSchema, PaginationMetaSchema, ProductSchema, } from "../../schemas";
6
+ class ProductService {
7
+ constructor(prisma) {
8
+ this.prisma = prisma;
9
+ }
10
+ /**
11
+ * Find a product by ID and organization ID
12
+ * @throws HttpException with 404 status if product is not found
13
+ */
14
+ findProduct(id, organizationId, options) {
15
+ return __awaiter(this, void 0, void 0, function* () {
16
+ const product = yield this.prisma.product.findUnique({
17
+ where: {
18
+ id,
19
+ organizationId,
20
+ deletedAt: null,
21
+ },
22
+ include: options === null || options === void 0 ? void 0 : options.include,
23
+ });
24
+ if (!product) {
25
+ throw new HttpException(404, "Product not found");
26
+ }
27
+ return product;
28
+ });
29
+ }
30
+ /**
31
+ * Create a new product
32
+ */
33
+ createProduct(organizationId, userId, body) {
34
+ return __awaiter(this, void 0, void 0, function* () {
35
+ const product = yield this.prisma.$transaction((tx) => __awaiter(this, void 0, void 0, function* () {
36
+ var _a, _b;
37
+ // Create the product
38
+ const product = yield tx.product.create({
39
+ data: Object.assign(Object.assign({ slug: body.slug, sku: body.sku, basePrice: body.basePrice, discountedBasePrice: body.discountedBasePrice, currency: body.currency, organizationId: organizationId, manufacturerId: body.manufacturerId, createdBy: userId, translations: {
40
+ create: body.translations,
41
+ }, images: {
42
+ connect: (_a = body.images) === null || _a === void 0 ? void 0 : _a.map((image) => ({ id: image.id })),
43
+ }, modifierGroups: {
44
+ create: (_b = body.modifierGroups) === null || _b === void 0 ? void 0 : _b.map((group) => ({
45
+ selectMin: group.selectMin,
46
+ selectMax: group.selectMax,
47
+ translations: {
48
+ create: group.translations,
49
+ },
50
+ modifiers: {
51
+ create: group.modifiers,
52
+ },
53
+ })),
54
+ } }, (body.categories
55
+ ? {
56
+ categories: {
57
+ connect: body.categories.map((id) => ({ id })),
58
+ },
59
+ }
60
+ : undefined)), { metadata: body.metadata || {} }),
61
+ include: {
62
+ translations: true,
63
+ images: true,
64
+ categories: {
65
+ include: {
66
+ translations: true,
67
+ },
68
+ },
69
+ modifierGroups: {
70
+ include: {
71
+ translations: true,
72
+ modifiers: true,
73
+ },
74
+ },
75
+ },
76
+ });
77
+ // Create the product snapshot
78
+ const snapshot = yield tx.productSnapshot.create({
79
+ data: {
80
+ productId: product.id,
81
+ data: product,
82
+ createdBy: userId,
83
+ },
84
+ });
85
+ // Update the product with the snapshot id as latestSnapshotId
86
+ yield tx.product.update({
87
+ where: { id: product.id },
88
+ data: {
89
+ latestSnapshotId: snapshot.id,
90
+ },
91
+ });
92
+ return product;
93
+ }));
94
+ return ProductSchema.parse(product);
95
+ });
96
+ }
97
+ /**
98
+ * Get a product by ID
99
+ */
100
+ getProduct(organizationId, id, query) {
101
+ return __awaiter(this, void 0, void 0, function* () {
102
+ const { locale } = query;
103
+ const product = yield this.findProduct(id, organizationId, Object.assign(Object.assign({}, (query.published && {
104
+ publishedAt: {
105
+ not: null,
106
+ },
107
+ })), { include: {
108
+ translations: locale
109
+ ? {
110
+ where: { locale },
111
+ }
112
+ : true,
113
+ images: true,
114
+ categories: {
115
+ include: {
116
+ translations: locale
117
+ ? {
118
+ where: { locale },
119
+ }
120
+ : true,
121
+ },
122
+ },
123
+ modifierGroups: {
124
+ include: {
125
+ translations: locale
126
+ ? {
127
+ where: { locale },
128
+ }
129
+ : true,
130
+ modifiers: true,
131
+ },
132
+ },
133
+ } }));
134
+ if (!locale) {
135
+ return ProductSchema.parse(product);
136
+ }
137
+ return LocalizedProductSchema.parse(flattenTranslationData(product));
138
+ });
139
+ }
140
+ /**
141
+ * Get a paginated list of products
142
+ */
143
+ getProducts(organizationId, query) {
144
+ return __awaiter(this, void 0, void 0, function* () {
145
+ const { page = 1, limit = 10, search, locale, published } = query;
146
+ const [list, meta] = yield this.prisma.product
147
+ .paginate({
148
+ orderBy: {
149
+ createdAt: "desc",
150
+ },
151
+ where: Object.assign(Object.assign({ organizationId, deletedAt: null }, (search && {
152
+ translations: {
153
+ some: {
154
+ title: {
155
+ contains: search,
156
+ mode: "insensitive",
157
+ },
158
+ },
159
+ },
160
+ })), (published && {
161
+ publishedAt: {
162
+ not: null,
163
+ },
164
+ })),
165
+ include: {
166
+ translations: locale
167
+ ? {
168
+ where: { locale },
169
+ }
170
+ : true,
171
+ images: true,
172
+ categories: {
173
+ include: {
174
+ translations: locale
175
+ ? {
176
+ where: { locale },
177
+ }
178
+ : true,
179
+ },
180
+ },
181
+ modifierGroups: {
182
+ include: {
183
+ translations: locale
184
+ ? {
185
+ where: { locale },
186
+ }
187
+ : true,
188
+ modifiers: true,
189
+ },
190
+ },
191
+ },
192
+ })
193
+ .withPages({
194
+ page,
195
+ limit,
196
+ });
197
+ if (!locale) {
198
+ // Return standard response with ProductSchema
199
+ return z
200
+ .object({
201
+ meta: PaginationMetaSchema,
202
+ list: z.array(ProductSchema),
203
+ })
204
+ .parse({
205
+ meta,
206
+ list,
207
+ });
208
+ }
209
+ // Process the list for localization
210
+ const localizedList = list.map((item) => flattenTranslationData(item));
211
+ // Return localized response with LocalizedProductSchema
212
+ return z
213
+ .object({
214
+ meta: PaginationMetaSchema,
215
+ list: z.array(LocalizedProductSchema),
216
+ })
217
+ .parse({
218
+ meta,
219
+ list: localizedList,
220
+ });
221
+ });
222
+ }
223
+ /**
224
+ * Get products by category
225
+ */
226
+ getProductsByCategory(organizationId, categoryId, query) {
227
+ return __awaiter(this, void 0, void 0, function* () {
228
+ const { page = 1, limit = 10, search, locale } = query;
229
+ const [list, meta] = yield this.prisma.product
230
+ .paginate({
231
+ orderBy: {
232
+ createdAt: "desc",
233
+ },
234
+ where: Object.assign({ organizationId, deletedAt: null, categories: {
235
+ some: {
236
+ id: categoryId,
237
+ },
238
+ } }, (search && {
239
+ translations: {
240
+ some: {
241
+ title: {
242
+ contains: search,
243
+ mode: "insensitive",
244
+ },
245
+ },
246
+ },
247
+ })),
248
+ include: {
249
+ translations: locale
250
+ ? {
251
+ where: { locale },
252
+ }
253
+ : true,
254
+ images: true,
255
+ categories: {
256
+ include: {
257
+ translations: locale
258
+ ? {
259
+ where: { locale },
260
+ }
261
+ : true,
262
+ },
263
+ },
264
+ modifierGroups: {
265
+ include: {
266
+ translations: locale
267
+ ? {
268
+ where: { locale },
269
+ }
270
+ : true,
271
+ modifiers: true,
272
+ },
273
+ },
274
+ },
275
+ })
276
+ .withPages({
277
+ page,
278
+ limit,
279
+ });
280
+ // For getProductsByCategory, we always use ProductSchema as specified in the contract
281
+ const processedList = locale
282
+ ? list.map((item) => ProductSchema.parse(flattenTranslationData(item)))
283
+ : list.map((item) => ProductSchema.parse(item));
284
+ return z
285
+ .object({
286
+ meta: PaginationMetaSchema,
287
+ list: z.array(ProductSchema),
288
+ })
289
+ .parse({
290
+ meta,
291
+ list: processedList,
292
+ });
293
+ });
294
+ }
295
+ /**
296
+ * Update a product
297
+ */
298
+ updateProduct(organizationId, id, userId, body) {
299
+ return __awaiter(this, void 0, void 0, function* () {
300
+ // Fetch the product by id
301
+ yield this.findProduct(id, organizationId);
302
+ const updatedProduct = yield this.prisma.$transaction((tx) => __awaiter(this, void 0, void 0, function* () {
303
+ var _a, _b, _c;
304
+ // Update the product
305
+ const product = yield tx.product.update({
306
+ where: {
307
+ id,
308
+ organizationId,
309
+ deletedAt: null,
310
+ },
311
+ data: {
312
+ slug: body.slug,
313
+ sku: body.sku,
314
+ basePrice: body.basePrice,
315
+ discountedBasePrice: body.discountedBasePrice,
316
+ currency: body.currency,
317
+ manufacturerId: body.manufacturerId,
318
+ updatedBy: userId,
319
+ translations: {
320
+ deleteMany: {},
321
+ create: body.translations || [],
322
+ },
323
+ images: {
324
+ set: ((_a = body.images) === null || _a === void 0 ? void 0 : _a.map((image) => ({ id: image.id }))) || [],
325
+ },
326
+ modifierGroups: {
327
+ deleteMany: {},
328
+ create: (_b = body.modifierGroups) === null || _b === void 0 ? void 0 : _b.map((group) => ({
329
+ selectMin: group.selectMin,
330
+ selectMax: group.selectMax,
331
+ translations: {
332
+ create: group.translations,
333
+ },
334
+ modifiers: {
335
+ create: group.modifiers,
336
+ },
337
+ })),
338
+ },
339
+ categories: {
340
+ set: ((_c = body.categories) === null || _c === void 0 ? void 0 : _c.map((id) => ({ id }))) || [],
341
+ },
342
+ metadata: body.metadata || {},
343
+ },
344
+ include: {
345
+ translations: true,
346
+ images: true,
347
+ categories: {
348
+ include: {
349
+ translations: true,
350
+ },
351
+ },
352
+ modifierGroups: {
353
+ include: {
354
+ translations: true,
355
+ modifiers: true,
356
+ },
357
+ },
358
+ },
359
+ });
360
+ // Create a new product snapshot
361
+ const snapshot = yield tx.productSnapshot.create({
362
+ data: {
363
+ productId: product.id,
364
+ data: product,
365
+ createdBy: userId,
366
+ },
367
+ });
368
+ // Update the product with the new snapshot id
369
+ yield tx.product.update({
370
+ where: { id: product.id },
371
+ data: {
372
+ latestSnapshotId: snapshot.id,
373
+ },
374
+ });
375
+ return product;
376
+ }));
377
+ return ProductSchema.parse(updatedProduct);
378
+ });
379
+ }
380
+ /**
381
+ * Update product status (publish/unpublish)
382
+ */
383
+ updateProductStatus(organizationId, id, operation, userId) {
384
+ return __awaiter(this, void 0, void 0, function* () {
385
+ // Fetch the product by id
386
+ yield this.findProduct(id, organizationId);
387
+ const updatedProduct = yield this.prisma.product.update({
388
+ where: {
389
+ id,
390
+ organizationId,
391
+ deletedAt: null,
392
+ },
393
+ data: {
394
+ publishedAt: operation === "publish" ? new Date() : null,
395
+ publishedBy: operation === "publish" ? userId : null,
396
+ updatedBy: userId,
397
+ },
398
+ include: {
399
+ translations: true,
400
+ images: true,
401
+ categories: {
402
+ include: {
403
+ translations: true,
404
+ },
405
+ },
406
+ modifierGroups: {
407
+ include: {
408
+ translations: true,
409
+ modifiers: true,
410
+ },
411
+ },
412
+ },
413
+ });
414
+ return ProductSchema.parse(updatedProduct);
415
+ });
416
+ }
417
+ /**
418
+ * Delete a product (soft delete)
419
+ */
420
+ deleteProduct(organizationId, id, userId) {
421
+ return __awaiter(this, void 0, void 0, function* () {
422
+ // Fetch the product by id
423
+ yield this.findProduct(id, organizationId);
424
+ yield this.prisma.product.update({
425
+ where: {
426
+ id,
427
+ organizationId,
428
+ deletedAt: null,
429
+ },
430
+ data: {
431
+ deletedAt: new Date(),
432
+ deletedBy: userId,
433
+ },
434
+ });
435
+ return;
436
+ });
437
+ }
438
+ }
439
+ export { ProductService };
440
+ //# sourceMappingURL=product.service.js.map