@evenicanpm/storefront-core 1.0.0-alpha

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 (475) hide show
  1. package/README.md +40 -0
  2. package/package.json +36 -0
  3. package/src/api-manager/README.md +38 -0
  4. package/src/api-manager/api-manager.config.json +12 -0
  5. package/src/api-manager/datasources/README.md +17 -0
  6. package/src/api-manager/datasources/d365/d365-address.datasource.ts +141 -0
  7. package/src/api-manager/datasources/d365/d365-base.datasource.ts +8 -0
  8. package/src/api-manager/datasources/d365/d365-cart.datasource.ts +374 -0
  9. package/src/api-manager/datasources/d365/d365-categories.datasource.ts +40 -0
  10. package/src/api-manager/datasources/d365/d365-order.datasource.ts +69 -0
  11. package/src/api-manager/datasources/d365/d365-organization.datasource.ts +92 -0
  12. package/src/api-manager/datasources/d365/d365-product.datasource.ts +272 -0
  13. package/src/api-manager/datasources/d365/d365-session.datasource.ts +25 -0
  14. package/src/api-manager/datasources/d365/d365-user.datasource.ts +132 -0
  15. package/src/api-manager/datasources/d365/d365.datasource.ts +45 -0
  16. package/src/api-manager/datasources/d365/index.ts +4 -0
  17. package/src/api-manager/datasources/d365/test-context.ts +30 -0
  18. package/src/api-manager/datasources/d365/utils/create-search-criteria.ts +17 -0
  19. package/src/api-manager/datasources/d365/utils/decode-jwt.ts +11 -0
  20. package/src/api-manager/datasources/d365/utils/get-context-cookie.ts +37 -0
  21. package/src/api-manager/datasources/d365/utils/parse-object.ts +9 -0
  22. package/src/api-manager/datasources/d365/utils/product-images-utils.ts +43 -0
  23. package/src/api-manager/datasources/d365/utils/product-inventory-utils.ts +37 -0
  24. package/src/api-manager/datasources/e4/e4-address.datasource.ts +107 -0
  25. package/src/api-manager/datasources/e4/e4-cart.datasource.ts +248 -0
  26. package/src/api-manager/datasources/e4/e4-order.datasource.ts +43 -0
  27. package/src/api-manager/datasources/e4/e4-organization.datasource.ts +19 -0
  28. package/src/api-manager/datasources/e4/e4-product.datasource.ts +157 -0
  29. package/src/api-manager/datasources/e4/e4-session.datasource.ts +43 -0
  30. package/src/api-manager/datasources/e4/e4-user.datasource.ts +118 -0
  31. package/src/api-manager/datasources/e4/e4.datasource.ts +55 -0
  32. package/src/api-manager/datasources/e4/e4.remaps.ts +331 -0
  33. package/src/api-manager/datasources/e4/e4.translator.test.ts +202 -0
  34. package/src/api-manager/datasources/e4/e4.translator.ts +648 -0
  35. package/src/api-manager/datasources/e4/graphqlRequestSdk.ts +43515 -0
  36. package/src/api-manager/datasources/e4/utils/unwrap-e4-variants.ts +65 -0
  37. package/src/api-manager/index.ts +71 -0
  38. package/src/api-manager/lib/cart-cookie-handler.ts +14 -0
  39. package/src/api-manager/lib/category-helpers.ts +113 -0
  40. package/src/api-manager/lib/get-dynamics-context.ts +34 -0
  41. package/src/api-manager/lib/get-graphql-client.test.ts +106 -0
  42. package/src/api-manager/lib/get-graphql-client.ts +53 -0
  43. package/src/api-manager/schemas/README.md +12 -0
  44. package/src/api-manager/schemas/address.schema.ts +46 -0
  45. package/src/api-manager/schemas/cart.schema.ts +92 -0
  46. package/src/api-manager/schemas/d365.schema.ts +7727 -0
  47. package/src/api-manager/schemas/order.schema.ts +30 -0
  48. package/src/api-manager/schemas/organization.schema.ts +32 -0
  49. package/src/api-manager/schemas/product.schema.ts +140 -0
  50. package/src/api-manager/schemas/session.schema.ts +17 -0
  51. package/src/api-manager/schemas/user.schema.ts +14 -0
  52. package/src/api-manager/services/address/mutations/create-address.ts +22 -0
  53. package/src/api-manager/services/address/mutations/delete-address.ts +21 -0
  54. package/src/api-manager/services/address/mutations/get-delivery-options.ts +22 -0
  55. package/src/api-manager/services/address/mutations/update-address.ts +21 -0
  56. package/src/api-manager/services/address/queries/get-countries.ts +16 -0
  57. package/src/api-manager/services/address/queries/get-states.ts +16 -0
  58. package/src/api-manager/services/cart/mutations/add-discount-code.ts +21 -0
  59. package/src/api-manager/services/cart/mutations/add-to-cart.ts +53 -0
  60. package/src/api-manager/services/cart/mutations/checkout.ts +11 -0
  61. package/src/api-manager/services/cart/mutations/delete-cart-line.ts +18 -0
  62. package/src/api-manager/services/cart/mutations/get-payment-accept-result.ts +20 -0
  63. package/src/api-manager/services/cart/mutations/remove-cart-line-delivery-mode.ts +24 -0
  64. package/src/api-manager/services/cart/mutations/remove-discount-code.ts +21 -0
  65. package/src/api-manager/services/cart/mutations/update-cart-line-delivery-mode.ts +24 -0
  66. package/src/api-manager/services/cart/mutations/update-cart-lines.ts +21 -0
  67. package/src/api-manager/services/cart/mutations/update-cart.ts +21 -0
  68. package/src/api-manager/services/cart/queries/get-cart.ts +12 -0
  69. package/src/api-manager/services/cart/queries/get-payment-accept-point.ts +18 -0
  70. package/src/api-manager/services/categories/queries/get-categories.ts +8 -0
  71. package/src/api-manager/services/create-mutation.ts +65 -0
  72. package/src/api-manager/services/create-query.ts +305 -0
  73. package/src/api-manager/services/get-query-client.ts +40 -0
  74. package/src/api-manager/services/order/queries/get-order-details.ts +17 -0
  75. package/src/api-manager/services/order/queries/get-orders.ts +14 -0
  76. package/src/api-manager/services/organization/queries/get-channel-configuration.ts +14 -0
  77. package/src/api-manager/services/organization/queries/get-stores.ts +17 -0
  78. package/src/api-manager/services/product/mutations/search-products.ts +23 -0
  79. package/src/api-manager/services/product/queries/get-product-availability.ts +15 -0
  80. package/src/api-manager/services/product/queries/get-product-by-id.ts +17 -0
  81. package/src/api-manager/services/product/queries/get-product-by-ids.ts +14 -0
  82. package/src/api-manager/services/product/queries/get-product-list.ts +16 -0
  83. package/src/api-manager/services/product/queries/get-related-products.ts +14 -0
  84. package/src/api-manager/services/product/queries/search-products.ts +10 -0
  85. package/src/api-manager/services/product/server/product.server.ts +13 -0
  86. package/src/api-manager/services/session/mutations/session-init.ts +22 -0
  87. package/src/api-manager/services/session/mutations/session-logout.ts +18 -0
  88. package/src/api-manager/services/session/queries/get-session.ts +10 -0
  89. package/src/api-manager/services/user/mutations/create-wishlist.ts +21 -0
  90. package/src/api-manager/services/user/mutations/delete-wishlist.ts +17 -0
  91. package/src/api-manager/services/user/mutations/update-user.ts +18 -0
  92. package/src/api-manager/services/user/queries/get-user-counts.ts +10 -0
  93. package/src/api-manager/services/user/queries/get-user.ts +10 -0
  94. package/src/api-manager/services/user/queries/get-wishlist-details.ts +10 -0
  95. package/src/api-manager/services/user/queries/get-wishlists.ts +10 -0
  96. package/src/api-manager/types/Datasource.ts +197 -0
  97. package/src/auth/auth-options.test.ts +127 -0
  98. package/src/auth/auth-options.ts +68 -0
  99. package/src/auth/msal.ts +65 -0
  100. package/src/auth/next-auth-cookie-manager.ts +86 -0
  101. package/src/auth/providers/aadb2c-provider.ts +33 -0
  102. package/src/auth/providers/authentik-provider.ts +24 -0
  103. package/src/auth/providers/index.ts +9 -0
  104. package/src/auth/providers/keycloak-provider.ts +22 -0
  105. package/src/auth/refresh-token-url-keys.ts +6 -0
  106. package/src/auth/refresh-token.ts +134 -0
  107. package/src/auth/signout.ts +46 -0
  108. package/src/auth/types/next-auth.d.ts +38 -0
  109. package/src/cms/blog.ts +229 -0
  110. package/src/cms/endpoints.ts +76 -0
  111. package/src/cms/interfaces/navigation.ts +52 -0
  112. package/src/cms/interfaces/productData.ts +83 -0
  113. package/src/cms/pages.ts +149 -0
  114. package/src/components/Blocks/BlockManager.tsx +67 -0
  115. package/src/components/Blocks/Components/BrandLogosScroller.tsx +72 -0
  116. package/src/components/Blocks/Components/CategoryCard.tsx +47 -0
  117. package/src/components/Blocks/Components/CategoryCarousel/index.tsx +60 -0
  118. package/src/components/Blocks/Components/FeaturePill.tsx +99 -0
  119. package/src/components/Blocks/Components/FeaturedCategories.tsx +41 -0
  120. package/src/components/Blocks/Components/FeaturedProducts.tsx +41 -0
  121. package/src/components/Blocks/Components/Footer.tsx +77 -0
  122. package/src/components/Blocks/Components/Hero.tsx +73 -0
  123. package/src/components/Blocks/Components/HeroCarousel/index.tsx +42 -0
  124. package/src/components/Blocks/Components/Image.tsx +39 -0
  125. package/src/components/Blocks/Components/MediaCard.tsx +41 -0
  126. package/src/components/Blocks/Components/ProductCarousel/index.tsx +82 -0
  127. package/src/components/Blocks/Components/ProductSectionFullWidth/index.tsx +103 -0
  128. package/src/components/Blocks/Components/RichText.tsx +19 -0
  129. package/src/components/Blocks/Components/Seo/index.tsx +48 -0
  130. package/src/components/Blocks/Components/Services/index.tsx +21 -0
  131. package/src/components/Blocks/Components/Services/service-card.tsx +70 -0
  132. package/src/components/Blocks/Components/shared/featured-product-card.tsx +29 -0
  133. package/src/components/Blocks/Components/shared/product-category-item.tsx +49 -0
  134. package/src/components/Blocks/Components/shared/product-grid.tsx +48 -0
  135. package/src/components/Blocks/Components/shared/top-categories-card.tsx +66 -0
  136. package/src/components/Blocks/Components/shared/top-rating-product-card.tsx +63 -0
  137. package/src/components/Blocks/Icons/Components/Category.tsx +14 -0
  138. package/src/components/Blocks/Icons/Components/DottedStar.tsx +40 -0
  139. package/src/components/Blocks/Icons/Components/FallbackIcon.tsx +33 -0
  140. package/src/components/Blocks/Icons/Components/GiftBox.tsx +18 -0
  141. package/src/components/Blocks/Icons/Components/Light.tsx +13 -0
  142. package/src/components/Blocks/Icons/Components/NewArrival.tsx +18 -0
  143. package/src/components/Blocks/Icons/Components/RankBadge.tsx +39 -0
  144. package/src/components/Blocks/Icons/index.ts +32 -0
  145. package/src/components/Blocks/index.tsx +16 -0
  146. package/src/components/Blocks/interfaces.ts +240 -0
  147. package/src/components/BoxShadowCard.tsx +16 -0
  148. package/src/components/Footer/data/index.ts +32 -0
  149. package/src/components/Footer/index.tsx +88 -0
  150. package/src/components/Footer/interfaces.ts +37 -0
  151. package/src/components/Footer/sections/FooterAppStore.tsx +45 -0
  152. package/src/components/Footer/sections/FooterContact.tsx +36 -0
  153. package/src/components/Footer/sections/FooterLinks.tsx +30 -0
  154. package/src/components/Footer/sections/FooterLogo.tsx +26 -0
  155. package/src/components/Footer/sections/FooterSocialLinks.tsx +70 -0
  156. package/src/components/Footer/styles/index.ts +39 -0
  157. package/src/components/GlobalLoading/index.tsx +102 -0
  158. package/src/components/ImageWithFallback.tsx +51 -0
  159. package/src/components/Loading/index.tsx +36 -0
  160. package/src/components/NavProvider/index.tsx +59 -0
  161. package/src/components/NavProvider/utils/createLink.ts +15 -0
  162. package/src/components/Notifications/README.md +15 -0
  163. package/src/components/Notifications/notification-context.tsx +82 -0
  164. package/src/components/Notifications/use-notification.ts +12 -0
  165. package/src/components/README.md +9 -0
  166. package/src/components/ReactQueryProvider/index.tsx +12 -0
  167. package/src/components/Shared/Image.tsx +5 -0
  168. package/src/components/T/index.tsx +15 -0
  169. package/src/components/_components/BazaarCard.tsx +21 -0
  170. package/src/components/_components/BazaarImage.tsx +12 -0
  171. package/src/components/_components/BazaarMenu.tsx +47 -0
  172. package/src/components/_components/BazaarSwitch.tsx +37 -0
  173. package/src/components/_components/BazaarTextField.tsx +73 -0
  174. package/src/components/_components/DropZone.tsx +86 -0
  175. package/src/components/_components/HoverBox.tsx +22 -0
  176. package/src/components/_components/LazyImage.tsx +9 -0
  177. package/src/components/_components/MiniCartClient.tsx +65 -0
  178. package/src/components/_components/SearchInput.tsx +28 -0
  179. package/src/components/_components/SnackbarProvider.tsx +32 -0
  180. package/src/components/_components/Typography.tsx +227 -0
  181. package/src/components/_components/WhiteButton.tsx +20 -0
  182. package/src/components/_components/accordion/accordion-header.tsx +43 -0
  183. package/src/components/_components/accordion/index.ts +1 -0
  184. package/src/components/_components/bazaar-types.ts +84 -0
  185. package/src/components/_components/carousel/carousel.tsx +72 -0
  186. package/src/components/_components/carousel/components/carousel-arrows.tsx +60 -0
  187. package/src/components/_components/carousel/components/carousel-dots.tsx +21 -0
  188. package/src/components/_components/carousel/index.ts +3 -0
  189. package/src/components/_components/carousel/styles/index.ts +93 -0
  190. package/src/components/_components/carousel-cards/carousel-card-1/carousel-card-1.tsx +64 -0
  191. package/src/components/_components/carousel-cards/carousel-card-1/index.ts +1 -0
  192. package/src/components/_components/carousel-cards/carousel-card-1/styles.ts +34 -0
  193. package/src/components/_components/carousel-cards/carousel-card-2/carousel-card-2.tsx +73 -0
  194. package/src/components/_components/carousel-cards/carousel-card-2/index.ts +1 -0
  195. package/src/components/_components/carousel-cards/carousel-card-2/styles.ts +26 -0
  196. package/src/components/_components/carousel-cards/carousel-card-3/carousel-card-3.tsx +34 -0
  197. package/src/components/_components/carousel-cards/carousel-card-3/index.ts +1 -0
  198. package/src/components/_components/carousel-cards/carousel-card-3/styles.ts +28 -0
  199. package/src/components/_components/carousel-cards/carousel-card-4/carousel-card-4.tsx +76 -0
  200. package/src/components/_components/carousel-cards/carousel-card-4/index.ts +1 -0
  201. package/src/components/_components/carousel-cards/carousel-card-4/styles.ts +27 -0
  202. package/src/components/_components/categories/category-list/category-list.tsx +59 -0
  203. package/src/components/_components/categories/category-list/index.ts +1 -0
  204. package/src/components/_components/categories/category-list/styles.ts +29 -0
  205. package/src/components/_components/categories/category-list/types.ts +4 -0
  206. package/src/components/_components/categories/category-list-item/category-menu-item.tsx +37 -0
  207. package/src/components/_components/categories/category-list-item/index.ts +1 -0
  208. package/src/components/_components/categories/category-list-item/styles.ts +35 -0
  209. package/src/components/_components/categories/category-menu.tsx +51 -0
  210. package/src/components/_components/categories/mega-menu/banner.tsx +56 -0
  211. package/src/components/_components/categories/mega-menu/column-list.tsx +70 -0
  212. package/src/components/_components/categories/mega-menu/mega-menu-1.tsx +37 -0
  213. package/src/components/_components/categories/mega-menu/mega-menu-2.tsx +37 -0
  214. package/src/components/_components/categories/mega-menu/styles.ts +25 -0
  215. package/src/components/_components/categories/types.ts +16 -0
  216. package/src/components/_components/category-cards/category-card-1/category-card-1.tsx +21 -0
  217. package/src/components/_components/category-cards/category-card-1/index.ts +1 -0
  218. package/src/components/_components/category-cards/category-card-1/styles.ts +37 -0
  219. package/src/components/_components/countdown/count-box.tsx +16 -0
  220. package/src/components/_components/countdown/count-down.tsx +24 -0
  221. package/src/components/_components/countdown/index.tsx +2 -0
  222. package/src/components/_components/countdown/useCountDown.ts +41 -0
  223. package/src/components/_components/data-table/index.ts +2 -0
  224. package/src/components/_components/data-table/table-header.tsx +91 -0
  225. package/src/components/_components/data-table/table-pagination.tsx +36 -0
  226. package/src/components/_components/flex-box/flex-between.tsx +14 -0
  227. package/src/components/_components/flex-box/flex-box.tsx +9 -0
  228. package/src/components/_components/flex-box/flex-row-center.tsx +9 -0
  229. package/src/components/_components/flex-box/index.ts +5 -0
  230. package/src/components/_components/footer/components/about-links.tsx +23 -0
  231. package/src/components/_components/footer/components/app-store.tsx +38 -0
  232. package/src/components/_components/footer/components/customer-care-links.tsx +21 -0
  233. package/src/components/_components/footer/components/logo.tsx +23 -0
  234. package/src/components/_components/footer/components/social-links.tsx +43 -0
  235. package/src/components/_components/footer/data/index.ts +54 -0
  236. package/src/components/_components/footer/footer-1.tsx +62 -0
  237. package/src/components/_components/footer/footer-2.tsx +57 -0
  238. package/src/components/_components/footer/footer-3.tsx +53 -0
  239. package/src/components/_components/footer/footer-4.tsx +71 -0
  240. package/src/components/_components/footer/index.ts +4 -0
  241. package/src/components/_components/footer/styles/index.ts +42 -0
  242. package/src/components/_components/header/components/categories-menu.tsx +23 -0
  243. package/src/components/_components/header/components/mobile-header.tsx +72 -0
  244. package/src/components/_components/header/components/user.test.tsx +200 -0
  245. package/src/components/_components/header/components/user.tsx +205 -0
  246. package/src/components/_components/header/header.tsx +63 -0
  247. package/src/components/_components/header/hooks/use-header.ts +13 -0
  248. package/src/components/_components/header/index.ts +1 -0
  249. package/src/components/_components/header/sticky-header.tsx +17 -0
  250. package/src/components/_components/header/styles/index.ts +24 -0
  251. package/src/components/_components/hooks/useOverflowDetect.ts +34 -0
  252. package/src/components/_components/hooks/useSettings.ts +16 -0
  253. package/src/components/_components/icons/cart-bag.tsx +13 -0
  254. package/src/components/_components/icons/category-outline.tsx +29 -0
  255. package/src/components/_components/icons/category.tsx +12 -0
  256. package/src/components/_components/icons/home.tsx +19 -0
  257. package/src/components/_components/icons/search.tsx +13 -0
  258. package/src/components/_components/icons/shopping-bag-outlined.tsx +13 -0
  259. package/src/components/_components/icons/up-down.tsx +21 -0
  260. package/src/components/_components/icons/user.tsx +13 -0
  261. package/src/components/_components/icons/user2.tsx +14 -0
  262. package/src/components/_components/mini-cart/__tests__/cart-item.test.tsx +174 -0
  263. package/src/components/_components/mini-cart/__tests__/mini-cart.test.tsx +121 -0
  264. package/src/components/_components/mini-cart/__tests__/test-cart-empty.json +84 -0
  265. package/src/components/_components/mini-cart/__tests__/test-cart-with-item.json +244 -0
  266. package/src/components/_components/mini-cart/components/bottom-actions.tsx +27 -0
  267. package/src/components/_components/mini-cart/components/cart-item.tsx +144 -0
  268. package/src/components/_components/mini-cart/components/empty-view.tsx +29 -0
  269. package/src/components/_components/mini-cart/components/top-header.tsx +34 -0
  270. package/src/components/_components/mini-cart/index.ts +1 -0
  271. package/src/components/_components/mini-cart/mini-cart.tsx +107 -0
  272. package/src/components/_components/mobile-navigation/index.ts +3 -0
  273. package/src/components/_components/mobile-navigation/mobile-navigation-bar.tsx +73 -0
  274. package/src/components/_components/mobile-navigation/styles/index.ts +63 -0
  275. package/src/components/_components/nav-link/index.ts +5 -0
  276. package/src/components/_components/nav-link/nav-link-2.tsx +32 -0
  277. package/src/components/_components/nav-link/nav-link-3.tsx +67 -0
  278. package/src/components/_components/nav-link/nav-link.tsx +53 -0
  279. package/src/components/_components/navbar/categories.tsx +27 -0
  280. package/src/components/_components/navbar/category-based-menu/category-based-menu.tsx +52 -0
  281. package/src/components/_components/navbar/category-based-menu/components/categories.tsx +44 -0
  282. package/src/components/_components/navbar/category-based-menu/components/category-item.tsx +31 -0
  283. package/src/components/_components/navbar/category-based-menu/components/child-categories.tsx +38 -0
  284. package/src/components/_components/navbar/category-based-menu/index.ts +1 -0
  285. package/src/components/_components/navbar/category-based-menu/styles.ts +81 -0
  286. package/src/components/_components/navbar/category-based-menu/types.ts +18 -0
  287. package/src/components/_components/navbar/index.ts +1 -0
  288. package/src/components/_components/navbar/mega-menu/category-list.tsx +29 -0
  289. package/src/components/_components/navbar/mega-menu/index.ts +1 -0
  290. package/src/components/_components/navbar/mega-menu/mega-menu.tsx +71 -0
  291. package/src/components/_components/navbar/mega-menu/styles.ts +43 -0
  292. package/src/components/_components/navbar/mobile-menu/index.ts +1 -0
  293. package/src/components/_components/navbar/mobile-menu/mobile-menu.tsx +70 -0
  294. package/src/components/_components/navbar/mobile-menu/render-levels.test.tsx +71 -0
  295. package/src/components/_components/navbar/mobile-menu/render-levels.tsx +62 -0
  296. package/src/components/_components/navbar/nav-list/cms-nav.test.tsx +84 -0
  297. package/src/components/_components/navbar/nav-list/index.ts +1 -0
  298. package/src/components/_components/navbar/nav-list/nav-item-child.tsx +66 -0
  299. package/src/components/_components/navbar/nav-list/nav-list.tsx +119 -0
  300. package/src/components/_components/navbar/navbar.tsx +43 -0
  301. package/src/components/_components/navbar/styles.ts +90 -0
  302. package/src/components/_components/navbar/utils/transform-nav.test.ts +209 -0
  303. package/src/components/_components/navbar/utils/transform-nav.ts +43 -0
  304. package/src/components/_components/newsletter/index.ts +1 -0
  305. package/src/components/_components/newsletter/newsletter.tsx +108 -0
  306. package/src/components/_components/newsletter/social-icons.tsx +35 -0
  307. package/src/components/_components/newsletter/styles.ts +65 -0
  308. package/src/components/_components/page-sidenav/grocery-side-nav/components/link-item.tsx +21 -0
  309. package/src/components/_components/page-sidenav/grocery-side-nav/components/list-item.tsx +27 -0
  310. package/src/components/_components/page-sidenav/grocery-side-nav/components/nav-accordion.tsx +36 -0
  311. package/src/components/_components/page-sidenav/grocery-side-nav/components/render-child.tsx +26 -0
  312. package/src/components/_components/page-sidenav/grocery-side-nav/grocery-side-nav.tsx +32 -0
  313. package/src/components/_components/page-sidenav/grocery-side-nav/index.ts +1 -0
  314. package/src/components/_components/page-sidenav/grocery-side-nav/styles/index.ts +11 -0
  315. package/src/components/_components/page-sidenav/health-beauty-side-nav/components/list-item.tsx +27 -0
  316. package/src/components/_components/page-sidenav/health-beauty-side-nav/components/nav-accordion.tsx +44 -0
  317. package/src/components/_components/page-sidenav/health-beauty-side-nav/components/render-child.tsx +20 -0
  318. package/src/components/_components/page-sidenav/health-beauty-side-nav/health-beauty-side-nav.tsx +43 -0
  319. package/src/components/_components/page-sidenav/health-beauty-side-nav/index.ts +1 -0
  320. package/src/components/_components/page-sidenav/health-beauty-side-nav/styles/index.ts +27 -0
  321. package/src/components/_components/page-sidenav/side-navbar/components/list-item.tsx +25 -0
  322. package/src/components/_components/page-sidenav/side-navbar/components/nav-accordion.tsx +46 -0
  323. package/src/components/_components/page-sidenav/side-navbar/components/render-child.tsx +20 -0
  324. package/src/components/_components/page-sidenav/side-navbar/index.ts +1 -0
  325. package/src/components/_components/page-sidenav/side-navbar/side-nav-bar.tsx +77 -0
  326. package/src/components/_components/page-sidenav/side-navbar/styles/index.ts +73 -0
  327. package/src/components/_components/page-sidenav/side-navbar-2/components/button-content.tsx +32 -0
  328. package/src/components/_components/page-sidenav/side-navbar-2/components/sidebar-accordion.tsx +66 -0
  329. package/src/components/_components/page-sidenav/side-navbar-2/index.ts +1 -0
  330. package/src/components/_components/page-sidenav/side-navbar-2/side-navbar-2.tsx +63 -0
  331. package/src/components/_components/page-sidenav/side-navbar-2/styles/index.ts +68 -0
  332. package/src/components/_components/product-cards/discount-chip.tsx +43 -0
  333. package/src/components/_components/product-cards/product-card-1/components/hover-actions.tsx +37 -0
  334. package/src/components/_components/product-cards/product-card-1/components/quantity-buttons.tsx +56 -0
  335. package/src/components/_components/product-cards/product-card-1/index.ts +1 -0
  336. package/src/components/_components/product-cards/product-card-1/product-card.tsx +146 -0
  337. package/src/components/_components/product-cards/product-card-1/styles/index.ts +46 -0
  338. package/src/components/_components/product-cards/product-card-10/index.ts +1 -0
  339. package/src/components/_components/product-cards/product-card-10/product-card.tsx +124 -0
  340. package/src/components/_components/product-cards/product-card-10/styles/index.ts +38 -0
  341. package/src/components/_components/product-cards/product-card-11/index.ts +1 -0
  342. package/src/components/_components/product-cards/product-card-11/product-card.tsx +63 -0
  343. package/src/components/_components/product-cards/product-card-11/styles/index.ts +16 -0
  344. package/src/components/_components/product-cards/product-card-12/index.ts +1 -0
  345. package/src/components/_components/product-cards/product-card-12/product-card.tsx +42 -0
  346. package/src/components/_components/product-cards/product-card-12/styles/index.ts +16 -0
  347. package/src/components/_components/product-cards/product-card-13/index.ts +1 -0
  348. package/src/components/_components/product-cards/product-card-13/product-card.tsx +45 -0
  349. package/src/components/_components/product-cards/product-card-13/styles/index.ts +25 -0
  350. package/src/components/_components/product-cards/product-card-14/index.ts +1 -0
  351. package/src/components/_components/product-cards/product-card-14/product-card.tsx +122 -0
  352. package/src/components/_components/product-cards/product-card-14/styles/index.ts +40 -0
  353. package/src/components/_components/product-cards/product-card-15/index.ts +1 -0
  354. package/src/components/_components/product-cards/product-card-15/product-card.tsx +118 -0
  355. package/src/components/_components/product-cards/product-card-15/styles/index.ts +57 -0
  356. package/src/components/_components/product-cards/product-card-16/components/quantity-buttons.tsx +56 -0
  357. package/src/components/_components/product-cards/product-card-16/index.ts +1 -0
  358. package/src/components/_components/product-cards/product-card-16/product-card.tsx +114 -0
  359. package/src/components/_components/product-cards/product-card-16/styles/index.ts +18 -0
  360. package/src/components/_components/product-cards/product-card-2/components/favorite-button.tsx +29 -0
  361. package/src/components/_components/product-cards/product-card-2/components/product-price.tsx +26 -0
  362. package/src/components/_components/product-cards/product-card-2/index.ts +1 -0
  363. package/src/components/_components/product-cards/product-card-2/product-card.tsx +70 -0
  364. package/src/components/_components/product-cards/product-card-3/components/hover-actions.tsx +83 -0
  365. package/src/components/_components/product-cards/product-card-3/index.ts +1 -0
  366. package/src/components/_components/product-cards/product-card-3/product-card.tsx +110 -0
  367. package/src/components/_components/product-cards/product-card-3/styles/index.ts +89 -0
  368. package/src/components/_components/product-cards/product-card-4/components/hover-actions.tsx +50 -0
  369. package/src/components/_components/product-cards/product-card-4/index.ts +1 -0
  370. package/src/components/_components/product-cards/product-card-4/product-card.tsx +128 -0
  371. package/src/components/_components/product-cards/product-card-4/styles/index.ts +66 -0
  372. package/src/components/_components/product-cards/product-card-5/components/button-actions.tsx +49 -0
  373. package/src/components/_components/product-cards/product-card-5/components/hover-actions.tsx +50 -0
  374. package/src/components/_components/product-cards/product-card-5/index.ts +1 -0
  375. package/src/components/_components/product-cards/product-card-5/product-card.tsx +137 -0
  376. package/src/components/_components/product-cards/product-card-5/styles/index.ts +94 -0
  377. package/src/components/_components/product-cards/product-card-6/components/hover-actions.tsx +50 -0
  378. package/src/components/_components/product-cards/product-card-6/index.ts +1 -0
  379. package/src/components/_components/product-cards/product-card-6/product-card.tsx +121 -0
  380. package/src/components/_components/product-cards/product-card-6/styles/index.ts +63 -0
  381. package/src/components/_components/product-cards/product-card-7/components/product-status.tsx +18 -0
  382. package/src/components/_components/product-cards/product-card-7/components/quantity-buttons.tsx +47 -0
  383. package/src/components/_components/product-cards/product-card-7/index.ts +1 -0
  384. package/src/components/_components/product-cards/product-card-7/product-card.tsx +136 -0
  385. package/src/components/_components/product-cards/product-card-7/styles/index.ts +98 -0
  386. package/src/components/_components/product-cards/product-card-8/index.ts +1 -0
  387. package/src/components/_components/product-cards/product-card-8/product-card.tsx +133 -0
  388. package/src/components/_components/product-cards/product-card-8/styles/index.ts +51 -0
  389. package/src/components/_components/product-cards/product-card-9/components/add-to-cart.tsx +60 -0
  390. package/src/components/_components/product-cards/product-card-9/components/favorite-button.tsx +27 -0
  391. package/src/components/_components/product-cards/product-card-9/components/tags.tsx +33 -0
  392. package/src/components/_components/product-cards/product-card-9/index.ts +1 -0
  393. package/src/components/_components/product-cards/product-card-9/product-card.tsx +169 -0
  394. package/src/components/_components/product-cards/product-price.tsx +26 -0
  395. package/src/components/_components/product-cards/product-rating.tsx +28 -0
  396. package/src/components/_components/product-cards/product-title.tsx +24 -0
  397. package/src/components/_components/product-cards/use-product.ts +35 -0
  398. package/src/components/_components/products-view/product-view-dialog.tsx +180 -0
  399. package/src/components/_components/products-view/products-grid-view.tsx +39 -0
  400. package/src/components/_components/products-view/products-list-view.tsx +35 -0
  401. package/src/components/_components/progress/index.ts +1 -0
  402. package/src/components/_components/progress/progress.tsx +77 -0
  403. package/src/components/_components/scrollbar/index.ts +1 -0
  404. package/src/components/_components/scrollbar/scrollbar.tsx +27 -0
  405. package/src/components/_components/scrollbar/styles.ts +15 -0
  406. package/src/components/_components/search-box/components/category-dropdown.tsx +61 -0
  407. package/src/components/_components/search-box/components/search-result.tsx +29 -0
  408. package/src/components/_components/search-box/hooks/use-search.ts +63 -0
  409. package/src/components/_components/search-box/index.ts +2 -0
  410. package/src/components/_components/search-box/search-input-category.test.tsx +110 -0
  411. package/src/components/_components/search-box/search-input-category.tsx +104 -0
  412. package/src/components/_components/search-box/search-input.test.tsx +41 -0
  413. package/src/components/_components/search-box/search-input.tsx +64 -0
  414. package/src/components/_components/search-box/styles/index.ts +45 -0
  415. package/src/components/_components/section-header/index.ts +2 -0
  416. package/src/components/_components/section-header/section-creator.tsx +28 -0
  417. package/src/components/_components/section-header/section-header.tsx +44 -0
  418. package/src/components/_components/service-cards/icon-component.tsx +18 -0
  419. package/src/components/_components/service-cards/service-card-1/index.ts +1 -0
  420. package/src/components/_components/service-cards/service-card-1/service-card-1.tsx +39 -0
  421. package/src/components/_components/service-cards/service-card-2/index.ts +1 -0
  422. package/src/components/_components/service-cards/service-card-2/service-card-2.tsx +34 -0
  423. package/src/components/_components/service-cards/service-card-3/index.ts +1 -0
  424. package/src/components/_components/service-cards/service-card-3/service-card-3.tsx +25 -0
  425. package/src/components/_components/service-cards/service-card-3/styles.ts +23 -0
  426. package/src/components/_components/settings/index.ts +1 -0
  427. package/src/components/_components/settings/setting.tsx +141 -0
  428. package/src/components/_components/settings/styles.ts +57 -0
  429. package/src/components/_components/shop-card/index.ts +1 -0
  430. package/src/components/_components/shop-card/shop-card.tsx +152 -0
  431. package/src/components/_components/shop-card/styles.ts +33 -0
  432. package/src/components/_components/side-nav/index.ts +1 -0
  433. package/src/components/_components/side-nav/side-nav.tsx +49 -0
  434. package/src/components/_components/site-logo.tsx +17 -0
  435. package/src/components/_components/sticky/Sticky.tsx +62 -0
  436. package/src/components/_components/sticky/index.ts +1 -0
  437. package/src/components/_components/sticky/styles.ts +38 -0
  438. package/src/components/_components/sticky-wrapper/index.ts +1 -0
  439. package/src/components/_components/sticky-wrapper/sticky-wrapper.tsx +21 -0
  440. package/src/components/_components/sticky-wrapper/styles.ts +25 -0
  441. package/src/components/_components/stories/story-content/index.ts +1 -0
  442. package/src/components/_components/stories/story-content/story-content.tsx +28 -0
  443. package/src/components/_components/stories/story-content/styles.ts +22 -0
  444. package/src/components/_components/stories/story-item/index.ts +1 -0
  445. package/src/components/_components/stories/story-item/story-item.tsx +24 -0
  446. package/src/components/_components/stories/story-item/styles.ts +11 -0
  447. package/src/components/_components/stories/story-viewer/index.ts +1 -0
  448. package/src/components/_components/stories/story-viewer/story-viewer.tsx +44 -0
  449. package/src/components/_components/stories/story-viewer/styles.ts +15 -0
  450. package/src/components/_components/subscribe-input/index.ts +1 -0
  451. package/src/components/_components/subscribe-input/styles.ts +14 -0
  452. package/src/components/_components/subscribe-input/subscribe-input.tsx +43 -0
  453. package/src/components/_components/topbar/index.ts +1 -0
  454. package/src/components/_components/topbar/styles.ts +55 -0
  455. package/src/components/_components/topbar/top-bar.tsx +112 -0
  456. package/src/components/_components/utils/constants.ts +8 -0
  457. package/src/components/countries-input.tsx +78 -0
  458. package/src/config.ts +47 -0
  459. package/src/lib/build-detail-url.ts +8 -0
  460. package/src/lib/build-product-detail-url.ts +12 -0
  461. package/src/lib/cart-cookie-client-handler.ts +12 -0
  462. package/src/lib/cart-cookie-handler.ts +14 -0
  463. package/src/lib/category-helpers.ts +113 -0
  464. package/src/lib/create-graphql-client.ts +32 -0
  465. package/src/lib/currency-formatter.ts +31 -0
  466. package/src/lib/get-palette-color.ts +50 -0
  467. package/src/lib/graphqlRequestSdk.ts +41234 -0
  468. package/src/lib/hexToLuma.ts +55 -0
  469. package/src/lib/lib.ts +61 -0
  470. package/src/lib/map-helper.ts +71 -0
  471. package/src/lib/page-slugs.ts +10 -0
  472. package/src/lib/refiner-utils.ts +32 -0
  473. package/src/lib/store-hours-helper.ts +274 -0
  474. package/src/lib/test-media.ts +23 -0
  475. package/tsconfig.json +27 -0
@@ -0,0 +1,65 @@
1
+ import { merge } from "object-mapper";
2
+ import { Attributes, Maybe, Variants } from "../graphqlRequestSdk";
3
+ import { dimensionMap } from "../e4.remaps";
4
+
5
+ type DimensionValue = {
6
+ Value: string;
7
+ RecordId: string;
8
+ };
9
+
10
+ type UnwrappedAttribute = {
11
+ DimensionTypeValue: string;
12
+ DimensionValue: DimensionValue;
13
+ TotalAvailableInventoryLevelCode: string;
14
+ ProductIds: string[];
15
+ };
16
+
17
+ /**
18
+ * Unwraps an E4 Product variant and converts it
19
+ * to D365 Dimension Data Structure
20
+ * @param variants an e4 product variant
21
+ * @returns [][]
22
+ */
23
+ export default function unwrapE4Variants(
24
+ variants: Variants[],
25
+ ): UnwrappedAttribute[][] {
26
+ if (!(variants && variants?.length)) return [];
27
+ const attrs: UnwrappedAttribute[] = variants.flatMap(
28
+ (v) =>
29
+ v.Attributes?.map((attr: Maybe<Attributes>) => {
30
+ const dimension = attr ? merge(attr, dimensionMap) : null;
31
+
32
+ if (!dimension) return null;
33
+
34
+ return {
35
+ ...dimension,
36
+ ProductIds: [v.ProductId],
37
+ } as UnwrappedAttribute;
38
+ }).filter(Boolean) as UnwrappedAttribute[],
39
+ );
40
+
41
+ const grouped: UnwrappedAttribute[][] = attrs.reduce((acc, item) => {
42
+ const group = acc.find(
43
+ (group) => group[0]?.DimensionTypeValue === item.DimensionTypeValue,
44
+ );
45
+
46
+ if (!group) {
47
+ acc.push([item]);
48
+ } else {
49
+ const existingDimension = group.find(
50
+ (attribute) =>
51
+ attribute.DimensionValue.Value === item.DimensionValue.Value,
52
+ );
53
+
54
+ if (!existingDimension) {
55
+ group.push(item);
56
+ } else if (!existingDimension.ProductIds.includes(item.ProductIds[0])) {
57
+ existingDimension.ProductIds.push(item.ProductIds[0]);
58
+ }
59
+ }
60
+
61
+ return acc;
62
+ }, [] as UnwrappedAttribute[][]);
63
+
64
+ return grouped;
65
+ }
@@ -0,0 +1,71 @@
1
+ import { Datasource, DatasourceApis } from "./types/Datasource";
2
+ import E4Datasource from "./datasources/e4/e4.datasource";
3
+ import { D365Datasource } from "./datasources/d365/index";
4
+ import rawConfig from "./api-manager.config.json";
5
+ import { z } from "zod";
6
+ import { getContextFromCookie } from "./datasources/d365/utils/get-context-cookie";
7
+ type EntityNames = keyof DatasourceApis;
8
+
9
+ interface Config {
10
+ primary: string;
11
+ secondary: string[];
12
+ overrides?: Partial<Record<EntityNames, string>>;
13
+ }
14
+
15
+ const Config = z.object({
16
+ primary: z.string(),
17
+ secondary: z.array(z.string()),
18
+ overrides: z.record(z.string(), z.string()),
19
+ });
20
+
21
+ /**
22
+ * Loads up all specified apis/datasources based on parsed config
23
+ * and returns the ApiManager object.
24
+ * @returns ApiManager object.
25
+ */
26
+ async function createApiManager() {
27
+ try {
28
+ Config.parse(rawConfig);
29
+ } catch (error) {
30
+ if (error instanceof z.ZodError) {
31
+ error.issues;
32
+ }
33
+ }
34
+
35
+ const context = await getContextFromCookie();
36
+ const datasourceMap: Record<string, Datasource> = {
37
+ d365: new D365Datasource("d365", context),
38
+ e4: E4Datasource,
39
+ // Add more datasources here as needed
40
+ };
41
+
42
+ const config = rawConfig as Config;
43
+ const primaryDatasource = datasourceMap[config.primary];
44
+ const secondaryDatasources = config.secondary.map(
45
+ (name) => datasourceMap[name],
46
+ );
47
+
48
+ const getDatasource = (entityName: EntityNames) => {
49
+ const override = config?.overrides?.[entityName];
50
+ if (override) {
51
+ return (
52
+ secondaryDatasources.find((ds) => ds.name === override) ??
53
+ primaryDatasource
54
+ );
55
+ }
56
+ return primaryDatasource;
57
+ };
58
+
59
+ return {
60
+ user: getDatasource("user").user,
61
+ session: getDatasource("session").session,
62
+ cart: getDatasource("cart").cart,
63
+ product: getDatasource("product").product,
64
+ categories: getDatasource("categories").categories,
65
+ order: getDatasource("order").order,
66
+ address: getDatasource("address").address,
67
+ organization: getDatasource("organization").organization,
68
+ };
69
+ }
70
+
71
+ export default createApiManager;
@@ -0,0 +1,14 @@
1
+ "use server";
2
+ import { cookies } from "next/headers";
3
+
4
+ const getCartCookie = async () => (await cookies()).get("cart_cookie")?.value;
5
+
6
+ const setCartCookie = async (cartId: string) => {
7
+ (await cookies()).set("cart_cookie", cartId);
8
+ };
9
+
10
+ const deleteCartCookie = async () => {
11
+ (await cookies()).delete("cart_cookie");
12
+ };
13
+
14
+ export { getCartCookie, setCartCookie, deleteCartCookie };
@@ -0,0 +1,113 @@
1
+ import {
2
+ Category,
3
+ TextValueTranslation,
4
+ } from "@msdyn365-commerce/retail-proxy";
5
+
6
+ export interface CategoryHierarchy extends Category {
7
+ Children: CategoryHierarchy[];
8
+ Slug?: string;
9
+ Url?: string;
10
+ NeutralizedName?: string;
11
+ IsCMSPage?: boolean;
12
+ }
13
+
14
+ export type CategoryMap = {
15
+ [RecordId: number]: CategoryHierarchy;
16
+ };
17
+
18
+ const mapCategoryToHierarchy = (
19
+ categoryList: Category[],
20
+ locale?: string,
21
+ includeRootCategory?: boolean,
22
+ ): CategoryHierarchy[] => {
23
+ if (!categoryList || categoryList.length === 0) {
24
+ return [];
25
+ }
26
+
27
+ const categoryMap: CategoryMap = {};
28
+
29
+ for (const category of categoryList) {
30
+ const localName = getFriendlyName(locale, category.NameTranslations);
31
+ const categoryHierarchy = <CategoryHierarchy>{ ...category };
32
+ categoryHierarchy.NeutralizedName = category.Name;
33
+ categoryHierarchy.Name = localName || categoryHierarchy.NeutralizedName;
34
+ // Derive Slug from Url or Name for D365
35
+ categoryHierarchy.Slug =
36
+ (category as CategoryHierarchy).Url?.split("/")
37
+ .pop()
38
+ ?.replace(/\d+$/, "") || normalizeCategoryName(category?.Name ?? "");
39
+ categoryMap[category.RecordId] = categoryHierarchy;
40
+ }
41
+
42
+ let rootCategory: CategoryHierarchy | undefined;
43
+ for (const category of Object.values(categoryMap)) {
44
+ const parentId = category.ParentCategory;
45
+ if (!category.Url) {
46
+ category.Url = generateUrl(categoryList, category, locale || "");
47
+ }
48
+ if (parentId === 0) {
49
+ rootCategory = category;
50
+ continue;
51
+ }
52
+
53
+ const parent = parentId && categoryMap[parentId];
54
+ if (parent) {
55
+ parent.Children = parent.Children || [];
56
+ parent.Children.push(category);
57
+ }
58
+ }
59
+
60
+ if (!rootCategory) {
61
+ return [];
62
+ }
63
+
64
+ if (includeRootCategory) {
65
+ const categoryHierarchy: CategoryHierarchy[] = [];
66
+ categoryHierarchy.push(rootCategory);
67
+ return categoryHierarchy;
68
+ }
69
+
70
+ return rootCategory.Children ?? [];
71
+ };
72
+
73
+ const generateUrl = (
74
+ categoryHierarchy: Category[],
75
+ currentCategory: CategoryHierarchy,
76
+ locale: string,
77
+ ) => {
78
+ const categoryNames: string[] = [];
79
+ let nextCat: CategoryHierarchy | Category | undefined = currentCategory;
80
+ while (nextCat) {
81
+ const catName =
82
+ getFriendlyName(locale, nextCat.NameTranslations) || nextCat.Name || "";
83
+ categoryNames.push(normalizeCategoryName(catName));
84
+ nextCat = categoryHierarchy.find(
85
+ (c) => c.RecordId === nextCat?.ParentCategory,
86
+ );
87
+ }
88
+ categoryNames.unshift(currentCategory.RecordId.toString());
89
+ return categoryNames.reverse().join("/");
90
+ };
91
+
92
+ const getFriendlyName = (
93
+ locale?: string,
94
+ nameTranslations?: TextValueTranslation[],
95
+ ): string | undefined => {
96
+ let nameTranslation: TextValueTranslation | undefined;
97
+ if (locale && nameTranslations && nameTranslations.length > 0) {
98
+ nameTranslation = nameTranslations.find(
99
+ (item) => item?.Language?.toLowerCase() === locale?.toLowerCase(),
100
+ );
101
+ }
102
+ return nameTranslation && nameTranslation.Text;
103
+ };
104
+
105
+ const normalizeCategoryName = (string_: string) =>
106
+ string_.toLowerCase().replaceAll(" ", "-");
107
+
108
+ export {
109
+ mapCategoryToHierarchy,
110
+ generateUrl,
111
+ getFriendlyName,
112
+ normalizeCategoryName,
113
+ };
@@ -0,0 +1,34 @@
1
+ import { ICallerContext } from "@msdyn365-commerce/retail-proxy";
2
+
3
+ export const getDynamicsContext = (
4
+ channelConfig: ChannelConfiguration,
5
+ token?: string,
6
+ ): ICallerContext => {
7
+ const { channelId, operatingUnitNumber, retailServerUrl, locale } =
8
+ channelConfig;
9
+
10
+ return {
11
+ requestContext: {
12
+ locale,
13
+ apiSettings: {
14
+ baseUrl: retailServerUrl,
15
+ channelId: Number(channelId),
16
+ oun: operatingUnitNumber,
17
+ catalogId: 0,
18
+ baseImageUrl: "",
19
+ },
20
+ user: {
21
+ isAuthenticated: !!token,
22
+ token: token || "",
23
+ },
24
+ operationId: crypto.randomUUID(),
25
+ },
26
+ };
27
+ };
28
+
29
+ export type ChannelConfiguration = {
30
+ locale: string;
31
+ retailServerUrl: string;
32
+ channelId: number;
33
+ operatingUnitNumber: string;
34
+ };
@@ -0,0 +1,106 @@
1
+ //import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import { getServerSession } from "next-auth/next";
3
+ import { cookies } from "next/headers";
4
+ import getGraphQLClient from "./get-graphql-client";
5
+
6
+ // TODO: FIX THESE TESTS
7
+ //
8
+ //const mockSetHeaders = vi.fn();
9
+ // const mockGraphQLClientInstance = { setHeaders: mockSetHeaders };
10
+
11
+ /*
12
+ vi.mock("graphql-request", () => ({
13
+ GraphQLClient: vi.fn(() => mockGraphQLClientInstance),
14
+ }));
15
+
16
+ vi.mock("@/api-manager/datasources/e4/graphqlRequestSdk", () => ({
17
+ getSdk: vi.fn(() => "mockSDK"),
18
+ }));
19
+
20
+ vi.mock("next-auth/next", () => ({
21
+ getServerSession: vi.fn(),
22
+ }));
23
+
24
+ vi.mock("@a/api/auth/[...nextauth]/auth-options", () => ({
25
+ default: {},
26
+ }));
27
+
28
+ vi.mock("next/headers", () => ({
29
+ cookies: vi.fn(),
30
+ }));
31
+
32
+ describe("getGraphQLClient", () => {
33
+ beforeEach(() => {
34
+ vi.clearAllMocks();
35
+ });
36
+
37
+ it("initializes GraphQL client without authentication", async () => {
38
+ (cookies as unknown as vi.Mock).mockReturnValue({
39
+ get: vi.fn().mockReturnValue(null),
40
+ });
41
+
42
+ const sdk = await getGraphQLClient();
43
+
44
+ expect(mockSetHeaders).toHaveBeenCalledWith({
45
+ "client-name": "storefront",
46
+ "client-version": "0.1.0",
47
+ "Content-Type": "application/json",
48
+ Accept: "application/json",
49
+ });
50
+ expect(sdk).toBe("mockSDK");
51
+ });
52
+
53
+ it("includes storefront session cookie if available", async () => {
54
+ (cookies as unknown as vi.Mock).mockReturnValue({
55
+ get: vi.fn().mockReturnValue({ value: "mockSessionCookie" }),
56
+ });
57
+
58
+ const sdk = await getGraphQLClient();
59
+
60
+ expect(mockSetHeaders).toHaveBeenCalledWith(
61
+ expect.objectContaining({
62
+ Cookie: "storefront=mockSessionCookie",
63
+ }),
64
+ );
65
+ expect(sdk).toBe("mockSDK");
66
+ });
67
+
68
+ it("includes authorization token when withAuth is true", async () => {
69
+ (cookies as unknown as vi.Mock).mockReturnValue({
70
+ get: vi.fn().mockReturnValue(null),
71
+ });
72
+
73
+ (getServerSession as vi.Mock).mockResolvedValue({
74
+ accessToken: "mockAccessToken",
75
+ });
76
+
77
+ const sdk = await getGraphQLClient(true);
78
+
79
+ expect(getServerSession).toHaveBeenCalled();
80
+ expect(mockSetHeaders).toHaveBeenCalledWith(
81
+ expect.objectContaining({
82
+ Authorization: "Bearer mockAccessToken",
83
+ }),
84
+ );
85
+ expect(sdk).toBe("mockSDK");
86
+ });
87
+
88
+ it("does not include authorization token if session is missing", async () => {
89
+ (cookies as unknown as vi.Mock).mockReturnValue({
90
+ get: vi.fn().mockReturnValue(null),
91
+ });
92
+
93
+ (getServerSession as vi.Mock).mockResolvedValue(null);
94
+
95
+ const sdk = await getGraphQLClient(true);
96
+
97
+ expect(getServerSession).toHaveBeenCalled();
98
+ expect(mockSetHeaders).not.toHaveBeenCalledWith(
99
+ expect.objectContaining({
100
+ Authorization: expect.any(String),
101
+ }),
102
+ );
103
+ expect(sdk).toBe("mockSDK");
104
+ });
105
+ });
106
+ */
@@ -0,0 +1,53 @@
1
+ "use server";
2
+
3
+ import { GraphQLClient } from "graphql-request";
4
+ import { getSdk } from "../datasources/e4/graphqlRequestSdk";
5
+ import { getServerSession } from "next-auth/next";
6
+ // TODO: Get auth inside client packages
7
+ import authOptions from "@/auth/auth-options";
8
+ import { cookies } from "next/headers";
9
+
10
+ const API_URL = process.env.REACT_APP_E4_API_ENDPOINT; //`https://api.e4.local/graphql`;
11
+
12
+ /**
13
+ * Initializes and returns a cached GraphQL client
14
+ * @param withAuth (optional) - If true, includes the authorization token
15
+ * @returns GraphQL SDK instance
16
+ */
17
+ const getGraphQLClient = async (withAuth = false) => {
18
+ const headers: Record<string, string> = {
19
+ "client-name": "storefront",
20
+ "client-version": "0.1.0",
21
+ "Content-Type": "application/json",
22
+ Accept: "application/json",
23
+ };
24
+
25
+ const cookieStore = await cookies();
26
+ const sessionCookie = cookieStore.get("storefront"); // cookie is set in middleware - setE4SessionCookies
27
+ // This session cookie solution only works when all api calls are through server actions.
28
+ // If not we need to route all e4 client api calls through an custom api route.
29
+ if (sessionCookie) {
30
+ headers["Cookie"] = `storefront=${sessionCookie.value}`;
31
+ }
32
+
33
+ if (withAuth) {
34
+ const session = await getServerSession(authOptions());
35
+ // @ts-ignore
36
+ if (session && session?.accessToken) {
37
+ // @ts-ignore
38
+ headers["Authorization"] = `Bearer ${session.accessToken}`;
39
+ }
40
+ }
41
+
42
+ // Best Practice: Never reuse a GraphQL client that mutates headers across different requests in server environments.
43
+ // When we resuse the client instance, sometimes the token is missing in e4 backend.
44
+ const client = new GraphQLClient(API_URL, {
45
+ headers,
46
+ credentials: "include",
47
+ });
48
+
49
+ client.setHeaders(headers);
50
+ return getSdk(client);
51
+ };
52
+
53
+ export default getGraphQLClient;
@@ -0,0 +1,12 @@
1
+ # Schemas
2
+
3
+ - Contains all the base models that datasource data fetching/mutating must output.
4
+ - The reason it is stored in it's own folder is because it is data source agnostic and should not belong to any one data source
5
+ - <entity>.schema.ts are the input and output validation schemas for each entity
6
+ - `d365.schema.ts` is generated from ts-to-zod to provide schemas for all d365 entities in the retail-proxy library.
7
+ - to re-run codegen of schemas run `npm run generate-schemas`
8
+ - Now that we have decided to use the generated schemas for the entity types, the `<entity>.schema.ts` files will contain mostly input types for mutations
9
+
10
+ ## Output types
11
+
12
+ - We should try to use the default schemas from D3565 as much as possible, if we encounter a unique situation or if there a lot of bloat properties on D365 type that do not exist in E4 then create a custom entity schema.
@@ -0,0 +1,46 @@
1
+ import z from "zod";
2
+ import { addressSchema } from "./d365.schema";
3
+
4
+ export const addressTypeSchema = z
5
+ .object({
6
+ Id: z.string(),
7
+ Name: z.string().optional(),
8
+ DisplayName: z.string().optional(),
9
+ })
10
+ .optional();
11
+
12
+ // export const addressSchema = z.object({
13
+ // Id:z.string().optional(),
14
+ // Name:z.string().optional(),
15
+ // FirstName: z.string().optional(),
16
+ // LastName: z.string().optional(),
17
+ // IsPrimary:z.boolean().optional(),
18
+ // AddressType: addressTypeSchema,
19
+ // AddressLine1: z.string().optional(),
20
+ // AddressLine2: z.string().optional(),
21
+ // City: z.string().optional(),
22
+ // StateId: z.string().optional(),
23
+ // StateName: z.string().optional(),
24
+ // CountryId: z.string().optional(),
25
+ // CountryName: z.string().optional(),
26
+ // CountryCode: z.string().optional(),
27
+ // ZipCode: z.string().optional(),
28
+ // Phone: z.string().optional(),
29
+ // });
30
+
31
+ const getCountriesInput = z.object({
32
+ locale: z.string().optional(),
33
+ });
34
+ const getStatesInput = z.object({
35
+ countryId: z.string().optional(),
36
+ });
37
+
38
+ const getDeliveryOptionsInput = z.object({
39
+ cartId: z.string(),
40
+ shippingAddress: addressSchema,
41
+ cartLineIds: z.array(z.string()),
42
+ });
43
+ export type GetCountriesInput = z.infer<typeof getCountriesInput>;
44
+ export type GetStatesInput = z.infer<typeof getStatesInput>;
45
+ export type GetDeliveryOptionsInput = z.infer<typeof getDeliveryOptionsInput>;
46
+ export type Address = z.infer<typeof addressSchema>;
@@ -0,0 +1,92 @@
1
+ import z from "zod";
2
+ import {
3
+ cartLineDeliveryPreferenceSchema,
4
+ cartLineSchema,
5
+ cartSchema,
6
+ retrievePaymentResultSettingsSchema,
7
+ simpleProductSchema,
8
+ tokenizedPaymentCardSchema,
9
+ } from "./d365.schema";
10
+
11
+ const extendedCartLineSchema = cartLineSchema.extend({
12
+ Product: simpleProductSchema.optional(),
13
+ });
14
+
15
+ export const extendedCartSchema = cartSchema
16
+ .omit({ CartLines: true })
17
+ .extend({ CartLines: extendedCartLineSchema.array() });
18
+
19
+ // input
20
+ export const modifyOrAddCartLineInput = z.object({
21
+ cartLine: z.custom<CartLine>().array(),
22
+ cartId: z.string().optional(),
23
+ version: z.number().optional(),
24
+ });
25
+
26
+ export const updateCartInput = z.object({
27
+ cart: extendedCartSchema.partial(),
28
+ });
29
+
30
+ export const getCartInput = z.object({
31
+ cartId: z.string().optional(),
32
+ });
33
+
34
+ export const manageDiscountCodeInput = z.object({
35
+ cartId: z.string().optional(),
36
+ discountCode: z.string(),
37
+ });
38
+
39
+ export const retrieveCardPaymentAcceptResultInput = z.object({
40
+ cartId: z.string(),
41
+ resultAccessCode: z.string(),
42
+ settings: retrievePaymentResultSettingsSchema,
43
+ });
44
+
45
+ export const getCardAcceptPointInput = z.object({
46
+ cartId: z.string(),
47
+ hideBillingAddress: z.boolean().optional(),
48
+ totalAmount: z.number(),
49
+ origin: z.string().optional(),
50
+ isClient: z.boolean(),
51
+ });
52
+
53
+ export const checkoutInput = z.object({
54
+ id: z.string(),
55
+ receiptEmail: z.string(),
56
+ tokenizedPaymentCard: tokenizedPaymentCardSchema,
57
+ currency: z.string(),
58
+ amount: z.number(),
59
+ });
60
+
61
+ export const updateCartLineDeliveryModeInput = z.object({
62
+ cartId: z.string(),
63
+ cartLineDeliverySpecification: cartLineDeliveryPreferenceSchema.array(),
64
+ });
65
+
66
+ export const removeCartLineDeliveryModeInput = z.object({
67
+ cart: extendedCartSchema.partial(),
68
+ });
69
+
70
+ // Typescript Types
71
+ // export type Cart = z.infer<typeof cartSchema>;
72
+ // export type CartLine = z.infer<typeof cartLineSchema>;
73
+ export type AddToCartInput = z.infer<typeof modifyOrAddCartLineInput>;
74
+ export type UpdateCartLineInput = z.infer<typeof modifyOrAddCartLineInput>;
75
+ export type UpdateCartInput = z.infer<typeof updateCartInput>;
76
+ export type DeleteCartLineInput = z.infer<typeof modifyOrAddCartLineInput>;
77
+ export type ManageDiscountCodeInput = z.infer<typeof manageDiscountCodeInput>;
78
+ export type Cart = z.infer<typeof extendedCartSchema>;
79
+ export type CartLine = z.infer<typeof extendedCartLineSchema>;
80
+ export type RetrieveCardPaymentAcceptResultInput = z.infer<
81
+ typeof retrieveCardPaymentAcceptResultInput
82
+ >;
83
+ export type GetCardPaymentAcceptPointInput = z.infer<
84
+ typeof getCardAcceptPointInput
85
+ >;
86
+ export type UpdateCartLineDeliveryModeInput = z.infer<
87
+ typeof updateCartLineDeliveryModeInput
88
+ >;
89
+ export type RemoveCartLineDeliveryModeInput = z.infer<
90
+ typeof removeCartLineDeliveryModeInput
91
+ >;
92
+ export type CheckoutInput = z.infer<typeof checkoutInput>;