@faststore/core 3.100.3 → 3.100.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +22 -22
  3. package/.next/cache/.tsbuildinfo +1 -1
  4. package/.next/cache/config.json +3 -3
  5. package/.next/cache/webpack/client-production/0.pack +0 -0
  6. package/.next/cache/webpack/client-production/index.pack +0 -0
  7. package/.next/cache/webpack/edge-server-production/0.pack +0 -0
  8. package/.next/cache/webpack/edge-server-production/index.pack +0 -0
  9. package/.next/cache/webpack/server-production/0.pack +0 -0
  10. package/.next/cache/webpack/server-production/index.pack +0 -0
  11. package/.next/prerender-manifest.js +1 -1
  12. package/.next/prerender-manifest.json +1 -1
  13. package/.next/react-loadable-manifest.json +6 -6
  14. package/.next/routes-manifest.json +1 -1
  15. package/.next/server/chunks/7098.js +2 -2
  16. package/.next/server/functions-config-manifest.json +1 -1
  17. package/.next/server/middleware-build-manifest.js +1 -1
  18. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  19. package/.next/server/pages/en-US/404.html +2 -2
  20. package/.next/server/pages/en-US/500.html +2 -2
  21. package/.next/server/pages/en-US/checkout.html +2 -2
  22. package/.next/server/pages/en-US/login.html +2 -2
  23. package/.next/server/pages/en-US/password-protection.html +2 -2
  24. package/.next/server/pages/en-US/s.html +2 -2
  25. package/.next/server/pages/en-US.html +2 -2
  26. package/.next/server/pages-manifest.json +1 -1
  27. package/.next/static/chunks/{2927.5a79877943a6bf7c.js → 2927.23bae2c79f0ac0f3.js} +1 -1
  28. package/.next/static/chunks/{UIToast.19a8664c01a00d3a.js → UIToast.de15325248043ce5.js} +1 -1
  29. package/.next/static/chunks/{webpack-25c67512e1907efd.js → webpack-6a844a3f6a390f62.js} +1 -1
  30. package/.next/trace +156 -156
  31. package/.turbo/turbo-build.log +12 -12
  32. package/.turbo/turbo-test.log +11 -10
  33. package/CHANGELOG.md +6 -0
  34. package/package.json +2 -2
  35. package/src/sdk/redirects/index.ts +20 -2
  36. package/test/sdk/redirects/index.test.ts +134 -0
  37. /package/.next/static/{0OKcQtIHO8diwBsczup15 → s20QxDT2pZcGbsFUk-djq}/_buildManifest.js +0 -0
  38. /package/.next/static/{0OKcQtIHO8diwBsczup15 → s20QxDT2pZcGbsFUk-djq}/_ssgManifest.js +0 -0
@@ -1,23 +1,23 @@
1
1
 
2
- > @faststore/core@3.100.2 prebuild /home/runner/work/faststore/faststore/packages/core
2
+ > @faststore/core@3.100.3 prebuild /home/runner/work/faststore/faststore/packages/core
3
3
  > na run partytown && na run generate
4
4
 
5
5
 
6
- > @faststore/core@3.100.2 partytown /home/runner/work/faststore/faststore/packages/core
6
+ > @faststore/core@3.100.3 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.100.2 generate /home/runner/work/faststore/faststore/packages/core
11
+ > @faststore/core@3.100.3 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.100.2 generate:schema /home/runner/work/faststore/faststore/packages/core
15
+ > @faststore/core@3.100.3 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.100.2 generate:codegen /home/runner/work/faststore/faststore/packages/core
20
+ > @faststore/core@3.100.3 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.100.2 format:generated /home/runner/work/faststore/faststore/packages/core
40
+ > @faststore/core@3.100.3 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.100.2 build /home/runner/work/faststore/faststore/packages/core
44
+ > @faststore/core@3.100.3 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
@@ -58,7 +58,7 @@ Browserslist: caniuse-lite is outdated. Please run:
58
58
  Creating an optimized production build ...
59
59
  Disabled SWC as replacement for Babel because of custom Babel configuration ".babelrc.js" https://nextjs.org/docs/messages/swc-disabled
60
60
  Using external babel configuration from /home/runner/work/faststore/faststore/packages/core/.babelrc.js
61
- Browserslist: browsers data (caniuse-lite) is 17 months old. Please run:
61
+ Browserslist: browsers data (caniuse-lite) is 19 months old. Please run:
62
62
  npx update-browserslist-db@latest
63
63
  Why you should do it regularly: https://github.com/browserslist/update-db#readme
64
64
  <w> [webpack.cache.PackFileCacheStrategy] Skipped not serializable cache item 'Compilation/modules|/home/runner/work/faststore/faststore/node_modules/.pnpm/next@13.5.11_@babel+core@7.26.7_@opentelemetry+api@1.4.1_react-dom@18.3.1_react@18.3.1__react@18.3.1_sass@1.83.4/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[7].oneOf[9].use[1]!/home/runner/work/faststore/faststore/node_modules/.pnpm/next@13.5.11_@babel+core@7.26.7_@opentelemetry+api@1.4.1_react-dom@18.3.1_react@18.3.1__react@18.3.1_sass@1.83.4/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[7].oneOf[9].use[2]!/home/runner/work/faststore/faststore/node_modules/.pnpm/next@13.5.11_@babel+core@7.26.7_@opentelemetry+api@1.4.1_react-dom@18.3.1_react@18.3.1__react@18.3.1_sass@1.83.4/node_modules/next/dist/build/webpack/loaders/resolve-url-loader/index.js??ruleSet[1].rules[7].oneOf[9].use[3]!/home/runner/work/faststore/faststore/node_modules/.pnpm/next@13.5.11_@babel+core@7.26.7_@opentelemetry+api@1.4.1_react-dom@18.3.1_react@18.3.1__react@18.3.1_sass@1.83.4/node_modules/next/dist/compiled/sass-loader/cjs.js??ruleSet[1].rules[7].oneOf[9].use[4]!/home/runner/work/faststore/faststore/packages/core/src/components/common/Toast/section.module.scss': No serializer registered for Warning
@@ -83,7 +83,7 @@ Learn more: https://nextjs.org/docs/api-reference/edge-runtime
83
83
 
84
84
  Import trace for requested module:
85
85
  ../../node_modules/.pnpm/jose@6.2.3/node_modules/jose/dist/webapi/lib/deflate.js
86
- ../../node_modules/.pnpm/jose@6.2.3/node_modules/jose/dist/webapi/jwe/flattened/decrypt.js
86
+ ../../node_modules/.pnpm/jose@6.2.3/node_modules/jose/dist/webapi/jwe/flattened/encrypt.js
87
87
  ../../node_modules/.pnpm/jose@6.2.3/node_modules/jose/dist/webapi/index.js
88
88
  ./src/server/password-protection-service.ts
89
89
 
@@ -93,7 +93,7 @@ Learn more: https://nextjs.org/docs/api-reference/edge-runtime
93
93
 
94
94
  Import trace for requested module:
95
95
  ../../node_modules/.pnpm/jose@6.2.3/node_modules/jose/dist/webapi/lib/deflate.js
96
- ../../node_modules/.pnpm/jose@6.2.3/node_modules/jose/dist/webapi/jwe/flattened/decrypt.js
96
+ ../../node_modules/.pnpm/jose@6.2.3/node_modules/jose/dist/webapi/jwe/flattened/encrypt.js
97
97
  ../../node_modules/.pnpm/jose@6.2.3/node_modules/jose/dist/webapi/index.js
98
98
  ./src/server/password-protection-service.ts
99
99
 
@@ -101,8 +101,8 @@ Import trace for requested module:
101
101
  Generating static pages (0/8) ...
102
102
 
103
103
  Generating static pages (2/8)
104
104
  Search not found. Add a new component for this section or remove it from the CMS
105
- 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.
106
105
  Search not found. Add a new component for this section or remove it from the CMS
106
+ 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.
107
107
 
108
108
  Generating static pages (4/8)
109
109
  Search not found. Add a new component for this section or remove it from the CMS
110
110
  Search not found. Add a new component for this section or remove it from the CMS
@@ -154,7 +154,7 @@ Route (pages) Size First Load JS
154
154
  ├ chunks/framework-d514426edf885c68.js 45.4 kB
155
155
  ├ chunks/main-a2d1cfe626f2fef1.js 33.4 kB
156
156
  ├ chunks/pages/_app-35e8dda638ee2672.js 26.6 kB
157
- ├ chunks/webpack-25c67512e1907efd.js 3.9 kB
157
+ ├ chunks/webpack-6a844a3f6a390f62.js 3.9 kB
158
158
  └ css/146a8678babc61bf.css 9.2 kB
159
159
 
160
160
  ƒ Middleware 44.8 kB
@@ -1,20 +1,21 @@
1
1
 
2
- > @faststore/core@3.100.2 test /home/runner/work/faststore/faststore/packages/core
2
+ > @faststore/core@3.100.3 test /home/runner/work/faststore/faststore/packages/core
3
3
  > jest
4
4
 
5
- PASS test/utils/clearCookies.test.ts (9.746 s)
5
+ PASS test/utils/clearCookies.test.ts (11.489 s)
6
+ PASS test/utils/cookieCacheBusting.test.ts (13.647 s)
6
7
  PASS test/utils/multipleTemplates.test.ts
7
- PASS test/server/password-protection-service.test.ts (16.656 s)
8
- PASS test/utils/cookieCacheBusting.test.ts (15.853 s)
9
- PASS test/server/cms/global.test.ts
8
+ PASS test/server/password-protection-service.test.ts (16.602 s)
9
+ PASS test/sdk/redirects/index.test.ts
10
10
  PASS test/utils/validateSessionRefreshToken.test.ts
11
+ PASS test/server/cms/global.test.ts
11
12
  PASS test/utils/isLocalHost.test.ts
12
- PASS test/server/cms/index.test.ts
13
13
  PASS test/utils/isLocalHost.browser.test.ts
14
- PASS test/server/index.test.ts (11.788 s)
14
+ PASS test/server/cms/index.test.ts (5.293 s)
15
+ PASS test/server/index.test.ts (10.491 s)
15
16
 
16
- Test Suites: 10 passed, 10 total
17
- Tests: 85 passed, 85 total
17
+ Test Suites: 11 passed, 11 total
18
+ Tests: 92 passed, 92 total
18
19
  Snapshots: 0 total
19
- Time: 27.32 s
20
+ Time: 27.151 s
20
21
  Ran all test suites.
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
+ ## [3.100.4](https://github.com/vtex/faststore/compare/v3.100.3...v3.100.4) (2026-08-28)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **core:** resolve redirect matcher module explicitly ([#3468](https://github.com/vtex/faststore/issues/3468)) ([fe3a3c7](https://github.com/vtex/faststore/commit/fe3a3c7c19237d53061be7b205838b626e225786)), closes [#3467](https://github.com/vtex/faststore/issues/3467) [#1450148](https://github.com/vtex/faststore/issues/1450148)
11
+
6
12
  ## [3.100.3](https://github.com/vtex/faststore/compare/v3.100.2...v3.100.3) (2026-06-30)
7
13
 
8
14
  ### Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/core",
3
- "version": "3.100.3",
3
+ "version": "3.100.4",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -127,5 +127,5 @@
127
127
  "ts-jest": "29.1.1",
128
128
  "typescript": "5.3.2"
129
129
  },
130
- "gitHead": "bf4812f3e3a53108f22ab987098b74f7eed9bfa3"
130
+ "gitHead": "b30af2d573626311c245c445860a45cb26478798"
131
131
  }
@@ -1,5 +1,5 @@
1
1
  import storeConfig from 'discovery.config'
2
- import { matcher } from 'src/customizations/src/redirects'
2
+ import { matcher } from 'src/customizations/src/redirects/index'
3
3
 
4
4
  type GetRedirectArgs = {
5
5
  pathname: string
@@ -19,6 +19,23 @@ const PERMANENT_STATUS = 308
19
19
 
20
20
  const ASSET_FILE_REGEX = /\.(js|css|png|jpg|jpeg|svg|gif|webp|ico|json|map)$/i
21
21
 
22
+ let hasWarnedInvalidMatcher = false
23
+
24
+ function resolveLocalMatch(pathname: string) {
25
+ if (typeof matcher === 'function') {
26
+ return matcher({ pathname })
27
+ }
28
+
29
+ if (!hasWarnedInvalidMatcher) {
30
+ hasWarnedInvalidMatcher = true
31
+ console.warn(
32
+ `[redirects] Expected src/redirects to export a \`matcher\` function, got ${typeof matcher}. Falling back to the platform redirect lookup.`
33
+ )
34
+ }
35
+
36
+ return null
37
+ }
38
+
22
39
  export async function getRedirect({
23
40
  pathname,
24
41
  }: GetRedirectArgs): Promise<GetRedirectReturn> {
@@ -29,7 +46,8 @@ export async function getRedirect({
29
46
  }
30
47
 
31
48
  try {
32
- const redirectMatch = matcher({ pathname })
49
+ const redirectMatch = resolveLocalMatch(pathname)
50
+
33
51
  if (redirectMatch) {
34
52
  return {
35
53
  destination: encodeURI(redirectMatch.destination),
@@ -0,0 +1,134 @@
1
+ const STORE_ID = 'teststore'
2
+ const REWRITER_URL = `https://${STORE_ID}.myvtex.com/_v/public/redirect-evaluate`
3
+
4
+ const MATCHER_MODULE = 'src/customizations/src/redirects/index'
5
+
6
+ type GetRedirect = typeof import('../../../src/sdk/redirects').getRedirect
7
+
8
+ async function loadGetRedirect(matcherExport?: unknown): Promise<GetRedirect> {
9
+ jest.resetModules()
10
+
11
+ jest.doMock('discovery.config', () => ({
12
+ __esModule: true,
13
+ default: { api: { storeId: STORE_ID } },
14
+ }))
15
+
16
+ if (matcherExport === undefined) {
17
+ jest.dontMock(MATCHER_MODULE)
18
+ } else {
19
+ jest.doMock(MATCHER_MODULE, () => ({
20
+ __esModule: true,
21
+ matcher: matcherExport,
22
+ }))
23
+ }
24
+
25
+ const { getRedirect } = await import('../../../src/sdk/redirects')
26
+
27
+ return getRedirect
28
+ }
29
+
30
+ function mockRewriter({ ok, body }: { ok: boolean; body?: unknown }) {
31
+ const fetchMock = jest
32
+ .fn()
33
+ .mockResolvedValue({ ok, json: async () => body } as Response)
34
+
35
+ globalThis.fetch = fetchMock as unknown as typeof fetch
36
+
37
+ return fetchMock
38
+ }
39
+
40
+ describe('getRedirect', () => {
41
+ const originalFetch = globalThis.fetch
42
+
43
+ beforeEach(() => {
44
+ jest.spyOn(console, 'error').mockImplementation(() => undefined)
45
+ jest.spyOn(console, 'warn').mockImplementation(() => undefined)
46
+ })
47
+
48
+ afterEach(() => {
49
+ globalThis.fetch = originalFetch
50
+ jest.dontMock('discovery.config')
51
+ jest.dontMock(MATCHER_MODULE)
52
+ jest.restoreAllMocks()
53
+ jest.resetModules()
54
+ })
55
+
56
+ it('skips asset paths without querying the rewriter', async () => {
57
+ const fetchMock = mockRewriter({ ok: false })
58
+ const getRedirect = await loadGetRedirect()
59
+
60
+ await expect(getRedirect({ pathname: '/icons.json' })).resolves.toBeNull()
61
+ expect(fetchMock).not.toHaveBeenCalled()
62
+ })
63
+
64
+ it('returns a custom matcher result without querying the rewriter', async () => {
65
+ const fetchMock = mockRewriter({ ok: false })
66
+ const getRedirect = await loadGetRedirect(() => ({
67
+ destination: '/promoção',
68
+ permanent: false,
69
+ }))
70
+
71
+ await expect(getRedirect({ pathname: '/sale' })).resolves.toEqual({
72
+ destination: encodeURI('/promoção'),
73
+ permanent: false,
74
+ })
75
+ expect(fetchMock).not.toHaveBeenCalled()
76
+ expect(console.warn).not.toHaveBeenCalled()
77
+ })
78
+
79
+ it('falls back to the rewriter when the matcher export is not a function', async () => {
80
+ const fetchMock = mockRewriter({
81
+ ok: true,
82
+ body: { location: '/eletrodomesticos', status: 308 },
83
+ })
84
+ // A store shipping `src/redirects.json` can shadow the customization
85
+ // module, which makes the imported `matcher` an array instead of a function.
86
+ const getRedirect = await loadGetRedirect([])
87
+
88
+ await expect(getRedirect({ pathname: '/old-page' })).resolves.toEqual({
89
+ destination: '/eletrodomesticos',
90
+ permanent: true,
91
+ })
92
+ expect(fetchMock).toHaveBeenCalledWith(`${REWRITER_URL}/old-page`)
93
+ expect(console.warn).toHaveBeenCalledTimes(1)
94
+ })
95
+
96
+ it('warns only once about an invalid matcher export', async () => {
97
+ mockRewriter({ ok: false })
98
+ const getRedirect = await loadGetRedirect([])
99
+
100
+ await getRedirect({ pathname: '/first' })
101
+ await getRedirect({ pathname: '/second' })
102
+
103
+ expect(console.warn).toHaveBeenCalledTimes(1)
104
+ })
105
+
106
+ it('does not leak a mocked matcher into a later default load', async () => {
107
+ mockRewriter({ ok: false })
108
+
109
+ const withInvalidMatcher = await loadGetRedirect([])
110
+ await expect(withInvalidMatcher({ pathname: '/first' })).resolves.toBeNull()
111
+
112
+ const withStubMatcher = await loadGetRedirect()
113
+ await expect(withStubMatcher({ pathname: '/second' })).resolves.toBeNull()
114
+
115
+ expect(console.warn).toHaveBeenCalledTimes(1)
116
+ })
117
+
118
+ it('marks non-permanent rewriter redirects as temporary', async () => {
119
+ mockRewriter({ ok: true, body: { location: '/new', status: 307 } })
120
+ const getRedirect = await loadGetRedirect()
121
+
122
+ await expect(getRedirect({ pathname: '/old' })).resolves.toEqual({
123
+ destination: '/new',
124
+ permanent: false,
125
+ })
126
+ })
127
+
128
+ it('returns null when the rewriter has no rule for the path', async () => {
129
+ mockRewriter({ ok: false })
130
+ const getRedirect = await loadGetRedirect()
131
+
132
+ await expect(getRedirect({ pathname: '/no-rule' })).resolves.toBeNull()
133
+ })
134
+ })