@mframework/layer-commerce 0.0.3
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 +101 -0
- package/app/cart/useCart.ts +1 -0
- package/app/components/ChevronIcon/ChevronIcon.config.ts +17 -0
- package/app/components/DateSelect/DateSelect.config.ts +15 -0
- package/app/components/Field/Field.config.ts +14 -0
- package/app/components/FieldDate/FieldDate.config.ts +16 -0
- package/app/components/Form/Form.type.ts +8 -0
- package/app/components/Product/Product.config.ts +19 -0
- package/app/components/Product/Stock.config.ts +15 -0
- package/app/components/ProductCustomizableOption/ProductCustomizableOption.config.ts +5 -0
- package/app/components/ProductGallery/ProductGallery.config.ts +15 -0
- package/app/components/ProductReviews/ProductReviews.config.ts +8 -0
- package/app/composables/_types.ts +18 -0
- package/app/composables/adapters/abstract/cartAdapter.ts +0 -0
- package/app/composables/adapters/abstract/categoryAdapter.ts +0 -0
- package/app/composables/adapters/abstract/customerAdapter.ts +0 -0
- package/app/composables/adapters/abstract/inventoryAdapter.ts +0 -0
- package/app/composables/adapters/abstract/orderAdapter.ts +0 -0
- package/app/composables/adapters/abstract/productAdapter.ts +7 -0
- package/app/composables/cart/registry.ts +20 -0
- package/app/composables/cart/types.ts +18 -0
- package/app/composables/cart/useCart.ts +15 -0
- package/app/composables/config.ts +19 -0
- package/app/composables/defs/apiDefinitions.ts +55 -0
- package/app/composables/defs/extension.feature +40 -0
- package/app/composables/defs/extension.mocks.ts +39 -0
- package/app/composables/defs/extension.test.ts +280 -0
- package/app/composables/defs/extension.ts +236 -0
- package/app/composables/defs/index.ts +3 -0
- package/app/composables/defs/typeHelpers.ts +8 -0
- package/app/composables/defs/types.ts +136 -0
- package/app/composables/domain/product.ts +12 -0
- package/app/composables/featured-products.ts +20 -0
- package/app/composables/helpers/contextualizedNormalizers.feature +14 -0
- package/app/composables/helpers/contextualizedNormalizers.test.ts +85 -0
- package/app/composables/helpers/contextualizedNormalizers.ts +20 -0
- package/app/composables/helpers/index.ts +1 -0
- package/app/composables/index.ts +9 -0
- package/app/composables/methods/auth.ts +83 -0
- package/app/composables/methods/cart.ts +119 -0
- package/app/composables/methods/category.ts +27 -0
- package/app/composables/methods/checkout.ts +54 -0
- package/app/composables/methods/customer.ts +52 -0
- package/app/composables/methods/helpers.ts +5 -0
- package/app/composables/methods/index.ts +75 -0
- package/app/composables/methods/order.ts +39 -0
- package/app/composables/methods/product.ts +95 -0
- package/app/composables/methods/settings.ts +16 -0
- package/app/composables/models/cart.ts +95 -0
- package/app/composables/models/category.ts +13 -0
- package/app/composables/models/checkout.ts +17 -0
- package/app/composables/models/customer.ts +16 -0
- package/app/composables/models/facets.ts +25 -0
- package/app/composables/models/index.ts +94 -0
- package/app/composables/models/order.ts +43 -0
- package/app/composables/models/product.ts +73 -0
- package/app/composables/models/shared.ts +75 -0
- package/app/composables/orders.ts +69 -0
- package/app/composables/products/registry.ts +86 -0
- package/app/composables/products/types.ts +8 -0
- package/app/composables/products/useEvents.ts +26 -0
- package/app/composables/products/useGiftCards.ts +29 -0
- package/app/composables/products/useProducts.ts +12 -0
- package/app/composables/products/useSubscriptions.ts +29 -0
- package/app/composables/products.ts +30 -0
- package/app/composables/registry.ts +24 -0
- package/app/composables/useAuth.ts +43 -0
- package/app/composables/useBreakpoints/index.ts +1 -0
- package/app/composables/useBreakpoints/useBreakpoints.ts +28 -0
- package/app/composables/useCache.ts +38 -0
- package/app/composables/useCart/__tests__/useCart.spec.ts +11 -0
- package/app/composables/useCart/index.ts +1 -0
- package/app/composables/useCart/types.ts +17 -0
- package/app/composables/useCart/useCart.ts +46 -0
- package/app/composables/useCartShippingMethods/__tests__/useCartShippingMethods.spec.ts +11 -0
- package/app/composables/useCartShippingMethods/index.ts +1 -0
- package/app/composables/useCartShippingMethods/types.ts +17 -0
- package/app/composables/useCartShippingMethods/useCartShippingMethods.ts +47 -0
- package/app/composables/useCatalog.ts +26 -0
- package/app/composables/useContent.ts +26 -0
- package/app/composables/useCustomer/__tests__/useCustomer.spec.ts +25 -0
- package/app/composables/useCustomer/index.ts +2 -0
- package/app/composables/useCustomer/types.ts +17 -0
- package/app/composables/useCustomer/useCustomer.ts +40 -0
- package/app/composables/useCustomerAddress/__tests__/useCustomerAddress.spec.ts +11 -0
- package/app/composables/useCustomerAddress/index.ts +2 -0
- package/app/composables/useCustomerAddress/types.ts +17 -0
- package/app/composables/useCustomerAddress/useCustomerAddress.ts +55 -0
- package/app/composables/useCustomerOrder/__tests__/useCustomerOrder.spec.ts +11 -0
- package/app/composables/useCustomerOrder/adress.ts +10 -0
- package/app/composables/useCustomerOrder/index.ts +2 -0
- package/app/composables/useCustomerOrder/product.ts +37 -0
- package/app/composables/useCustomerOrder/types.ts +40 -0
- package/app/composables/useCustomerOrder/useCustomerOrder.ts +63 -0
- package/app/composables/useCustomerOrders/__tests__/useCustomerOrders.spec.ts +11 -0
- package/app/composables/useCustomerOrders/index.ts +2 -0
- package/app/composables/useCustomerOrders/types.ts +20 -0
- package/app/composables/useCustomerOrders/useCustomerOrders.ts +56 -0
- package/app/composables/useCustomerReturns/__tests__/useCustomerReturns.spec.ts +11 -0
- package/app/composables/useCustomerReturns/index.ts +2 -0
- package/app/composables/useCustomerReturns/types.ts +17 -0
- package/app/composables/useCustomerReturns/useCustomerReturns.ts +41 -0
- package/app/composables/useHandleError/index.ts +1 -0
- package/app/composables/useHandleError/types.ts +11 -0
- package/app/composables/useHandleError/useHandleError.ts +27 -0
- package/app/composables/useInventory.ts +29 -0
- package/app/composables/useLoading.ts +21 -0
- package/app/composables/useNotification.ts +21 -0
- package/app/composables/usePageTitle.ts +20 -0
- package/app/composables/useProduct/index.ts +2 -0
- package/app/composables/useProduct/types.ts +17 -0
- package/app/composables/useProduct/useProduct.ts +42 -0
- package/app/composables/useProductAttribute/__tests__/useProduct.mock.ts +31 -0
- package/app/composables/useProductAttribute/__tests__/useProductAttribute.spec.ts +14 -0
- package/app/composables/useProductAttribute/index.ts +1 -0
- package/app/composables/useProductAttribute/useProductAttribute.ts +37 -0
- package/app/composables/useProductRecommended/__tests__/useProductRecommended.spec.ts +12 -0
- package/app/composables/useProductRecommended/index.ts +1 -0
- package/app/composables/useProductRecommended/types.ts +17 -0
- package/app/composables/useProductRecommended/useProductRecommended.ts +43 -0
- package/app/composables/useProductReviews/__tests__/productReviews.mock.ts +20 -0
- package/app/composables/useProductReviews/__tests__/useProductReviews.spec.ts +22 -0
- package/app/composables/useProductReviews/index.ts +2 -0
- package/app/composables/useProductReviews/types.ts +17 -0
- package/app/composables/useProductReviews/useProductReviews.ts +46 -0
- package/app/composables/useProducts/__tests__/useProducts.spec.ts +11 -0
- package/app/composables/useProducts/types.ts +22 -0
- package/app/composables/useProducts/useProducts.ts +41 -0
- package/app/composables/useTax.ts +27 -0
- package/app/composables/validationRules/index.ts +1 -0
- package/app/composables/validationRules/password.feature +67 -0
- package/app/composables/validationRules/password.test.ts +89 -0
- package/app/composables/validationRules/password.ts +25 -0
- package/app/normalizers/Cart.query.ts +729 -0
- package/app/normalizers/Cart.type.ts +285 -0
- package/app/normalizers/Category.query.ts +146 -0
- package/app/normalizers/Category.type.ts +55 -0
- package/app/normalizers/CheckEmail.query.ts +28 -0
- package/app/normalizers/Checkout.query.ts +253 -0
- package/app/normalizers/Checkout.type.ts +77 -0
- package/app/normalizers/CmsBlock.query.ts +57 -0
- package/app/normalizers/CmsBlock.type.ts +25 -0
- package/app/normalizers/CmsPage.query.ts +59 -0
- package/app/normalizers/CmsPage.type.ts +26 -0
- package/app/normalizers/Config.query.ts +224 -0
- package/app/normalizers/Config.type.ts +196 -0
- package/app/normalizers/ContactForm.query.ts +49 -0
- package/app/normalizers/CreditMemo.type.ts +49 -0
- package/app/normalizers/GiftCard.type.ts +24 -0
- package/app/normalizers/Invoice.type.ts +58 -0
- package/app/normalizers/Menu.query.ts +54 -0
- package/app/normalizers/Menu.type.ts +22 -0
- package/app/normalizers/MyAccount.query.ts +268 -0
- package/app/normalizers/MyAccount.type.ts +129 -0
- package/app/normalizers/NewsletterSubscription.query.ts +38 -0
- package/app/normalizers/Order.query.ts +741 -0
- package/app/normalizers/Order.type.ts +268 -0
- package/app/normalizers/Payment.type.ts +28 -0
- package/app/normalizers/ProductAlerts.query.ts +23 -0
- package/app/normalizers/ProductCompare.query.ts +226 -0
- package/app/normalizers/ProductCompare.type.ts +90 -0
- package/app/normalizers/ProductList.query.ts +1620 -0
- package/app/normalizers/ProductList.type.ts +726 -0
- package/app/normalizers/Region.query.ts +58 -0
- package/app/normalizers/Region.type.ts +23 -0
- package/app/normalizers/Return.type.ts +50 -0
- package/app/normalizers/Review.query.ts +81 -0
- package/app/normalizers/Review.type.ts +42 -0
- package/app/normalizers/Slider.query.ts +72 -0
- package/app/normalizers/Slider.type.ts +26 -0
- package/app/normalizers/StoreInPickUp.query.ts +54 -0
- package/app/normalizers/StoreInPickUp.type.ts +59 -0
- package/app/normalizers/Subscription.type.ts +25 -0
- package/app/normalizers/Transaction.type.ts +20 -0
- package/app/normalizers/UrlRewrites.query.ts +55 -0
- package/app/normalizers/UrlRewrites.type.ts +25 -0
- package/app/normalizers/Wishlist.query.ts +202 -0
- package/app/normalizers/Wishlist.type.ts +42 -0
- package/app/pages/brand/[...slug].vue +76 -0
- package/app/pages/brands.vue +67 -0
- package/app/pages/cart.vue +142 -0
- package/app/pages/compare.vue +166 -0
- package/app/pages/departments/[...slug].vue +353 -0
- package/app/pages/departments/category/[...slug].vue +114 -0
- package/app/pages/incentive/[...id].vue +66 -0
- package/app/pages/invoice/[id].vue +309 -0
- package/app/pages/order/[id].vue +327 -0
- package/app/pages/product/[...id].vue +309 -0
- package/app/pages/product/showcases/index.vue +86 -0
- package/app/pages/shipment/[...id].vue +176 -0
- package/app/pages/shop/[...slug].vue +158 -0
- package/app/pages/shops.vue +76 -0
- package/app/pages/subscription/[...id].vue +147 -0
- package/app/pages/transaction/[...id].vue +74 -0
- package/app/routes/CategoryPage/CategoryPage.config.ts +28 -0
- package/app/routes/CategoryPage/CategoryPage.type.ts +8 -0
- package/app/routes/Checkout/Checkout.config.ts +3 -0
- package/app/routes/Checkout/Checkout.type.ts +14 -0
- package/app/routes/MyAccount/MyAccount.config.ts +1 -0
- package/app/routes/SearchPage/SearchPage.config.ts +1 -0
- package/app/routes/UrlRewrites/UrlRewrites.config.ts +5 -0
- package/app/stores/Cart/Cart.type.ts +26 -0
- package/app/stores/MyAccount/MyAccount.action.ts +7 -0
- package/app/stores/Notification/Notification.action.ts +40 -0
- package/app/stores/Notification/Notification.type.ts +16 -0
- package/app/stores/Popup/Popup.action.ts +30 -0
- package/app/stores/Product/Product.dispatcher.ts +53 -0
- package/app/stores/Product/Product.reducer.ts +12 -0
- package/app/stores/ProductList/ProductList.dispatcher.ts +35 -0
- package/app/stores/ProductList/ProductList.reducer.ts +13 -0
- package/app/stores/Store.type.ts +31 -0
- package/app/stores/Wishlist/Wishlist.type.ts +12 -0
- package/app/stores/cart.ts +218 -0
- package/app/stores/cartStore.ts +224 -0
- package/app/stores/checkout.ts +18 -0
- package/app/stores/compare.ts +65 -0
- package/app/stores/currency.js +29 -0
- package/app/stores/digital-products.js +11 -0
- package/app/stores/orders.ts +172 -0
- package/app/stores/product.ts +34 -0
- package/app/stores/productList.ts +35 -0
- package/app/stores/productListInfo.ts +0 -0
- package/app/stores/products.ts +118 -0
- package/app/stores/recentlyViewedProducts.ts +56 -0
- package/app/stores/review.ts +33 -0
- package/app/stores/storeInPickUp.ts +21 -0
- package/app/stores/user.ts +20 -0
- package/app/stores/wishlist.ts +46 -0
- package/app/types/Account.type.ts +141 -0
- package/app/types/Breadcrumbs.type.ts +23 -0
- package/app/types/CMS.type.ts +33 -0
- package/app/types/Category.type.ts +67 -0
- package/app/types/Checkout.type.ts +58 -0
- package/app/types/Common.type.ts +77 -0
- package/app/types/Config.type.ts +47 -0
- package/app/types/Device.type.ts +37 -0
- package/app/types/Direction.type.ts +23 -0
- package/app/types/Downloadable.type.ts +24 -0
- package/app/types/Error.type.ts +22 -0
- package/app/types/Field.type.ts +151 -0
- package/app/types/Global.type.ts +156 -0
- package/app/types/Graphql.type.ts +4497 -0
- package/app/types/Layout.type.ts +18 -0
- package/app/types/Menu.type.ts +39 -0
- package/app/types/MiniCart.type.ts +61 -0
- package/app/types/NotificationList.type.ts +34 -0
- package/app/types/Order.type.ts +174 -0
- package/app/types/Price.type.ts +72 -0
- package/app/types/ProductCompare.type.ts +24 -0
- package/app/types/ProductList.type.ts +351 -0
- package/app/types/Rating.type.ts +42 -0
- package/app/types/Router.type.ts +67 -0
- package/app/types/Slider.type.ts +25 -0
- package/app/types/StockStatus.type.ts +21 -0
- package/app/types/domain/index.ts +94 -0
- package/app/types/index.ts +33 -0
- package/app/types/shims.d.ts +52 -0
- package/app/types/tilework-opus.d.ts +48 -0
- package/app/utils/Address/Address.type.ts +28 -0
- package/app/utils/Address/index.ts +325 -0
- package/app/utils/Auth/IsSignedIn.ts +4 -0
- package/app/utils/Auth/Token.ts +9 -0
- package/app/utils/Base64/Base64.ts +16 -0
- package/app/utils/Base64/index.ts +12 -0
- package/app/utils/Browser/Browser.ts +29 -0
- package/app/utils/Browser/index.ts +12 -0
- package/app/utils/BrowserDatabase/BrowserDatabase.ts +70 -0
- package/app/utils/BrowserDatabase/index.ts +12 -0
- package/app/utils/CSS/CSS.ts +65 -0
- package/app/utils/CSS/index.ts +12 -0
- package/app/utils/Cache/Cache.ts +99 -0
- package/app/utils/Cart/Cart.ts +300 -0
- package/app/utils/Cart/Cart.type.ts +76 -0
- package/app/utils/Cart/Token.ts +59 -0
- package/app/utils/Cart/index.ts +13 -0
- package/app/utils/Category/Filters.ts +39 -0
- package/app/utils/Category/index.ts +12 -0
- package/app/utils/Common/index.ts +32 -0
- package/app/utils/Compare/Compare.ts +89 -0
- package/app/utils/Compare/index.ts +12 -0
- package/app/utils/Currency/Currency.ts +84 -0
- package/app/utils/Currency/index.ts +12 -0
- package/app/utils/DynamicReducer/DynamicReducer.type.ts +14 -0
- package/app/utils/DynamicReducer/Helper.ts +30 -0
- package/app/utils/DynamicReducer/index.tsx +35 -0
- package/app/utils/ElementTransition/ElementTransition.ts +100 -0
- package/app/utils/Form/Extract.ts +316 -0
- package/app/utils/Form/Form.ts +46 -0
- package/app/utils/Form/Form.type.ts +60 -0
- package/app/utils/Form/Transform.ts +33 -0
- package/app/utils/FormPortalCollector/index.ts +45 -0
- package/app/utils/History/History.type.ts +31 -0
- package/app/utils/History/index.ts +17 -0
- package/app/utils/Manipulations/Array.ts +18 -0
- package/app/utils/Manipulations/Date.ts +36 -0
- package/app/utils/Manipulations/index.ts +14 -0
- package/app/utils/Media/Media.ts +27 -0
- package/app/utils/Media/index.ts +13 -0
- package/app/utils/Menu/Menu.ts +116 -0
- package/app/utils/Menu/Menu.type.ts +37 -0
- package/app/utils/Menu/index.ts +12 -0
- package/app/utils/Mobile/index.ts +13 -0
- package/app/utils/Mobile/isMobile.ts +34 -0
- package/app/utils/Orders/Orders.ts +71 -0
- package/app/utils/Orders/Orders.type.ts +19 -0
- package/app/utils/Orders/index.ts +13 -0
- package/app/utils/Polyfill/index.ts +336 -0
- package/app/utils/Preload/CategoryPreload.ts +74 -0
- package/app/utils/Preload/ProductPreload.ts +28 -0
- package/app/utils/Preload/index.ts +75 -0
- package/app/utils/Price/Price.config.ts +189 -0
- package/app/utils/Price/Price.ts +63 -0
- package/app/utils/Price/index.ts +12 -0
- package/app/utils/Product/Extract.ts +652 -0
- package/app/utils/Product/Product.ts +575 -0
- package/app/utils/Product/Product.type.ts +260 -0
- package/app/utils/Product/Transform.ts +382 -0
- package/app/utils/Product/index.ts +12 -0
- package/app/utils/Promise/MakeCancelable.ts +44 -0
- package/app/utils/Promise/Promise.type.ts +15 -0
- package/app/utils/Promise/index.ts +13 -0
- package/app/utils/Query/Field.ts +71 -0
- package/app/utils/Query/Fragment.ts +22 -0
- package/app/utils/Query/PrepareDocument.ts +119 -0
- package/app/utils/Query/Query.type.ts +26 -0
- package/app/utils/Query/index.ts +15 -0
- package/app/utils/Request/Config.ts +21 -0
- package/app/utils/Request/DataContainer.ts +102 -0
- package/app/utils/Request/Debounce.ts +48 -0
- package/app/utils/Request/Error.ts +31 -0
- package/app/utils/Request/Hash.ts +88 -0
- package/app/utils/Request/LowPriorityLoad.ts +32 -0
- package/app/utils/Request/LowPriorityRender.ts +55 -0
- package/app/utils/Request/Mutation.ts +25 -0
- package/app/utils/Request/Query.ts +25 -0
- package/app/utils/Request/QueryDispatcher.ts +135 -0
- package/app/utils/Request/Request.ts +310 -0
- package/app/utils/Store/Store.type.ts +26 -0
- package/app/utils/Store/index.ts +71 -0
- package/app/utils/Url/Url.ts +297 -0
- package/app/utils/Url/index.ts +12 -0
- package/app/utils/Validator/Config.ts +96 -0
- package/app/utils/Validator/Validator.ts +268 -0
- package/app/utils/Validator/Validator.type.ts +47 -0
- package/app/utils/Validator/index.ts +12 -0
- package/app/utils/Wishlist/Wishlist.ts +65 -0
- package/app/utils/Wishlist/index.ts +12 -0
- package/app/utils/client.ts +280 -0
- package/app/utils/index.ts +53 -0
- package/app/utils/normalizer.ts +23 -0
- package/app/utils/normalizers/magento.ts +29 -0
- package/app/utils/normalizers/shopify.ts +29 -0
- package/nuxt.config.ts +11 -0
- package/package.json +43 -0
- package/tsconfig.json +45 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import type { DefineStepFunction } from "jest-cucumber";
|
|
3
|
+
import { defineFeature, loadFeature } from "jest-cucumber";
|
|
4
|
+
import { beforeEach, expect } from "vitest";
|
|
5
|
+
import { unifiedExtensionFactory } from "./extension";
|
|
6
|
+
import {
|
|
7
|
+
getAdditionalNormalizerContext,
|
|
8
|
+
methods,
|
|
9
|
+
normalizers,
|
|
10
|
+
rawMoneyMock,
|
|
11
|
+
} from "./extension.mocks";
|
|
12
|
+
import type { DefineAddCustomFields } from "./types";
|
|
13
|
+
|
|
14
|
+
const feature = loadFeature("./extension.feature", {
|
|
15
|
+
loadRelativePath: true,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
defineFeature(feature, (test) => {
|
|
19
|
+
let overrideNormalizers: Partial<typeof normalizers>;
|
|
20
|
+
let addCustomFields: [
|
|
21
|
+
DefineAddCustomFields<typeof normalizers>,
|
|
22
|
+
...DefineAddCustomFields<typeof normalizers>[],
|
|
23
|
+
];
|
|
24
|
+
let overrideApiMethods: Partial<typeof methods>;
|
|
25
|
+
const createUnifiedExtension = unifiedExtensionFactory<typeof methods, typeof normalizers, any>({
|
|
26
|
+
normalizers,
|
|
27
|
+
extendApiMethods: methods,
|
|
28
|
+
getAdditionalNormalizerContext,
|
|
29
|
+
});
|
|
30
|
+
let extension: ReturnType<typeof createUnifiedExtension>;
|
|
31
|
+
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
overrideNormalizers = {};
|
|
34
|
+
addCustomFields = [{}];
|
|
35
|
+
overrideApiMethods = {};
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
function whenTheExtensionIsCreated(when: DefineStepFunction) {
|
|
39
|
+
when("extension is created", () => {
|
|
40
|
+
extension = createUnifiedExtension({
|
|
41
|
+
normalizers: {
|
|
42
|
+
override: overrideNormalizers,
|
|
43
|
+
addCustomFields,
|
|
44
|
+
},
|
|
45
|
+
methods: {
|
|
46
|
+
override: overrideApiMethods,
|
|
47
|
+
},
|
|
48
|
+
config: {},
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
test("Overriding normalizer", ({ given, when, and, then }) => {
|
|
54
|
+
let result: any;
|
|
55
|
+
|
|
56
|
+
given("one of the normalizers is overridden", () => {
|
|
57
|
+
overrideNormalizers = {
|
|
58
|
+
normalizeMoney(rawMoney) {
|
|
59
|
+
return {
|
|
60
|
+
amount: rawMoney.amount,
|
|
61
|
+
currency: "USD",
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
whenTheExtensionIsCreated(when);
|
|
68
|
+
|
|
69
|
+
and("the normalizer is called", () => {
|
|
70
|
+
result = extension.normalizers.normalizeMoney(rawMoneyMock, { currency: "PLN" });
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
then("the overridden normalizer should be called", () => {
|
|
74
|
+
expect(result).toMatchInlineSnapshot(`
|
|
75
|
+
{
|
|
76
|
+
"amount": 10,
|
|
77
|
+
"currency": "USD",
|
|
78
|
+
}
|
|
79
|
+
`);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
and("remaining normalizers should be unchanged", () => {
|
|
83
|
+
expect(extension.normalizers.normalizeProductCatalogItem).toBeDefined();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
test("Add custom fields array with a single element", ({ given, when, and, then }) => {
|
|
87
|
+
let result: any;
|
|
88
|
+
|
|
89
|
+
given("a custom field is added to one of the normalizers", () => {
|
|
90
|
+
addCustomFields = [
|
|
91
|
+
{
|
|
92
|
+
normalizeMoney: ({ formattedAmount }) => ({
|
|
93
|
+
formattedAmount,
|
|
94
|
+
}),
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
whenTheExtensionIsCreated(when);
|
|
100
|
+
|
|
101
|
+
and("the normalizer is called", () => {
|
|
102
|
+
result = extension.normalizers.normalizeMoney(rawMoneyMock, { currency: "PLN" });
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
then("the custom field should be present in the $custom object", () => {
|
|
106
|
+
expect(result).toMatchInlineSnapshot(`
|
|
107
|
+
{
|
|
108
|
+
"$custom": {
|
|
109
|
+
"formattedAmount": "10.00",
|
|
110
|
+
},
|
|
111
|
+
"amount": 10,
|
|
112
|
+
"currency": "PLN",
|
|
113
|
+
}
|
|
114
|
+
`);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
and("remaining normalizers should be unchanged", () => {
|
|
118
|
+
expect(extension.normalizers.normalizeProductCatalogItem).toBeDefined();
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
test("Add custom fields array with multiple elements", ({ given, when, and, then }) => {
|
|
122
|
+
given("multiple elements of the addCustomFields array override the same normalizer", () => {
|
|
123
|
+
addCustomFields = [
|
|
124
|
+
{
|
|
125
|
+
normalizeMoney: ({ formattedAmount }) => ({
|
|
126
|
+
formattedAmount,
|
|
127
|
+
}),
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
normalizeMoney: ({ decimalPlaces }) => ({
|
|
131
|
+
decimalPlaces,
|
|
132
|
+
}),
|
|
133
|
+
},
|
|
134
|
+
];
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
whenTheExtensionIsCreated(when);
|
|
138
|
+
|
|
139
|
+
and("the normalizer is called", () => {
|
|
140
|
+
extension.normalizers.normalizeMoney(rawMoneyMock, { currency: "PLN" });
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
then("all custom fields should be present in the $custom object", () => {
|
|
144
|
+
expect(extension.normalizers.normalizeMoney(rawMoneyMock, { currency: "PLN" }))
|
|
145
|
+
.toMatchInlineSnapshot(`
|
|
146
|
+
{
|
|
147
|
+
"$custom": {
|
|
148
|
+
"decimalPlaces": 2,
|
|
149
|
+
"formattedAmount": "10.00",
|
|
150
|
+
},
|
|
151
|
+
"amount": 10,
|
|
152
|
+
"currency": "PLN",
|
|
153
|
+
}
|
|
154
|
+
`);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
test("Nested custom fields", ({ given, and, when, then }) => {
|
|
158
|
+
let result: any;
|
|
159
|
+
|
|
160
|
+
given("multiple elements of the addCustomFields array override the same normalizer", () => {
|
|
161
|
+
addCustomFields = [
|
|
162
|
+
{
|
|
163
|
+
normalizeMoney: () => ({
|
|
164
|
+
nested: {
|
|
165
|
+
nested_field1: "value1",
|
|
166
|
+
nestedLvl2: {
|
|
167
|
+
nestedLvl2_field1: "value1",
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
}),
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
normalizeMoney: () => ({
|
|
174
|
+
nested: {
|
|
175
|
+
nested_field2: "value2",
|
|
176
|
+
},
|
|
177
|
+
nested2: {
|
|
178
|
+
nested2_field1: "value3",
|
|
179
|
+
},
|
|
180
|
+
}),
|
|
181
|
+
},
|
|
182
|
+
];
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
and("custom fields are objects", () => {});
|
|
186
|
+
|
|
187
|
+
whenTheExtensionIsCreated(when);
|
|
188
|
+
|
|
189
|
+
and("the normalizer is called", () => {
|
|
190
|
+
result = extension.normalizers.normalizeMoney(rawMoneyMock, { currency: "PLN" });
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
then("objects should be merged into the $custom object", () => {
|
|
194
|
+
expect(result).toMatchInlineSnapshot(`
|
|
195
|
+
{
|
|
196
|
+
"$custom": {
|
|
197
|
+
"nested": {
|
|
198
|
+
"nestedLvl2": {
|
|
199
|
+
"nestedLvl2_field1": "value1",
|
|
200
|
+
},
|
|
201
|
+
"nested_field1": "value1",
|
|
202
|
+
"nested_field2": "value2",
|
|
203
|
+
},
|
|
204
|
+
"nested2": {
|
|
205
|
+
"nested2_field1": "value3",
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
"amount": 10,
|
|
209
|
+
"currency": "PLN",
|
|
210
|
+
}
|
|
211
|
+
`);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
test("Adding the same custom fields more than once", ({ given, when, and, then }) => {
|
|
216
|
+
let result: any;
|
|
217
|
+
|
|
218
|
+
given("multiple elements of the addCustomFields array add the same custom field", () => {
|
|
219
|
+
addCustomFields = [
|
|
220
|
+
{
|
|
221
|
+
normalizeMoney: ({ formattedAmount, decimalPlaces }) => ({
|
|
222
|
+
formattedAmount,
|
|
223
|
+
decimalPlaces,
|
|
224
|
+
}),
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
normalizeMoney: () => ({
|
|
228
|
+
formattedAmount: "overridden",
|
|
229
|
+
}),
|
|
230
|
+
},
|
|
231
|
+
];
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
whenTheExtensionIsCreated(when);
|
|
235
|
+
|
|
236
|
+
and("the normalizer is called", () => {
|
|
237
|
+
result = extension.normalizers.normalizeMoney(rawMoneyMock, { currency: "PLN" });
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
then(
|
|
241
|
+
"the custom field should have value based on the last element of the addCustomFields array",
|
|
242
|
+
() => {
|
|
243
|
+
expect(result).toMatchInlineSnapshot(`
|
|
244
|
+
{
|
|
245
|
+
"$custom": {
|
|
246
|
+
"decimalPlaces": 2,
|
|
247
|
+
"formattedAmount": "overridden",
|
|
248
|
+
},
|
|
249
|
+
"amount": 10,
|
|
250
|
+
"currency": "PLN",
|
|
251
|
+
}
|
|
252
|
+
`);
|
|
253
|
+
},
|
|
254
|
+
);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
test("Overriding api method", ({ given, when, and, then }) => {
|
|
258
|
+
let result: any;
|
|
259
|
+
|
|
260
|
+
given("one of the api methods is overridden", () => {
|
|
261
|
+
overrideApiMethods = {
|
|
262
|
+
getSuccess: () => Promise.resolve({ ok: false }),
|
|
263
|
+
};
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
whenTheExtensionIsCreated(when);
|
|
267
|
+
|
|
268
|
+
and("the api method is called", async () => {
|
|
269
|
+
result = await extension.extendApiMethods.getSuccess();
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
then("the overridden api method should be called", () => {
|
|
273
|
+
expect(result).toMatchInlineSnapshot(`
|
|
274
|
+
{
|
|
275
|
+
"ok": false,
|
|
276
|
+
}
|
|
277
|
+
`);
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
});
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
type ApiMethods = Record<string, (...args: any[]) => any>;
|
|
3
|
+
|
|
4
|
+
interface ApiClientExtension {
|
|
5
|
+
name: string;
|
|
6
|
+
extendApiMethods?: Record<string, (...args: any[]) => any>;
|
|
7
|
+
hooks?: (req: any, res: any) => any;
|
|
8
|
+
isNamespaced?: boolean;
|
|
9
|
+
}
|
|
10
|
+
import { mergeDeepRight } from "ramda";
|
|
11
|
+
import { toContextualizedNormalizers } from "../helpers";
|
|
12
|
+
const Logger: any = console;
|
|
13
|
+
import type {
|
|
14
|
+
BaseNormalizerContext,
|
|
15
|
+
CreateUnifiedExtensionParams,
|
|
16
|
+
DefineAddCustomFields,
|
|
17
|
+
GetAdditionalNormalizerContextConstraint,
|
|
18
|
+
GetAdditionalNormalizerContextParams,
|
|
19
|
+
NormalizersConstraint,
|
|
20
|
+
UnifiedCmsConfig,
|
|
21
|
+
UnifiedConfig,
|
|
22
|
+
UnifiedExtensionContextConstraint,
|
|
23
|
+
UnifiedExtensionFactoryParams,
|
|
24
|
+
} from "./types";
|
|
25
|
+
|
|
26
|
+
const CURRENCY_COOKIE = "vsf-currency";
|
|
27
|
+
const LOCALE_COOKIE = "vsf-locale";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @description A factory function which builds the default normalizers and default API methods into unified extension.
|
|
31
|
+
* It expects the type of the API methods, normalizers, and config as generics.
|
|
32
|
+
*
|
|
33
|
+
* @returns A `createUnifiedExtension` function which can be used by the user to create a unified extension.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* export const createUnifiedExtension = unifiedExtensionFactory<
|
|
38
|
+
* typeof apiMethods,
|
|
39
|
+
* Normalizers,
|
|
40
|
+
* Config
|
|
41
|
+
* >({
|
|
42
|
+
* extendApiMethods: apiMethods,
|
|
43
|
+
* normalizers,
|
|
44
|
+
* });
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export function unifiedExtensionFactory<
|
|
48
|
+
TApiMethods extends ApiMethods,
|
|
49
|
+
TNormalizers extends NormalizersConstraint,
|
|
50
|
+
TConfig extends UnifiedConfig,
|
|
51
|
+
>(factoryParams: UnifiedExtensionFactoryParams<TApiMethods, TNormalizers>) {
|
|
52
|
+
return function createUnifiedExtension<
|
|
53
|
+
TAddCustomFieldsArray extends [
|
|
54
|
+
DefineAddCustomFields<TNormalizers>,
|
|
55
|
+
...DefineAddCustomFields<TNormalizers>[],
|
|
56
|
+
],
|
|
57
|
+
>(
|
|
58
|
+
params: CreateUnifiedExtensionParams<TConfig, TApiMethods, TNormalizers, TAddCustomFieldsArray>,
|
|
59
|
+
) {
|
|
60
|
+
const {
|
|
61
|
+
extendApiMethods: defaultApiMethods,
|
|
62
|
+
normalizers: defaultNormalizers,
|
|
63
|
+
getAdditionalNormalizerContext,
|
|
64
|
+
} = factoryParams;
|
|
65
|
+
const baseNormalizers = { ...defaultNormalizers, ...params.normalizers.override };
|
|
66
|
+
const normalizers = mergeNormalizers(baseNormalizers, params.normalizers.addCustomFields);
|
|
67
|
+
const { config: extensionConfig, methods, isNamespaced = factoryParams.isNamespaced } = params;
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
name: "unified",
|
|
71
|
+
extendApiMethods: {
|
|
72
|
+
...defaultApiMethods,
|
|
73
|
+
...methods?.override,
|
|
74
|
+
} as TApiMethods,
|
|
75
|
+
hooks(req: any, res: any) {
|
|
76
|
+
return {
|
|
77
|
+
beforeCall({ args, configuration }: { args: any; configuration: any }) {
|
|
78
|
+
if (!req.cookies[CURRENCY_COOKIE] && extensionConfig) {
|
|
79
|
+
req.cookies[CURRENCY_COOKIE] = extensionConfig.defaultCurrency;
|
|
80
|
+
}
|
|
81
|
+
configuration.unified = extensionConfig;
|
|
82
|
+
if (!configuration.normalizerContext) {
|
|
83
|
+
configuration.normalizerContext = createNormalizerContext(
|
|
84
|
+
normalizers,
|
|
85
|
+
getAdditionalNormalizerContext,
|
|
86
|
+
{ req, res, config: configuration },
|
|
87
|
+
);
|
|
88
|
+
configuration.normalizerContext.currency =
|
|
89
|
+
req.cookies?.[CURRENCY_COOKIE] ?? extensionConfig.defaultCurrency ?? "USD";
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return args;
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
},
|
|
96
|
+
isNamespaced,
|
|
97
|
+
normalizers,
|
|
98
|
+
/**
|
|
99
|
+
* @internal You shouldn't use this field. It's present only to infer the type of addCustomFields
|
|
100
|
+
*/
|
|
101
|
+
_addCustomFields: {} as TAddCustomFieldsArray,
|
|
102
|
+
} satisfies ApiClientExtension & Record<string, any>;
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @description A factory function which builds the default normalizers and default API methods into unified extension.
|
|
108
|
+
* It expects the type of the API methods, normalizers, and config as generics.
|
|
109
|
+
*
|
|
110
|
+
* @returns A Middleware extension which can be registered in the API client.
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```ts
|
|
114
|
+
* export const createUnifiedExtension = createUnifiedCmsExtension({
|
|
115
|
+
* extendApiMethods: {
|
|
116
|
+
* getPage,
|
|
117
|
+
* },
|
|
118
|
+
* normalizers,
|
|
119
|
+
* getAdditionalNormalizerContext: () => ({
|
|
120
|
+
* documentToHtmlString,
|
|
121
|
+
* }),
|
|
122
|
+
* });
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
export function createUnifiedCmsExtension<
|
|
126
|
+
TApiMethods extends ApiMethods,
|
|
127
|
+
TNormalizers extends NormalizersConstraint,
|
|
128
|
+
>(params: UnifiedExtensionFactoryParams<TApiMethods, TNormalizers>) {
|
|
129
|
+
const {
|
|
130
|
+
extendApiMethods,
|
|
131
|
+
normalizers: defaultNormalizers,
|
|
132
|
+
getAdditionalNormalizerContext,
|
|
133
|
+
isNamespaced = true,
|
|
134
|
+
} = params;
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
name: "unified",
|
|
138
|
+
extendApiMethods,
|
|
139
|
+
isNamespaced,
|
|
140
|
+
hooks(req: any, res: any) {
|
|
141
|
+
return {
|
|
142
|
+
beforeCall({ args, configuration }: { args: any; configuration: any }) {
|
|
143
|
+
if (!configuration.normalizerContext) {
|
|
144
|
+
const unifiedConfig = configuration?.unified ?? ({} as UnifiedCmsConfig<TNormalizers>);
|
|
145
|
+
const baseNormalizers = {
|
|
146
|
+
...defaultNormalizers,
|
|
147
|
+
...unifiedConfig.normalizers?.override,
|
|
148
|
+
};
|
|
149
|
+
const normalizers = mergeNormalizers(
|
|
150
|
+
baseNormalizers,
|
|
151
|
+
unifiedConfig.normalizers?.addCustomFields ?? [],
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
configuration.normalizerContext = createNormalizerContext(
|
|
155
|
+
normalizers,
|
|
156
|
+
getAdditionalNormalizerContext,
|
|
157
|
+
{ req, res, config: configuration },
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
return args;
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
},
|
|
164
|
+
} satisfies ApiClientExtension;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* A helper function to get the normalizers from the context.
|
|
169
|
+
* @param context Context passed to the API method
|
|
170
|
+
* @returns normalizers
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* const { normalizeProduct } = getNormalizers(context);
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
export function getNormalizers<TContext extends UnifiedExtensionContextConstraint>(
|
|
178
|
+
context: TContext,
|
|
179
|
+
): TContext["config"]["normalizerContext"]["normalizers"] {
|
|
180
|
+
return context.config.normalizerContext.normalizers;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* A helper function to assign values to the normalizer context.
|
|
185
|
+
* @param context Context passed to the API method
|
|
186
|
+
* @param overrides Object with the values to override in the normalizer context
|
|
187
|
+
* @returns void - it mutates the context
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```ts
|
|
191
|
+
* assignToNormalizerContext(context, { locale: "de" });
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
export function assignToNormalizerContext<TContext extends UnifiedExtensionContextConstraint>(
|
|
195
|
+
context: TContext,
|
|
196
|
+
overrides: Partial<TContext["config"]["normalizerContext"]>,
|
|
197
|
+
) {
|
|
198
|
+
Object.assign(context.config.normalizerContext, overrides);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function createNormalizerContext<TNormalizers extends NormalizersConstraint>(
|
|
202
|
+
normalizers: TNormalizers,
|
|
203
|
+
getAdditionalNormalizerContext: GetAdditionalNormalizerContextConstraint,
|
|
204
|
+
{ req, res, config }: GetAdditionalNormalizerContextParams,
|
|
205
|
+
) {
|
|
206
|
+
const logger = Logger;
|
|
207
|
+
const normalizerContext: BaseNormalizerContext<TNormalizers> = {
|
|
208
|
+
locale: req.cookies?.[LOCALE_COOKIE] ?? "en",
|
|
209
|
+
...getAdditionalNormalizerContext({ req, res, config }),
|
|
210
|
+
logger,
|
|
211
|
+
};
|
|
212
|
+
normalizerContext.normalizers = toContextualizedNormalizers(normalizers, () => normalizerContext);
|
|
213
|
+
|
|
214
|
+
return normalizerContext;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export function mergeNormalizers<TNormalizers extends NormalizersConstraint>(
|
|
218
|
+
baseNormalizers: TNormalizers,
|
|
219
|
+
addCustomFields: DefineAddCustomFields<TNormalizers>[],
|
|
220
|
+
): TNormalizers {
|
|
221
|
+
const normalizers: any = { ...baseNormalizers };
|
|
222
|
+
|
|
223
|
+
addCustomFields.forEach((customFieldsNormalizers) => {
|
|
224
|
+
Object.entries(customFieldsNormalizers).forEach(([name, customFields]) => {
|
|
225
|
+
const currentNormalizer = normalizers[name]!;
|
|
226
|
+
if (normalizers[name] && customFields) {
|
|
227
|
+
normalizers[name] = (input: any, context: any) =>
|
|
228
|
+
mergeDeepRight(currentNormalizer(input, context), {
|
|
229
|
+
$custom: customFields(input, context),
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
return normalizers;
|
|
236
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
/* eslint-disable no-use-before-define */
|
|
3
|
+
type ApiMethods = Record<string, (...args: any[]) => any>;
|
|
4
|
+
import type { MergeDeep } from './typeHelpers';
|
|
5
|
+
import type { ContextualizedNormalizers } from "../helpers";
|
|
6
|
+
import type { Maybe, SfCurrency, SfFacetType } from "../models";
|
|
7
|
+
|
|
8
|
+
// Minimal local IntegrationContext replacement
|
|
9
|
+
export interface IntegrationContext<CLIENT = any, CONFIG = any, API = any> {
|
|
10
|
+
client: CLIENT;
|
|
11
|
+
config: CONFIG;
|
|
12
|
+
api: API;
|
|
13
|
+
req?: any;
|
|
14
|
+
res?: any;
|
|
15
|
+
[x: string]: any;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface VSFLogger {
|
|
19
|
+
debug(message?: any, ...args: any[]): void;
|
|
20
|
+
info(message?: any, ...args: any[]): void;
|
|
21
|
+
warn(message?: any, ...args: any[]): void;
|
|
22
|
+
error(message?: any, ...args: any[]): void;
|
|
23
|
+
}
|
|
24
|
+
export interface UnifiedConfig {
|
|
25
|
+
currencies?: SfCurrency[];
|
|
26
|
+
defaultCurrency: SfCurrency;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface BaseNormalizerContext<TNormalizers extends NormalizersConstraint = any> {
|
|
30
|
+
locale: string;
|
|
31
|
+
currency: string;
|
|
32
|
+
normalizers: ContextualizedNormalizers<TNormalizers>;
|
|
33
|
+
logger: VSFLogger;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type NormalizerConstraint<
|
|
37
|
+
TNormalizerContext extends BaseNormalizerContext = BaseNormalizerContext,
|
|
38
|
+
> = (rawData: any, context: TNormalizerContext) => any;
|
|
39
|
+
|
|
40
|
+
export type NormalizersConstraint<TNormalizerContext extends BaseNormalizerContext = any> = Record<
|
|
41
|
+
string,
|
|
42
|
+
NormalizerConstraint<TNormalizerContext>
|
|
43
|
+
>;
|
|
44
|
+
|
|
45
|
+
export type UnifiedExtensionContextConstraint<
|
|
46
|
+
TNormalizerContext extends BaseNormalizerContext = any,
|
|
47
|
+
> = IntegrationContext & { config: { normalizerContext: TNormalizerContext } };
|
|
48
|
+
|
|
49
|
+
export type GetFacetTypeFn<TInput> = (input: TInput) => Maybe<SfFacetType | string>;
|
|
50
|
+
export type FilterFacetsFn<TInput> = (input: TInput) => boolean;
|
|
51
|
+
|
|
52
|
+
export type GetAdditionalNormalizerContextParams<TConfig extends Record<string, any> = any> = {
|
|
53
|
+
req: IntegrationContext["req"];
|
|
54
|
+
res: IntegrationContext["res"];
|
|
55
|
+
config: TConfig;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export type GetAdditionalNormalizerContextConstraint = (
|
|
59
|
+
params: GetAdditionalNormalizerContextParams,
|
|
60
|
+
) => any;
|
|
61
|
+
|
|
62
|
+
export type GetAdditionalNormalizerContext<
|
|
63
|
+
TIntegrationContext extends IntegrationContext,
|
|
64
|
+
TNormalizerContext extends BaseNormalizerContext,
|
|
65
|
+
> = (
|
|
66
|
+
params: GetAdditionalNormalizerContextParams<TIntegrationContext["config"]>,
|
|
67
|
+
) => Omit<TNormalizerContext, keyof BaseNormalizerContext>;
|
|
68
|
+
|
|
69
|
+
export interface AddCustomFields {}
|
|
70
|
+
|
|
71
|
+
export type InferAddCustomFieldsFromArray<
|
|
72
|
+
TArray extends Record<string, (...args: any) => any>[],
|
|
73
|
+
TResult = {},
|
|
74
|
+
> = TArray extends [
|
|
75
|
+
infer THead extends Record<string, (...args: any) => any>,
|
|
76
|
+
...infer TTail extends Record<string, (...args: any) => any>[],
|
|
77
|
+
]
|
|
78
|
+
? InferAddCustomFieldsFromArray<
|
|
79
|
+
TTail,
|
|
80
|
+
MergeDeep<
|
|
81
|
+
TResult,
|
|
82
|
+
{
|
|
83
|
+
[TKey in keyof THead]: Exclude<ReturnType<THead[TKey]>, null | undefined>;
|
|
84
|
+
}
|
|
85
|
+
>
|
|
86
|
+
>
|
|
87
|
+
: TResult;
|
|
88
|
+
|
|
89
|
+
export type InferAddCustomFields<TUnifiedExtension extends { _addCustomFields: any }> =
|
|
90
|
+
InferAddCustomFieldsFromArray<TUnifiedExtension["_addCustomFields"]>;
|
|
91
|
+
|
|
92
|
+
export type InferCustom<TNormalizer extends string> =
|
|
93
|
+
AddCustomFields extends Record<TNormalizer, infer TCustom> ? TCustom : object;
|
|
94
|
+
|
|
95
|
+
export type DefineAddCustomFields<TNormalizers extends NormalizersConstraint> = {
|
|
96
|
+
[Key in keyof TNormalizers]?: (...args: Parameters<TNormalizers[Key]>) => any;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export interface NormalizersConfig<
|
|
100
|
+
TNormalizers extends NormalizersConstraint,
|
|
101
|
+
TAddCustomFieldsArray,
|
|
102
|
+
> {
|
|
103
|
+
override?: Partial<TNormalizers>;
|
|
104
|
+
addCustomFields: TAddCustomFieldsArray;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface UnifiedExtensionFactoryParams<
|
|
108
|
+
TApiMethods extends ApiMethods,
|
|
109
|
+
TNormalizers extends NormalizersConstraint,
|
|
110
|
+
> {
|
|
111
|
+
normalizers: TNormalizers;
|
|
112
|
+
extendApiMethods: TApiMethods;
|
|
113
|
+
getAdditionalNormalizerContext: GetAdditionalNormalizerContextConstraint;
|
|
114
|
+
isNamespaced?: boolean;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface CreateUnifiedExtensionParams<
|
|
118
|
+
TConfig extends Record<string, any>,
|
|
119
|
+
TApiMethods extends ApiMethods,
|
|
120
|
+
TNormalizers extends NormalizersConstraint,
|
|
121
|
+
TAddCustomFieldsArray extends DefineAddCustomFields<TNormalizers>[],
|
|
122
|
+
> {
|
|
123
|
+
config: TConfig;
|
|
124
|
+
normalizers: NormalizersConfig<TNormalizers, TAddCustomFieldsArray>;
|
|
125
|
+
methods?: {
|
|
126
|
+
override?: Partial<TApiMethods>;
|
|
127
|
+
};
|
|
128
|
+
isNamespaced?: boolean;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface UnifiedCmsConfig<
|
|
132
|
+
TNormalizers extends NormalizersConstraint,
|
|
133
|
+
TAddCustomFieldsArray = DefineAddCustomFields<TNormalizers>[],
|
|
134
|
+
> {
|
|
135
|
+
normalizers?: NormalizersConfig<TNormalizers, TAddCustomFieldsArray>;
|
|
136
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useProducts } from './useProducts/useProducts'
|
|
2
|
+
|
|
3
|
+
export function useFeaturedProducts() {
|
|
4
|
+
const { fetchProducts } = useProducts()
|
|
5
|
+
return {
|
|
6
|
+
async getFeaturedProducts(options: any = {}) {
|
|
7
|
+
const items = await fetchProducts()
|
|
8
|
+
// If fetchProducts returns a ref/computed, attempt to unwrap
|
|
9
|
+
// and filter by a common `featured` flag if present
|
|
10
|
+
try {
|
|
11
|
+
const list = (items as any)?.value ?? items
|
|
12
|
+
return (Array.isArray(list) ? list.filter((p: any) => p.featured || p.is_featured || p.isFeatured) : []) as any[]
|
|
13
|
+
} catch (e) {
|
|
14
|
+
return []
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default useFeaturedProducts
|