@faststore/core 4.5.1-dev.4 → 4.6.0-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-generate.log +3 -3
- package/.turbo/turbo-test.log +127 -79
- package/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/discovery.config.default.js +1 -2
- package/next.config.js +21 -5
- package/package.json +8 -8
- package/src/instrumentation.ts +15 -7
- package/src/pages/api/graphql.ts +37 -11
- package/src/server/index.ts +38 -10
- package/src/server/options.ts +3 -22
- package/test/instrumentation.test.ts +27 -0
- package/test/pages/api/graphql.test.ts +40 -2
- package/test/server/rootSpan.test.ts +90 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> @faststore/core@4.5.1-dev.
|
|
2
|
+
> @faststore/core@4.5.1-dev.4 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.5.1-dev.
|
|
6
|
+
> @faststore/core@4.5.1-dev.4 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 /home/runner/work/faststore/faststore/packages/core/@generated/
|
|
20
20
|
[32m[COMPLETED][39m Generate outputs
|
|
21
21
|
|
|
22
|
-
> @faststore/core@4.5.1-dev.
|
|
22
|
+
> @faststore/core@4.5.1-dev.4 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,11 +1,11 @@
|
|
|
1
1
|
|
|
2
|
-
> @faststore/core@4.5.1-dev.
|
|
2
|
+
> @faststore/core@4.5.1-dev.4 test /home/runner/work/faststore/faststore/packages/core
|
|
3
3
|
> vitest run
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
[1m[46m RUN [49m[22m [36mv4.0.
|
|
6
|
+
[1m[46m RUN [49m[22m [36mv4.0.18 [39m[90m/home/runner/work/faststore/faststore/packages/core[39m
|
|
7
7
|
|
|
8
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/reconcileSessionLocale.browser.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m
|
|
8
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/reconcileSessionLocale.browser.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 36[2mms[22m[39m
|
|
9
9
|
[90mstderr[2m | test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx
|
|
10
10
|
[22m[39mError in optimistic validation: TypeError: Failed to parse URL from /api/graphql?operationName=ValidateCartMutation&operationHash=8199d03debb0a6751ec53d8ee8987b78d0292acb
|
|
11
11
|
[90m at node:internal/deps/undici/undici:16416:13[39m
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:354:17) {
|
|
19
19
|
[cause]: TypeError: Invalid URL
|
|
20
20
|
[90m at new URL (node:internal/url:828:25)[39m
|
|
21
|
-
at new URL$1 (file:///home/runner/work/faststore/faststore/node_modules/[4m.pnpm[24m/vitest@4.0.
|
|
21
|
+
at new URL$1 (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/index.CyBMJtT7.js:556:9)
|
|
22
22
|
[90m at new Request (node:internal/deps/undici/undici:10971:25)[39m
|
|
23
23
|
[90m at fetch (node:internal/deps/undici/undici:11891:25)[39m
|
|
24
24
|
[90m at fetch (node:internal/deps/undici/undici:16414:10)[39m
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
Browserslist: browsers data (caniuse-lite) is 6 months old. Please run:
|
|
36
36
|
npx update-browserslist-db@latest
|
|
37
37
|
Why you should do it regularly: https://github.com/browserslist/update-db#readme
|
|
38
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/ContractSwitcher.browser.test.tsx [2m([22m[2m13 tests[22m[2m)[22m[33m 1958[2mms[22m[39m
|
|
39
|
-
[33m[2m✓[22m[39m shows an error state when the list fails to load [33m 633[2mms[22m[39m
|
|
40
38
|
[90mstderr[2m | test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx[2m > [22m[2mRecommendationShelf[2m > [22m[2mrenders nothing when there is an error
|
|
41
39
|
[22m[39mError fetching recommendations [90mundefined[39m boom for campaign vrn:recommendations:acc:rec-top-items-v2:campaign-1
|
|
42
40
|
|
|
43
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
41
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[32m 283[2mms[22m[39m
|
|
42
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/ContractSwitcher.browser.test.tsx [2m([22m[2m13 tests[22m[2m)[22m[33m 2139[2mms[22m[39m
|
|
43
|
+
[33m[2m✓[22m[39m shows an error state when the list fails to load [33m 585[2mms[22m[39m
|
|
44
44
|
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2mposts the password and redirects to the requested return path
|
|
45
45
|
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
46
46
|
|
|
@@ -270,13 +270,12 @@ act(() => {
|
|
|
270
270
|
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
|
|
271
271
|
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
272
272
|
|
|
273
|
-
[32m✓[39m [30m[46m browser [49m[39m test/pages/password-protection.browser.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[33m
|
|
274
|
-
[33m[2m✓[22m[39m renders the password protection form [33m
|
|
275
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/getInitialSession.browser.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m
|
|
273
|
+
[32m✓[39m [30m[46m browser [49m[39m test/pages/password-protection.browser.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[33m 1851[2mms[22m[39m
|
|
274
|
+
[33m[2m✓[22m[39m renders the password protection form [33m 789[2mms[22m[39m
|
|
275
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/getInitialSession.browser.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 29[2mms[22m[39m
|
|
276
276
|
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/changeContractToken.browser.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 80[2mms[22m[39m
|
|
277
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationDrawer.browser.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[33m
|
|
278
|
-
[33m[2m✓[22m[39m renders the menu view with contract details and manage footer [33m
|
|
279
|
-
[33m[2m✓[22m[39m opens the contract switcher and returns to the menu on back [33m 397[2mms[22m[39m
|
|
277
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationDrawer.browser.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[33m 1109[2mms[22m[39m
|
|
278
|
+
[33m[2m✓[22m[39m renders the menu view with contract details and manage footer [33m 577[2mms[22m[39m
|
|
280
279
|
[90mstderr[2m | test/sdk/localization/store-url.browser.test.ts
|
|
281
280
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
282
281
|
at validateCart [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/index.ts:121:27[90m)[39m
|
|
@@ -284,9 +283,9 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
284
283
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:354:23)
|
|
285
284
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
286
285
|
|
|
287
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/localization/store-url.browser.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
288
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/
|
|
289
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/
|
|
286
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/localization/store-url.browser.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 17[2mms[22m[39m
|
|
287
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/useSwitchContract.browser.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 119[2mms[22m[39m
|
|
288
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/useAvailableContracts.browser.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 74[2mms[22m[39m
|
|
290
289
|
[90mstderr[2m | test/components/account/doLogout.browser.test.ts
|
|
291
290
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
292
291
|
at validateCart [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/index.ts:121:27[90m)[39m
|
|
@@ -294,9 +293,9 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
294
293
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:354:23)
|
|
295
294
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
296
295
|
|
|
297
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/doLogout.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m
|
|
298
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationDrawerHeader.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
299
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationDrawerFooter.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[
|
|
296
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/doLogout.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 31[2mms[22m[39m
|
|
297
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationDrawerHeader.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 251[2mms[22m[39m
|
|
298
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationDrawerFooter.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[33m 306[2mms[22m[39m
|
|
300
299
|
[90mstderr[2m | test/sdk/account/clearPersistedSessionState.browser.test.ts
|
|
301
300
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
302
301
|
at validateCart [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/index.ts:121:27[90m)[39m
|
|
@@ -304,11 +303,12 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
304
303
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:354:23)
|
|
305
304
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
306
305
|
|
|
307
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
308
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
309
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/localization/bindingPaths.test.ts [2m([22m[2m71 tests[22m[2m)[22m[32m 19[2mms[22m[39m
|
|
306
|
+
[32m✓[39m [30m[46m browser [49m[39m test/utils/isLocalHost.browser.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
307
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/clearPersistedSessionState.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
310
308
|
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/reconcileSessionLocale.disabled.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 3[2mms[22m[39m
|
|
311
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
309
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/localization/bindingPaths.test.ts [2m([22m[2m71 tests[22m[2m)[22m[32m 27[2mms[22m[39m
|
|
310
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/password-protection-service.test.ts [2m([22m[2m22 tests[22m[2m)[22m[32m 35[2mms[22m[39m
|
|
311
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/match-url.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 9[2mms[22m[39m
|
|
312
312
|
[90mstderr[2m | test/sdk/account/refreshToken.browser.test.ts
|
|
313
313
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
314
314
|
at validateCart [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/index.ts:121:27[90m)[39m
|
|
@@ -316,11 +316,10 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
316
316
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:354:23)
|
|
317
317
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
318
318
|
|
|
319
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
320
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/refreshToken.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m
|
|
321
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/localization/
|
|
322
|
-
[32m✓[39m [30m[43m node [49m[39m test/pages/api/unlock.test.ts [2m([22m[2m15 tests[22m[2m)[22m[32m
|
|
323
|
-
[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
|
|
319
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/localization/useBindingSelector.test.tsx [2m([22m[2m22 tests[22m[2m)[22m[32m 13[2mms[22m[39m
|
|
320
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/refreshToken.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
321
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/localization/bindingSelector.test.ts [2m([22m[2m18 tests[22m[2m)[22m[32m 10[2mms[22m[39m
|
|
322
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/unlock.test.ts [2m([22m[2m15 tests[22m[2m)[22m[32m 147[2mms[22m[39m
|
|
324
323
|
[90mstderr[2m | test/components/search/SearchInputComponent.test.tsx
|
|
325
324
|
[22m[39mWarning: forwardRef render functions accept exactly two parameters: props and ref. Did you forget to use the ref parameter?
|
|
326
325
|
|
|
@@ -385,22 +384,11 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
|
|
|
385
384
|
at Wrapper (/home/runner/work/faststore/faststore/packages/core/test/components/search/SearchInputComponent.test.tsx:106:20)
|
|
386
385
|
|
|
387
386
|
[32m✓[39m [30m[43m node [49m[39m test/components/search/SearchInputComponent.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[32m 84[2mms[22m[39m
|
|
388
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/cookieCacheBusting.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m
|
|
387
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/cookieCacheBusting.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 9[2mms[22m[39m
|
|
389
388
|
[32m✓[39m [30m[43m node [49m[39m test/sdk/search/useSearchHistory.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 54[2mms[22m[39m
|
|
390
|
-
[32m✓[39m [30m[43m node [49m[39m test/experimental/myAccountCmsServerSideProps.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m
|
|
391
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/clearCookies.test.ts [2m([22m[2m20 tests[22m[2m)[22m[32m
|
|
392
|
-
[
|
|
393
|
-
[22m[39mSet password request failed: Bad Request
|
|
394
|
-
|
|
395
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/useSetPassword.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 51[2mms[22m[39m
|
|
396
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountListQuotesTable.test.tsx [2m([22m[2m12 tests[22m[2m)[22m[33m 427[2mms[22m[39m
|
|
397
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/quoteFilters.test.ts [2m([22m[2m23 tests[22m[2m)[22m[32m 33[2mms[22m[39m
|
|
398
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/multipleTemplates.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
399
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/localization/localizeRedirectDestination.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
400
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountListQuotes.test.tsx [2m([22m[2m9 tests[22m[2m)[22m[33m 818[2mms[22m[39m
|
|
401
|
-
[33m[2m✓[22m[39m navigates with the search term on blur [33m 370[2mms[22m[39m
|
|
402
|
-
[33m[2m✓[22m[39m navigates without a label param when the search is cleared [33m 358[2mms[22m[39m
|
|
403
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntryOperation.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 43[2mms[22m[39m
|
|
389
|
+
[32m✓[39m [30m[43m node [49m[39m test/experimental/myAccountCmsServerSideProps.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 10[2mms[22m[39m
|
|
390
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/clearCookies.test.ts [2m([22m[2m20 tests[22m[2m)[22m[32m 29[2mms[22m[39m
|
|
391
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountListQuotesTable.test.tsx [2m([22m[2m12 tests[22m[2m)[22m[33m 386[2mms[22m[39m
|
|
404
392
|
[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
|
|
405
393
|
[22m[39mGraphql execution returned with error: [
|
|
406
394
|
{
|
|
@@ -447,47 +435,107 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
|
|
|
447
435
|
{ message: [32m'bad'[39m, status: [33m400[39m, type: [32m'BadRequestError'[39m }
|
|
448
436
|
]
|
|
449
437
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
[
|
|
454
|
-
[
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
438
|
+
[90mstderr[2m | test/pages/api/graphql.test.ts[2m > [22m[2m/api/graphql request handling[2m > [22m[2mmaps BadRequestError thrown by execute to its status
|
|
439
|
+
[22m[39mSomething unexpected occurred querying Graphql endpoint:
|
|
440
|
+
_ [FastStoreError]: malformed
|
|
441
|
+
at [90m/home/runner/work/faststore/faststore/packages/core/[39mtest/pages/api/graphql.test.ts:190:31
|
|
442
|
+
at [90m/home/runner/work/faststore/faststore/packages/core/[39mtest/pages/api/graphql.test.ts:196:39
|
|
443
|
+
at 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:1024:60
|
|
444
|
+
at 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:145:11
|
|
445
|
+
at 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:915:26
|
|
446
|
+
at 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:1243:20
|
|
447
|
+
at new Promise (<anonymous>)
|
|
448
|
+
at runWithTimeout (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:1209:10)
|
|
449
|
+
at 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:37
|
|
450
|
+
at Traces.$ (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/traces.CCmnQaNT.js:142:27) {
|
|
451
|
+
extensions: { status: [33m400[39m, type: [32m'BadRequestError'[39m }
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
[90mstderr[2m | test/pages/api/graphql.test.ts[2m > [22m[2m/api/graphql request handling[2m > [22m[2mmaps UnauthorizedError thrown by execute to its status
|
|
455
|
+
[22m[39mSomething unexpected occurred querying Graphql endpoint:
|
|
456
|
+
te [FastStoreError]: expired
|
|
457
|
+
at [90m/home/runner/work/faststore/faststore/packages/core/[39mtest/pages/api/graphql.test.ts:191:33
|
|
458
|
+
at [90m/home/runner/work/faststore/faststore/packages/core/[39mtest/pages/api/graphql.test.ts:196:39
|
|
459
|
+
at 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:1024:60
|
|
460
|
+
at 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:145:11
|
|
461
|
+
at 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:915:26
|
|
462
|
+
at 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:1243:20
|
|
463
|
+
at new Promise (<anonymous>)
|
|
464
|
+
at runWithTimeout (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:1209:10)
|
|
465
|
+
at 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:37
|
|
466
|
+
at Traces.$ (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/traces.CCmnQaNT.js:142:27) {
|
|
467
|
+
extensions: { status: [33m401[39m, type: [32m'UnauthorizedError'[39m }
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
[90mstderr[2m | test/pages/api/graphql.test.ts[2m > [22m[2m/api/graphql request handling[2m > [22m[2mmaps an unexpected failure thrown by execute to its status
|
|
471
|
+
[22m[39mSomething unexpected occurred querying Graphql endpoint:
|
|
472
|
+
Error: socket hang up
|
|
473
|
+
at [90m/home/runner/work/faststore/faststore/packages/core/[39mtest/pages/api/graphql.test.ts:192:37
|
|
474
|
+
at [90m/home/runner/work/faststore/faststore/packages/core/[39mtest/pages/api/graphql.test.ts:196:39
|
|
475
|
+
at 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:1024:60
|
|
476
|
+
at 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:145:11
|
|
477
|
+
at 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:915:26
|
|
478
|
+
at 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:1243:20
|
|
479
|
+
at new Promise (<anonymous>)
|
|
480
|
+
at runWithTimeout (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:1209:10)
|
|
481
|
+
at 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:37
|
|
482
|
+
at Traces.$ (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/traces.CCmnQaNT.js:142:27)
|
|
483
|
+
|
|
484
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/graphql.test.ts [2m([22m[2m17 tests[22m[2m)[22m[32m 20[2mms[22m[39m
|
|
485
|
+
[90mstderr[2m | test/sdk/account/useSetPassword.test.ts[2m > [22m[2museSetPassword[2m > [22m[2mmaps wrongcredentials error responses to the existing message
|
|
486
|
+
[22m[39mSet password request failed: Bad Request
|
|
487
|
+
|
|
488
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/useSetPassword.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 29[2mms[22m[39m
|
|
489
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountListQuotes.test.tsx [2m([22m[2m9 tests[22m[2m)[22m[33m 842[2mms[22m[39m
|
|
490
|
+
[33m[2m✓[22m[39m navigates with the search term on blur [33m 362[2mms[22m[39m
|
|
491
|
+
[33m[2m✓[22m[39m navigates without a label param when the search is cleared [33m 364[2mms[22m[39m
|
|
492
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/quoteFilters.test.ts [2m([22m[2m23 tests[22m[2m)[22m[32m 35[2mms[22m[39m
|
|
493
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/multipleTemplates.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
494
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntryOperation.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 30[2mms[22m[39m
|
|
495
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/localization/localizeRedirectDestination.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
496
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntryUpload.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 71[2mms[22m[39m
|
|
497
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuotesFilterSlider.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[32m 125[2mms[22m[39m
|
|
498
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/analytics/useStartRecommendationSession.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 45[2mms[22m[39m
|
|
499
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntry.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 40[2mms[22m[39m
|
|
500
|
+
[32m✓[39m [30m[43m node [49m[39m test/proxy.localization.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 45[2mms[22m[39m
|
|
501
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/index.test.ts [2m([22m[2m7 tests[22m[2m)[22m[33m 830[2mms[22m[39m
|
|
502
|
+
[33m[2m✓[22m[39m should handle options and execute [33m 313[2mms[22m[39m
|
|
503
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/getMyAccountRoutes.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 9[2mms[22m[39m
|
|
504
|
+
[32m✓[39m [30m[43m node [49m[39m test/proxy.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 14[2mms[22m[39m
|
|
505
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/webops-api.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 15[2mms[22m[39m
|
|
506
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderFormItems.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 46[2mms[22m[39m
|
|
507
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/content/service.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
508
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuotesSelectedTags.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[32m 103[2mms[22m[39m
|
|
509
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/refreshToken.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 9[2mms[22m[39m
|
|
510
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/cms/global.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
465
511
|
[32m✓[39m [30m[43m node [49m[39m test/sdk/localization/store-url.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
466
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/analytics/hasEnabledRecommendationShelf.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
467
512
|
[32m✓[39m [30m[43m node [49m[39m test/sdk/auth/useAuth.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 27[2mms[22m[39m
|
|
468
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
469
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
470
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/
|
|
513
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuotesStatusSelector.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[32m 120[2mms[22m[39m
|
|
514
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/analytics/hasEnabledRecommendationShelf.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
515
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/getRequestHostname.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
516
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/preview.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 9[2mms[22m[39m
|
|
517
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/validateSessionRefreshToken.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
518
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/rootSpan.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 31[2mms[22m[39m
|
|
471
519
|
[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
|
|
472
|
-
[32m✓[39m [30m[43m node [49m[39m test/pages/api/preview.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 8[2mms[22m[39m
|
|
473
520
|
[32m✓[39m [30m[43m node [49m[39m test/components/RecommendationShelf/vrn.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
474
|
-
[32m✓[39m [30m[43m node [49m[39m test/server/cms/index.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
475
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/retry.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m
|
|
476
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/
|
|
477
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/
|
|
478
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/unlockResponse.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m
|
|
521
|
+
[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
|
|
522
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/retry.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 13[2mms[22m[39m
|
|
523
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/account/Layout.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m 39[2mms[22m[39m
|
|
524
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/RecommendationShelf/useRecommendationUserId.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 193[2mms[22m[39m
|
|
525
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/unlockResponse.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
479
526
|
[32m✓[39m [30m[43m node [49m[39m test/server/cms/myAccountDefaultSections.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
480
527
|
[32m✓[39m [30m[43m node [49m[39m test/components/RecommendationShelf/useRecommendations.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
481
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/isLocalHost.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m
|
|
482
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/account/OrganizationDrawerBody.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
528
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/isLocalHost.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
529
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/account/OrganizationDrawerBody.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 39[2mms[22m[39m
|
|
483
530
|
[32m✓[39m [30m[43m node [49m[39m test/utils/userOrderStatus.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
484
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/analytics/utils.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
485
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
486
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
487
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
[2m
|
|
491
|
-
[2m
|
|
492
|
-
[2m
|
|
531
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/analytics/utils.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 3[2mms[22m[39m
|
|
532
|
+
[32m✓[39m [30m[43m node [49m[39m test/instrumentation.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
533
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/auth/ProfileChallenge.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 27[2mms[22m[39m
|
|
534
|
+
[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
|
|
535
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuoteStatusBadge.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 22[2mms[22m[39m
|
|
536
|
+
|
|
537
|
+
[2m Test Files [22m [1m[32m75 passed[39m[22m[90m (75)[39m
|
|
538
|
+
[2m Tests [22m [1m[32m584 passed[39m[22m[90m (584)[39m
|
|
539
|
+
[2m Start at [22m 22:51:57
|
|
540
|
+
[2m Duration [22m 33.94s[2m (transform 8.01s, setup 0ms, import 27.87s, tests 10.10s, environment 44.06s)[22m
|
|
493
541
|
|
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.6.0-dev.0](https://github.com/vtex/faststore/compare/v4.5.1-dev.4...v4.6.0-dev.0) (2026-08-11)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- removing vtex/diagnostics-nodejs ([#3389](https://github.com/vtex/faststore/issues/3389)) ([74e2d50](https://github.com/vtex/faststore/commit/74e2d503a44903929b90af7701956536690d4e41))
|
|
11
|
+
|
|
6
12
|
## [4.5.1-dev.4](https://github.com/vtex/faststore/compare/v4.5.1-dev.3...v4.5.1-dev.4) (2026-08-10)
|
|
7
13
|
|
|
8
14
|
**Note:** Version bump only for package @faststore/core
|
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ packages/core/
|
|
|
31
31
|
│ ├── server/ # Server-side utilities (CMS content fetching)
|
|
32
32
|
│ ├── customizations/ # Store-level overrides: styles, fonts, components, fragments
|
|
33
33
|
│ ├── styles/ # Global SCSS styles
|
|
34
|
-
│ └── instrumentation.ts # Next.js instrumentation hook (boots @faststore/diagnostics
|
|
34
|
+
│ └── instrumentation.ts # Next.js instrumentation hook (boots @faststore/diagnostics — see docs/observability.md)
|
|
35
35
|
├── cms/faststore/ # CMS configuration: sections.json, content-types.json, schemas
|
|
36
36
|
├── @generated/ # Auto-generated GraphQL types — do not edit
|
|
37
37
|
├── discovery.config.default.js # Committed base store configuration (platform, sales channel, locale)
|
|
@@ -166,8 +166,7 @@ module.exports = {
|
|
|
166
166
|
analytics: {
|
|
167
167
|
// https://developers.google.com/tag-platform/tag-manager/web#standard_web_page_installation,
|
|
168
168
|
gtmContainerId: 'GTM-PGHZ95N',
|
|
169
|
-
serviceName: 'faststore
|
|
170
|
-
otelEnabled: true,
|
|
169
|
+
serviceName: 'faststore',
|
|
171
170
|
},
|
|
172
171
|
|
|
173
172
|
cms: {
|
package/next.config.js
CHANGED
|
@@ -14,7 +14,6 @@ const getRootFolder = () => {
|
|
|
14
14
|
console.log(`
|
|
15
15
|
Root folder at: ${getRootFolder()}
|
|
16
16
|
AccountID: ${storeConfig.api?.storeId ?? 'Unknown'}
|
|
17
|
-
Analytics Enabled: ${storeConfig.analytics?.otelEnabled ?? false}
|
|
18
17
|
`)
|
|
19
18
|
|
|
20
19
|
/**
|
|
@@ -22,8 +21,6 @@ console.log(`
|
|
|
22
21
|
* */
|
|
23
22
|
const nextConfig = {
|
|
24
23
|
/* config options here */
|
|
25
|
-
/* Replaces terser by swc for minifying. It's the default in NextJS 13 */
|
|
26
|
-
swcMinify: true,
|
|
27
24
|
...(Array.isArray(storeConfig.experimental?.transpilePackages) &&
|
|
28
25
|
storeConfig.experimental.transpilePackages.length > 0 && {
|
|
29
26
|
transpilePackages: storeConfig.experimental.transpilePackages,
|
|
@@ -55,9 +52,7 @@ const nextConfig = {
|
|
|
55
52
|
sassOptions: {
|
|
56
53
|
silenceDeprecations: ['if-function', 'legacy-js-api'],
|
|
57
54
|
},
|
|
58
|
-
// TODO: We won't need to enable this experimental feature when migrating to Next.js 13
|
|
59
55
|
experimental: {
|
|
60
|
-
instrumentationHook: true,
|
|
61
56
|
scrollRestoration: !storeConfig.experimental.scrollRestoration,
|
|
62
57
|
},
|
|
63
58
|
/*
|
|
@@ -68,6 +63,27 @@ const nextConfig = {
|
|
|
68
63
|
* */
|
|
69
64
|
outputFileTracingRoot: getRootFolder(),
|
|
70
65
|
webpack: (config, { isServer, dev }) => {
|
|
66
|
+
// `@opentelemetry/sdk-node` (pulled in by @faststore/diagnostics) does an
|
|
67
|
+
// optional `require('@opentelemetry/shim-opencensus')` guarded by a try/catch.
|
|
68
|
+
// The module is an optional peer that isn't installed, so webpack reports a
|
|
69
|
+
// "Module not found" error it can't see is intentional. Aliasing it to `false`
|
|
70
|
+
// resolves it to an empty module, matching the graceful degradation the SDK
|
|
71
|
+
// already expects at runtime (Turbopack handles this case on its own).
|
|
72
|
+
config.resolve.alias = {
|
|
73
|
+
...config.resolve.alias,
|
|
74
|
+
'@opentelemetry/shim-opencensus': false,
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// `require-in-the-middle` (used by OpenTelemetry instrumentation) patches
|
|
78
|
+
// modules through a dynamic `require` that webpack can't statically analyze,
|
|
79
|
+
// emitting a benign "Critical dependency" warning. `serverExternalPackages`
|
|
80
|
+
// handles this for Turbopack, but the webpack builder still traces into it,
|
|
81
|
+
// so we silence the warning for this module specifically.
|
|
82
|
+
config.ignoreWarnings = [
|
|
83
|
+
...(config.ignoreWarnings ?? []),
|
|
84
|
+
{ module: /require-in-the-middle/ },
|
|
85
|
+
]
|
|
86
|
+
|
|
71
87
|
// https://github.com/vercel/next.js/discussions/11267#discussioncomment-2479112
|
|
72
88
|
// camel-case style names from css modules
|
|
73
89
|
config.module.rules
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faststore/core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.6.0-dev.0",
|
|
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/
|
|
75
|
-
"@faststore/
|
|
76
|
-
"@faststore/
|
|
77
|
-
"@faststore/
|
|
78
|
-
"@faststore/ui": "4.
|
|
74
|
+
"@faststore/api": "4.6.0-dev.0",
|
|
75
|
+
"@faststore/diagnostics": "4.6.0-dev.0",
|
|
76
|
+
"@faststore/lighthouse": "4.6.0-dev.0",
|
|
77
|
+
"@faststore/sdk": "4.6.0-dev.0",
|
|
78
|
+
"@faststore/ui": "4.6.0-dev.0"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
81
|
"@cypress/code-coverage": "^3.12.1",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"@types/fs-extra": "^9.0.13",
|
|
89
89
|
"@types/node": "20.19.13",
|
|
90
90
|
"@vitejs/plugin-react": "^5.1.2",
|
|
91
|
-
"@vitest/coverage-v8": "4.0.
|
|
91
|
+
"@vitest/coverage-v8": "4.0.18",
|
|
92
92
|
"@vtex/prettier-config": "1.0.0",
|
|
93
93
|
"axe-core": "^4.8.1",
|
|
94
94
|
"cypress": "12.17.4",
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"is-ci": "^3.0.0",
|
|
100
100
|
"jsdom": "^27.4.0",
|
|
101
101
|
"typescript": "5.9.3",
|
|
102
|
-
"vitest": "4.0.
|
|
102
|
+
"vitest": "4.0.18"
|
|
103
103
|
},
|
|
104
104
|
"peerDependencies": {
|
|
105
105
|
"graphql": "16.11.0",
|
package/src/instrumentation.ts
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import config from '../discovery.config'
|
|
2
2
|
import pkgJSON from '../package.json'
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Next.js instrumentation hook. This is the only place telemetry is booted, so
|
|
6
|
+
* the OTel SDK is registered before any request is served.
|
|
7
|
+
*/
|
|
4
8
|
export async function register() {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
// Disabled feature until release date
|
|
10
|
+
const instrumentationEnabled = false
|
|
11
|
+
|
|
12
|
+
// The runtime check must wrap the import instead of guarding with an early
|
|
13
|
+
// return: bundlers replace `process.env.NEXT_RUNTIME` with a literal, so only
|
|
14
|
+
// a positive branch gets dropped from the edge bundle. Left reachable, the
|
|
15
|
+
// OTel SDK pulls in Node builtins (`fs`, `zlib`, `stream`) that fail to resolve.
|
|
16
|
+
if (process.env.NEXT_RUNTIME === 'nodejs' && instrumentationEnabled) {
|
|
9
17
|
const { name, version } = pkgJSON
|
|
18
|
+
|
|
10
19
|
try {
|
|
11
20
|
const { getTelemetryClient } = await import('@faststore/diagnostics')
|
|
12
|
-
console.log('Instrumemtation.ts: Getting telemetry client')
|
|
13
21
|
|
|
14
|
-
return getTelemetryClient({
|
|
22
|
+
return await getTelemetryClient({
|
|
15
23
|
serviceName: config.analytics?.serviceName ?? name,
|
|
16
24
|
version,
|
|
17
25
|
account: config.api.storeId,
|
|
@@ -19,7 +27,7 @@ export async function register() {
|
|
|
19
27
|
packageName: name,
|
|
20
28
|
})
|
|
21
29
|
} catch (error) {
|
|
22
|
-
console.error('Failed to initialize OTEL Instrumentation')
|
|
30
|
+
console.error('Failed to initialize OTEL Instrumentation', error)
|
|
23
31
|
}
|
|
24
32
|
}
|
|
25
33
|
}
|
package/src/pages/api/graphql.ts
CHANGED
|
@@ -13,6 +13,9 @@ import { getRequestHostname } from 'src/utils/getRequestHostname'
|
|
|
13
13
|
import { isLocalHost } from 'src/utils/isLocalHost'
|
|
14
14
|
import { shouldForceRefreshTokenForValidateSession } from 'src/utils/validateSessionRefreshToken'
|
|
15
15
|
import { execute } from '../../server'
|
|
16
|
+
import { logger } from '@faststore/diagnostics'
|
|
17
|
+
|
|
18
|
+
const OTELLogger = logger('@faststore/core')
|
|
16
19
|
|
|
17
20
|
const DEFAULT_MAX_AGE = 5 * 60 // 5 minutes
|
|
18
21
|
const DEFAULT_STALE_WHILE_REVALIDATE = 60 * 60 // 1 hour
|
|
@@ -150,6 +153,12 @@ const hasVtexIdclientAutCookie = (request: NextApiRequest): boolean => {
|
|
|
150
153
|
const handler: NextApiHandler = async (request, response) => {
|
|
151
154
|
if (request.method !== 'POST' && request.method !== 'GET') {
|
|
152
155
|
response.status(405).end()
|
|
156
|
+
OTELLogger(
|
|
157
|
+
'info',
|
|
158
|
+
'Invalid request method: %s %s',
|
|
159
|
+
request.method,
|
|
160
|
+
request.url
|
|
161
|
+
)
|
|
153
162
|
|
|
154
163
|
return
|
|
155
164
|
}
|
|
@@ -158,6 +167,15 @@ const handler: NextApiHandler = async (request, response) => {
|
|
|
158
167
|
// value is used to cache bust the request if there is a VtexIdclientAutCookie
|
|
159
168
|
const { operation, variables, query, v: value } = parseRequest(request)
|
|
160
169
|
|
|
170
|
+
// Variables and the query body are deliberately not logged: they carry
|
|
171
|
+
// session and customer data.
|
|
172
|
+
OTELLogger(
|
|
173
|
+
'debug',
|
|
174
|
+
'operation: %s hash: %s',
|
|
175
|
+
operation?.__meta__?.operationName,
|
|
176
|
+
operation?.__meta__?.operationHash
|
|
177
|
+
)
|
|
178
|
+
|
|
161
179
|
const isLocal = isLocalHost(getRequestHostname(request.headers.host))
|
|
162
180
|
|
|
163
181
|
if (
|
|
@@ -209,18 +227,21 @@ const handler: NextApiHandler = async (request, response) => {
|
|
|
209
227
|
// upstream status) is nested in `originalError`. Recover it so the BFF
|
|
210
228
|
// propagates the real status instead of collapsing everything to 500.
|
|
211
229
|
const fastStoreError = errors.map(recoverFastStoreError).find(Boolean)
|
|
230
|
+
const reportedErrors = errors.map((graphqlError) => {
|
|
231
|
+
const fsError = recoverFastStoreError(graphqlError)
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
message: (graphqlError as { message?: string })?.message,
|
|
235
|
+
status: fsError?.extensions.status,
|
|
236
|
+
type: fsError?.extensions.type,
|
|
237
|
+
}
|
|
238
|
+
})
|
|
212
239
|
|
|
213
|
-
console.error(
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
return {
|
|
219
|
-
message: (graphqlError as { message?: string })?.message,
|
|
220
|
-
status: fsError?.extensions.status,
|
|
221
|
-
type: fsError?.extensions.type,
|
|
222
|
-
}
|
|
223
|
-
})
|
|
240
|
+
console.error('Graphql execution returned with error: ', reportedErrors)
|
|
241
|
+
OTELLogger(
|
|
242
|
+
'error',
|
|
243
|
+
'Graphql execution returned with error: %o',
|
|
244
|
+
reportedErrors
|
|
224
245
|
)
|
|
225
246
|
|
|
226
247
|
const status = fastStoreError?.extensions.status ?? 500
|
|
@@ -304,6 +325,11 @@ const handler: NextApiHandler = async (request, response) => {
|
|
|
304
325
|
'Something unexpected occurred querying Graphql endpoint: \n',
|
|
305
326
|
err
|
|
306
327
|
)
|
|
328
|
+
OTELLogger(
|
|
329
|
+
'error',
|
|
330
|
+
'Something unexpected occurred querying Graphql endpoint: %o',
|
|
331
|
+
err
|
|
332
|
+
)
|
|
307
333
|
|
|
308
334
|
if (err instanceof BadRequestError) {
|
|
309
335
|
response.status(400).end()
|
package/src/server/index.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
GraphqlVtexSchema,
|
|
17
17
|
isFastStoreError,
|
|
18
18
|
} from '@faststore/api'
|
|
19
|
+
import { OTELAPI } from '@faststore/diagnostics'
|
|
19
20
|
import { loadFilesSync } from '@graphql-tools/load-files'
|
|
20
21
|
import { mergeTypeDefs } from '@graphql-tools/merge'
|
|
21
22
|
import { makeExecutableSchema } from '@graphql-tools/schema'
|
|
@@ -28,7 +29,7 @@ import thirdPartyResolvers from '../customizations/src/graphql/thirdParty/resolv
|
|
|
28
29
|
import vtexExtensionsResolvers from '../customizations/src/graphql/vtex/resolvers'
|
|
29
30
|
|
|
30
31
|
import type { Operation } from '../sdk/graphql/request'
|
|
31
|
-
import { apiOptions
|
|
32
|
+
import { apiOptions } from './options'
|
|
32
33
|
|
|
33
34
|
interface ExecuteOptions<V = Record<string, unknown>> {
|
|
34
35
|
operation: Operation
|
|
@@ -70,8 +71,7 @@ export function getFinalAPISchema() {
|
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
export const getEnvelop = async () => {
|
|
73
|
-
const
|
|
74
|
-
const apiContextFactory = await GraphqlVtexContextFactory(options)
|
|
74
|
+
const apiContextFactory = await GraphqlVtexContextFactory(apiOptions)
|
|
75
75
|
|
|
76
76
|
return envelop({
|
|
77
77
|
plugins: [
|
|
@@ -136,13 +136,17 @@ export const execute = async <V extends Maybe<{ [key: string]: unknown }>, D>(
|
|
|
136
136
|
contextValue.storage.locale = locale
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
const { data, errors } =
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
139
|
+
const { data, errors } = await withRootSpan(
|
|
140
|
+
`graphql ${operationName ?? 'operation'}`,
|
|
141
|
+
() =>
|
|
142
|
+
run({
|
|
143
|
+
schema,
|
|
144
|
+
document: parse(query),
|
|
145
|
+
variableValues: variables,
|
|
146
|
+
contextValue,
|
|
147
|
+
operationName,
|
|
148
|
+
}) as Promise<{ data: D; errors: unknown[] }>
|
|
149
|
+
)
|
|
146
150
|
|
|
147
151
|
return {
|
|
148
152
|
data,
|
|
@@ -153,3 +157,27 @@ export const execute = async <V extends Maybe<{ [key: string]: unknown }>, D>(
|
|
|
153
157
|
},
|
|
154
158
|
}
|
|
155
159
|
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Runs an operation inside a per-request root span, made the active context so
|
|
163
|
+
* the resolver spans emitted by `@faststore/api` parent to it. Resolves to a
|
|
164
|
+
* plain call when telemetry is disabled.
|
|
165
|
+
*/
|
|
166
|
+
async function withRootSpan<T>(name: string, run: () => Promise<T>) {
|
|
167
|
+
if (!apiOptions.OTEL_ENABLED) {
|
|
168
|
+
return run()
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const span = OTELAPI.trace.getTracer('@faststore/core').startSpan(name)
|
|
172
|
+
const otelContext = OTELAPI.trace.setSpan(OTELAPI.context.active(), span)
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
return await OTELAPI.context.with(otelContext, run)
|
|
176
|
+
} catch (error) {
|
|
177
|
+
span.setStatus({ code: OTELAPI.SpanStatusCode.ERROR })
|
|
178
|
+
span.recordException(error as Error)
|
|
179
|
+
throw error
|
|
180
|
+
} finally {
|
|
181
|
+
span.end()
|
|
182
|
+
}
|
|
183
|
+
}
|
package/src/server/options.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { APIOptions } from '@faststore/api'
|
|
2
|
-
import { getTraceClient } from '@faststore/diagnostics'
|
|
3
2
|
import storeConfig from '../../discovery.config'
|
|
4
3
|
import pkgJSON from '../../package.json'
|
|
5
4
|
|
|
6
|
-
const {
|
|
5
|
+
const { version } = pkgJSON
|
|
7
6
|
|
|
8
7
|
export const apiOptions: APIOptions = {
|
|
9
8
|
platform: storeConfig.platform as APIOptions['platform'],
|
|
@@ -23,25 +22,7 @@ export const apiOptions: APIOptions = {
|
|
|
23
22
|
storeConfig.api?.enableUnavailableItemsOnCart ?? false,
|
|
24
23
|
},
|
|
25
24
|
version,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
},
|
|
25
|
+
// feature flag default to false as it should not emit traces/logs yet
|
|
26
|
+
OTEL_ENABLED: false,
|
|
29
27
|
discoveryConfig: storeConfig,
|
|
30
28
|
}
|
|
31
|
-
|
|
32
|
-
export async function withTraceClient<T extends APIOptions = typeof apiOptions>(
|
|
33
|
-
apiOptions: T
|
|
34
|
-
): Promise<T> {
|
|
35
|
-
const OTEL = {}
|
|
36
|
-
getTraceClient(
|
|
37
|
-
apiOptions?.discoveryConfig?.analytics?.serviceName ?? name
|
|
38
|
-
)?.inject(OTEL)
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
...apiOptions,
|
|
42
|
-
OTEL: {
|
|
43
|
-
...OTEL,
|
|
44
|
-
enabled: storeConfig.analytics?.otelEnabled?.toString() === 'true',
|
|
45
|
-
},
|
|
46
|
-
} as T
|
|
47
|
-
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { register } from '../src/instrumentation'
|
|
4
|
+
|
|
5
|
+
const getTelemetryClient = vi.hoisted(() => vi.fn())
|
|
6
|
+
|
|
7
|
+
vi.mock('@faststore/diagnostics', () => ({ getTelemetryClient }))
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
vi.clearAllMocks()
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
vi.unstubAllEnvs()
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
describe('register', () => {
|
|
18
|
+
it.each(['nodejs', 'edge', undefined])(
|
|
19
|
+
'does not boot telemetry on the %s runtime while the feature is off',
|
|
20
|
+
async (runtime) => {
|
|
21
|
+
vi.stubEnv('NEXT_RUNTIME', runtime)
|
|
22
|
+
|
|
23
|
+
await expect(register()).resolves.toBeUndefined()
|
|
24
|
+
expect(getTelemetryClient).not.toHaveBeenCalled()
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
})
|
|
@@ -29,9 +29,13 @@ const createResponse = () => {
|
|
|
29
29
|
return res as unknown as NextApiResponse & typeof res
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
const createRequest = (
|
|
32
|
+
const createRequest = (
|
|
33
|
+
operationName = 'ClientShippingSimulationQuery',
|
|
34
|
+
method = 'GET'
|
|
35
|
+
) =>
|
|
33
36
|
({
|
|
34
|
-
method
|
|
37
|
+
method,
|
|
38
|
+
url: '/api/graphql',
|
|
35
39
|
headers: { host: 'localhost:3000' },
|
|
36
40
|
query: {
|
|
37
41
|
operationName,
|
|
@@ -165,3 +169,37 @@ describe('/api/graphql error status propagation', () => {
|
|
|
165
169
|
expect(res.status).toHaveBeenCalledWith(404)
|
|
166
170
|
})
|
|
167
171
|
})
|
|
172
|
+
|
|
173
|
+
describe('/api/graphql request handling', () => {
|
|
174
|
+
beforeEach(() => {
|
|
175
|
+
vi.clearAllMocks()
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
it.each(['PUT', 'DELETE', 'PATCH', 'OPTIONS'])(
|
|
179
|
+
'rejects %s with 405 without reaching the GraphQL layer',
|
|
180
|
+
async (method) => {
|
|
181
|
+
const res = createResponse()
|
|
182
|
+
await handler(createRequest(undefined, method), res)
|
|
183
|
+
|
|
184
|
+
expect(res.status).toHaveBeenCalledWith(405)
|
|
185
|
+
expect(mockedExecute).not.toHaveBeenCalled()
|
|
186
|
+
}
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
it.each([
|
|
190
|
+
['BadRequestError', () => new BadRequestError('malformed'), 400],
|
|
191
|
+
['UnauthorizedError', () => new UnauthorizedError('expired'), 401],
|
|
192
|
+
['an unexpected failure', () => new Error('socket hang up'), 500],
|
|
193
|
+
])(
|
|
194
|
+
'maps %s thrown by execute to its status',
|
|
195
|
+
async (_name, makeError, status) => {
|
|
196
|
+
mockedExecute.mockRejectedValue(makeError())
|
|
197
|
+
|
|
198
|
+
const res = createResponse()
|
|
199
|
+
await handler(createRequest(), res)
|
|
200
|
+
|
|
201
|
+
expect(res.status).toHaveBeenCalledWith(status)
|
|
202
|
+
expect(res.end).toHaveBeenCalled()
|
|
203
|
+
}
|
|
204
|
+
)
|
|
205
|
+
})
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { OTELAPI } from '@faststore/diagnostics'
|
|
2
|
+
import {
|
|
3
|
+
afterAll,
|
|
4
|
+
afterEach,
|
|
5
|
+
beforeEach,
|
|
6
|
+
describe,
|
|
7
|
+
expect,
|
|
8
|
+
it,
|
|
9
|
+
vi,
|
|
10
|
+
} from 'vitest'
|
|
11
|
+
|
|
12
|
+
import { execute } from '../../src/server'
|
|
13
|
+
import { apiOptions } from '../../src/server/options'
|
|
14
|
+
|
|
15
|
+
const span = {
|
|
16
|
+
end: vi.fn(),
|
|
17
|
+
setStatus: vi.fn(),
|
|
18
|
+
recordException: vi.fn(),
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const startSpan = vi.fn(() => span)
|
|
22
|
+
|
|
23
|
+
const otelEnabledByDefault = apiOptions.OTEL_ENABLED
|
|
24
|
+
|
|
25
|
+
// `__typename` resolves inside GraphQL itself, so these run the whole envelop
|
|
26
|
+
// pipeline without reaching the VTEX platform.
|
|
27
|
+
const runOperation = (query: string, operationName?: string) =>
|
|
28
|
+
execute({
|
|
29
|
+
operation: { __meta__: { operationName, operationHash: 'not-persisted' } },
|
|
30
|
+
variables: {},
|
|
31
|
+
query,
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
vi.clearAllMocks()
|
|
36
|
+
vi.spyOn(OTELAPI.trace, 'getTracer').mockReturnValue({ startSpan } as never)
|
|
37
|
+
apiOptions.OTEL_ENABLED = true
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
afterEach(() => {
|
|
41
|
+
vi.restoreAllMocks()
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
afterAll(() => {
|
|
45
|
+
apiOptions.OTEL_ENABLED = otelEnabledByDefault
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
describe('execute root span', () => {
|
|
49
|
+
it('wraps the operation in a span named after it', async () => {
|
|
50
|
+
const { data } = await runOperation(
|
|
51
|
+
'query RootSpanQuery { __typename }',
|
|
52
|
+
'RootSpanQuery'
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
expect(data).toEqual({ __typename: 'Query' })
|
|
56
|
+
expect(startSpan).toHaveBeenCalledWith('graphql RootSpanQuery')
|
|
57
|
+
expect(span.end).toHaveBeenCalledTimes(1)
|
|
58
|
+
expect(span.setStatus).not.toHaveBeenCalled()
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it('names the span generically when the operation is anonymous', async () => {
|
|
62
|
+
await runOperation('{ __typename }')
|
|
63
|
+
|
|
64
|
+
expect(startSpan).toHaveBeenCalledWith('graphql operation')
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('marks the span as failed and ends it when the operation throws', async () => {
|
|
68
|
+
await expect(
|
|
69
|
+
runOperation('this is not graphql', 'BrokenQuery')
|
|
70
|
+
).rejects.toThrow(/Syntax Error/)
|
|
71
|
+
|
|
72
|
+
expect(span.setStatus).toHaveBeenCalledWith({
|
|
73
|
+
code: OTELAPI.SpanStatusCode.ERROR,
|
|
74
|
+
})
|
|
75
|
+
expect(span.recordException).toHaveBeenCalledWith(expect.any(Error))
|
|
76
|
+
expect(span.end).toHaveBeenCalledTimes(1)
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('skips instrumentation entirely when telemetry is disabled', async () => {
|
|
80
|
+
apiOptions.OTEL_ENABLED = false
|
|
81
|
+
|
|
82
|
+
const { data } = await runOperation(
|
|
83
|
+
'query RootSpanQuery { __typename }',
|
|
84
|
+
'RootSpanQuery'
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
expect(data).toEqual({ __typename: 'Query' })
|
|
88
|
+
expect(startSpan).not.toHaveBeenCalled()
|
|
89
|
+
})
|
|
90
|
+
})
|