@faststore/core 4.10.0 → 4.10.1-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.
- package/.turbo/turbo-generate.log +3 -3
- package/.turbo/turbo-test.log +146 -142
- package/CHANGELOG.md +10 -0
- package/package.json +6 -6
- package/src/server/content/service.ts +70 -21
- package/test/server/content/service.test.ts +241 -2
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> @faststore/core@4.10.
|
|
2
|
+
> @faststore/core@4.10.1-dev.0 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.10.
|
|
6
|
+
> @faststore/core@4.10.1-dev.0 gen-types /home/runner/work/faststore/faststore/packages/core
|
|
7
7
|
> node ../cli/bin/run generate-types .
|
|
8
8
|
|
|
9
9
|
[33m[STARTED][39m Parse Configuration
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
[32m[COMPLETED][39m Generate to @generated/
|
|
20
20
|
[32m[COMPLETED][39m Generate outputs
|
|
21
21
|
|
|
22
|
-
> @faststore/core@4.10.
|
|
22
|
+
> @faststore/core@4.10.1-dev.0 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
|
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @faststore/core@4.10.
|
|
2
|
+
> @faststore/core@4.10.1-dev.0 test /home/runner/work/faststore/faststore/packages/core
|
|
3
3
|
> vitest run
|
|
4
4
|
|
|
5
5
|
|
|
@@ -7,30 +7,33 @@
|
|
|
7
7
|
|
|
8
8
|
Not implemented: navigation to another Document
|
|
9
9
|
Not implemented: navigation to another Document
|
|
10
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/ui/useScrollRestoration.browser.test.ts [2m([22m[2m43 tests[22m[2m)[22m[33m
|
|
10
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/ui/useScrollRestoration.browser.test.ts [2m([22m[2m43 tests[22m[2m)[22m[33m 1284[2mms[22m[39m
|
|
11
11
|
Browserslist: browsers data (caniuse-lite) is 8 months old. Please run:
|
|
12
12
|
npx update-browserslist-db@latest
|
|
13
13
|
Why you should do it regularly: https://github.com/browserslist/update-db#readme
|
|
14
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/cards/MyAccountListCards.browser.test.tsx [2m([22m[2m16 tests[22m[2m)[22m[33m
|
|
15
|
-
[33m[2m✓[22m[39m shows the tab bar and renders Personal cards by default [33m
|
|
16
|
-
[33m[2m✓[22m[39m paginates when there are more than 25 cards [33m
|
|
17
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/ContractSwitcher.browser.test.tsx [2m([22m[2m22 tests[22m[2m)[22m[33m
|
|
18
|
-
[33m[2m✓[22m[39m shows an error state when the list fails to load [33m
|
|
19
|
-
[33m[2m✓[22m[39m requires selecting a contract before Confirm is enabled, then switches (REQ-03) [33m
|
|
20
|
-
[33m[2m✓[22m[39m keeps Confirm disabled until a different contract is selected [33m
|
|
21
|
-
[33m[2m✓[22m[39m keeps Confirm disabled when switching is unavailable [33m
|
|
22
|
-
[33m[2m✓[22m[39m keeps Confirm disabled when the selected contract is filtered out [33m
|
|
23
|
-
[33m[2m✓[22m[39m honors CMS-provided labels for the header, current session, search, footer, and available count [33m
|
|
24
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/BuyingPolicyAlert.browser.test.tsx [2m([22m[2m13 tests[22m[2m)[22m[33m
|
|
25
|
-
[33m[2m✓[22m[39m opens the reject confirmation modal with the default English copy [33m
|
|
26
|
-
[33m[2m✓[22m[39m opens the reject confirmation modal with CMS-provided labels [33m
|
|
27
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/ui/RichText/RichText.browser.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[
|
|
28
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationDrawer.browser.test.tsx [2m([22m[2m10 tests[22m[2m)[22m[33m
|
|
29
|
-
[33m[2m✓[22m[39m renders the menu view with contract details and manage footer [33m
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
33
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
14
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/cards/MyAccountListCards.browser.test.tsx [2m([22m[2m16 tests[22m[2m)[22m[33m 2990[2mms[22m[39m
|
|
15
|
+
[33m[2m✓[22m[39m shows the tab bar and renders Personal cards by default [33m 1029[2mms[22m[39m
|
|
16
|
+
[33m[2m✓[22m[39m paginates when there are more than 25 cards [33m 575[2mms[22m[39m
|
|
17
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/ContractSwitcher.browser.test.tsx [2m([22m[2m22 tests[22m[2m)[22m[33m 4422[2mms[22m[39m
|
|
18
|
+
[33m[2m✓[22m[39m shows an error state when the list fails to load [33m 728[2mms[22m[39m
|
|
19
|
+
[33m[2m✓[22m[39m requires selecting a contract before Confirm is enabled, then switches (REQ-03) [33m 541[2mms[22m[39m
|
|
20
|
+
[33m[2m✓[22m[39m keeps Confirm disabled until a different contract is selected [33m 393[2mms[22m[39m
|
|
21
|
+
[33m[2m✓[22m[39m keeps Confirm disabled when switching is unavailable [33m 372[2mms[22m[39m
|
|
22
|
+
[33m[2m✓[22m[39m keeps Confirm disabled when the selected contract is filtered out [33m 441[2mms[22m[39m
|
|
23
|
+
[33m[2m✓[22m[39m honors CMS-provided labels for the header, current session, search, footer, and available count [33m 431[2mms[22m[39m
|
|
24
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/BuyingPolicyAlert.browser.test.tsx [2m([22m[2m13 tests[22m[2m)[22m[33m 3066[2mms[22m[39m
|
|
25
|
+
[33m[2m✓[22m[39m opens the reject confirmation modal with the default English copy [33m 1448[2mms[22m[39m
|
|
26
|
+
[33m[2m✓[22m[39m opens the reject confirmation modal with CMS-provided labels [33m 435[2mms[22m[39m
|
|
27
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/ui/RichText/RichText.browser.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[33m 397[2mms[22m[39m
|
|
28
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationDrawer.browser.test.tsx [2m([22m[2m10 tests[22m[2m)[22m[33m 2039[2mms[22m[39m
|
|
29
|
+
[33m[2m✓[22m[39m renders the menu view with contract details and manage footer [33m 1045[2mms[22m[39m
|
|
30
|
+
[33m[2m✓[22m[39m opens the contract switcher and returns to the menu on back [33m 410[2mms[22m[39m
|
|
31
|
+
[33m[2m✓[22m[39m resets to the menu when the drawer closes [33m 323[2mms[22m[39m
|
|
32
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/CartRecommendationShelf/CartRecommendationShelf.browser.test.tsx [2m([22m[2m13 tests[22m[2m)[22m[32m 240[2mms[22m[39m
|
|
33
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/reconcileSessionLocale.browser.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 11[2mms[22m[39m
|
|
34
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/localization/useBindingSelector.browser.test.tsx [2m([22m[2m9 tests[22m[2m)[22m[32m 67[2mms[22m[39m
|
|
35
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/ui/ProductGallery/GalleryPageHeightLock.browser.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[32m 99[2mms[22m[39m
|
|
36
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/recommendations/useRecommendationShelf.browser.test.tsx [2m([22m[2m12 tests[22m[2m)[22m[32m 140[2mms[22m[39m
|
|
34
37
|
[90mstderr[2m | test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx
|
|
35
38
|
[22m[39mError in optimistic validation: TypeError: Failed to parse URL from /api/graphql?operationName=ValidateCartMutation&operationHash=3c71b0d3fc2bade14df68abfa271858beb361b12
|
|
36
39
|
[90m at node:internal/deps/undici/undici:16416:13[39m
|
|
@@ -60,12 +63,10 @@ Browserslist: browsers data (caniuse-lite) is 8 months old. Please run:
|
|
|
60
63
|
[90mstderr[2m | test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx[2m > [22m[2mRecommendationShelf[2m > [22m[2mrenders nothing when there is an error
|
|
61
64
|
[22m[39mError fetching recommendations [90mundefined[39m boom for campaign vrn:recommendations:acc:rec-top-items-v2:campaign-1
|
|
62
65
|
|
|
63
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
64
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
65
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
66
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
67
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountOrderDetails.browser.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m 62[2mms[22m[39m
|
|
68
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/navigation/Navbar.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 40[2mms[22m[39m
|
|
66
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[32m 191[2mms[22m[39m
|
|
67
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/CartSidebar/CartSidebar.browser.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[32m 75[2mms[22m[39m
|
|
68
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/getInitialSession.browser.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 13[2mms[22m[39m
|
|
69
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountOrderDetails.browser.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m 77[2mms[22m[39m
|
|
69
70
|
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2mposts the password and redirects to the requested return path
|
|
70
71
|
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
71
72
|
|
|
@@ -151,7 +152,7 @@ act(() => {
|
|
|
151
152
|
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
|
|
152
153
|
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
153
154
|
|
|
154
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/
|
|
155
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/navigation/Navbar.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 93[2mms[22m[39m
|
|
155
156
|
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2muses the fallback invalid-password message when API omits an error
|
|
156
157
|
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
157
158
|
|
|
@@ -296,8 +297,9 @@ act(() => {
|
|
|
296
297
|
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
|
|
297
298
|
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
298
299
|
|
|
299
|
-
[32m✓[39m [30m[46m browser [49m[39m test/pages/password-protection.browser.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[33m
|
|
300
|
-
|
|
300
|
+
[32m✓[39m [30m[46m browser [49m[39m test/pages/password-protection.browser.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[33m 978[2mms[22m[39m
|
|
301
|
+
[33m[2m✓[22m[39m renders the password protection form [33m 528[2mms[22m[39m
|
|
302
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationDrawerFooter.browser.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[33m 560[2mms[22m[39m
|
|
301
303
|
[90mstderr[2m | test/components/cms/RenderSections.browser.test.tsx
|
|
302
304
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
303
305
|
at waitForSessionValidated [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/waitForSessionValidated.ts:16:32[90m)[39m
|
|
@@ -306,8 +308,9 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
306
308
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:357:23)
|
|
307
309
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
308
310
|
|
|
309
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
310
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/
|
|
311
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/useSwitchContract.browser.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 71[2mms[22m[39m
|
|
312
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/navigation/NavbarSlider.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 48[2mms[22m[39m
|
|
313
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/cms/RenderSections.browser.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[32m 99[2mms[22m[39m
|
|
311
314
|
[90mstderr[2m | test/sdk/localization/store-url.browser.test.ts
|
|
312
315
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
313
316
|
at waitForSessionValidated [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/waitForSessionValidated.ts:16:32[90m)[39m
|
|
@@ -317,14 +320,14 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
317
320
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
318
321
|
|
|
319
322
|
[32m✓[39m [30m[46m browser [49m[39m test/sdk/localization/store-url.browser.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
320
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
321
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
322
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/templates/SearchPage/SearchWrapper.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
323
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/recommendations/useRecommendationShelf.sessionFallback.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
324
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountListQuotes.browser.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m
|
|
325
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/navigation/NavbarAccountArea.browser.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m
|
|
326
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/CartRecommendationShelf/CartRecommendationProductCard.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
327
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/changeContractToken.browser.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m
|
|
323
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/useAvailableContracts.browser.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 32[2mms[22m[39m
|
|
324
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/Menu.browser.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[33m 385[2mms[22m[39m
|
|
325
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/templates/SearchPage/SearchWrapper.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 29[2mms[22m[39m
|
|
326
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/recommendations/useRecommendationShelf.sessionFallback.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 90[2mms[22m[39m
|
|
327
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountListQuotes.browser.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m 149[2mms[22m[39m
|
|
328
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/navigation/NavbarAccountArea.browser.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m 67[2mms[22m[39m
|
|
329
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/CartRecommendationShelf/CartRecommendationProductCard.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 66[2mms[22m[39m
|
|
330
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/changeContractToken.browser.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 22[2mms[22m[39m
|
|
328
331
|
[90mstderr[2m | test/components/account/doLogout.browser.test.ts
|
|
329
332
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
330
333
|
at waitForSessionValidated [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/waitForSessionValidated.ts:16:32[90m)[39m
|
|
@@ -333,9 +336,9 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
333
336
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:357:23)
|
|
334
337
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
335
338
|
|
|
336
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/doLogout.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m
|
|
337
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/ui/LocalizationButton.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
338
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationDrawerHeader.browser.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[33m
|
|
339
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/doLogout.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 16[2mms[22m[39m
|
|
340
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/ui/LocalizationButton.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 49[2mms[22m[39m
|
|
341
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationDrawerHeader.browser.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[33m 376[2mms[22m[39m
|
|
339
342
|
[90mstderr[2m | test/sdk/account/clearPersistedSessionState.browser.test.ts
|
|
340
343
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
341
344
|
at waitForSessionValidated [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/waitForSessionValidated.ts:16:32[90m)[39m
|
|
@@ -344,15 +347,14 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
344
347
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:357:23)
|
|
345
348
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
346
349
|
|
|
347
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/clearPersistedSessionState.browser.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m
|
|
348
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountOrderDelivery.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
349
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/DeliveryOptionAccordion.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
350
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountOrderStatus.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
350
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/clearPersistedSessionState.browser.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 21[2mms[22m[39m
|
|
351
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountOrderDelivery.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 100[2mms[22m[39m
|
|
352
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/DeliveryOptionAccordion.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 102[2mms[22m[39m
|
|
353
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountOrderStatus.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 112[2mms[22m[39m
|
|
351
354
|
[32m✓[39m [30m[46m browser [49m[39m test/components/region/useRegion.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 26[2mms[22m[39m
|
|
352
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountListCards.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
353
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountOrdersList.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
354
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/SummaryCard.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
355
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationSignInButton.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 262[2mms[22m[39m
|
|
355
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountListCards.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 90[2mms[22m[39m
|
|
356
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountOrdersList.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 22[2mms[22m[39m
|
|
357
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/SummaryCard.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 101[2mms[22m[39m
|
|
356
358
|
[90mstderr[2m | test/sdk/session/sessionStore.browser.test.ts
|
|
357
359
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
358
360
|
at waitForSessionValidated [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/waitForSessionValidated.ts:16:32[90m)[39m
|
|
@@ -361,8 +363,9 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
361
363
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:357:23)
|
|
362
364
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
363
365
|
|
|
364
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/sessionStore.browser.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
365
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/
|
|
366
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/sessionStore.browser.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 10[2mms[22m[39m
|
|
367
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationSignInButton.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 252[2mms[22m[39m
|
|
368
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/DeliveryOptionAccordionDeliveryInfo.browser.test.tsx [2m([22m[2m1 test[22m[2m)[22m[32m 48[2mms[22m[39m
|
|
366
369
|
[90mstderr[2m | test/sdk/session/validateSession.browser.test.ts
|
|
367
370
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
368
371
|
at waitForSessionValidated [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/waitForSessionValidated.ts:16:32[90m)[39m
|
|
@@ -371,15 +374,13 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
371
374
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:357:23)
|
|
372
375
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
373
376
|
|
|
374
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/validateSession.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m
|
|
375
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/StatusCard.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
377
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/validateSession.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
378
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/StatusCard.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 115[2mms[22m[39m
|
|
376
379
|
[32m✓[39m [30m[46m browser [49m[39m test/utils/isLocalHost.browser.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
377
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/reconcileSessionLocale.disabled.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m
|
|
378
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/DeliveryCard.browser.test.tsx [2m([22m[2m1 test[22m[2m)[22m[32m
|
|
379
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/
|
|
380
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/
|
|
381
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/localization/bindingPaths.test.ts [2m([22m[2m71 tests[22m[2m)[22m[32m 31[2mms[22m[39m
|
|
382
|
-
[32m✓[39m [30m[43m node [49m[39m test/server/password-protection-service.test.ts [2m([22m[2m22 tests[22m[2m)[22m[32m 43[2mms[22m[39m
|
|
380
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/reconcileSessionLocale.disabled.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
381
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/DeliveryCard.browser.test.tsx [2m([22m[2m1 test[22m[2m)[22m[32m 64[2mms[22m[39m
|
|
382
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/DeliveryOptionAccordionProducts.browser.test.tsx [2m([22m[2m1 test[22m[2m)[22m[32m 71[2mms[22m[39m
|
|
383
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/skeletons/ProductGridSkeleton.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 30[2mms[22m[39m
|
|
383
384
|
[90mstderr[2m | test/sdk/account/refreshToken.browser.test.ts
|
|
384
385
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
385
386
|
at waitForSessionValidated [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/waitForSessionValidated.ts:16:32[90m)[39m
|
|
@@ -389,10 +390,10 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
389
390
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
390
391
|
|
|
391
392
|
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/refreshToken.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
392
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
393
|
-
[32m✓[39m [30m[
|
|
394
|
-
[32m✓[39m [30m[
|
|
395
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
393
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/localization/bindingPaths.test.ts [2m([22m[2m71 tests[22m[2m)[22m[32m 32[2mms[22m[39m
|
|
394
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/password-protection-service.test.ts [2m([22m[2m22 tests[22m[2m)[22m[32m 39[2mms[22m[39m
|
|
395
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/FilterFacetPendingApproval.browser.test.tsx [2m([22m[2m1 test[22m[2m)[22m[32m 229[2mms[22m[39m
|
|
396
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/switch-contract.test.ts [2m([22m[2m25 tests[22m[2m)[22m[32m 93[2mms[22m[39m
|
|
396
397
|
[90mstderr[2m | test/sdk/deliveryPromise/provider.effect.test.tsx[2m > [22m[2mDeliveryPromiseProvider pickup fetch[2m > [22m[2mclears the loading flag after a failed request and retries on the next update
|
|
397
398
|
[22m[39mFailed to fetch pickup points: Error: network
|
|
398
399
|
at [90m/home/runner/work/faststore/faststore/packages/core/[39mtest/sdk/deliveryPromise/provider.effect.test.tsx:250:30
|
|
@@ -419,12 +420,16 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
419
420
|
at trace (file:///home/runner/work/faststore/faststore/node_modules/[4m.pnpm[24m/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/[4mvitest[24m/dist/chunks/test.B8ej_ZHS.js:239:21)
|
|
420
421
|
at runTest (file:///home/runner/work/faststore/faststore/node_modules/[4m.pnpm[24m/@vitest+runner@4.0.18/node_modules/[4m@vitest/runner[24m/dist/index.js:1653:12)
|
|
421
422
|
|
|
422
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/deliveryPromise/provider.effect.test.tsx [2m([22m[2m9 tests[22m[2m)[22m[32m
|
|
423
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
424
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
423
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/deliveryPromise/provider.effect.test.tsx [2m([22m[2m9 tests[22m[2m)[22m[32m 84[2mms[22m[39m
|
|
424
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/content/service.test.ts [2m([22m[2m15 tests[22m[2m)[22m[32m 27[2mms[22m[39m
|
|
425
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/match-url.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 11[2mms[22m[39m
|
|
426
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/localization/useBindingSelector.test.tsx [2m([22m[2m22 tests[22m[2m)[22m[32m 11[2mms[22m[39m
|
|
427
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/unlock.test.ts [2m([22m[2m15 tests[22m[2m)[22m[32m 175[2mms[22m[39m
|
|
428
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/session/syncSalesChannelFromOrderForm.test.ts [2m([22m[2m14 tests[22m[2m)[22m[32m 14[2mms[22m[39m
|
|
425
429
|
[90mstderr[2m | test/components/search/SearchInputComponent.test.tsx
|
|
426
430
|
[22m[39mWarning: forwardRef render functions accept exactly two parameters: props and ref. Did you forget to use the ref parameter?
|
|
427
431
|
|
|
432
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/localization/bindingSelector.test.ts [2m([22m[2m18 tests[22m[2m)[22m[32m 9[2mms[22m[39m
|
|
428
433
|
[90mstderr[2m | test/components/search/SearchInputComponent.test.tsx[2m > [22m[2mSearchInput (OES integration)[2m > [22m[2mrenders without crashing
|
|
429
434
|
[22m[39mWarning: React does not recognize the `visibleDropdown` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `visibledropdown` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
|
|
430
435
|
at div
|
|
@@ -485,13 +490,12 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
|
|
|
485
490
|
at Suspense
|
|
486
491
|
at Wrapper (/home/runner/work/faststore/faststore/packages/core/test/components/search/SearchInputComponent.test.tsx:106:20)
|
|
487
492
|
|
|
488
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
489
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/
|
|
490
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
491
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountListQuotes.test.tsx [2m([22m[2m11 tests[22m[2m)[22m[33m
|
|
493
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/search/SearchInputComponent.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[32m 93[2mms[22m[39m
|
|
494
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountListQuotesTable.test.tsx [2m([22m[2m15 tests[22m[2m)[22m[33m 472[2mms[22m[39m
|
|
495
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/search/useSearchHistory.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 50[2mms[22m[39m
|
|
496
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountListQuotes.test.tsx [2m([22m[2m11 tests[22m[2m)[22m[33m 840[2mms[22m[39m
|
|
492
497
|
[33m[2m✓[22m[39m navigates with the search term on blur [33m 361[2mms[22m[39m
|
|
493
|
-
[33m[2m✓[22m[39m navigates without a label param when the search is cleared [33m
|
|
494
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/search/useSearchHistory.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 67[2mms[22m[39m
|
|
498
|
+
[33m[2m✓[22m[39m navigates without a label param when the search is cleared [33m 360[2mms[22m[39m
|
|
495
499
|
[90mstderr[2m | test/pages/pvt/account/cards/index.test.ts[2m > [22m[2mCards page getServerSideProps[2m > [22m[2mredirects to /pvt/account/403 when the query fails with 401/403
|
|
496
500
|
[22m[39m{ extensions: { status: [33m401[39m } }
|
|
497
501
|
|
|
@@ -499,10 +503,10 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
|
|
|
499
503
|
[22m[39m{ extensions: { status: [33m502[39m } }
|
|
500
504
|
|
|
501
505
|
[32m✓[39m [30m[43m node [49m[39m test/pages/pvt/account/cards/index.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 12[2mms[22m[39m
|
|
502
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/quoteFilters.test.ts [2m([22m[2m26 tests[22m[2m)[22m[32m
|
|
503
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/productJsonLd.test.ts [2m([22m[2m36 tests[22m[2m)[22m[32m
|
|
504
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/cookieCacheBusting.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m
|
|
505
|
-
[32m✓[39m [30m[43m node [49m[39m test/experimental/myAccountCmsServerSideProps.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m
|
|
506
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/quoteFilters.test.ts [2m([22m[2m26 tests[22m[2m)[22m[32m 53[2mms[22m[39m
|
|
507
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/productJsonLd.test.ts [2m([22m[2m36 tests[22m[2m)[22m[32m 12[2mms[22m[39m
|
|
508
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/cookieCacheBusting.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 15[2mms[22m[39m
|
|
509
|
+
[32m✓[39m [30m[43m node [49m[39m test/experimental/myAccountCmsServerSideProps.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 10[2mms[22m[39m
|
|
506
510
|
[90mstderr[2m | test/pages/api/graphql.test.ts[2m > [22m[2m/api/graphql error status propagation[2m > [22m[2mpropagates the upstream 400 from a wrapped BadRequestError instead of 500
|
|
507
511
|
[22m[39mGraphql execution returned with error: [
|
|
508
512
|
{
|
|
@@ -612,78 +616,78 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
|
|
|
612
616
|
at trace (file:///home/runner/work/faststore/faststore/node_modules/[4m.pnpm[24m/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/[4mvitest[24m/dist/chunks/test.B8ej_ZHS.js:239:21)
|
|
613
617
|
at runTest (file:///home/runner/work/faststore/faststore/node_modules/[4m.pnpm[24m/@vitest+runner@4.0.18/node_modules/[4m@vitest/runner[24m/dist/index.js:1653:12)
|
|
614
618
|
|
|
615
|
-
[32m✓[39m [30m[43m node [49m[39m test/pages/api/graphql.test.ts [2m([22m[2m19 tests[22m[2m)[22m[32m
|
|
616
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/clearCookies.test.ts [2m([22m[2m20 tests[22m[2m)[22m[32m
|
|
617
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/multipleTemplates.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
619
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/graphql.test.ts [2m([22m[2m19 tests[22m[2m)[22m[32m 44[2mms[22m[39m
|
|
620
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/clearCookies.test.ts [2m([22m[2m20 tests[22m[2m)[22m[32m 29[2mms[22m[39m
|
|
621
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/multipleTemplates.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
618
622
|
[90mstderr[2m | test/sdk/account/useSetPassword.test.ts[2m > [22m[2museSetPassword[2m > [22m[2mmaps wrongcredentials error responses to the existing message
|
|
619
623
|
[22m[39mSet password request failed: Bad Request
|
|
620
624
|
|
|
621
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/useSetPassword.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m
|
|
625
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/useSetPassword.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 50[2mms[22m[39m
|
|
622
626
|
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntryOperation.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 49[2mms[22m[39m
|
|
623
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/localization/localizeRedirectDestination.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m
|
|
624
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuotesFilterSlider.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
625
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuotesStatusSelector.test.tsx [2m([22m[2m14 tests[22m[2m)[22m[32m
|
|
626
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
627
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
628
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuotesSelectedTags.test.tsx [2m([22m[2m10 tests[22m[2m)[22m[32m
|
|
629
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/redirects/index.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m
|
|
630
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntryUpload.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
631
|
-
[32m✓[39m [30m[43m node [49m[39m test/proxy.localization.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m
|
|
632
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntry.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
633
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/account/orders/getDeliveryOptionLabel.test.ts [2m([22m[2m21 tests[22m[2m)[22m[32m
|
|
634
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/graphql/retryPolicy.test.ts [2m([22m[2m18 tests[22m[2m)[22m[32m
|
|
635
|
-
[32m✓[39m [30m[43m node [49m[39m test/server/cms/myAccountDefaultSections.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m
|
|
636
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/productJsonLdRendering.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[32m
|
|
637
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/trustedForwardedHost.test.ts [2m([22m[2m27 tests[22m[2m)[22m[32m
|
|
638
|
-
[32m✓[39m [30m[43m node [49m[39m test/server/index.test.ts [2m([22m[2m7 tests[22m[2m)[22m[33m
|
|
639
|
-
[33m[2m✓[22m[39m should return a valid merged GraphQL schema [33m
|
|
640
|
-
[33m[2m✓[22m[39m should
|
|
641
|
-
|
|
642
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/analytics/useStartRecommendationSession.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m
|
|
643
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
644
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
645
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/
|
|
627
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/localization/localizeRedirectDestination.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m 9[2mms[22m[39m
|
|
628
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuotesFilterSlider.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[32m 209[2mms[22m[39m
|
|
629
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuotesStatusSelector.test.tsx [2m([22m[2m14 tests[22m[2m)[22m[32m 198[2mms[22m[39m
|
|
630
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/localization/hreflang.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 8[2mms[22m[39m
|
|
631
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/getMyAccountRoutes.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
632
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuotesSelectedTags.test.tsx [2m([22m[2m10 tests[22m[2m)[22m[32m 127[2mms[22m[39m
|
|
633
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/redirects/index.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 50[2mms[22m[39m
|
|
634
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntryUpload.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 51[2mms[22m[39m
|
|
635
|
+
[32m✓[39m [30m[43m node [49m[39m test/proxy.localization.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 60[2mms[22m[39m
|
|
636
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntry.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 52[2mms[22m[39m
|
|
637
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/account/orders/getDeliveryOptionLabel.test.ts [2m([22m[2m21 tests[22m[2m)[22m[32m 8[2mms[22m[39m
|
|
638
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/graphql/retryPolicy.test.ts [2m([22m[2m18 tests[22m[2m)[22m[32m 18[2mms[22m[39m
|
|
639
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/cms/myAccountDefaultSections.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 8[2mms[22m[39m
|
|
640
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/productJsonLdRendering.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[32m 16[2mms[22m[39m
|
|
641
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/trustedForwardedHost.test.ts [2m([22m[2m27 tests[22m[2m)[22m[32m 11[2mms[22m[39m
|
|
642
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/index.test.ts [2m([22m[2m7 tests[22m[2m)[22m[33m 1039[2mms[22m[39m
|
|
643
|
+
[33m[2m✓[22m[39m should return a valid merged GraphQL schema [33m 314[2mms[22m[39m
|
|
644
|
+
[33m[2m✓[22m[39m should exist with its plugins [33m 317[2mms[22m[39m
|
|
645
|
+
[33m[2m✓[22m[39m should handle options and execute [33m 393[2mms[22m[39m
|
|
646
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/analytics/useStartRecommendationSession.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 56[2mms[22m[39m
|
|
647
|
+
[32m✓[39m [30m[43m node [49m[39m test/proxy.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 22[2mms[22m[39m
|
|
648
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/webops-api.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 18[2mms[22m[39m
|
|
649
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderFormItems.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 88[2mms[22m[39m
|
|
646
650
|
[32m✓[39m [30m[43m node [49m[39m test/components/account/orders/StatusCard.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 32[2mms[22m[39m
|
|
647
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/
|
|
648
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/
|
|
649
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/
|
|
650
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
651
|
-
[32m✓[39m [30m[43m node [49m[39m test/server/cms/global.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
652
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/deliveryPromise/provider.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m
|
|
653
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/auth/useAuth.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m
|
|
654
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/getRequestHostname.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m
|
|
655
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/account/Layout.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[32m
|
|
656
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
657
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
658
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/search/SearchInput.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m
|
|
659
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/validateSessionRefreshToken.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m
|
|
660
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/recommendations/vrn.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m
|
|
661
|
-
[32m✓[39m [30m[43m node [49m[39m test/server/cms/index.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
662
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
663
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
664
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/
|
|
665
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
666
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
667
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/unlockResponse.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m
|
|
651
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/localization/store-url.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
652
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/deliveryPromise/queries.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
|
|
653
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/cart/waitForSessionValidated.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 13[2mms[22m[39m
|
|
654
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/refreshToken.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 10[2mms[22m[39m
|
|
655
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/cms/global.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
656
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/deliveryPromise/provider.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
657
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/auth/useAuth.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 37[2mms[22m[39m
|
|
658
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/getRequestHostname.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
659
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/account/Layout.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[32m 85[2mms[22m[39m
|
|
660
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/rootSpan.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 51[2mms[22m[39m
|
|
661
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/preview.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 11[2mms[22m[39m
|
|
662
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/search/SearchInput.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 8[2mms[22m[39m
|
|
663
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/validateSessionRefreshToken.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
664
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/recommendations/vrn.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
665
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/cms/index.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
666
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/region/useRegion.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 27[2mms[22m[39m
|
|
667
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/retry.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 16[2mms[22m[39m
|
|
668
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/getB2BSessionClaims.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
669
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/userOrderStatus.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
670
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/recommendations/useRecommendationUserId.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 195[2mms[22m[39m
|
|
671
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/unlockResponse.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
668
672
|
[32m✓[39m [30m[43m node [49m[39m test/sdk/recommendations/useRecommendations.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
669
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/account/OrganizationDrawerBody.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
670
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/deliveryPromise/reducer.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
671
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
672
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
673
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/account/orders/getOrderTotalLabel.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
673
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/account/OrganizationDrawerBody.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 57[2mms[22m[39m
|
|
674
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/deliveryPromise/reducer.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
675
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuoteStatusBadge.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m 35[2mms[22m[39m
|
|
676
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/isLocalHost.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
674
677
|
[32m✓[39m [30m[43m node [49m[39m test/sdk/session/toSessionInput.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
678
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/account/orders/getOrderTotalLabel.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
679
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/account/orders/listOrdersLabels.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
675
680
|
[32m✓[39m [30m[43m node [49m[39m test/utils/getCookie.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
676
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/
|
|
677
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
678
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/filterChannel.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
679
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/session/isSignInAreaResolved.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
681
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/auth/ProfileChallenge.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 39[2mms[22m[39m
|
|
682
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/session/isSignInAreaResolved.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 3[2mms[22m[39m
|
|
683
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/filterChannel.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
680
684
|
[32m✓[39m [30m[43m node [49m[39m test/sdk/analytics/utils.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
681
|
-
[32m✓[39m [30m[43m node [49m[39m test/instrumentation.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
682
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
683
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
685
|
+
[32m✓[39m [30m[43m node [49m[39m test/instrumentation.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
686
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/account/orders/orderDetailsLabels.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
687
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/clearPersistedSessionState.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 12[2mms[22m[39m
|
|
684
688
|
|
|
685
689
|
[2m Test Files [22m [1m[32m135 passed[39m[22m[90m (135)[39m
|
|
686
|
-
[2m Tests [22m [1m[
|
|
687
|
-
[2m Start at [22m
|
|
688
|
-
[2m Duration [22m
|
|
690
|
+
[2m Tests [22m [1m[32m1076 passed[39m[22m[90m (1076)[39m
|
|
691
|
+
[2m Start at [22m 16:44:28
|
|
692
|
+
[2m Duration [22m 67.24s[2m (transform 18.40s, setup 0ms, import 60.45s, tests 24.70s, environment 81.30s)[22m
|
|
689
693
|
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
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.10.1-dev.1](https://github.com/vtex/faststore/compare/v4.10.1-dev.0...v4.10.1-dev.1) (2026-10-21)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **core:** cache Content Platform template list across page generations ([#3526](https://github.com/vtex/faststore/issues/3526)) ([b03ed33](https://github.com/vtex/faststore/commit/b03ed332bd8c4ea5ef4bb834b8590728946852e5)), closes [#3384](https://github.com/vtex/faststore/issues/3384) [#3384](https://github.com/vtex/faststore/issues/3384)
|
|
11
|
+
|
|
12
|
+
## [4.10.1-dev.0](https://github.com/vtex/faststore/compare/v4.10.0...v4.10.1-dev.0) (2026-10-15)
|
|
13
|
+
|
|
14
|
+
**Note:** Version bump only for package @faststore/core
|
|
15
|
+
|
|
6
16
|
# [4.10.0](https://github.com/vtex/faststore/compare/v4.10.0-dev.1...v4.10.0) (2026-10-15)
|
|
7
17
|
|
|
8
18
|
**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.10.
|
|
3
|
+
"version": "4.10.1-dev.1",
|
|
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.10.
|
|
75
|
-
"@faststore/
|
|
76
|
-
"@faststore/
|
|
77
|
-
"@faststore/sdk": "4.10.
|
|
78
|
-
"@faststore/ui": "4.10.
|
|
74
|
+
"@faststore/api": "4.10.1-dev.1",
|
|
75
|
+
"@faststore/lighthouse": "4.10.1-dev.1",
|
|
76
|
+
"@faststore/diagnostics": "4.10.1-dev.1",
|
|
77
|
+
"@faststore/sdk": "4.10.1-dev.1",
|
|
78
|
+
"@faststore/ui": "4.10.1-dev.1"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
81
|
"@cypress/code-coverage": "^3.12.1",
|
|
@@ -19,15 +19,27 @@ import { isBranchPreview, isContentPlatformSource } from './utils'
|
|
|
19
19
|
|
|
20
20
|
type ContentResult = ContentData | (ContentEntry & PageContentType)
|
|
21
21
|
|
|
22
|
+
type ContentListCacheEntry = {
|
|
23
|
+
expiresAt: number
|
|
24
|
+
promise: Promise<{ data: ContentResult[] }>
|
|
25
|
+
}
|
|
26
|
+
|
|
22
27
|
const OPTIONAL_CONTENT_TYPES = [
|
|
23
28
|
'globalHeaderSections',
|
|
24
29
|
'globalFooterSections',
|
|
25
30
|
] as const
|
|
31
|
+
|
|
32
|
+
// Bounds how stale the template list can get in long-lived processes (ISR);
|
|
33
|
+
// a CMS publish already triggers a new build.
|
|
34
|
+
const CONTENT_LIST_CACHE_TTL_MS = 5 * 60 * 1000
|
|
35
|
+
|
|
26
36
|
export class ContentService {
|
|
27
37
|
private readonly clientCP = new ClientCP({
|
|
28
38
|
tenant: config.api.storeId,
|
|
29
39
|
})
|
|
30
40
|
|
|
41
|
+
private readonly contentListCache = new Map<string, ContentListCacheEntry>()
|
|
42
|
+
|
|
31
43
|
async getSingleContent<T extends ContentData>(
|
|
32
44
|
params: ContentParams
|
|
33
45
|
): Promise<T> {
|
|
@@ -46,29 +58,12 @@ export class ContentService {
|
|
|
46
58
|
|
|
47
59
|
if (isContentPlatformSource()) {
|
|
48
60
|
const serviceParams = this.convertOptionsToParams(options)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
let scroll: string | undefined
|
|
53
|
-
let pages = 0
|
|
54
|
-
|
|
55
|
-
do {
|
|
56
|
-
const result = await this.clientCP.listEntries(serviceParams, scroll)
|
|
57
|
-
allEntries.push(...result.entries)
|
|
58
|
-
const next = result.scroll ?? undefined
|
|
59
|
-
if (next && next === scroll) break
|
|
60
|
-
scroll = next
|
|
61
|
-
} while (scroll && ++pages < MAX_PAGES)
|
|
62
|
-
|
|
63
|
-
if (pages >= MAX_PAGES) {
|
|
64
|
-
console.warn('listEntries pagination hit MAX_PAGES cap', serviceParams)
|
|
61
|
+
|
|
62
|
+
if (options.isPreview) {
|
|
63
|
+
return this.listAndFillEntries(serviceParams, true)
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
return this.
|
|
68
|
-
allEntries,
|
|
69
|
-
serviceParams,
|
|
70
|
-
options.isPreview
|
|
71
|
-
)
|
|
66
|
+
return this.getCachedContentList(serviceParams)
|
|
72
67
|
}
|
|
73
68
|
return getCMSPage(options.cmsOptions)
|
|
74
69
|
}
|
|
@@ -136,6 +131,60 @@ export class ContentService {
|
|
|
136
131
|
}
|
|
137
132
|
}
|
|
138
133
|
|
|
134
|
+
private getCachedContentList(
|
|
135
|
+
serviceParams: EntryPathParams
|
|
136
|
+
): Promise<{ data: ContentResult[] }> {
|
|
137
|
+
// listEntries only depends on these fields; the page slug must stay out of the key.
|
|
138
|
+
const { accountName, storeId, contentType, locale } = serviceParams
|
|
139
|
+
const key = JSON.stringify([accountName, storeId, contentType, locale])
|
|
140
|
+
|
|
141
|
+
const cached = this.contentListCache.get(key)
|
|
142
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
143
|
+
return cached.promise
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const promise = this.listAndFillEntries(serviceParams, false).catch(
|
|
147
|
+
(err: unknown) => {
|
|
148
|
+
if (this.contentListCache.get(key)?.promise === promise) {
|
|
149
|
+
this.contentListCache.delete(key)
|
|
150
|
+
}
|
|
151
|
+
throw err
|
|
152
|
+
}
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
this.contentListCache.set(key, {
|
|
156
|
+
expiresAt: Date.now() + CONTENT_LIST_CACHE_TTL_MS,
|
|
157
|
+
promise,
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
return promise
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private async listAndFillEntries(
|
|
164
|
+
serviceParams: EntryPathParams,
|
|
165
|
+
isPreview: boolean
|
|
166
|
+
): Promise<{ data: (ContentEntry & PageContentType)[] }> {
|
|
167
|
+
// TODO: This should be temporary until the cp data-plane have a search engine.
|
|
168
|
+
const MAX_PAGES = 25
|
|
169
|
+
const allEntries: ContentEntry[] = []
|
|
170
|
+
let scroll: string | undefined
|
|
171
|
+
let pages = 0
|
|
172
|
+
|
|
173
|
+
do {
|
|
174
|
+
const result = await this.clientCP.listEntries(serviceParams, scroll)
|
|
175
|
+
allEntries.push(...result.entries)
|
|
176
|
+
const next = result.scroll ?? undefined
|
|
177
|
+
if (next && next === scroll) break
|
|
178
|
+
scroll = next
|
|
179
|
+
} while (scroll && ++pages < MAX_PAGES)
|
|
180
|
+
|
|
181
|
+
if (pages >= MAX_PAGES) {
|
|
182
|
+
console.warn('listEntries pagination hit MAX_PAGES cap', serviceParams)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return this.fillEntriesWithData(allEntries, serviceParams, isPreview)
|
|
186
|
+
}
|
|
187
|
+
|
|
139
188
|
private async fillEntriesWithData(
|
|
140
189
|
entries: ContentEntry[],
|
|
141
190
|
serviceParams: EntryPathParams,
|
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import type { EntryPathParams } from '@vtex/client-cp'
|
|
2
|
-
import { describe, expect, it } from 'vitest'
|
|
1
|
+
import type { ContentEntry, EntryPathParams } from '@vtex/client-cp'
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
3
3
|
|
|
4
4
|
import { ContentService } from '../../../src/server/content/service'
|
|
5
5
|
import type {
|
|
6
6
|
ContentOptions,
|
|
7
7
|
ContentParams,
|
|
8
8
|
} from '../../../src/server/content/types'
|
|
9
|
+
import type * as ContentUtils from '../../../src/server/content/utils'
|
|
10
|
+
import { isContentPlatformSource } from '../../../src/server/content/utils'
|
|
11
|
+
|
|
12
|
+
vi.mock('../../../src/server/content/utils', async (importOriginal) => {
|
|
13
|
+
const actual = await importOriginal<typeof ContentUtils>()
|
|
14
|
+
return {
|
|
15
|
+
...actual,
|
|
16
|
+
isContentPlatformSource: vi.fn(actual.isContentPlatformSource),
|
|
17
|
+
}
|
|
18
|
+
})
|
|
9
19
|
|
|
10
20
|
type ContentServiceInternals = {
|
|
11
21
|
createContentOptions: (params: ContentParams) => ContentOptions
|
|
@@ -15,6 +25,59 @@ type ContentServiceInternals = {
|
|
|
15
25
|
const getServiceInternals = (service: ContentService) =>
|
|
16
26
|
service as unknown as ContentServiceInternals
|
|
17
27
|
|
|
28
|
+
const NOT_FOUND = 'Request failed with status code 404'
|
|
29
|
+
|
|
30
|
+
const entryData: Record<string, Record<string, unknown>> = {
|
|
31
|
+
generic: { sections: [{ name: 'Generic' }] },
|
|
32
|
+
collection: {
|
|
33
|
+
settings: { template: { value: '/colecao' } },
|
|
34
|
+
sections: [{ name: 'Collection' }],
|
|
35
|
+
},
|
|
36
|
+
other: {
|
|
37
|
+
settings: { template: { value: '/outra' } },
|
|
38
|
+
sections: [{ name: 'Other' }],
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const toEntry = (id: string) => ({ id, name: id }) as ContentEntry
|
|
43
|
+
|
|
44
|
+
function createFakeClientCP(pages: string[][]) {
|
|
45
|
+
return {
|
|
46
|
+
listEntries: vi.fn(async (_params: EntryPathParams, scroll?: string) => {
|
|
47
|
+
const index = scroll ? Number(scroll) : 0
|
|
48
|
+
return {
|
|
49
|
+
entries: pages[index].map(toEntry),
|
|
50
|
+
scroll: index + 1 < pages.length ? String(index + 1) : null,
|
|
51
|
+
}
|
|
52
|
+
}),
|
|
53
|
+
getEntry: vi.fn(async ({ entryId }: EntryPathParams) => ({
|
|
54
|
+
...entryData[entryId as string],
|
|
55
|
+
})),
|
|
56
|
+
previewEntryById: vi.fn(async ({ entryId }: EntryPathParams) => ({
|
|
57
|
+
...entryData[entryId as string],
|
|
58
|
+
})),
|
|
59
|
+
getEntryBySlug: vi.fn(
|
|
60
|
+
async (_params: EntryPathParams): Promise<Record<string, unknown>> => {
|
|
61
|
+
throw new Error(NOT_FOUND)
|
|
62
|
+
}
|
|
63
|
+
),
|
|
64
|
+
previewEntryBySlug: vi.fn(
|
|
65
|
+
async (_params: EntryPathParams): Promise<Record<string, unknown>> => {
|
|
66
|
+
throw new Error(NOT_FOUND)
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function createServiceWithClient(
|
|
73
|
+
pages: string[][] = [['generic', 'collection', 'other']]
|
|
74
|
+
) {
|
|
75
|
+
const service = new ContentService()
|
|
76
|
+
const clientCP = createFakeClientCP(pages)
|
|
77
|
+
Object.defineProperty(service, 'clientCP', { value: clientCP })
|
|
78
|
+
return { service, clientCP }
|
|
79
|
+
}
|
|
80
|
+
|
|
18
81
|
describe('ContentService', () => {
|
|
19
82
|
describe('convertOptionsToParams', () => {
|
|
20
83
|
it('maps a flat SEO slug filter to the client-cp slug param', () => {
|
|
@@ -95,4 +158,180 @@ describe('ContentService', () => {
|
|
|
95
158
|
expect('locale' in options.cmsOptions).toBe(false)
|
|
96
159
|
})
|
|
97
160
|
})
|
|
161
|
+
|
|
162
|
+
describe('Content Platform template list cache', () => {
|
|
163
|
+
const FIVE_MINUTES = 5 * 60 * 1000
|
|
164
|
+
|
|
165
|
+
beforeEach(() => {
|
|
166
|
+
vi.mocked(isContentPlatformSource).mockReturnValue(true)
|
|
167
|
+
vi.spyOn(console, 'warn').mockImplementation(() => {})
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
afterEach(() => {
|
|
171
|
+
vi.mocked(isContentPlatformSource).mockReset()
|
|
172
|
+
vi.restoreAllMocks()
|
|
173
|
+
vi.useRealTimers()
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
it('shares one list and entry fetch across concurrent PLPs with different slugs', async () => {
|
|
177
|
+
const { service, clientCP } = createServiceWithClient()
|
|
178
|
+
|
|
179
|
+
const [collectionPage, otherPage, unknownPage] = await Promise.all([
|
|
180
|
+
service.getPlpContent({ slug: 'colecao/camisetas' }, []),
|
|
181
|
+
service.getPlpContent({ slug: 'outra' }, []),
|
|
182
|
+
service.getPlpContent({ slug: 'nao-existe' }, []),
|
|
183
|
+
])
|
|
184
|
+
|
|
185
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(1)
|
|
186
|
+
expect(clientCP.getEntry).toHaveBeenCalledTimes(3)
|
|
187
|
+
expect(collectionPage.sections).toEqual([{ name: 'Collection' }])
|
|
188
|
+
expect(otherPage.sections).toEqual([{ name: 'Other' }])
|
|
189
|
+
expect(unknownPage.sections).toEqual([{ name: 'Generic' }])
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
it('reuses the cached list within the TTL', async () => {
|
|
193
|
+
const { service, clientCP } = createServiceWithClient()
|
|
194
|
+
|
|
195
|
+
await service.getPlpContent({ slug: 'colecao' }, [])
|
|
196
|
+
await service.getPlpContent({ slug: 'outra' }, [])
|
|
197
|
+
|
|
198
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(1)
|
|
199
|
+
expect(clientCP.getEntry).toHaveBeenCalledTimes(3)
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('still prefers a direct slug match over the cached list', async () => {
|
|
203
|
+
const { service, clientCP } = createServiceWithClient()
|
|
204
|
+
await service.getPlpContent({ slug: 'colecao' }, [])
|
|
205
|
+
|
|
206
|
+
clientCP.getEntryBySlug.mockResolvedValueOnce({
|
|
207
|
+
sections: [{ name: 'Direct' }],
|
|
208
|
+
})
|
|
209
|
+
const page = await service.getPlpContent({ slug: 'colecao' }, [])
|
|
210
|
+
|
|
211
|
+
expect(page.sections).toEqual([{ name: 'Direct' }])
|
|
212
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(1)
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
it('consumes every scroll page once', async () => {
|
|
216
|
+
const { service, clientCP } = createServiceWithClient([
|
|
217
|
+
['generic'],
|
|
218
|
+
['collection'],
|
|
219
|
+
['other'],
|
|
220
|
+
])
|
|
221
|
+
|
|
222
|
+
await Promise.all([
|
|
223
|
+
service.getMultipleContent({ contentType: 'plp' }),
|
|
224
|
+
service.getMultipleContent({ contentType: 'plp' }),
|
|
225
|
+
])
|
|
226
|
+
const { data } = await service.getMultipleContent({ contentType: 'plp' })
|
|
227
|
+
|
|
228
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(3)
|
|
229
|
+
expect(
|
|
230
|
+
clientCP.listEntries.mock.calls.map(([, scroll]) => scroll)
|
|
231
|
+
).toEqual([undefined, '1', '2'])
|
|
232
|
+
expect(data.map((entry) => entry.id)).toEqual([
|
|
233
|
+
'generic',
|
|
234
|
+
'collection',
|
|
235
|
+
'other',
|
|
236
|
+
])
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
it('keeps separate entries per content type', async () => {
|
|
240
|
+
const { service, clientCP } = createServiceWithClient()
|
|
241
|
+
|
|
242
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
243
|
+
await service.getMultipleContent({ contentType: 'pdp' })
|
|
244
|
+
await service.getMultipleContent({ contentType: 'pdp' })
|
|
245
|
+
|
|
246
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(2)
|
|
247
|
+
expect(
|
|
248
|
+
clientCP.listEntries.mock.calls.map(([params]) => params.contentType)
|
|
249
|
+
).toEqual(['plp', 'pdp'])
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
it('keeps separate entries per locale', async () => {
|
|
253
|
+
const { service, clientCP } = createServiceWithClient()
|
|
254
|
+
|
|
255
|
+
await service.getMultipleContent({ contentType: 'plp', locale: 'pt-BR' })
|
|
256
|
+
await service.getMultipleContent({ contentType: 'plp', locale: 'en-US' })
|
|
257
|
+
await service.getMultipleContent({ contentType: 'plp', locale: 'pt-BR' })
|
|
258
|
+
|
|
259
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(2)
|
|
260
|
+
expect(
|
|
261
|
+
clientCP.listEntries.mock.calls.map(([params]) => params.locale)
|
|
262
|
+
).toEqual(['pt-BR', 'en-US'])
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
it('bypasses the cache for previews', async () => {
|
|
266
|
+
const { service, clientCP } = createServiceWithClient()
|
|
267
|
+
const previewParams: ContentParams = {
|
|
268
|
+
contentType: 'plp',
|
|
269
|
+
previewData: {
|
|
270
|
+
contentType: 'plp',
|
|
271
|
+
documentId: 'collection',
|
|
272
|
+
versionId: 'version-1',
|
|
273
|
+
},
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
277
|
+
await service.getMultipleContent(previewParams)
|
|
278
|
+
await service.getMultipleContent(previewParams)
|
|
279
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
280
|
+
|
|
281
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(3)
|
|
282
|
+
expect(clientCP.getEntry).toHaveBeenCalledTimes(3)
|
|
283
|
+
expect(clientCP.previewEntryById).toHaveBeenCalledTimes(6)
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
it('does not cache failures', async () => {
|
|
287
|
+
const { service, clientCP } = createServiceWithClient()
|
|
288
|
+
const error = new Error('Request failed with status code 500')
|
|
289
|
+
clientCP.listEntries.mockRejectedValueOnce(error)
|
|
290
|
+
|
|
291
|
+
await expect(
|
|
292
|
+
service.getMultipleContent({ contentType: 'plp' })
|
|
293
|
+
).rejects.toBe(error)
|
|
294
|
+
const { data } = await service.getMultipleContent({ contentType: 'plp' })
|
|
295
|
+
|
|
296
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(2)
|
|
297
|
+
expect(data).toHaveLength(3)
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
it('does not let a late failure evict a newer fetch', async () => {
|
|
301
|
+
vi.useFakeTimers()
|
|
302
|
+
const { service, clientCP } = createServiceWithClient()
|
|
303
|
+
let rejectFirst: (err: Error) => void = () => {}
|
|
304
|
+
clientCP.listEntries.mockImplementationOnce(
|
|
305
|
+
() =>
|
|
306
|
+
new Promise((_, reject) => {
|
|
307
|
+
rejectFirst = reject
|
|
308
|
+
})
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
const first = service.getMultipleContent({ contentType: 'plp' })
|
|
312
|
+
const firstResult = expect(first).rejects.toThrow('late failure')
|
|
313
|
+
vi.advanceTimersByTime(FIVE_MINUTES)
|
|
314
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
315
|
+
|
|
316
|
+
rejectFirst(new Error('late failure'))
|
|
317
|
+
await firstResult
|
|
318
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
319
|
+
|
|
320
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(2)
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
it('fetches the list again after the TTL', async () => {
|
|
324
|
+
vi.useFakeTimers()
|
|
325
|
+
const { service, clientCP } = createServiceWithClient()
|
|
326
|
+
|
|
327
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
328
|
+
vi.advanceTimersByTime(FIVE_MINUTES - 1)
|
|
329
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
330
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(1)
|
|
331
|
+
|
|
332
|
+
vi.advanceTimersByTime(1)
|
|
333
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
334
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(2)
|
|
335
|
+
})
|
|
336
|
+
})
|
|
98
337
|
})
|