@faststore/core 3.98.0-dev.5 → 3.98.0-dev.8

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 (367) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +124 -123
  3. package/.next/cache/.tsbuildinfo +1 -1
  4. package/.next/cache/config.json +3 -3
  5. package/.next/cache/webpack/client-production/0.pack +0 -0
  6. package/.next/cache/webpack/client-production/index.pack +0 -0
  7. package/.next/cache/webpack/server-production/0.pack +0 -0
  8. package/.next/cache/webpack/server-production/index.pack +0 -0
  9. package/.next/next-minimal-server.js.nft.json +1 -1
  10. package/.next/next-server.js.nft.json +1 -1
  11. package/.next/prerender-manifest.js +1 -1
  12. package/.next/prerender-manifest.json +1 -1
  13. package/.next/react-loadable-manifest.json +170 -173
  14. package/.next/required-server-files.json +1 -1
  15. package/.next/routes-manifest.json +1 -1
  16. package/.next/server/chunks/{5796.js → 1027.js} +1 -1
  17. package/.next/server/chunks/1197.js +1 -0
  18. package/.next/server/chunks/{3483.js → 1313.js} +1 -1
  19. package/.next/server/chunks/1419.js +1 -0
  20. package/.next/server/chunks/1576.js +1 -0
  21. package/.next/server/chunks/{7275.js → 1588.js} +1 -1
  22. package/.next/server/chunks/1741.js +3 -0
  23. package/.next/server/chunks/221.js +1 -0
  24. package/.next/server/chunks/2259.js +9 -0
  25. package/.next/server/chunks/2513.js +1 -0
  26. package/.next/server/chunks/2955.js +1 -0
  27. package/.next/server/chunks/{4803.js → 3114.js} +1 -1
  28. package/.next/server/chunks/3327.js +1 -0
  29. package/.next/server/chunks/3488.js +1 -0
  30. package/.next/server/chunks/{1917.js → 3513.js} +1 -1
  31. package/.next/server/chunks/3683.js +1 -0
  32. package/.next/server/chunks/{8563.js → 3724.js} +1 -1
  33. package/.next/server/chunks/3977.js +1 -0
  34. package/.next/server/chunks/426.js +1 -0
  35. package/.next/server/chunks/4573.js +1 -0
  36. package/.next/server/chunks/4681.js +1 -0
  37. package/.next/server/chunks/5133.js +3 -0
  38. package/.next/server/chunks/5212.js +7 -0
  39. package/.next/server/chunks/5608.js +1 -0
  40. package/.next/server/chunks/5628.js +12 -0
  41. package/.next/server/chunks/{1607.js → 5764.js} +1 -1
  42. package/.next/server/chunks/{9740.js → 6259.js} +1 -1
  43. package/.next/server/chunks/6698.js +1 -1
  44. package/.next/server/chunks/689.js +1 -0
  45. package/.next/server/chunks/6952.js +1 -0
  46. package/.next/server/chunks/7121.js +1 -0
  47. package/.next/server/chunks/7417.js +1 -0
  48. package/.next/server/chunks/{1280.js → 7722.js} +1 -1
  49. package/.next/server/chunks/7796.js +1 -0
  50. package/.next/server/chunks/7956.js +1 -0
  51. package/.next/server/chunks/{6804.js → 7976.js} +3 -3
  52. package/.next/server/chunks/{9985.js → 8146.js} +1 -1
  53. package/.next/server/chunks/8290.js +1 -0
  54. package/.next/server/chunks/8376.js +13 -0
  55. package/.next/server/chunks/8466.js +6 -0
  56. package/.next/server/chunks/8569.js +1 -1
  57. package/.next/server/chunks/8659.js +1 -0
  58. package/.next/server/chunks/8741.js +1 -0
  59. package/.next/server/chunks/8971.js +493 -0
  60. package/.next/server/chunks/9088.js +1 -1
  61. package/.next/server/chunks/9237.js +1 -1
  62. package/.next/server/chunks/9374.js +13 -0
  63. package/.next/server/chunks/{8068.js → 9425.js} +1 -1
  64. package/.next/server/chunks/{UINavbarSlider.js → 9984.js} +1 -1
  65. package/.next/server/chunks/9986.js +1 -0
  66. package/.next/server/chunks/ButtonSignIn.js +1 -1
  67. package/.next/server/chunks/FilterSkeleton.js +1 -1
  68. package/.next/server/chunks/ScrollToTopButton.js +1 -1
  69. package/.next/server/chunks/UIBannerText.js +1 -1
  70. package/.next/server/chunks/UISKUMatrixSidebar.js +1 -1
  71. package/.next/server/functions-config-manifest.json +1 -1
  72. package/.next/server/middleware-build-manifest.js +1 -1
  73. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  74. package/.next/server/pages/404.js +1 -1
  75. package/.next/server/pages/404.js.nft.json +1 -1
  76. package/.next/server/pages/500.js +1 -1
  77. package/.next/server/pages/500.js.nft.json +1 -1
  78. package/.next/server/pages/[...slug].js +1 -1
  79. package/.next/server/pages/[...slug].js.nft.json +1 -1
  80. package/.next/server/pages/[slug]/p.js +1 -1
  81. package/.next/server/pages/[slug]/p.js.nft.json +1 -1
  82. package/.next/server/pages/_app.js +1 -1
  83. package/.next/server/pages/_app.js.nft.json +1 -1
  84. package/.next/server/pages/_document.js +1 -1
  85. package/.next/server/pages/_document.js.nft.json +1 -1
  86. package/.next/server/pages/_error.js +1 -1
  87. package/.next/server/pages/_error.js.nft.json +1 -1
  88. package/.next/server/pages/api/fs/logout.js +1 -1
  89. package/.next/server/pages/api/fs/logout.js.nft.json +1 -1
  90. package/.next/server/pages/api/graphql.js +2 -2
  91. package/.next/server/pages/api/graphql.js.nft.json +1 -1
  92. package/.next/server/pages/api/health/live.js +1 -1
  93. package/.next/server/pages/api/health/live.js.nft.json +1 -1
  94. package/.next/server/pages/api/health/ready.js +1 -1
  95. package/.next/server/pages/api/health/ready.js.nft.json +1 -1
  96. package/.next/server/pages/api/preview.js +1 -1
  97. package/.next/server/pages/api/preview.js.nft.json +1 -1
  98. package/.next/server/pages/checkout.js +1 -1
  99. package/.next/server/pages/checkout.js.nft.json +1 -1
  100. package/.next/server/pages/en-US/404.html +2 -2
  101. package/.next/server/pages/en-US/404.json +1 -1
  102. package/.next/server/pages/en-US/500.html +2 -2
  103. package/.next/server/pages/en-US/500.json +1 -1
  104. package/.next/server/pages/en-US/checkout.html +2 -2
  105. package/.next/server/pages/en-US/checkout.json +1 -1
  106. package/.next/server/pages/en-US/login.html +2 -2
  107. package/.next/server/pages/en-US/login.json +1 -1
  108. package/.next/server/pages/en-US/s.html +2 -2
  109. package/.next/server/pages/en-US/s.json +1 -1
  110. package/.next/server/pages/en-US.html +2 -2
  111. package/.next/server/pages/en-US.json +1 -1
  112. package/.next/server/pages/index.js +1 -1
  113. package/.next/server/pages/index.js.nft.json +1 -1
  114. package/.next/server/pages/login.js +1 -1
  115. package/.next/server/pages/login.js.nft.json +1 -1
  116. package/.next/server/pages/pvt/account/403.js +1 -1
  117. package/.next/server/pages/pvt/account/403.js.nft.json +1 -1
  118. package/.next/server/pages/pvt/account/404.js +1 -1
  119. package/.next/server/pages/pvt/account/404.js.nft.json +1 -1
  120. package/.next/server/pages/pvt/account/[...unknown].js +1 -1
  121. package/.next/server/pages/pvt/account/[...unknown].js.nft.json +1 -1
  122. package/.next/server/pages/pvt/account/orders/[id].js +1 -1
  123. package/.next/server/pages/pvt/account/orders/[id].js.nft.json +1 -1
  124. package/.next/server/pages/pvt/account/orders.js +1 -1
  125. package/.next/server/pages/pvt/account/orders.js.nft.json +1 -1
  126. package/.next/server/pages/pvt/account/profile.js +1 -1
  127. package/.next/server/pages/pvt/account/profile.js.nft.json +1 -1
  128. package/.next/server/pages/pvt/account/security.js +1 -1
  129. package/.next/server/pages/pvt/account/security.js.nft.json +1 -1
  130. package/.next/server/pages/pvt/account/user-details.js +1 -1
  131. package/.next/server/pages/pvt/account/user-details.js.nft.json +1 -1
  132. package/.next/server/pages/pvt/account.js +1 -1
  133. package/.next/server/pages/pvt/account.js.nft.json +1 -1
  134. package/.next/server/pages/s.js +1 -1
  135. package/.next/server/pages/s.js.nft.json +1 -1
  136. package/.next/server/pages-manifest.json +1 -1
  137. package/.next/server/webpack-runtime.js +1 -1
  138. package/.next/static/chunks/{5796.4351370494d8b8b6.js → 1027.f17a7c96c17ce487.js} +1 -1
  139. package/.next/static/chunks/1313.bba028de90630608.js +1 -0
  140. package/.next/static/chunks/1756.89b7f413bb26ba74.js +1 -0
  141. package/.next/static/chunks/{8325.dabe9aa22eaadeed.js → 1911.fb72de1df3c3715c.js} +1 -1
  142. package/.next/static/chunks/2221-f8edfdaa4839bdf0.js +2 -0
  143. package/.next/static/chunks/2564.273fd8b0db75b1c4.js +1 -0
  144. package/.next/static/chunks/2811.cf089090a8b79215.js +1 -0
  145. package/.next/static/chunks/{2927.23bae2c79f0ac0f3.js → 2927.5a79877943a6bf7c.js} +1 -1
  146. package/.next/static/chunks/346.2840f007e6d1054c.js +1 -0
  147. package/.next/static/chunks/3496.bcb4d219501a8b6b.js +1 -0
  148. package/.next/static/chunks/3753-74460a0793c0a75c.js +8 -0
  149. package/.next/static/chunks/3802.1e0df8a20802da16.js +1 -0
  150. package/.next/static/chunks/3883-ebdbb60b50a90c59.js +28 -0
  151. package/.next/static/chunks/4436.9b2b6e1c3f79424d.js +1 -0
  152. package/.next/static/chunks/4681.318feb830c746e3b.js +1 -0
  153. package/.next/static/chunks/484.9fdcaa9ffd8dac08.js +1 -0
  154. package/.next/static/chunks/6218.e8ba8bf8602ec880.js +1 -0
  155. package/.next/static/chunks/{6393.e4b26fee060438d6.js → 6393.f5f13a004beeef40.js} +1 -1
  156. package/.next/static/chunks/6656-efc464f20ffeaa51.js +1 -0
  157. package/.next/static/chunks/6797-ff5656c8624c4265.js +1 -0
  158. package/.next/static/chunks/6943.6bc97e925b54493d.js +1 -0
  159. package/.next/static/chunks/7417.55a6e20779dd3702.js +1 -0
  160. package/.next/static/chunks/7534.ee76e63d58ddd222.js +1 -0
  161. package/.next/static/chunks/7796.a30626656a270831.js +1 -0
  162. package/.next/static/chunks/9105.354374e349da85cb.js +1 -0
  163. package/.next/static/chunks/9222.04daf7868c957e52.js +1 -0
  164. package/.next/static/chunks/{9237.7555603703f81bf7.js → 9237.2d7e1a4978875414.js} +1 -1
  165. package/.next/static/chunks/9399.199f217093e4af1e.js +1 -0
  166. package/.next/static/chunks/{8068.43663fb64762f7b8.js → 9425.9d8b3da847111f21.js} +1 -1
  167. package/.next/static/chunks/9701.f9a0bfffba8807dc.js +1 -0
  168. package/.next/static/chunks/BannerNewsletter.b5770016d20acfd2.js +1 -0
  169. package/.next/static/chunks/{BannerText.4061ccfc191e6b96.js → BannerText.5ba50fbe683158ec.js} +1 -1
  170. package/.next/static/chunks/{ButtonSignIn.f6e210eaca873e48.js → ButtonSignIn.639d8dfc65ded368.js} +1 -1
  171. package/.next/static/chunks/CartItem.3c2ceb3a4ee542bc.js +1 -0
  172. package/.next/static/chunks/CartSidebar.89b0dd6237c025ec.js +1 -0
  173. package/.next/static/chunks/{EmptyCart.320e2f94a0d5e6b1.js → EmptyCart.aa60d42ae8eb5264.js} +1 -1
  174. package/.next/static/chunks/{FilterSkeleton.7ab99e28f92341c9.js → FilterSkeleton.8f1b651c40e06f0b.js} +1 -1
  175. package/.next/static/chunks/Footer.cd83c4dc0252494a.js +1 -0
  176. package/.next/static/chunks/Gift.4c97f836f82d5ebe.js +1 -0
  177. package/.next/static/chunks/Newsletter.bdec43379ca9191a.js +1 -0
  178. package/.next/static/chunks/OrderSummary.994b7314f2d004af.js +1 -0
  179. package/.next/static/chunks/PreviewTag.696854f6690e1b9e.js +1 -0
  180. package/.next/static/chunks/ProductShelf.fe1f19bc68859695.js +1 -0
  181. package/.next/static/chunks/ProductTiles.2c63ae178a75d5b6.js +1 -0
  182. package/.next/static/chunks/{RegionModal.a7be32d2d7832ba4.js → RegionModal.fbbdd54ee2422522.js} +1 -1
  183. package/.next/static/chunks/RegionSlider.49e558b340a5506a.js +1 -0
  184. package/.next/static/chunks/{ScrollToTopButton.c15431f2e8bb93ef.js → ScrollToTopButton.55e3a1233d04b8eb.js} +1 -1
  185. package/.next/static/chunks/ShoppingAssistant.8772fe90bd678202.js +1 -0
  186. package/.next/static/chunks/Toast.f083d9966a9a181e.js +1 -0
  187. package/.next/static/chunks/UISKUMatrixSidebar.01f8f5222dcdf80f.js +1 -0
  188. package/.next/static/chunks/{UIToast.de15325248043ce5.js → UIToast.19a8664c01a00d3a.js} +1 -1
  189. package/.next/static/chunks/main-edeb2c6a5c48bb3f.js +1 -0
  190. package/.next/static/chunks/pages/404-1e8f91fa1bca3ab8.js +1 -0
  191. package/.next/static/chunks/pages/500-f21feacbb9810e94.js +1 -0
  192. package/.next/static/chunks/pages/[...slug]-400781188d59cfd6.js +1 -0
  193. package/.next/static/chunks/pages/[slug]/p-f324b592d1c566b9.js +1 -0
  194. package/.next/static/chunks/pages/_app-735c745509e1e8d6.js +1 -0
  195. package/.next/static/chunks/pages/{_error-2b0148be56a716e9.js → _error-464097ff69347627.js} +1 -1
  196. package/.next/static/chunks/pages/checkout-6076b4baf0ca1aa6.js +1 -0
  197. package/.next/static/chunks/pages/index-3266ece2e885bb3a.js +1 -0
  198. package/.next/static/chunks/pages/login-add3b376f68ce39a.js +1 -0
  199. package/.next/static/chunks/pages/pvt/account/403-d44b70591d2c86dc.js +1 -0
  200. package/.next/static/chunks/pages/pvt/account/404-646fb609f579101e.js +1 -0
  201. package/.next/static/chunks/pages/pvt/account/[...unknown]-3fb3963ca3d77c0b.js +1 -0
  202. package/.next/static/chunks/pages/pvt/account/orders/[id]-cda2266c9693d552.js +1 -0
  203. package/.next/static/chunks/pages/pvt/account/orders-ec545a2679db206e.js +1 -0
  204. package/.next/static/chunks/pages/pvt/account/profile-27164b37098c553f.js +1 -0
  205. package/.next/static/chunks/pages/pvt/account/security-4bd3e75771a120ec.js +1 -0
  206. package/.next/static/chunks/pages/pvt/account/user-details-a48a44dfdc07c1e9.js +1 -0
  207. package/.next/static/chunks/pages/pvt/account-5a6dcae3b380b672.js +1 -0
  208. package/.next/static/chunks/pages/s-0fe527a651dd5989.js +1 -0
  209. package/.next/static/chunks/webpack-05d1941e155b909e.js +1 -0
  210. package/.next/static/css/0c6f09f86cf5e919.css +1 -0
  211. package/.next/static/css/{b684b347c5cc6514.css → 1154064b68a7f35e.css} +1 -1
  212. package/.next/static/css/1b7e34d448a42825.css +1 -0
  213. package/.next/static/css/4e57bdfb48115ce3.css +1 -0
  214. package/.next/static/css/501e6ed2c71b1fe4.css +1 -0
  215. package/.next/static/css/{837662922091162f.css → 52ab64b6a2b14e3e.css} +1 -1
  216. package/.next/static/css/5f2c773b21b68cba.css +1 -0
  217. package/.next/static/css/8a513f4b536b0ab0.css +1 -0
  218. package/.next/static/css/9b4c21dcd3bc4a17.css +1 -0
  219. package/.next/static/css/c9e0745e893e09e1.css +1 -0
  220. package/.next/static/css/cc2ab6a8cbda0780.css +1 -0
  221. package/.next/static/css/e68c313e4ce2fd1b.css +1 -0
  222. package/.next/static/css/{08d03445f1797608.css → e857065b4012f946.css} +1 -1
  223. package/.next/static/css/ee1b84a920113838.css +1 -0
  224. package/.next/static/css/f16438bcf4508fb3.css +1 -0
  225. package/.next/static/z8AHWODjJNpdcwMdEzCeK/_buildManifest.js +1 -0
  226. package/.next/trace +142 -140
  227. package/.turbo/turbo-build.log +46 -66
  228. package/.turbo/turbo-test.log +5 -5
  229. package/@generated/gql.ts +10 -10
  230. package/@generated/graphql.ts +68 -58
  231. package/@generated/persisted-documents.json +2 -2
  232. package/CHANGELOG.md +24 -4
  233. package/cms/faststore/sections.json +474 -3
  234. package/cypress/tsconfig.json +7 -0
  235. package/jest.config.js +3 -0
  236. package/package.json +4 -3
  237. package/public/icons.svg +62 -0
  238. package/src/components/ThirdPartyScripts/index.ts +1 -1
  239. package/src/components/ThirdPartyScripts/{useWebchatScript.tsx → useShoppingAssistant.tsx} +5 -5
  240. package/src/components/account/MyAccountDrawer/OrganizationDrawer/OrganizationDrawer.tsx +27 -18
  241. package/src/components/account/MyAccountDrawer/OrganizationDrawer/useReloadAfterLogoutReturn.ts +75 -0
  242. package/src/components/cms/global/Components.ts +5 -3
  243. package/src/components/search/SearchInput/SearchInput.tsx +490 -5
  244. package/src/components/sections/Navbar/Navbar.tsx +67 -0
  245. package/src/components/sections/Navbar/section.module.scss +3 -0
  246. package/src/components/sections/ProductDetails/ProductDetails.tsx +1 -0
  247. package/src/components/sections/ShoppingAssistant/ShoppingAssistant.tsx +24 -0
  248. package/src/components/sections/ShoppingAssistant/index.ts +1 -0
  249. package/src/pages/_app.tsx +2 -0
  250. package/src/sdk/graphql/request.ts +1 -1
  251. package/src/sdk/graphql/useQuery.ts +23 -6
  252. package/src/sdk/product/convertProductToQuickOrder.ts +85 -0
  253. package/src/sdk/product/useBulkProductsQuery.ts +128 -0
  254. package/src/styles/global/index.scss +2 -1
  255. package/src/utils/cookieCacheBusting.ts +35 -41
  256. package/src/utils/utilities.ts +62 -0
  257. package/test/tsconfig.json +7 -0
  258. package/test/utils/cookieCacheBusting.test.ts +54 -47
  259. package/.next/server/chunks/1554.js +0 -1
  260. package/.next/server/chunks/1780.js +0 -1
  261. package/.next/server/chunks/2249.js +0 -1
  262. package/.next/server/chunks/2430.js +0 -1
  263. package/.next/server/chunks/2445.js +0 -12
  264. package/.next/server/chunks/2570.js +0 -1
  265. package/.next/server/chunks/294.js +0 -1
  266. package/.next/server/chunks/3029.js +0 -1
  267. package/.next/server/chunks/3836.js +0 -1
  268. package/.next/server/chunks/3890.js +0 -492
  269. package/.next/server/chunks/3945.js +0 -1
  270. package/.next/server/chunks/3951.js +0 -7
  271. package/.next/server/chunks/4194.js +0 -1
  272. package/.next/server/chunks/4365.js +0 -1
  273. package/.next/server/chunks/4913.js +0 -13
  274. package/.next/server/chunks/5683.js +0 -1
  275. package/.next/server/chunks/5723.js +0 -13
  276. package/.next/server/chunks/6789.js +0 -1
  277. package/.next/server/chunks/6886.js +0 -1
  278. package/.next/server/chunks/7098.js +0 -9
  279. package/.next/server/chunks/7692.js +0 -1
  280. package/.next/server/chunks/772.js +0 -6
  281. package/.next/server/chunks/7799.js +0 -1
  282. package/.next/server/chunks/83.js +0 -1
  283. package/.next/server/chunks/8307.js +0 -1
  284. package/.next/server/chunks/8482.js +0 -1
  285. package/.next/server/chunks/8598.js +0 -1
  286. package/.next/server/chunks/8687.js +0 -1
  287. package/.next/server/chunks/870.js +0 -1
  288. package/.next/server/chunks/9117.js +0 -1
  289. package/.next/server/chunks/948.js +0 -2
  290. package/.next/server/chunks/9563.js +0 -3
  291. package/.next/server/chunks/9853.js +0 -1
  292. package/.next/server/chunks/9990.js +0 -1
  293. package/.next/static/_z3BqQGl9pxQ05QAjq4G2/_buildManifest.js +0 -1
  294. package/.next/static/chunks/1208-9118a8f14ecf05c8.js +0 -8
  295. package/.next/static/chunks/1841.a1b15f2c88e02d32.js +0 -1
  296. package/.next/static/chunks/2284.922fe939dafb3b2d.js +0 -1
  297. package/.next/static/chunks/2500.d6beb5af6ee00a9e.js +0 -1
  298. package/.next/static/chunks/2851.e68ed3c8d27a032a.js +0 -1
  299. package/.next/static/chunks/3155.7bc4c730a79d9ecb.js +0 -1
  300. package/.next/static/chunks/3399.72d28af405858825.js +0 -1
  301. package/.next/static/chunks/3483.ef53d632a763da3f.js +0 -1
  302. package/.next/static/chunks/349.235b18ceb82aa256.js +0 -1
  303. package/.next/static/chunks/3836.612763339fc4c64c.js +0 -1
  304. package/.next/static/chunks/4803.9822f0b7e469b933.js +0 -1
  305. package/.next/static/chunks/5859.3bc094416cffd966.js +0 -1
  306. package/.next/static/chunks/6031-b0b111f48a7d504d.js +0 -28
  307. package/.next/static/chunks/6700.a72869377e81146c.js +0 -1
  308. package/.next/static/chunks/6789.960162355435a81d.js +0 -1
  309. package/.next/static/chunks/7191-4bf7ddfc2bd0f3a9.js +0 -1
  310. package/.next/static/chunks/7522-9010743f5d7e8aca.js +0 -1
  311. package/.next/static/chunks/7692.8d5bf4560341a2f6.js +0 -1
  312. package/.next/static/chunks/83.98ce246c274ee7e4.js +0 -1
  313. package/.next/static/chunks/9173-03cb4807f10c57e8.js +0 -1
  314. package/.next/static/chunks/9399.48251a278809f7d3.js +0 -1
  315. package/.next/static/chunks/941.3e2782ab9c490eb0.js +0 -1
  316. package/.next/static/chunks/9465.a1858c778b1083b9.js +0 -1
  317. package/.next/static/chunks/9701.b0e8741551995fbb.js +0 -1
  318. package/.next/static/chunks/9909.787576b171184aa5.js +0 -1
  319. package/.next/static/chunks/BannerNewsletter.90d4a98c15a35cea.js +0 -1
  320. package/.next/static/chunks/CartItem.092df07db9e8b271.js +0 -1
  321. package/.next/static/chunks/CartSidebar.f0c16e2bc6f96e9e.js +0 -1
  322. package/.next/static/chunks/Footer.63a7682a81a96f8e.js +0 -1
  323. package/.next/static/chunks/Gift.08db4da8c89cacf1.js +0 -1
  324. package/.next/static/chunks/Newsletter.dbf35a8ea6d2067e.js +0 -1
  325. package/.next/static/chunks/OrderSummary.f9adad5622605046.js +0 -1
  326. package/.next/static/chunks/PreviewTag.f4f0c8710a7bcad9.js +0 -1
  327. package/.next/static/chunks/ProductShelf.7ebce1c763b4508e.js +0 -1
  328. package/.next/static/chunks/ProductTiles.18f55314e61957f4.js +0 -1
  329. package/.next/static/chunks/RegionSlider.b4dd4e7c0483966d.js +0 -1
  330. package/.next/static/chunks/Toast.2e9b26159af29889.js +0 -1
  331. package/.next/static/chunks/UISKUMatrixSidebar.87ba393b7d738e99.js +0 -1
  332. package/.next/static/chunks/Webchat.e410860c49bcba26.js +0 -1
  333. package/.next/static/chunks/main-ec03882c4375091d.js +0 -1
  334. package/.next/static/chunks/pages/404-4b3f1e22c77f849a.js +0 -1
  335. package/.next/static/chunks/pages/500-bb2de0c11524b2b8.js +0 -1
  336. package/.next/static/chunks/pages/[...slug]-52db16871a86e9bd.js +0 -1
  337. package/.next/static/chunks/pages/[slug]/p-0901bccd311c7775.js +0 -1
  338. package/.next/static/chunks/pages/_app-eae02e7ad5c9db46.js +0 -1
  339. package/.next/static/chunks/pages/checkout-dc07d72b3514c83d.js +0 -1
  340. package/.next/static/chunks/pages/index-1f8bf0fb351b90f4.js +0 -1
  341. package/.next/static/chunks/pages/login-e97ef92769456bf6.js +0 -1
  342. package/.next/static/chunks/pages/pvt/account/403-91597100f8956385.js +0 -1
  343. package/.next/static/chunks/pages/pvt/account/404-c68124bed7cb7c48.js +0 -1
  344. package/.next/static/chunks/pages/pvt/account/[...unknown]-f80f645594d2740c.js +0 -1
  345. package/.next/static/chunks/pages/pvt/account/orders/[id]-e03ebb0393ac92a2.js +0 -1
  346. package/.next/static/chunks/pages/pvt/account/orders-12a215899ae6f3eb.js +0 -1
  347. package/.next/static/chunks/pages/pvt/account/profile-b6cdbf02d4682544.js +0 -1
  348. package/.next/static/chunks/pages/pvt/account/security-e6289a40e745d3c4.js +0 -1
  349. package/.next/static/chunks/pages/pvt/account/user-details-fba1822e52e7de26.js +0 -1
  350. package/.next/static/chunks/pages/pvt/account-65fefcc699344bdb.js +0 -1
  351. package/.next/static/chunks/pages/s-41cffb20de1d2617.js +0 -1
  352. package/.next/static/chunks/webpack-f021535669f6ed5e.js +0 -1
  353. package/.next/static/css/05c399956ff24b77.css +0 -1
  354. package/.next/static/css/0f070d03aacd9cc5.css +0 -1
  355. package/.next/static/css/0fae3d432331aae9.css +0 -1
  356. package/.next/static/css/0fc6b2ff69142c6a.css +0 -1
  357. package/.next/static/css/31380ebc6e671486.css +0 -1
  358. package/.next/static/css/40a294d0a24ad01d.css +0 -1
  359. package/.next/static/css/47f1b4e8de15d314.css +0 -1
  360. package/.next/static/css/973dd40d4773e8cd.css +0 -1
  361. package/.next/static/css/9d403a1bee48c9fc.css +0 -1
  362. package/.next/static/css/a6a4ebbe01adbbad.css +0 -1
  363. package/.next/static/css/bdff52aea05613d4.css +0 -1
  364. package/src/components/sections/Webchat/Webchat.tsx +0 -22
  365. package/src/components/sections/Webchat/index.ts +0 -1
  366. /package/.next/static/{_z3BqQGl9pxQ05QAjq4G2 → z8AHWODjJNpdcwMdEzCeK}/_ssgManifest.js +0 -0
  367. /package/src/components/sections/{Webchat → ShoppingAssistant}/section.module.scss +0 -0
@@ -0,0 +1,24 @@
1
+ import { useRef } from 'react'
2
+
3
+ import { useShoppingAssistant } from 'src/components/ThirdPartyScripts'
4
+
5
+ import Section from '../Section'
6
+
7
+ import styles from './section.module.scss'
8
+
9
+ const ShoppingAssistant = () => {
10
+ const scriptContainerRef = useRef<HTMLDivElement>(null)
11
+ useShoppingAssistant(scriptContainerRef)
12
+
13
+ return (
14
+ <Section
15
+ className={`${styles.section} section-shopping-assistant layout__section`}
16
+ >
17
+ <div ref={scriptContainerRef} aria-hidden="true" hidden />
18
+ </Section>
19
+ )
20
+ }
21
+
22
+ ShoppingAssistant.$componentKey = 'ShoppingAssistant'
23
+
24
+ export default ShoppingAssistant
@@ -0,0 +1 @@
1
+ export { default } from './ShoppingAssistant'
@@ -6,6 +6,7 @@ import { useRouter } from 'next/router'
6
6
  import { useSearch } from '@faststore/sdk'
7
7
  import { UIProvider } from '@faststore/ui'
8
8
 
9
+ import { useReloadAfterLogoutReturn } from 'src/components/account/MyAccountDrawer/OrganizationDrawer/useReloadAfterLogoutReturn'
9
10
  import ThirdPartyScripts from 'src/components/ThirdPartyScripts'
10
11
  import Layout from 'src/Layout'
11
12
  import AnalyticsHandler from 'src/sdk/analytics'
@@ -24,6 +25,7 @@ import { ITEMS_PER_PAGE } from 'src/constants'
24
25
 
25
26
  function App({ Component, pageProps }: AppProps) {
26
27
  useGeolocation()
28
+ useReloadAfterLogoutReturn()
27
29
  storeConfig.experimental?.scrollRestoration && useScrollRestoration()
28
30
  const router = useRouter()
29
31
  const { start: startGlobalSearchState } = useSearch()
@@ -29,7 +29,7 @@ export const request = async <Query = unknown, Variables = unknown>(
29
29
  variables: Variables,
30
30
  options?: RequestOptions
31
31
  ) => {
32
- // Get cache busting value based on cookie changes
32
+ // Get cache busting value based person?.id from session
33
33
  const value = getClientCacheBustingValue()
34
34
 
35
35
  const { data, errors } = await baseRequest<Variables, Query>('/api/graphql', {
@@ -1,8 +1,10 @@
1
- import useSWR from 'swr'
2
1
  import type { SWRConfiguration } from 'swr'
2
+ import useSWR from 'swr'
3
+
4
+ import { getClientCacheBustingValue } from 'src/utils/cookieCacheBusting'
3
5
 
4
- import { request } from './request'
5
6
  import type { Operation, RequestOptions } from './request'
7
+ import { request } from './request'
6
8
 
7
9
  export type QueryOptions = SWRConfiguration &
8
10
  RequestOptions & { doNotRun?: boolean }
@@ -12,6 +14,19 @@ export const getKey = <Variables>(
12
14
  variables: Variables
13
15
  ) => `${operationName}::${JSON.stringify(variables)}`
14
16
 
17
+ /**
18
+ * Returns a suffix for the cache key based on auth state (logged-in vs anonymous).
19
+ * This ensures SWR keeps separate cache entries for logged-in and logged-out users,
20
+ * avoiding stale product data (e.g. prices, availability) when switching session state.
21
+ */
22
+ const getSessionCacheKeySuffix = (): string => {
23
+ if (typeof window === 'undefined') {
24
+ return ''
25
+ }
26
+ const value = getClientCacheBustingValue()
27
+ return value ?? ''
28
+ }
29
+
15
30
  export const DEFAULT_OPTIONS = {
16
31
  errorRetryCount: 3,
17
32
  refreshWhenHidden: false,
@@ -27,10 +42,12 @@ export const useQuery = <Data, Variables = Record<string, unknown>>(
27
42
  options?: QueryOptions
28
43
  ) =>
29
44
  useSWR<Data>(
30
- () =>
31
- options?.doNotRun
32
- ? null
33
- : getKey(operation['__meta__']['operationName'], variables),
45
+ () => {
46
+ if (options?.doNotRun) return null
47
+ const baseKey = getKey(operation['__meta__']['operationName'], variables)
48
+ const sessionSuffix = getSessionCacheKeySuffix()
49
+ return `${baseKey}::${sessionSuffix}`
50
+ },
34
51
  {
35
52
  fetcher: () => {
36
53
  return new Promise((resolve) => {
@@ -0,0 +1,85 @@
1
+ import type { Product } from '@faststore/ui'
2
+ import type { ProductDetailsFragment_ProductFragment } from '@generated/graphql'
3
+
4
+ /**
5
+ * Converts a product from the API to the format expected by QuickOrderDrawer
6
+ */
7
+ export const convertProductToQuickOrder = (
8
+ product: ProductDetailsFragment_ProductFragment,
9
+ requestedQuantity: number
10
+ ): Product | null => {
11
+ if (!product || !product.offers || !product.offers.offers.length) {
12
+ return null
13
+ }
14
+
15
+ const offer = product.offers.offers[0]
16
+
17
+ // Determine availability based on the offer's availability field
18
+ // Availability can be 'https://schema.org/InStock' or 'https://schema.org/OutOfStock'
19
+ const isOutOfStock = offer.availability === 'https://schema.org/OutOfStock'
20
+ const isInStock = offer.availability === 'https://schema.org/InStock'
21
+
22
+ // Get inventory quantity from the offer
23
+ // If quantity is not provided, we'll use a default high value when InStock
24
+ // This handles cases where the API doesn't return quantity but marks it as InStock
25
+ const offerQuantity = (offer as { quantity?: number | null }).quantity
26
+ const inventory =
27
+ offerQuantity != null
28
+ ? offerQuantity
29
+ : isInStock
30
+ ? 999999 // Default to high inventory when InStock but quantity not provided
31
+ : 0
32
+
33
+ // Product is available if it's in stock
34
+ // If quantity is provided, we also check it, but availability field takes precedence
35
+ const availability = isInStock ? 'available' : 'outOfStock'
36
+
37
+ // Determine selectedCount and quantityUpdated based on availability and inventory
38
+ let selectedCount: number
39
+ let quantityUpdated: boolean
40
+ const normalizedRequestedQuantity =
41
+ Number.isFinite(requestedQuantity) && requestedQuantity > 0
42
+ ? Math.floor(requestedQuantity)
43
+ : 1
44
+
45
+ if (isOutOfStock) {
46
+ // Out of stock: set quantity to 0
47
+ selectedCount = 0
48
+ quantityUpdated = true
49
+ } else if (inventory === 0) {
50
+ // Inventory is 0 but marked as InStock (edge case): set quantity to 0
51
+ selectedCount = 0
52
+ quantityUpdated = true
53
+ } else if (offerQuantity != null && normalizedRequestedQuantity > inventory) {
54
+ // Quantity is provided and requested quantity exceeds inventory: cap at inventory
55
+ selectedCount = inventory
56
+ quantityUpdated = true
57
+ } else {
58
+ // Requested quantity is within inventory (or quantity not provided): use requested quantity
59
+ selectedCount = normalizedRequestedQuantity
60
+ quantityUpdated = normalizedRequestedQuantity !== requestedQuantity
61
+ }
62
+
63
+ // Get the variant name from allVariantProducts that matches this product's SKU
64
+ // This ensures we use the correct variant name instead of the product name
65
+ const variantProduct =
66
+ product.isVariantOf?.skuVariants?.allVariantProducts?.find(
67
+ (variant) =>
68
+ variant.productID === product.id || variant.productID === product.sku
69
+ )
70
+ const productName = variantProduct?.name ?? product.name
71
+
72
+ return {
73
+ id: product.sku,
74
+ name: productName,
75
+ price: offer.price,
76
+ quantityUpdated,
77
+ image: {
78
+ url: product.image[0]?.url ?? '',
79
+ alternateName: product.image[0]?.alternateName || product.name,
80
+ },
81
+ inventory,
82
+ availability: availability as 'available' | 'outOfStock',
83
+ selectedCount,
84
+ }
85
+ }
@@ -0,0 +1,128 @@
1
+ import { useEffect, useMemo, useState } from 'react'
2
+
3
+ import { gql } from '@generated'
4
+ import type {
5
+ ClientProductQueryQuery,
6
+ ClientProductQueryQueryVariables,
7
+ } from '@generated/graphql'
8
+
9
+ import { request } from '../graphql/request'
10
+ import { useSession } from '../session'
11
+
12
+ // Use the same query as useProductQuery for individual products
13
+ const query = gql(`
14
+ query ClientProductQuery($locator: [IStoreSelectedFacet!]!) {
15
+ ...ClientProduct
16
+ product(locator: $locator) {
17
+ ...ProductDetailsFragment_product
18
+ }
19
+ }
20
+ `)
21
+
22
+ export interface BulkProductData {
23
+ sku: string
24
+ product?: ClientProductQueryQuery['product']
25
+ error?: Error
26
+ }
27
+
28
+ // Batch size to avoid overwhelming the server
29
+ const BATCH_SIZE = 10
30
+ const BATCH_DELAY_MS = 100
31
+
32
+ export const useBulkProductsQuery = (skus: string[]) => {
33
+ const { channel, locale } = useSession()
34
+ const [products, setProducts] = useState<BulkProductData[]>([])
35
+ const [isLoading, setIsLoading] = useState(false)
36
+ const [error, setError] = useState<Error | null>(null)
37
+
38
+ // Create a stable key for the SKUs array to use as a dependency
39
+ const skusKey = useMemo(() => {
40
+ return skus.join(',')
41
+ }, [skus])
42
+
43
+ useEffect(() => {
44
+ if (skus.length === 0) {
45
+ setProducts([])
46
+ setIsLoading(false)
47
+ return
48
+ }
49
+
50
+ const fetchProducts = async () => {
51
+ setIsLoading(true)
52
+ setError(null)
53
+
54
+ try {
55
+ if (!channel) {
56
+ throw new Error(
57
+ `useBulkProductsQuery: 'channel' from session is an empty string.`
58
+ )
59
+ }
60
+
61
+ const results: BulkProductData[] = []
62
+
63
+ for (let i = 0; i < skus.length; i += BATCH_SIZE) {
64
+ const batch = skus.slice(i, i + BATCH_SIZE)
65
+
66
+ const batchPromises = batch.map(
67
+ async (sku): Promise<BulkProductData> => {
68
+ try {
69
+ const variables: ClientProductQueryQueryVariables = {
70
+ locator: [
71
+ { key: 'id', value: sku },
72
+ { key: 'channel', value: channel },
73
+ { key: 'locale', value: locale },
74
+ ],
75
+ }
76
+
77
+ // Use POST method to avoid URL length issues with GET
78
+ const data = await request<
79
+ ClientProductQueryQuery,
80
+ ClientProductQueryQueryVariables
81
+ >(query, variables, {
82
+ fetchOptions: {
83
+ method: 'POST',
84
+ },
85
+ })
86
+
87
+ return {
88
+ sku,
89
+ product: data.product,
90
+ }
91
+ } catch (err) {
92
+ console.error(`Failed to fetch product ${sku}:`, err)
93
+ return {
94
+ sku,
95
+ error:
96
+ err instanceof Error
97
+ ? err
98
+ : new Error(`Failed to fetch product: ${sku}`),
99
+ }
100
+ }
101
+ }
102
+ )
103
+
104
+ const batchResults = await Promise.all(batchPromises)
105
+ results.push(...batchResults)
106
+
107
+ // Add a small delay between batches to avoid rate limiting
108
+ if (i + BATCH_SIZE < skus.length) {
109
+ await new Promise((resolve) => setTimeout(resolve, BATCH_DELAY_MS))
110
+ }
111
+ }
112
+
113
+ setProducts(results)
114
+ } catch (err) {
115
+ setError(
116
+ err instanceof Error ? err : new Error('Failed to fetch products')
117
+ )
118
+ setProducts([])
119
+ } finally {
120
+ setIsLoading(false)
121
+ }
122
+ }
123
+
124
+ fetchProducts()
125
+ }, [skusKey, channel, locale, skus.length])
126
+
127
+ return { products, isLoading, error }
128
+ }
@@ -11,4 +11,5 @@
11
11
  @import "src/components/sections/Section/section.scss";
12
12
 
13
13
  // Importing this component because is being used outside the context of the Section
14
- @import "@faststore/ui/src/components/molecules/Dropdown/styles.scss";
14
+ @import "@faststore/ui/src/components/organisms/QuickOrderDrawer/styles.scss";
15
+ @import "@faststore/ui/src/components/organisms/SlideOver/styles.scss";
@@ -1,59 +1,49 @@
1
- import discoveryConfig from 'discovery.config'
1
+ import { sessionStore } from 'src/sdk/session'
2
2
 
3
- export const STORAGE_KEY_AUTH_COOKIE_VALUE = 'faststore_auth_cookie_value'
3
+ export const STORAGE_KEY_PERSON_ID = 'faststore_person_id'
4
4
  export const STORAGE_KEY_CACHE_BUST_LAST_VALUE =
5
5
  'faststore_cache_bust_last_value'
6
6
 
7
7
  /**
8
- * Gets the VtexIdclientAutCookie value from browser
9
- * Note: vtex_segment is httpOnly and cannot be accessed via JavaScript,
10
- * so we only monitor VtexIdclientAutCookie_<account>
8
+ * Gets person?.id from session (via ValidateSession).
9
+ * Reads session store directly since auth cookies are httpOnly and inaccessible via JavaScript.
11
10
  */
12
- const getAuthCookieValue = (): string | null => {
13
- if (typeof document === 'undefined') {
11
+ const getPersonId = (): string | null => {
12
+ if (typeof window === 'undefined') {
14
13
  return null
15
14
  }
16
-
17
- const account = discoveryConfig.api.storeId
18
- const authCookieName = `VtexIdclientAutCookie_${account}`
19
- const cookies = document.cookie.split(';').map((cookie) => cookie.trim())
20
- const authCookie = cookies.find((c) => c.startsWith(`${authCookieName}=`))
21
-
22
- if (!authCookie) {
23
- return null
24
- }
25
-
26
- return authCookie.split('=').slice(1).join('=')
15
+ const session = sessionStore.read() ?? sessionStore.readInitial()
16
+ return session?.person?.id ?? null
27
17
  }
28
18
 
29
19
  /**
30
- * Gets the stored auth cookie value from sessionStorage (client-side only)
20
+ * Gets the stored person id from sessionStorage (client-side only)
31
21
  */
32
- const getStoredAuthCookieValue = (): string | null => {
22
+ const getStoredPersonId = (): string | null => {
33
23
  if (typeof sessionStorage === 'undefined') {
34
24
  return null
35
25
  }
36
26
 
37
27
  try {
38
- return sessionStorage.getItem(STORAGE_KEY_AUTH_COOKIE_VALUE)
28
+ return sessionStorage.getItem(STORAGE_KEY_PERSON_ID)
39
29
  } catch {
40
30
  return null
41
31
  }
42
32
  }
43
33
 
44
34
  /**
45
- * Stores the auth cookie value in sessionStorage (client-side only)
35
+ * Stores the person id in sessionStorage (client-side only)
46
36
  */
47
- const storeAuthCookieValue = (value: string | null): void => {
37
+ const storePersonId = (value: string | null): void => {
48
38
  if (typeof sessionStorage === 'undefined') {
49
39
  return
50
40
  }
51
41
 
52
42
  try {
53
43
  if (value === null) {
54
- sessionStorage.removeItem(STORAGE_KEY_AUTH_COOKIE_VALUE)
44
+ sessionStorage.removeItem(STORAGE_KEY_PERSON_ID)
55
45
  } else {
56
- sessionStorage.setItem(STORAGE_KEY_AUTH_COOKIE_VALUE, value)
46
+ sessionStorage.setItem(STORAGE_KEY_PERSON_ID, value)
57
47
  }
58
48
  } catch {
59
49
  // Ignore storage errors
@@ -93,13 +83,13 @@ const storeLastValue = (value: string): void => {
93
83
  /**
94
84
  * Clears all cache busting related data from sessionStorage (client-side only)
95
85
  */
96
- const clearStorage = (): void => {
86
+ const clearCacheBustingStorage = (): void => {
97
87
  if (typeof sessionStorage === 'undefined') {
98
88
  return
99
89
  }
100
90
 
101
91
  try {
102
- sessionStorage.removeItem(STORAGE_KEY_AUTH_COOKIE_VALUE)
92
+ sessionStorage.removeItem(STORAGE_KEY_PERSON_ID)
103
93
  sessionStorage.removeItem(STORAGE_KEY_CACHE_BUST_LAST_VALUE)
104
94
  } catch {
105
95
  // Ignore storage errors
@@ -107,28 +97,31 @@ const clearStorage = (): void => {
107
97
  }
108
98
 
109
99
  /**
110
- * Gets cache busting value for client-side based on auth cookie changes
100
+ * Gets cache busting value for client-side based on auth state changes.
101
+ * Uses person?.id from session (via useSession/ValidateSession) since auth cookies
102
+ * are now httpOnly and cannot be accessed via JavaScript.
111
103
  */
112
104
  export const getClientCacheBustingValue = (): string | null => {
113
- const currentAuthCookieValue = getAuthCookieValue()
105
+ const currentPersonId = getPersonId()
114
106
 
115
- // Guard clause: if auth cookie doesn't exist, clear storage and don't proceed with cache busting logic
116
- if (currentAuthCookieValue === null) {
117
- clearStorage()
107
+ // Guard clause: if user is not logged in (no person?.id), clear storage and don't proceed with cache busting logic
108
+ if (currentPersonId === null) {
109
+ clearCacheBustingStorage()
118
110
  return null
119
111
  }
120
112
 
121
- const storedAuthCookieValue = getStoredAuthCookieValue()
113
+ const storedPersonId = getStoredPersonId()
122
114
 
123
- // If auth cookie changed, update stored value and return new timestamp
124
- if (currentAuthCookieValue !== storedAuthCookieValue) {
125
- storeAuthCookieValue(currentAuthCookieValue)
115
+ // If person changed (login/logout or different user), update stored value and return new value
116
+ if (currentPersonId !== storedPersonId) {
117
+ storePersonId(currentPersonId)
126
118
  const timestamp = Date.now().toString()
127
- storeLastValue(timestamp)
128
- return timestamp
119
+ const value = `${timestamp}::${currentPersonId}`
120
+ storeLastValue(value)
121
+ return value
129
122
  }
130
123
 
131
- // Auth cookie hasn't changed, return last value or create one if it doesn't exist
124
+ // Person hasn't changed, return last value or create one if it doesn't exist
132
125
  const lastValue = getLastValue()
133
126
  if (lastValue) {
134
127
  return lastValue
@@ -136,6 +129,7 @@ export const getClientCacheBustingValue = (): string | null => {
136
129
 
137
130
  // Fallback: if no last value, create one
138
131
  const timestamp = Date.now().toString()
139
- storeLastValue(timestamp)
140
- return timestamp
132
+ const value = `${timestamp}::${currentPersonId}`
133
+ storeLastValue(value)
134
+ return value
141
135
  }
@@ -108,3 +108,65 @@ export const buildFormData = (
108
108
 
109
109
  export const toArray = <T>(x: T[] | T | undefined) =>
110
110
  Array.isArray(x) ? x : x ? [x] : []
111
+
112
+ /**
113
+ * Formats the file name to a more user-friendly version.
114
+ * @param fileName - The original file name.
115
+ * @returns The formatted file name.
116
+ * @example
117
+ * formatFileName('smartphoneX5-23-256gb-black-edition-2023.csv')
118
+ * // Returns: 'smartphoneX5-23...ck-edition-2023.csv'
119
+ */
120
+ export function formatFileName(fileName: string): string {
121
+ const maxLength = 30
122
+ const extensionIndex = fileName.lastIndexOf('.')
123
+ const extension = extensionIndex !== -1 ? fileName.slice(extensionIndex) : ''
124
+
125
+ if (fileName.length <= maxLength) {
126
+ return fileName
127
+ }
128
+
129
+ const nameWithoutExtension =
130
+ extensionIndex !== -1 ? fileName.slice(0, extensionIndex) : fileName
131
+
132
+ const availableBase = maxLength - extension.length
133
+
134
+ if (availableBase <= 0) {
135
+ // Extension alone exceeds maxLength; truncate from the end of the full name
136
+ return fileName.slice(0, maxLength)
137
+ }
138
+
139
+ const ellipsis = '...'
140
+ if (availableBase <= ellipsis.length) {
141
+ return `${nameWithoutExtension.slice(0, availableBase)}${extension}`
142
+ }
143
+
144
+ const half = Math.floor((availableBase - ellipsis.length) / 2)
145
+ const start = nameWithoutExtension.slice(0, half)
146
+ const end = nameWithoutExtension.slice(
147
+ -(availableBase - ellipsis.length - half)
148
+ )
149
+ const truncatedNameWithoutExtension = `${start}${ellipsis}${end}`
150
+
151
+ return `${truncatedNameWithoutExtension}${extension}`
152
+ }
153
+
154
+ /**
155
+ * Formats a file size in bytes to a human-readable string.
156
+ * @param bytes - The file size in bytes.
157
+ * @returns The formatted file size string.
158
+ * @example
159
+ * formatFileSize(2048) // Returns: '2 KB'
160
+ */
161
+ export const formatFileSize = (bytes: number): string => {
162
+ if (bytes <= 0) return '0 Bytes'
163
+
164
+ const k = 1024
165
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
166
+ const i = Math.min(
167
+ Math.floor(Math.log(bytes) / Math.log(k)),
168
+ sizes.length - 1
169
+ )
170
+
171
+ return `${Number.parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}`
172
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "../tsconfig.json",
3
+ "compilerOptions": {
4
+ "types": ["jest"]
5
+ },
6
+ "include": ["**/*.ts", "**/*.tsx"]
7
+ }