@faststore/core 3.99.1 → 4.0.0-dev.1

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 (543) hide show
  1. package/.turbo/turbo-generate.log +29 -0
  2. package/.turbo/turbo-test.log +47 -16
  3. package/@generated/cached-operations.json +24 -0
  4. package/@generated/gql.ts +134 -210
  5. package/@generated/graphql.ts +1628 -3037
  6. package/@generated/index.ts +1 -1
  7. package/@generated/persisted-documents.json +1 -1
  8. package/@generated/schema.graphql +1854 -1743
  9. package/CHANGELOG.md +11 -5
  10. package/README.md +2 -1
  11. package/api/index.ts +6 -7
  12. package/cms/faststore/base.jsonc +1 -1
  13. package/cms/faststore/components/cms_component__alert.jsonc +5 -1
  14. package/cms/faststore/components/cms_component__bannernewsletter.jsonc +5 -1
  15. package/cms/faststore/components/cms_component__bannertext.jsonc +5 -1
  16. package/cms/faststore/components/cms_component__breadcrumb.jsonc +16 -4
  17. package/cms/faststore/components/cms_component__cartsidebar.jsonc +21 -1
  18. package/cms/faststore/components/cms_component__children.jsonc +5 -1
  19. package/cms/faststore/components/cms_component__crosssellingshelf.jsonc +5 -1
  20. package/cms/faststore/components/cms_component__emptystate.jsonc +8 -3
  21. package/cms/faststore/components/cms_component__footer.jsonc +9 -3
  22. package/cms/faststore/components/cms_component__hero.jsonc +5 -1
  23. package/cms/faststore/components/cms_component__incentives.jsonc +5 -1
  24. package/cms/faststore/components/cms_component__navbar.jsonc +139 -1
  25. package/cms/faststore/components/cms_component__newsletter.jsonc +5 -1
  26. package/cms/faststore/components/cms_component__productdetails.jsonc +33 -1
  27. package/cms/faststore/components/cms_component__productgallery.jsonc +113 -15
  28. package/cms/faststore/components/cms_component__productshelf.jsonc +5 -1
  29. package/cms/faststore/components/cms_component__producttiles.jsonc +5 -1
  30. package/cms/faststore/components/cms_component__regionbar.jsonc +5 -1
  31. package/cms/faststore/components/cms_component__regionmodal.jsonc +5 -1
  32. package/cms/faststore/components/cms_component__regionpopover.jsonc +5 -1
  33. package/cms/faststore/components/cms_component__scrolltotopbutton.jsonc +29 -0
  34. package/cms/faststore/components/cms_component__search.jsonc +5 -1
  35. package/cms/faststore/content-types.json +115 -0
  36. package/cms/faststore/pages/cms_content_type__globalsections.jsonc +52 -0
  37. package/cms/faststore/pages/cms_content_type__home.jsonc +6 -0
  38. package/cms/faststore/pages/cms_content_type__landingpage.jsonc +8 -1
  39. package/cms/faststore/pages/cms_content_type__pdp.jsonc +6 -0
  40. package/cms/faststore/pages/cms_content_type__plp.jsonc +17 -0
  41. package/cms/faststore/pages/cms_content_type__search.jsonc +17 -0
  42. package/cms/faststore/schema.json +547 -43
  43. package/cms/faststore/sections.json +330 -21
  44. package/discovery.config.default.js +49 -3
  45. package/next-env.d.ts +2 -1
  46. package/next.config.js +48 -26
  47. package/package.json +47 -60
  48. package/public/icons.svg +5 -1
  49. package/scripts/i18n.js +76 -0
  50. package/src/components/account/MyAccountDrawer/OrganizationDrawer/OrganizationDrawer.tsx +2 -1
  51. package/src/components/account/MyAccountDrawer/OrganizationDrawer/section.module.scss +25 -24
  52. package/src/components/account/MyAccountDrawer/ProfileSummary/profile-summary.scss +8 -6
  53. package/src/components/account/MyAccountLayout/styles.scss +16 -12
  54. package/src/components/account/MyAccountMenu/styles.scss +21 -22
  55. package/src/components/account/MyAccountUserDetails/styles.module.scss +4 -2
  56. package/src/components/account/components/MyAccountAccordion/styles.scss +4 -2
  57. package/src/components/account/components/MyAccountHeader/styles.scss +3 -1
  58. package/src/components/account/components/MyAccountTable/styles.scss +6 -4
  59. package/src/components/account/orders/MyAccountListOrders/MyAccountFilterSlider/section.module.scss +21 -19
  60. package/src/components/account/orders/MyAccountListOrders/MyAccountListOrdersTable/MyAccountListOrdersTable.tsx +3 -1
  61. package/src/components/account/orders/MyAccountListOrders/MyAccountListOrdersTable/styles.scss +5 -3
  62. package/src/components/account/orders/MyAccountListOrders/styles.module.scss +25 -22
  63. package/src/components/account/orders/MyAccountOrderDetails/MyAccountBudgetsCard/styles.scss +7 -5
  64. package/src/components/account/orders/MyAccountOrderDetails/MyAccountDeliveryOptionAccordion/styles.scss +7 -5
  65. package/src/components/account/orders/MyAccountOrderDetails/MyAccountMoreInformationCard/styles.scss +3 -1
  66. package/src/components/account/orders/MyAccountOrderDetails/MyAccountOrderActionModal/styles.module.scss +8 -6
  67. package/src/components/account/orders/MyAccountOrderDetails/MyAccountOrderActions/styles.scss +3 -1
  68. package/src/components/account/orders/MyAccountOrderDetails/MyAccountStatusCard/styles.scss +8 -6
  69. package/src/components/account/orders/MyAccountOrderDetails/section.module.scss +36 -43
  70. package/src/components/account/profile/profile.module.scss +3 -1
  71. package/src/components/account/section.module.scss +3 -1
  72. package/src/components/account/security/styles.module.scss +14 -8
  73. package/src/components/cart/CartSidebar/CartSidebar.tsx +10 -1
  74. package/src/components/cart/CartSidebar/section.module.scss +19 -17
  75. package/src/components/cart/EmptyCart/EmptyCart.tsx +12 -4
  76. package/src/components/cms/GlobalSections.tsx +12 -12
  77. package/src/components/cms/RenderSections.tsx +10 -2
  78. package/src/components/cms/plp/Components.ts +9 -0
  79. package/src/components/common/Alert/section.module.scss +10 -5
  80. package/src/components/common/PreviewTag/section.module.scss +48 -40
  81. package/src/components/common/Toast/section.module.scss +4 -2
  82. package/src/components/localization/LocalizationSelector/LocalizationSelector.tsx +320 -0
  83. package/src/components/localization/LocalizationSelector/index.ts +1 -0
  84. package/src/components/localization/LocalizationSelector/section.module.scss +18 -0
  85. package/src/components/localization/index.ts +1 -0
  86. package/src/components/navigation/Navbar/Navbar.tsx +49 -1
  87. package/src/components/navigation/NavbarSlider/NavbarSlider.tsx +19 -1
  88. package/src/components/navigation/NavbarSlider/section.module.scss +12 -10
  89. package/src/components/product/OutOfStock/OutOfStock.tsx +6 -1
  90. package/src/components/product/ProductCard/ProductCard.tsx +1 -1
  91. package/src/components/region/RegionModal/RegionModal.tsx +4 -1
  92. package/src/components/region/RegionModal/section.module.scss +10 -8
  93. package/src/components/region/RegionPopover/RegionPopover.tsx +6 -5
  94. package/src/components/region/RegionPopover/section.module.scss +9 -7
  95. package/src/components/region/RegionSlider/RegionSlider.tsx +5 -2
  96. package/src/components/region/RegionSlider/section.module.scss +16 -13
  97. package/src/components/search/Filter/FilterDeliveryMethodFacet.tsx +5 -5
  98. package/src/components/search/Filter/FilterDesktop.tsx +13 -4
  99. package/src/components/search/Filter/FilterSlider.tsx +18 -6
  100. package/src/components/search/Filter/section.module.scss +21 -19
  101. package/src/components/search/SearchDropdown/SearchDropdown.tsx +9 -7
  102. package/src/components/search/SearchHistory/SearchHistory.tsx +7 -2
  103. package/src/components/search/SearchInput/SearchInput.tsx +21 -8
  104. package/src/components/search/SearchProductItem/SearchProductItem.tsx +10 -3
  105. package/src/components/search/SearchTop/SearchTop.tsx +30 -24
  106. package/src/components/search/Sort/Sort.tsx +17 -19
  107. package/src/components/sections/Alert/Alert.tsx +6 -1
  108. package/src/components/sections/BannerNewsletter/section.module.scss +6 -4
  109. package/src/components/sections/BannerText/section.module.scss +5 -3
  110. package/src/components/sections/Breadcrumb/Breadcrumb.tsx +6 -2
  111. package/src/components/sections/Breadcrumb/section.module.scss +7 -5
  112. package/src/components/sections/EmptyState/section.module.scss +5 -3
  113. package/src/components/sections/Footer/Footer.tsx +1 -5
  114. package/src/components/sections/Footer/section.module.scss +10 -8
  115. package/src/components/sections/Hero/Hero.tsx +3 -1
  116. package/src/components/sections/Hero/section.module.scss +6 -4
  117. package/src/components/sections/Incentives/section.module.scss +5 -3
  118. package/src/components/sections/Navbar/Navbar.tsx +45 -0
  119. package/src/components/sections/Navbar/section.module.scss +34 -33
  120. package/src/components/sections/Newsletter/section.module.scss +10 -8
  121. package/src/components/sections/ProductDetails/ProductDetails.tsx +23 -1
  122. package/src/components/sections/ProductDetails/section.module.scss +32 -30
  123. package/src/components/sections/ProductGallery/EmptyGallery.tsx +13 -16
  124. package/src/components/sections/ProductGallery/section.module.scss +42 -39
  125. package/src/components/sections/ProductShelf/section.module.scss +22 -17
  126. package/src/components/sections/ProductTiles/section.module.scss +15 -13
  127. package/src/components/sections/RegionBar/section.module.scss +5 -3
  128. package/src/components/sections/ScrollToTopButton/ScrollToTopButton.tsx +4 -3
  129. package/src/components/sections/ScrollToTopButton/section.module.scss +4 -2
  130. package/src/components/templates/LandingPage/LandingPage.tsx +22 -16
  131. package/src/components/templates/ProductListingPage/ProductListing.tsx +1 -13
  132. package/src/components/templates/ProductListingPage/ProductListingPage.tsx +8 -3
  133. package/src/components/ui/Breadcrumb/Breadcrumb.tsx +14 -11
  134. package/src/components/ui/Button/ButtonSignIn/ButtonSignIn.tsx +2 -1
  135. package/src/components/ui/Button/ButtonSignIn/ButtonSignInFallback/ButtonSignInFallback.tsx +3 -1
  136. package/src/components/ui/Link/Link.tsx +19 -2
  137. package/src/components/ui/LinkButton/LinkButton.tsx +28 -0
  138. package/src/components/ui/LinkButton/index.ts +2 -0
  139. package/src/components/ui/LocalizationButton/LocalizationButton.tsx +124 -0
  140. package/src/components/ui/LocalizationButton/index.ts +1 -0
  141. package/src/components/ui/PickupPoints/PickupPointCards.tsx +2 -4
  142. package/src/components/ui/ProductComparison/ProductComparisonSidebar.tsx +34 -17
  143. package/src/components/ui/ProductDescription/ProductDescription.tsx +8 -3
  144. package/src/components/ui/ProductDetails/AddToCartLoadingSkeleton.tsx +6 -2
  145. package/src/components/ui/ProductDetails/ProductDetailsSettings.tsx +17 -5
  146. package/src/components/ui/ProductGallery/ProductGallery.tsx +7 -3
  147. package/src/components/ui/ProductGallery/ProductGalleryPage.tsx +1 -3
  148. package/src/components/ui/ShippingSimulation/ShippingSimulation.tsx +6 -1
  149. package/src/customizations/src/styles/custom-mixins.scss +0 -2
  150. package/src/experimental/index.ts +26 -0
  151. package/src/experimental/myAccountServerSideProps.ts +11 -2
  152. package/src/experimental/searchServerSideFunctions/getServerSideProps.ts +13 -7
  153. package/src/experimental/searchServerSideFunctions/getStaticProps.ts +5 -4
  154. package/src/instrumentation.ts +20 -6
  155. package/src/pages/404.tsx +5 -4
  156. package/src/pages/500.tsx +5 -4
  157. package/src/pages/[...slug].tsx +7 -4
  158. package/src/pages/[slug]/p.tsx +26 -8
  159. package/src/pages/_app.tsx +9 -1
  160. package/src/pages/api/fs/logout.ts +3 -2
  161. package/src/pages/api/graphql.ts +7 -23
  162. package/src/pages/api/preview.ts +21 -8
  163. package/src/pages/checkout.tsx +15 -5
  164. package/src/pages/index.tsx +18 -9
  165. package/src/pages/login.tsx +5 -4
  166. package/src/pages/pvt/account/403.tsx +11 -2
  167. package/src/pages/pvt/account/404.tsx +13 -3
  168. package/src/pages/pvt/account/index.tsx +6 -4
  169. package/src/pages/pvt/account/orders/[id].tsx +11 -3
  170. package/src/pages/pvt/account/orders/index.tsx +11 -3
  171. package/src/pages/pvt/account/profile.tsx +11 -2
  172. package/src/pages/pvt/account/security.tsx +11 -2
  173. package/src/pages/pvt/account/user-details.tsx +11 -2
  174. package/src/pages/s.tsx +26 -6
  175. package/src/proxy.ts +154 -0
  176. package/src/sdk/account/refreshToken.ts +4 -4
  177. package/src/sdk/account/useReorder.ts +8 -2
  178. package/src/sdk/analytics/platform/vtex/search.ts +3 -2
  179. package/src/sdk/cart/redirectToCheckout.ts +14 -8
  180. package/src/sdk/cart/useCheckoutButton.ts +7 -1
  181. package/src/sdk/deliveryPromise/useDeliveryPromise.ts +10 -18
  182. package/src/sdk/graphql/request.ts +102 -50
  183. package/src/sdk/localization/bindingSelector.ts +91 -0
  184. package/src/sdk/localization/index.ts +4 -0
  185. package/src/sdk/localization/match-url.ts +64 -0
  186. package/src/sdk/localization/types.ts +31 -0
  187. package/src/sdk/localization/useBindingSelector.ts +183 -0
  188. package/src/sdk/localization/useLocaleValidation.ts +49 -0
  189. package/src/sdk/localization/useLocalizationConfig.tsx +160 -0
  190. package/src/sdk/offer/fetcher.ts +3 -2
  191. package/src/sdk/product/useLocalizedVariables.ts +1 -1
  192. package/src/sdk/product/usePageProductsQuery.ts +2 -2
  193. package/src/sdk/product/useProductGalleryQuery.ts +1 -2
  194. package/src/sdk/product/useProductLink.ts +3 -1
  195. package/src/sdk/search/formatSearchPath.ts +28 -3
  196. package/src/sdk/search/state.ts +22 -13
  197. package/src/sdk/search/useSearchBase.ts +10 -0
  198. package/src/sdk/search/useSearchHistory.ts +41 -7
  199. package/src/sdk/session/index.ts +21 -3
  200. package/src/sdk/shipping/useShippingSimulation.ts +10 -2
  201. package/src/sdk/tsconfig.json +6 -0
  202. package/src/sdk/ui/useLink.ts +48 -0
  203. package/src/server/cms/global.ts +40 -0
  204. package/src/server/cms/index.ts +18 -10
  205. package/src/server/cms/pdp.ts +1 -0
  206. package/src/server/cms/plp.ts +3 -0
  207. package/src/server/content/service.ts +36 -24
  208. package/src/server/content/types.ts +10 -3
  209. package/src/server/index.ts +27 -20
  210. package/src/server/options.ts +27 -2
  211. package/src/styles/global/index.scss +10 -7
  212. package/src/styles/main.scss +3 -3
  213. package/src/typings/locales.ts +41 -0
  214. package/src/utils/fetchProductGallerySSR.ts +3 -1
  215. package/src/utils/getBaseDomain.ts +2 -1
  216. package/src/utils/getRequestHostname.ts +26 -0
  217. package/src/utils/globalSettings.ts +11 -0
  218. package/src/utils/localization/bindingPaths.ts +337 -0
  219. package/src/utils/localization/validateLocaleForHostname.ts +69 -0
  220. package/src/utils/localization/withLocaleValidation.ts +36 -0
  221. package/src/utils/utilities.ts +22 -0
  222. package/test/pages/api/preview.test.ts +93 -0
  223. package/test/sdk/localization/bindingSelector.test.ts +246 -0
  224. package/test/sdk/localization/store-url.browser.test.ts +140 -0
  225. package/test/sdk/localization/store-url.test.ts +96 -0
  226. package/test/sdk/localization/useBindingSelector.test.tsx +219 -0
  227. package/test/sdk/search/useSearchHistory.test.ts +222 -0
  228. package/test/server/cms/index.test.ts +3 -4
  229. package/test/server/content/service.test.ts +98 -0
  230. package/test/server/index.test.ts +10 -22
  231. package/test/utils/cookieCacheBusting.test.ts +32 -24
  232. package/test/utils/getRequestHostname.test.ts +71 -0
  233. package/test/utils/localization/bindingPaths.test.ts +706 -0
  234. package/test/utils/match-url.test.ts +388 -0
  235. package/tsconfig.json +11 -3
  236. package/vitest.config.ts +61 -0
  237. package/.next/BUILD_ID +0 -1
  238. package/.next/build-manifest.json +0 -197
  239. package/.next/cache/.tsbuildinfo +0 -1
  240. package/.next/cache/config.json +0 -7
  241. package/.next/cache/webpack/client-production/0.pack +0 -0
  242. package/.next/cache/webpack/client-production/index.pack +0 -0
  243. package/.next/cache/webpack/edge-server-production/0.pack +0 -0
  244. package/.next/cache/webpack/edge-server-production/index.pack +0 -0
  245. package/.next/cache/webpack/server-production/0.pack +0 -0
  246. package/.next/cache/webpack/server-production/index.pack +0 -0
  247. package/.next/export-marker.json +0 -1
  248. package/.next/images-manifest.json +0 -1
  249. package/.next/next-minimal-server.js.nft.json +0 -1
  250. package/.next/next-server.js.nft.json +0 -1
  251. package/.next/package.json +0 -1
  252. package/.next/prerender-manifest.js +0 -1
  253. package/.next/prerender-manifest.json +0 -1
  254. package/.next/react-loadable-manifest.json +0 -478
  255. package/.next/required-server-files.json +0 -1
  256. package/.next/routes-manifest.json +0 -1
  257. package/.next/server/chunks/1280.js +0 -1
  258. package/.next/server/chunks/1454.js +0 -1
  259. package/.next/server/chunks/1554.js +0 -1
  260. package/.next/server/chunks/1607.js +0 -1
  261. package/.next/server/chunks/1780.js +0 -1
  262. package/.next/server/chunks/1917.js +0 -1
  263. package/.next/server/chunks/1972.js +0 -1
  264. package/.next/server/chunks/2230.js +0 -1
  265. package/.next/server/chunks/2249.js +0 -1
  266. package/.next/server/chunks/2430.js +0 -1
  267. package/.next/server/chunks/2445.js +0 -12
  268. package/.next/server/chunks/2570.js +0 -1
  269. package/.next/server/chunks/2792.js +0 -1
  270. package/.next/server/chunks/2903.js +0 -1
  271. package/.next/server/chunks/294.js +0 -1
  272. package/.next/server/chunks/2955.js +0 -1
  273. package/.next/server/chunks/3006.js +0 -1
  274. package/.next/server/chunks/3029.js +0 -1
  275. package/.next/server/chunks/3060.js +0 -1
  276. package/.next/server/chunks/3408.js +0 -1
  277. package/.next/server/chunks/3483.js +0 -1
  278. package/.next/server/chunks/3683.js +0 -1
  279. package/.next/server/chunks/3836.js +0 -1
  280. package/.next/server/chunks/3890.js +0 -494
  281. package/.next/server/chunks/3922.js +0 -1
  282. package/.next/server/chunks/3945.js +0 -1
  283. package/.next/server/chunks/3951.js +0 -7
  284. package/.next/server/chunks/416.js +0 -1
  285. package/.next/server/chunks/4194.js +0 -1
  286. package/.next/server/chunks/4365.js +0 -1
  287. package/.next/server/chunks/4451.js +0 -1
  288. package/.next/server/chunks/4803.js +0 -1
  289. package/.next/server/chunks/4913.js +0 -13
  290. package/.next/server/chunks/5402.js +0 -1
  291. package/.next/server/chunks/5723.js +0 -13
  292. package/.next/server/chunks/5796.js +0 -1
  293. package/.next/server/chunks/6393.js +0 -1
  294. package/.next/server/chunks/6457.js +0 -6
  295. package/.next/server/chunks/6698.js +0 -1
  296. package/.next/server/chunks/6804.js +0 -6
  297. package/.next/server/chunks/6886.js +0 -1
  298. package/.next/server/chunks/7098.js +0 -9
  299. package/.next/server/chunks/7169.js +0 -1
  300. package/.next/server/chunks/7228.js +0 -1
  301. package/.next/server/chunks/7275.js +0 -1
  302. package/.next/server/chunks/7371.js +0 -1
  303. package/.next/server/chunks/7692.js +0 -1
  304. package/.next/server/chunks/7799.js +0 -1
  305. package/.next/server/chunks/8068.js +0 -1
  306. package/.next/server/chunks/83.js +0 -1
  307. package/.next/server/chunks/831.js +0 -1
  308. package/.next/server/chunks/8563.js +0 -1
  309. package/.next/server/chunks/8569.js +0 -1
  310. package/.next/server/chunks/8687.js +0 -1
  311. package/.next/server/chunks/870.js +0 -1
  312. package/.next/server/chunks/8737.js +0 -1
  313. package/.next/server/chunks/8741.js +0 -1
  314. package/.next/server/chunks/9088.js +0 -1
  315. package/.next/server/chunks/9117.js +0 -1
  316. package/.next/server/chunks/9237.js +0 -1
  317. package/.next/server/chunks/948.js +0 -3
  318. package/.next/server/chunks/9563.js +0 -3
  319. package/.next/server/chunks/9570.js +0 -1
  320. package/.next/server/chunks/9740.js +0 -1
  321. package/.next/server/chunks/9853.js +0 -1
  322. package/.next/server/chunks/9984.js +0 -1
  323. package/.next/server/chunks/9985.js +0 -1
  324. package/.next/server/chunks/9990.js +0 -1
  325. package/.next/server/chunks/ButtonSignIn.js +0 -1
  326. package/.next/server/chunks/Dropdown.js +0 -1
  327. package/.next/server/chunks/DropdownButton.js +0 -1
  328. package/.next/server/chunks/DropdownItem.js +0 -1
  329. package/.next/server/chunks/DropdownMenu.js +0 -1
  330. package/.next/server/chunks/FilterSkeleton.js +0 -1
  331. package/.next/server/chunks/ScrollToTopButton.js +0 -1
  332. package/.next/server/chunks/UIBannerText.js +0 -1
  333. package/.next/server/chunks/UISKUMatrixSidebar.js +0 -1
  334. package/.next/server/chunks/font-manifest.json +0 -1
  335. package/.next/server/edge-instrumentation.js +0 -2
  336. package/.next/server/edge-instrumentation.js.map +0 -1
  337. package/.next/server/edge-runtime-webpack.js +0 -157
  338. package/.next/server/edge-runtime-webpack.js.map +0 -1
  339. package/.next/server/font-manifest.json +0 -1
  340. package/.next/server/functions-config-manifest.json +0 -1
  341. package/.next/server/instrumentation.js +0 -1
  342. package/.next/server/instrumentation.js.nft.json +0 -1
  343. package/.next/server/middleware-build-manifest.js +0 -1
  344. package/.next/server/middleware-manifest.json +0 -6
  345. package/.next/server/middleware-react-loadable-manifest.js +0 -1
  346. package/.next/server/next-font-manifest.js +0 -1
  347. package/.next/server/next-font-manifest.json +0 -1
  348. package/.next/server/pages/404.js +0 -1
  349. package/.next/server/pages/404.js.nft.json +0 -1
  350. package/.next/server/pages/500.js +0 -1
  351. package/.next/server/pages/500.js.nft.json +0 -1
  352. package/.next/server/pages/[...slug].js +0 -1
  353. package/.next/server/pages/[...slug].js.nft.json +0 -1
  354. package/.next/server/pages/[slug]/p.js +0 -1
  355. package/.next/server/pages/[slug]/p.js.nft.json +0 -1
  356. package/.next/server/pages/_app.js +0 -1
  357. package/.next/server/pages/_app.js.nft.json +0 -1
  358. package/.next/server/pages/_document.js +0 -1
  359. package/.next/server/pages/_document.js.nft.json +0 -1
  360. package/.next/server/pages/_error.js +0 -1
  361. package/.next/server/pages/_error.js.nft.json +0 -1
  362. package/.next/server/pages/api/fs/logout.js +0 -1
  363. package/.next/server/pages/api/fs/logout.js.nft.json +0 -1
  364. package/.next/server/pages/api/graphql.js +0 -3
  365. package/.next/server/pages/api/graphql.js.nft.json +0 -1
  366. package/.next/server/pages/api/health/live.js +0 -1
  367. package/.next/server/pages/api/health/live.js.nft.json +0 -1
  368. package/.next/server/pages/api/health/ready.js +0 -1
  369. package/.next/server/pages/api/health/ready.js.nft.json +0 -1
  370. package/.next/server/pages/api/preview.js +0 -1
  371. package/.next/server/pages/api/preview.js.nft.json +0 -1
  372. package/.next/server/pages/checkout.js +0 -1
  373. package/.next/server/pages/checkout.js.nft.json +0 -1
  374. package/.next/server/pages/en-US/404.html +0 -42
  375. package/.next/server/pages/en-US/404.json +0 -1
  376. package/.next/server/pages/en-US/500.html +0 -42
  377. package/.next/server/pages/en-US/500.json +0 -1
  378. package/.next/server/pages/en-US/checkout.html +0 -42
  379. package/.next/server/pages/en-US/checkout.json +0 -1
  380. package/.next/server/pages/en-US/login.html +0 -42
  381. package/.next/server/pages/en-US/login.json +0 -1
  382. package/.next/server/pages/en-US/s.html +0 -42
  383. package/.next/server/pages/en-US/s.json +0 -1
  384. package/.next/server/pages/en-US.html +0 -42
  385. package/.next/server/pages/en-US.json +0 -1
  386. package/.next/server/pages/index.js +0 -1
  387. package/.next/server/pages/index.js.nft.json +0 -1
  388. package/.next/server/pages/login.js +0 -1
  389. package/.next/server/pages/login.js.nft.json +0 -1
  390. package/.next/server/pages/pvt/account/403.js +0 -1
  391. package/.next/server/pages/pvt/account/403.js.nft.json +0 -1
  392. package/.next/server/pages/pvt/account/404.js +0 -1
  393. package/.next/server/pages/pvt/account/404.js.nft.json +0 -1
  394. package/.next/server/pages/pvt/account/[...unknown].js +0 -1
  395. package/.next/server/pages/pvt/account/[...unknown].js.nft.json +0 -1
  396. package/.next/server/pages/pvt/account/orders/[id].js +0 -1
  397. package/.next/server/pages/pvt/account/orders/[id].js.nft.json +0 -1
  398. package/.next/server/pages/pvt/account/orders.js +0 -1
  399. package/.next/server/pages/pvt/account/orders.js.nft.json +0 -1
  400. package/.next/server/pages/pvt/account/profile.js +0 -1
  401. package/.next/server/pages/pvt/account/profile.js.nft.json +0 -1
  402. package/.next/server/pages/pvt/account/security.js +0 -1
  403. package/.next/server/pages/pvt/account/security.js.nft.json +0 -1
  404. package/.next/server/pages/pvt/account/user-details.js +0 -1
  405. package/.next/server/pages/pvt/account/user-details.js.nft.json +0 -1
  406. package/.next/server/pages/pvt/account.js +0 -1
  407. package/.next/server/pages/pvt/account.js.nft.json +0 -1
  408. package/.next/server/pages/s.js +0 -1
  409. package/.next/server/pages/s.js.nft.json +0 -1
  410. package/.next/server/pages-manifest.json +0 -1
  411. package/.next/server/webpack-api-runtime.js +0 -1
  412. package/.next/server/webpack-runtime.js +0 -1
  413. package/.next/static/NAuY8lqaeBBZf9CMZuYI2/_buildManifest.js +0 -1
  414. package/.next/static/NAuY8lqaeBBZf9CMZuYI2/_ssgManifest.js +0 -1
  415. package/.next/static/chunks/227-f109b24190a008ab.js +0 -8
  416. package/.next/static/chunks/2284.185d834d9829b652.js +0 -1
  417. package/.next/static/chunks/2851.e68ed3c8d27a032a.js +0 -1
  418. package/.next/static/chunks/2927.5a79877943a6bf7c.js +0 -1
  419. package/.next/static/chunks/3155.7bc4c730a79d9ecb.js +0 -1
  420. package/.next/static/chunks/3166-0b30a3887c0c346d.js +0 -1
  421. package/.next/static/chunks/3399.017c5209b74b0d97.js +0 -1
  422. package/.next/static/chunks/3483.ef53d632a763da3f.js +0 -1
  423. package/.next/static/chunks/349.b3b38e1e9f719dda.js +0 -1
  424. package/.next/static/chunks/3802.5e8b0b689eacc0f8.js +0 -1
  425. package/.next/static/chunks/3836.620480018be48233.js +0 -1
  426. package/.next/static/chunks/4436.e7af66f0b654ee36.js +0 -1
  427. package/.next/static/chunks/4803.b1920b6e3a1a6304.js +0 -1
  428. package/.next/static/chunks/5796.4351370494d8b8b6.js +0 -1
  429. package/.next/static/chunks/6393.55f991b1a6bb4fe7.js +0 -1
  430. package/.next/static/chunks/6700.b23221a57514e737.js +0 -1
  431. package/.next/static/chunks/6789.960162355435a81d.js +0 -1
  432. package/.next/static/chunks/7191-befad64ba238a817.js +0 -1
  433. package/.next/static/chunks/7692.8d5bf4560341a2f6.js +0 -1
  434. package/.next/static/chunks/7861.7f9f1a124a43da30.js +0 -6
  435. package/.next/static/chunks/8068.43663fb64762f7b8.js +0 -1
  436. package/.next/static/chunks/83.e0c16f0299b364a5.js +0 -1
  437. package/.next/static/chunks/8325.dabe9aa22eaadeed.js +0 -1
  438. package/.next/static/chunks/8587.53c8ce185ed1a2cb.js +0 -1
  439. package/.next/static/chunks/9173-e89da04079c35360.js +0 -2
  440. package/.next/static/chunks/9237.7555603703f81bf7.js +0 -1
  441. package/.next/static/chunks/9298-1d1ed0a54133cb59.js +0 -28
  442. package/.next/static/chunks/9399.d116a7fd62024783.js +0 -1
  443. package/.next/static/chunks/941.3e2782ab9c490eb0.js +0 -1
  444. package/.next/static/chunks/9701.f9a0bfffba8807dc.js +0 -1
  445. package/.next/static/chunks/9909.787576b171184aa5.js +0 -1
  446. package/.next/static/chunks/9960.7ef77f8a8b046170.js +0 -1
  447. package/.next/static/chunks/9979.aedbc094bdc2c599.js +0 -1
  448. package/.next/static/chunks/BannerNewsletter.00328ad162109908.js +0 -1
  449. package/.next/static/chunks/BannerText.dbbec87cadb8a521.js +0 -1
  450. package/.next/static/chunks/ButtonSignIn.f6e210eaca873e48.js +0 -1
  451. package/.next/static/chunks/CartItem.b34e295377f6f94f.js +0 -1
  452. package/.next/static/chunks/CartSidebar.ac447d1ef6276da1.js +0 -1
  453. package/.next/static/chunks/Dropdown.38b48c749bad6b60.js +0 -1
  454. package/.next/static/chunks/DropdownButton.66fa6b25dddb3a07.js +0 -1
  455. package/.next/static/chunks/DropdownItem.38b8f5a07c7f422a.js +0 -1
  456. package/.next/static/chunks/DropdownMenu.48b11521a24c6efd.js +0 -1
  457. package/.next/static/chunks/EmptyCart.320e2f94a0d5e6b1.js +0 -1
  458. package/.next/static/chunks/FilterSkeleton.7ab99e28f92341c9.js +0 -1
  459. package/.next/static/chunks/Footer.166b02c2f13980c6.js +0 -1
  460. package/.next/static/chunks/Gift.c49ba26da2fbab5e.js +0 -1
  461. package/.next/static/chunks/Newsletter.fc406f6029057022.js +0 -1
  462. package/.next/static/chunks/OrderSummary.5957d69f990d9add.js +0 -1
  463. package/.next/static/chunks/PreviewTag.f4f0c8710a7bcad9.js +0 -1
  464. package/.next/static/chunks/ProductShelf.cc46f5cdeeaeaff6.js +0 -1
  465. package/.next/static/chunks/ProductTiles.9b804e51b0704d60.js +0 -1
  466. package/.next/static/chunks/RegionModal.319ad44250cb12d2.js +0 -1
  467. package/.next/static/chunks/RegionSlider.0e0e93369f4f9c92.js +0 -1
  468. package/.next/static/chunks/ScrollToTopButton.c15431f2e8bb93ef.js +0 -1
  469. package/.next/static/chunks/ShoppingAssistant.ba191eb4dbed67e5.js +0 -1
  470. package/.next/static/chunks/Toast.5f90f0436708be5e.js +0 -1
  471. package/.next/static/chunks/UIBannerText.7315b16af4457059.js +0 -1
  472. package/.next/static/chunks/UISKUMatrixSidebar.b4349b2682bbe183.js +0 -1
  473. package/.next/static/chunks/UIToast.19a8664c01a00d3a.js +0 -1
  474. package/.next/static/chunks/framework-d514426edf885c68.js +0 -33
  475. package/.next/static/chunks/main-ec03882c4375091d.js +0 -1
  476. package/.next/static/chunks/pages/404-e3dfbbac003b02a2.js +0 -1
  477. package/.next/static/chunks/pages/500-c7814e085081d7b8.js +0 -1
  478. package/.next/static/chunks/pages/[...slug]-dc8a395a43b081f1.js +0 -1
  479. package/.next/static/chunks/pages/[slug]/p-644f1132f5a0f736.js +0 -1
  480. package/.next/static/chunks/pages/_app-84aaff8a9d4de60e.js +0 -1
  481. package/.next/static/chunks/pages/_error-2b0148be56a716e9.js +0 -1
  482. package/.next/static/chunks/pages/checkout-2071467ad42dfb99.js +0 -1
  483. package/.next/static/chunks/pages/index-8774d5b4a8744eb2.js +0 -1
  484. package/.next/static/chunks/pages/login-e74747c9f9cb5b49.js +0 -1
  485. package/.next/static/chunks/pages/pvt/account/403-491e6b062487b30f.js +0 -1
  486. package/.next/static/chunks/pages/pvt/account/404-5ad472d9f2ee1980.js +0 -1
  487. package/.next/static/chunks/pages/pvt/account/[...unknown]-f80f645594d2740c.js +0 -1
  488. package/.next/static/chunks/pages/pvt/account/orders/[id]-64e42157c0974c48.js +0 -1
  489. package/.next/static/chunks/pages/pvt/account/orders-faab39f2aff05fae.js +0 -1
  490. package/.next/static/chunks/pages/pvt/account/profile-9672177ee2665bc0.js +0 -1
  491. package/.next/static/chunks/pages/pvt/account/security-03eb1ccab9a30563.js +0 -1
  492. package/.next/static/chunks/pages/pvt/account/user-details-7838e3f79781596c.js +0 -1
  493. package/.next/static/chunks/pages/pvt/account-65fefcc699344bdb.js +0 -1
  494. package/.next/static/chunks/pages/s-162ba789e6611175.js +0 -1
  495. package/.next/static/chunks/polyfills-c67a75d1b6f99dc8.js +0 -1
  496. package/.next/static/chunks/webpack-f621ff3e951d2982.js +0 -1
  497. package/.next/static/css/02259c549b2179f2.css +0 -1
  498. package/.next/static/css/02eaf202d3d11fd1.css +0 -1
  499. package/.next/static/css/033e241c58ba6fbb.css +0 -1
  500. package/.next/static/css/042d012bc1895b5c.css +0 -1
  501. package/.next/static/css/14176a4704ff97b2.css +0 -1
  502. package/.next/static/css/146a8678babc61bf.css +0 -1
  503. package/.next/static/css/16d65422bfa80f51.css +0 -1
  504. package/.next/static/css/1c4983f11b861ea0.css +0 -1
  505. package/.next/static/css/204754bbd8cc4bef.css +0 -1
  506. package/.next/static/css/24d91007fc96be10.css +0 -1
  507. package/.next/static/css/2980acad3f8e1028.css +0 -1
  508. package/.next/static/css/2c19433e38fd7533.css +0 -1
  509. package/.next/static/css/31380ebc6e671486.css +0 -1
  510. package/.next/static/css/42df884711219edb.css +0 -1
  511. package/.next/static/css/4f0597b0bf0ef2e1.css +0 -1
  512. package/.next/static/css/54cedf4b65e5863f.css +0 -1
  513. package/.next/static/css/6580147d7ab8fcca.css +0 -1
  514. package/.next/static/css/6819dddf2b1b5ea7.css +0 -1
  515. package/.next/static/css/7ef7762f412ed665.css +0 -1
  516. package/.next/static/css/82f3cd529b672812.css +0 -1
  517. package/.next/static/css/837662922091162f.css +0 -1
  518. package/.next/static/css/8e6ab59ace21e03b.css +0 -1
  519. package/.next/static/css/a852afa9be31e946.css +0 -1
  520. package/.next/static/css/b684b347c5cc6514.css +0 -1
  521. package/.next/static/css/bcdaef0a83277ef5.css +0 -1
  522. package/.next/static/css/c33615999008d3f9.css +0 -1
  523. package/.next/static/css/c34f6ea9953e2f63.css +0 -1
  524. package/.next/static/css/ea11d74a2848b093.css +0 -1
  525. package/.next/static/css/f16438bcf4508fb3.css +0 -1
  526. package/.next/static/css/f60366555f563deb.css +0 -1
  527. package/.next/trace +0 -143
  528. package/.turbo/turbo-build.log +0 -140
  529. package/jest.config.js +0 -17
  530. package/public/~partytown/debug/partytown-atomics.js +0 -556
  531. package/public/~partytown/debug/partytown-media.js +0 -374
  532. package/public/~partytown/debug/partytown-sandbox-sw.js +0 -543
  533. package/public/~partytown/debug/partytown-sw.js +0 -59
  534. package/public/~partytown/debug/partytown-ww-atomics.js +0 -1789
  535. package/public/~partytown/debug/partytown-ww-sw.js +0 -1781
  536. package/public/~partytown/debug/partytown.js +0 -72
  537. package/public/~partytown/partytown-atomics.js +0 -2
  538. package/public/~partytown/partytown-media.js +0 -2
  539. package/public/~partytown/partytown-sw.js +0 -2
  540. package/public/~partytown/partytown.js +0 -2
  541. package/src/middleware__DISABLED.ts +0 -65
  542. package/src/server/generator/generateGraphQLSchemaFile.ts +0 -3
  543. package/src/server/generator/schema.ts +0 -81
@@ -0,0 +1,222 @@
1
+ /**
2
+ * @vitest-environment jsdom
3
+ */
4
+
5
+ import { act, renderHook } from '@testing-library/react'
6
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
7
+
8
+ vi.mock('discovery.config', () => ({
9
+ __esModule: true,
10
+ default: {
11
+ localization: { enabled: false, defaultLocale: 'pt-BR' },
12
+ session: { locale: 'en-US' },
13
+ },
14
+ }))
15
+
16
+ const mockUseSession = vi.hoisted(() => vi.fn(() => ({ locale: 'pt-BR' })))
17
+ vi.mock('src/sdk/session', () => ({ useSession: mockUseSession }))
18
+
19
+ import {
20
+ searchHistoryStore,
21
+ type History,
22
+ } from '../../../src/sdk/search/useSearchHistory'
23
+ import useSearchHistory from '../../../src/sdk/search/useSearchHistory'
24
+
25
+ function makeHistory(term: string, path = `/s?q=${term}`) {
26
+ return { term, path } satisfies History
27
+ }
28
+
29
+ describe('useSearchHistory', () => {
30
+ beforeEach(() => {
31
+ searchHistoryStore.set({})
32
+ mockUseSession.mockReturnValue({ locale: 'pt-BR' })
33
+ })
34
+
35
+ afterEach(() => {
36
+ vi.clearAllMocks()
37
+ })
38
+
39
+ describe('searchHistory (read by locale)', () => {
40
+ it('returns empty array when store is empty', () => {
41
+ const { result } = renderHook(() => useSearchHistory())
42
+ expect(result.current.searchHistory).toEqual([])
43
+ })
44
+
45
+ it('returns history for current locale when store has data for that locale', () => {
46
+ const items = [makeHistory('tenis'), makeHistory('camisa')]
47
+ searchHistoryStore.set({ 'pt-BR': items })
48
+
49
+ const { result } = renderHook(() => useSearchHistory())
50
+ expect(result.current.searchHistory).toEqual(items)
51
+ })
52
+
53
+ it('returns empty array when store has data only for another locale', () => {
54
+ searchHistoryStore.set({
55
+ 'en-US': [makeHistory('shoes')],
56
+ })
57
+
58
+ const { result } = renderHook(() => useSearchHistory())
59
+ expect(result.current.searchHistory).toEqual([])
60
+ })
61
+
62
+ it('uses session locale and shows correct slice when locale changes', () => {
63
+ searchHistoryStore.set({
64
+ 'pt-BR': [makeHistory('tenis')],
65
+ 'en-US': [makeHistory('shoes')],
66
+ })
67
+
68
+ const { result, rerender } = renderHook(() => useSearchHistory())
69
+ expect(result.current.searchHistory).toEqual([makeHistory('tenis')])
70
+
71
+ mockUseSession.mockReturnValue({ locale: 'en-US' })
72
+ rerender()
73
+ expect(result.current.searchHistory).toEqual([makeHistory('shoes')])
74
+ })
75
+ })
76
+
77
+ describe('addToSearchHistory', () => {
78
+ it('adds item to current locale and persists', () => {
79
+ const { result } = renderHook(() => useSearchHistory())
80
+
81
+ act(() => {
82
+ result.current.addToSearchHistory(makeHistory('tenis'))
83
+ })
84
+
85
+ expect(result.current.searchHistory).toHaveLength(1)
86
+ expect(result.current.searchHistory[0].term).toBe('tenis')
87
+ expect(searchHistoryStore.read()).toEqual({
88
+ 'pt-BR': [makeHistory('tenis')],
89
+ })
90
+ })
91
+
92
+ it('dedupes by term and moves to front', () => {
93
+ searchHistoryStore.set({
94
+ 'pt-BR': [makeHistory('camisa'), makeHistory('tenis')],
95
+ })
96
+ const { result } = renderHook(() => useSearchHistory())
97
+
98
+ act(() => {
99
+ result.current.addToSearchHistory(
100
+ makeHistory('tenis', '/s?q=tenis&sort=score_desc')
101
+ )
102
+ })
103
+
104
+ expect(result.current.searchHistory.map((h) => h.term)).toEqual([
105
+ 'tenis',
106
+ 'camisa',
107
+ ])
108
+ expect(result.current.searchHistory).toHaveLength(2)
109
+ })
110
+
111
+ it('respects maxHistorySize (default 4)', () => {
112
+ const { result } = renderHook(() => useSearchHistory())
113
+
114
+ act(() => result.current.addToSearchHistory(makeHistory('a')))
115
+ act(() => result.current.addToSearchHistory(makeHistory('b')))
116
+ act(() => result.current.addToSearchHistory(makeHistory('c')))
117
+ act(() => result.current.addToSearchHistory(makeHistory('d')))
118
+ act(() => result.current.addToSearchHistory(makeHistory('e')))
119
+
120
+ expect(result.current.searchHistory).toHaveLength(4)
121
+ expect(result.current.searchHistory.map((h) => h.term)).toEqual([
122
+ 'e',
123
+ 'd',
124
+ 'c',
125
+ 'b',
126
+ ])
127
+ })
128
+
129
+ it('can use custom maxHistorySize', () => {
130
+ const { result } = renderHook(() => useSearchHistory(2))
131
+
132
+ act(() => result.current.addToSearchHistory(makeHistory('a')))
133
+ act(() => result.current.addToSearchHistory(makeHistory('b')))
134
+ act(() => result.current.addToSearchHistory(makeHistory('c')))
135
+
136
+ expect(result.current.searchHistory).toHaveLength(2)
137
+ expect(result.current.searchHistory.map((h) => h.term)).toEqual([
138
+ 'c',
139
+ 'b',
140
+ ])
141
+ })
142
+
143
+ it('does not affect other locales', () => {
144
+ searchHistoryStore.set({
145
+ 'en-US': [makeHistory('shoes')],
146
+ })
147
+ const { result } = renderHook(() => useSearchHistory())
148
+
149
+ act(() => {
150
+ result.current.addToSearchHistory(makeHistory('tenis'))
151
+ })
152
+
153
+ expect(searchHistoryStore.read()).toEqual({
154
+ 'en-US': [makeHistory('shoes')],
155
+ 'pt-BR': [makeHistory('tenis')],
156
+ })
157
+ })
158
+ })
159
+
160
+ describe('clearSearchHistory', () => {
161
+ it('removes only current locale and leaves others', () => {
162
+ searchHistoryStore.set({
163
+ 'pt-BR': [makeHistory('tenis')],
164
+ 'en-US': [makeHistory('shoes')],
165
+ })
166
+ const { result } = renderHook(() => useSearchHistory())
167
+
168
+ act(() => {
169
+ result.current.clearSearchHistory()
170
+ })
171
+
172
+ expect(result.current.searchHistory).toEqual([])
173
+ expect(searchHistoryStore.read()).toEqual({
174
+ 'en-US': [makeHistory('shoes')],
175
+ })
176
+ })
177
+
178
+ it('sets store to empty object when clearing last locale', () => {
179
+ searchHistoryStore.set({ 'pt-BR': [makeHistory('tenis')] })
180
+ const { result } = renderHook(() => useSearchHistory())
181
+
182
+ act(() => {
183
+ result.current.clearSearchHistory()
184
+ })
185
+
186
+ expect(searchHistoryStore.read()).toEqual({})
187
+ })
188
+ })
189
+
190
+ describe('legacy format (array) migration', () => {
191
+ it('normalizes array to Record with default locale and exposes as searchHistory when session matches default', () => {
192
+ const legacy = [makeHistory('old1'), makeHistory('old2')]
193
+ searchHistoryStore.set(legacy as unknown as Record<string, History[]>)
194
+ mockUseSession.mockReturnValue({ locale: 'en-US' })
195
+
196
+ const { result } = renderHook(() => useSearchHistory())
197
+
198
+ expect(result.current.searchHistory).toHaveLength(2)
199
+ expect(result.current.searchHistory.map((h) => h.term)).toEqual([
200
+ 'old1',
201
+ 'old2',
202
+ ])
203
+ })
204
+
205
+ it('after migration persists Record so store no longer holds array', async () => {
206
+ const legacy = [makeHistory('old1')]
207
+ searchHistoryStore.set(legacy as unknown as Record<string, History[]>)
208
+ mockUseSession.mockReturnValue({ locale: 'en-US' })
209
+
210
+ renderHook(() => useSearchHistory())
211
+
212
+ await act(async () => {
213
+ await Promise.resolve()
214
+ })
215
+
216
+ const stored = searchHistoryStore.read()
217
+ expect(Array.isArray(stored)).toBe(false)
218
+ expect(stored).toHaveProperty('en-US')
219
+ expect((stored as Record<string, History[]>)['en-US']).toHaveLength(1)
220
+ })
221
+ })
222
+ })
@@ -1,5 +1,5 @@
1
+ import { vi } from 'vitest'
1
2
  import { clientCMS, getCMSPage } from '../../../src/server/cms'
2
- import { jest } from '@jest/globals'
3
3
  import type { ContentData } from '@vtex/client-cms'
4
4
 
5
5
  describe('CMS Integration', () => {
@@ -20,7 +20,7 @@ describe('CMS Integration', () => {
20
20
 
21
21
  describe('getCMSPage', () => {
22
22
  it('returns the first page if there is only one page', async () => {
23
- const mockFunction = jest.fn(() => {
23
+ const mockFunction = vi.fn(() => {
24
24
  return Promise.resolve({
25
25
  data: mockData(3),
26
26
  hasNextPage: false,
@@ -36,8 +36,7 @@ describe('CMS Integration', () => {
36
36
  })
37
37
 
38
38
  it('loads multiple pages', async () => {
39
- const mockFunction: jest.Mock<typeof clientCMS.getCMSPagesByContentType> =
40
- jest.fn()
39
+ const mockFunction = vi.fn()
41
40
 
42
41
  mockFunction.mockImplementationOnce(() => {
43
42
  return Promise.resolve({
@@ -0,0 +1,98 @@
1
+ import type { EntryPathParams } from '@vtex/client-cp'
2
+ import { describe, expect, it } from 'vitest'
3
+
4
+ import { ContentService } from '../../../src/server/content/service'
5
+ import type {
6
+ ContentOptions,
7
+ ContentParams,
8
+ } from '../../../src/server/content/types'
9
+
10
+ type ContentServiceInternals = {
11
+ createContentOptions: (params: ContentParams) => ContentOptions
12
+ convertOptionsToParams: (options: ContentOptions) => EntryPathParams
13
+ }
14
+
15
+ const getServiceInternals = (service: ContentService) =>
16
+ service as unknown as ContentServiceInternals
17
+
18
+ describe('ContentService', () => {
19
+ describe('convertOptionsToParams', () => {
20
+ it('maps a flat SEO slug filter to the client-cp slug param', () => {
21
+ const service = getServiceInternals(new ContentService())
22
+ const options = service.createContentOptions({
23
+ contentType: 'landingPage',
24
+ filters: { 'settings.seo.slug': '/summer-sale' },
25
+ })
26
+
27
+ const params = service.convertOptionsToParams(options)
28
+
29
+ expect(params.slug).toBe('summer-sale')
30
+ })
31
+
32
+ it('keeps an explicit slug when filters also include settings.seo.slug', () => {
33
+ const service = getServiceInternals(new ContentService())
34
+ const options = service.createContentOptions({
35
+ contentType: 'landingPage',
36
+ slug: 'summer-sale',
37
+ filters: { 'settings.seo.slug': '/other-slug' },
38
+ })
39
+
40
+ const params = service.convertOptionsToParams(options)
41
+
42
+ expect(params.slug).toBe('summer-sale')
43
+ })
44
+ })
45
+
46
+ describe('createContentOptions', () => {
47
+ it('prefers the preview locale when the request falls back to the default locale', () => {
48
+ const service = getServiceInternals(new ContentService())
49
+
50
+ const options = service.createContentOptions({
51
+ contentType: 'landingPage',
52
+ locale: 'en-US',
53
+ previewData: {
54
+ contentType: 'landingPage',
55
+ documentId: 'entry-1',
56
+ versionId: 'branch-1',
57
+ locale: 'pt-BR',
58
+ },
59
+ })
60
+
61
+ expect(options.locale).toBe('pt-BR')
62
+ })
63
+
64
+ it('keeps the explicit route locale when it already differs from the default locale', () => {
65
+ const service = getServiceInternals(new ContentService())
66
+
67
+ const options = service.createContentOptions({
68
+ contentType: 'landingPage',
69
+ locale: 'fr-FR',
70
+ previewData: {
71
+ contentType: 'landingPage',
72
+ documentId: 'entry-1',
73
+ versionId: 'branch-1',
74
+ locale: 'pt-BR',
75
+ },
76
+ })
77
+
78
+ expect(options.locale).toBe('fr-FR')
79
+ })
80
+
81
+ it('does not leak the preview locale into CMS locator params', () => {
82
+ const service = getServiceInternals(new ContentService())
83
+
84
+ const options = service.createContentOptions({
85
+ contentType: 'landingPage',
86
+ locale: 'en-US',
87
+ previewData: {
88
+ contentType: 'landingPage',
89
+ documentId: 'entry-1',
90
+ versionId: 'branch-1',
91
+ locale: 'pt-BR',
92
+ },
93
+ })
94
+
95
+ expect('locale' in options.cmsOptions).toBe(false)
96
+ })
97
+ })
98
+ })
@@ -1,11 +1,8 @@
1
1
  import { assertValidSchema } from 'graphql'
2
+ import { describe, expect, it } from 'vitest'
2
3
 
3
4
  import storeConfig from '../../discovery.config'
4
- import { execute, getEnvelop } from '../../src/server'
5
- import {
6
- getMergedSchema,
7
- getTypeDefsFromFolder,
8
- } from '../../src/server/generator/schema'
5
+ import { execute, getEnvelop, getFinalAPISchema } from '../../src/server'
9
6
 
10
7
  const TYPES = [
11
8
  'StoreAggregateOffer',
@@ -83,6 +80,8 @@ const QUERIES = [
83
80
  'pickupPoints',
84
81
  ]
85
82
 
83
+ const OPTIONAL_GENERATED_QUERIES = new Set(['accountName'])
84
+
86
85
  const MUTATIONS = [
87
86
  'validateCart',
88
87
  'validateSession',
@@ -93,7 +92,7 @@ const MUTATIONS = [
93
92
 
94
93
  describe('FastStore GraphQL Layer', () => {
95
94
  describe('@faststore/api', () => {
96
- const nativeSchema = getMergedSchema()
95
+ const nativeSchema = getFinalAPISchema()
97
96
 
98
97
  it('should return a valid GraphQL schema', async () => {
99
98
  // `assertValidSchema()` will throw an error if the schema is invalid, and
@@ -109,8 +108,11 @@ describe('FastStore GraphQL Layer', () => {
109
108
 
110
109
  it('should return a valid GraphQL schema contain all expected queries', async () => {
111
110
  const queryFields = nativeSchema.getQueryType()?.getFields() ?? {}
111
+ const queryNames = Object.keys(queryFields).filter(
112
+ (query) => !OPTIONAL_GENERATED_QUERIES.has(query)
113
+ )
112
114
 
113
- expect(Object.keys(queryFields)).toEqual(QUERIES)
115
+ expect(queryNames).toEqual(QUERIES)
114
116
  })
115
117
 
116
118
  it('should return a valid GraphQL schema contain all expected mutations', async () => {
@@ -120,23 +122,9 @@ describe('FastStore GraphQL Layer', () => {
120
122
  })
121
123
  })
122
124
 
123
- describe('VTEX API Extension', () => {
124
- it('getTypeDefsFromFolder function should return an Array', () => {
125
- const typeDefs = getTypeDefsFromFolder('vtex')
126
- expect(typeDefs).toBeInstanceOf(Array)
127
- })
128
- })
129
-
130
- describe('Third Party API Extension', () => {
131
- it('getTypeDefsFromFolder function should return an Array', () => {
132
- const typeDefs = getTypeDefsFromFolder('thirdParty')
133
- expect(typeDefs).toBeInstanceOf(Array)
134
- })
135
- })
136
-
137
125
  describe('Final Schema after merging', () => {
138
126
  it('should return a valid merged GraphQL schema', async () => {
139
- const schema = getMergedSchema()
127
+ const schema = getFinalAPISchema()
140
128
 
141
129
  // `assertValidSchema()` will throw an error if the schema is invalid, and
142
130
  // return nothing if it is valid. That's why we're checking for `undefined`.
@@ -1,26 +1,34 @@
1
1
  /**
2
- * @jest-environment jsdom
2
+ * @vitest-environment jsdom
3
3
  */
4
4
 
5
- const mockRead = jest.fn()
6
- const mockReadInitial = jest.fn()
5
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
7
6
 
8
- jest.mock('src/sdk/session', () => ({
9
- sessionStore: {
10
- read: () => mockRead(),
11
- readInitial: () => mockReadInitial(),
7
+ const mockRead = vi.fn()
8
+ const mockReadInitial = vi.fn()
9
+
10
+ vi.mock('discovery.config', () => ({
11
+ __esModule: true,
12
+ default: {
13
+ api: {
14
+ storeId: 'store',
15
+ },
16
+ deliveryPromise: { enabled: true },
12
17
  },
13
18
  }))
14
19
 
15
- jest.mock('discovery.config', () => ({
16
- deliveryPromise: { enabled: true },
20
+ vi.mock('src/sdk/session', () => ({
21
+ sessionStore: {
22
+ read: (...args: unknown[]) => mockRead(...args),
23
+ readInitial: (...args: unknown[]) => mockReadInitial(...args),
24
+ },
17
25
  }))
18
26
 
19
27
  import {
20
28
  getClientCacheBustingValue,
29
+ STORAGE_KEY_CACHE_BUST_LAST_VALUE,
21
30
  STORAGE_KEY_PERSON_ID,
22
31
  STORAGE_KEY_POSTAL_CODE,
23
- STORAGE_KEY_CACHE_BUST_LAST_VALUE,
24
32
  } from '../../src/utils/cookieCacheBusting'
25
33
 
26
34
  const setSession = ({
@@ -45,14 +53,14 @@ const clearSession = () => {
45
53
 
46
54
  describe('cookieCacheBusting', () => {
47
55
  beforeEach(() => {
48
- jest.restoreAllMocks()
49
56
  sessionStorage.clear()
57
+ vi.restoreAllMocks()
50
58
  clearSession()
51
59
  })
52
60
 
53
61
  describe('returns null (shared public CDN cache)', () => {
54
62
  it('should clear storage and return null when neither person nor postalCode is set', () => {
55
- const removeItemSpy = jest.spyOn(Storage.prototype, 'removeItem')
63
+ const removeItemSpy = vi.spyOn(Storage.prototype, 'removeItem')
56
64
 
57
65
  const result = getClientCacheBustingValue()
58
66
 
@@ -69,8 +77,8 @@ describe('cookieCacheBusting', () => {
69
77
  it('should return a new timestamp value and persist when person logs in', () => {
70
78
  setSession({ personId: 'user-id-1' })
71
79
 
72
- const nowSpy = jest.spyOn(Date, 'now').mockReturnValue(1700000000000)
73
- const setItemSpy = jest.spyOn(Storage.prototype, 'setItem')
80
+ const nowSpy = vi.spyOn(Date, 'now').mockReturnValue(1700000000000)
81
+ const setItemSpy = vi.spyOn(Storage.prototype, 'setItem')
74
82
 
75
83
  const result = getClientCacheBustingValue()
76
84
 
@@ -94,8 +102,8 @@ describe('cookieCacheBusting', () => {
94
102
  '1700000000000::user-id-1'
95
103
  )
96
104
 
97
- const nowSpy = jest.spyOn(Date, 'now')
98
- const setItemSpy = jest.spyOn(Storage.prototype, 'setItem')
105
+ const nowSpy = vi.spyOn(Date, 'now')
106
+ const setItemSpy = vi.spyOn(Storage.prototype, 'setItem')
99
107
 
100
108
  const result = getClientCacheBustingValue()
101
109
 
@@ -108,8 +116,8 @@ describe('cookieCacheBusting', () => {
108
116
  setSession({ personId: 'user-id-1' })
109
117
  sessionStorage.setItem(STORAGE_KEY_PERSON_ID, 'user-id-1')
110
118
 
111
- const nowSpy = jest.spyOn(Date, 'now').mockReturnValue(1700000000123)
112
- const setItemSpy = jest.spyOn(Storage.prototype, 'setItem')
119
+ const nowSpy = vi.spyOn(Date, 'now').mockReturnValue(1700000000123)
120
+ const setItemSpy = vi.spyOn(Storage.prototype, 'setItem')
113
121
 
114
122
  const result = getClientCacheBustingValue()
115
123
 
@@ -133,7 +141,7 @@ describe('cookieCacheBusting', () => {
133
141
  '1700000000000::user-id-1'
134
142
  )
135
143
 
136
- jest.spyOn(Date, 'now').mockReturnValue(1700000000456)
144
+ vi.spyOn(Date, 'now').mockReturnValue(1700000000456)
137
145
 
138
146
  const result = getClientCacheBustingValue()
139
147
 
@@ -149,7 +157,7 @@ describe('cookieCacheBusting', () => {
149
157
  it('should return a value for anonymous users who have a postalCode set', () => {
150
158
  setSession({ postalCode: '24230220' })
151
159
 
152
- jest.spyOn(Date, 'now').mockReturnValue(1700000001000)
160
+ vi.spyOn(Date, 'now').mockReturnValue(1700000001000)
153
161
 
154
162
  const result = getClientCacheBustingValue()
155
163
 
@@ -164,7 +172,7 @@ describe('cookieCacheBusting', () => {
164
172
  '1700000001000::24230220'
165
173
  )
166
174
 
167
- const nowSpy = jest.spyOn(Date, 'now')
175
+ const nowSpy = vi.spyOn(Date, 'now')
168
176
 
169
177
  const result = getClientCacheBustingValue()
170
178
 
@@ -180,7 +188,7 @@ describe('cookieCacheBusting', () => {
180
188
  '1700000001000::50030260'
181
189
  )
182
190
 
183
- jest.spyOn(Date, 'now').mockReturnValue(1700000002000)
191
+ vi.spyOn(Date, 'now').mockReturnValue(1700000002000)
184
192
 
185
193
  const result = getClientCacheBustingValue()
186
194
 
@@ -194,7 +202,7 @@ describe('cookieCacheBusting', () => {
194
202
  it('should combine personId and postalCode for logged-in users', () => {
195
203
  setSession({ personId: 'user-id-1', postalCode: '24230220' })
196
204
 
197
- jest.spyOn(Date, 'now').mockReturnValue(1700000003000)
205
+ vi.spyOn(Date, 'now').mockReturnValue(1700000003000)
198
206
 
199
207
  const result = getClientCacheBustingValue()
200
208
 
@@ -210,7 +218,7 @@ describe('cookieCacheBusting', () => {
210
218
  '1700000003000::user-id-1::50030260'
211
219
  )
212
220
 
213
- jest.spyOn(Date, 'now').mockReturnValue(1700000004000)
221
+ vi.spyOn(Date, 'now').mockReturnValue(1700000004000)
214
222
 
215
223
  const result = getClientCacheBustingValue()
216
224
 
@@ -0,0 +1,71 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { getRequestHostname } from '../../src/utils/getRequestHostname'
3
+
4
+ describe('getRequestHostname', () => {
5
+ describe('returns null for missing input', () => {
6
+ it('returns null when host is null', () => {
7
+ expect(getRequestHostname(null)).toBeNull()
8
+ })
9
+
10
+ it('returns null when host is undefined', () => {
11
+ expect(getRequestHostname(undefined)).toBeNull()
12
+ })
13
+
14
+ it('returns null when host is an empty string', () => {
15
+ expect(getRequestHostname('')).toBeNull()
16
+ })
17
+
18
+ it('returns null when host is whitespace-only', () => {
19
+ expect(getRequestHostname(' ')).toBeNull()
20
+ })
21
+ })
22
+
23
+ describe('strips the port', () => {
24
+ it('removes the port from a hostname with port', () => {
25
+ expect(getRequestHostname('brandless.fast.store:443')).toBe(
26
+ 'brandless.fast.store'
27
+ )
28
+ })
29
+
30
+ it('removes the port from localhost', () => {
31
+ expect(getRequestHostname('localhost:3000')).toBe('localhost')
32
+ })
33
+
34
+ it('keeps the hostname unchanged when there is no port', () => {
35
+ expect(getRequestHostname('brandless.fast.store')).toBe(
36
+ 'brandless.fast.store'
37
+ )
38
+ })
39
+ })
40
+
41
+ describe('lowercases the hostname', () => {
42
+ it('lowercases an uppercase hostname', () => {
43
+ expect(getRequestHostname('Brandless.Fast.Store')).toBe(
44
+ 'brandless.fast.store'
45
+ )
46
+ })
47
+
48
+ it('lowercases a hostname with port', () => {
49
+ expect(getRequestHostname('STORE.COM:8080')).toBe('store.com')
50
+ })
51
+ })
52
+
53
+ describe('handles surrounding whitespace', () => {
54
+ it('trims leading and trailing whitespace', () => {
55
+ expect(getRequestHostname(' store.com ')).toBe('store.com')
56
+ })
57
+
58
+ it('trims whitespace and strips port', () => {
59
+ expect(getRequestHostname(' store.com:443 ')).toBe('store.com')
60
+ })
61
+ })
62
+
63
+ describe('falls back gracefully on malformed input', () => {
64
+ it('returns the lowercased pre-port segment when URL parsing fails', () => {
65
+ // `new URL('https://...')` accepts most strings, so to exercise the
66
+ // fallback we rely on `.split(':')[0].toLowerCase()` for any value the
67
+ // URL parser cannot handle. In practice this is a defensive branch.
68
+ expect(getRequestHostname('STORE.COM:443')).toBe('store.com')
69
+ })
70
+ })
71
+ })