@faststore/core 3.99.0-dev.2 → 3.99.0-dev.5
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/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +38 -38
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/cache/config.json +3 -3
- package/.next/cache/webpack/client-production/0.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/prerender-manifest.js +1 -1
- package/.next/prerender-manifest.json +1 -1
- package/.next/react-loadable-manifest.json +6 -6
- package/.next/routes-manifest.json +1 -1
- package/.next/server/chunks/1741.js +2 -2
- package/.next/server/chunks/5133.js +1 -1
- package/.next/server/chunks/5212.js +1 -1
- package/.next/server/chunks/7121.js +1 -1
- package/.next/server/chunks/8971.js +5 -4
- package/.next/server/functions-config-manifest.json +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/api/graphql.js +3 -3
- package/.next/server/pages/en-US/404.html +2 -2
- package/.next/server/pages/en-US/500.html +2 -2
- package/.next/server/pages/en-US/checkout.html +2 -2
- package/.next/server/pages/en-US/login.html +2 -2
- package/.next/server/pages/en-US/s.html +2 -2
- package/.next/server/pages/en-US.html +2 -2
- package/.next/server/pages/pvt/account/403.js +1 -1
- package/.next/server/pages-manifest.json +1 -1
- package/.next/static/{OZ8Lk7JM4bzozJAoz6cqt → T_jYtdcAXYxkLOxLasDa4}/_buildManifest.js +1 -1
- package/.next/static/chunks/2221-3b8af0bc108994c0.js +2 -0
- package/.next/static/chunks/{2927.5a79877943a6bf7c.js → 2927.23bae2c79f0ac0f3.js} +1 -1
- package/.next/static/chunks/{UIToast.19a8664c01a00d3a.js → UIToast.de15325248043ce5.js} +1 -1
- package/.next/static/chunks/pages/_app-ec4b3e60344d1bab.js +1 -0
- package/.next/static/chunks/pages/pvt/account/{403-d44b70591d2c86dc.js → 403-f3cb4fbbbb801a00.js} +1 -1
- package/.next/static/chunks/{webpack-fc37ce1526507eaf.js → webpack-da79ff7bed51ca28.js} +1 -1
- package/.next/trace +143 -142
- package/.turbo/turbo-build.log +16 -16
- package/.turbo/turbo-test.log +11 -9
- package/@generated/gql.ts +2 -2
- package/@generated/graphql.ts +6 -1
- package/@generated/persisted-documents.json +1 -1
- package/@generated/schema.graphql +2 -0
- package/CHANGELOG.md +19 -0
- package/discovery.config.default.js +1 -0
- package/package.json +7 -7
- package/src/components/account/MyAccountDrawer/OrganizationDrawer/useReloadAfterLogoutReturn.ts +6 -1
- package/src/pages/api/graphql.ts +10 -22
- package/src/sdk/account/useRefreshToken.ts +3 -14
- package/src/sdk/cart/index.ts +12 -2
- package/src/sdk/session/index.ts +106 -59
- package/src/sdk/session/storageKeys.ts +2 -0
- package/src/sdk/useStore.ts +7 -1
- package/src/utils/validateSessionRefreshToken.ts +29 -0
- package/test/utils/validateSessionRefreshToken.test.ts +69 -0
- package/.next/static/chunks/2221-b085ff74b21a2c2c.js +0 -2
- package/.next/static/chunks/pages/_app-be3fecd37c6b273c.js +0 -1
- /package/.next/static/{OZ8Lk7JM4bzozJAoz6cqt → T_jYtdcAXYxkLOxLasDa4}/_ssgManifest.js +0 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
|
|
2
|
-
> @faststore/core@3.99.0-dev.
|
|
2
|
+
> @faststore/core@3.99.0-dev.4 prebuild /home/runner/work/faststore/faststore/packages/core
|
|
3
3
|
> na run partytown && na run generate
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @faststore/core@3.99.0-dev.
|
|
6
|
+
> @faststore/core@3.99.0-dev.4 partytown /home/runner/work/faststore/faststore/packages/core
|
|
7
7
|
> partytown copylib ./public/~partytown
|
|
8
8
|
|
|
9
9
|
Partytown lib copied to: /home/runner/work/faststore/faststore/packages/core/public/~partytown
|
|
10
10
|
|
|
11
|
-
> @faststore/core@3.99.0-dev.
|
|
11
|
+
> @faststore/core@3.99.0-dev.4 generate /home/runner/work/faststore/faststore/packages/core
|
|
12
12
|
> na run generate:schema && na run generate:codegen && na run format:generated
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
> @faststore/core@3.99.0-dev.
|
|
15
|
+
> @faststore/core@3.99.0-dev.4 generate:schema /home/runner/work/faststore/faststore/packages/core
|
|
16
16
|
> tsx src/server/generator/generateGraphQLSchemaFile.ts
|
|
17
17
|
|
|
18
18
|
Schema GraphQL file generated successfully
|
|
19
19
|
|
|
20
|
-
> @faststore/core@3.99.0-dev.
|
|
20
|
+
> @faststore/core@3.99.0-dev.4 generate:codegen /home/runner/work/faststore/faststore/packages/core
|
|
21
21
|
> graphql-codegen
|
|
22
22
|
|
|
23
23
|
[STARTED] Parse Configuration
|
|
@@ -37,11 +37,11 @@ Running lifecycle hook "afterStart" scripts...
|
|
|
37
37
|
[CLI] Loading Documents
|
|
38
38
|
[CLI] Generating output
|
|
39
39
|
|
|
40
|
-
> @faststore/core@3.99.0-dev.
|
|
40
|
+
> @faststore/core@3.99.0-dev.4 format:generated /home/runner/work/faststore/faststore/packages/core
|
|
41
41
|
> prettier --write "@generated/**/*.{ts,js,tsx,jsx,json}" --loglevel error
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
> @faststore/core@3.99.0-dev.
|
|
44
|
+
> @faststore/core@3.99.0-dev.4 build /home/runner/work/faststore/faststore/packages/core
|
|
45
45
|
> next build
|
|
46
46
|
|
|
47
47
|
⚠ No build cache found. Please configure build caching for faster rebuilds. Read more: https://nextjs.org/docs/messages/no-cache
|
|
@@ -59,23 +59,23 @@ https://nextjs.org/telemetry
|
|
|
59
59
|
Collecting page data ...
|
|
60
60
|
Generating static pages (0/6) ...
|
|
61
61
|
|
|
62
62
|
Generating static pages (1/6)
|
|
63
|
-
|
|
64
63
|
Generating static pages (2/6)
|
|
65
64
|
Warning: Dynamic Content not found for the page: home. Refer to the Dynamic Content documentation at https://developers.vtex.com/docs/guides/faststore/dynamic-content-overview for mapping the page and the corresponding data-fetching function.
|
|
65
|
+
|
|
66
66
|
Generating static pages (2/6)
|
|
67
67
|
|
|
68
68
|
Generating static pages (4/6)
|
|
69
69
|
|
|
70
70
|
✓ Generating static pages (6/6)
|
|
71
71
|
Finalizing page optimization ...
|
|
72
72
|
Collecting build traces ...
|
|
73
73
|
|
|
74
74
|
Route (pages) Size First Load JS
|
|
75
|
-
┌ ● / 7.39 kB
|
|
75
|
+
┌ ● / 7.39 kB 166 kB
|
|
76
76
|
├ └ css/02259c549b2179f2.css 3.1 kB
|
|
77
77
|
├ /_app 0 B 109 kB
|
|
78
78
|
├ ● /[...slug] 2.55 kB 175 kB
|
|
79
|
-
├ ● /[slug]/p 97.3 kB
|
|
79
|
+
├ ● /[slug]/p 97.3 kB 256 kB
|
|
80
80
|
├ ├ css/e68c313e4ce2fd1b.css 6.34 kB
|
|
81
81
|
├ └ css/9b4c21dcd3bc4a17.css 16.7 kB
|
|
82
|
-
├ ○ /404 1.58 kB
|
|
83
|
-
├ ● /500 1.57 kB
|
|
82
|
+
├ ○ /404 1.58 kB 160 kB
|
|
83
|
+
├ ● /500 1.57 kB 160 kB
|
|
84
84
|
├ λ /api/fs/logout 0 B 109 kB
|
|
85
85
|
├ λ /api/graphql 0 B 109 kB
|
|
86
86
|
├ λ /api/health/live 0 B 109 kB
|
|
@@ -85,13 +85,13 @@ Route (pages) Size First Load JS
|
|
|
85
85
|
├ ● /login 1.7 kB 160 kB
|
|
86
86
|
├ λ /pvt/account 245 B 109 kB
|
|
87
87
|
├ ● /pvt/account/[...unknown] 286 B 109 kB
|
|
88
|
-
├ λ /pvt/account/403 2.
|
|
88
|
+
├ λ /pvt/account/403 2.98 kB 161 kB
|
|
89
89
|
├ └ css/094ad5cc00c74e64.css 4.82 kB
|
|
90
90
|
├ λ /pvt/account/404 2.18 kB 160 kB
|
|
91
91
|
├ └ css/72f154a00f1cf621.css 4.88 kB
|
|
92
92
|
├ λ /pvt/account/orders 9.89 kB 168 kB
|
|
93
93
|
├ └ css/4b2af1aaeb961465.css 14.4 kB
|
|
94
|
-
├ λ /pvt/account/orders/[id] 13.6 kB
|
|
94
|
+
├ λ /pvt/account/orders/[id] 13.6 kB 172 kB
|
|
95
95
|
├ └ css/482e6fa149885bc2.css 13.9 kB
|
|
96
96
|
├ λ /pvt/account/profile 1.99 kB 160 kB
|
|
97
97
|
├ └ css/5cd37b7508dd5190.css 4.56 kB
|
|
@@ -103,8 +103,8 @@ Route (pages) Size First Load JS
|
|
|
103
103
|
+ First Load JS shared by all 118 kB
|
|
104
104
|
├ chunks/framework-d514426edf885c68.js 45.4 kB
|
|
105
105
|
├ chunks/main-edeb2c6a5c48bb3f.js 33.2 kB
|
|
106
|
-
├ chunks/pages/_app-
|
|
107
|
-
├ chunks/webpack-
|
|
106
|
+
├ chunks/pages/_app-ec4b3e60344d1bab.js 26.6 kB
|
|
107
|
+
├ chunks/webpack-da79ff7bed51ca28.js 3.88 kB
|
|
108
108
|
└ css/8a513f4b536b0ab0.css 9.18 kB
|
|
109
109
|
|
|
110
110
|
λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
|
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
|
|
2
|
-
> @faststore/core@3.99.0-dev.
|
|
2
|
+
> @faststore/core@3.99.0-dev.4 test /home/runner/work/faststore/faststore/packages/core
|
|
3
3
|
> jest
|
|
4
4
|
|
|
5
|
-
PASS test/utils/multipleTemplates.test.ts (
|
|
6
|
-
PASS test/utils/clearCookies.test.ts (
|
|
7
|
-
PASS test/utils/cookieCacheBusting.test.ts (15.452 s)
|
|
5
|
+
PASS test/utils/multipleTemplates.test.ts (11.101 s)
|
|
6
|
+
PASS test/utils/clearCookies.test.ts (10.671 s)
|
|
8
7
|
PASS test/server/cms/global.test.ts
|
|
9
|
-
PASS test/
|
|
10
|
-
PASS test/
|
|
8
|
+
PASS test/utils/cookieCacheBusting.test.ts (14.531 s)
|
|
9
|
+
PASS test/utils/validateSessionRefreshToken.test.ts
|
|
10
|
+
PASS test/server/cms/index.test.ts (6.215 s)
|
|
11
|
+
PASS test/server/index.test.ts (12.984 s)
|
|
12
|
+
A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --detectOpenHandles to find leaks. Active timers can also cause this, ensure that .unref() was called on them.
|
|
11
13
|
|
|
12
|
-
Test Suites:
|
|
13
|
-
Tests:
|
|
14
|
+
Test Suites: 7 passed, 7 total
|
|
15
|
+
Tests: 58 passed, 58 total
|
|
14
16
|
Snapshots: 0 total
|
|
15
|
-
Time:
|
|
17
|
+
Time: 25.438 s
|
|
16
18
|
Ran all test suites.
|
package/@generated/gql.ts
CHANGED
|
@@ -62,7 +62,7 @@ const documents = {
|
|
|
62
62
|
types.ProcessOrderAuthorizationMutationDocument,
|
|
63
63
|
'\n query ValidateUser {\n validateUser {\n isValid\n }\n }\n':
|
|
64
64
|
types.ValidateUserDocument,
|
|
65
|
-
'\n mutation ValidateCartMutation($cart: IStoreCart!, $session: IStoreSession!) {\n validateCart(cart: $cart, session: $session) {\n order {\n orderNumber\n acceptedOffer {\n ...CartItem\n }\n shouldSplitItem\n }\n messages {\n ...CartMessage\n }\n }\n }\n\n fragment CartMessage on StoreCartMessage {\n text\n status\n }\n\n fragment CartItem on StoreOffer {\n seller {\n identifier\n }\n quantity\n price\n priceWithTaxes\n listPrice\n listPriceWithTaxes\n itemOffered {\n ...CartProductItem\n }\n }\n\n fragment CartProductItem on StoreProduct {\n sku\n name\n unitMultiplier\n image {\n url\n alternateName\n }\n brand {\n name\n }\n isVariantOf {\n productGroupID\n name\n skuVariants {\n activeVariations\n slugsMap\n availableVariations\n }\n }\n gtin\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n }\n':
|
|
65
|
+
'\n mutation ValidateCartMutation($cart: IStoreCart!, $session: IStoreSession!) {\n validateCart(cart: $cart, session: $session) {\n order {\n orderNumber\n acceptedOffer {\n ...CartItem\n }\n shouldSplitItem\n }\n messages {\n ...CartMessage\n }\n }\n }\n\n fragment CartMessage on StoreCartMessage {\n text\n status\n }\n\n fragment CartItem on StoreOffer {\n seller {\n identifier\n }\n quantity\n price\n priceWithTaxes\n listPrice\n listPriceWithTaxes\n isGift\n itemOffered {\n ...CartProductItem\n }\n }\n\n fragment CartProductItem on StoreProduct {\n sku\n name\n unitMultiplier\n image {\n url\n alternateName\n }\n brand {\n name\n }\n isVariantOf {\n productGroupID\n name\n skuVariants {\n activeVariations\n slugsMap\n availableVariations\n }\n }\n gtin\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n }\n':
|
|
66
66
|
types.ValidateCartMutationDocument,
|
|
67
67
|
'\n query ClientPickupPointsQuery(\n $geoCoordinates: IStoreGeoCoordinates\n ) {\n pickupPoints(geoCoordinates: $geoCoordinates) {\n pickupPointDistances {\n pickupId\n distance\n pickupName\n isActive\n address {\n city\n state\n number\n postalCode\n street\n }\n }\n }\n }\n':
|
|
68
68
|
types.ClientPickupPointsQueryDocument,
|
|
@@ -250,7 +250,7 @@ export function gql(
|
|
|
250
250
|
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
251
251
|
*/
|
|
252
252
|
export function gql(
|
|
253
|
-
source: '\n mutation ValidateCartMutation($cart: IStoreCart!, $session: IStoreSession!) {\n validateCart(cart: $cart, session: $session) {\n order {\n orderNumber\n acceptedOffer {\n ...CartItem\n }\n shouldSplitItem\n }\n messages {\n ...CartMessage\n }\n }\n }\n\n fragment CartMessage on StoreCartMessage {\n text\n status\n }\n\n fragment CartItem on StoreOffer {\n seller {\n identifier\n }\n quantity\n price\n priceWithTaxes\n listPrice\n listPriceWithTaxes\n itemOffered {\n ...CartProductItem\n }\n }\n\n fragment CartProductItem on StoreProduct {\n sku\n name\n unitMultiplier\n image {\n url\n alternateName\n }\n brand {\n name\n }\n isVariantOf {\n productGroupID\n name\n skuVariants {\n activeVariations\n slugsMap\n availableVariations\n }\n }\n gtin\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n }\n'
|
|
253
|
+
source: '\n mutation ValidateCartMutation($cart: IStoreCart!, $session: IStoreSession!) {\n validateCart(cart: $cart, session: $session) {\n order {\n orderNumber\n acceptedOffer {\n ...CartItem\n }\n shouldSplitItem\n }\n messages {\n ...CartMessage\n }\n }\n }\n\n fragment CartMessage on StoreCartMessage {\n text\n status\n }\n\n fragment CartItem on StoreOffer {\n seller {\n identifier\n }\n quantity\n price\n priceWithTaxes\n listPrice\n listPriceWithTaxes\n isGift\n itemOffered {\n ...CartProductItem\n }\n }\n\n fragment CartProductItem on StoreProduct {\n sku\n name\n unitMultiplier\n image {\n url\n alternateName\n }\n brand {\n name\n }\n isVariantOf {\n productGroupID\n name\n skuVariants {\n activeVariations\n slugsMap\n availableVariations\n }\n }\n gtin\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n }\n'
|
|
254
254
|
): typeof import('./graphql').ValidateCartMutationDocument
|
|
255
255
|
/**
|
|
256
256
|
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
package/@generated/graphql.ts
CHANGED
|
@@ -1348,6 +1348,8 @@ export type StoreMarketingData = {
|
|
|
1348
1348
|
export type StoreOffer = {
|
|
1349
1349
|
/** Offer item availability. */
|
|
1350
1350
|
availability: Scalars['String']['output']
|
|
1351
|
+
/** Whether this offer is a gift (e.g. free promotional item). */
|
|
1352
|
+
isGift: Maybe<Scalars['Boolean']['output']>
|
|
1351
1353
|
/** Offer item condition. */
|
|
1352
1354
|
itemCondition: Scalars['String']['output']
|
|
1353
1355
|
/** Information on the item being offered. */
|
|
@@ -3143,6 +3145,7 @@ export type ValidateCartMutationMutation = {
|
|
|
3143
3145
|
priceWithTaxes: number
|
|
3144
3146
|
listPrice: number
|
|
3145
3147
|
listPriceWithTaxes: number
|
|
3148
|
+
isGift: boolean | null
|
|
3146
3149
|
seller: { identifier: string }
|
|
3147
3150
|
itemOffered: {
|
|
3148
3151
|
sku: string
|
|
@@ -3181,6 +3184,7 @@ export type CartItemFragment = {
|
|
|
3181
3184
|
priceWithTaxes: number
|
|
3182
3185
|
listPrice: number
|
|
3183
3186
|
listPriceWithTaxes: number
|
|
3187
|
+
isGift: boolean | null
|
|
3184
3188
|
seller: { identifier: string }
|
|
3185
3189
|
itemOffered: {
|
|
3186
3190
|
sku: string
|
|
@@ -4390,6 +4394,7 @@ export const CartItemFragmentDoc = new TypedDocumentString(
|
|
|
4390
4394
|
priceWithTaxes
|
|
4391
4395
|
listPrice
|
|
4392
4396
|
listPriceWithTaxes
|
|
4397
|
+
isGift
|
|
4393
4398
|
itemOffered {
|
|
4394
4399
|
...CartProductItem
|
|
4395
4400
|
}
|
|
@@ -4536,7 +4541,7 @@ export const ValidateUserDocument = {
|
|
|
4536
4541
|
export const ValidateCartMutationDocument = {
|
|
4537
4542
|
__meta__: {
|
|
4538
4543
|
operationName: 'ValidateCartMutation',
|
|
4539
|
-
operationHash: '
|
|
4544
|
+
operationHash: '32c15f8888ca34f223def7972b7f19090808435a',
|
|
4540
4545
|
},
|
|
4541
4546
|
} as unknown as TypedDocumentString<
|
|
4542
4547
|
ValidateCartMutationMutation,
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"e2b06da6840614d3c72768e56579b9d3b8e80802": "mutation CancelOrderMutation($data: IUserOrderCancel!) { cancelOrder(data: $data) { data } }",
|
|
11
11
|
"8c25d37c8d6e7c20ab21bb8a4f4e6a2fe320ea8d": "mutation ProcessOrderAuthorizationMutation($data: IProcessOrderAuthorization!) { processOrderAuthorization(data: $data) { isPendingForOtherAuthorizer ruleForAuthorization { dimensionId orderAuthorizationId rule { authorizationData { authorizers { authorizationDate email id type } requireAllApprovals } authorizedEmails doId id isUserAuthorized isUserNextAuthorizer name notification priority scoreInterval { accept deny } status timeout trigger { condition { conditionType description expression greatherThan lessThan } effect { description effectType funcPath } } } } } }",
|
|
12
12
|
"32f99c73c3de958b64d6bece1afe800469f54548": "query ValidateUser { validateUser { isValid } }",
|
|
13
|
-
"
|
|
13
|
+
"32c15f8888ca34f223def7972b7f19090808435a": "fragment CartItem on StoreOffer { isGift itemOffered { ...CartProductItem } listPrice listPriceWithTaxes price priceWithTaxes quantity seller { identifier } } fragment CartMessage on StoreCartMessage { status text } fragment CartProductItem on StoreProduct { additionalProperty { name propertyID value valueReference } brand { name } gtin image { alternateName url } isVariantOf { name productGroupID skuVariants { activeVariations availableVariations slugsMap } } name sku unitMultiplier } mutation ValidateCartMutation($cart: IStoreCart!, $session: IStoreSession!) { validateCart(cart: $cart, session: $session) { messages { ...CartMessage } order { acceptedOffer { ...CartItem } orderNumber shouldSplitItem } } }",
|
|
14
14
|
"3fa04e88c811fcb5ece7206fd5aa745bdbc143a8": "query ClientPickupPointsQuery($geoCoordinates: IStoreGeoCoordinates) { pickupPoints(geoCoordinates: $geoCoordinates) { pickupPointDistances { address { city number postalCode state street } distance isActive pickupId pickupName } } }",
|
|
15
15
|
"feb7005103a859e2bc8cf2360d568806fd88deba": "mutation SubscribeToNewsletter($data: IPersonNewsletter!) { subscribeToNewsletter(data: $data) { id } }",
|
|
16
16
|
"dc912e7272e3d9f5ced206837df87f544d39d0a5": "query ClientProductCountQuery($term: String) { productCount(term: $term) { total } }",
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
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
|
+
# 3.99.0-dev.5 (2026-05-04)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- Enhance session validation logic to skip token refresh in local … ([#3285](https://github.com/vtex/faststore/issues/3285)) ([41a330a](https://github.com/vtex/faststore/commit/41a330a9704a29369141e6e78b1f6d01e5a2e1a5))
|
|
11
|
+
|
|
12
|
+
# 3.99.0-dev.4 (2026-04-28)
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
- Refactor token refresh logic in GraphQL API handler - SFS-3104 ([#3263](https://github.com/vtex/faststore/issues/3263)) ([695ab6a](https://github.com/vtex/faststore/commit/695ab6a9413eb53ef457cfc890c74e41c29c1ab8))
|
|
17
|
+
|
|
18
|
+
# 3.99.0-dev.3 (2026-04-23)
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
- add isGift field to StoreOffer type and resolvers - SFS-3040 ([#3220](https://github.com/vtex/faststore/issues/3220)) ([e10fc92](https://github.com/vtex/faststore/commit/e10fc92633a5296a5b03286028d31d9c280561c6))
|
|
23
|
+
- Enhance session management with logout - SFS-3105 ([#3268](https://github.com/vtex/faststore/issues/3268)) ([9468e32](https://github.com/vtex/faststore/commit/9468e32a3531ca3c91c7f82a34ac1c750c6a26ef))
|
|
24
|
+
|
|
6
25
|
# [3.99.0-dev.2](https://github.com/vtex/faststore/compare/v3.99.0-dev.1...v3.99.0-dev.2) (2026-04-21)
|
|
7
26
|
|
|
8
27
|
**Note:** Version bump only for package @faststore/core
|
|
@@ -148,6 +148,7 @@ module.exports = {
|
|
|
148
148
|
enableRedirects: false,
|
|
149
149
|
enableSearchSSR: false,
|
|
150
150
|
enableFaststoreMyAccount: false,
|
|
151
|
+
useIsGiftFromOrderForm: false,
|
|
151
152
|
graphqlCacheControl: {
|
|
152
153
|
maxAge: 0, // 0 disables cache, 5 * 60 enable cache control maxAge 5 minutes
|
|
153
154
|
staleWhileRevalidate: 60 * 60, // 1 hour
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faststore/core",
|
|
3
|
-
"version": "3.99.0-dev.
|
|
3
|
+
"version": "3.99.0-dev.5",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
"@envelop/graphql-jit": "^8.0.3",
|
|
52
52
|
"@envelop/parser-cache": "^6.0.2",
|
|
53
53
|
"@envelop/validation-cache": "^6.0.2",
|
|
54
|
-
"@faststore/api": "3.
|
|
55
|
-
"@faststore/graphql-utils": "^3.
|
|
56
|
-
"@faststore/lighthouse": "3.
|
|
57
|
-
"@faststore/sdk": "3.99.0-dev.
|
|
58
|
-
"@faststore/ui": "3.99.0-dev.
|
|
54
|
+
"@faststore/api": "3.99.0-dev.5",
|
|
55
|
+
"@faststore/graphql-utils": "^3.99.0-dev.5",
|
|
56
|
+
"@faststore/lighthouse": "3.99.0-dev.5",
|
|
57
|
+
"@faststore/sdk": "3.99.0-dev.5",
|
|
58
|
+
"@faststore/ui": "3.99.0-dev.5",
|
|
59
59
|
"@graphql-codegen/cli": "5.0.2",
|
|
60
60
|
"@graphql-codegen/client-preset": "4.2.6",
|
|
61
61
|
"@graphql-codegen/typescript": "4.0.7",
|
|
@@ -124,5 +124,5 @@
|
|
|
124
124
|
"ts-jest": "29.1.1",
|
|
125
125
|
"typescript": "5.3.2"
|
|
126
126
|
},
|
|
127
|
-
"gitHead": "
|
|
127
|
+
"gitHead": "aae7a4fc1fe2b819b410d400f8b2ea70fedcdcfe"
|
|
128
128
|
}
|
package/src/components/account/MyAccountDrawer/OrganizationDrawer/useReloadAfterLogoutReturn.ts
CHANGED
|
@@ -12,7 +12,10 @@ import { useEffect } from 'react'
|
|
|
12
12
|
* We handle both: check the flag on mount (fresh load) and on pageshow (bfcache).
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
import {
|
|
16
|
+
RELOAD_AFTER_LOGOUT_KEY,
|
|
17
|
+
SESSION_READY_KEY,
|
|
18
|
+
} from '../../../../sdk/session/storageKeys'
|
|
16
19
|
|
|
17
20
|
/**
|
|
18
21
|
* Call before redirecting to logout. When the user returns to the store, the app
|
|
@@ -43,6 +46,8 @@ const checkAndReloadIfReturnedFromLogout = (): void => {
|
|
|
43
46
|
try {
|
|
44
47
|
if (sessionStorage.getItem(RELOAD_AFTER_LOGOUT_KEY)) {
|
|
45
48
|
sessionStorage.removeItem(RELOAD_AFTER_LOGOUT_KEY)
|
|
49
|
+
// Pre-set session ready so the reloaded page starts without a skeleton.
|
|
50
|
+
sessionStorage.setItem(SESSION_READY_KEY, 'true')
|
|
46
51
|
setTimeout(forceRefreshWithoutCache, RELOAD_DELAY_MS)
|
|
47
52
|
}
|
|
48
53
|
} catch {
|
package/src/pages/api/graphql.ts
CHANGED
|
@@ -8,7 +8,8 @@ import { parse } from 'cookie'
|
|
|
8
8
|
import type { NextApiHandler, NextApiRequest } from 'next'
|
|
9
9
|
|
|
10
10
|
import discoveryConfig from 'discovery.config'
|
|
11
|
-
import { getJWTAutCookie
|
|
11
|
+
import { getJWTAutCookie } from 'src/utils/getCookie'
|
|
12
|
+
import { shouldForceRefreshTokenForValidateSession } from 'src/utils/validateSessionRefreshToken'
|
|
12
13
|
import { execute } from '../../server'
|
|
13
14
|
|
|
14
15
|
const DEFAULT_MAX_AGE = 5 * 60 // 5 minutes
|
|
@@ -160,7 +161,11 @@ const handler: NextApiHandler = async (request, response) => {
|
|
|
160
161
|
// value is used to cache bust the request if there is a VtexIdclientAutCookie
|
|
161
162
|
const { operation, variables, query, v: value } = parseRequest(request)
|
|
162
163
|
|
|
164
|
+
const hostname = request.headers.host?.split(':')[0]
|
|
165
|
+
const isLocal = hostname === 'localhost' || hostname === '127.0.0.1'
|
|
166
|
+
|
|
163
167
|
if (
|
|
168
|
+
!isLocal &&
|
|
164
169
|
operation.__meta__.operationName === 'ValidateSession' &&
|
|
165
170
|
discoveryConfig.experimental?.refreshToken
|
|
166
171
|
) {
|
|
@@ -169,27 +174,10 @@ const handler: NextApiHandler = async (request, response) => {
|
|
|
169
174
|
account: discoveryConfig.api.storeId,
|
|
170
175
|
})
|
|
171
176
|
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
const refreshAfterExpired =
|
|
177
|
-
refreshAfterExist && isExpired(Number(variables.session.refreshAfter))
|
|
178
|
-
|
|
179
|
-
const tokenExistAndIsFirstRefreshTokenRequest =
|
|
180
|
-
!!jwt && !refreshAfterExist
|
|
181
|
-
|
|
182
|
-
// when token expired, browser clears the cookie, but we still have the refreshAfter in session and the refresh token cookie
|
|
183
|
-
const tokenNotExistAndRefreshAfterExistAndIsExpired =
|
|
184
|
-
!jwt && !!refreshAfterExist && refreshAfterExpired
|
|
185
|
-
|
|
186
|
-
const tokenExpiredAndRefreshAfterIsNullOrExpired =
|
|
187
|
-
tokenExpired && (!refreshAfterExist || refreshAfterExpired)
|
|
188
|
-
|
|
189
|
-
const shouldRefreshToken =
|
|
190
|
-
tokenExistAndIsFirstRefreshTokenRequest ||
|
|
191
|
-
tokenNotExistAndRefreshAfterExistAndIsExpired ||
|
|
192
|
-
tokenExpiredAndRefreshAfterIsNullOrExpired
|
|
177
|
+
const shouldRefreshToken = shouldForceRefreshTokenForValidateSession({
|
|
178
|
+
jwt,
|
|
179
|
+
sessionRefreshAfter: variables?.session?.refreshAfter,
|
|
180
|
+
})
|
|
193
181
|
|
|
194
182
|
if (shouldRefreshToken) {
|
|
195
183
|
throw new UnauthorizedError(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react'
|
|
2
|
-
import { sessionStore } from '../session'
|
|
2
|
+
import { logoutAndClearSession, sessionStore } from '../session'
|
|
3
3
|
import { isRefreshTokenSuccessful, refreshTokenRequest } from './refreshToken'
|
|
4
4
|
|
|
5
5
|
export const useRefreshToken = (
|
|
@@ -37,23 +37,12 @@ export const useRefreshToken = (
|
|
|
37
37
|
url.searchParams.set('_refresh', Date.now().toString())
|
|
38
38
|
window.location.href = url.toString()
|
|
39
39
|
} else {
|
|
40
|
-
|
|
41
|
-
sessionStore.set({
|
|
42
|
-
...currentSession,
|
|
43
|
-
refreshAfter: String(Math.floor(Date.now() / 1000) + 1 * 60 * 60), // now + 1 hour
|
|
44
|
-
})
|
|
45
|
-
|
|
40
|
+
await logoutAndClearSession(currentSession)
|
|
46
41
|
setShouldShow403(true)
|
|
47
42
|
}
|
|
48
43
|
} catch (error) {
|
|
49
44
|
console.error('Error during refresh token process:', error)
|
|
50
|
-
|
|
51
|
-
// Set refreshAfter to postpone future requests and redirect to login
|
|
52
|
-
sessionStore.set({
|
|
53
|
-
...currentSession,
|
|
54
|
-
refreshAfter: String(Math.floor(Date.now() / 1000) + 1 * 60 * 60), // now + 1 hour
|
|
55
|
-
})
|
|
56
|
-
|
|
45
|
+
await logoutAndClearSession(currentSession)
|
|
57
46
|
setShouldShow403(true)
|
|
58
47
|
}
|
|
59
48
|
}
|
package/src/sdk/cart/index.ts
CHANGED
|
@@ -16,7 +16,11 @@ import { request } from '../graphql/request'
|
|
|
16
16
|
import { sessionStore } from '../session'
|
|
17
17
|
import { createValidationStore, useStore } from '../useStore'
|
|
18
18
|
|
|
19
|
-
export interface CartItem
|
|
19
|
+
export interface CartItem
|
|
20
|
+
extends SDKCartItem,
|
|
21
|
+
Omit<CartItemFragment, 'isGift'> {
|
|
22
|
+
isGift?: boolean | null
|
|
23
|
+
}
|
|
20
24
|
|
|
21
25
|
export interface Cart extends SDKCart<CartItem> {
|
|
22
26
|
messages?: CartMessageFragment[]
|
|
@@ -53,6 +57,7 @@ export const ValidateCartMutation = gql(`
|
|
|
53
57
|
priceWithTaxes
|
|
54
58
|
listPrice
|
|
55
59
|
listPriceWithTaxes
|
|
60
|
+
isGift
|
|
56
61
|
itemOffered {
|
|
57
62
|
...CartProductItem
|
|
58
63
|
}
|
|
@@ -88,7 +93,12 @@ export const ValidateCartMutation = gql(`
|
|
|
88
93
|
}
|
|
89
94
|
`)
|
|
90
95
|
|
|
91
|
-
const isGift = (item: CartItem) =>
|
|
96
|
+
const isGift = (item: CartItem) => {
|
|
97
|
+
if (storeConfig.experimental?.useIsGiftFromOrderForm) {
|
|
98
|
+
return item?.isGift ?? false
|
|
99
|
+
}
|
|
100
|
+
return item.price === 0
|
|
101
|
+
}
|
|
92
102
|
|
|
93
103
|
const getItemId = (item: Pick<CartItem, 'itemOffered' | 'seller' | 'price'>) =>
|
|
94
104
|
[
|