@faststore/core 4.8.0-dev.6 → 4.8.0-dev.7

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.
@@ -1,9 +1,9 @@
1
1
 
2
- > @faststore/core@4.8.0-dev.5 generate /home/runner/work/faststore/faststore/packages/core
2
+ > @faststore/core@4.8.0-dev.6 generate /home/runner/work/faststore/faststore/packages/core
3
3
  > pnpm run gen-types && pnpm run cache-graphql
4
4
 
5
5
 
6
- > @faststore/core@4.8.0-dev.5 gen-types /home/runner/work/faststore/faststore/packages/core
6
+ > @faststore/core@4.8.0-dev.6 gen-types /home/runner/work/faststore/faststore/packages/core
7
7
  > node ../cli/bin/run generate-types .
8
8
 
9
9
  [STARTED] Parse Configuration
@@ -19,7 +19,7 @@
19
19
  [COMPLETED] Generate to @generated/
20
20
  [COMPLETED] Generate outputs
21
21
 
22
- > @faststore/core@4.8.0-dev.5 cache-graphql /home/runner/work/faststore/faststore/packages/core
22
+ > @faststore/core@4.8.0-dev.6 cache-graphql /home/runner/work/faststore/faststore/packages/core
23
23
  > node ../cli/bin/run cache-graphql --config=./discovery.config.default.js --queries=./@generated/persisted-documents.json
24
24
 
25
25
  [Info] - Config file location: /home/runner/work/faststore/faststore/packages/core/discovery.config.default.js
@@ -1,5 +1,5 @@
1
1
 
2
- > @faststore/core@4.8.0-dev.5 test /home/runner/work/faststore/faststore/packages/core
2
+ > @faststore/core@4.8.0-dev.6 test /home/runner/work/faststore/faststore/packages/core
3
3
  > vitest run
4
4
 
5
5
 
@@ -10,17 +10,16 @@ Not implemented: navigation to another Document
10
10
  Browserslist: browsers data (caniuse-lite) is 7 months old. Please run:
11
11
  npx update-browserslist-db@latest
12
12
  Why you should do it regularly: https://github.com/browserslist/update-db#readme
13
- ✓  browser  test/sdk/ui/useScrollRestoration.browser.test.ts (43 tests) 910ms
14
- ✓  browser  test/components/CartRecommendationShelf/CartRecommendationShelf.browser.test.tsx (13 tests) 510ms
15
- ✓  browser  test/components/account/cards/MyAccountListCards.browser.test.tsx (14 tests) 2388ms
16
- ✓ shows the tab bar and renders Personal cards by default  1027ms
17
- ✓ paginates when there are more than 25 cards  389ms
18
- ✓  browser  test/sdk/localization/useBindingSelector.browser.test.tsx (9 tests) 224ms
19
- ✓  browser  test/components/account/ContractSwitcher.browser.test.tsx (13 tests) 2328ms
20
- ✓ shows an error state when the list fails to load  514ms
21
- ✓ requires selecting a contract before Confirm is enabled, then switches (REQ-03)  304ms
22
- ✓  browser  test/components/ui/ProductGallery/GalleryPageHeightLock.browser.test.tsx (8 tests) 212ms
23
- ✓  browser  test/sdk/session/reconcileSessionLocale.browser.test.ts (5 tests) 27ms
13
+ ✓  browser  test/sdk/ui/useScrollRestoration.browser.test.ts (43 tests) 837ms
14
+ ✓  browser  test/components/CartRecommendationShelf/CartRecommendationShelf.browser.test.tsx (13 tests) 412ms
15
+ ✓  browser  test/components/account/cards/MyAccountListCards.browser.test.tsx (14 tests) 1807ms
16
+ ✓ shows the tab bar and renders Personal cards by default  601ms
17
+ ✓ paginates when there are more than 25 cards  324ms
18
+ ✓  browser  test/sdk/localization/useBindingSelector.browser.test.tsx (9 tests) 130ms
19
+ ✓  browser  test/components/account/ContractSwitcher.browser.test.tsx (13 tests) 1943ms
20
+ ✓ shows an error state when the list fails to load  610ms
21
+ ✓  browser  test/components/ui/ProductGallery/GalleryPageHeightLock.browser.test.tsx (8 tests) 240ms
22
+ ✓  browser  test/sdk/session/reconcileSessionLocale.browser.test.ts (5 tests) 17ms
24
23
  stderr | test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx
25
24
  Error in optimistic validation: TypeError: Failed to parse URL from /api/graphql?operationName=ValidateCartMutation&operationHash=3c71b0d3fc2bade14df68abfa271858beb361b12
26
25
   at node:internal/deps/undici/undici:16416:13
@@ -50,9 +49,9 @@ Browserslist: browsers data (caniuse-lite) is 7 months old. Please run:
50
49
  stderr | test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx > RecommendationShelf > renders nothing when there is an error
51
50
  Error fetching recommendations undefined boom for campaign vrn:recommendations:acc:rec-top-items-v2:campaign-1
52
51
 
53
- ✓  browser  test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx (8 tests) 291ms
54
- ✓  browser  test/sdk/recommendations/useRecommendationShelf.browser.test.tsx (12 tests) 136ms
55
- ✓  browser  test/components/CartSidebar/CartSidebar.browser.test.tsx (5 tests) 119ms
52
+ ✓  browser  test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx (8 tests) 141ms
53
+ ✓  browser  test/sdk/recommendations/useRecommendationShelf.browser.test.tsx (12 tests) 96ms
54
+ ✓  browser  test/components/CartSidebar/CartSidebar.browser.test.tsx (5 tests) 97ms
56
55
  stderr | test/pages/password-protection.browser.test.tsx > PasswordProtectionLogin > posts the password and redirects to the requested return path
57
56
  Warning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
58
57
 
@@ -138,6 +137,7 @@ act(() => {
138
137
  This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
139
138
  at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
140
139
 
140
+ ✓  browser  test/sdk/session/getInitialSession.browser.test.ts (6 tests) 8ms
141
141
  stderr | test/pages/password-protection.browser.test.tsx > PasswordProtectionLogin > uses the fallback invalid-password message when API omits an error
142
142
  Warning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
143
143
 
@@ -282,12 +282,11 @@ act(() => {
282
282
  This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
283
283
  at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
284
284
 
285
- ✓  browser  test/pages/password-protection.browser.test.tsx (6 tests) 936ms
286
- ✓ renders the password protection form  331ms
287
- ✓  browser  test/components/account/OrganizationDrawer.browser.test.tsx (5 tests) 750ms
288
- ✓ renders the menu view with contract details and manage footer  378ms
289
- ✓  browser  test/sdk/session/getInitialSession.browser.test.ts (6 tests) 15ms
290
- ✓  browser  test/sdk/account/changeContractToken.browser.test.ts (9 tests) 45ms
285
+ ✓  browser  test/pages/password-protection.browser.test.tsx (6 tests) 619ms
286
+ ✓ renders the password protection form  351ms
287
+ ✓  browser  test/components/account/OrganizationDrawer.browser.test.tsx (5 tests) 682ms
288
+ ✓ renders the menu view with contract details and manage footer  326ms
289
+ ✓  browser  test/sdk/account/changeContractToken.browser.test.ts (9 tests) 40ms
291
290
  stderr | test/sdk/localization/store-url.browser.test.ts
292
291
  Error in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
293
292
  at waitForSessionValidated (/home/runner/work/faststore/faststore/packages/core/src/sdk/cart/waitForSessionValidated.ts:16:32)
@@ -296,7 +295,6 @@ This ensures that you're testing the behavior the user would see in the browser.
296
295
  at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:354:23)
297
296
   at processTicksAndRejections (node:internal/process/task_queues:103:5)
298
297
 
299
- ✓  browser  test/sdk/localization/store-url.browser.test.ts (3 tests) 4ms
300
298
  stderr | test/components/cms/RenderSections.browser.test.tsx
301
299
  Error in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
302
300
  at waitForSessionValidated (/home/runner/work/faststore/faststore/packages/core/src/sdk/cart/waitForSessionValidated.ts:16:32)
@@ -305,12 +303,13 @@ This ensures that you're testing the behavior the user would see in the browser.
305
303
  at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:354:23)
306
304
   at processTicksAndRejections (node:internal/process/task_queues:103:5)
307
305
 
308
- ✓  browser  test/sdk/account/useAvailableContracts.browser.test.ts (6 tests) 30ms
309
- ✓  browser  test/components/cms/RenderSections.browser.test.tsx (5 tests) 77ms
310
- ✓  browser  test/components/templates/SearchPage/SearchWrapper.browser.test.tsx (3 tests) 37ms
311
- ✓  browser  test/sdk/recommendations/useRecommendationShelf.sessionFallback.browser.test.tsx (2 tests) 75ms
312
- ✓  browser  test/sdk/account/useSwitchContract.browser.test.ts (4 tests) 28ms
313
- ✓  browser  test/components/CartRecommendationShelf/CartRecommendationProductCard.browser.test.tsx (3 tests) 48ms
306
+ ✓  browser  test/sdk/localization/store-url.browser.test.ts (3 tests) 4ms
307
+ ✓  browser  test/sdk/account/useAvailableContracts.browser.test.ts (6 tests) 23ms
308
+ ✓  browser  test/components/cms/RenderSections.browser.test.tsx (5 tests) 71ms
309
+ ✓  browser  test/components/templates/SearchPage/SearchWrapper.browser.test.tsx (3 tests) 30ms
310
+ ✓  browser  test/sdk/recommendations/useRecommendationShelf.sessionFallback.browser.test.tsx (2 tests) 120ms
311
+ ✓  browser  test/sdk/account/useSwitchContract.browser.test.ts (4 tests) 25ms
312
+ ✓  browser  test/components/CartRecommendationShelf/CartRecommendationProductCard.browser.test.tsx (3 tests) 42ms
314
313
  stderr | test/components/account/doLogout.browser.test.ts
315
314
  Error in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
316
315
  at waitForSessionValidated (/home/runner/work/faststore/faststore/packages/core/src/sdk/cart/waitForSessionValidated.ts:16:32)
@@ -319,11 +318,11 @@ This ensures that you're testing the behavior the user would see in the browser.
319
318
  at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:354:23)
320
319
   at processTicksAndRejections (node:internal/process/task_queues:103:5)
321
320
 
322
- ✓  browser  test/components/account/doLogout.browser.test.ts (1 test) 30ms
323
- ✓  browser  test/components/ui/LocalizationButton.browser.test.tsx (3 tests) 45ms
324
- ✓  browser  test/components/sections/Account/AccountListCards.browser.test.tsx (3 tests) 83ms
325
- ✓  browser  test/components/account/OrganizationDrawerHeader.browser.test.tsx (3 tests) 279ms
326
- ✓  browser  test/components/account/OrganizationDrawerFooter.browser.test.tsx (3 tests) 273ms
321
+ ✓  browser  test/components/account/doLogout.browser.test.ts (1 test) 21ms
322
+ ✓  browser  test/components/ui/LocalizationButton.browser.test.tsx (3 tests) 40ms
323
+ ✓  browser  test/components/sections/Account/AccountListCards.browser.test.tsx (3 tests) 62ms
324
+ ✓  browser  test/components/account/OrganizationDrawerHeader.browser.test.tsx (3 tests) 220ms
325
+ ✓  browser  test/components/account/OrganizationDrawerFooter.browser.test.tsx (3 tests) 230ms
327
326
  stderr | test/sdk/account/clearPersistedSessionState.browser.test.ts
328
327
  Error in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
329
328
  at waitForSessionValidated (/home/runner/work/faststore/faststore/packages/core/src/sdk/cart/waitForSessionValidated.ts:16:32)
@@ -332,10 +331,11 @@ This ensures that you're testing the behavior the user would see in the browser.
332
331
  at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:354:23)
333
332
   at processTicksAndRejections (node:internal/process/task_queues:103:5)
334
333
 
334
+ ✓  browser  test/sdk/account/clearPersistedSessionState.browser.test.ts (1 test) 6ms
335
335
  ✓  browser  test/utils/isLocalHost.browser.test.ts (3 tests) 4ms
336
- ✓  browser  test/sdk/account/clearPersistedSessionState.browser.test.ts (1 test) 12ms
337
336
  ✓  browser  test/sdk/session/reconcileSessionLocale.disabled.browser.test.ts (1 test) 3ms
338
- ✓  node  test/utils/localization/bindingPaths.test.ts (71 tests) 32ms
337
+ ✓  node  test/utils/localization/bindingPaths.test.ts (71 tests) 12ms
338
+ ✓  node  test/server/password-protection-service.test.ts (22 tests) 29ms
339
339
  stderr | test/sdk/account/refreshToken.browser.test.ts
340
340
  Error in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
341
341
  at waitForSessionValidated (/home/runner/work/faststore/faststore/packages/core/src/sdk/cart/waitForSessionValidated.ts:16:32)
@@ -344,13 +344,12 @@ This ensures that you're testing the behavior the user would see in the browser.
344
344
  at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:354:23)
345
345
   at processTicksAndRejections (node:internal/process/task_queues:103:5)
346
346
 
347
+ ✓  browser  test/components/skeletons/ProductGridSkeleton.browser.test.tsx (2 tests) 34ms
347
348
  ✓  browser  test/sdk/account/refreshToken.browser.test.ts (1 test) 4ms
348
- ✓  browser  test/components/skeletons/ProductGridSkeleton.browser.test.tsx (2 tests) 36ms
349
- ✓  node  test/server/password-protection-service.test.ts (22 tests) 36ms
350
349
  ✓  node  test/utils/match-url.test.ts (10 tests) 8ms
351
- ✓  node  test/sdk/localization/useBindingSelector.test.tsx (22 tests) 15ms
352
- ✓  node  test/pages/api/unlock.test.ts (15 tests) 152ms
353
- ✓  node  test/sdk/localization/bindingSelector.test.ts (18 tests) 7ms
350
+ ✓  node  test/sdk/localization/useBindingSelector.test.tsx (22 tests) 12ms
351
+ ✓  node  test/pages/api/unlock.test.ts (15 tests) 140ms
352
+ ✓  node  test/sdk/localization/bindingSelector.test.ts (18 tests) 8ms
354
353
  stderr | test/components/search/SearchInputComponent.test.tsx
355
354
  Warning: forwardRef render functions accept exactly two parameters: props and ref. Did you forget to use the ref parameter?
356
355
 
@@ -414,19 +413,19 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
414
413
  at Suspense
415
414
  at Wrapper (/home/runner/work/faststore/faststore/packages/core/test/components/search/SearchInputComponent.test.tsx:106:20)
416
415
 
417
- ✓  node  test/components/search/SearchInputComponent.test.tsx (6 tests) 73ms
418
- ✓  node  test/sdk/search/useSearchHistory.test.ts (13 tests) 55ms
419
- ✓  node  test/utils/cookieCacheBusting.test.ts (10 tests) 14ms
416
+ ✓  node  test/components/search/SearchInputComponent.test.tsx (6 tests) 62ms
417
+ ✓  node  test/sdk/search/useSearchHistory.test.ts (13 tests) 38ms
418
+ ✓  node  test/utils/cookieCacheBusting.test.ts (10 tests) 10ms
420
419
  stderr | test/pages/pvt/account/cards/index.test.ts > Cards page getServerSideProps > redirects to /pvt/account/403 when the query fails with 401/403
421
420
  { extensions: { status: 401 } }
422
421
 
423
422
  stderr | test/pages/pvt/account/cards/index.test.ts > Cards page getServerSideProps > renders the error state (no redirect) when the query fails with a non-auth status
424
423
  { extensions: { status: 502 } }
425
424
 
426
- ✓  node  test/pages/pvt/account/cards/index.test.ts (8 tests) 12ms
427
- ✓  node  test/utils/clearCookies.test.ts (20 tests) 19ms
425
+ ✓  node  test/pages/pvt/account/cards/index.test.ts (8 tests) 8ms
426
+ ✓  node  test/utils/clearCookies.test.ts (20 tests) 24ms
428
427
  ✓  node  test/experimental/myAccountCmsServerSideProps.test.ts (5 tests) 7ms
429
- ✓  node  test/components/quotes/MyAccountListQuotesTable.test.tsx (12 tests) 372ms
428
+ ✓  node  test/components/quotes/MyAccountListQuotesTable.test.tsx (12 tests) 314ms
430
429
  stderr | test/pages/api/graphql.test.ts > /api/graphql error status propagation > propagates the upstream 400 from a wrapped BadRequestError instead of 500
431
430
  Graphql execution returned with error: [
432
431
  {
@@ -519,69 +518,69 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
519
518
  at file:///home/runner/work/faststore/faststore/node_modules/.pnpm/@vitest+runner@4.0.18/node_modules/@vitest/runner/dist/index.js:1653:37
520
519
  at Traces.$ (file:///home/runner/work/faststore/faststore/node_modules/.pnpm/vitest@4.0.18_@opentelemetry+api@1.9.0_@types+node@20.19.13_jiti@2.6.1_jsdom@27.4.0_sas_13be941c57d55f08f06eeaf1c180ddfe/node_modules/vitest/dist/chunks/traces.CCmnQaNT.js:142:27)
521
520
 
522
- ✓  node  test/pages/api/graphql.test.ts (17 tests) 28ms
523
- ✓  node  test/components/quotes/MyAccountListQuotes.test.tsx (9 tests) 802ms
524
- ✓ navigates with the search term on blur  360ms
525
- ✓ navigates without a label param when the search is cleared  357ms
521
+ ✓  node  test/pages/api/graphql.test.ts (17 tests) 19ms
526
522
  stderr | test/sdk/account/useSetPassword.test.ts > useSetPassword > maps wrongcredentials error responses to the existing message
527
523
  Set password request failed: Bad Request
528
524
 
529
- ✓  node  test/sdk/account/useSetPassword.test.ts (6 tests) 31ms
530
- ✓  node  test/utils/multipleTemplates.test.ts (8 tests) 7ms
531
- ✓  node  test/sdk/orderEntry/useOrderEntryOperation.test.ts (8 tests) 30ms
532
- ✓  node  test/components/quotes/quoteFilters.test.ts (23 tests) 35ms
533
- ✓  node  test/utils/localization/localizeRedirectDestination.test.ts (11 tests) 8ms
525
+ ✓  node  test/sdk/account/useSetPassword.test.ts (6 tests) 22ms
526
+ ✓  node  test/components/quotes/quoteFilters.test.ts (23 tests) 22ms
527
+ ✓  node  test/components/quotes/MyAccountListQuotes.test.tsx (9 tests) 796ms
528
+ ✓ navigates with the search term on blur  358ms
529
+ ✓ navigates without a label param when the search is cleared  357ms
530
+ ✓  node  test/sdk/orderEntry/useOrderEntryOperation.test.ts (8 tests) 37ms
531
+ ✓  node  test/utils/multipleTemplates.test.ts (8 tests) 4ms
532
+ ✓  node  test/utils/localization/localizeRedirectDestination.test.ts (11 tests) 5ms
534
533
  ✓  node  test/utils/localization/hreflang.test.ts (8 tests) 5ms
535
- ✓  node  test/sdk/account/getMyAccountRoutes.test.ts (12 tests) 6ms
536
- ✓  node  test/sdk/orderEntry/useOrderEntryUpload.test.ts (8 tests) 51ms
537
- ✓  node  test/sdk/redirects/index.test.ts (7 tests) 56ms
538
- ✓  node  test/components/quotes/MyAccountQuotesFilterSlider.test.tsx (5 tests) 135ms
539
- ✓  node  test/utils/productJsonLd.test.ts (17 tests) 6ms
540
- ✓  node  test/proxy.localization.test.ts (5 tests) 36ms
541
- ✓  node  test/sdk/orderEntry/useOrderEntry.test.ts (8 tests) 28ms
542
- ✓  node  test/server/index.test.ts (7 tests) 984ms
543
- ✓ should return a valid merged GraphQL schema  318ms
544
- ✓ should handle options and execute  373ms
545
- ✓  node  test/sdk/session/syncSalesChannelFromOrderForm.test.ts (6 tests) 6ms
546
- ✓  node  test/components/quotes/MyAccountQuotesSelectedTags.test.tsx (8 tests) 112ms
547
- ✓  node  test/sdk/analytics/useStartRecommendationSession.test.ts (6 tests) 38ms
548
- ✓  node  test/proxy.test.ts (4 tests) 16ms
549
- ✓  node  test/server/webops-api.test.ts (9 tests) 15ms
550
- ✓  node  test/sdk/orderEntry/useOrderFormItems.test.ts (7 tests) 37ms
534
+ ✓  node  test/sdk/account/getMyAccountRoutes.test.ts (12 tests) 11ms
535
+ ✓  node  test/sdk/orderEntry/useOrderEntryUpload.test.ts (8 tests) 38ms
536
+ ✓  node  test/sdk/redirects/index.test.ts (7 tests) 39ms
537
+ ✓  node  test/components/quotes/MyAccountQuotesFilterSlider.test.tsx (5 tests) 119ms
538
+ ✓  node  test/utils/productJsonLd.test.ts (17 tests) 8ms
539
+ ✓  node  test/proxy.localization.test.ts (5 tests) 29ms
540
+ ✓  node  test/sdk/graphql/retryPolicy.test.ts (18 tests) 14ms
541
+ ✓  node  test/sdk/orderEntry/useOrderEntry.test.ts (8 tests) 30ms
542
+ ✓  node  test/server/index.test.ts (7 tests) 794ms
543
+ ✓ should handle options and execute  376ms
544
+ ✓  node  test/sdk/session/syncSalesChannelFromOrderForm.test.ts (6 tests) 7ms
545
+ ✓  node  test/sdk/analytics/useStartRecommendationSession.test.ts (6 tests) 43ms
546
+ ✓  node  test/components/quotes/MyAccountQuotesSelectedTags.test.tsx (8 tests) 69ms
547
+ ✓  node  test/server/webops-api.test.ts (9 tests) 16ms
548
+ ✓  node  test/proxy.test.ts (4 tests) 12ms
549
+ ✓  node  test/sdk/orderEntry/useOrderFormItems.test.ts (7 tests) 30ms
550
+ ✓  node  test/sdk/cart/waitForSessionValidated.test.ts (5 tests) 11ms
551
551
  ✓  node  test/sdk/localization/store-url.test.ts (4 tests) 4ms
552
- ✓  node  test/sdk/cart/waitForSessionValidated.test.ts (5 tests) 12ms
553
- ✓  node  test/server/cms/myAccountDefaultSections.test.ts (7 tests) 4ms
554
- ✓  node  test/server/content/service.test.ts (5 tests) 8ms
555
- ✓  node  test/utils/productJsonLdRendering.test.tsx (4 tests) 10ms
556
- ✓  node  test/sdk/account/refreshToken.test.ts (5 tests) 8ms
557
- ✓  node  test/server/cms/global.test.ts (3 tests) 5ms
558
- ✓  node  test/sdk/auth/useAuth.test.ts (5 tests) 66ms
559
- ✓  node  test/components/quotes/MyAccountQuotesStatusSelector.test.tsx (6 tests) 132ms
560
- ✓  node  test/utils/getRequestHostname.test.ts (12 tests) 5ms
561
- ✓  node  test/server/rootSpan.test.ts (4 tests) 51ms
562
- ✓  node  test/pages/api/preview.test.ts (2 tests) 11ms
563
- ✓  node  test/components/search/SearchInput.test.ts (6 tests) 8ms
564
- ✓  node  test/utils/validateSessionRefreshToken.test.ts (6 tests) 4ms
565
- ✓  node  test/components/account/Layout.test.tsx (6 tests) 54ms
566
- ✓  node  test/sdk/recommendations/vrn.test.ts (5 tests) 7ms
567
- ✓  node  test/utils/retry.test.ts (5 tests) 13ms
568
- ✓  node  test/server/cms/index.test.ts (2 tests) 5ms
569
- ✓  node  test/sdk/account/getB2BSessionClaims.test.ts (4 tests) 5ms
570
- ✓  node  test/utils/unlockResponse.test.ts (11 tests) 6ms
571
- ✓  node  test/sdk/recommendations/useRecommendations.test.ts (2 tests) 3ms
572
- ✓  node  test/sdk/recommendations/useRecommendationUserId.test.ts (4 tests) 187ms
552
+ ✓  node  test/server/cms/myAccountDefaultSections.test.ts (7 tests) 6ms
553
+ ✓  node  test/server/content/service.test.ts (5 tests) 4ms
554
+ ✓  node  test/utils/productJsonLdRendering.test.tsx (4 tests) 9ms
555
+ ✓  node  test/server/cms/global.test.ts (3 tests) 4ms
556
+ ✓  node  test/sdk/account/refreshToken.test.ts (5 tests) 5ms
557
+ ✓  node  test/sdk/auth/useAuth.test.ts (5 tests) 27ms
558
+ ✓  node  test/components/quotes/MyAccountQuotesStatusSelector.test.tsx (6 tests) 112ms
559
+ ✓  node  test/utils/getRequestHostname.test.ts (12 tests) 4ms
560
+ ✓  node  test/server/rootSpan.test.ts (4 tests) 32ms
561
+ ✓  node  test/pages/api/preview.test.ts (2 tests) 8ms
562
+ ✓  node  test/components/search/SearchInput.test.ts (6 tests) 7ms
563
+ ✓  node  test/utils/validateSessionRefreshToken.test.ts (6 tests) 3ms
564
+ ✓  node  test/components/account/Layout.test.tsx (6 tests) 58ms
565
+ ✓  node  test/sdk/recommendations/vrn.test.ts (5 tests) 4ms
566
+ ✓  node  test/server/cms/index.test.ts (2 tests) 4ms
567
+ ✓  node  test/utils/retry.test.ts (5 tests) 12ms
568
+ ✓  node  test/sdk/account/getB2BSessionClaims.test.ts (4 tests) 3ms
569
+ ✓  node  test/utils/unlockResponse.test.ts (11 tests) 3ms
570
+ ✓  node  test/sdk/recommendations/useRecommendations.test.ts (2 tests) 4ms
571
+ ✓  node  test/sdk/recommendations/useRecommendationUserId.test.ts (4 tests) 176ms
573
572
  ✓  node  test/utils/isLocalHost.test.ts (7 tests) 4ms
574
- ✓  node  test/components/account/OrganizationDrawerBody.test.tsx (3 tests) 52ms
575
- ✓  node  test/utils/userOrderStatus.test.ts (3 tests) 4ms
573
+ ✓  node  test/components/account/OrganizationDrawerBody.test.tsx (3 tests) 37ms
574
+ ✓  node  test/utils/userOrderStatus.test.ts (3 tests) 3ms
576
575
  ✓  node  test/utils/getCookie.test.ts (4 tests) 4ms
577
- ✓  node  test/sdk/analytics/utils.test.ts (2 tests) 4ms
578
- ✓  node  test/components/auth/ProfileChallenge.test.tsx (3 tests) 27ms
579
- ✓  node  test/instrumentation.test.ts (3 tests) 6ms
580
- ✓  node  test/sdk/account/clearPersistedSessionState.test.ts (1 test) 17ms
581
- ✓  node  test/components/quotes/MyAccountQuoteStatusBadge.test.tsx (2 tests) 24ms
582
-
583
-  Test Files  97 passed (97)
584
-  Tests  775 passed (775)
585
-  Start at  16:35:24
586
-  Duration  47.08s (transform 13.69s, setup 0ms, import 42.13s, tests 13.98s, environment 58.37s)
576
+ ✓  node  test/sdk/analytics/utils.test.ts (2 tests) 3ms
577
+ ✓  node  test/components/auth/ProfileChallenge.test.tsx (3 tests) 32ms
578
+ ✓  node  test/instrumentation.test.ts (3 tests) 3ms
579
+ ✓  node  test/sdk/account/clearPersistedSessionState.test.ts (1 test) 6ms
580
+ ✓  node  test/components/quotes/MyAccountQuoteStatusBadge.test.tsx (2 tests) 19ms
581
+
582
+  Test Files  98 passed (98)
583
+  Tests  793 passed (793)
584
+  Start at  17:47:42
585
+  Duration  36.02s (transform 10.49s, setup 0ms, import 32.11s, tests 11.46s, environment 45.03s)
587
586
 
package/CHANGELOG.md CHANGED
@@ -3,6 +3,12 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [4.8.0-dev.7](https://github.com/vtex/faststore/compare/v4.8.0-dev.6...v4.8.0-dev.7) (2026-09-14)
7
+
8
+ ### Bug Fixes
9
+
10
+ - stop retrying upstream 429 responses ([#3453](https://github.com/vtex/faststore/issues/3453)) ([a142258](https://github.com/vtex/faststore/commit/a14225863578965609aa5012cc1ca9f0132959b2)), closes [#3379](https://github.com/vtex/faststore/issues/3379) [#3420](https://github.com/vtex/faststore/issues/3420) [#1629](https://github.com/vtex/faststore/issues/1629) [/github.com/vtex/faststore/pull/3453#issuecomment-5433632179](https://github.com//github.com/vtex/faststore/pull/3453/issues/issuecomment-5433632179)
11
+
6
12
  # [4.8.0-dev.6](https://github.com/vtex/faststore/compare/v4.8.0-dev.5...v4.8.0-dev.6) (2026-09-11)
7
13
 
8
14
  **Note:** Version bump only for package @faststore/core
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/core",
3
- "version": "4.8.0-dev.6",
3
+ "version": "4.8.0-dev.7",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -71,11 +71,11 @@
71
71
  "style-loader": "^3.3.1",
72
72
  "swr": "^2.2.5",
73
73
  "use-sync-external-store": "^1.6.0",
74
- "@faststore/api": "4.8.0-dev.6",
75
- "@faststore/lighthouse": "4.8.0-dev.6",
76
- "@faststore/diagnostics": "4.8.0-dev.6",
77
- "@faststore/sdk": "4.8.0-dev.6",
78
- "@faststore/ui": "4.8.0-dev.6"
74
+ "@faststore/api": "4.8.0-dev.7",
75
+ "@faststore/diagnostics": "4.8.0-dev.7",
76
+ "@faststore/ui": "4.8.0-dev.7",
77
+ "@faststore/lighthouse": "4.8.0-dev.7",
78
+ "@faststore/sdk": "4.8.0-dev.7"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@cypress/code-coverage": "^3.12.1",
@@ -0,0 +1,49 @@
1
+ const MAX_BACKOFF_EXPONENT = 8
2
+ const TOO_MANY_REQUESTS = 429
3
+
4
+ /** Mirrors SWR's `RevalidatorOptions`. */
5
+ type RetryOptions = { retryCount: number; dedupe?: boolean }
6
+
7
+ /** Mirrors the subset of SWR's resolved config that the retry policy reads. */
8
+ type RetryConfig = { errorRetryCount?: number; errorRetryInterval: number }
9
+
10
+ /**
11
+ * SWR retry policy: never retry an upstream rate limit, retry everything else
12
+ * exactly as SWR would.
13
+ *
14
+ * A 429 means an upstream is already shedding load, so retrying multiplies the
15
+ * traffic it is trying to reject. Providing `onErrorRetry` replaces SWR's
16
+ * default implementation entirely, so the fall-through branch mirrors
17
+ * swr@2.4.0's default (ceiling check plus jittered exponential backoff) to keep
18
+ * every other status behaving as it did before. Revisit on an SWR upgrade.
19
+ *
20
+ * SWR writes the truncation as `~~`; `Math.trunc` is used here instead because
21
+ * the values stay far below 2^31, where the two are equivalent.
22
+ */
23
+ export const onErrorRetry = (
24
+ error: unknown,
25
+ _key: string,
26
+ config: RetryConfig,
27
+ revalidate: (opts: RetryOptions) => void,
28
+ opts: RetryOptions
29
+ ) => {
30
+ if (
31
+ (error as { status?: number } | undefined)?.status === TOO_MANY_REQUESTS
32
+ ) {
33
+ return
34
+ }
35
+
36
+ const maxRetryCount = config.errorRetryCount
37
+ const { retryCount } = opts
38
+
39
+ const timeout =
40
+ Math.trunc(
41
+ (Math.random() + 0.5) * (1 << Math.min(retryCount, MAX_BACKOFF_EXPONENT))
42
+ ) * config.errorRetryInterval
43
+
44
+ if (maxRetryCount !== undefined && retryCount > maxRetryCount) {
45
+ return
46
+ }
47
+
48
+ setTimeout(revalidate, timeout, opts)
49
+ }
@@ -5,6 +5,7 @@ import { getClientCacheBustingValue } from 'src/utils/cookieCacheBusting'
5
5
 
6
6
  import type { Operation, RequestOptions } from './request'
7
7
  import { request } from './request'
8
+ import { onErrorRetry } from './retryPolicy'
8
9
 
9
10
  export type QueryOptions = SWRConfiguration &
10
11
  RequestOptions & { doNotRun?: boolean }
@@ -34,6 +35,7 @@ export const DEFAULT_OPTIONS = {
34
35
  revalidateOnFocus: false,
35
36
  revalidateOnReconnect: false,
36
37
  shouldRetryOnError: true,
38
+ onErrorRetry,
37
39
  }
38
40
 
39
41
  export const useQuery = <Data, Variables = Record<string, unknown>>(
@@ -0,0 +1,135 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
2
+
3
+ import { onErrorRetry } from '../../../src/sdk/graphql/retryPolicy'
4
+
5
+ const ERROR_RETRY_INTERVAL = 5000
6
+
7
+ type RetryConfig = Parameters<typeof onErrorRetry>[2]
8
+
9
+ const createConfig = (overrides: Partial<RetryConfig> = {}): RetryConfig => ({
10
+ errorRetryCount: 3,
11
+ errorRetryInterval: ERROR_RETRY_INTERVAL,
12
+ ...overrides,
13
+ })
14
+
15
+ // The client throws the object built by `baseRequest` in `request.ts`, which
16
+ // carries the HTTP status — not an Error instance.
17
+ const clientError = (status?: number) => ({
18
+ status,
19
+ message: 'upstream failure',
20
+ })
21
+
22
+ const runRetry = ({
23
+ error,
24
+ retryCount = 0,
25
+ config = createConfig(),
26
+ }: {
27
+ error: unknown
28
+ retryCount?: number
29
+ config?: RetryConfig
30
+ }) => {
31
+ const revalidate = vi.fn()
32
+
33
+ onErrorRetry(error, 'a-key', config, revalidate, {
34
+ retryCount,
35
+ dedupe: false,
36
+ })
37
+
38
+ vi.runAllTimers()
39
+
40
+ return revalidate
41
+ }
42
+
43
+ describe('useQuery retry policy', () => {
44
+ beforeEach(() => {
45
+ vi.useFakeTimers()
46
+ // Pins SWR's jitter so the backoff assertions are deterministic.
47
+ vi.spyOn(Math, 'random').mockReturnValue(0.5)
48
+ })
49
+
50
+ afterEach(() => {
51
+ // `restoreAllMocks` must run first: the `setTimeout` spy is installed while
52
+ // timers are faked, so restoring it after `useRealTimers` would put the
53
+ // faked timer back onto `globalThis`.
54
+ vi.restoreAllMocks()
55
+ vi.useRealTimers()
56
+ })
57
+
58
+ it('never retries an upstream rate limit (429)', () => {
59
+ expect(runRetry({ error: clientError(429) })).not.toHaveBeenCalled()
60
+ })
61
+
62
+ it('does not retry a 429 even on the first attempt of a fresh key', () => {
63
+ const revalidate = runRetry({ error: clientError(429), retryCount: 0 })
64
+
65
+ expect(revalidate).not.toHaveBeenCalled()
66
+ })
67
+
68
+ it.each([400, 401, 403, 404, 409, 422, 500, 502, 503])(
69
+ 'still retries status %i',
70
+ (status) => {
71
+ expect(runRetry({ error: clientError(status) })).toHaveBeenCalledTimes(1)
72
+ }
73
+ )
74
+
75
+ it('still retries an error carrying no status (e.g. network failure)', () => {
76
+ expect(runRetry({ error: clientError(undefined) })).toHaveBeenCalledTimes(1)
77
+ })
78
+
79
+ it('retries while at the errorRetryCount ceiling', () => {
80
+ expect(
81
+ runRetry({ error: clientError(500), retryCount: 3 })
82
+ ).toHaveBeenCalledTimes(1)
83
+ })
84
+
85
+ it('stops retrying once errorRetryCount is exceeded', () => {
86
+ expect(
87
+ runRetry({ error: clientError(500), retryCount: 4 })
88
+ ).not.toHaveBeenCalled()
89
+ })
90
+
91
+ it.each([
92
+ [0, 1 * ERROR_RETRY_INTERVAL],
93
+ [2, 4 * ERROR_RETRY_INTERVAL],
94
+ [3, 8 * ERROR_RETRY_INTERVAL],
95
+ ])(
96
+ 'mirrors SWR exponential backoff for retryCount %i',
97
+ (retryCount, expectedTimeout) => {
98
+ const setTimeoutSpy = vi.spyOn(globalThis, 'setTimeout')
99
+ const revalidate = vi.fn()
100
+
101
+ onErrorRetry(
102
+ clientError(500),
103
+ 'a-key',
104
+ createConfig({ errorRetryCount: 10 }),
105
+ revalidate,
106
+ { retryCount, dedupe: false }
107
+ )
108
+
109
+ expect(setTimeoutSpy).toHaveBeenCalledWith(
110
+ revalidate,
111
+ expectedTimeout,
112
+ expect.objectContaining({ retryCount })
113
+ )
114
+ }
115
+ )
116
+
117
+ it('caps the backoff exponent at 8, as SWR does', () => {
118
+ const setTimeoutSpy = vi.spyOn(globalThis, 'setTimeout')
119
+ const revalidate = vi.fn()
120
+
121
+ onErrorRetry(
122
+ clientError(500),
123
+ 'a-key',
124
+ createConfig({ errorRetryCount: 100 }),
125
+ revalidate,
126
+ { retryCount: 12, dedupe: false }
127
+ )
128
+
129
+ expect(setTimeoutSpy).toHaveBeenCalledWith(
130
+ revalidate,
131
+ 256 * ERROR_RETRY_INTERVAL,
132
+ expect.objectContaining({ retryCount: 12 })
133
+ )
134
+ })
135
+ })