@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.
Files changed (385) hide show
  1. package/LICENSE +2 -0
  2. package/README.md +2 -0
  3. package/dist/GridInsertionService-CEYo9pGj.js +22 -0
  4. package/dist/GridInsertionService-CS_bnPh0.cjs +28 -0
  5. package/dist/bandolier-Ble8jEa8.js +1221 -0
  6. package/dist/bandolier-Bm2xAt_j.cjs +1221 -0
  7. package/dist/carpe-Da7b-LCW.cjs +599 -0
  8. package/dist/carpe-W13mhRRP.js +597 -0
  9. package/dist/cdnService-CZ-aXcY6.cjs +23 -0
  10. package/dist/cdnService-zQfKk3Eb.js +18 -0
  11. package/dist/chatElementDisplayLocation-CX8fuNao.d.cts +239 -0
  12. package/dist/chatElementDisplayLocation-CwptS9tx.d.ts +239 -0
  13. package/dist/chunk-CUT6urMc.cjs +30 -0
  14. package/dist/contexts/index.cjs +13 -0
  15. package/dist/contexts/index.d.cts +65 -0
  16. package/dist/contexts/index.d.ts +66 -0
  17. package/dist/contexts/index.js +7 -0
  18. package/dist/contexts-BRjfVq_k.js +5064 -0
  19. package/dist/contexts-BYArqZtK.cjs +5164 -0
  20. package/dist/coterie-3y0D9ko4.cjs +229 -0
  21. package/dist/coterie-DOWcJAYv.js +229 -0
  22. package/dist/custservice-types-CFIFwZ-r.js +10 -0
  23. package/dist/custservice-types-CkfxZiHY.cjs +16 -0
  24. package/dist/default-C2fEZKXk.js +175 -0
  25. package/dist/default-CBUq6Q6G.cjs +4 -0
  26. package/dist/default-CGIFZK6m.js +4 -0
  27. package/dist/default-D_KPZdPJ.cjs +198 -0
  28. package/dist/divIds-Bss-btao.js +49 -0
  29. package/dist/divIds-DnZNd7rA.cjs +223 -0
  30. package/dist/dreamlandBaby-DCIsuU9R.cjs +338 -0
  31. package/dist/dreamlandBaby-DvSaZGrz.js +338 -0
  32. package/dist/entrypoints-D_JUvkgy.cjs +18 -0
  33. package/dist/entrypoints-YLQsbBRD.js +6 -0
  34. package/dist/enviveConfigContext-CUGLpPGU.js +34 -0
  35. package/dist/enviveConfigContext-Dfr2VH6u.cjs +48 -0
  36. package/dist/fiveCbd-B1SESMCO.js +605 -0
  37. package/dist/fiveCbd-CkOlVby_.cjs +605 -0
  38. package/dist/forLoveAndLemons-CfYPMnKS.cjs +660 -0
  39. package/dist/forLoveAndLemons-DmwYZIk0.js +658 -0
  40. package/dist/greenpan-Bsl3ir59.cjs +389 -0
  41. package/dist/greenpan-BtOi45lf.js +389 -0
  42. package/dist/grooveLife-6_dtYsRk.js +334 -0
  43. package/dist/grooveLife-Cmm1PSCL.cjs +334 -0
  44. package/dist/homegrownCannabis-C-kw-74X.js +400 -0
  45. package/dist/homegrownCannabis-CO0uY_mp.cjs +400 -0
  46. package/dist/hooks/index.cjs +16 -0
  47. package/dist/hooks/index.d.cts +357 -0
  48. package/dist/hooks/index.d.ts +357 -0
  49. package/dist/hooks/index.js +7 -0
  50. package/dist/jackArcher-CLVmwwpI.js +719 -0
  51. package/dist/jackArcher-DdYTIzAV.cjs +719 -0
  52. package/dist/jordanCraig-Am-Oor-O.js +1778 -0
  53. package/dist/jordanCraig-_u3-w4Hp.cjs +1778 -0
  54. package/dist/kindredBravely-CWovIDSc.cjs +482 -0
  55. package/dist/kindredBravely-eWp-ud_E.js +482 -0
  56. package/dist/kutFromTheKloth-BMV4BuGQ.js +361 -0
  57. package/dist/kutFromTheKloth-Q589bAOC.cjs +361 -0
  58. package/dist/larryAndSerges-BMUlTgI-.js +252 -0
  59. package/dist/larryAndSerges-CEau764j.cjs +252 -0
  60. package/dist/leapsAndRebounds-DGMzPO7T.js +352 -0
  61. package/dist/leapsAndRebounds-DHAtRTJD.cjs +352 -0
  62. package/dist/logger-Dln20ans.cjs +25 -0
  63. package/dist/logger-pdEEY8T2.js +19 -0
  64. package/dist/longevityrx-CZW8Hxzi.cjs +312 -0
  65. package/dist/longevityrx-jH2JLhNH.js +312 -0
  66. package/dist/lookOptic-BGXP5P_V.js +274 -0
  67. package/dist/lookOptic-CA6RwLbG.cjs +274 -0
  68. package/dist/mantraBrand-Cm9_PBCT.js +742 -0
  69. package/dist/mantraBrand-DByNqpnL.cjs +742 -0
  70. package/dist/medterra-B0wxj_PV.js +575 -0
  71. package/dist/medterra-DnPN2ksU.cjs +575 -0
  72. package/dist/modells-Bmz8Ag5M.js +476 -0
  73. package/dist/modells-CoYgkLSp.cjs +476 -0
  74. package/dist/models-DHdb7QWn.js +51 -0
  75. package/dist/models-ixxUsGL_.cjs +69 -0
  76. package/dist/pressedFloral-DSKs_oVG.js +653 -0
  77. package/dist/pressedFloral-DjBiSoUl.cjs +653 -0
  78. package/dist/skinPerfection-B_3xzVNS.cjs +326 -0
  79. package/dist/skinPerfection-IDrBuAPt.js +326 -0
  80. package/dist/snapSupplements-BJk5T5ba.js +277 -0
  81. package/dist/snapSupplements-BStTsdOZ.cjs +277 -0
  82. package/dist/socialProofClasses-Bhv2Vulz.js +9 -0
  83. package/dist/socialProofClasses-CrQBWdSA.cjs +39 -0
  84. package/dist/spanx-BYg0LE7R.js +653 -0
  85. package/dist/spanx-LwU1zSzq.cjs +655 -0
  86. package/dist/spanxStaging-CfSmuKYB.js +837 -0
  87. package/dist/spanxStaging-OZLV9qix.cjs +840 -0
  88. package/dist/suggestionBarV2-types-BllzwsBD.js +34 -0
  89. package/dist/suggestionBarV2-types-CaovchMP.cjs +46 -0
  90. package/dist/supergoop-BqPXDnKk.cjs +327 -0
  91. package/dist/supergoop-CIlrHND_.js +325 -0
  92. package/dist/types-C4T5UOIW.cjs +230 -0
  93. package/dist/types-CYNvLeSA.js +176 -0
  94. package/dist/uniqueVintage-B30mOqbH.cjs +1205 -0
  95. package/dist/uniqueVintage-CFueJOhO.js +1203 -0
  96. package/dist/venaCbd-DHGZy49P.cjs +357 -0
  97. package/dist/venaCbd-T0CqVD4k.js +357 -0
  98. package/dist/westonJonBoucher-BdMzs_Yg.cjs +414 -0
  99. package/dist/westonJonBoucher-b4TCQ4ev.js +414 -0
  100. package/dist/wineEnthusiast-BLGlOjgr.cjs +932 -0
  101. package/dist/wineEnthusiast-BqR0i_54.js +932 -0
  102. package/dist/wolfMattress-CyyO-LoC.js +362 -0
  103. package/dist/wolfMattress-DNGZOivg.cjs +362 -0
  104. package/dist/wolfTactical-3Mm2fvVF.js +341 -0
  105. package/dist/wolfTactical-BmXYlFjr.cjs +341 -0
  106. package/package.json +66 -0
  107. package/src/adapters/amplitude/amplitudeAdapter.ts +454 -0
  108. package/src/adapters/amplitude/index.ts +2 -0
  109. package/src/adapters/amplitude/stubAmplitudeAdapter.ts +34 -0
  110. package/src/adapters/spiffy/commerce/api.ts +596 -0
  111. package/src/adapters/spiffy/commerce/exceptions/sessionExceptions.ts +6 -0
  112. package/src/adapters/spiffy/commerce/exceptions/unsupportedProductExceptions.ts +6 -0
  113. package/src/adapters/spiffy/commerce/graphql.ts +184 -0
  114. package/src/application/config/generalStaticConfig.ts +37 -0
  115. package/src/application/logging/logger.ts +29 -0
  116. package/src/application/models/api/context.ts +4 -0
  117. package/src/application/models/api/generationParams.ts +4 -0
  118. package/src/application/models/api/nextMessageRequest.ts +11 -0
  119. package/src/application/models/api/orgAnalyticsConfig.ts +19 -0
  120. package/src/application/models/api/orgConfigResults.ts +40 -0
  121. package/src/application/models/api/organizationConfig.ts +12 -0
  122. package/src/application/models/api/response.ts +132 -0
  123. package/src/application/models/api/responseGenerics.ts +67 -0
  124. package/src/application/models/api/search.ts +26 -0
  125. package/src/application/models/api/suggestion.ts +4 -0
  126. package/src/application/models/api/supportedEventRequest.ts +8 -0
  127. package/src/application/models/api/userEvent.ts +101 -0
  128. package/src/application/models/cachedValue.ts +8 -0
  129. package/src/application/models/chatElementDisplayLocation.ts +22 -0
  130. package/src/application/models/clientDetails.ts +18 -0
  131. package/src/application/models/colorsConfig.ts +28 -0
  132. package/src/application/models/conversationalSearchIds.ts +5 -0
  133. package/src/application/models/dataLayer.ts +45 -0
  134. package/src/application/models/domMutationContinuation.ts +7 -0
  135. package/src/application/models/domObservationStrategy.ts +9 -0
  136. package/src/application/models/events.ts +5 -0
  137. package/src/application/models/featureGates.ts +23 -0
  138. package/src/application/models/frontendConfig.ts +14 -0
  139. package/src/application/models/googleAnalyticsEvents.ts +8 -0
  140. package/src/application/models/graphql/index.ts +2 -0
  141. package/src/application/models/graphql/queries/getMerchantColorsQuery.ts +37 -0
  142. package/src/application/models/graphql/queries/getMerchantFrontendConfigQuery.ts +103 -0
  143. package/src/application/models/graphql/queries/getMerchantOrgIdQuery.ts +11 -0
  144. package/src/application/models/guards/api/index.ts +12 -0
  145. package/src/application/models/guards/api/isApiFormResponse.ts +90 -0
  146. package/src/application/models/guards/api/isApiFormSubmittedResponseAttributes.ts +37 -0
  147. package/src/application/models/guards/api/isApiOrderResponseAttributes.ts +155 -0
  148. package/src/application/models/guards/api/isApiOrgConfigResults.ts +277 -0
  149. package/src/application/models/guards/api/isApiOrganizationConfig.ts +207 -0
  150. package/src/application/models/guards/api/isApiPDPEventAttributes.ts +21 -0
  151. package/src/application/models/guards/api/isApiPLPEventAttributes.ts +41 -0
  152. package/src/application/models/guards/api/isApiPageResponseAttributes.ts +21 -0
  153. package/src/application/models/guards/api/isApiProductResponseAttributes.ts +85 -0
  154. package/src/application/models/guards/api/isApiProductSearchAttributes.ts +23 -0
  155. package/src/application/models/guards/api/isApiProductSearchFilterAttributes.ts +15 -0
  156. package/src/application/models/guards/api/isApiQueryTypedEventAttributes.ts +4 -0
  157. package/src/application/models/guards/api/isApiResponse.ts +39 -0
  158. package/src/application/models/guards/api/isApiReviewResponseAttributes.ts +30 -0
  159. package/src/application/models/guards/api/isApiReviewRichInformation.ts +37 -0
  160. package/src/application/models/guards/api/isApiSearchEventAttributes.ts +28 -0
  161. package/src/application/models/guards/api/isApiSuggestion.ts +36 -0
  162. package/src/application/models/guards/api/isApiSuggestionClickedEventAttributes.ts +9 -0
  163. package/src/application/models/guards/api/isApiTextResponseAttributes.ts +9 -0
  164. package/src/application/models/guards/api/isApiUserEvent.ts +25 -0
  165. package/src/application/models/guards/graphQL/isGraphQLColorsConfig.ts +50 -0
  166. package/src/application/models/guards/isBaseEcommerceEvent.ts +17 -0
  167. package/src/application/models/guards/isGA4EcommerceEvent.ts +17 -0
  168. package/src/application/models/guards/isLegacyUAEcommerceEvent.ts +17 -0
  169. package/src/application/models/guards/isMobilePLPChatPlacementParameter.ts +11 -0
  170. package/src/application/models/guards/isSpanxTakeAQuizCtaParameter.ts +4 -0
  171. package/src/application/models/guards/isVariantInfo.ts +37 -0
  172. package/src/application/models/guards/utils.ts +43 -0
  173. package/src/application/models/index.ts +20 -0
  174. package/src/application/models/localStorageEventListener.ts +4 -0
  175. package/src/application/models/message.ts +146 -0
  176. package/src/application/models/mobilePLPChatPlacementParameter.ts +3 -0
  177. package/src/application/models/orgsEnum.ts +36 -0
  178. package/src/application/models/productExperiment.ts +5 -0
  179. package/src/application/models/spanxTakeAQuizCtaParameter.ts +4 -0
  180. package/src/application/models/spiffyWidgets.ts +16 -0
  181. package/src/application/models/supportedOrgs.ts +137 -0
  182. package/src/application/models/utilityTypes/camelCase.ts +87 -0
  183. package/src/application/models/utilityTypes/camelCasedPropertiesDeep.ts +80 -0
  184. package/src/application/models/utilityTypes/delimiterCase.ts +121 -0
  185. package/src/application/models/utilityTypes/delimiterCasedPropertiesDeep.ts +98 -0
  186. package/src/application/models/utilityTypes/index.ts +1 -0
  187. package/src/application/models/utilityTypes/internal.ts +93 -0
  188. package/src/application/models/utilityTypes/primitive.ts +8 -0
  189. package/src/application/models/utilityTypes/snakeCasedPropertiesDeep.ts +49 -0
  190. package/src/application/models/utilityTypes/splitWords.ts +76 -0
  191. package/src/application/models/utilityTypes/trim.ts +28 -0
  192. package/src/application/models/utilityTypes/unknownArray.ts +25 -0
  193. package/src/application/models/utils/snakeToCamelTransformer.ts +90 -0
  194. package/src/application/models/utils/stringToFulfillmentDisplayStatusEnumValue.ts +68 -0
  195. package/src/application/models/validators/validateGraphQLColorsConfig.ts +29 -0
  196. package/src/application/models/validators/validateGraphQLFrontendConfig.ts +594 -0
  197. package/src/application/models/validators/validateGraphQLOrgId.ts +7 -0
  198. package/src/application/models/validators/validateMobilePLPChatPlacementParameter.ts +14 -0
  199. package/src/application/models/validators/validateOrgConfigResults.ts +47 -0
  200. package/src/application/models/validators/validateOrganizationConfig.ts +37 -0
  201. package/src/application/models/validators/validateResponse.ts +187 -0
  202. package/src/application/models/validators/validateSuggestion.ts +16 -0
  203. package/src/application/models/validators/validateUserEvent.ts +110 -0
  204. package/src/application/models/variantInfo/index.ts +1 -0
  205. package/src/application/models/variantInfo/pageVisitInfo.ts +6 -0
  206. package/src/application/models/variantInfo/plpInfo.ts +3 -0
  207. package/src/application/models/variantInfo/productInfo.ts +5 -0
  208. package/src/application/models/variantInfo/variantInfo.ts +23 -0
  209. package/src/application/service/cachingService.ts +84 -0
  210. package/src/application/service/cdnService.ts +18 -0
  211. package/src/application/service/customerService/index.ts +8 -0
  212. package/src/application/service/customerService/providers/UnsupportedCustomerService.ts +15 -0
  213. package/src/application/service/customerService/types.ts +31 -0
  214. package/src/application/service/domMutationObserver.ts +320 -0
  215. package/src/application/service/domMutations/GridInsertionService.ts +123 -0
  216. package/src/application/service/domMutations/dataLayer/dataLayerEventsListener.ts +99 -0
  217. package/src/application/service/domMutations/domInsertionService.ts +90 -0
  218. package/src/application/service/domMutations/domMutationListener.ts +15 -0
  219. package/src/application/service/domMutations/domMutationListenerState.ts +52 -0
  220. package/src/application/service/domMutations/floatingChat/embeddedChatsPlacementsListener.ts +41 -0
  221. package/src/application/service/domMutations/gladly/gladlyListener.ts +61 -0
  222. package/src/application/service/domMutations/spiffy/orgs/common/kustomerVisibilityListener.ts +41 -0
  223. package/src/application/service/domMutations/spiffy/orgs/common/orgsCommonDataLayerListener.ts +119 -0
  224. package/src/application/service/environmentService.ts +51 -0
  225. package/src/application/service/featureFlagService.ts +130 -0
  226. package/src/application/service/kustomerIntegrationService.ts +111 -0
  227. package/src/application/service/localStorageService.ts +77 -0
  228. package/src/application/service/pageVariantService.ts +779 -0
  229. package/src/application/service/searchService.ts +140 -0
  230. package/src/application/service/sessionStorageService.ts +27 -0
  231. package/src/application/service/shopifyUrlService.ts +63 -0
  232. package/src/application/service/userIdentityService.ts +114 -0
  233. package/src/application/service/windowChatToggleService.ts +71 -0
  234. package/src/application/service/windowDataLayerService.ts +181 -0
  235. package/src/application/service/windowFrontendConfigService.ts +104 -0
  236. package/src/application/utils/__tests__/divideArrays.test.ts +14 -0
  237. package/src/application/utils/analyticsUtils.ts +110 -0
  238. package/src/application/utils/coreContextToApiContext.ts +11 -0
  239. package/src/application/utils/coreUserEventToApiUserEvent.ts +106 -0
  240. package/src/application/utils/divideArray.ts +7 -0
  241. package/src/application/utils/domObserver.ts +96 -0
  242. package/src/application/utils/elementObserver.ts +246 -0
  243. package/src/application/utils/imageFilter.ts +12 -0
  244. package/src/application/utils/index.ts +3 -0
  245. package/src/application/utils/merchantUtils.ts +16 -0
  246. package/src/application/utils/messageFromFormSubmittedEvent.ts +31 -0
  247. package/src/application/utils/messageFromQueryEvent.ts +38 -0
  248. package/src/application/utils/messageFromResponse.ts +133 -0
  249. package/src/application/utils/messageFromSuggestionEvent.ts +32 -0
  250. package/src/application/utils/mouseEventTypes.ts +1 -0
  251. package/src/application/utils/mutationHelper.ts +51 -0
  252. package/src/application/utils/nextMessageRequestToApiRequest.ts +31 -0
  253. package/src/application/utils/nodeSelector.ts +133 -0
  254. package/src/application/utils/overrides.ts +196 -0
  255. package/src/application/utils/stringUtils.ts +55 -0
  256. package/src/application/utils/supportedEventRequestToApiRequest.ts +12 -0
  257. package/src/application/utils/urlsParser.ts +53 -0
  258. package/src/application/utils/validation.ts +5 -0
  259. package/src/atoms/app/index.ts +57 -0
  260. package/src/atoms/app/variant.ts +261 -0
  261. package/src/atoms/atomStore.ts +34 -0
  262. package/src/atoms/chat/chatState.ts +44 -0
  263. package/src/atoms/chat/form.ts +19 -0
  264. package/src/atoms/chat/index.ts +38 -0
  265. package/src/atoms/chat/lastMessage.ts +11 -0
  266. package/src/atoms/chat/messageQueue.ts +65 -0
  267. package/src/atoms/chat/performanceMetrics.ts +84 -0
  268. package/src/atoms/chat/renderedWidgetRefs.ts +28 -0
  269. package/src/atoms/chat/replies.ts +51 -0
  270. package/src/atoms/chat/suggestions.ts +36 -0
  271. package/src/atoms/globalSearch.ts +12 -0
  272. package/src/atoms/index.ts +5 -0
  273. package/src/atoms/org/customerService.ts +13 -0
  274. package/src/atoms/org/graphqlConfig.ts +27 -0
  275. package/src/atoms/org/index.ts +7 -0
  276. package/src/atoms/org/merchantCss.ts +44 -0
  277. package/src/atoms/org/org.ts +256 -0
  278. package/src/atoms/org/orgAnalyticsConfig.ts +28 -0
  279. package/src/atoms/org/orgPageConfig.ts +38 -0
  280. package/src/atoms/org/orgUIConfig.ts +122 -0
  281. package/src/atoms/search/chatSearch.ts +293 -0
  282. package/src/atoms/search/index.ts +2 -0
  283. package/src/atoms/search/productFilters.ts +207 -0
  284. package/src/atoms/search/productSorter.ts +23 -0
  285. package/src/atoms/search/searchAPI.ts +194 -0
  286. package/src/atoms/search/types.ts +55 -0
  287. package/src/atoms/search/utils.ts +18 -0
  288. package/src/config/divIds.ts +27 -0
  289. package/src/config/locators/components/chat/entrypoints.ts +13 -0
  290. package/src/config/locators/components/chat/index.ts +23 -0
  291. package/src/config/locators/components/chat/preview.ts +13 -0
  292. package/src/config/locators/components/chat/variants/index.ts +16 -0
  293. package/src/config/locators/components/common/buttons.ts +6 -0
  294. package/src/config/locators/components/common/cards.ts +18 -0
  295. package/src/config/locators/components/common/links.ts +1 -0
  296. package/src/config/locators/components/common/tables.ts +2 -0
  297. package/src/config/locators/components/floating-button.ts +2 -0
  298. package/src/config/locators/components/index.ts +3 -0
  299. package/src/config/locators/components/report-issue.ts +21 -0
  300. package/src/config/locators/components/search/index.ts +5 -0
  301. package/src/config/locators/components/shadow-dom.ts +1 -0
  302. package/src/config/locators/embedded.ts +21 -0
  303. package/src/config/locators/index.ts +3 -0
  304. package/src/config/socialProofClasses.ts +17 -0
  305. package/src/contexts/chatContext.tsx +451 -0
  306. package/src/contexts/enviveConfigContext.tsx +70 -0
  307. package/src/contexts/index.ts +4 -0
  308. package/src/contexts/systemSettingsContext.tsx +61 -0
  309. package/src/contexts/types.ts +1059 -0
  310. package/src/enabled-features.ts +83 -0
  311. package/src/events/event-types.ts +11 -0
  312. package/src/events/index.ts +52 -0
  313. package/src/events/registerAnalyticsListeners.ts +49 -0
  314. package/src/extension.ts +63 -0
  315. package/src/hooks/index.ts +22 -0
  316. package/src/hooks/useBlockBackButton.ts +29 -0
  317. package/src/hooks/useChatToggle.ts +66 -0
  318. package/src/hooks/useCustomerSupportHandoff.ts +39 -0
  319. package/src/hooks/useDebounce.ts +17 -0
  320. package/src/hooks/useDynamicVariants.ts +210 -0
  321. package/src/hooks/useElementObserver.ts +245 -0
  322. package/src/hooks/useFileUpload.ts +61 -0
  323. package/src/hooks/useGrabAndScroll.ts +133 -0
  324. package/src/hooks/useHideElements.ts +82 -0
  325. package/src/hooks/useHorizontalScrollAnimation.ts +115 -0
  326. package/src/hooks/useImageResolver.ts +51 -0
  327. package/src/hooks/useIntersection.ts +28 -0
  328. package/src/hooks/useIsSmallScreen.ts +23 -0
  329. package/src/hooks/useMessageFilter.ts +49 -0
  330. package/src/hooks/useMessageScrollObserver.ts +47 -0
  331. package/src/hooks/useReducedMotionWithOverride.ts +15 -0
  332. package/src/hooks/useSearch.tsx +433 -0
  333. package/src/hooks/useSnapCalculator.ts +38 -0
  334. package/src/hooks/useSnapControl.ts +155 -0
  335. package/src/hooks/useSystemSettingsContext.ts +12 -0
  336. package/src/hooks/useTrackComponentVisibleEvent.ts +52 -0
  337. package/src/hooks/useUpdateAnalyticsProps.ts +56 -0
  338. package/src/hooks/utils.ts +153 -0
  339. package/src/index.ts +31 -0
  340. package/src/initialize.ts +163 -0
  341. package/src/interceptors/types.ts +6 -0
  342. package/src/interceptors/useFormEscalation.ts +40 -0
  343. package/src/interceptors/useMessageInterceptor.ts +32 -0
  344. package/src/main.ts +85 -0
  345. package/src/main.tsx +123 -0
  346. package/src/merchants/bandolier/bandolier.ts +1389 -0
  347. package/src/merchants/carpe/carpe.ts +656 -0
  348. package/src/merchants/coterie/coterie.ts +280 -0
  349. package/src/merchants/default.ts +193 -0
  350. package/src/merchants/dreamlandBaby/dreamlandBaby.ts +375 -0
  351. package/src/merchants/fiveCbd/fiveCbd.ts +697 -0
  352. package/src/merchants/forLoveAndLemons/forLoveAndLemons.ts +721 -0
  353. package/src/merchants/greenpan/greenpan.ts +440 -0
  354. package/src/merchants/grooveLife/grooveLife.ts +386 -0
  355. package/src/merchants/homegrownCannabis/homegrownCannabis.ts +468 -0
  356. package/src/merchants/init-merchant.sh +53 -0
  357. package/src/merchants/jackArcher/jackArcher.ts +974 -0
  358. package/src/merchants/jordanCraig/jordanCraig.ts +1927 -0
  359. package/src/merchants/kindredBravely/kindredBravely.ts +529 -0
  360. package/src/merchants/kutFromTheKloth/kutFromTheKloth.ts +418 -0
  361. package/src/merchants/larryAndSerges/larryAndSerges.ts +314 -0
  362. package/src/merchants/leapsAndRebounds/leapsAndRebounds.ts +424 -0
  363. package/src/merchants/longevityrx/longevityrx.ts +368 -0
  364. package/src/merchants/lookOptic/lookOptic.ts +323 -0
  365. package/src/merchants/mantraBrand/mantraBrand.ts +838 -0
  366. package/src/merchants/medterra/medterra.ts +670 -0
  367. package/src/merchants/modells/modells.ts +546 -0
  368. package/src/merchants/pressedFloral/pressedFloral.ts +734 -0
  369. package/src/merchants/skinPerfection/skinPerfection.ts +379 -0
  370. package/src/merchants/snapSupplements/snapSupplements.ts +325 -0
  371. package/src/merchants/spanx/spanx.ts +810 -0
  372. package/src/merchants/spanx/spanxStaging.ts +942 -0
  373. package/src/merchants/supergoop/supergoop.ts +376 -0
  374. package/src/merchants/uniqueVintage/uniqueVintage.ts +1314 -0
  375. package/src/merchants/uniqueVintage/views/useUniqueVintageChatSearch.ts +147 -0
  376. package/src/merchants/venaCbd/venaCbd.ts +410 -0
  377. package/src/merchants/westonJonBoucher/westonJonBoucher.ts +473 -0
  378. package/src/merchants/wineEnthusiast/wineEnthusiast.ts +990 -0
  379. package/src/merchants/wolfMattress/wolfMattress.ts +411 -0
  380. package/src/merchants/wolfTactical/wolfTactical.ts +389 -0
  381. package/src/types/custservice-types.ts +28 -0
  382. package/src/types/search-filter-types.ts +111 -0
  383. package/src/types/suggestionBarV2-types.ts +4 -0
  384. package/src/types/test-types.ts +3 -0
  385. 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,7 @@
1
+ export const validateGraphQLOrgId = (data: unknown): string | undefined => {
2
+ if (typeof data !== 'string' || data === '') {
3
+ return undefined;
4
+ }
5
+
6
+ return data;
7
+ };
@@ -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
+ };