@evenicanpm/storefront-core 1.0.2 → 1.0.4

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 (409) hide show
  1. package/docs.tsconfig.json +35 -0
  2. package/package.json +6 -3
  3. package/src/api-manager/README.md +30 -22
  4. package/src/api-manager/datasources/e4/{e4-address.datasource.ts → address/e4-address.datasource.ts} +10 -10
  5. package/src/api-manager/datasources/e4/address/e4-address.remaps.ts +70 -0
  6. package/src/api-manager/datasources/e4/address/e4-address.translator.ts +98 -0
  7. package/src/api-manager/datasources/e4/{e4-cart.datasource.ts → cart/e4-cart.datasource.ts} +17 -16
  8. package/src/api-manager/datasources/e4/cart/e4-cart.remaps.ts +94 -0
  9. package/src/api-manager/datasources/e4/cart/e4-cart.translator.ts +23 -0
  10. package/src/api-manager/datasources/e4/categories/e4-categories.datasource.ts +38 -0
  11. package/src/api-manager/datasources/e4/categories/e4-categories.translator.ts +161 -0
  12. package/src/api-manager/datasources/e4/e4.datasource.ts +8 -39
  13. package/src/api-manager/datasources/e4/{e4-order.datasource.ts → order/e4-order.datasource.ts} +3 -3
  14. package/src/api-manager/datasources/e4/order/e4-order.remaps.ts +101 -0
  15. package/src/api-manager/datasources/e4/{e4-organization.datasource.ts → organization/e4-organization.datasource.ts} +1 -1
  16. package/src/api-manager/datasources/e4/{e4-product.datasource.ts → product/e4-product.datasource.ts} +13 -11
  17. package/src/api-manager/datasources/e4/product/e4-product.remaps.ts +88 -0
  18. package/src/api-manager/datasources/e4/{e4.translator.ts → product/e4-product.translator.ts} +9 -329
  19. package/src/api-manager/datasources/e4/{e4-session.datasource.ts → session/e4-session.datasource.ts} +3 -3
  20. package/src/api-manager/datasources/e4/session/e4-session.translator.ts +18 -0
  21. package/src/api-manager/datasources/e4/user/e4-user.datasource.ts +13 -6
  22. package/src/api-manager/datasources/e4/user/e4-user.remaps.ts +49 -0
  23. package/src/api-manager/datasources/e4/user/e4-user.translator.ts +23 -2
  24. package/src/api-manager/datasources/e4/utils/unwrap-e4-variants.ts +1 -1
  25. package/src/api-manager/index.ts +11 -6
  26. package/src/api-manager/schemas/product.schema.ts +0 -1
  27. package/src/api-manager/schemas/user.schema.ts +3 -1
  28. package/src/api-manager/services/cart/mutations/add-to-cart.ts +1 -1
  29. package/src/api-manager/services/cart/mutations/checkout.ts +1 -2
  30. package/src/api-manager/services/create-query.ts +10 -0
  31. package/src/api-manager/services/product/queries/get-product-availability.ts +1 -1
  32. package/src/api-manager/services/product/server/product.server.ts +4 -1
  33. package/src/api-manager/services/user/mutations/add-to-wishlist.ts +23 -3
  34. package/src/api-manager/services/user/mutations/remove-from-wishlist.ts +23 -0
  35. package/src/api-manager/types/Datasource.ts +1 -5
  36. package/src/cms/blocks/BlockManager.tsx +67 -0
  37. package/src/cms/blocks/Components/BrandLogosScroller.tsx +72 -0
  38. package/src/cms/blocks/Components/CategoryCard.tsx +47 -0
  39. package/src/cms/blocks/Components/CategoryCarousel/index.tsx +59 -0
  40. package/src/cms/blocks/Components/FeaturePill.tsx +99 -0
  41. package/src/cms/blocks/Components/FeaturedCategories.tsx +41 -0
  42. package/src/cms/blocks/Components/FeaturedProducts.tsx +41 -0
  43. package/src/cms/blocks/Components/Footer/data/index.ts +32 -0
  44. package/src/cms/blocks/Components/Footer/index.tsx +88 -0
  45. package/src/cms/blocks/Components/Footer/interfaces.ts +37 -0
  46. package/src/cms/blocks/Components/Footer/sections/FooterAppStore.tsx +45 -0
  47. package/src/cms/blocks/Components/Footer/sections/FooterContact.tsx +36 -0
  48. package/src/cms/blocks/Components/Footer/sections/FooterLinks.tsx +30 -0
  49. package/src/cms/blocks/Components/Footer/sections/FooterLogo.tsx +26 -0
  50. package/src/cms/blocks/Components/Footer/sections/FooterSocialLinks.tsx +70 -0
  51. package/src/cms/blocks/Components/Footer/styles/index.ts +39 -0
  52. package/src/cms/blocks/Components/Footer.tsx +77 -0
  53. package/src/cms/blocks/Components/Hero.tsx +73 -0
  54. package/src/cms/blocks/Components/HeroCarousel/index.tsx +48 -0
  55. package/src/cms/blocks/Components/Image.tsx +39 -0
  56. package/src/cms/blocks/Components/MediaCard.tsx +41 -0
  57. package/src/cms/blocks/Components/ProductCarousel/index.tsx +88 -0
  58. package/src/cms/blocks/Components/ProductSectionFullWidth/index.tsx +107 -0
  59. package/src/cms/blocks/Components/RichText.tsx +19 -0
  60. package/src/cms/blocks/Components/Seo/index.tsx +48 -0
  61. package/src/cms/blocks/Components/Services/index.tsx +21 -0
  62. package/src/cms/blocks/Components/Services/service-card.tsx +73 -0
  63. package/src/cms/blocks/Components/shared/featured-product-card.tsx +29 -0
  64. package/src/cms/blocks/Components/shared/product-category-item.tsx +49 -0
  65. package/src/cms/blocks/Components/shared/product-grid.tsx +63 -0
  66. package/src/cms/blocks/Components/shared/top-categories-card.tsx +66 -0
  67. package/src/cms/blocks/Components/shared/top-rating-product-card.tsx +66 -0
  68. package/src/cms/blocks/Icons/Components/Category.tsx +14 -0
  69. package/src/cms/blocks/Icons/Components/DottedStar.tsx +40 -0
  70. package/src/cms/blocks/Icons/Components/FallbackIcon.tsx +33 -0
  71. package/src/cms/blocks/Icons/Components/GiftBox.tsx +18 -0
  72. package/src/cms/blocks/Icons/Components/Light.tsx +13 -0
  73. package/src/cms/blocks/Icons/Components/NewArrival.tsx +18 -0
  74. package/src/cms/blocks/Icons/Components/RankBadge.tsx +39 -0
  75. package/src/cms/blocks/Icons/index.ts +32 -0
  76. package/src/cms/blocks/index.tsx +16 -0
  77. package/src/cms/blocks/interfaces.ts +240 -0
  78. package/src/components/Notifications/README.md +1 -1
  79. package/src/components/Notifications/notification-context.tsx +1 -1
  80. package/src/components/README.md +3 -8
  81. package/src/components/_components/MiniCartClient.tsx +1 -1
  82. package/src/components/_components/navbar/category-based-menu/components/categories.tsx +1 -1
  83. package/src/components/_components/navbar/mega-menu/mega-menu.tsx +1 -1
  84. package/src/components/_components/navbar/nav-list/nav-item-child.tsx +2 -2
  85. package/src/components/_components/product-cards/product-card-1/product-card-1-wrapper.tsx +1 -1
  86. package/src/components/_components/products-view/product-view-dialog.tsx +1 -1
  87. package/src/components/_components/settings/setting.tsx +1 -1
  88. package/src/components/_components/wishlist/add-to-wishlist-dialog.tsx +2 -2
  89. package/src/components/_components/wishlist/components/create-new-list.tsx +1 -1
  90. package/src/components/_components/wishlist/remove-from-wishlist-dialog.tsx +2 -2
  91. package/src/components/_components/wishlist-modal/add-to-wishlist-dialog.tsx +2 -2
  92. package/src/components/_components/wishlist-modal/remove-from-wishlist-dialog.tsx +2 -2
  93. package/src/components/countries-input.tsx +0 -1
  94. package/src/components-v2/BazaarCard.tsx +21 -0
  95. package/src/components-v2/BazaarImage.tsx +12 -0
  96. package/src/components-v2/BazaarMenu.tsx +47 -0
  97. package/src/components-v2/BazaarSwitch.tsx +37 -0
  98. package/src/components-v2/BazaarTextField.tsx +73 -0
  99. package/src/components-v2/BoxShadowCard.tsx +16 -0
  100. package/src/components-v2/DropZone.tsx +86 -0
  101. package/src/components-v2/HoverBox.tsx +22 -0
  102. package/src/components-v2/Image.tsx +5 -0
  103. package/src/components-v2/ImageWithFallback.tsx +51 -0
  104. package/src/components-v2/LazyImage.tsx +12 -0
  105. package/src/components-v2/Loading.tsx +36 -0
  106. package/src/components-v2/README.md +4 -0
  107. package/src/components-v2/SearchInput.tsx +28 -0
  108. package/src/components-v2/SnackbarProvider.tsx +32 -0
  109. package/src/components-v2/T/index.tsx +15 -0
  110. package/src/components-v2/Typography.tsx +227 -0
  111. package/src/components-v2/WhiteButton.tsx +20 -0
  112. package/src/components-v2/accordion/accordion-header.tsx +43 -0
  113. package/src/components-v2/accordion/index.ts +1 -0
  114. package/src/components-v2/bazaar-types.ts +84 -0
  115. package/src/components-v2/carousel/carousel.tsx +106 -0
  116. package/src/components-v2/carousel/components/carousel-arrows.tsx +54 -0
  117. package/src/components-v2/carousel/components/carousel-dots.tsx +18 -0
  118. package/src/components-v2/carousel/index.ts +1 -0
  119. package/src/components-v2/carousel/styles/index.ts +93 -0
  120. package/src/components-v2/carousel-cards/carousel-card-1/carousel-card-1.tsx +83 -0
  121. package/src/components-v2/carousel-cards/carousel-card-1/index.ts +1 -0
  122. package/src/components-v2/carousel-cards/carousel-card-1/styles.ts +34 -0
  123. package/src/components-v2/categories/category-list/category-list.tsx +101 -0
  124. package/src/components-v2/categories/category-list/index.ts +1 -0
  125. package/src/components-v2/categories/category-list/styles.ts +35 -0
  126. package/src/components-v2/categories/category-list/types.ts +4 -0
  127. package/src/components-v2/categories/category-list-item/category-menu-item.tsx +37 -0
  128. package/src/components-v2/categories/category-list-item/index.ts +1 -0
  129. package/src/components-v2/categories/category-list-item/styles.ts +35 -0
  130. package/src/components-v2/categories/category-menu.tsx +53 -0
  131. package/src/components-v2/categories/mega-menu/banner.tsx +91 -0
  132. package/src/components-v2/categories/mega-menu/column-list.tsx +77 -0
  133. package/src/components-v2/categories/mega-menu/mega-menu-1.tsx +55 -0
  134. package/src/components-v2/categories/mega-menu/mega-menu-2.tsx +67 -0
  135. package/src/components-v2/categories/mega-menu/styles.ts +25 -0
  136. package/src/components-v2/categories/types.ts +16 -0
  137. package/src/components-v2/countries-input.tsx +73 -0
  138. package/src/components-v2/flex-box/flex-between.tsx +14 -0
  139. package/src/components-v2/flex-box/flex-box.tsx +9 -0
  140. package/src/components-v2/flex-box/flex-row-center.tsx +9 -0
  141. package/src/components-v2/flex-box/index.ts +5 -0
  142. package/src/components-v2/header/components/categories-menu.tsx +23 -0
  143. package/src/components-v2/header/components/mobile-header.tsx +148 -0
  144. package/src/components-v2/header/components/user.test.tsx +200 -0
  145. package/src/components-v2/header/components/user.tsx +250 -0
  146. package/src/components-v2/header/header.tsx +83 -0
  147. package/src/components-v2/header/hooks/use-header.ts +13 -0
  148. package/src/components-v2/header/index.ts +1 -0
  149. package/src/components-v2/header/sticky-header.tsx +49 -0
  150. package/src/components-v2/header/styles/index.ts +24 -0
  151. package/src/components-v2/icons/cart-bag.tsx +13 -0
  152. package/src/components-v2/icons/category-outline.tsx +29 -0
  153. package/src/components-v2/icons/category.tsx +12 -0
  154. package/src/components-v2/icons/home.tsx +19 -0
  155. package/src/components-v2/icons/search.tsx +13 -0
  156. package/src/components-v2/icons/shopping-bag-outlined.tsx +13 -0
  157. package/src/components-v2/icons/up-down.tsx +21 -0
  158. package/src/components-v2/icons/user.tsx +13 -0
  159. package/src/components-v2/icons/user2.tsx +14 -0
  160. package/src/components-v2/mini-cart/__tests__/cart-item.test.tsx +174 -0
  161. package/src/components-v2/mini-cart/__tests__/mini-cart.test.tsx +121 -0
  162. package/src/components-v2/mini-cart/__tests__/test-cart-empty.json +84 -0
  163. package/src/components-v2/mini-cart/__tests__/test-cart-with-item.json +244 -0
  164. package/src/components-v2/mini-cart/components/bottom-actions.tsx +81 -0
  165. package/src/components-v2/mini-cart/components/cart-item.tsx +205 -0
  166. package/src/components-v2/mini-cart/components/empty-view.tsx +69 -0
  167. package/src/components-v2/mini-cart/components/top-header.tsx +76 -0
  168. package/src/components-v2/mini-cart/index.ts +1 -0
  169. package/src/components-v2/mini-cart/mini-cart-trigger.tsx +99 -0
  170. package/src/components-v2/mini-cart/mini-cart.tsx +175 -0
  171. package/src/components-v2/mobile-navigation/index.ts +3 -0
  172. package/src/components-v2/mobile-navigation/mobile-navigation-bar.tsx +118 -0
  173. package/src/components-v2/mobile-navigation/styles/index.ts +63 -0
  174. package/src/components-v2/nav-link/index.ts +5 -0
  175. package/src/components-v2/nav-link/nav-link-2.tsx +32 -0
  176. package/src/components-v2/nav-link/nav-link-3.tsx +67 -0
  177. package/src/components-v2/nav-link/nav-link.tsx +53 -0
  178. package/src/components-v2/navbar/categories.tsx +81 -0
  179. package/src/components-v2/navbar/category-based-menu/category-based-menu.tsx +146 -0
  180. package/src/components-v2/navbar/category-based-menu/index.ts +1 -0
  181. package/src/components-v2/navbar/category-based-menu/styles.ts +81 -0
  182. package/src/components-v2/navbar/category-based-menu/types.ts +18 -0
  183. package/src/components-v2/navbar/index.ts +1 -0
  184. package/src/components-v2/navbar/mega-menu/index.ts +1 -0
  185. package/src/components-v2/navbar/mega-menu/mega-menu.tsx +138 -0
  186. package/src/components-v2/navbar/mega-menu/styles.ts +43 -0
  187. package/src/components-v2/navbar/mobile-menu/index.ts +1 -0
  188. package/src/components-v2/navbar/mobile-menu/mobile-menu.test.tsx +111 -0
  189. package/src/components-v2/navbar/mobile-menu/mobile-menu.tsx +141 -0
  190. package/src/components-v2/navbar/nav-list/cms-nav.test.tsx +84 -0
  191. package/src/components-v2/navbar/nav-list/index.ts +1 -0
  192. package/src/components-v2/navbar/nav-list/nav-item-child.tsx +66 -0
  193. package/src/components-v2/navbar/nav-list/nav-list.tsx +141 -0
  194. package/src/components-v2/navbar/navbar.tsx +95 -0
  195. package/src/components-v2/navbar/styles.ts +90 -0
  196. package/src/components-v2/navbar/utils/transform-nav.test.ts +209 -0
  197. package/src/components-v2/navbar/utils/transform-nav.ts +43 -0
  198. package/src/components-v2/no-records.tsx +20 -0
  199. package/src/components-v2/product-cards/discount-chip.tsx +43 -0
  200. package/src/components-v2/product-cards/product-card/components/hover-actions.tsx +37 -0
  201. package/src/components-v2/product-cards/product-card/components/quantity-buttons.tsx +65 -0
  202. package/src/components-v2/product-cards/product-card/index.ts +1 -0
  203. package/src/components-v2/product-cards/product-card/product-card.tsx +410 -0
  204. package/src/components-v2/product-cards/product-card/styles/index.ts +52 -0
  205. package/src/components-v2/product-cards/product-card-plp/components/quantity-buttons.tsx +54 -0
  206. package/src/components-v2/product-cards/product-card-plp/index.ts +1 -0
  207. package/src/components-v2/product-cards/product-card-plp/product-card.tsx +161 -0
  208. package/src/components-v2/product-cards/product-card-plp/styles/index.ts +18 -0
  209. package/src/components-v2/product-cards/product-card-plp-list/components/add-to-cart.tsx +63 -0
  210. package/src/components-v2/product-cards/product-card-plp-list/components/favorite-button.tsx +27 -0
  211. package/src/components-v2/product-cards/product-card-plp-list/components/tags.tsx +33 -0
  212. package/src/components-v2/product-cards/product-card-plp-list/index.ts +1 -0
  213. package/src/components-v2/product-cards/product-card-plp-list/product-card.tsx +219 -0
  214. package/src/components-v2/product-cards/product-card-search/index.ts +1 -0
  215. package/src/components-v2/product-cards/product-card-search/product-card.tsx +166 -0
  216. package/src/components-v2/product-cards/product-card-search/styles/index.ts +61 -0
  217. package/src/components-v2/product-cards/product-price.tsx +26 -0
  218. package/src/components-v2/product-cards/product-rating.tsx +28 -0
  219. package/src/components-v2/product-cards/product-title.tsx +24 -0
  220. package/src/components-v2/product-cards/use-product.ts +35 -0
  221. package/src/components-v2/product-dialog/compound/product-dialog.tsx +225 -0
  222. package/src/components-v2/product-dialog/index.tsx +29 -0
  223. package/src/components-v2/product-dimensions/compound/dimensions-group-error.tsx +46 -0
  224. package/src/components-v2/product-dimensions/compound/dimensions-group-label.tsx +27 -0
  225. package/src/components-v2/product-dimensions/compound/dimensions-group-list-chip.tsx +78 -0
  226. package/src/components-v2/product-dimensions/compound/dimensions-group-list.tsx +24 -0
  227. package/src/components-v2/product-dimensions/compound/dimensions-group.tsx +55 -0
  228. package/src/components-v2/product-dimensions/compound/dimensions.tsx +81 -0
  229. package/src/components-v2/product-dimensions/index.tsx +38 -0
  230. package/src/components-v2/product-dimensions/utils/has-selected-dimension.ts +20 -0
  231. package/src/components-v2/product-quantity-buttons/compound/quantity-buttons-root.tsx +181 -0
  232. package/src/components-v2/product-quantity-buttons/index.tsx +22 -0
  233. package/src/components-v2/product-quantity-variants/index.tsx +90 -0
  234. package/src/components-v2/products-view/compound/context.ts +25 -0
  235. package/src/components-v2/products-view/compound/products-grid-view.tsx +109 -0
  236. package/src/components-v2/products-view/compound/products-list-view.tsx +98 -0
  237. package/src/components-v2/products-view/compound/types.ts +12 -0
  238. package/src/components-v2/products-view/index.tsx +45 -0
  239. package/src/components-v2/products-view/products-grid-view.tsx +65 -0
  240. package/src/components-v2/products-view/products-list-view.tsx +66 -0
  241. package/src/components-v2/progress/index.ts +1 -0
  242. package/src/components-v2/progress/progress.tsx +77 -0
  243. package/src/components-v2/scrollbar/index.ts +1 -0
  244. package/src/components-v2/scrollbar/scrollbar.tsx +27 -0
  245. package/src/components-v2/scrollbar/styles.ts +15 -0
  246. package/src/components-v2/search-bar/compound/context.ts +31 -0
  247. package/src/components-v2/search-bar/compound/results-item-lg.tsx +43 -0
  248. package/src/components-v2/search-bar/compound/results-item-sm.tsx +48 -0
  249. package/src/components-v2/search-bar/compound/results-suspense.tsx +49 -0
  250. package/src/components-v2/search-bar/compound/results.tsx +42 -0
  251. package/src/components-v2/search-bar/compound/search-bar-root.tsx +64 -0
  252. package/src/components-v2/search-bar/compound/textfield-adornment-button.tsx +22 -0
  253. package/src/components-v2/search-bar/compound/textfield-adornment-category.tsx +83 -0
  254. package/src/components-v2/search-bar/compound/textfield-adornment-search-icon.tsx +34 -0
  255. package/src/components-v2/search-bar/compound/textfield.tsx +58 -0
  256. package/src/components-v2/search-bar/hooks/use-click-outside.ts +20 -0
  257. package/src/components-v2/search-bar/hooks/use-search.ts +63 -0
  258. package/src/components-v2/search-bar/index.tsx +36 -0
  259. package/src/components-v2/search-bar/styles/index.ts +49 -0
  260. package/src/components-v2/search-bar/utils/findCategoryNameById.ts +18 -0
  261. package/src/components-v2/section/compound/section-header.tsx +63 -0
  262. package/src/components-v2/section/compound/section.tsx +26 -0
  263. package/src/components-v2/section/index.ts +1 -0
  264. package/src/components-v2/side-nav/index.ts +1 -0
  265. package/src/components-v2/side-nav/side-nav.tsx +48 -0
  266. package/src/components-v2/site-logo.tsx +17 -0
  267. package/src/components-v2/sticky/index.ts +1 -0
  268. package/src/components-v2/sticky/sticky.tsx +62 -0
  269. package/src/components-v2/sticky/styles.ts +38 -0
  270. package/src/components-v2/utils/constants.ts +8 -0
  271. package/src/components-v2/wishlist-dialogs/add-to-wishlist/add-to-wishlist-button.tsx +69 -0
  272. package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-bottom-ui.tsx +35 -0
  273. package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-dialog.tsx +79 -0
  274. package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-list.tsx +41 -0
  275. package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/context.ts +29 -0
  276. package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/wishlist-dialog-header.tsx +74 -0
  277. package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/wishlist-dialog-item.tsx +82 -0
  278. package/src/components-v2/wishlist-dialogs/add-to-wishlist/hooks/use-add-to-wishlist.ts +152 -0
  279. package/src/components-v2/wishlist-dialogs/add-to-wishlist/index.tsx +39 -0
  280. package/src/components-v2/wishlist-dialogs/create-wishlist/compound/context.ts +2 -0
  281. package/src/components-v2/wishlist-dialogs/create-wishlist/compound/create-wishlist-bottom-ui.tsx +42 -0
  282. package/src/components-v2/wishlist-dialogs/create-wishlist/compound/create-wishlist-dialog.tsx +92 -0
  283. package/src/components-v2/wishlist-dialogs/create-wishlist/compound/create-wishlist-form.tsx +96 -0
  284. package/src/components-v2/wishlist-dialogs/create-wishlist/create-wishlist-button.tsx +42 -0
  285. package/src/components-v2/wishlist-dialogs/create-wishlist/index.tsx +22 -0
  286. package/src/components-v2/wishlist-dialogs/styles.ts +61 -0
  287. package/src/hooks/{use-cart.tsx → use-cart.ts} +29 -23
  288. package/src/hooks/use-variants.ts +138 -0
  289. package/src/lib/build-detail-url.ts +2 -1
  290. package/src/pages/README.md +4 -0
  291. package/src/pages/product-details/product-intro/product-intro.tsx +29 -24
  292. package/src/pages/product-list/quick-view-dialog-content.tsx +22 -11
  293. package/src/pages-v2/README.md +4 -0
  294. package/src/pages-v2/account/addresses/address-form.tsx +289 -0
  295. package/src/pages-v2/account/addresses/address-item.tsx +104 -0
  296. package/src/pages-v2/account/dashboard-header.tsx +123 -0
  297. package/src/pages-v2/account/navigation.tsx +87 -0
  298. package/src/pages-v2/account/orders/icons/delivery.tsx +14 -0
  299. package/src/pages-v2/account/orders/icons/package-box.tsx +13 -0
  300. package/src/pages-v2/account/orders/icons/truck-filled.tsx +14 -0
  301. package/src/pages-v2/account/orders/order-progress.tsx +114 -0
  302. package/src/pages-v2/account/orders/order-row.tsx +64 -0
  303. package/src/pages-v2/account/orders/order-summary.tsx +87 -0
  304. package/src/pages-v2/account/orders/ordered-products.tsx +121 -0
  305. package/src/pages-v2/account/profile/profile-button.test.tsx +59 -0
  306. package/src/pages-v2/account/profile/profile-button.tsx +50 -0
  307. package/src/pages-v2/account/profile/user-info.tsx +62 -0
  308. package/src/pages-v2/account/styles.ts +32 -0
  309. package/src/pages-v2/account/table-row.tsx +19 -0
  310. package/src/pages-v2/account/wishlist/create-new-list.tsx +167 -0
  311. package/src/pages-v2/account/wishlist/create-wishlist-button.tsx +40 -0
  312. package/src/pages-v2/account/wishlist/wishlist-item.tsx +82 -0
  313. package/src/pages-v2/blog/pagination.tsx +38 -0
  314. package/src/pages-v2/cart/cart-item.tsx +312 -0
  315. package/src/pages-v2/cart/checkout-form.tsx +122 -0
  316. package/src/pages-v2/cart/coupon-entry.tsx +90 -0
  317. package/src/pages-v2/cart/estimate-shipping.tsx +183 -0
  318. package/src/pages-v2/cart/wrapper.tsx +30 -0
  319. package/src/pages-v2/checkout/checkout-alt-form/address-card.tsx +76 -0
  320. package/src/pages-v2/checkout/checkout-alt-form/checkout-form.tsx +131 -0
  321. package/src/pages-v2/checkout/checkout-alt-form/checkout-step.tsx +120 -0
  322. package/src/pages-v2/checkout/checkout-alt-form/customer-information.tsx +94 -0
  323. package/src/pages-v2/checkout/checkout-alt-form/delivery-address.tsx +174 -0
  324. package/src/pages-v2/checkout/checkout-alt-form/delivery-date.tsx +114 -0
  325. package/src/pages-v2/checkout/checkout-alt-form/delivery-options.tsx +190 -0
  326. package/src/pages-v2/checkout/checkout-alt-form/edit-address-form.tsx +130 -0
  327. package/src/pages-v2/checkout/checkout-alt-form/heading.tsx +50 -0
  328. package/src/pages-v2/checkout/checkout-alt-form/index.ts +1 -0
  329. package/src/pages-v2/checkout/checkout-alt-form/new-address-form.tsx +299 -0
  330. package/src/pages-v2/checkout/checkout-alt-form/node.tsx +9 -0
  331. package/src/pages-v2/checkout/checkout-alt-form/payment-details.tsx +347 -0
  332. package/src/pages-v2/checkout/checkout-alt-form/safe-card-preview-data.tsx +36 -0
  333. package/src/pages-v2/checkout/checkout-alt-form/types.ts +20 -0
  334. package/src/pages-v2/checkout/checkout-alt-summary/cart-item.tsx +42 -0
  335. package/src/pages-v2/checkout/checkout-alt-summary/checkout-alt-summary.tsx +42 -0
  336. package/src/pages-v2/checkout/checkout-alt-summary/index.ts +1 -0
  337. package/src/pages-v2/checkout/checkout-alt-summary/list-item.tsx +31 -0
  338. package/src/pages-v2/confirmation/address.tsx +25 -0
  339. package/src/pages-v2/confirmation/confirmation-summary.tsx +55 -0
  340. package/src/pages-v2/confirmation/ordered-products.tsx +115 -0
  341. package/src/pages-v2/product-details/available-shops.tsx +48 -0
  342. package/src/pages-v2/product-details/bopis/find-in-store-button.tsx +64 -0
  343. package/src/pages-v2/product-details/bopis/find-in-store-modal.tsx +257 -0
  344. package/src/pages-v2/product-details/bopis/pickup-option-select.tsx +127 -0
  345. package/src/pages-v2/product-details/bopis/search-header.tsx +69 -0
  346. package/src/pages-v2/product-details/bopis/store-card/index.ts +1 -0
  347. package/src/pages-v2/product-details/bopis/store-card/shop-card.tsx +121 -0
  348. package/src/pages-v2/product-details/bopis/store-card/styles.ts +33 -0
  349. package/src/pages-v2/product-details/bopis/store-card/utils/convertSecondsToTime.ts +8 -0
  350. package/src/pages-v2/product-details/bopis/store-card/utils/getDaysResources.ts +25 -0
  351. package/src/pages-v2/product-details/checkbox-label.tsx +20 -0
  352. package/src/pages-v2/product-details/currency.ts +64 -0
  353. package/src/pages-v2/product-details/frequently-bought.tsx +97 -0
  354. package/src/pages-v2/product-details/frequently-product-card.tsx +63 -0
  355. package/src/pages-v2/product-details/product-comment.tsx +49 -0
  356. package/src/pages-v2/product-details/product-description.tsx +22 -0
  357. package/src/pages-v2/product-details/product-filter-card.tsx +265 -0
  358. package/src/pages-v2/product-details/product-intro/compound/context.ts +52 -0
  359. package/src/pages-v2/product-details/product-intro/compound/product-info.tsx +231 -0
  360. package/src/pages-v2/product-details/product-intro/compound/product-intro-images.tsx +124 -0
  361. package/src/pages-v2/product-details/product-intro/compound/product-intro.tsx +49 -0
  362. package/src/pages-v2/product-details/product-intro/compound/thumbnail-with-skeleton.tsx +28 -0
  363. package/src/pages-v2/product-details/product-intro/utils.ts +42 -0
  364. package/src/pages-v2/product-details/product-review.tsx +131 -0
  365. package/src/pages-v2/product-details/product-tabs.tsx +117 -0
  366. package/src/pages-v2/product-details/related-products.tsx +56 -0
  367. package/src/pages-v2/product-details/types.ts +11 -0
  368. package/src/pages-v2/product-list/breadcrumbs.tsx +39 -0
  369. package/src/pages-v2/product-list/checkbox-label.tsx +20 -0
  370. package/src/pages-v2/product-list/facet-group.tsx +125 -0
  371. package/src/pages-v2/product-list/facet.tsx +36 -0
  372. package/src/pages-v2/product-list/list-filter.tsx +43 -0
  373. package/src/pages-v2/product-list/pagination.tsx +80 -0
  374. package/src/pages-v2/product-list/product-list-context.tsx +302 -0
  375. package/src/pages-v2/product-list/product-list-state.ts +187 -0
  376. package/src/pages-v2/product-list/product-rating.tsx +16 -0
  377. package/src/pages-v2/product-list/quick-view-dialog-content.tsx +214 -0
  378. package/src/pages-v2/product-list/quick-view-dialog.tsx +54 -0
  379. package/src/pages-v2/product-list/range-filter.tsx +125 -0
  380. package/src/pages-v2/product-list/scrollbar.tsx +38 -0
  381. package/src/pages-v2/product-list/search-bar.tsx +162 -0
  382. package/src/pages-v2/product-list/selected-facets.tsx +80 -0
  383. package/src/pages-v2/product-list/side-nav.tsx +49 -0
  384. package/src/pages-v2/product-list/swatch.tsx +80 -0
  385. package/src/pages-v2/product-list/types.ts +18 -0
  386. package/src/pages-v2/product-list/use-product-list.ts +12 -0
  387. package/src/pages-v2/product-list/useCategoryFilter.tsx +26 -0
  388. package/src/pages-v2/product-list/utils/facet-helpers.ts +5 -0
  389. package/src/pages-v2/product-list/utils/generate-breadcrumbs.ts +30 -0
  390. package/src/pages-v2/product-list/utils/getCategoryFilterFromSlug.ts +153 -0
  391. package/src/pages-v2/product-list/utils/product-list-helper.ts +111 -0
  392. package/src/pages-v2/product-list/utils/product-list-types.ts +41 -0
  393. package/src/pages-v2/product-list/utils/search-for-category.ts +76 -0
  394. package/src/pages-v2/product-list/utils/sort-options.ts +44 -0
  395. package/src/pages-v2/product-list/utils/use-previous-refiners.ts +14 -0
  396. package/src/pages-v2/quickorder/order-upload.tsx +150 -0
  397. package/src/pages-v2/quickorder/quick-order-form.tsx +346 -0
  398. package/src/pages-v2/quickorder/quick-order-row.tsx +144 -0
  399. package/src/providers/nav-provider/index.tsx +59 -0
  400. package/src/providers/nav-provider/utils/createLink.ts +15 -0
  401. package/src/providers/notifications/README.md +15 -0
  402. package/src/providers/notifications/notification-context.tsx +82 -0
  403. package/src/providers/notifications/use-notification.ts +12 -0
  404. package/tsconfig.json +3 -2
  405. package/typedoc.js +12 -0
  406. package/src/api-manager/api-manager.config.json +0 -12
  407. package/src/api-manager/datasources/e4/e4.remaps.ts +0 -355
  408. package/src/api-manager/datasources/e4/e4.translator.test.ts +0 -202
  409. package/src/hooks/use-variants.tsx +0 -85
@@ -0,0 +1,35 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES6",
4
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
5
+ "module": "ESNext",
6
+ "sourceMap": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "declaration": true,
10
+ "moduleResolution": "node",
11
+ "resolveJsonModule": true,
12
+ "outDir": "./dist",
13
+ "jsx": "preserve",
14
+ "baseUrl": "./",
15
+ "paths": {
16
+ "@/lib/*": ["src/lib/*"],
17
+ "@/api-manager/*": ["src/api-manager/*"],
18
+ "@/auth/*": ["src/auth/*"],
19
+ "@/_components/*": ["src/components/_components/*"],
20
+ "@/components/*": ["src/components/*"],
21
+ "@/cms/*": ["src/cms/*"],
22
+ "@/schemas/*": ["src/api-manager/schemas/*"],
23
+ "@/services/*": ["src/api-manager/services/*"],
24
+ "@/hooks/*": ["src/hooks/*"],
25
+ "@config": ["src/config"]
26
+ }
27
+ },
28
+ "include": [
29
+ "src/components-v2/product-dimensions",
30
+ "src/components-v2/product-quantity-buttons",
31
+ "src/components-v2/products-view",
32
+ "src/components-v2/search-bar",
33
+ "src/components-v2/section"
34
+ ]
35
+ }
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@evenicanpm/storefront-core",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Core module for D365/e4 Headless Storefront",
5
5
  "scripts": {
6
- "test": "echo \"Error: no test specified\" && exit 1"
6
+ "test": "echo \"Error: no test specified\" && exit 1",
7
+ "docs": "typedoc"
7
8
  },
8
9
  "exports": {
9
10
  ".": "./index.js",
@@ -31,7 +32,9 @@
31
32
  "@tanstack/react-query": "^5.76.1",
32
33
  "next": "^15.2.1",
33
34
  "next-auth": "^4.24.11",
35
+ "object-mapper": "^6.2.0",
34
36
  "typescript": "^5.8.3",
35
- "object-mapper": "^6.2.0"
37
+ "typedoc": "^0.28.9",
38
+ "typedoc-plugin-merge-module": "^7.0.0"
36
39
  }
37
40
  }
@@ -1,38 +1,46 @@
1
- # Api Manager Package
1
+ # Api Manager
2
2
 
3
3
  - All data fetching will originate from this layer
4
- - Eg. a server action will call the ApiManager to interact with external systems, api, etc.
5
4
 
6
- # Folders
5
+ ## User Guide
7
6
 
8
- ## Datasources
7
+ ### 1. Setup the Api Manager config file
9
8
 
10
- - Datasource interface implementations - api manager loads multiple of these and then switches between
9
+ 1. Add a `@api-manager-config` webpack alias in your storefront next.config.js
11
10
 
12
- ## Schemas
11
+ ```js
12
+ "@api-manager-config": path.resolve(
13
+ process.cwd(),
14
+ "api-manager.config.ts",
15
+ )
16
+ ```
13
17
 
14
- - input/output types for all datasource
15
- - D365 is base type, all other datasources should translate to this model
18
+ 2. Create a JS file that exports the config object as the default.
19
+ 3. Storefront-core will read this alias when creating api manager.
16
20
 
17
- ## Core
21
+ ### 2. Add a new method to the `ApiManager`
18
22
 
19
- - Base classes and interfaces
23
+ 1. If the entity does not have a `entity.model.ts` file in `src/app/data-access/models`, add one and create schemas for input types eg. `addToCartInput`
24
+ 2. Add usecase to `data-access/Datasource.ts` interface
25
+ 3. Add the same usecase to `data-access/ApiManager.ts` class methods
26
+ 4. Finally, add method to the relevant data source, eg. `/src/app/data-access/datasources/E4.datasource.ts`
27
+ 5. You are now able to call the method from the `ApiManager.`
20
28
 
21
- ## Lib
29
+ ## Folder Structure
22
30
 
23
- - Utilities and helpers that instantiate api manager etc.
31
+ ### Datasources
32
+
33
+ - External API's
24
34
 
25
- ## Services
35
+ ### Schemas
26
36
 
27
- - layer on top of react-query
28
- - a series of hooks used for react client components
37
+ - input/output types for all datasource
38
+ - D365 is base type, all other datasources should translate to this model
29
39
 
30
- # Guide
40
+ ### Lib
31
41
 
32
- ## Add a new method to the `ApiManager`
42
+ - Utilities and helpers that instantiate api manager etc.
33
43
 
34
- 1. If the entity does not have a `entity.model.ts` file in `src/app/data-access/models`, add one and create schemas for input types eg. `addToCartInput`
35
- 2. Add usecase to `data-access/Datasource.ts` interface
36
- 3. Add the same usecase to `data-access/ApiManager.ts` class methods
37
- 4. Finally, add method to the relevant data source, eg. `/src/app/data-access/datasources/E4.datasource.ts`
38
- 5. You are now able to call the method from the `ApiManager.`
44
+ ### Services
45
+
46
+ - React-query **cache** layer
@@ -1,4 +1,4 @@
1
- import getGraphqlClient from "../../lib/get-graphql-client";
1
+ import getGraphqlClient from "../../../lib/get-graphql-client";
2
2
  import {
3
3
  Address,
4
4
  GetDeliveryOptionsInput,
@@ -9,9 +9,9 @@ import {
9
9
  DeliveryOption,
10
10
  StateProvinceInfo,
11
11
  } from "@msdyn365-commerce/retail-proxy";
12
- import { Shipping } from "./graphqlRequestSdk";
13
- import * as translator from "./e4.translator";
14
- import { addressMap } from "./e4.remaps";
12
+ import { Shipping } from "../graphqlRequestSdk";
13
+ import * as addressTranslator from "./e4-address.translator";
14
+ import { addressMap } from "./e4-address.remaps";
15
15
  import { merge } from "object-mapper";
16
16
 
17
17
  const address = {
@@ -22,12 +22,12 @@ const address = {
22
22
  throw new Error("Error getting countries");
23
23
  }
24
24
 
25
- return translator.countriesTransformValidate(data?.countries ?? []);
25
+ return addressTranslator.countriesTransformValidate(data?.countries ?? []);
26
26
  },
27
27
  async getStates(input: GetStatesInput): Promise<StateProvinceInfo[]> {
28
28
  const e4Api = await getGraphqlClient();
29
29
  const { data, errors } = await e4Api.e4Country({
30
- id: (await translator.getCountryId(input?.countryId || "")) ?? "",
30
+ id: (await addressTranslator.getCountryId(input?.countryId || "")) ?? "",
31
31
  });
32
32
  if (errors) {
33
33
  throw new Error("Error getting states");
@@ -40,7 +40,7 @@ const address = {
40
40
  isoAlpha3Code: "",
41
41
  state: [],
42
42
  };
43
- const result = translator.countryTransformValidate(countryData);
43
+ const result = addressTranslator.countryTransformValidate(countryData);
44
44
  return Array.isArray(result) ? result : [];
45
45
  },
46
46
  async getDeliveryOptions(
@@ -56,13 +56,13 @@ const address = {
56
56
  throw new Error("Error getting shipping methods");
57
57
  }
58
58
 
59
- return translator.deliveryOptionsTransformValidate(
59
+ return addressTranslator.deliveryOptionsTransformValidate(
60
60
  (data?.shippingbyCarrier as Shipping[]) ?? [],
61
61
  ) as DeliveryOption[];
62
62
  },
63
63
  async createAddress(address: Address): Promise<Address> {
64
64
  const e4Api = await getGraphqlClient(true);
65
- const e4Address = await translator.addressTransform(address);
65
+ const e4Address = await addressTranslator.addressTransform(address);
66
66
  const { data, errors } = await e4Api.e4AddressCreate({
67
67
  address: e4Address,
68
68
  });
@@ -79,7 +79,7 @@ const address = {
79
79
  },
80
80
  async updateAddress(address: Address): Promise<Address> {
81
81
  const e4Api = await getGraphqlClient(true);
82
- const e4Address = await translator.addressTransform(address);
82
+ const e4Address = await addressTranslator.addressTransform(address);
83
83
  const { data, errors } = await e4Api.e4AddressUpdate({
84
84
  address: e4Address,
85
85
  });
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Maps E4 API responses to the D365 data structure.
3
+ *
4
+ * This file uses the `object-mapper` library to transform
5
+ * API responses into a format compatible with D365.
6
+ *
7
+ * https://github.com/wankdanker/node-object-mapper
8
+ *
9
+ */
10
+ import { Address as E4Address } from "../graphqlRequestSdk";
11
+ import { Address } from "@msdyn365-commerce/retail-proxy";
12
+
13
+ export const addressMap = {
14
+ "[].id": [
15
+ { key: "[].Id" },
16
+ {
17
+ key: "[].RecordId",
18
+ transform: (id: string) => {
19
+ if (id !== null) return parseInt(id);
20
+ },
21
+ },
22
+ ],
23
+ "[].name": "[].Name",
24
+ "[].isPrimary": "[].IsPrimary",
25
+ "[].addressType.id": {
26
+ key: "[].AddressTypeValue",
27
+ transform: (id: string) => {
28
+ if (id !== null) return parseInt(id);
29
+ },
30
+ },
31
+ "[].address1": "[].Street",
32
+ "[].city": "[].City",
33
+ "[].stateName": "[].State",
34
+ "[].countryName": "[].ThreeLetterISORegionName",
35
+ "[].postalCode": "[].ZipCode",
36
+ "[].phoneNumber": "[].Phone",
37
+ "[].address2": {
38
+ key: "[].FullAddress",
39
+ transform: (_val: string, _src: E4Address[], dest: Address) => {
40
+ return `${dest?.Street}, ${dest?.City} ${dest?.State} ${dest?.ZipCode}, ${dest?.ThreeLetterISORegionName}`;
41
+ },
42
+ },
43
+ };
44
+
45
+ export const addressReverseMap = {
46
+ Name: "name",
47
+ Street: "address1",
48
+ City: "city",
49
+ ZipCode: "postalCode",
50
+ Phone: "phoneNumber",
51
+ Id: "id",
52
+ };
53
+
54
+ export const countriesMap = {
55
+ isoAlpha3Code: "CountryRegionId",
56
+ isoAlpha2Code: "ISOCode",
57
+ name: "ShortName",
58
+ };
59
+
60
+ export const countryMap = {
61
+ "state[].code": "[].StateId",
62
+ "state[].name": "[].StateName",
63
+ isoAlpha3Code: "[].CountryRegionId",
64
+ };
65
+
66
+ export const deliveryOptionsMap = {
67
+ id: ["Code", "RecordId"],
68
+ name: "Description",
69
+ total: "TotalChargeAmount",
70
+ };
@@ -0,0 +1,98 @@
1
+ import getGraphqlClient from "../../../lib/get-graphql-client";
2
+ import { AddressInput, Country, Shipping } from "../graphqlRequestSdk";
3
+ import { Address } from "@/api-manager/schemas/address.schema";
4
+ import { merge } from "object-mapper";
5
+ import {
6
+ addressReverseMap,
7
+ countriesMap,
8
+ countryMap,
9
+ deliveryOptionsMap,
10
+ } from "./e4-address.remaps";
11
+
12
+ /**
13
+ * Transforms the Address schema to e4 API address
14
+ */
15
+ export const addressTransform = async (address: Address) => {
16
+ const countryId = await getCountryId(address?.ThreeLetterISORegionName ?? "");
17
+ const stateId = await getStateId(address?.State ?? "", countryId ?? "");
18
+
19
+ const formattedAddress: AddressInput = merge(address, addressReverseMap);
20
+ formattedAddress.firstName = "";
21
+ formattedAddress.lastName = "";
22
+ formattedAddress.address2 = "";
23
+ formattedAddress.stateId = stateId;
24
+ formattedAddress.countryId = countryId;
25
+ formattedAddress.addressTypeId = 1; // We only create and update shipping addresses.
26
+
27
+ return formattedAddress;
28
+ };
29
+
30
+ const countriesCache = new Map<string, Country[]>();
31
+ const countryCache = new Map<string, Country>();
32
+
33
+ /**
34
+ * For d365 country id and value are 'USA' but for e4 it is '80175021088166' and 'USA'.
35
+ * So use countryId, to map the codes back to ids before API calls.
36
+ */
37
+ export const getCountryId = async (code: string) => {
38
+ const cacheKey = "countries";
39
+ let countries: Country[] = [];
40
+
41
+ if (countriesCache.has(cacheKey)) {
42
+ countries = countriesCache.get(cacheKey) ?? countries;
43
+ } else {
44
+ const e4Api = await getGraphqlClient();
45
+ const { data } = await e4Api.e4CountryList();
46
+ countriesCache.set(cacheKey, data?.countries as Country[]);
47
+ countries = data?.countries as Country[];
48
+ }
49
+ const country = countries.find(
50
+ (c: { isoAlpha3Code: string }) => c?.isoAlpha3Code === code,
51
+ );
52
+
53
+ return country?.id;
54
+ };
55
+
56
+ const getStateId = async (stateCode: string, countryId: string) => {
57
+ const cacheKey = `states-${countryId}`;
58
+ let country: Country = {
59
+ id: "",
60
+ isoAlpha2Code: "",
61
+ isoAlpha3Code: "",
62
+ name: "",
63
+ };
64
+
65
+ if (countryCache.has(cacheKey)) {
66
+ country = countryCache.get(cacheKey) ?? country;
67
+ } else {
68
+ const e4Api = await getGraphqlClient();
69
+ const { data } = await e4Api.e4Country({ id: countryId });
70
+ country = data?.country as Country;
71
+ countryCache.set(cacheKey, country);
72
+ }
73
+
74
+ const state = country?.state?.find((s) => s?.code === stateCode);
75
+
76
+ return state?.id;
77
+ };
78
+
79
+ export const countriesTransformValidate = (countries: Country[]) => {
80
+ if (Array.isArray(countries) && countries.length) {
81
+ return countries.map((country) => merge(country, countriesMap));
82
+ }
83
+ return [];
84
+ };
85
+
86
+ export const countryTransformValidate = (country: Country) => {
87
+ if (country?.state && country?.state.length) {
88
+ return merge(country, countryMap);
89
+ }
90
+ return [];
91
+ };
92
+
93
+ export const deliveryOptionsTransformValidate = (options: Shipping[]) => {
94
+ if (Array.isArray(options) && options.length) {
95
+ return options.map((option) => merge(option, deliveryOptionsMap));
96
+ }
97
+ return [];
98
+ };
@@ -1,7 +1,8 @@
1
- import getGraphqlClient from "../../lib/get-graphql-client";
2
- import * as cartSchema from "../../schemas/cart.schema";
3
- import { Cart } from "../../schemas/cart.schema";
4
- import * as translator from "./e4.translator";
1
+ import getGraphqlClient from "../../../lib/get-graphql-client";
2
+ import * as cartSchema from "../../../schemas/cart.schema";
3
+ import { Cart } from "../../../schemas/cart.schema";
4
+ import * as cartTranslator from "./e4-cart.translator";
5
+ import * as addressTranslator from "../address/e4-address.translator";
5
6
 
6
7
  import {
7
8
  CardPaymentAcceptPoint,
@@ -9,8 +10,8 @@ import {
9
10
  LineDeliverySpecification,
10
11
  ProductWarehouseInventoryInformation,
11
12
  } from "@msdyn365-commerce/retail-proxy";
12
- import { CartApi } from "../../types/Datasource";
13
- import { Cart as E4Cart } from "./graphqlRequestSdk";
13
+ import { CartApi } from "../../../types/Datasource";
14
+ import { Cart as E4Cart } from "../graphqlRequestSdk";
14
15
  import { SalesOrder } from "@/api-manager/schemas/order.schema";
15
16
 
16
17
  const cart: CartApi = {
@@ -24,7 +25,7 @@ const cart: CartApi = {
24
25
  throw new Error("Error reading cart");
25
26
  }
26
27
 
27
- const transformedData = translator.cartTransformValidate(
28
+ const transformedData = cartTranslator.cartTransformValidate(
28
29
  data?.cart as E4Cart,
29
30
  );
30
31
  return transformedData;
@@ -47,7 +48,7 @@ const cart: CartApi = {
47
48
  throw new Error("Error adding to cart");
48
49
  }
49
50
 
50
- const transformedData = translator.cartTransformValidate(
51
+ const transformedData = cartTranslator.cartTransformValidate(
51
52
  data?.addToCart?.cart as E4Cart,
52
53
  );
53
54
  return transformedData;
@@ -73,7 +74,7 @@ const cart: CartApi = {
73
74
  if (cart.ShippingAddress) {
74
75
  const address = cart.ShippingAddress;
75
76
  const createAddress = await e4Api.e4CreateCartAddress({
76
- address: await translator.addressTransform(address),
77
+ address: await addressTranslator.addressTransform(address),
77
78
  });
78
79
 
79
80
  if (createAddress.errors) {
@@ -89,7 +90,7 @@ const cart: CartApi = {
89
90
  throw new Error("Error getting cart information");
90
91
  }
91
92
 
92
- const transformedData = translator.cartTransformValidate(
93
+ const transformedData = cartTranslator.cartTransformValidate(
93
94
  data?.cart as E4Cart,
94
95
  );
95
96
  return transformedData;
@@ -118,7 +119,7 @@ const cart: CartApi = {
118
119
  cart = data.updateCartLine;
119
120
  }
120
121
 
121
- const transformedData = translator.cartTransformValidate(
122
+ const transformedData = cartTranslator.cartTransformValidate(
122
123
  cart?.cart as E4Cart,
123
124
  );
124
125
  return transformedData;
@@ -142,7 +143,7 @@ const cart: CartApi = {
142
143
  throw new Error("Error updating cart");
143
144
  }
144
145
 
145
- const transformedData = translator.cartTransformValidate(
146
+ const transformedData = cartTranslator.cartTransformValidate(
146
147
  data?.deleteCartLine?.cart as E4Cart,
147
148
  );
148
149
  return transformedData;
@@ -157,7 +158,7 @@ const cart: CartApi = {
157
158
  throw new Error("Error reading cart");
158
159
  }
159
160
 
160
- const transformedData = translator.cartTransformValidate(
161
+ const transformedData = cartTranslator.cartTransformValidate(
161
162
  data?.cart as E4Cart,
162
163
  );
163
164
  return transformedData;
@@ -192,7 +193,7 @@ const cart: CartApi = {
192
193
  );
193
194
  }
194
195
 
195
- return translator.cartTransformValidate(
196
+ return cartTranslator.cartTransformValidate(
196
197
  data?.setOrderShipping?.cart as E4Cart,
197
198
  );
198
199
  },
@@ -244,11 +245,11 @@ const cart: CartApi = {
244
245
  SalesLines: [],
245
246
  };
246
247
  },
247
- getCartLinesInventory: function(
248
+ getCartLinesInventory: function (
248
249
  _input: cartSchema.InventorySearchCartLinesCriteriaInput,
249
250
  ): Promise<ProductWarehouseInventoryInformation> {
250
251
  throw new Error("Function not implemented.");
251
252
  },
252
253
  };
253
254
 
254
- export { cart };
255
+ export default cart;
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Maps E4 API responses to the D365 data structure.
3
+ *
4
+ * This file uses the `object-mapper` library to transform
5
+ * API responses into a format compatible with D365.
6
+ *
7
+ * https://github.com/wankdanker/node-object-mapper
8
+ *
9
+ */
10
+ import {
11
+ Address,
12
+ Product as DynProduct,
13
+ } from "@msdyn365-commerce/retail-proxy";
14
+ import { Product, CartLine, Address as E4Address } from "../graphqlRequestSdk";
15
+ import { merge } from "object-mapper";
16
+ import { productMap } from "../product/e4-product.remaps";
17
+ import { addressMap } from "../address/e4-address.remaps";
18
+
19
+ /* CART REMAPS */
20
+ export const cartLineMap = {
21
+ "[].product": {
22
+ key: "[].Product?",
23
+ transform: (product: Product) => {
24
+ // If cart is empty, prevents CartLines[] from having entries
25
+ if (!product) return;
26
+
27
+ // For some reason transform is run multiple times. This prevents merge from running multiple times and overwriting translation.
28
+ const translated = merge(product, productMap) as DynProduct & {
29
+ ProductTypeValue?: number;
30
+ };
31
+ if (!translated.RecordId) return product;
32
+ translated.ProductTypeValue = 4; // default for now. Type = Standalone
33
+ return translated;
34
+ },
35
+ },
36
+ "[].id": "[].LineId",
37
+ "[].product.id": {
38
+ key: "[].ProductId",
39
+ transform: (id: string) => {
40
+ if (id !== null) return parseInt(id);
41
+ },
42
+ },
43
+ "[].product.code": "[].ItemId",
44
+ "[].product.name": "[].Product.Name",
45
+ "[].quantity": "[].Quantity",
46
+ "[].price": [
47
+ { key: "[].Price", default: 0 },
48
+ { key: "[].Product.Price", default: 0 },
49
+ { key: "[].Product.BasePrice", default: 0 },
50
+ { key: "[].Product.AdjustedPrice", default: 0 },
51
+ ],
52
+ "[].amount": [{ key: "[].TotalAmount" }, { key: "[].NetPrice" }],
53
+ "[].uom.name": {
54
+ key: "[].UnitOfMeasureSymbol",
55
+ transform: (name: string) => {
56
+ if (name !== null) {
57
+ if (name === "Each") return "ea";
58
+ return name;
59
+ }
60
+ },
61
+ },
62
+ "[].product.productType": {
63
+ key: "[].Product.ProductTypeValue",
64
+ default: 4,
65
+ },
66
+ };
67
+
68
+ export const cartMap = {
69
+ id: "Id",
70
+ itemCount: "TotalItems",
71
+
72
+ lines: {
73
+ key: "CartLines",
74
+ transform: (lines: CartLine[]) => {
75
+ if (lines.length === 0) return [];
76
+ return merge(lines, cartLineMap);
77
+ },
78
+ },
79
+
80
+ subtotal: "SubtotalAmountWithoutTax",
81
+ freightTotal: "ShippingChargeAmount",
82
+ taxTotal: "TaxAmount",
83
+ total: "TotalAmount",
84
+ email: "ReceiptEmail",
85
+
86
+ addresses: {
87
+ key: "ShippingAddress",
88
+ transform: (addresses: E4Address[]) => {
89
+ if (addresses.length === 0) return undefined;
90
+ const translated = merge(addresses, addressMap) as Address[];
91
+ return translated[addresses.length - 1];
92
+ },
93
+ },
94
+ };
@@ -0,0 +1,23 @@
1
+ import { extendedCartSchema, Cart } from "@/api-manager/schemas/cart.schema";
2
+ import { Cart as E4Cart } from "../graphqlRequestSdk";
3
+ import { cartMap } from "./e4-cart.remaps";
4
+ import { merge } from "object-mapper";
5
+
6
+ /**
7
+ * Transforms the E4 AddToCart response to a Cart retail-proxy object
8
+ * Add parameters to transform model as needed
9
+ *
10
+ * @param data the E4 Cart object
11
+ * @returns the transformed cart object
12
+ */
13
+ export const cartTransformValidate = (cart: E4Cart): Cart => {
14
+ if (!(cart && cart?.id)) throw new Error("Not a valid cart");
15
+ const transformedData = merge(cart, cartMap);
16
+ try {
17
+ extendedCartSchema.parse(transformedData);
18
+ } catch (e) {
19
+ console.warn("Cart data does not match retail-proxy schema", e);
20
+ }
21
+
22
+ return transformedData as Cart;
23
+ };
@@ -0,0 +1,38 @@
1
+ import getGraphqlClient from "@/api-manager/lib/get-graphql-client";
2
+ import { CategoryHierarchy } from "@/lib/category-helpers";
3
+ import { CategoryApi } from "@/api-manager/types/Datasource";
4
+ import { Category as E4Category } from "../graphqlRequestSdk";
5
+ import * as categoryTranslator from "./e4-categories.translator";
6
+
7
+ const categories: CategoryApi = {
8
+ async getCategories(): Promise<CategoryHierarchy[]> {
9
+ const e4Api = await getGraphqlClient();
10
+ const { data: rawApiResult, errors } = await e4Api.categories();
11
+
12
+ if (errors) {
13
+ console.error(
14
+ "GraphQL errors reading categories (in categories.getCategories):",
15
+ errors,
16
+ );
17
+ throw new Error("Error getting categories");
18
+ }
19
+
20
+ const rawCategoryArray = rawApiResult?.categories?.category;
21
+
22
+ if (!Array.isArray(rawCategoryArray)) {
23
+ console.warn(
24
+ "Categories data at expected path not found or not an array in categories.getCategories:",
25
+ rawApiResult,
26
+ );
27
+ return [];
28
+ }
29
+
30
+ const transformedHierarchicalData =
31
+ categoryTranslator.categoryTransformValidate(
32
+ rawApiResult?.categories?.category as E4Category[],
33
+ );
34
+ return transformedHierarchicalData;
35
+ },
36
+ };
37
+
38
+ export default categories;