@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.
- package/README.md +40 -0
- package/package.json +36 -0
- package/src/api-manager/README.md +38 -0
- package/src/api-manager/api-manager.config.json +12 -0
- package/src/api-manager/datasources/README.md +17 -0
- package/src/api-manager/datasources/d365/d365-address.datasource.ts +141 -0
- package/src/api-manager/datasources/d365/d365-base.datasource.ts +8 -0
- package/src/api-manager/datasources/d365/d365-cart.datasource.ts +374 -0
- package/src/api-manager/datasources/d365/d365-categories.datasource.ts +40 -0
- package/src/api-manager/datasources/d365/d365-order.datasource.ts +69 -0
- package/src/api-manager/datasources/d365/d365-organization.datasource.ts +92 -0
- package/src/api-manager/datasources/d365/d365-product.datasource.ts +272 -0
- package/src/api-manager/datasources/d365/d365-session.datasource.ts +25 -0
- package/src/api-manager/datasources/d365/d365-user.datasource.ts +132 -0
- package/src/api-manager/datasources/d365/d365.datasource.ts +45 -0
- package/src/api-manager/datasources/d365/index.ts +4 -0
- package/src/api-manager/datasources/d365/test-context.ts +30 -0
- package/src/api-manager/datasources/d365/utils/create-search-criteria.ts +17 -0
- package/src/api-manager/datasources/d365/utils/decode-jwt.ts +11 -0
- package/src/api-manager/datasources/d365/utils/get-context-cookie.ts +37 -0
- package/src/api-manager/datasources/d365/utils/parse-object.ts +9 -0
- package/src/api-manager/datasources/d365/utils/product-images-utils.ts +43 -0
- package/src/api-manager/datasources/d365/utils/product-inventory-utils.ts +37 -0
- package/src/api-manager/datasources/e4/e4-address.datasource.ts +107 -0
- package/src/api-manager/datasources/e4/e4-cart.datasource.ts +248 -0
- package/src/api-manager/datasources/e4/e4-order.datasource.ts +43 -0
- package/src/api-manager/datasources/e4/e4-organization.datasource.ts +19 -0
- package/src/api-manager/datasources/e4/e4-product.datasource.ts +157 -0
- package/src/api-manager/datasources/e4/e4-session.datasource.ts +43 -0
- package/src/api-manager/datasources/e4/e4-user.datasource.ts +118 -0
- package/src/api-manager/datasources/e4/e4.datasource.ts +55 -0
- package/src/api-manager/datasources/e4/e4.remaps.ts +331 -0
- package/src/api-manager/datasources/e4/e4.translator.test.ts +202 -0
- package/src/api-manager/datasources/e4/e4.translator.ts +648 -0
- package/src/api-manager/datasources/e4/graphqlRequestSdk.ts +43515 -0
- package/src/api-manager/datasources/e4/utils/unwrap-e4-variants.ts +65 -0
- package/src/api-manager/index.ts +71 -0
- package/src/api-manager/lib/cart-cookie-handler.ts +14 -0
- package/src/api-manager/lib/category-helpers.ts +113 -0
- package/src/api-manager/lib/get-dynamics-context.ts +34 -0
- package/src/api-manager/lib/get-graphql-client.test.ts +106 -0
- package/src/api-manager/lib/get-graphql-client.ts +53 -0
- package/src/api-manager/schemas/README.md +12 -0
- package/src/api-manager/schemas/address.schema.ts +46 -0
- package/src/api-manager/schemas/cart.schema.ts +92 -0
- package/src/api-manager/schemas/d365.schema.ts +7727 -0
- package/src/api-manager/schemas/order.schema.ts +30 -0
- package/src/api-manager/schemas/organization.schema.ts +32 -0
- package/src/api-manager/schemas/product.schema.ts +140 -0
- package/src/api-manager/schemas/session.schema.ts +17 -0
- package/src/api-manager/schemas/user.schema.ts +14 -0
- package/src/api-manager/services/address/mutations/create-address.ts +22 -0
- package/src/api-manager/services/address/mutations/delete-address.ts +21 -0
- package/src/api-manager/services/address/mutations/get-delivery-options.ts +22 -0
- package/src/api-manager/services/address/mutations/update-address.ts +21 -0
- package/src/api-manager/services/address/queries/get-countries.ts +16 -0
- package/src/api-manager/services/address/queries/get-states.ts +16 -0
- package/src/api-manager/services/cart/mutations/add-discount-code.ts +21 -0
- package/src/api-manager/services/cart/mutations/add-to-cart.ts +53 -0
- package/src/api-manager/services/cart/mutations/checkout.ts +11 -0
- package/src/api-manager/services/cart/mutations/delete-cart-line.ts +18 -0
- package/src/api-manager/services/cart/mutations/get-payment-accept-result.ts +20 -0
- package/src/api-manager/services/cart/mutations/remove-cart-line-delivery-mode.ts +24 -0
- package/src/api-manager/services/cart/mutations/remove-discount-code.ts +21 -0
- package/src/api-manager/services/cart/mutations/update-cart-line-delivery-mode.ts +24 -0
- package/src/api-manager/services/cart/mutations/update-cart-lines.ts +21 -0
- package/src/api-manager/services/cart/mutations/update-cart.ts +21 -0
- package/src/api-manager/services/cart/queries/get-cart.ts +12 -0
- package/src/api-manager/services/cart/queries/get-payment-accept-point.ts +18 -0
- package/src/api-manager/services/categories/queries/get-categories.ts +8 -0
- package/src/api-manager/services/create-mutation.ts +65 -0
- package/src/api-manager/services/create-query.ts +305 -0
- package/src/api-manager/services/get-query-client.ts +40 -0
- package/src/api-manager/services/order/queries/get-order-details.ts +17 -0
- package/src/api-manager/services/order/queries/get-orders.ts +14 -0
- package/src/api-manager/services/organization/queries/get-channel-configuration.ts +14 -0
- package/src/api-manager/services/organization/queries/get-stores.ts +17 -0
- package/src/api-manager/services/product/mutations/search-products.ts +23 -0
- package/src/api-manager/services/product/queries/get-product-availability.ts +15 -0
- package/src/api-manager/services/product/queries/get-product-by-id.ts +17 -0
- package/src/api-manager/services/product/queries/get-product-by-ids.ts +14 -0
- package/src/api-manager/services/product/queries/get-product-list.ts +16 -0
- package/src/api-manager/services/product/queries/get-related-products.ts +14 -0
- package/src/api-manager/services/product/queries/search-products.ts +10 -0
- package/src/api-manager/services/product/server/product.server.ts +13 -0
- package/src/api-manager/services/session/mutations/session-init.ts +22 -0
- package/src/api-manager/services/session/mutations/session-logout.ts +18 -0
- package/src/api-manager/services/session/queries/get-session.ts +10 -0
- package/src/api-manager/services/user/mutations/create-wishlist.ts +21 -0
- package/src/api-manager/services/user/mutations/delete-wishlist.ts +17 -0
- package/src/api-manager/services/user/mutations/update-user.ts +18 -0
- package/src/api-manager/services/user/queries/get-user-counts.ts +10 -0
- package/src/api-manager/services/user/queries/get-user.ts +10 -0
- package/src/api-manager/services/user/queries/get-wishlist-details.ts +10 -0
- package/src/api-manager/services/user/queries/get-wishlists.ts +10 -0
- package/src/api-manager/types/Datasource.ts +197 -0
- package/src/auth/auth-options.test.ts +127 -0
- package/src/auth/auth-options.ts +68 -0
- package/src/auth/msal.ts +65 -0
- package/src/auth/next-auth-cookie-manager.ts +86 -0
- package/src/auth/providers/aadb2c-provider.ts +33 -0
- package/src/auth/providers/authentik-provider.ts +24 -0
- package/src/auth/providers/index.ts +9 -0
- package/src/auth/providers/keycloak-provider.ts +22 -0
- package/src/auth/refresh-token-url-keys.ts +6 -0
- package/src/auth/refresh-token.ts +134 -0
- package/src/auth/signout.ts +46 -0
- package/src/auth/types/next-auth.d.ts +38 -0
- package/src/cms/blog.ts +229 -0
- package/src/cms/endpoints.ts +76 -0
- package/src/cms/interfaces/navigation.ts +52 -0
- package/src/cms/interfaces/productData.ts +83 -0
- package/src/cms/pages.ts +149 -0
- package/src/components/Blocks/BlockManager.tsx +67 -0
- package/src/components/Blocks/Components/BrandLogosScroller.tsx +72 -0
- package/src/components/Blocks/Components/CategoryCard.tsx +47 -0
- package/src/components/Blocks/Components/CategoryCarousel/index.tsx +60 -0
- package/src/components/Blocks/Components/FeaturePill.tsx +99 -0
- package/src/components/Blocks/Components/FeaturedCategories.tsx +41 -0
- package/src/components/Blocks/Components/FeaturedProducts.tsx +41 -0
- package/src/components/Blocks/Components/Footer.tsx +77 -0
- package/src/components/Blocks/Components/Hero.tsx +73 -0
- package/src/components/Blocks/Components/HeroCarousel/index.tsx +42 -0
- package/src/components/Blocks/Components/Image.tsx +39 -0
- package/src/components/Blocks/Components/MediaCard.tsx +41 -0
- package/src/components/Blocks/Components/ProductCarousel/index.tsx +82 -0
- package/src/components/Blocks/Components/ProductSectionFullWidth/index.tsx +103 -0
- package/src/components/Blocks/Components/RichText.tsx +19 -0
- package/src/components/Blocks/Components/Seo/index.tsx +48 -0
- package/src/components/Blocks/Components/Services/index.tsx +21 -0
- package/src/components/Blocks/Components/Services/service-card.tsx +70 -0
- package/src/components/Blocks/Components/shared/featured-product-card.tsx +29 -0
- package/src/components/Blocks/Components/shared/product-category-item.tsx +49 -0
- package/src/components/Blocks/Components/shared/product-grid.tsx +48 -0
- package/src/components/Blocks/Components/shared/top-categories-card.tsx +66 -0
- package/src/components/Blocks/Components/shared/top-rating-product-card.tsx +63 -0
- package/src/components/Blocks/Icons/Components/Category.tsx +14 -0
- package/src/components/Blocks/Icons/Components/DottedStar.tsx +40 -0
- package/src/components/Blocks/Icons/Components/FallbackIcon.tsx +33 -0
- package/src/components/Blocks/Icons/Components/GiftBox.tsx +18 -0
- package/src/components/Blocks/Icons/Components/Light.tsx +13 -0
- package/src/components/Blocks/Icons/Components/NewArrival.tsx +18 -0
- package/src/components/Blocks/Icons/Components/RankBadge.tsx +39 -0
- package/src/components/Blocks/Icons/index.ts +32 -0
- package/src/components/Blocks/index.tsx +16 -0
- package/src/components/Blocks/interfaces.ts +240 -0
- package/src/components/BoxShadowCard.tsx +16 -0
- package/src/components/Footer/data/index.ts +32 -0
- package/src/components/Footer/index.tsx +88 -0
- package/src/components/Footer/interfaces.ts +37 -0
- package/src/components/Footer/sections/FooterAppStore.tsx +45 -0
- package/src/components/Footer/sections/FooterContact.tsx +36 -0
- package/src/components/Footer/sections/FooterLinks.tsx +30 -0
- package/src/components/Footer/sections/FooterLogo.tsx +26 -0
- package/src/components/Footer/sections/FooterSocialLinks.tsx +70 -0
- package/src/components/Footer/styles/index.ts +39 -0
- package/src/components/GlobalLoading/index.tsx +102 -0
- package/src/components/ImageWithFallback.tsx +51 -0
- package/src/components/Loading/index.tsx +36 -0
- package/src/components/NavProvider/index.tsx +59 -0
- package/src/components/NavProvider/utils/createLink.ts +15 -0
- package/src/components/Notifications/README.md +15 -0
- package/src/components/Notifications/notification-context.tsx +82 -0
- package/src/components/Notifications/use-notification.ts +12 -0
- package/src/components/README.md +9 -0
- package/src/components/ReactQueryProvider/index.tsx +12 -0
- package/src/components/Shared/Image.tsx +5 -0
- package/src/components/T/index.tsx +15 -0
- package/src/components/_components/BazaarCard.tsx +21 -0
- package/src/components/_components/BazaarImage.tsx +12 -0
- package/src/components/_components/BazaarMenu.tsx +47 -0
- package/src/components/_components/BazaarSwitch.tsx +37 -0
- package/src/components/_components/BazaarTextField.tsx +73 -0
- package/src/components/_components/DropZone.tsx +86 -0
- package/src/components/_components/HoverBox.tsx +22 -0
- package/src/components/_components/LazyImage.tsx +9 -0
- package/src/components/_components/MiniCartClient.tsx +65 -0
- package/src/components/_components/SearchInput.tsx +28 -0
- package/src/components/_components/SnackbarProvider.tsx +32 -0
- package/src/components/_components/Typography.tsx +227 -0
- package/src/components/_components/WhiteButton.tsx +20 -0
- package/src/components/_components/accordion/accordion-header.tsx +43 -0
- package/src/components/_components/accordion/index.ts +1 -0
- package/src/components/_components/bazaar-types.ts +84 -0
- package/src/components/_components/carousel/carousel.tsx +72 -0
- package/src/components/_components/carousel/components/carousel-arrows.tsx +60 -0
- package/src/components/_components/carousel/components/carousel-dots.tsx +21 -0
- package/src/components/_components/carousel/index.ts +3 -0
- package/src/components/_components/carousel/styles/index.ts +93 -0
- package/src/components/_components/carousel-cards/carousel-card-1/carousel-card-1.tsx +64 -0
- package/src/components/_components/carousel-cards/carousel-card-1/index.ts +1 -0
- package/src/components/_components/carousel-cards/carousel-card-1/styles.ts +34 -0
- package/src/components/_components/carousel-cards/carousel-card-2/carousel-card-2.tsx +73 -0
- package/src/components/_components/carousel-cards/carousel-card-2/index.ts +1 -0
- package/src/components/_components/carousel-cards/carousel-card-2/styles.ts +26 -0
- package/src/components/_components/carousel-cards/carousel-card-3/carousel-card-3.tsx +34 -0
- package/src/components/_components/carousel-cards/carousel-card-3/index.ts +1 -0
- package/src/components/_components/carousel-cards/carousel-card-3/styles.ts +28 -0
- package/src/components/_components/carousel-cards/carousel-card-4/carousel-card-4.tsx +76 -0
- package/src/components/_components/carousel-cards/carousel-card-4/index.ts +1 -0
- package/src/components/_components/carousel-cards/carousel-card-4/styles.ts +27 -0
- package/src/components/_components/categories/category-list/category-list.tsx +59 -0
- package/src/components/_components/categories/category-list/index.ts +1 -0
- package/src/components/_components/categories/category-list/styles.ts +29 -0
- package/src/components/_components/categories/category-list/types.ts +4 -0
- package/src/components/_components/categories/category-list-item/category-menu-item.tsx +37 -0
- package/src/components/_components/categories/category-list-item/index.ts +1 -0
- package/src/components/_components/categories/category-list-item/styles.ts +35 -0
- package/src/components/_components/categories/category-menu.tsx +51 -0
- package/src/components/_components/categories/mega-menu/banner.tsx +56 -0
- package/src/components/_components/categories/mega-menu/column-list.tsx +70 -0
- package/src/components/_components/categories/mega-menu/mega-menu-1.tsx +37 -0
- package/src/components/_components/categories/mega-menu/mega-menu-2.tsx +37 -0
- package/src/components/_components/categories/mega-menu/styles.ts +25 -0
- package/src/components/_components/categories/types.ts +16 -0
- package/src/components/_components/category-cards/category-card-1/category-card-1.tsx +21 -0
- package/src/components/_components/category-cards/category-card-1/index.ts +1 -0
- package/src/components/_components/category-cards/category-card-1/styles.ts +37 -0
- package/src/components/_components/countdown/count-box.tsx +16 -0
- package/src/components/_components/countdown/count-down.tsx +24 -0
- package/src/components/_components/countdown/index.tsx +2 -0
- package/src/components/_components/countdown/useCountDown.ts +41 -0
- package/src/components/_components/data-table/index.ts +2 -0
- package/src/components/_components/data-table/table-header.tsx +91 -0
- package/src/components/_components/data-table/table-pagination.tsx +36 -0
- package/src/components/_components/flex-box/flex-between.tsx +14 -0
- package/src/components/_components/flex-box/flex-box.tsx +9 -0
- package/src/components/_components/flex-box/flex-row-center.tsx +9 -0
- package/src/components/_components/flex-box/index.ts +5 -0
- package/src/components/_components/footer/components/about-links.tsx +23 -0
- package/src/components/_components/footer/components/app-store.tsx +38 -0
- package/src/components/_components/footer/components/customer-care-links.tsx +21 -0
- package/src/components/_components/footer/components/logo.tsx +23 -0
- package/src/components/_components/footer/components/social-links.tsx +43 -0
- package/src/components/_components/footer/data/index.ts +54 -0
- package/src/components/_components/footer/footer-1.tsx +62 -0
- package/src/components/_components/footer/footer-2.tsx +57 -0
- package/src/components/_components/footer/footer-3.tsx +53 -0
- package/src/components/_components/footer/footer-4.tsx +71 -0
- package/src/components/_components/footer/index.ts +4 -0
- package/src/components/_components/footer/styles/index.ts +42 -0
- package/src/components/_components/header/components/categories-menu.tsx +23 -0
- package/src/components/_components/header/components/mobile-header.tsx +72 -0
- package/src/components/_components/header/components/user.test.tsx +200 -0
- package/src/components/_components/header/components/user.tsx +205 -0
- package/src/components/_components/header/header.tsx +63 -0
- package/src/components/_components/header/hooks/use-header.ts +13 -0
- package/src/components/_components/header/index.ts +1 -0
- package/src/components/_components/header/sticky-header.tsx +17 -0
- package/src/components/_components/header/styles/index.ts +24 -0
- package/src/components/_components/hooks/useOverflowDetect.ts +34 -0
- package/src/components/_components/hooks/useSettings.ts +16 -0
- package/src/components/_components/icons/cart-bag.tsx +13 -0
- package/src/components/_components/icons/category-outline.tsx +29 -0
- package/src/components/_components/icons/category.tsx +12 -0
- package/src/components/_components/icons/home.tsx +19 -0
- package/src/components/_components/icons/search.tsx +13 -0
- package/src/components/_components/icons/shopping-bag-outlined.tsx +13 -0
- package/src/components/_components/icons/up-down.tsx +21 -0
- package/src/components/_components/icons/user.tsx +13 -0
- package/src/components/_components/icons/user2.tsx +14 -0
- package/src/components/_components/mini-cart/__tests__/cart-item.test.tsx +174 -0
- package/src/components/_components/mini-cart/__tests__/mini-cart.test.tsx +121 -0
- package/src/components/_components/mini-cart/__tests__/test-cart-empty.json +84 -0
- package/src/components/_components/mini-cart/__tests__/test-cart-with-item.json +244 -0
- package/src/components/_components/mini-cart/components/bottom-actions.tsx +27 -0
- package/src/components/_components/mini-cart/components/cart-item.tsx +144 -0
- package/src/components/_components/mini-cart/components/empty-view.tsx +29 -0
- package/src/components/_components/mini-cart/components/top-header.tsx +34 -0
- package/src/components/_components/mini-cart/index.ts +1 -0
- package/src/components/_components/mini-cart/mini-cart.tsx +107 -0
- package/src/components/_components/mobile-navigation/index.ts +3 -0
- package/src/components/_components/mobile-navigation/mobile-navigation-bar.tsx +73 -0
- package/src/components/_components/mobile-navigation/styles/index.ts +63 -0
- package/src/components/_components/nav-link/index.ts +5 -0
- package/src/components/_components/nav-link/nav-link-2.tsx +32 -0
- package/src/components/_components/nav-link/nav-link-3.tsx +67 -0
- package/src/components/_components/nav-link/nav-link.tsx +53 -0
- package/src/components/_components/navbar/categories.tsx +27 -0
- package/src/components/_components/navbar/category-based-menu/category-based-menu.tsx +52 -0
- package/src/components/_components/navbar/category-based-menu/components/categories.tsx +44 -0
- package/src/components/_components/navbar/category-based-menu/components/category-item.tsx +31 -0
- package/src/components/_components/navbar/category-based-menu/components/child-categories.tsx +38 -0
- package/src/components/_components/navbar/category-based-menu/index.ts +1 -0
- package/src/components/_components/navbar/category-based-menu/styles.ts +81 -0
- package/src/components/_components/navbar/category-based-menu/types.ts +18 -0
- package/src/components/_components/navbar/index.ts +1 -0
- package/src/components/_components/navbar/mega-menu/category-list.tsx +29 -0
- package/src/components/_components/navbar/mega-menu/index.ts +1 -0
- package/src/components/_components/navbar/mega-menu/mega-menu.tsx +71 -0
- package/src/components/_components/navbar/mega-menu/styles.ts +43 -0
- package/src/components/_components/navbar/mobile-menu/index.ts +1 -0
- package/src/components/_components/navbar/mobile-menu/mobile-menu.tsx +70 -0
- package/src/components/_components/navbar/mobile-menu/render-levels.test.tsx +71 -0
- package/src/components/_components/navbar/mobile-menu/render-levels.tsx +62 -0
- package/src/components/_components/navbar/nav-list/cms-nav.test.tsx +84 -0
- package/src/components/_components/navbar/nav-list/index.ts +1 -0
- package/src/components/_components/navbar/nav-list/nav-item-child.tsx +66 -0
- package/src/components/_components/navbar/nav-list/nav-list.tsx +119 -0
- package/src/components/_components/navbar/navbar.tsx +43 -0
- package/src/components/_components/navbar/styles.ts +90 -0
- package/src/components/_components/navbar/utils/transform-nav.test.ts +209 -0
- package/src/components/_components/navbar/utils/transform-nav.ts +43 -0
- package/src/components/_components/newsletter/index.ts +1 -0
- package/src/components/_components/newsletter/newsletter.tsx +108 -0
- package/src/components/_components/newsletter/social-icons.tsx +35 -0
- package/src/components/_components/newsletter/styles.ts +65 -0
- package/src/components/_components/page-sidenav/grocery-side-nav/components/link-item.tsx +21 -0
- package/src/components/_components/page-sidenav/grocery-side-nav/components/list-item.tsx +27 -0
- package/src/components/_components/page-sidenav/grocery-side-nav/components/nav-accordion.tsx +36 -0
- package/src/components/_components/page-sidenav/grocery-side-nav/components/render-child.tsx +26 -0
- package/src/components/_components/page-sidenav/grocery-side-nav/grocery-side-nav.tsx +32 -0
- package/src/components/_components/page-sidenav/grocery-side-nav/index.ts +1 -0
- package/src/components/_components/page-sidenav/grocery-side-nav/styles/index.ts +11 -0
- package/src/components/_components/page-sidenav/health-beauty-side-nav/components/list-item.tsx +27 -0
- package/src/components/_components/page-sidenav/health-beauty-side-nav/components/nav-accordion.tsx +44 -0
- package/src/components/_components/page-sidenav/health-beauty-side-nav/components/render-child.tsx +20 -0
- package/src/components/_components/page-sidenav/health-beauty-side-nav/health-beauty-side-nav.tsx +43 -0
- package/src/components/_components/page-sidenav/health-beauty-side-nav/index.ts +1 -0
- package/src/components/_components/page-sidenav/health-beauty-side-nav/styles/index.ts +27 -0
- package/src/components/_components/page-sidenav/side-navbar/components/list-item.tsx +25 -0
- package/src/components/_components/page-sidenav/side-navbar/components/nav-accordion.tsx +46 -0
- package/src/components/_components/page-sidenav/side-navbar/components/render-child.tsx +20 -0
- package/src/components/_components/page-sidenav/side-navbar/index.ts +1 -0
- package/src/components/_components/page-sidenav/side-navbar/side-nav-bar.tsx +77 -0
- package/src/components/_components/page-sidenav/side-navbar/styles/index.ts +73 -0
- package/src/components/_components/page-sidenav/side-navbar-2/components/button-content.tsx +32 -0
- package/src/components/_components/page-sidenav/side-navbar-2/components/sidebar-accordion.tsx +66 -0
- package/src/components/_components/page-sidenav/side-navbar-2/index.ts +1 -0
- package/src/components/_components/page-sidenav/side-navbar-2/side-navbar-2.tsx +63 -0
- package/src/components/_components/page-sidenav/side-navbar-2/styles/index.ts +68 -0
- package/src/components/_components/product-cards/discount-chip.tsx +43 -0
- package/src/components/_components/product-cards/product-card-1/components/hover-actions.tsx +37 -0
- package/src/components/_components/product-cards/product-card-1/components/quantity-buttons.tsx +56 -0
- package/src/components/_components/product-cards/product-card-1/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-1/product-card.tsx +146 -0
- package/src/components/_components/product-cards/product-card-1/styles/index.ts +46 -0
- package/src/components/_components/product-cards/product-card-10/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-10/product-card.tsx +124 -0
- package/src/components/_components/product-cards/product-card-10/styles/index.ts +38 -0
- package/src/components/_components/product-cards/product-card-11/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-11/product-card.tsx +63 -0
- package/src/components/_components/product-cards/product-card-11/styles/index.ts +16 -0
- package/src/components/_components/product-cards/product-card-12/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-12/product-card.tsx +42 -0
- package/src/components/_components/product-cards/product-card-12/styles/index.ts +16 -0
- package/src/components/_components/product-cards/product-card-13/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-13/product-card.tsx +45 -0
- package/src/components/_components/product-cards/product-card-13/styles/index.ts +25 -0
- package/src/components/_components/product-cards/product-card-14/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-14/product-card.tsx +122 -0
- package/src/components/_components/product-cards/product-card-14/styles/index.ts +40 -0
- package/src/components/_components/product-cards/product-card-15/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-15/product-card.tsx +118 -0
- package/src/components/_components/product-cards/product-card-15/styles/index.ts +57 -0
- package/src/components/_components/product-cards/product-card-16/components/quantity-buttons.tsx +56 -0
- package/src/components/_components/product-cards/product-card-16/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-16/product-card.tsx +114 -0
- package/src/components/_components/product-cards/product-card-16/styles/index.ts +18 -0
- package/src/components/_components/product-cards/product-card-2/components/favorite-button.tsx +29 -0
- package/src/components/_components/product-cards/product-card-2/components/product-price.tsx +26 -0
- package/src/components/_components/product-cards/product-card-2/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-2/product-card.tsx +70 -0
- package/src/components/_components/product-cards/product-card-3/components/hover-actions.tsx +83 -0
- package/src/components/_components/product-cards/product-card-3/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-3/product-card.tsx +110 -0
- package/src/components/_components/product-cards/product-card-3/styles/index.ts +89 -0
- package/src/components/_components/product-cards/product-card-4/components/hover-actions.tsx +50 -0
- package/src/components/_components/product-cards/product-card-4/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-4/product-card.tsx +128 -0
- package/src/components/_components/product-cards/product-card-4/styles/index.ts +66 -0
- package/src/components/_components/product-cards/product-card-5/components/button-actions.tsx +49 -0
- package/src/components/_components/product-cards/product-card-5/components/hover-actions.tsx +50 -0
- package/src/components/_components/product-cards/product-card-5/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-5/product-card.tsx +137 -0
- package/src/components/_components/product-cards/product-card-5/styles/index.ts +94 -0
- package/src/components/_components/product-cards/product-card-6/components/hover-actions.tsx +50 -0
- package/src/components/_components/product-cards/product-card-6/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-6/product-card.tsx +121 -0
- package/src/components/_components/product-cards/product-card-6/styles/index.ts +63 -0
- package/src/components/_components/product-cards/product-card-7/components/product-status.tsx +18 -0
- package/src/components/_components/product-cards/product-card-7/components/quantity-buttons.tsx +47 -0
- package/src/components/_components/product-cards/product-card-7/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-7/product-card.tsx +136 -0
- package/src/components/_components/product-cards/product-card-7/styles/index.ts +98 -0
- package/src/components/_components/product-cards/product-card-8/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-8/product-card.tsx +133 -0
- package/src/components/_components/product-cards/product-card-8/styles/index.ts +51 -0
- package/src/components/_components/product-cards/product-card-9/components/add-to-cart.tsx +60 -0
- package/src/components/_components/product-cards/product-card-9/components/favorite-button.tsx +27 -0
- package/src/components/_components/product-cards/product-card-9/components/tags.tsx +33 -0
- package/src/components/_components/product-cards/product-card-9/index.ts +1 -0
- package/src/components/_components/product-cards/product-card-9/product-card.tsx +169 -0
- package/src/components/_components/product-cards/product-price.tsx +26 -0
- package/src/components/_components/product-cards/product-rating.tsx +28 -0
- package/src/components/_components/product-cards/product-title.tsx +24 -0
- package/src/components/_components/product-cards/use-product.ts +35 -0
- package/src/components/_components/products-view/product-view-dialog.tsx +180 -0
- package/src/components/_components/products-view/products-grid-view.tsx +39 -0
- package/src/components/_components/products-view/products-list-view.tsx +35 -0
- package/src/components/_components/progress/index.ts +1 -0
- package/src/components/_components/progress/progress.tsx +77 -0
- package/src/components/_components/scrollbar/index.ts +1 -0
- package/src/components/_components/scrollbar/scrollbar.tsx +27 -0
- package/src/components/_components/scrollbar/styles.ts +15 -0
- package/src/components/_components/search-box/components/category-dropdown.tsx +61 -0
- package/src/components/_components/search-box/components/search-result.tsx +29 -0
- package/src/components/_components/search-box/hooks/use-search.ts +63 -0
- package/src/components/_components/search-box/index.ts +2 -0
- package/src/components/_components/search-box/search-input-category.test.tsx +110 -0
- package/src/components/_components/search-box/search-input-category.tsx +104 -0
- package/src/components/_components/search-box/search-input.test.tsx +41 -0
- package/src/components/_components/search-box/search-input.tsx +64 -0
- package/src/components/_components/search-box/styles/index.ts +45 -0
- package/src/components/_components/section-header/index.ts +2 -0
- package/src/components/_components/section-header/section-creator.tsx +28 -0
- package/src/components/_components/section-header/section-header.tsx +44 -0
- package/src/components/_components/service-cards/icon-component.tsx +18 -0
- package/src/components/_components/service-cards/service-card-1/index.ts +1 -0
- package/src/components/_components/service-cards/service-card-1/service-card-1.tsx +39 -0
- package/src/components/_components/service-cards/service-card-2/index.ts +1 -0
- package/src/components/_components/service-cards/service-card-2/service-card-2.tsx +34 -0
- package/src/components/_components/service-cards/service-card-3/index.ts +1 -0
- package/src/components/_components/service-cards/service-card-3/service-card-3.tsx +25 -0
- package/src/components/_components/service-cards/service-card-3/styles.ts +23 -0
- package/src/components/_components/settings/index.ts +1 -0
- package/src/components/_components/settings/setting.tsx +141 -0
- package/src/components/_components/settings/styles.ts +57 -0
- package/src/components/_components/shop-card/index.ts +1 -0
- package/src/components/_components/shop-card/shop-card.tsx +152 -0
- package/src/components/_components/shop-card/styles.ts +33 -0
- package/src/components/_components/side-nav/index.ts +1 -0
- package/src/components/_components/side-nav/side-nav.tsx +49 -0
- package/src/components/_components/site-logo.tsx +17 -0
- package/src/components/_components/sticky/Sticky.tsx +62 -0
- package/src/components/_components/sticky/index.ts +1 -0
- package/src/components/_components/sticky/styles.ts +38 -0
- package/src/components/_components/sticky-wrapper/index.ts +1 -0
- package/src/components/_components/sticky-wrapper/sticky-wrapper.tsx +21 -0
- package/src/components/_components/sticky-wrapper/styles.ts +25 -0
- package/src/components/_components/stories/story-content/index.ts +1 -0
- package/src/components/_components/stories/story-content/story-content.tsx +28 -0
- package/src/components/_components/stories/story-content/styles.ts +22 -0
- package/src/components/_components/stories/story-item/index.ts +1 -0
- package/src/components/_components/stories/story-item/story-item.tsx +24 -0
- package/src/components/_components/stories/story-item/styles.ts +11 -0
- package/src/components/_components/stories/story-viewer/index.ts +1 -0
- package/src/components/_components/stories/story-viewer/story-viewer.tsx +44 -0
- package/src/components/_components/stories/story-viewer/styles.ts +15 -0
- package/src/components/_components/subscribe-input/index.ts +1 -0
- package/src/components/_components/subscribe-input/styles.ts +14 -0
- package/src/components/_components/subscribe-input/subscribe-input.tsx +43 -0
- package/src/components/_components/topbar/index.ts +1 -0
- package/src/components/_components/topbar/styles.ts +55 -0
- package/src/components/_components/topbar/top-bar.tsx +112 -0
- package/src/components/_components/utils/constants.ts +8 -0
- package/src/components/countries-input.tsx +78 -0
- package/src/config.ts +47 -0
- package/src/lib/build-detail-url.ts +8 -0
- package/src/lib/build-product-detail-url.ts +12 -0
- package/src/lib/cart-cookie-client-handler.ts +12 -0
- package/src/lib/cart-cookie-handler.ts +14 -0
- package/src/lib/category-helpers.ts +113 -0
- package/src/lib/create-graphql-client.ts +32 -0
- package/src/lib/currency-formatter.ts +31 -0
- package/src/lib/get-palette-color.ts +50 -0
- package/src/lib/graphqlRequestSdk.ts +41234 -0
- package/src/lib/hexToLuma.ts +55 -0
- package/src/lib/lib.ts +61 -0
- package/src/lib/map-helper.ts +71 -0
- package/src/lib/page-slugs.ts +10 -0
- package/src/lib/refiner-utils.ts +32 -0
- package/src/lib/store-hours-helper.ts +274 -0
- package/src/lib/test-media.ts +23 -0
- package/tsconfig.json +27 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { useMutation } from "@tanstack/react-query";
|
|
2
|
+
import { ApiPath } from "./create-query";
|
|
3
|
+
import { DatasourceApis } from "../types/Datasource";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A wrapper for useMutation that enables passing of api manager path
|
|
7
|
+
* and handles creating the mutation function in a standardized way
|
|
8
|
+
*
|
|
9
|
+
* @param apiManagerPath path to the api manager function
|
|
10
|
+
* @param options
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
export const useCreateMutation = <TInput, TOutput>(
|
|
14
|
+
apiManagerPath: ApiPath<keyof DatasourceApis>,
|
|
15
|
+
options?: {
|
|
16
|
+
onSuccess?: (result: TOutput, input: TInput) => void;
|
|
17
|
+
onError?: (error: unknown, input: TInput) => void;
|
|
18
|
+
onMutate?: (input: TInput) => void;
|
|
19
|
+
onSettled?: (
|
|
20
|
+
result: TOutput | undefined,
|
|
21
|
+
error: unknown,
|
|
22
|
+
input: TInput,
|
|
23
|
+
) => void;
|
|
24
|
+
},
|
|
25
|
+
) => {
|
|
26
|
+
return useMutation<TOutput, unknown, TInput>({
|
|
27
|
+
// MutationsFn should always point to ApiManager Route Handler
|
|
28
|
+
mutationFn: async (input: TInput) => {
|
|
29
|
+
const response = await fetch("/api", {
|
|
30
|
+
method: "POST",
|
|
31
|
+
body: JSON.stringify({ input, apiManagerPath }),
|
|
32
|
+
});
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
throw new Error("Mutation failed");
|
|
35
|
+
}
|
|
36
|
+
return response.json();
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
onMutate: (input) => {
|
|
40
|
+
if (options?.onMutate) {
|
|
41
|
+
options.onMutate(input);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
onSuccess: (result, input) => {
|
|
46
|
+
if (options?.onSuccess) {
|
|
47
|
+
options.onSuccess(result, input);
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
onError: (error, input) => {
|
|
52
|
+
if (options?.onError) {
|
|
53
|
+
options.onError(error, input);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
console.warn(`${apiManagerPath} MUTATION FAILED:`, error);
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
onSettled: (result, error, input) => {
|
|
60
|
+
if (options?.onSettled) {
|
|
61
|
+
options.onSettled(result, error, input);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
};
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
// TODO: use api manager types to remove type any
|
|
3
|
+
import createApiManager from "../index";
|
|
4
|
+
import { isServer, QueryClient } from "@tanstack/query-core";
|
|
5
|
+
import {
|
|
6
|
+
UseQueryResult,
|
|
7
|
+
UseSuspenseQueryResult,
|
|
8
|
+
useQuery,
|
|
9
|
+
useSuspenseQuery,
|
|
10
|
+
} from "@tanstack/react-query";
|
|
11
|
+
import { DatasourceApis } from "../types/Datasource";
|
|
12
|
+
import { Mutex } from "async-mutex";
|
|
13
|
+
import { manuallyRetrieveSessionCookie } from "@/auth/next-auth-cookie-manager";
|
|
14
|
+
import { getSession } from "next-auth/react";
|
|
15
|
+
import jwt from "jsonwebtoken";
|
|
16
|
+
|
|
17
|
+
const QUERY_ROUTE = "/api";
|
|
18
|
+
const mutex = new Mutex();
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Creates a react-query query with all data access methods exported.
|
|
22
|
+
* Handles switching between direct api-manager calls and accessing api manager through
|
|
23
|
+
* route handler. If no query key provided, use api manager path as cache key prefix.
|
|
24
|
+
* @param queryKey a prefix to add to cache key
|
|
25
|
+
* @param route the route to the corresponding route handler
|
|
26
|
+
* @param apiManagerPath a tuple of two items, entity name and method
|
|
27
|
+
* @param options.disableProperty if these input properties are undefined then disable query
|
|
28
|
+
* @returns
|
|
29
|
+
*/
|
|
30
|
+
export const createQuery = <TInput, TOutput>(
|
|
31
|
+
apiManagerPath: ApiPath<keyof DatasourceApis>,
|
|
32
|
+
config?: {
|
|
33
|
+
queryKey?: string;
|
|
34
|
+
disableProperties?: Array<keyof TInput>;
|
|
35
|
+
},
|
|
36
|
+
) => {
|
|
37
|
+
/**
|
|
38
|
+
* Generates the configuration object for a query, including the query function, cache key, and enabled state.
|
|
39
|
+
*
|
|
40
|
+
* The query function (`queryFn`) is determined based on the execution environment (server or client):
|
|
41
|
+
* - On the server, it checks for token expiry, refreshes the token if needed, creates an API manager, and invokes the appropriate API function.
|
|
42
|
+
* - On the client, it checks for token expiry and either refreshes the token or performs a fetch operation.
|
|
43
|
+
*
|
|
44
|
+
* The `enabled` property is computed based on the presence and truthiness of specified properties in the input, if `disableProperties` are provided in options.
|
|
45
|
+
*
|
|
46
|
+
* @param input - Optional input parameters for the query and API function.
|
|
47
|
+
* @returns An object containing:
|
|
48
|
+
* - `queryKey`: The cache key for the query, built from the input.
|
|
49
|
+
* - `queryFn`: The asynchronous function to execute for the query.
|
|
50
|
+
* - `enabled`: A boolean indicating whether the query should be enabled.
|
|
51
|
+
*/
|
|
52
|
+
const getQueryData = (input?: TInput) => {
|
|
53
|
+
const queryFn = isServer
|
|
54
|
+
? /// Server ///
|
|
55
|
+
async () => {
|
|
56
|
+
const apiManager = await createApiManager();
|
|
57
|
+
const apiFunction = getApiFromPath(apiManager, apiManagerPath);
|
|
58
|
+
const result = await apiFunction(input);
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
: /// Client ///
|
|
62
|
+
async () => {
|
|
63
|
+
// Check if token is expired
|
|
64
|
+
const shouldRefreshToken = await checkTokenExpiry();
|
|
65
|
+
if (shouldRefreshToken) {
|
|
66
|
+
return await handleTokenRefreshClient(input);
|
|
67
|
+
} else {
|
|
68
|
+
return await doFetch(input, apiManagerPath);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// if disable props specified then use them to compute enabled
|
|
73
|
+
const enabled: boolean = config?.disableProperties
|
|
74
|
+
? config.disableProperties.every((prop) => !!input?.[prop])
|
|
75
|
+
: true;
|
|
76
|
+
|
|
77
|
+
const data = {
|
|
78
|
+
queryKey: buildCacheKey(input),
|
|
79
|
+
queryFn,
|
|
80
|
+
enabled,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
return data;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Sends a POST request to the specified route with the provided input and API manager path.
|
|
88
|
+
*
|
|
89
|
+
* @template TInput - The type of the input parameter.
|
|
90
|
+
* @param input - The input data to be sent in the request body. Can be undefined.
|
|
91
|
+
* @param route - The endpoint URL to which the request is sent.
|
|
92
|
+
* @param apiManagerPath - The API manager path used to identify the API endpoint.
|
|
93
|
+
* @returns A promise that resolves to the response of the fetch request.
|
|
94
|
+
*/
|
|
95
|
+
const doFetch = async (
|
|
96
|
+
input: TInput | undefined,
|
|
97
|
+
apiManagerPath: ApiPath<keyof DatasourceApis>,
|
|
98
|
+
additionalHeaders?: HeadersInit,
|
|
99
|
+
) => {
|
|
100
|
+
// Merge headers
|
|
101
|
+
const headers = new Headers(additionalHeaders);
|
|
102
|
+
// generic route handler (new) - will refactor all queries to use this
|
|
103
|
+
const result = await fetch(QUERY_ROUTE, {
|
|
104
|
+
method: "POST",
|
|
105
|
+
body: JSON.stringify({ input, apiManagerPath }),
|
|
106
|
+
headers,
|
|
107
|
+
});
|
|
108
|
+
return await result.json();
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Client-side hook to call data from react query cache
|
|
113
|
+
* @returns
|
|
114
|
+
*/
|
|
115
|
+
const useData = (input?: TInput): UseQueryResult<TOutput> => {
|
|
116
|
+
return useQuery(getQueryData(input));
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Client-side hook to call data from react query cache,
|
|
121
|
+
* used with suspense for suspense loading state handling
|
|
122
|
+
* @returns
|
|
123
|
+
*/
|
|
124
|
+
const useSuspenseData = (input?: TInput): UseSuspenseQueryResult<TOutput> => {
|
|
125
|
+
return useSuspenseQuery(getQueryData(input));
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Called on server to fetch query and load cache
|
|
130
|
+
* @param queryClient
|
|
131
|
+
* @returns
|
|
132
|
+
*/
|
|
133
|
+
const fetchData = async (queryClient: QueryClient, input?: TInput) => {
|
|
134
|
+
return await queryClient.fetchQuery(getQueryData(input));
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Called on server to fetch query and load cache in anticipation
|
|
139
|
+
* of client using data
|
|
140
|
+
* @param queryClient
|
|
141
|
+
*/
|
|
142
|
+
const prefetchData = async (queryClient: QueryClient, input?: TInput) => {
|
|
143
|
+
return await queryClient.prefetchQuery(getQueryData(input));
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
*
|
|
148
|
+
* @param queryClient react-query client
|
|
149
|
+
* @param data the data to set the query to
|
|
150
|
+
* @param input the input of the query that's used to generate cache key
|
|
151
|
+
* returns a promise of QueryResult for query
|
|
152
|
+
*/
|
|
153
|
+
const setQueryData = async (
|
|
154
|
+
queryClient: QueryClient,
|
|
155
|
+
data: TOutput,
|
|
156
|
+
input?: TInput,
|
|
157
|
+
) => {
|
|
158
|
+
const key = buildCacheKey(input);
|
|
159
|
+
return await queryClient.setQueryData(key, data);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
*
|
|
164
|
+
* @param input the input for the query of TInput
|
|
165
|
+
* @returns if no input, the query key, if input, query key and input in array
|
|
166
|
+
*/
|
|
167
|
+
const buildCacheKey = (input?: TInput) => {
|
|
168
|
+
const prefix = config?.queryKey ?? apiManagerPath;
|
|
169
|
+
return input ? [prefix, input] : [prefix];
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Asynchronously checks whether the current session's access token has expired.
|
|
174
|
+
*
|
|
175
|
+
* Retrieves the current session and decodes the access token to extract its expiration time.
|
|
176
|
+
* Compares the token's expiration (`exp`) claim with the current time.
|
|
177
|
+
*
|
|
178
|
+
* @returns A promise that resolves to `true` if the token is expired, or `false` otherwise.
|
|
179
|
+
*/
|
|
180
|
+
const checkTokenExpiry = async () => {
|
|
181
|
+
let token: string | undefined;
|
|
182
|
+
if (isServer) {
|
|
183
|
+
// Server-side: retrieve session from cookies
|
|
184
|
+
const session = (await manuallyRetrieveSessionCookie()) ?? undefined;
|
|
185
|
+
token = session?.accessToken;
|
|
186
|
+
} else {
|
|
187
|
+
const session = await getSession();
|
|
188
|
+
token = session?.accessToken;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const decoded = token && (jwt.decode(token) as { exp?: number } | null);
|
|
192
|
+
|
|
193
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
|
194
|
+
|
|
195
|
+
const isExpired =
|
|
196
|
+
!!decoded && typeof decoded.exp === "number" && decoded.exp < currentTime;
|
|
197
|
+
|
|
198
|
+
return isExpired;
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Handles fetching data with token refresh logic in a thread-safe manner.
|
|
203
|
+
*
|
|
204
|
+
* Acquires a mutex lock to ensure only one token refresh operation occurs at a time.
|
|
205
|
+
* Checks if the token is expired and, if so, adds a header to indicate that the token should be refreshed.
|
|
206
|
+
* Performs the fetch operation with the appropriate headers and returns the parsed JSON response.
|
|
207
|
+
* Releases the mutex lock after the operation completes, regardless of success or failure.
|
|
208
|
+
*
|
|
209
|
+
* @param input - The input data for the fetch operation, which may be undefined.
|
|
210
|
+
* @returns A promise that resolves to the parsed JSON response from the fetch operation.
|
|
211
|
+
* @throws An error if the fetch operation fails.
|
|
212
|
+
*/
|
|
213
|
+
const handleTokenRefreshClient = async (input: TInput | undefined) => {
|
|
214
|
+
const release = await mutex.acquire();
|
|
215
|
+
try {
|
|
216
|
+
// Check if token is expired again
|
|
217
|
+
const stillShouldRefreshToken = await checkTokenExpiry();
|
|
218
|
+
const headers = new Headers();
|
|
219
|
+
if (stillShouldRefreshToken) {
|
|
220
|
+
// Add refresh token header
|
|
221
|
+
headers.append("should-refresh-token", "true");
|
|
222
|
+
}
|
|
223
|
+
// Call do fetch with the headers
|
|
224
|
+
const response = await doFetch(input, apiManagerPath, headers);
|
|
225
|
+
|
|
226
|
+
return response.json();
|
|
227
|
+
} catch (error) {
|
|
228
|
+
// Handle API Error
|
|
229
|
+
console.error("Error fetching data:", error);
|
|
230
|
+
throw new Error("Failed to fetch data");
|
|
231
|
+
} finally {
|
|
232
|
+
release();
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
return {
|
|
237
|
+
useData,
|
|
238
|
+
useSuspenseData,
|
|
239
|
+
setQueryData,
|
|
240
|
+
fetchData,
|
|
241
|
+
prefetchData,
|
|
242
|
+
buildCacheKey,
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* A tuple type where api manager entity is first item and second item is method
|
|
248
|
+
* of first item
|
|
249
|
+
*/
|
|
250
|
+
export type ApiPath<T extends keyof DatasourceApis = keyof DatasourceApis> = [
|
|
251
|
+
T,
|
|
252
|
+
keyof DatasourceApis[T],
|
|
253
|
+
];
|
|
254
|
+
|
|
255
|
+
/// Utilities ///
|
|
256
|
+
/**
|
|
257
|
+
* Takes an apiManager and reaches into nested sub api's based on array path
|
|
258
|
+
* @param apiManager
|
|
259
|
+
* @param path array of path steps
|
|
260
|
+
* @returns the function at the specified path
|
|
261
|
+
*/
|
|
262
|
+
export function getApiFromPath<TInput, TOutput>(
|
|
263
|
+
apiManager: any,
|
|
264
|
+
path: ApiPath,
|
|
265
|
+
): (input?: TInput) => Promise<TOutput> {
|
|
266
|
+
const [entity, method] = path;
|
|
267
|
+
// Typescript is doing heavy lifting to ensure correct api path
|
|
268
|
+
// so safe to call method directly
|
|
269
|
+
const result = apiManager[entity][method];
|
|
270
|
+
|
|
271
|
+
if (process.env.NODE_ENV === "development") {
|
|
272
|
+
// eslint-disable-next-line no-console
|
|
273
|
+
console.log(`[CREATE QUERY] Accessing API Path:`, {
|
|
274
|
+
entity,
|
|
275
|
+
method,
|
|
276
|
+
result,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Function reference loses 'this' context.
|
|
281
|
+
// Re-bind for d365 classes.
|
|
282
|
+
if (typeof result === "function") {
|
|
283
|
+
return result.bind(apiManager[entity]);
|
|
284
|
+
}
|
|
285
|
+
return result;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
*
|
|
290
|
+
* @param key
|
|
291
|
+
* @param method
|
|
292
|
+
* @returns
|
|
293
|
+
*/
|
|
294
|
+
export function createApiPath<T extends keyof DatasourceApis>(
|
|
295
|
+
key: T,
|
|
296
|
+
method: keyof DatasourceApis[T],
|
|
297
|
+
) {
|
|
298
|
+
// have to re-cast to general keyof DatasourceApi after
|
|
299
|
+
// using stricter type for type narrowing and intellisense
|
|
300
|
+
return [key, method] as ApiPath<keyof DatasourceApis>;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export type Query<TInput, TOutput> = ReturnType<
|
|
304
|
+
typeof createQuery<TInput, TOutput>
|
|
305
|
+
>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isServer,
|
|
3
|
+
QueryClient,
|
|
4
|
+
defaultShouldDehydrateQuery,
|
|
5
|
+
defaultShouldDehydrateMutation,
|
|
6
|
+
} from "@tanstack/react-query";
|
|
7
|
+
|
|
8
|
+
function makeQueryClient() {
|
|
9
|
+
return new QueryClient({
|
|
10
|
+
defaultOptions: {
|
|
11
|
+
queries: {
|
|
12
|
+
staleTime: 60 * 1000,
|
|
13
|
+
},
|
|
14
|
+
dehydrate: {
|
|
15
|
+
serializeData: (data) => JSON.stringify(data),
|
|
16
|
+
shouldDehydrateMutation: (mutation) =>
|
|
17
|
+
defaultShouldDehydrateMutation(mutation),
|
|
18
|
+
// include pending queries in dehydration
|
|
19
|
+
shouldDehydrateQuery: (query) =>
|
|
20
|
+
defaultShouldDehydrateQuery(query) ||
|
|
21
|
+
query.state.status === "pending",
|
|
22
|
+
},
|
|
23
|
+
hydrate: {
|
|
24
|
+
deserializeData: (data) => (data && JSON.parse(data)) || data,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let browserQueryClient: QueryClient | undefined;
|
|
31
|
+
|
|
32
|
+
export function getQueryClient() {
|
|
33
|
+
if (isServer) {
|
|
34
|
+
// Server: always make a new query client
|
|
35
|
+
return makeQueryClient();
|
|
36
|
+
} else {
|
|
37
|
+
if (!browserQueryClient) browserQueryClient = makeQueryClient();
|
|
38
|
+
return browserQueryClient;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GetSalesOrderDetailsInput,
|
|
3
|
+
SalesOrder,
|
|
4
|
+
} from "@/api-manager/schemas/order.schema";
|
|
5
|
+
import { createQuery, createApiPath } from "../../create-query";
|
|
6
|
+
|
|
7
|
+
const apiPath = createApiPath("order", "getSalesOrderDetails");
|
|
8
|
+
const config = {
|
|
9
|
+
queryKey: "salesOrderDetails",
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const getOrderDetails = createQuery<GetSalesOrderDetailsInput, SalesOrder>(
|
|
13
|
+
apiPath,
|
|
14
|
+
config,
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
export default getOrderDetails;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SalesOrder,
|
|
3
|
+
SalesOrderInput,
|
|
4
|
+
} from "@/api-manager/schemas/order.schema";
|
|
5
|
+
import { createApiPath, createQuery } from "../../create-query";
|
|
6
|
+
|
|
7
|
+
const apiPath = createApiPath("order", "getSalesOrders");
|
|
8
|
+
const config = {
|
|
9
|
+
queryKey: "salesOrderDetails",
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const getOrders = createQuery<SalesOrderInput, SalesOrder[]>(apiPath, config);
|
|
13
|
+
|
|
14
|
+
export default getOrders;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ChannelConfiguration } from "@/api-manager/schemas/organization.schema";
|
|
2
|
+
import { createApiPath, createQuery } from "../../create-query";
|
|
3
|
+
|
|
4
|
+
const apiPath = createApiPath("organization", "getChannelConfiguration");
|
|
5
|
+
const config = {
|
|
6
|
+
queryKey: "channelConfiguration",
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const getChannelConfiguration = createQuery<null, ChannelConfiguration[]>(
|
|
10
|
+
apiPath,
|
|
11
|
+
config,
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
export default getChannelConfiguration;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GetOrgUnitLocationsByAreaInput,
|
|
3
|
+
OrgUnitLocationReturnType,
|
|
4
|
+
} from "@/api-manager/schemas/organization.schema";
|
|
5
|
+
import { createApiPath, createQuery } from "../../create-query";
|
|
6
|
+
|
|
7
|
+
const apiPath = createApiPath("organization", "getStoresList");
|
|
8
|
+
const config = {
|
|
9
|
+
queryKey: "getStores",
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const getStoresList = createQuery<
|
|
13
|
+
GetOrgUnitLocationsByAreaInput,
|
|
14
|
+
OrgUnitLocationReturnType[]
|
|
15
|
+
>(apiPath, config);
|
|
16
|
+
|
|
17
|
+
export default getStoresList;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { searchProductsInput } from "@/api-manager/schemas/product.schema";
|
|
2
|
+
import { useMutation } from "@tanstack/react-query";
|
|
3
|
+
import { ProductSearchResult } from "@msdyn365-commerce/retail-proxy";
|
|
4
|
+
import { searchProductsServer } from "../server/product.server";
|
|
5
|
+
import { UseMutationResult } from "@tanstack/react-query";
|
|
6
|
+
|
|
7
|
+
// TODO: once migrating to query version this interface is no longer needed
|
|
8
|
+
export type EntityDataManagerMutate<TData, TVariables> =
|
|
9
|
+
() => UseMutationResult<TData, Error, TVariables, unknown>;
|
|
10
|
+
|
|
11
|
+
/** DEPRECATED - REPLACE WITH QUERY VERSION */
|
|
12
|
+
const useSearchProducts: EntityDataManagerMutate<
|
|
13
|
+
ProductSearchResult[],
|
|
14
|
+
searchProductsInput
|
|
15
|
+
> = () => {
|
|
16
|
+
return useMutation({
|
|
17
|
+
mutationFn: (input: searchProductsInput) => {
|
|
18
|
+
return searchProductsServer(input);
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default useSearchProducts;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ProductWarehouseInventoryInformation } from "@msdyn365-commerce/retail-proxy";
|
|
2
|
+
import { InventorySearchCriteriaInput } from "@/api-manager/schemas/product.schema";
|
|
3
|
+
import { createApiPath, createQuery } from "../../create-query";
|
|
4
|
+
|
|
5
|
+
const apiPath = createApiPath("product", "getInventory");
|
|
6
|
+
|
|
7
|
+
const getProductAvailability = createQuery<
|
|
8
|
+
InventorySearchCriteriaInput,
|
|
9
|
+
ProductWarehouseInventoryInformation
|
|
10
|
+
>(apiPath, {
|
|
11
|
+
queryKey: "product-inventory",
|
|
12
|
+
disableProperties: ["allDimensionsSelected", "searchCriteria"],
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export default getProductAvailability;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GetProductByIdInput,
|
|
3
|
+
ProductDetails,
|
|
4
|
+
} from "../../../schemas/product.schema";
|
|
5
|
+
import { createApiPath, createQuery } from "../../create-query";
|
|
6
|
+
|
|
7
|
+
const apiPath = createApiPath("product", "getProductById");
|
|
8
|
+
|
|
9
|
+
const getProductById = createQuery<GetProductByIdInput, ProductDetails>(
|
|
10
|
+
apiPath,
|
|
11
|
+
{
|
|
12
|
+
queryKey: "product",
|
|
13
|
+
disableProperties: ["id"],
|
|
14
|
+
},
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
export default getProductById;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { GetProductByIdsInput } from "../../../schemas/product.schema";
|
|
2
|
+
import { SimpleProduct } from "@msdyn365-commerce/retail-proxy";
|
|
3
|
+
import { createApiPath, createQuery } from "../../create-query";
|
|
4
|
+
|
|
5
|
+
const apiPath = createApiPath("product", "getProductByIds");
|
|
6
|
+
|
|
7
|
+
const getProductByIds = createQuery<GetProductByIdsInput, SimpleProduct[]>(
|
|
8
|
+
apiPath,
|
|
9
|
+
{
|
|
10
|
+
queryKey: "products",
|
|
11
|
+
},
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
export default getProductByIds;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SearchByCriteriaInput,
|
|
3
|
+
SearchByCriteriaResponse,
|
|
4
|
+
} from "@/api-manager/schemas/product.schema";
|
|
5
|
+
import { createApiPath, createQuery } from "../../create-query";
|
|
6
|
+
|
|
7
|
+
const apiPath = createApiPath("product", "getProductsList");
|
|
8
|
+
|
|
9
|
+
const getProductList = createQuery<
|
|
10
|
+
SearchByCriteriaInput,
|
|
11
|
+
SearchByCriteriaResponse
|
|
12
|
+
>(apiPath, {
|
|
13
|
+
queryKey: "product-list",
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export default getProductList;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { GetRelatedProductsInput } from "../../../schemas/product.schema";
|
|
2
|
+
import { ProductSearchResult } from "@msdyn365-commerce/retail-proxy";
|
|
3
|
+
import { createApiPath, createQuery } from "../../create-query";
|
|
4
|
+
|
|
5
|
+
const apiPath = createApiPath("product", "getRelatedProducts");
|
|
6
|
+
|
|
7
|
+
const getRelatedProducts = createQuery<
|
|
8
|
+
GetRelatedProductsInput,
|
|
9
|
+
ProductSearchResult[]
|
|
10
|
+
>(apiPath, {
|
|
11
|
+
queryKey: "related-products",
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export default getRelatedProducts;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { searchProductsInput } from "@/api-manager/schemas/product.schema";
|
|
2
|
+
import { ProductSearchResult } from "@msdyn365-commerce/retail-proxy";
|
|
3
|
+
import { createApiPath, createQuery } from "../../create-query";
|
|
4
|
+
|
|
5
|
+
const apiPath = createApiPath("product", "searchProducts");
|
|
6
|
+
const searchProducts = createQuery<searchProductsInput, ProductSearchResult[]>(
|
|
7
|
+
apiPath,
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
export default searchProducts;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
import parseObject from "../../../datasources/d365/utils/parse-object";
|
|
4
|
+
import { ProductSearchResult } from "@msdyn365-commerce/retail-proxy";
|
|
5
|
+
import { searchProductsInput } from "@/api-manager/schemas/product.schema";
|
|
6
|
+
import createApiManager from "../../../index";
|
|
7
|
+
|
|
8
|
+
export const searchProductsServer = async (
|
|
9
|
+
input: searchProductsInput,
|
|
10
|
+
): Promise<ProductSearchResult[]> => {
|
|
11
|
+
const apiManager = await createApiManager();
|
|
12
|
+
return parseObject(apiManager.product.searchProducts(input));
|
|
13
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
2
|
+
import {
|
|
3
|
+
Session,
|
|
4
|
+
SessionInitInput,
|
|
5
|
+
} from "@/api-manager/schemas/session.schema";
|
|
6
|
+
import { useCreateMutation } from "../../create-mutation";
|
|
7
|
+
import { createApiPath } from "../../create-query";
|
|
8
|
+
|
|
9
|
+
const apiPath = createApiPath("session", "sessionInit");
|
|
10
|
+
|
|
11
|
+
const useSessionInit = () => {
|
|
12
|
+
const queryClient = useQueryClient();
|
|
13
|
+
|
|
14
|
+
return useCreateMutation<SessionInitInput, Session>(apiPath, {
|
|
15
|
+
onSuccess: () => {
|
|
16
|
+
queryClient.invalidateQueries({ queryKey: ["sessionRead"] });
|
|
17
|
+
queryClient.invalidateQueries({ queryKey: ["me"] });
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default useSessionInit;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
2
|
+
import { useCreateMutation } from "../../create-mutation";
|
|
3
|
+
import { createApiPath } from "../../create-query";
|
|
4
|
+
|
|
5
|
+
const apiPath = createApiPath("session", "sessionLogout");
|
|
6
|
+
|
|
7
|
+
const useSessionLogout = () => {
|
|
8
|
+
const queryClient = useQueryClient();
|
|
9
|
+
|
|
10
|
+
return useCreateMutation<unknown, boolean>(apiPath, {
|
|
11
|
+
onSuccess: () => {
|
|
12
|
+
queryClient.invalidateQueries({ queryKey: ["sessionRead"] });
|
|
13
|
+
queryClient.invalidateQueries({ queryKey: ["me"] });
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default useSessionLogout;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Session } from "@/api-manager/schemas/session.schema";
|
|
2
|
+
import { createApiPath, createQuery } from "../../create-query";
|
|
3
|
+
|
|
4
|
+
const apiPath = createApiPath("session", "getSession");
|
|
5
|
+
|
|
6
|
+
const getSession = createQuery<null, Session[]>(apiPath, {
|
|
7
|
+
queryKey: "session-read",
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
export default getSession;
|