@envive-ai/react-hooks 0.1.0
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/LICENSE +2 -0
- package/README.md +2 -0
- package/dist/GridInsertionService-CEYo9pGj.js +22 -0
- package/dist/GridInsertionService-CS_bnPh0.cjs +28 -0
- package/dist/bandolier-Ble8jEa8.js +1221 -0
- package/dist/bandolier-Bm2xAt_j.cjs +1221 -0
- package/dist/carpe-Da7b-LCW.cjs +599 -0
- package/dist/carpe-W13mhRRP.js +597 -0
- package/dist/cdnService-CZ-aXcY6.cjs +23 -0
- package/dist/cdnService-zQfKk3Eb.js +18 -0
- package/dist/chatElementDisplayLocation-CX8fuNao.d.cts +239 -0
- package/dist/chatElementDisplayLocation-CwptS9tx.d.ts +239 -0
- package/dist/chunk-CUT6urMc.cjs +30 -0
- package/dist/contexts/index.cjs +13 -0
- package/dist/contexts/index.d.cts +65 -0
- package/dist/contexts/index.d.ts +66 -0
- package/dist/contexts/index.js +7 -0
- package/dist/contexts-BRjfVq_k.js +5064 -0
- package/dist/contexts-BYArqZtK.cjs +5164 -0
- package/dist/coterie-3y0D9ko4.cjs +229 -0
- package/dist/coterie-DOWcJAYv.js +229 -0
- package/dist/custservice-types-CFIFwZ-r.js +10 -0
- package/dist/custservice-types-CkfxZiHY.cjs +16 -0
- package/dist/default-C2fEZKXk.js +175 -0
- package/dist/default-CBUq6Q6G.cjs +4 -0
- package/dist/default-CGIFZK6m.js +4 -0
- package/dist/default-D_KPZdPJ.cjs +198 -0
- package/dist/divIds-Bss-btao.js +49 -0
- package/dist/divIds-DnZNd7rA.cjs +223 -0
- package/dist/dreamlandBaby-DCIsuU9R.cjs +338 -0
- package/dist/dreamlandBaby-DvSaZGrz.js +338 -0
- package/dist/entrypoints-D_JUvkgy.cjs +18 -0
- package/dist/entrypoints-YLQsbBRD.js +6 -0
- package/dist/enviveConfigContext-CUGLpPGU.js +34 -0
- package/dist/enviveConfigContext-Dfr2VH6u.cjs +48 -0
- package/dist/fiveCbd-B1SESMCO.js +605 -0
- package/dist/fiveCbd-CkOlVby_.cjs +605 -0
- package/dist/forLoveAndLemons-CfYPMnKS.cjs +660 -0
- package/dist/forLoveAndLemons-DmwYZIk0.js +658 -0
- package/dist/greenpan-Bsl3ir59.cjs +389 -0
- package/dist/greenpan-BtOi45lf.js +389 -0
- package/dist/grooveLife-6_dtYsRk.js +334 -0
- package/dist/grooveLife-Cmm1PSCL.cjs +334 -0
- package/dist/homegrownCannabis-C-kw-74X.js +400 -0
- package/dist/homegrownCannabis-CO0uY_mp.cjs +400 -0
- package/dist/hooks/index.cjs +16 -0
- package/dist/hooks/index.d.cts +357 -0
- package/dist/hooks/index.d.ts +357 -0
- package/dist/hooks/index.js +7 -0
- package/dist/jackArcher-CLVmwwpI.js +719 -0
- package/dist/jackArcher-DdYTIzAV.cjs +719 -0
- package/dist/jordanCraig-Am-Oor-O.js +1778 -0
- package/dist/jordanCraig-_u3-w4Hp.cjs +1778 -0
- package/dist/kindredBravely-CWovIDSc.cjs +482 -0
- package/dist/kindredBravely-eWp-ud_E.js +482 -0
- package/dist/kutFromTheKloth-BMV4BuGQ.js +361 -0
- package/dist/kutFromTheKloth-Q589bAOC.cjs +361 -0
- package/dist/larryAndSerges-BMUlTgI-.js +252 -0
- package/dist/larryAndSerges-CEau764j.cjs +252 -0
- package/dist/leapsAndRebounds-DGMzPO7T.js +352 -0
- package/dist/leapsAndRebounds-DHAtRTJD.cjs +352 -0
- package/dist/logger-Dln20ans.cjs +25 -0
- package/dist/logger-pdEEY8T2.js +19 -0
- package/dist/longevityrx-CZW8Hxzi.cjs +312 -0
- package/dist/longevityrx-jH2JLhNH.js +312 -0
- package/dist/lookOptic-BGXP5P_V.js +274 -0
- package/dist/lookOptic-CA6RwLbG.cjs +274 -0
- package/dist/mantraBrand-Cm9_PBCT.js +742 -0
- package/dist/mantraBrand-DByNqpnL.cjs +742 -0
- package/dist/medterra-B0wxj_PV.js +575 -0
- package/dist/medterra-DnPN2ksU.cjs +575 -0
- package/dist/modells-Bmz8Ag5M.js +476 -0
- package/dist/modells-CoYgkLSp.cjs +476 -0
- package/dist/models-DHdb7QWn.js +51 -0
- package/dist/models-ixxUsGL_.cjs +69 -0
- package/dist/pressedFloral-DSKs_oVG.js +653 -0
- package/dist/pressedFloral-DjBiSoUl.cjs +653 -0
- package/dist/skinPerfection-B_3xzVNS.cjs +326 -0
- package/dist/skinPerfection-IDrBuAPt.js +326 -0
- package/dist/snapSupplements-BJk5T5ba.js +277 -0
- package/dist/snapSupplements-BStTsdOZ.cjs +277 -0
- package/dist/socialProofClasses-Bhv2Vulz.js +9 -0
- package/dist/socialProofClasses-CrQBWdSA.cjs +39 -0
- package/dist/spanx-BYg0LE7R.js +653 -0
- package/dist/spanx-LwU1zSzq.cjs +655 -0
- package/dist/spanxStaging-CfSmuKYB.js +837 -0
- package/dist/spanxStaging-OZLV9qix.cjs +840 -0
- package/dist/suggestionBarV2-types-BllzwsBD.js +34 -0
- package/dist/suggestionBarV2-types-CaovchMP.cjs +46 -0
- package/dist/supergoop-BqPXDnKk.cjs +327 -0
- package/dist/supergoop-CIlrHND_.js +325 -0
- package/dist/types-C4T5UOIW.cjs +230 -0
- package/dist/types-CYNvLeSA.js +176 -0
- package/dist/uniqueVintage-B30mOqbH.cjs +1205 -0
- package/dist/uniqueVintage-CFueJOhO.js +1203 -0
- package/dist/venaCbd-DHGZy49P.cjs +357 -0
- package/dist/venaCbd-T0CqVD4k.js +357 -0
- package/dist/westonJonBoucher-BdMzs_Yg.cjs +414 -0
- package/dist/westonJonBoucher-b4TCQ4ev.js +414 -0
- package/dist/wineEnthusiast-BLGlOjgr.cjs +932 -0
- package/dist/wineEnthusiast-BqR0i_54.js +932 -0
- package/dist/wolfMattress-CyyO-LoC.js +362 -0
- package/dist/wolfMattress-DNGZOivg.cjs +362 -0
- package/dist/wolfTactical-3Mm2fvVF.js +341 -0
- package/dist/wolfTactical-BmXYlFjr.cjs +341 -0
- package/package.json +66 -0
- package/src/adapters/amplitude/amplitudeAdapter.ts +454 -0
- package/src/adapters/amplitude/index.ts +2 -0
- package/src/adapters/amplitude/stubAmplitudeAdapter.ts +34 -0
- package/src/adapters/spiffy/commerce/api.ts +596 -0
- package/src/adapters/spiffy/commerce/exceptions/sessionExceptions.ts +6 -0
- package/src/adapters/spiffy/commerce/exceptions/unsupportedProductExceptions.ts +6 -0
- package/src/adapters/spiffy/commerce/graphql.ts +184 -0
- package/src/application/config/generalStaticConfig.ts +37 -0
- package/src/application/logging/logger.ts +29 -0
- package/src/application/models/api/context.ts +4 -0
- package/src/application/models/api/generationParams.ts +4 -0
- package/src/application/models/api/nextMessageRequest.ts +11 -0
- package/src/application/models/api/orgAnalyticsConfig.ts +19 -0
- package/src/application/models/api/orgConfigResults.ts +40 -0
- package/src/application/models/api/organizationConfig.ts +12 -0
- package/src/application/models/api/response.ts +132 -0
- package/src/application/models/api/responseGenerics.ts +67 -0
- package/src/application/models/api/search.ts +26 -0
- package/src/application/models/api/suggestion.ts +4 -0
- package/src/application/models/api/supportedEventRequest.ts +8 -0
- package/src/application/models/api/userEvent.ts +101 -0
- package/src/application/models/cachedValue.ts +8 -0
- package/src/application/models/chatElementDisplayLocation.ts +22 -0
- package/src/application/models/clientDetails.ts +18 -0
- package/src/application/models/colorsConfig.ts +28 -0
- package/src/application/models/conversationalSearchIds.ts +5 -0
- package/src/application/models/dataLayer.ts +45 -0
- package/src/application/models/domMutationContinuation.ts +7 -0
- package/src/application/models/domObservationStrategy.ts +9 -0
- package/src/application/models/events.ts +5 -0
- package/src/application/models/featureGates.ts +23 -0
- package/src/application/models/frontendConfig.ts +14 -0
- package/src/application/models/googleAnalyticsEvents.ts +8 -0
- package/src/application/models/graphql/index.ts +2 -0
- package/src/application/models/graphql/queries/getMerchantColorsQuery.ts +37 -0
- package/src/application/models/graphql/queries/getMerchantFrontendConfigQuery.ts +103 -0
- package/src/application/models/graphql/queries/getMerchantOrgIdQuery.ts +11 -0
- package/src/application/models/guards/api/index.ts +12 -0
- package/src/application/models/guards/api/isApiFormResponse.ts +90 -0
- package/src/application/models/guards/api/isApiFormSubmittedResponseAttributes.ts +37 -0
- package/src/application/models/guards/api/isApiOrderResponseAttributes.ts +155 -0
- package/src/application/models/guards/api/isApiOrgConfigResults.ts +277 -0
- package/src/application/models/guards/api/isApiOrganizationConfig.ts +207 -0
- package/src/application/models/guards/api/isApiPDPEventAttributes.ts +21 -0
- package/src/application/models/guards/api/isApiPLPEventAttributes.ts +41 -0
- package/src/application/models/guards/api/isApiPageResponseAttributes.ts +21 -0
- package/src/application/models/guards/api/isApiProductResponseAttributes.ts +85 -0
- package/src/application/models/guards/api/isApiProductSearchAttributes.ts +23 -0
- package/src/application/models/guards/api/isApiProductSearchFilterAttributes.ts +15 -0
- package/src/application/models/guards/api/isApiQueryTypedEventAttributes.ts +4 -0
- package/src/application/models/guards/api/isApiResponse.ts +39 -0
- package/src/application/models/guards/api/isApiReviewResponseAttributes.ts +30 -0
- package/src/application/models/guards/api/isApiReviewRichInformation.ts +37 -0
- package/src/application/models/guards/api/isApiSearchEventAttributes.ts +28 -0
- package/src/application/models/guards/api/isApiSuggestion.ts +36 -0
- package/src/application/models/guards/api/isApiSuggestionClickedEventAttributes.ts +9 -0
- package/src/application/models/guards/api/isApiTextResponseAttributes.ts +9 -0
- package/src/application/models/guards/api/isApiUserEvent.ts +25 -0
- package/src/application/models/guards/graphQL/isGraphQLColorsConfig.ts +50 -0
- package/src/application/models/guards/isBaseEcommerceEvent.ts +17 -0
- package/src/application/models/guards/isGA4EcommerceEvent.ts +17 -0
- package/src/application/models/guards/isLegacyUAEcommerceEvent.ts +17 -0
- package/src/application/models/guards/isMobilePLPChatPlacementParameter.ts +11 -0
- package/src/application/models/guards/isSpanxTakeAQuizCtaParameter.ts +4 -0
- package/src/application/models/guards/isVariantInfo.ts +37 -0
- package/src/application/models/guards/utils.ts +43 -0
- package/src/application/models/index.ts +20 -0
- package/src/application/models/localStorageEventListener.ts +4 -0
- package/src/application/models/message.ts +146 -0
- package/src/application/models/mobilePLPChatPlacementParameter.ts +3 -0
- package/src/application/models/orgsEnum.ts +36 -0
- package/src/application/models/productExperiment.ts +5 -0
- package/src/application/models/spanxTakeAQuizCtaParameter.ts +4 -0
- package/src/application/models/spiffyWidgets.ts +16 -0
- package/src/application/models/supportedOrgs.ts +137 -0
- package/src/application/models/utilityTypes/camelCase.ts +87 -0
- package/src/application/models/utilityTypes/camelCasedPropertiesDeep.ts +80 -0
- package/src/application/models/utilityTypes/delimiterCase.ts +121 -0
- package/src/application/models/utilityTypes/delimiterCasedPropertiesDeep.ts +98 -0
- package/src/application/models/utilityTypes/index.ts +1 -0
- package/src/application/models/utilityTypes/internal.ts +93 -0
- package/src/application/models/utilityTypes/primitive.ts +8 -0
- package/src/application/models/utilityTypes/snakeCasedPropertiesDeep.ts +49 -0
- package/src/application/models/utilityTypes/splitWords.ts +76 -0
- package/src/application/models/utilityTypes/trim.ts +28 -0
- package/src/application/models/utilityTypes/unknownArray.ts +25 -0
- package/src/application/models/utils/snakeToCamelTransformer.ts +90 -0
- package/src/application/models/utils/stringToFulfillmentDisplayStatusEnumValue.ts +68 -0
- package/src/application/models/validators/validateGraphQLColorsConfig.ts +29 -0
- package/src/application/models/validators/validateGraphQLFrontendConfig.ts +594 -0
- package/src/application/models/validators/validateGraphQLOrgId.ts +7 -0
- package/src/application/models/validators/validateMobilePLPChatPlacementParameter.ts +14 -0
- package/src/application/models/validators/validateOrgConfigResults.ts +47 -0
- package/src/application/models/validators/validateOrganizationConfig.ts +37 -0
- package/src/application/models/validators/validateResponse.ts +187 -0
- package/src/application/models/validators/validateSuggestion.ts +16 -0
- package/src/application/models/validators/validateUserEvent.ts +110 -0
- package/src/application/models/variantInfo/index.ts +1 -0
- package/src/application/models/variantInfo/pageVisitInfo.ts +6 -0
- package/src/application/models/variantInfo/plpInfo.ts +3 -0
- package/src/application/models/variantInfo/productInfo.ts +5 -0
- package/src/application/models/variantInfo/variantInfo.ts +23 -0
- package/src/application/service/cachingService.ts +84 -0
- package/src/application/service/cdnService.ts +18 -0
- package/src/application/service/customerService/index.ts +8 -0
- package/src/application/service/customerService/providers/UnsupportedCustomerService.ts +15 -0
- package/src/application/service/customerService/types.ts +31 -0
- package/src/application/service/domMutationObserver.ts +320 -0
- package/src/application/service/domMutations/GridInsertionService.ts +123 -0
- package/src/application/service/domMutations/dataLayer/dataLayerEventsListener.ts +99 -0
- package/src/application/service/domMutations/domInsertionService.ts +90 -0
- package/src/application/service/domMutations/domMutationListener.ts +15 -0
- package/src/application/service/domMutations/domMutationListenerState.ts +52 -0
- package/src/application/service/domMutations/floatingChat/embeddedChatsPlacementsListener.ts +41 -0
- package/src/application/service/domMutations/gladly/gladlyListener.ts +61 -0
- package/src/application/service/domMutations/spiffy/orgs/common/kustomerVisibilityListener.ts +41 -0
- package/src/application/service/domMutations/spiffy/orgs/common/orgsCommonDataLayerListener.ts +119 -0
- package/src/application/service/environmentService.ts +51 -0
- package/src/application/service/featureFlagService.ts +130 -0
- package/src/application/service/kustomerIntegrationService.ts +111 -0
- package/src/application/service/localStorageService.ts +77 -0
- package/src/application/service/pageVariantService.ts +779 -0
- package/src/application/service/searchService.ts +140 -0
- package/src/application/service/sessionStorageService.ts +27 -0
- package/src/application/service/shopifyUrlService.ts +63 -0
- package/src/application/service/userIdentityService.ts +114 -0
- package/src/application/service/windowChatToggleService.ts +71 -0
- package/src/application/service/windowDataLayerService.ts +181 -0
- package/src/application/service/windowFrontendConfigService.ts +104 -0
- package/src/application/utils/__tests__/divideArrays.test.ts +14 -0
- package/src/application/utils/analyticsUtils.ts +110 -0
- package/src/application/utils/coreContextToApiContext.ts +11 -0
- package/src/application/utils/coreUserEventToApiUserEvent.ts +106 -0
- package/src/application/utils/divideArray.ts +7 -0
- package/src/application/utils/domObserver.ts +96 -0
- package/src/application/utils/elementObserver.ts +246 -0
- package/src/application/utils/imageFilter.ts +12 -0
- package/src/application/utils/index.ts +3 -0
- package/src/application/utils/merchantUtils.ts +16 -0
- package/src/application/utils/messageFromFormSubmittedEvent.ts +31 -0
- package/src/application/utils/messageFromQueryEvent.ts +38 -0
- package/src/application/utils/messageFromResponse.ts +133 -0
- package/src/application/utils/messageFromSuggestionEvent.ts +32 -0
- package/src/application/utils/mouseEventTypes.ts +1 -0
- package/src/application/utils/mutationHelper.ts +51 -0
- package/src/application/utils/nextMessageRequestToApiRequest.ts +31 -0
- package/src/application/utils/nodeSelector.ts +133 -0
- package/src/application/utils/overrides.ts +196 -0
- package/src/application/utils/stringUtils.ts +55 -0
- package/src/application/utils/supportedEventRequestToApiRequest.ts +12 -0
- package/src/application/utils/urlsParser.ts +53 -0
- package/src/application/utils/validation.ts +5 -0
- package/src/atoms/app/index.ts +57 -0
- package/src/atoms/app/variant.ts +261 -0
- package/src/atoms/atomStore.ts +34 -0
- package/src/atoms/chat/chatState.ts +44 -0
- package/src/atoms/chat/form.ts +19 -0
- package/src/atoms/chat/index.ts +38 -0
- package/src/atoms/chat/lastMessage.ts +11 -0
- package/src/atoms/chat/messageQueue.ts +65 -0
- package/src/atoms/chat/performanceMetrics.ts +84 -0
- package/src/atoms/chat/renderedWidgetRefs.ts +28 -0
- package/src/atoms/chat/replies.ts +51 -0
- package/src/atoms/chat/suggestions.ts +36 -0
- package/src/atoms/globalSearch.ts +12 -0
- package/src/atoms/index.ts +5 -0
- package/src/atoms/org/customerService.ts +13 -0
- package/src/atoms/org/graphqlConfig.ts +27 -0
- package/src/atoms/org/index.ts +7 -0
- package/src/atoms/org/merchantCss.ts +44 -0
- package/src/atoms/org/org.ts +256 -0
- package/src/atoms/org/orgAnalyticsConfig.ts +28 -0
- package/src/atoms/org/orgPageConfig.ts +38 -0
- package/src/atoms/org/orgUIConfig.ts +122 -0
- package/src/atoms/search/chatSearch.ts +293 -0
- package/src/atoms/search/index.ts +2 -0
- package/src/atoms/search/productFilters.ts +207 -0
- package/src/atoms/search/productSorter.ts +23 -0
- package/src/atoms/search/searchAPI.ts +194 -0
- package/src/atoms/search/types.ts +55 -0
- package/src/atoms/search/utils.ts +18 -0
- package/src/config/divIds.ts +27 -0
- package/src/config/locators/components/chat/entrypoints.ts +13 -0
- package/src/config/locators/components/chat/index.ts +23 -0
- package/src/config/locators/components/chat/preview.ts +13 -0
- package/src/config/locators/components/chat/variants/index.ts +16 -0
- package/src/config/locators/components/common/buttons.ts +6 -0
- package/src/config/locators/components/common/cards.ts +18 -0
- package/src/config/locators/components/common/links.ts +1 -0
- package/src/config/locators/components/common/tables.ts +2 -0
- package/src/config/locators/components/floating-button.ts +2 -0
- package/src/config/locators/components/index.ts +3 -0
- package/src/config/locators/components/report-issue.ts +21 -0
- package/src/config/locators/components/search/index.ts +5 -0
- package/src/config/locators/components/shadow-dom.ts +1 -0
- package/src/config/locators/embedded.ts +21 -0
- package/src/config/locators/index.ts +3 -0
- package/src/config/socialProofClasses.ts +17 -0
- package/src/contexts/chatContext.tsx +451 -0
- package/src/contexts/enviveConfigContext.tsx +70 -0
- package/src/contexts/index.ts +4 -0
- package/src/contexts/systemSettingsContext.tsx +61 -0
- package/src/contexts/types.ts +1059 -0
- package/src/enabled-features.ts +83 -0
- package/src/events/event-types.ts +11 -0
- package/src/events/index.ts +52 -0
- package/src/events/registerAnalyticsListeners.ts +49 -0
- package/src/extension.ts +63 -0
- package/src/hooks/index.ts +22 -0
- package/src/hooks/useBlockBackButton.ts +29 -0
- package/src/hooks/useChatToggle.ts +66 -0
- package/src/hooks/useCustomerSupportHandoff.ts +39 -0
- package/src/hooks/useDebounce.ts +17 -0
- package/src/hooks/useDynamicVariants.ts +210 -0
- package/src/hooks/useElementObserver.ts +245 -0
- package/src/hooks/useFileUpload.ts +61 -0
- package/src/hooks/useGrabAndScroll.ts +133 -0
- package/src/hooks/useHideElements.ts +82 -0
- package/src/hooks/useHorizontalScrollAnimation.ts +115 -0
- package/src/hooks/useImageResolver.ts +51 -0
- package/src/hooks/useIntersection.ts +28 -0
- package/src/hooks/useIsSmallScreen.ts +23 -0
- package/src/hooks/useMessageFilter.ts +49 -0
- package/src/hooks/useMessageScrollObserver.ts +47 -0
- package/src/hooks/useReducedMotionWithOverride.ts +15 -0
- package/src/hooks/useSearch.tsx +433 -0
- package/src/hooks/useSnapCalculator.ts +38 -0
- package/src/hooks/useSnapControl.ts +155 -0
- package/src/hooks/useSystemSettingsContext.ts +12 -0
- package/src/hooks/useTrackComponentVisibleEvent.ts +52 -0
- package/src/hooks/useUpdateAnalyticsProps.ts +56 -0
- package/src/hooks/utils.ts +153 -0
- package/src/index.ts +31 -0
- package/src/initialize.ts +163 -0
- package/src/interceptors/types.ts +6 -0
- package/src/interceptors/useFormEscalation.ts +40 -0
- package/src/interceptors/useMessageInterceptor.ts +32 -0
- package/src/main.ts +85 -0
- package/src/main.tsx +123 -0
- package/src/merchants/bandolier/bandolier.ts +1389 -0
- package/src/merchants/carpe/carpe.ts +656 -0
- package/src/merchants/coterie/coterie.ts +280 -0
- package/src/merchants/default.ts +193 -0
- package/src/merchants/dreamlandBaby/dreamlandBaby.ts +375 -0
- package/src/merchants/fiveCbd/fiveCbd.ts +697 -0
- package/src/merchants/forLoveAndLemons/forLoveAndLemons.ts +721 -0
- package/src/merchants/greenpan/greenpan.ts +440 -0
- package/src/merchants/grooveLife/grooveLife.ts +386 -0
- package/src/merchants/homegrownCannabis/homegrownCannabis.ts +468 -0
- package/src/merchants/init-merchant.sh +53 -0
- package/src/merchants/jackArcher/jackArcher.ts +974 -0
- package/src/merchants/jordanCraig/jordanCraig.ts +1927 -0
- package/src/merchants/kindredBravely/kindredBravely.ts +529 -0
- package/src/merchants/kutFromTheKloth/kutFromTheKloth.ts +418 -0
- package/src/merchants/larryAndSerges/larryAndSerges.ts +314 -0
- package/src/merchants/leapsAndRebounds/leapsAndRebounds.ts +424 -0
- package/src/merchants/longevityrx/longevityrx.ts +368 -0
- package/src/merchants/lookOptic/lookOptic.ts +323 -0
- package/src/merchants/mantraBrand/mantraBrand.ts +838 -0
- package/src/merchants/medterra/medterra.ts +670 -0
- package/src/merchants/modells/modells.ts +546 -0
- package/src/merchants/pressedFloral/pressedFloral.ts +734 -0
- package/src/merchants/skinPerfection/skinPerfection.ts +379 -0
- package/src/merchants/snapSupplements/snapSupplements.ts +325 -0
- package/src/merchants/spanx/spanx.ts +810 -0
- package/src/merchants/spanx/spanxStaging.ts +942 -0
- package/src/merchants/supergoop/supergoop.ts +376 -0
- package/src/merchants/uniqueVintage/uniqueVintage.ts +1314 -0
- package/src/merchants/uniqueVintage/views/useUniqueVintageChatSearch.ts +147 -0
- package/src/merchants/venaCbd/venaCbd.ts +410 -0
- package/src/merchants/westonJonBoucher/westonJonBoucher.ts +473 -0
- package/src/merchants/wineEnthusiast/wineEnthusiast.ts +990 -0
- package/src/merchants/wolfMattress/wolfMattress.ts +411 -0
- package/src/merchants/wolfTactical/wolfTactical.ts +389 -0
- package/src/types/custservice-types.ts +28 -0
- package/src/types/search-filter-types.ts +111 -0
- package/src/types/suggestionBarV2-types.ts +4 -0
- package/src/types/test-types.ts +3 -0
- package/src/types.ts +66 -0
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
import { FrontendConfig } from 'src/application/models/frontendConfig';
|
|
2
|
+
import { transformSnakeToCamel } from 'src/application/models/utils/snakeToCamelTransformer';
|
|
3
|
+
import {
|
|
4
|
+
WidgetConfig,
|
|
5
|
+
PageVariantConfig,
|
|
6
|
+
PageVariantTestType,
|
|
7
|
+
WidgetMountingConfig,
|
|
8
|
+
} from 'src/contexts/types';
|
|
9
|
+
import { DOMInsertionType } from 'src/application/service/domMutations/domInsertionService';
|
|
10
|
+
import { GridInsertionType } from 'src/application/service/domMutations/GridInsertionService';
|
|
11
|
+
import Logger from 'src/application/logging/logger';
|
|
12
|
+
|
|
13
|
+
// Helper function to validate and transform PageVariantQueryData to PageVariantConfig
|
|
14
|
+
export const validateAndTransformPageVariants = (
|
|
15
|
+
config: Record<string, unknown>,
|
|
16
|
+
): PageVariantConfig => {
|
|
17
|
+
const transformed = transformSnakeToCamel(config) as Record<string, unknown>;
|
|
18
|
+
|
|
19
|
+
const { variantChecks, widgetMounting, ...rest } = transformed;
|
|
20
|
+
|
|
21
|
+
// Convert variantChecks to variantTests with testType normalization
|
|
22
|
+
const variantTests = Array.isArray(variantChecks)
|
|
23
|
+
? variantChecks.map(({ checkType, ...restCheck }) => ({
|
|
24
|
+
...restCheck,
|
|
25
|
+
testType: checkType,
|
|
26
|
+
}))
|
|
27
|
+
: [];
|
|
28
|
+
|
|
29
|
+
// Normalize widgetMounting: checks -> tests, checkType -> testType
|
|
30
|
+
const normalizedWidgetMounting = Array.isArray(widgetMounting)
|
|
31
|
+
? widgetMounting.map(({ mountingPointWidgets, ...restMounting }) => ({
|
|
32
|
+
...restMounting,
|
|
33
|
+
...(Array.isArray(mountingPointWidgets)
|
|
34
|
+
? {
|
|
35
|
+
mountingPointWidgets: mountingPointWidgets.map(({ checks, ...restWidget }) => ({
|
|
36
|
+
...restWidget,
|
|
37
|
+
tests: Array.isArray(checks)
|
|
38
|
+
? checks.map(({ checkType, ...restCheck }) => ({
|
|
39
|
+
...restCheck,
|
|
40
|
+
testType: checkType,
|
|
41
|
+
}))
|
|
42
|
+
: [],
|
|
43
|
+
})),
|
|
44
|
+
}
|
|
45
|
+
: {}),
|
|
46
|
+
}))
|
|
47
|
+
: [];
|
|
48
|
+
|
|
49
|
+
const normalizedConfig: Record<string, unknown> = {
|
|
50
|
+
...rest,
|
|
51
|
+
...(variantTests ? { variantTests } : {}),
|
|
52
|
+
...(normalizedWidgetMounting ? { widgetMounting: normalizedWidgetMounting } : {}),
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const variantId = normalizedConfig.variantId as string;
|
|
56
|
+
const variantType = normalizedConfig.variantType as string;
|
|
57
|
+
|
|
58
|
+
if (typeof variantId !== 'string' || !variantId) {
|
|
59
|
+
throw new Error(`Missing or invalid variantId for pageVariant`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (typeof variantType !== 'string' || !variantType) {
|
|
63
|
+
throw new Error(`Missing or invalid variantType for pageVariant '${variantId}'`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!Array.isArray(variantTests)) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
`Missing or invalid variantTests for pageVariant '${variantId}'. Must be an array`,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
for (const test of variantTests) {
|
|
73
|
+
if (!test.testType || typeof test.testType !== 'string') {
|
|
74
|
+
throw new Error(`Invalid variantTest.testType for pageVariant '${variantId}'`);
|
|
75
|
+
}
|
|
76
|
+
if (!Object.values(PageVariantTestType).includes(test.testType as PageVariantTestType)) {
|
|
77
|
+
throw new Error(
|
|
78
|
+
`Invalid testType '${test.testType}' for pageVariant '${variantId}'. Valid types: ${Object.values(
|
|
79
|
+
PageVariantTestType,
|
|
80
|
+
).join(', ')}`,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!Array.isArray(normalizedWidgetMounting)) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Missing or invalid widgetMounting for pageVariant '${variantId}'. Must be an array`,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
for (const mounting of normalizedWidgetMounting) {
|
|
92
|
+
if (typeof mounting.mountingConfigId !== 'string' || !mounting.mountingConfigId) {
|
|
93
|
+
throw new Error(`Invalid mountingConfigId in widgetMounting for pageVariant '${variantId}'`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (mounting.widgetConfigId && typeof mounting.widgetConfigId !== 'string') {
|
|
97
|
+
throw new Error(`Invalid widgetConfigId in widgetMounting for pageVariant '${variantId}'`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (mounting.mountingPointWidgets) {
|
|
101
|
+
for (const widget of mounting.mountingPointWidgets) {
|
|
102
|
+
if (typeof widget.widgetConfigId !== 'string' || !widget.widgetConfigId) {
|
|
103
|
+
throw new Error(
|
|
104
|
+
`Invalid widgetConfigId in mountingPointWidgets for pageVariant '${variantId}'`,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (!Array.isArray(widget.tests)) {
|
|
109
|
+
throw new Error(
|
|
110
|
+
`Invalid or missing tests in mountingPointWidgets for pageVariant '${variantId}'`,
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (variantType === 'plp') {
|
|
118
|
+
if (typeof normalizedConfig.plpIdExtractor !== 'string' || !normalizedConfig.plpIdExtractor) {
|
|
119
|
+
throw new Error(`Missing or invalid plpIdExtractor for PLP pageVariant '${variantId}'`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (variantType === 'pdp') {
|
|
124
|
+
if (
|
|
125
|
+
typeof normalizedConfig.productIdExtractor !== 'string' ||
|
|
126
|
+
!normalizedConfig.productIdExtractor
|
|
127
|
+
) {
|
|
128
|
+
throw new Error(`Missing or invalid productIdExtractor for PDP pageVariant '${variantId}'`);
|
|
129
|
+
}
|
|
130
|
+
if (
|
|
131
|
+
normalizedConfig.parentProductIdExtractor &&
|
|
132
|
+
typeof normalizedConfig.parentProductIdExtractor !== 'string'
|
|
133
|
+
) {
|
|
134
|
+
throw new Error(
|
|
135
|
+
`Invalid parentProductIdExtractor for PDP pageVariant '${variantId}'. Must be string if provided`,
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return normalizedConfig as PageVariantConfig;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
// Helper function to validate and transform MountingConfigQueryData to WidgetMountingConfig
|
|
144
|
+
export const validateAndTransformMountingConfig = (
|
|
145
|
+
config: Record<string, unknown>,
|
|
146
|
+
configKey: string,
|
|
147
|
+
): WidgetMountingConfig => {
|
|
148
|
+
// RENAMING LOGIC: Convert backend "Check" terminology to frontend "Test" terminology
|
|
149
|
+
const normalizedConfig = { ...config };
|
|
150
|
+
|
|
151
|
+
// Convert checkId to testId for frontend compatibility (data is already camelCase)
|
|
152
|
+
if (normalizedConfig.checkId && !normalizedConfig.testId) {
|
|
153
|
+
normalizedConfig.testId = normalizedConfig.checkId;
|
|
154
|
+
delete normalizedConfig.checkId;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Required fields - these must be present and valid
|
|
158
|
+
if (typeof normalizedConfig.mountingConfigId !== 'string' || !normalizedConfig.mountingConfigId) {
|
|
159
|
+
throw new Error(`Missing or invalid mountingConfigId for config '${configKey}'`);
|
|
160
|
+
}
|
|
161
|
+
if (typeof normalizedConfig.containerId !== 'string' || !normalizedConfig.containerId) {
|
|
162
|
+
throw new Error(`Missing or invalid containerId for config '${configKey}'`);
|
|
163
|
+
}
|
|
164
|
+
if (typeof normalizedConfig.testId !== 'string' || !normalizedConfig.testId) {
|
|
165
|
+
throw new Error(`Missing or invalid testId for config '${configKey}'`);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Required insertionPoint
|
|
169
|
+
if (
|
|
170
|
+
!normalizedConfig.insertionPoint ||
|
|
171
|
+
typeof normalizedConfig.insertionPoint !== 'object' ||
|
|
172
|
+
Array.isArray(normalizedConfig.insertionPoint)
|
|
173
|
+
) {
|
|
174
|
+
throw new Error(`Missing or invalid insertionPoint for config '${configKey}'`);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const insertionPoint = normalizedConfig.insertionPoint as Record<string, unknown>;
|
|
178
|
+
|
|
179
|
+
// Validate insertionPoint required fields
|
|
180
|
+
if (typeof insertionPoint.selector !== 'string' || !insertionPoint.selector) {
|
|
181
|
+
throw new Error(`Missing or invalid insertionPoint.selector for config '${configKey}'`);
|
|
182
|
+
}
|
|
183
|
+
if (typeof insertionPoint.insertionType !== 'string' || !insertionPoint.insertionType) {
|
|
184
|
+
throw new Error(`Missing or invalid insertionPoint.insertionType for config '${configKey}'`);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Validate insertionType is a valid DOMInsertionType
|
|
188
|
+
if (!Object.values(DOMInsertionType).includes(insertionPoint.insertionType as DOMInsertionType)) {
|
|
189
|
+
throw new Error(
|
|
190
|
+
`Invalid insertionPoint.insertionType '${insertionPoint.insertionType}' for config '${configKey}'. Valid types: ${Object.values(DOMInsertionType).join(', ')}`,
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Validate optional insertionPoint fields
|
|
195
|
+
if (insertionPoint.selectionIndex != null && typeof insertionPoint.selectionIndex !== 'number') {
|
|
196
|
+
throw new Error(
|
|
197
|
+
`Invalid insertionPoint.selectionIndex for config '${configKey}'. Must be a number or null/undefined`,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Validate optional parentInsertionPoint if present
|
|
202
|
+
let parentInsertionPoint;
|
|
203
|
+
if (normalizedConfig.parentInsertionPoint) {
|
|
204
|
+
if (
|
|
205
|
+
typeof normalizedConfig.parentInsertionPoint !== 'object' ||
|
|
206
|
+
Array.isArray(normalizedConfig.parentInsertionPoint)
|
|
207
|
+
) {
|
|
208
|
+
throw new Error(`Invalid parentInsertionPoint for config '${configKey}'. Must be an object`);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const parentPoint = normalizedConfig.parentInsertionPoint as Record<string, unknown>;
|
|
212
|
+
if (typeof parentPoint.selector !== 'string' || !parentPoint.selector) {
|
|
213
|
+
throw new Error(`Missing or invalid parentInsertionPoint.selector for config '${configKey}'`);
|
|
214
|
+
}
|
|
215
|
+
if (typeof parentPoint.insertionType !== 'string' || !parentPoint.insertionType) {
|
|
216
|
+
throw new Error(
|
|
217
|
+
`Missing or invalid parentInsertionPoint.insertionType for config '${configKey}'`,
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (!Object.values(DOMInsertionType).includes(parentPoint.insertionType as DOMInsertionType)) {
|
|
222
|
+
throw new Error(
|
|
223
|
+
`Invalid parentInsertionPoint.insertionType '${parentPoint.insertionType}' for config '${configKey}'. Valid types: ${Object.values(DOMInsertionType).join(', ')}`,
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (parentPoint.selectionIndex != null && typeof parentPoint.selectionIndex !== 'number') {
|
|
228
|
+
throw new Error(
|
|
229
|
+
`Invalid parentInsertionPoint.selectionIndex for config '${configKey}'. Must be a number or null/undefined`,
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
parentInsertionPoint = {
|
|
234
|
+
selector: parentPoint.selector,
|
|
235
|
+
insertionType: parentPoint.insertionType as DOMInsertionType,
|
|
236
|
+
selectionIndex: parentPoint.selectionIndex as number | undefined,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Validate optional wrappingElement if present
|
|
241
|
+
let wrappingElement;
|
|
242
|
+
if (normalizedConfig.wrappingElement) {
|
|
243
|
+
if (
|
|
244
|
+
typeof normalizedConfig.wrappingElement !== 'object' ||
|
|
245
|
+
Array.isArray(normalizedConfig.wrappingElement)
|
|
246
|
+
) {
|
|
247
|
+
throw new Error(`Invalid wrappingElement for config '${configKey}'. Must be an object`);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const wrapping = normalizedConfig.wrappingElement as Record<string, unknown>;
|
|
251
|
+
if (typeof wrapping.className !== 'string' || !wrapping.className) {
|
|
252
|
+
throw new Error(`Missing or invalid wrappingElement.className for config '${configKey}'`);
|
|
253
|
+
}
|
|
254
|
+
if (typeof wrapping.element !== 'string' || !wrapping.element) {
|
|
255
|
+
throw new Error(`Missing or invalid wrappingElement.element for config '${configKey}'`);
|
|
256
|
+
}
|
|
257
|
+
if (typeof wrapping.insertionType !== 'string' || !wrapping.insertionType) {
|
|
258
|
+
throw new Error(`Missing or invalid wrappingElement.insertionType for config '${configKey}'`);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (!Object.values(DOMInsertionType).includes(wrapping.insertionType as DOMInsertionType)) {
|
|
262
|
+
throw new Error(
|
|
263
|
+
`Invalid wrappingElement.insertionType '${wrapping.insertionType}' for config '${configKey}'. Valid types: ${Object.values(DOMInsertionType).join(', ')}`,
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
wrappingElement = {
|
|
268
|
+
className: wrapping.className,
|
|
269
|
+
element: wrapping.element,
|
|
270
|
+
insertionType: wrapping.insertionType as DOMInsertionType,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Validate optional fields
|
|
275
|
+
if (
|
|
276
|
+
normalizedConfig.divCheckSelector != null &&
|
|
277
|
+
typeof normalizedConfig.divCheckSelector !== 'string'
|
|
278
|
+
) {
|
|
279
|
+
throw new Error(
|
|
280
|
+
`Invalid divCheckSelector for config '${configKey}'. Must be a string or null/undefined`,
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
if (normalizedConfig.className != null && typeof normalizedConfig.className !== 'string') {
|
|
284
|
+
throw new Error(
|
|
285
|
+
`Invalid className for config '${configKey}'. Must be a string or null/undefined`,
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
if (
|
|
289
|
+
normalizedConfig.suppressionSelector != null &&
|
|
290
|
+
typeof normalizedConfig.suppressionSelector !== 'string'
|
|
291
|
+
) {
|
|
292
|
+
throw new Error(
|
|
293
|
+
`Invalid suppressionSelector for config '${configKey}'. Must be a string or null/undefined`,
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
if (
|
|
297
|
+
normalizedConfig.dataAttributes != null &&
|
|
298
|
+
(typeof normalizedConfig.dataAttributes !== 'object' ||
|
|
299
|
+
Array.isArray(normalizedConfig.dataAttributes))
|
|
300
|
+
) {
|
|
301
|
+
throw new Error(
|
|
302
|
+
`Invalid dataAttributes for config '${configKey}'. Must be an object or null/undefined`,
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
if (
|
|
306
|
+
normalizedConfig.style != null &&
|
|
307
|
+
(typeof normalizedConfig.style !== 'object' || Array.isArray(normalizedConfig.style))
|
|
308
|
+
) {
|
|
309
|
+
throw new Error(`Invalid style for config '${configKey}'. Must be an object or null/undefined`);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Validate gridInsertionType if present
|
|
313
|
+
let gridInsertionType;
|
|
314
|
+
if (normalizedConfig.gridInsertionType) {
|
|
315
|
+
if (
|
|
316
|
+
typeof normalizedConfig.gridInsertionType !== 'string' ||
|
|
317
|
+
!normalizedConfig.gridInsertionType
|
|
318
|
+
) {
|
|
319
|
+
throw new Error(`Invalid gridInsertionType for config '${configKey}'. Must be a string`);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (
|
|
323
|
+
!Object.values(GridInsertionType).includes(
|
|
324
|
+
normalizedConfig.gridInsertionType as GridInsertionType,
|
|
325
|
+
)
|
|
326
|
+
) {
|
|
327
|
+
throw new Error(
|
|
328
|
+
`Invalid gridInsertionType '${normalizedConfig.gridInsertionType}' for config '${configKey}'. Valid types: ${Object.values(GridInsertionType).join(', ')}`,
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
gridInsertionType = normalizedConfig.gridInsertionType as GridInsertionType;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Build the return object, only including optional fields if they have values
|
|
335
|
+
const result: WidgetMountingConfig = {
|
|
336
|
+
mountingConfigId: normalizedConfig.mountingConfigId,
|
|
337
|
+
containerId: normalizedConfig.containerId,
|
|
338
|
+
testId: normalizedConfig.testId,
|
|
339
|
+
insertionPoint: {
|
|
340
|
+
selector: insertionPoint.selector,
|
|
341
|
+
insertionType: insertionPoint.insertionType as DOMInsertionType,
|
|
342
|
+
...(insertionPoint.selectionIndex != null && {
|
|
343
|
+
selectionIndex: insertionPoint.selectionIndex,
|
|
344
|
+
}),
|
|
345
|
+
},
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
// Only add optional fields if they have values
|
|
349
|
+
if (parentInsertionPoint) {
|
|
350
|
+
result.parentInsertionPoint = parentInsertionPoint;
|
|
351
|
+
}
|
|
352
|
+
if (gridInsertionType) {
|
|
353
|
+
result.gridInsertionType = gridInsertionType;
|
|
354
|
+
}
|
|
355
|
+
if (wrappingElement) {
|
|
356
|
+
result.wrappingElement = wrappingElement;
|
|
357
|
+
}
|
|
358
|
+
if (normalizedConfig.divCheckSelector) {
|
|
359
|
+
result.divCheckSelector = normalizedConfig.divCheckSelector as string;
|
|
360
|
+
}
|
|
361
|
+
if (normalizedConfig.className) {
|
|
362
|
+
result.className = normalizedConfig.className as string;
|
|
363
|
+
}
|
|
364
|
+
if (normalizedConfig.suppressionSelector) {
|
|
365
|
+
result.suppressionSelector = normalizedConfig.suppressionSelector;
|
|
366
|
+
}
|
|
367
|
+
if (normalizedConfig.dataAttributes) {
|
|
368
|
+
result.dataAttributes = normalizedConfig.dataAttributes as Record<string, string>;
|
|
369
|
+
}
|
|
370
|
+
if (normalizedConfig.style) {
|
|
371
|
+
result.style = normalizedConfig.style as Partial<CSSStyleDeclaration>;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return result;
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
// Helper function to validate and transform WidgetConfigQueryData to WidgetConfig
|
|
378
|
+
export const validateAndTransformWidgetConfig = (
|
|
379
|
+
config: Record<string, unknown>,
|
|
380
|
+
configKey: string,
|
|
381
|
+
): WidgetConfig => {
|
|
382
|
+
const normalizedConfig = transformSnakeToCamel(config) as Record<string, unknown>;
|
|
383
|
+
|
|
384
|
+
if (typeof normalizedConfig.widgetConfigId !== 'string' || !normalizedConfig.widgetConfigId) {
|
|
385
|
+
throw new Error(`Missing or invalid widgetConfigId for widget config '${configKey}'`);
|
|
386
|
+
}
|
|
387
|
+
if (typeof normalizedConfig.type !== 'string' || !normalizedConfig.type) {
|
|
388
|
+
throw new Error(`Missing or invalid type for widget config '${configKey}'`);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (normalizedConfig.contentId != null && typeof normalizedConfig.contentId !== 'string') {
|
|
392
|
+
throw new Error(
|
|
393
|
+
`Invalid contentId for widget config '${configKey}'. Must be a string or null/undefined`,
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Note: Widget configs are complex unions with type-specific properties.
|
|
398
|
+
|
|
399
|
+
// Return the normalized config as WidgetConfig
|
|
400
|
+
// Use intermediate 'unknown' cast for complex union types
|
|
401
|
+
return normalizedConfig as unknown as WidgetConfig;
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
export const validateGraphQLFrontendConfig = (data: unknown): FrontendConfig | undefined => {
|
|
405
|
+
if (data === null || data === undefined) {
|
|
406
|
+
return undefined;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (typeof data !== 'object' || Array.isArray(data)) {
|
|
410
|
+
Logger.logWarn('Invalid GraphQL frontend config data: not an object', undefined, { data });
|
|
411
|
+
return undefined;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const obj = data as Record<string, unknown>;
|
|
415
|
+
|
|
416
|
+
// Validate merchant_override_css if present
|
|
417
|
+
if (
|
|
418
|
+
'merchant_override_css' in obj &&
|
|
419
|
+
typeof obj.merchant_override_css !== 'string' &&
|
|
420
|
+
obj.merchant_override_css !== null
|
|
421
|
+
) {
|
|
422
|
+
Logger.logWarn(
|
|
423
|
+
'Invalid GraphQL frontend config data: merchant_override_css must be a string or null',
|
|
424
|
+
undefined,
|
|
425
|
+
{ data },
|
|
426
|
+
);
|
|
427
|
+
return undefined;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Validate page_variants if present
|
|
431
|
+
if ('page_variants' in obj) {
|
|
432
|
+
if (
|
|
433
|
+
obj.page_variants !== undefined &&
|
|
434
|
+
obj.page_variants !== null &&
|
|
435
|
+
!Array.isArray(obj.page_variants)
|
|
436
|
+
) {
|
|
437
|
+
Logger.logWarn(
|
|
438
|
+
'Invalid GraphQL frontend config data: page_variants must be an array or null/undefined',
|
|
439
|
+
undefined,
|
|
440
|
+
{ data },
|
|
441
|
+
);
|
|
442
|
+
return undefined;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Validate mounting_configs if present
|
|
447
|
+
if ('mounting_configs' in obj) {
|
|
448
|
+
if (
|
|
449
|
+
obj.mounting_configs !== undefined &&
|
|
450
|
+
obj.mounting_configs !== null &&
|
|
451
|
+
!Array.isArray(obj.mounting_configs)
|
|
452
|
+
) {
|
|
453
|
+
Logger.logWarn(
|
|
454
|
+
'Invalid GraphQL frontend config data: mounting_configs must be an array or null/undefined',
|
|
455
|
+
undefined,
|
|
456
|
+
{ data },
|
|
457
|
+
);
|
|
458
|
+
return undefined;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Validate widget_configs if present
|
|
463
|
+
if ('widget_configs' in obj) {
|
|
464
|
+
if (
|
|
465
|
+
obj.widget_configs !== undefined &&
|
|
466
|
+
obj.widget_configs !== null &&
|
|
467
|
+
!Array.isArray(obj.widget_configs)
|
|
468
|
+
) {
|
|
469
|
+
Logger.logWarn(
|
|
470
|
+
'Invalid GraphQL frontend config data: widget_configs must be an array or null/undefined',
|
|
471
|
+
undefined,
|
|
472
|
+
{ data },
|
|
473
|
+
);
|
|
474
|
+
return undefined;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Validate ui_configs if present
|
|
479
|
+
if ('ui_configs' in obj && typeof obj.ui_configs !== 'object' && obj.ui_configs !== null) {
|
|
480
|
+
Logger.logWarn(
|
|
481
|
+
'Invalid GraphQL frontend config data: ui_configs must be an object or null/undefined',
|
|
482
|
+
undefined,
|
|
483
|
+
{ data },
|
|
484
|
+
);
|
|
485
|
+
return undefined;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
try {
|
|
489
|
+
// Transform the data to camelCase
|
|
490
|
+
const transformedData = transformSnakeToCamel(obj) as Record<string, unknown>;
|
|
491
|
+
|
|
492
|
+
// Convert page_variants from array to validated array if present
|
|
493
|
+
if (transformedData.pageVariants && Array.isArray(transformedData.pageVariants)) {
|
|
494
|
+
const pageVariantsArray = transformedData.pageVariants;
|
|
495
|
+
const validatedPageVariants: PageVariantConfig[] = [];
|
|
496
|
+
|
|
497
|
+
for (const variant of pageVariantsArray) {
|
|
498
|
+
if (variant && typeof variant === 'object' && typeof variant.variantId === 'string') {
|
|
499
|
+
try {
|
|
500
|
+
const validatedVariant = validateAndTransformPageVariants(variant);
|
|
501
|
+
validatedPageVariants.push(validatedVariant);
|
|
502
|
+
} catch (error) {
|
|
503
|
+
Logger.logWarn('Invalid page variant, skipping', error, {
|
|
504
|
+
variantId: variant.variantId,
|
|
505
|
+
variant,
|
|
506
|
+
});
|
|
507
|
+
// Continue processing other variants
|
|
508
|
+
}
|
|
509
|
+
} else {
|
|
510
|
+
Logger.logWarn('Invalid page variant structure, skipping', undefined, { variant });
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
transformedData.pageVariants = validatedPageVariants;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// Convert mounting_configs from array to Record if present
|
|
518
|
+
if (transformedData.mountingConfigs && Array.isArray(transformedData.mountingConfigs)) {
|
|
519
|
+
const mountingConfigsArray = transformedData.mountingConfigs as Array<{
|
|
520
|
+
key: string;
|
|
521
|
+
config: unknown;
|
|
522
|
+
}>;
|
|
523
|
+
const mountingConfigsRecord: Record<string, WidgetMountingConfig> = {};
|
|
524
|
+
|
|
525
|
+
for (const item of mountingConfigsArray) {
|
|
526
|
+
if (
|
|
527
|
+
item &&
|
|
528
|
+
typeof item.key === 'string' &&
|
|
529
|
+
item.config &&
|
|
530
|
+
typeof item.config === 'object'
|
|
531
|
+
) {
|
|
532
|
+
try {
|
|
533
|
+
// Validate and transform the config structure
|
|
534
|
+
const config = item.config as Record<string, unknown>;
|
|
535
|
+
const validatedConfig = validateAndTransformMountingConfig(config, item.key);
|
|
536
|
+
mountingConfigsRecord[item.key] = validatedConfig;
|
|
537
|
+
} catch (error) {
|
|
538
|
+
Logger.logWarn('Invalid mounting config, skipping', error, {
|
|
539
|
+
configKey: item.key,
|
|
540
|
+
config: item.config,
|
|
541
|
+
});
|
|
542
|
+
// Continue processing other configs
|
|
543
|
+
}
|
|
544
|
+
} else {
|
|
545
|
+
Logger.logWarn('Invalid mounting config item structure, skipping', undefined, { item });
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
transformedData.mountingConfigs = mountingConfigsRecord;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// Convert widget_configs from array to Record if present
|
|
553
|
+
if (transformedData.widgetConfigs && Array.isArray(transformedData.widgetConfigs)) {
|
|
554
|
+
const widgetConfigsArray = transformedData.widgetConfigs as Array<{
|
|
555
|
+
key: string;
|
|
556
|
+
config: unknown;
|
|
557
|
+
}>;
|
|
558
|
+
const widgetConfigsRecord: Record<string, unknown> = {};
|
|
559
|
+
|
|
560
|
+
for (const item of widgetConfigsArray) {
|
|
561
|
+
if (
|
|
562
|
+
item &&
|
|
563
|
+
typeof item.key === 'string' &&
|
|
564
|
+
item.config &&
|
|
565
|
+
typeof item.config === 'object'
|
|
566
|
+
) {
|
|
567
|
+
try {
|
|
568
|
+
// Validate and transform widget config using the dedicated validation function
|
|
569
|
+
const config = item.config as Record<string, unknown>;
|
|
570
|
+
const validatedConfig = validateAndTransformWidgetConfig(config, item.key);
|
|
571
|
+
widgetConfigsRecord[item.key] = validatedConfig;
|
|
572
|
+
} catch (error) {
|
|
573
|
+
Logger.logWarn('Invalid widget config, skipping', error, {
|
|
574
|
+
configKey: item.key,
|
|
575
|
+
config: item.config,
|
|
576
|
+
});
|
|
577
|
+
// Continue processing other configs
|
|
578
|
+
}
|
|
579
|
+
} else {
|
|
580
|
+
Logger.logWarn('Invalid widget config item structure, skipping', undefined, { item });
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
transformedData.widgetConfigs = widgetConfigsRecord;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
return transformedData as FrontendConfig;
|
|
588
|
+
} catch (error) {
|
|
589
|
+
Logger.logWarn('Failed to validate and transform GraphQL frontend config data', error, {
|
|
590
|
+
data,
|
|
591
|
+
});
|
|
592
|
+
return undefined;
|
|
593
|
+
}
|
|
594
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { isMobilePLPChatPlacementParameter } from '../guards/isMobilePLPChatPlacementParameter';
|
|
2
|
+
import { MobilePLPChatPlacementParameter } from '../mobilePLPChatPlacementParameter';
|
|
3
|
+
|
|
4
|
+
export const validateMobilePLPChatPlacementParameter = (
|
|
5
|
+
value: unknown,
|
|
6
|
+
): MobilePLPChatPlacementParameter | undefined => {
|
|
7
|
+
if (!isMobilePLPChatPlacementParameter(value)) {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
rowIndex: value.row_index,
|
|
13
|
+
};
|
|
14
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { isApiOrgConfigResults } from 'src/application/models/guards/api/isApiOrgConfigResults';
|
|
2
|
+
import { OrgConfig } from 'src/application/models/api/orgConfigResults';
|
|
3
|
+
import { validateOrganizationConfig } from 'src/application/models/validators/validateOrganizationConfig';
|
|
4
|
+
import { OrganizationConfig } from 'src/application/models/api/organizationConfig';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param data
|
|
9
|
+
* @returns
|
|
10
|
+
*/
|
|
11
|
+
export const validateOrgConfigResults = (data: unknown): OrgConfig | undefined => {
|
|
12
|
+
if (!isApiOrgConfigResults(data)) {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
configs: data.configs
|
|
18
|
+
.map((config) => validateOrganizationConfig(config))
|
|
19
|
+
.filter((config): config is OrganizationConfig => config != null),
|
|
20
|
+
experiments: data.experiments.map((experiment) => ({
|
|
21
|
+
group: experiment.group,
|
|
22
|
+
groupName: experiment.group_name,
|
|
23
|
+
name: experiment.name,
|
|
24
|
+
ruleId: experiment.rule_id,
|
|
25
|
+
// TODO this needs to be strongly typed but we're not running any experiments at the moment
|
|
26
|
+
value: experiment.value as Record<string, unknown>,
|
|
27
|
+
})),
|
|
28
|
+
gates: data.gates.map((gate) => ({
|
|
29
|
+
groupName: gate.group_name,
|
|
30
|
+
name: gate.name,
|
|
31
|
+
ruleId: gate.rule_id,
|
|
32
|
+
value: gate.value,
|
|
33
|
+
})),
|
|
34
|
+
org: {
|
|
35
|
+
org: {
|
|
36
|
+
id: data.org.org.id,
|
|
37
|
+
displayName: data.org.org.display_name,
|
|
38
|
+
domain: data.org.org.domain,
|
|
39
|
+
shortName: data.org.org.short_name,
|
|
40
|
+
status: data.org.org.status,
|
|
41
|
+
createdAt: data.org.org.created_at?.toISOString(),
|
|
42
|
+
updatedAt: data.org.org.updated_at?.toISOString(),
|
|
43
|
+
},
|
|
44
|
+
settings: {},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
};
|