@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,21 @@
1
+ import { useQueryClient } from "@tanstack/react-query";
2
+ import { createApiPath } from "../../create-query";
3
+ import { useCreateMutation } from "../../create-mutation";
4
+ import {
5
+ CreateWishListInput,
6
+ WishList,
7
+ } from "../../../datasources/e4/graphqlRequestSdk";
8
+
9
+ const apiPath = createApiPath("user", "createWishlist");
10
+
11
+ const useCreateWishlist = () => {
12
+ const queryClient = useQueryClient();
13
+
14
+ return useCreateMutation<CreateWishListInput, WishList>(apiPath, {
15
+ onSuccess: () => {
16
+ queryClient.invalidateQueries({ queryKey: ["wishlists"] });
17
+ },
18
+ });
19
+ };
20
+
21
+ export default useCreateWishlist;
@@ -0,0 +1,17 @@
1
+ import { useQueryClient } from "@tanstack/react-query";
2
+ import { createApiPath } from "../../create-query";
3
+ import { useCreateMutation } from "../../create-mutation";
4
+
5
+ const apiPath = createApiPath("user", "deleteWishlist");
6
+
7
+ const useDeleteWishlist = () => {
8
+ const queryClient = useQueryClient();
9
+
10
+ return useCreateMutation<string, string>(apiPath, {
11
+ onSuccess: () => {
12
+ queryClient.invalidateQueries({ queryKey: ["wishlists"] });
13
+ },
14
+ });
15
+ };
16
+
17
+ export default useDeleteWishlist;
@@ -0,0 +1,18 @@
1
+ import { useQueryClient } from "@tanstack/react-query";
2
+ import { User } from "@/api-manager/schemas/user.schema";
3
+ import { useCreateMutation } from "../../create-mutation";
4
+ import { createApiPath } from "../../create-query";
5
+
6
+ const apiPath = createApiPath("user", "updateUser");
7
+
8
+ const useUpdateUser = () => {
9
+ const queryClient = useQueryClient();
10
+
11
+ return useCreateMutation<User, User>(apiPath, {
12
+ onSuccess: () => {
13
+ queryClient.invalidateQueries({ queryKey: ["me"] });
14
+ },
15
+ });
16
+ };
17
+
18
+ export default useUpdateUser;
@@ -0,0 +1,10 @@
1
+ import { UserCounts } from "@/api-manager/schemas/user.schema";
2
+ import { createApiPath, createQuery } from "../../create-query";
3
+
4
+ const apiPath = createApiPath("user", "getUserCounts");
5
+
6
+ const getUserCounts = createQuery<string, UserCounts>(apiPath, {
7
+ queryKey: "user-counts",
8
+ });
9
+
10
+ export default getUserCounts;
@@ -0,0 +1,10 @@
1
+ import { createApiPath, createQuery } from "../../create-query";
2
+ import { User } from "@/api-manager/schemas/user.schema";
3
+
4
+ const apiPath = createApiPath("user", "getUser");
5
+
6
+ const getUser = createQuery<null, User | null>(apiPath, {
7
+ queryKey: "me",
8
+ });
9
+
10
+ export default getUser;
@@ -0,0 +1,10 @@
1
+ import { createApiPath, createQuery } from "../../create-query";
2
+ import { WishList } from "../../../datasources/e4/graphqlRequestSdk";
3
+
4
+ const apiPath = createApiPath("user", "getWishlistDetails");
5
+
6
+ const getWishListDetails = createQuery<string, WishList>(apiPath, {
7
+ queryKey: "wish-list-details",
8
+ });
9
+
10
+ export default getWishListDetails;
@@ -0,0 +1,10 @@
1
+ import { WishList } from "../../../datasources/e4/graphqlRequestSdk";
2
+ import { createApiPath, createQuery } from "../../create-query";
3
+
4
+ const apiPath = createApiPath("user", "getWishlists");
5
+
6
+ const getWishlists = createQuery<null, WishList[]>(apiPath, {
7
+ queryKey: "wish-lists",
8
+ });
9
+
10
+ export default getWishlists;
@@ -0,0 +1,197 @@
1
+ import * as cartSchemas from "@/api-manager/schemas/cart.schema";
2
+ import * as productSchemas from "@/api-manager/schemas/product.schema";
3
+ import { User, UserCounts } from "@/api-manager/schemas/user.schema";
4
+ import {
5
+ Session,
6
+ SessionInitInput,
7
+ } from "@/api-manager/schemas/session.schema";
8
+ import {
9
+ Address,
10
+ GetCountriesInput,
11
+ GetDeliveryOptionsInput,
12
+ GetStatesInput,
13
+ } from "@/api-manager/schemas/address.schema";
14
+ import {
15
+ ChannelConfiguration,
16
+ GetOrgUnitLocationsByAreaInput,
17
+ OrgUnitLocationReturnType,
18
+ } from "@/api-manager/schemas/organization.schema";
19
+ import {
20
+ GetSalesOrderDetailsInput,
21
+ SalesOrderInput,
22
+ SalesOrder,
23
+ } from "@/api-manager/schemas/order.schema";
24
+ import { CategoryHierarchy } from "../lib/category-helpers";
25
+ import {
26
+ CardPaymentAcceptPoint,
27
+ CardPaymentAcceptResult,
28
+ CountryRegionInfo,
29
+ DeliveryOption,
30
+ ProductSearchResult,
31
+ SimpleProduct,
32
+ StateProvinceInfo,
33
+ ProductWarehouseInventoryAvailability,
34
+ } from "@msdyn365-commerce/retail-proxy";
35
+ import {
36
+ CategoriesQuery,
37
+ CreateWishListInput,
38
+ WishList,
39
+ } from "../datasources/e4/graphqlRequestSdk";
40
+
41
+ /**
42
+ * Datasource Interface, defines the methods and I/O types that a datasource must implement.
43
+ */
44
+ export interface DatasourceApis {
45
+ user: UserApi;
46
+ session: SessionApi;
47
+ cart: CartApi;
48
+ product: ProductApi;
49
+ categories: CategoryApi;
50
+ order: OrderApi;
51
+ address: AddressApi;
52
+ organization: OrganizationApi;
53
+ }
54
+
55
+ export abstract class Datasource implements DatasourceApis {
56
+ public name: string;
57
+ abstract user: UserApi;
58
+ abstract cart: CartApi;
59
+ abstract product: ProductApi;
60
+ abstract categories: CategoryApi;
61
+ abstract order: OrderApi;
62
+ abstract address: AddressApi;
63
+ abstract organization: OrganizationApi;
64
+ abstract session: SessionApi;
65
+
66
+ constructor(name: string) {
67
+ this.name = name;
68
+ }
69
+ }
70
+
71
+ /**
72
+ * PrimaryDatasource Interface, all methods are required.
73
+ */
74
+ export type PrimaryDatasource = Datasource;
75
+
76
+ /**
77
+ * SecondaryDatasource Interface, all methods are optional.
78
+ */
79
+ export type SecondaryDatasource = Partial<Datasource>;
80
+
81
+ export interface OrganizationApi {
82
+ getChannelConfiguration(): Promise<ChannelConfiguration>;
83
+ getStoresList(
84
+ input: GetOrgUnitLocationsByAreaInput,
85
+ ): Promise<OrgUnitLocationReturnType[]>;
86
+ }
87
+
88
+ /**
89
+ * User Data Actions
90
+ */
91
+ export interface UserApi {
92
+ updateUser(user: User): Promise<User>;
93
+ getUser(): Promise<User | null>;
94
+ getUserCounts(userId: string): Promise<UserCounts>;
95
+ // wishlists
96
+ getWishlists(): Promise<WishList[]>;
97
+ getWishlistDetails(id: string): Promise<WishList>;
98
+ createWishlist(wishlist: CreateWishListInput): Promise<WishList>;
99
+ deleteWishlist(id: string): Promise<string>;
100
+ }
101
+
102
+ /**
103
+ * Session Data Actions
104
+ */
105
+ export interface SessionApi {
106
+ sessionInit(input: SessionInitInput): Promise<Session>;
107
+ sessionLogout(): Promise<boolean>;
108
+ getSession(): Promise<Session>;
109
+ }
110
+
111
+ // export interface Datasource extends Datasource {};
112
+ /**
113
+ * Cart Data Actions
114
+ */
115
+ export interface CartApi {
116
+ initCart(): Promise<cartSchemas.Cart>;
117
+ addToCart(input: cartSchemas.AddToCartInput): Promise<cartSchemas.Cart>;
118
+ updateCart(input: cartSchemas.UpdateCartInput): Promise<cartSchemas.Cart>;
119
+ deleteCartLine(
120
+ input: cartSchemas.DeleteCartLineInput,
121
+ ): Promise<cartSchemas.Cart>;
122
+ getCart(input?: { cartId: string }): Promise<cartSchemas.Cart>;
123
+ updateCartLines(
124
+ input: cartSchemas.UpdateCartLineInput,
125
+ ): Promise<cartSchemas.Cart>;
126
+ addDiscountCode(
127
+ input: cartSchemas.ManageDiscountCodeInput,
128
+ ): Promise<cartSchemas.Cart>;
129
+ removeDiscountcode(
130
+ input: cartSchemas.ManageDiscountCodeInput,
131
+ ): Promise<cartSchemas.Cart>;
132
+ updateLineDeliveryMode(
133
+ input: cartSchemas.UpdateCartLineDeliveryModeInput,
134
+ ): Promise<cartSchemas.Cart>;
135
+ removeLineDeliveryMode(
136
+ input: cartSchemas.RemoveCartLineDeliveryModeInput,
137
+ ): Promise<cartSchemas.Cart>;
138
+ getCardAcceptPoint(
139
+ input: cartSchemas.GetCardPaymentAcceptPointInput,
140
+ ): Promise<CardPaymentAcceptPoint>;
141
+ retrieveCardPaymentAcceptResult(
142
+ input: cartSchemas.RetrieveCardPaymentAcceptResultInput,
143
+ ): Promise<CardPaymentAcceptResult>;
144
+ checkout(input: cartSchemas.CheckoutInput): Promise<SalesOrder>;
145
+ }
146
+
147
+ /**
148
+ * Product Data Actions
149
+ */
150
+ export interface ProductApi {
151
+ getProductById(
152
+ input: productSchemas.GetProductByIdInput,
153
+ ): Promise<productSchemas.ProductDetails>;
154
+ getProductByIds(
155
+ input: productSchemas.GetProductByIdsInput,
156
+ ): Promise<SimpleProduct[]>;
157
+ getProductsList(
158
+ input: productSchemas.SearchByCriteriaInput,
159
+ ): Promise<productSchemas.SearchByCriteriaResponse>;
160
+ searchProducts(
161
+ input: productSchemas.searchProductsInput,
162
+ ): Promise<ProductSearchResult[]>;
163
+ getCategoryList(): Promise<CategoriesQuery>;
164
+ getRelatedProducts(
165
+ input: productSchemas.GetRelatedProductsInput,
166
+ ): Promise<ProductSearchResult[]>;
167
+ getInventory(
168
+ input: productSchemas.InventorySearchCriteriaInput,
169
+ ): Promise<ProductWarehouseInventoryAvailability>;
170
+ }
171
+
172
+ /**
173
+ * CategoriesDataActions
174
+ */
175
+ export interface CategoryApi {
176
+ getCategories(): Promise<CategoryHierarchy[]>;
177
+ }
178
+
179
+ /**
180
+ * Order Data Actions
181
+ */
182
+ export interface OrderApi {
183
+ getSalesOrders(input: SalesOrderInput): Promise<SalesOrder[]>;
184
+ getSalesOrderDetails(input: GetSalesOrderDetailsInput): Promise<SalesOrder>;
185
+ }
186
+
187
+ /**
188
+ * Address Data Actions
189
+ */
190
+ export interface AddressApi {
191
+ getCountries(input: GetCountriesInput): Promise<CountryRegionInfo[]>;
192
+ getStates(input: GetStatesInput): Promise<StateProvinceInfo[]>;
193
+ getDeliveryOptions(input: GetDeliveryOptionsInput): Promise<DeliveryOption[]>;
194
+ createAddress(address: Address): Promise<Address>;
195
+ updateAddress(address: Address): Promise<Address>;
196
+ deleteAddress(addressId: string): Promise<string>;
197
+ }
@@ -0,0 +1,127 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import authOptions, { ExtendedJwtToken } from "./auth-options";
3
+ import { JWT } from "next-auth/jwt";
4
+ import { Account } from "next-auth";
5
+ import { Session } from "next-auth";
6
+
7
+ // vi.mock("./aadb2c-provider", () => ({
8
+ // azureADB2CProvider: {},
9
+ // refreshAccessToken: vi.fn(async (token) => ({
10
+ // ...token,
11
+ // accessToken: "newAccessToken",
12
+ // accessTokenExpiresAt: Date.now() + 3600 * 1000,
13
+ // })),
14
+ // }));
15
+
16
+ describe("next-auth option callbacks", () => {
17
+ describe("jwt callback", () => {
18
+ it("should store accessToken and refreshToken when account and profile are available", async () => {
19
+ const token: ExtendedJwtToken = {
20
+ accessToken: "",
21
+ accessTokenExpiresAt: 0,
22
+ provider: "azure-ad-b2c",
23
+ refreshTokenExpiresAt: 0,
24
+ exp: 0,
25
+ };
26
+ const account: Account = {
27
+ access_token: "testAccessToken",
28
+ refresh_token: "testRefreshToken",
29
+ expires_on: Math.floor(Date.now() / 1000) + 3600,
30
+ refresh_token_expires_in: 86400,
31
+ providerAccountId: "test-provider-account-id",
32
+ provider: "azure-ad-b2c",
33
+ type: "oauth",
34
+ };
35
+
36
+ let newToken;
37
+ if (
38
+ authOptions &&
39
+ authOptions().callbacks &&
40
+ authOptions().callbacks.jwt
41
+ ) {
42
+ newToken = await authOptions().callbacks.jwt({
43
+ token,
44
+ user: { id: "123" },
45
+ account,
46
+ profile: {},
47
+ });
48
+ }
49
+
50
+ expect(newToken?.accessToken).toBe("testAccessToken");
51
+ expect(newToken?.refreshToken).toBe("testRefreshToken");
52
+ expect(newToken?.accessTokenExpiresAt).toBe(token.accessTokenExpiresAt); // We're not setting this or using it anymore
53
+ expect(newToken?.refreshTokenExpiresAt).toBe(token.refreshTokenExpiresAt); // We're not setting this or using it anymore);
54
+ });
55
+
56
+ // it("should return token if access token is not expired", async () => {
57
+ // const token: JWT = {
58
+ // accessToken: "validToken",
59
+ // accessTokenExpiresAt: Date.now() + 3600 * 1000,
60
+ // refreshToken: "",
61
+ // refreshTokenExpiresAt: 0
62
+ // };
63
+
64
+ // let newToken;
65
+ // if (authOptions && authOptions.callbacks && authOptions.callbacks.jwt) {
66
+ // newToken = await authOptions.callbacks.jwt({ token, user: { id: '123' }, account: null });
67
+ // }
68
+
69
+ // expect(newToken).toEqual(token);
70
+ // });
71
+
72
+ // it("should return error if refresh token is expired", async () => {
73
+ // const token = { accessTokenExpiresAt: Date.now() - 1000, refreshTokenExpiresAt: Date.now() - 1000 };
74
+
75
+ // let newToken;
76
+ // if (authOptions && authOptions.callbacks && authOptions.callbacks.jwt) {
77
+ // newToken = await authOptions.callbacks.jwt({ token, user: { id: '123' }, account: null });
78
+ // }
79
+
80
+ // expect(newToken?.error).toBe("RefreshTokenExpired");
81
+ // });
82
+
83
+ // it("should refresh access token if access token is expired but refresh token is valid", async () => {
84
+ // const token = { accessToken: "oldToken", accessTokenExpiresAt: Date.now() - 1000, refreshToken: "validRefreshToken", refreshTokenExpiresAt: Date.now() + 3600 * 1000 };
85
+
86
+ // let newToken;
87
+ // if (authOptions && authOptions.callbacks && authOptions.callbacks.jwt) {
88
+ // newToken = await authOptions.callbacks.jwt({ token, user: { id: '123' }, account: null });
89
+ // }
90
+
91
+ // // expect(refreshAccessToken).toHaveBeenCalledWith(token);
92
+ // expect(newToken?.accessToken).toBe("newAccessToken");
93
+ // });
94
+ });
95
+
96
+ describe("session callback", () => {
97
+ it("should pass accessToken and error to session", async () => {
98
+ const session = { expires: "", user: { name: "123" } };
99
+ const token: JWT = {
100
+ accessToken: "sessionToken",
101
+ accessTokenExpiresAt: 0,
102
+ refreshToken: "",
103
+ refreshTokenExpiresAt: 0,
104
+ error: "SomeError",
105
+ };
106
+ let newSession: Session | null;
107
+ if (
108
+ authOptions &&
109
+ authOptions().callbacks &&
110
+ authOptions().callbacks.session
111
+ ) {
112
+ newSession = await authOptions().callbacks.session({
113
+ session,
114
+ token,
115
+ user: { id: "123", email: "", emailVerified: new Date(Date.now()) },
116
+ newSession: {},
117
+ trigger: "update",
118
+ });
119
+ } else {
120
+ newSession = null;
121
+ }
122
+
123
+ expect(newSession?.accessToken).toBe("sessionToken");
124
+ expect(newSession?.error).toBe("SomeError");
125
+ });
126
+ });
127
+ });
@@ -0,0 +1,68 @@
1
+ import { Session, type NextAuthOptions } from "next-auth";
2
+ import { getServerSession } from "next-auth/next";
3
+ import { JWT } from "next-auth/jwt";
4
+ import {
5
+ GetServerSidePropsContext,
6
+ NextApiRequest,
7
+ NextApiResponse,
8
+ } from "next";
9
+ import { getProviders } from "./providers";
10
+ import { deleteCartCookie } from "@/lib/cart-cookie-handler";
11
+ import { getConfig } from "@config";
12
+
13
+ // Split providers into separate array so we can iterate them and match the provider ID
14
+ export type ExtendedJwtToken = JWT & {
15
+ provider: string;
16
+ exp: number;
17
+ };
18
+
19
+ export type ExtendedSession = Session & { token?: JWT };
20
+
21
+ const createAuthOptions = (): NextAuthOptions => {
22
+ const providers = getProviders();
23
+ const secret = getConfig().NEXTAUTH_SECRET;
24
+ return {
25
+ providers,
26
+ secret,
27
+ // Order in which callbacks are called = signin > redirect > jwt > session. Thats why session callback has token info.
28
+ callbacks: {
29
+ // By default, NextAuth uses "session" with strategy: "jwt"
30
+ async jwt({ token, account, profile }) {
31
+ const _token = token as ExtendedJwtToken;
32
+ // account and profile is available only in first callback after signin
33
+ if (account && profile) {
34
+ _token.provider = account.provider;
35
+ _token.accessToken = account.access_token;
36
+ _token.refreshToken = account.refresh_token;
37
+ }
38
+ return _token;
39
+ // return await checkAccessTokenExpiry(_token)
40
+ },
41
+ async session({ session, token }) {
42
+ const _session = { ...session } as ExtendedSession;
43
+ // Way to pass data to the browser
44
+ // Use this error to force logout in UI. No proper way to signout user from server.
45
+ _session.error = token?.error;
46
+ _session.accessToken = token.accessToken;
47
+
48
+ return _session;
49
+ },
50
+ },
51
+ events: {
52
+ signOut: async () => {
53
+ await deleteCartCookie();
54
+ },
55
+ },
56
+ };
57
+ };
58
+
59
+ export function auth( // <-- use this function to access the jwt from React components
60
+ ...args:
61
+ | [GetServerSidePropsContext["req"], GetServerSidePropsContext["res"]]
62
+ | [NextApiRequest, NextApiResponse]
63
+ | []
64
+ ) {
65
+ return getServerSession(...args, createAuthOptions());
66
+ }
67
+
68
+ export default createAuthOptions;
@@ -0,0 +1,65 @@
1
+ import { PublicClientApplication, Configuration } from "@azure/msal-browser";
2
+ import { getConfig } from "@config";
3
+
4
+ const createMsalConfig = (): Configuration => {
5
+ return {
6
+ auth: {
7
+ clientId: getConfig().AZURE_AD_B2C_CLIENTID, //process.env.NEXT_PUBLIC_AZURE_AD_B2C_CLIENTID || "",
8
+ authority: getConfig().AZURE_AD_B2C_LOGIN_AUTHORITY, //process.env.NEXT_PUBLIC_AZURE_AD_B2C_LOGIN_AUTHORITY || "",
9
+ redirectUri: "/", //process.env.NEXT_PUBLIC_AZURE_AD_B2C_REDIRECT || "/",
10
+ postLogoutRedirectUri: getConfig().AZURE_AD_B2C_POST_LOGOUT_REDIRECT, //process.env.NEXT_PUBLIC_AZURE_AD_B2C_POST_LOGOUT_REDIRECT || "/",
11
+ knownAuthorities: [
12
+ getConfig().AZURE_AD_B2C_KNOWN_AUTHORITY, //process.env.NEXT_PUBLIC_AZURE_AD_B2C_KNOWN_AUTHORITY || "",
13
+ ],
14
+ navigateToLoginRequestUrl: true,
15
+ },
16
+ system: {
17
+ allowNativeBroker: false, // Disables WAM Broker
18
+ },
19
+ };
20
+ };
21
+
22
+ // create module singleton (to pass the env variables)
23
+ // const msalInstance = new PublicClientApplication(createMsalConfig());
24
+ let msalInstance: PublicClientApplication | null = null;
25
+
26
+ const initializeMsal = async () => {
27
+ try {
28
+ const config = createMsalConfig();
29
+ msalInstance = new PublicClientApplication(config);
30
+ await msalInstance.initialize();
31
+
32
+ const accounts = msalInstance.getAllAccounts();
33
+ if (accounts.length > 0) {
34
+ msalInstance.setActiveAccount(accounts[0]);
35
+ }
36
+ } catch (error) {
37
+ console.error("MSAL Initialization Error:", error);
38
+ }
39
+ };
40
+
41
+ const getMsalInstance = () => {
42
+ if (!msalInstance) throw new Error("msalInstance not initialized");
43
+ return msalInstance;
44
+ };
45
+
46
+ const getRequestConfig = (requestType?: string) => {
47
+ const editAuthority = getConfig().AZURE_AD_B2C_EDIT_AUTHORITY;
48
+ const resetAuthority = getConfig().AZURE_AD_B2C_RESET_AUTHORITY;
49
+
50
+ const baseRequest = {
51
+ scopes: [getConfig().AZURE_AD_B2C_API_PERMISSION],
52
+ authority: createMsalConfig().auth.authority,
53
+ };
54
+
55
+ switch (requestType) {
56
+ case "edit":
57
+ return { ...baseRequest, authority: editAuthority };
58
+ case "reset":
59
+ return { ...baseRequest, authority: resetAuthority };
60
+ default:
61
+ return baseRequest;
62
+ }
63
+ };
64
+
65
+ export { getMsalInstance, initializeMsal, getRequestConfig };
@@ -0,0 +1,86 @@
1
+ "use server";
2
+ import { RequestCookie } from "next/dist/compiled/@edge-runtime/cookies";
3
+ import { cookies } from "next/headers";
4
+ import { encode, decode, JWT } from "next-auth/jwt";
5
+ import { ExtendedJwtToken } from "@/auth/auth-options";
6
+ const NEXT_AUTH_COOKIE_NAME = "next-auth.session-token";
7
+ const SECURE_COOKIE_PREFIX = "__Secure-";
8
+
9
+ /**
10
+ * Retrieves and decodes the NextAuth session cookie from the request.
11
+ *
12
+ * This function handles both single and chunked session cookies:
13
+ * - If the session cookie is under 4KB, it is stored as a single cookie.
14
+ * - If the session cookie exceeds 4KB, it is split into multiple chunked cookies with indexed names.
15
+ *
16
+ * The function attempts to retrieve the single cookie first. If not found,
17
+ * it iteratively collects all chunked cookies, concatenates their values,
18
+ * and decodes the resulting token.
19
+ *
20
+ * @returns A Promise resolving to the decoded session object, or `undefined` if no session cookie is found.
21
+ */
22
+ const manuallyRetrieveSessionCookie = async () => {
23
+ const cookieStore = await cookies();
24
+ let cookie: RequestCookie | undefined;
25
+ // Single token when the cookie size is < 4k
26
+ cookie = cookieStore.get(`${SECURE_COOKIE_PREFIX}${NEXT_AUTH_COOKIE_NAME}`);
27
+ //If the cookie is found, return it. the cookie is under 4kb
28
+ if (cookie) {
29
+ return decode({
30
+ token: cookie.value,
31
+ secret: process.env.NEXTAUTH_SECRET || "",
32
+ });
33
+ }
34
+ //If the cookie is not found, we need to see if there is a chunked cookie
35
+ //The chunked cookie is stored in multiple cookies with the same name and an index
36
+ //The cookie is chunked when the cookie size is > 4k
37
+ //The value is just split between the cookies, so we can just concat them.
38
+ let i = 0;
39
+ const cookieValues: string[] = [];
40
+ do {
41
+ cookie = cookieStore.get(
42
+ `${SECURE_COOKIE_PREFIX}${NEXT_AUTH_COOKIE_NAME}.${i}`,
43
+ );
44
+ if (cookie) {
45
+ cookieValues.push(cookie.value);
46
+ }
47
+ i++;
48
+ } while (cookie !== undefined);
49
+ if (cookieValues.length) {
50
+ return decode({
51
+ token: cookieValues.join(""),
52
+ secret: process.env.NEXTAUTH_SECRET || "",
53
+ });
54
+ }
55
+
56
+ //If no cookie is found, return undefined
57
+ return undefined;
58
+ };
59
+
60
+ /**
61
+ * Manually sets the NextAuth session cookie with the provided JWT token.
62
+ *
63
+ * This function encodes the given JWT or ExtendedJwtToken and sets it as a secure,
64
+ * HTTP-only cookie named `__Secure-next-auth.session-token`. The cookie is set using
65
+ * the current cookie store, and the encoding uses the secret from the `NEXTAUTH_SECRET`
66
+ * environment variable.
67
+ *
68
+ * @param token - The JWT or ExtendedJwtToken to be encoded and stored in the session cookie.
69
+ * @returns A promise that resolves when the cookie has been set.
70
+ */
71
+ const manuallySetSessionCookie = async (token: JWT | ExtendedJwtToken) => {
72
+ const cookieStore = await cookies();
73
+ // Set the cookie with the name __Secure-next-auth.session-token
74
+ const value = await encode({
75
+ token,
76
+ secret: process.env.NEXTAUTH_SECRET || "",
77
+ });
78
+ cookieStore.set({
79
+ name: `${SECURE_COOKIE_PREFIX}${NEXT_AUTH_COOKIE_NAME}`,
80
+ value,
81
+ httpOnly: true,
82
+ secure: true,
83
+ });
84
+ };
85
+
86
+ export { manuallyRetrieveSessionCookie, manuallySetSessionCookie };
@@ -0,0 +1,33 @@
1
+ import { getConfig } from "@config";
2
+ import AzureADB2CProvider from "next-auth/providers/azure-ad-b2c";
3
+
4
+ // By default, NextAuth tries to use either PKCE or Client Secret-based authentication, depending on how the provider is configured.
5
+ // If clientSecret is provided, it assumes client secret authentication (which doesn't use code_challenge).
6
+ // If clientSecret is missing, it assumes PKCE.
7
+ // But Azure AD B2C sometimes requires PKCE explicitly, so NextAuth needs to be told to always use PKCE.
8
+ const azureADB2CProvider = () => {
9
+ const CLIENT_ID = getConfig().AZURE_AD_B2C_CLIENTID;
10
+ const SCOPE = `${getConfig().AZURE_AD_B2C_API_PERMISSION} offline_access openid`;
11
+ const LOGIN_AUTHORITY = getConfig().AZURE_AD_B2C_LOGIN_AUTHORITY;
12
+
13
+ return AzureADB2CProvider({
14
+ clientId: CLIENT_ID,
15
+ clientSecret: "",
16
+ issuer: `${LOGIN_AUTHORITY}/v2.0`, // either (tenantId and primaryUserFlow) or issuer must be provided
17
+ authorization: {
18
+ // We can also send params from UI - signIn("azure-ad-b2c", {}, { prompt: "login" })
19
+ params: {
20
+ scope: SCOPE,
21
+ // When a user logs in once, the session remains active, and next time Azure AD B2C automatically logs the user in without showing the sign-in page again
22
+ // This option forces login screen every time.
23
+ prompt: "login",
24
+ },
25
+ },
26
+ checks: ["pkce"],
27
+ client: {
28
+ token_endpoint_auth_method: "none", // Disables Client Secret, ensuring that only PKCE is used
29
+ },
30
+ });
31
+ };
32
+
33
+ export default azureADB2CProvider;