@faststore/core 3.0.60 → 3.0.61
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/app-build-manifest.json +3 -3
- package/.next/build-manifest.json +21 -21
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/cache/config.json +3 -3
- package/.next/cache/eslint/.cache_1gneedd +1 -1
- package/.next/cache/fetch-cache/50912854cb7c781522a6ff8792d714e549515fcbbbfd660761961b06afe01c07 +1 -1
- 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/next-minimal-server.js.nft.json +1 -1
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.js +1 -1
- package/.next/prerender-manifest.json +1 -1
- package/.next/routes-manifest.json +1 -1
- package/.next/server/app/_not-found.html +2 -2
- package/.next/server/app/_not-found.rsc +1 -1
- package/.next/server/app/fs-next-update.html +2 -2
- package/.next/server/app/fs-next-update.rsc +1 -1
- package/.next/server/chunks/2381.js +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/pages/404.html +2 -2
- package/.next/server/pages/[slug]/p.js +5 -5
- 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/account.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-manifest.json +1 -1
- package/.next/static/{6RpWP2aATNq_ljgOww_7v → 4w3LMmusMebDghIVyNvPn}/_buildManifest.js +1 -1
- package/.next/static/chunks/pages/{404-be2217109dab18cf.js → 404-6d926d3bdc58852b.js} +1 -1
- package/.next/static/chunks/pages/{500-64a07a16830e129c.js → 500-cbffc24e6eaddf18.js} +1 -1
- package/.next/static/chunks/pages/{login-258e5b7ecec36481.js → login-78b2d6166a2ebbaa.js} +1 -1
- package/.next/static/chunks/{webpack-a45dc84c9a0ef3fd.js → webpack-4f403c9b52a287c6.js} +1 -1
- package/.next/static/css/9b7689964b990431.css +1 -0
- package/.next/trace +62 -62
- package/.turbo/turbo-build.log +3 -3
- package/.turbo/turbo-test.log +5 -5
- package/package.json +2 -2
- package/src/pages/[slug]/p.tsx +1 -1
- package/src/server/cms/pdp.ts +7 -15
- package/src/utils/multipleTemplates.ts +57 -19
- package/test/utils/multipleTemplates.test.ts +80 -2
- package/.next/static/css/548bab931c45c770.css +0 -1
- /package/.next/static/{6RpWP2aATNq_ljgOww_7v → 4w3LMmusMebDghIVyNvPn}/_ssgManifest.js +0 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
$ yarn partytown & yarn generate && next build
|
|
2
2
|
$ partytown copylib ./public/~partytown
|
|
3
|
-
Partytown lib copied to: /home/runner/work/faststore/faststore/packages/core/public/~partytown
|
|
4
3
|
$ faststore generate-graphql -c
|
|
4
|
+
Partytown lib copied to: /home/runner/work/faststore/faststore/packages/core/public/~partytown
|
|
5
5
|
success - GraphQL schema, types, and optimizations successfully generated 🎉
|
|
6
6
|
⚠ No build cache found. Please configure build caching for faster rebuilds. Read more: https://nextjs.org/docs/messages/no-cache
|
|
7
7
|
Attention: Next.js now collects completely anonymous telemetry regarding usage.
|
|
@@ -38,7 +38,7 @@ Route (app) Size First Load JS
|
|
|
38
38
|
├ chunks/472-369461a1f39981d5.js 28.4 kB
|
|
39
39
|
├ chunks/fd9d1056-43c43818840d7811.js 51.1 kB
|
|
40
40
|
├ chunks/main-app-e13fa67c2c3ceca5.js 230 B
|
|
41
|
-
└ chunks/webpack-
|
|
41
|
+
└ chunks/webpack-4f403c9b52a287c6.js 2.43 kB
|
|
42
42
|
|
|
43
43
|
Route (pages) Size First Load JS
|
|
44
44
|
┌ ● / 1.04 kB 148 kB
|
|
@@ -62,7 +62,7 @@ Route (pages) Size First Load JS
|
|
|
62
62
|
├ chunks/framework-21e9365486ba23a6.js 45.4 kB
|
|
63
63
|
├ chunks/main-9c9c62c368c0a47e.js 34.8 kB
|
|
64
64
|
├ chunks/pages/_app-1930798899758fda.js 11.2 kB
|
|
65
|
-
├ chunks/webpack-
|
|
65
|
+
├ chunks/webpack-4f403c9b52a287c6.js 2.43 kB
|
|
66
66
|
└ css/5d1f64b61ea581f4.css 3.05 kB
|
|
67
67
|
|
|
68
68
|
λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
|
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
$ jest
|
|
2
|
-
PASS test/
|
|
3
|
-
PASS test/
|
|
4
|
-
PASS test/server/index.test.ts (
|
|
2
|
+
PASS test/server/cms/index.test.ts (31.47 s)
|
|
3
|
+
PASS test/utils/multipleTemplates.test.ts (31.586 s)
|
|
4
|
+
PASS test/server/index.test.ts (32.977 s)
|
|
5
5
|
|
|
6
6
|
Test Suites: 3 passed, 3 total
|
|
7
|
-
Tests:
|
|
7
|
+
Tests: 19 passed, 19 total
|
|
8
8
|
Snapshots: 0 total
|
|
9
|
-
Time:
|
|
9
|
+
Time: 34.047 s
|
|
10
10
|
Ran all test suites.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faststore/core",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.61",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": "vtex/faststore",
|
|
6
6
|
"browserslist": "supports es6-module and not dead",
|
|
@@ -125,5 +125,5 @@
|
|
|
125
125
|
"node": "18.19.0",
|
|
126
126
|
"yarn": "1.19.1"
|
|
127
127
|
},
|
|
128
|
-
"gitHead": "
|
|
128
|
+
"gitHead": "9ce5509d24e1a1f6eca08c77544b94db7ef4037b"
|
|
129
129
|
}
|
package/src/pages/[slug]/p.tsx
CHANGED
|
@@ -231,7 +231,7 @@ export const getStaticProps: GetStaticProps<
|
|
|
231
231
|
throw errors[0]
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
const cmsPage: PDPContentType = await getPDP(
|
|
234
|
+
const cmsPage: PDPContentType = await getPDP(data.product, previewData)
|
|
235
235
|
|
|
236
236
|
const { seo } = data.product
|
|
237
237
|
const title = seo.title || storeConfig.seo.title
|
package/src/server/cms/pdp.ts
CHANGED
|
@@ -21,7 +21,6 @@ type PDPfromCmsEnvData = {
|
|
|
21
21
|
export type PDPContentType = ContentData & PDPSettings
|
|
22
22
|
|
|
23
23
|
export const getPDP = async (
|
|
24
|
-
slug: string,
|
|
25
24
|
product: ServerProductQueryQuery['product'],
|
|
26
25
|
previewData: Locator
|
|
27
26
|
) => {
|
|
@@ -29,25 +28,19 @@ export const getPDP = async (
|
|
|
29
28
|
const cmsData = JSON.parse(config.cms.data)
|
|
30
29
|
const allPDPsFromCmsEnvData: PDPfromCmsEnvData[] = cmsData['pdp']
|
|
31
30
|
|
|
32
|
-
return await getPDPFromCmsEnvData(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
{
|
|
37
|
-
...(previewData?.contentType === 'pdp' ? previewData : null),
|
|
38
|
-
contentType: 'pdp',
|
|
39
|
-
}
|
|
40
|
-
)
|
|
31
|
+
return await getPDPFromCmsEnvData(product, allPDPsFromCmsEnvData, {
|
|
32
|
+
...(previewData?.contentType === 'pdp' ? previewData : null),
|
|
33
|
+
contentType: 'pdp',
|
|
34
|
+
})
|
|
41
35
|
}
|
|
42
36
|
|
|
43
|
-
return (await getPDPFromCms(
|
|
37
|
+
return (await getPDPFromCms(product, {
|
|
44
38
|
...(previewData?.contentType === 'pdp' ? previewData : null),
|
|
45
39
|
contentType: 'pdp',
|
|
46
40
|
})) as PDPContentType
|
|
47
41
|
}
|
|
48
42
|
|
|
49
43
|
const getPDPFromCmsEnvData = async (
|
|
50
|
-
slug: string,
|
|
51
44
|
product: ServerProductQueryQuery['product'],
|
|
52
45
|
allPDPsFromCMSData: PDPfromCmsEnvData[],
|
|
53
46
|
options: Options
|
|
@@ -58,7 +51,7 @@ const getPDPFromCmsEnvData = async (
|
|
|
58
51
|
throw new MissingContentError(options)
|
|
59
52
|
}
|
|
60
53
|
|
|
61
|
-
const template = findBestPDPTemplate(pages,
|
|
54
|
+
const template = findBestPDPTemplate(pages, product)
|
|
62
55
|
|
|
63
56
|
return getPage<PDPContentType>({
|
|
64
57
|
contentType: 'pdp',
|
|
@@ -68,7 +61,6 @@ const getPDPFromCmsEnvData = async (
|
|
|
68
61
|
}
|
|
69
62
|
|
|
70
63
|
const getPDPFromCms = async (
|
|
71
|
-
slug: string,
|
|
72
64
|
product: ServerProductQueryQuery['product'],
|
|
73
65
|
options: Options
|
|
74
66
|
): Promise<Partial<PDPContentType>> => {
|
|
@@ -78,5 +70,5 @@ const getPDPFromCms = async (
|
|
|
78
70
|
throw new MissingContentError(options)
|
|
79
71
|
}
|
|
80
72
|
|
|
81
|
-
return findBestPDPTemplate(pages,
|
|
73
|
+
return findBestPDPTemplate(pages, product)
|
|
82
74
|
}
|
|
@@ -135,40 +135,53 @@ export function normalizePDPTemplate(templateValue: string) {
|
|
|
135
135
|
return formattedValue.toLowerCase()
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
+
// Returns an array of slugs without the number at the end ("-{number}/p") at each interaction if it matches, otherwise returns the slug as is.
|
|
139
|
+
const getSlugsWithoutSkuIdFromPDP = (slug: string) => {
|
|
140
|
+
const slugs = []
|
|
141
|
+
let currentSlug = slug
|
|
142
|
+
let match = currentSlug.match(/-\d+\/p$/)
|
|
143
|
+
|
|
144
|
+
while (match) {
|
|
145
|
+
const newSlug = currentSlug.replace(/-\d+\/p$/, '/p')
|
|
146
|
+
slugs.push(newSlug)
|
|
147
|
+
currentSlug = newSlug
|
|
148
|
+
match = currentSlug.match(/-\d+\/p$/)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return slugs
|
|
152
|
+
}
|
|
153
|
+
|
|
138
154
|
/**
|
|
139
155
|
* Find the best PDP template from the CMS based on the slug or in the product category tree.
|
|
140
156
|
* Prioritizing the following order:
|
|
141
157
|
*
|
|
142
|
-
* 1. A PDP template that matches the page slug (e.g. slug = /apple-magic-mouse/p).
|
|
143
|
-
* 2. A PDP template that matches the
|
|
144
|
-
* 3. A PDP template that matches the product
|
|
145
|
-
* 4. A PDP template that matches the product
|
|
146
|
-
* 5.
|
|
158
|
+
* 1. A PDP template that matches the page slug with skuId (e.g. slug = /apple-magic-mouse-12345/p).
|
|
159
|
+
* 2. A PDP template that matches the page slug (e.g. slug = /apple-magic-mouse/p).
|
|
160
|
+
* 3. A PDP template that matches the product subcategory (e.g. /department/category/subcategory).
|
|
161
|
+
* 4. A PDP template that matches the product category (e.g. /department/category).
|
|
162
|
+
* 5. A PDP template that matches the product department (e.g. /department).
|
|
163
|
+
* 6. If no matches are found, use the generic PDP template.
|
|
147
164
|
*
|
|
148
165
|
* @param pages
|
|
149
|
-
* @param originalSlug
|
|
150
166
|
* @param product
|
|
151
|
-
* @returns The best PDP template page for the
|
|
167
|
+
* @returns The best PDP template page for the product
|
|
152
168
|
*/
|
|
153
169
|
export function findBestPDPTemplate(
|
|
154
170
|
pages: Partial<PDPContentType>[],
|
|
155
|
-
slug: string,
|
|
156
171
|
product: ServerProductQueryQuery['product']
|
|
157
172
|
) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
: []
|
|
164
|
-
productSlugAndCategoryTree.unshift(slug)
|
|
165
|
-
|
|
166
|
-
for (const item of productSlugAndCategoryTree) {
|
|
173
|
+
const templateValues = getPDPTemplateValues({
|
|
174
|
+
itemListElement: product.breadcrumbList.itemListElement ?? [],
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
for (const template of templateValues) {
|
|
167
178
|
for (const page of pages) {
|
|
168
179
|
if (!page.settings?.template?.value) continue
|
|
169
180
|
|
|
170
|
-
const
|
|
171
|
-
|
|
181
|
+
const templateValueFromCms = normalizePDPTemplate(
|
|
182
|
+
page.settings.template.value
|
|
183
|
+
)
|
|
184
|
+
if (templateValueFromCms === template) {
|
|
172
185
|
return page
|
|
173
186
|
}
|
|
174
187
|
}
|
|
@@ -176,3 +189,28 @@ export function findBestPDPTemplate(
|
|
|
176
189
|
|
|
177
190
|
return pages.find((page) => !page.settings?.template?.value) || pages[0]
|
|
178
191
|
}
|
|
192
|
+
|
|
193
|
+
export function getPDPTemplateValues({
|
|
194
|
+
itemListElement = [],
|
|
195
|
+
}: {
|
|
196
|
+
itemListElement: ServerProductQueryQuery['product']['breadcrumbList']['itemListElement']
|
|
197
|
+
}) {
|
|
198
|
+
// productSlugAndCategoryTree with the prioritized order. [link-skuId/p, subcategory tree, category tree, department]
|
|
199
|
+
const productSlugAndCategoryTree = [...itemListElement]
|
|
200
|
+
.reverse()
|
|
201
|
+
.map(({ item }) => item)
|
|
202
|
+
|
|
203
|
+
// PDP slug comes from FastStore API with the format `${link}-${skuId}/p`, the most specific for multiple page templates,
|
|
204
|
+
// so it should be the first element
|
|
205
|
+
const slugWithSkuId = productSlugAndCategoryTree[0]
|
|
206
|
+
|
|
207
|
+
// PDP slug without skuId `${link}/p`, should be the second element
|
|
208
|
+
const slugsWithoutSkuId = getSlugsWithoutSkuIdFromPDP(slugWithSkuId)
|
|
209
|
+
|
|
210
|
+
// removes duplicated and undefined
|
|
211
|
+
return [
|
|
212
|
+
slugWithSkuId,
|
|
213
|
+
...slugsWithoutSkuId,
|
|
214
|
+
...productSlugAndCategoryTree.slice(1),
|
|
215
|
+
].filter((item, index, arr) => item && arr.indexOf(item) === index)
|
|
216
|
+
}
|
|
@@ -1,8 +1,27 @@
|
|
|
1
1
|
import type { Rewrite, RewritesConfig } from '../../src/utils/multipleTemplates'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
getPDPTemplateValues,
|
|
4
|
+
hasRewritesConfigForSlug,
|
|
5
|
+
} from '../../src/utils/multipleTemplates'
|
|
6
|
+
|
|
7
|
+
const productItemListElementMock = [
|
|
8
|
+
{ item: '/department/', name: 'test', position: 1 }, // Department
|
|
9
|
+
{ item: '/department/category/', name: 'test', position: 1 }, // Category tree
|
|
10
|
+
{ item: '/department/category/subcategory/', name: 'test', position: 1 }, // Subcategory tree
|
|
11
|
+
{
|
|
12
|
+
item: '/department/category/subcategory/subcategory2/',
|
|
13
|
+
name: 'test',
|
|
14
|
+
position: 1,
|
|
15
|
+
}, // Subcategory tree tree
|
|
16
|
+
{
|
|
17
|
+
item: '/department/category/subcategory/subcategory2/subcategory3/',
|
|
18
|
+
name: 'test',
|
|
19
|
+
position: 1,
|
|
20
|
+
}, // Subcategory tree
|
|
21
|
+
]
|
|
3
22
|
|
|
4
23
|
describe('Multiple page templates', () => {
|
|
5
|
-
describe('hasRewritesConfigForSlug', () => {
|
|
24
|
+
describe('PLP hasRewritesConfigForSlug', () => {
|
|
6
25
|
it('should return true when rewrites is an array of objects containing the desired destination and source', () => {
|
|
7
26
|
const rewritesArr: Rewrite[] = [
|
|
8
27
|
{ source: '/test/my-office', destination: '/office' },
|
|
@@ -63,4 +82,63 @@ describe('Multiple page templates', () => {
|
|
|
63
82
|
expect(result).toBe(false)
|
|
64
83
|
})
|
|
65
84
|
})
|
|
85
|
+
|
|
86
|
+
describe('PDP getPDPTemplateValues', () => {
|
|
87
|
+
it('should return correct template values when productItemListElement first item has skuId and numbers', () => {
|
|
88
|
+
const mock = [
|
|
89
|
+
...productItemListElementMock,
|
|
90
|
+
{ item: '/slug-product-test-111111-2222/p', name: 'test', position: 1 },
|
|
91
|
+
] // PDP slug with skuId and number
|
|
92
|
+
const result = getPDPTemplateValues({
|
|
93
|
+
itemListElement: mock,
|
|
94
|
+
})
|
|
95
|
+
expect(result).toEqual([
|
|
96
|
+
'/slug-product-test-111111-2222/p', // PDP slug with skuId
|
|
97
|
+
'/slug-product-test-111111/p', // PDP slug without skuId
|
|
98
|
+
'/slug-product-test/p', // PDP slug without number
|
|
99
|
+
'/department/category/subcategory/subcategory2/subcategory3/', // Subcategory tree
|
|
100
|
+
'/department/category/subcategory/subcategory2/', // Subcategory tree
|
|
101
|
+
'/department/category/subcategory/', // Subcategory
|
|
102
|
+
'/department/category/', // Category
|
|
103
|
+
'/department/', // Department
|
|
104
|
+
])
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('should return correct template values when productItemListElement first item have skuId', () => {
|
|
108
|
+
const mock = [
|
|
109
|
+
...productItemListElementMock,
|
|
110
|
+
{ item: '/slug-product-test-111111/p', name: 'test', position: 1 },
|
|
111
|
+
] // PDP slug with skuId
|
|
112
|
+
const result = getPDPTemplateValues({
|
|
113
|
+
itemListElement: mock,
|
|
114
|
+
})
|
|
115
|
+
expect(result).toEqual([
|
|
116
|
+
'/slug-product-test-111111/p', // PDP slug with skuId
|
|
117
|
+
'/slug-product-test/p', // PDP slug without number
|
|
118
|
+
'/department/category/subcategory/subcategory2/subcategory3/', // Subcategory tree
|
|
119
|
+
'/department/category/subcategory/subcategory2/', // Subcategory tree
|
|
120
|
+
'/department/category/subcategory/', // Subcategory
|
|
121
|
+
'/department/category/', // Category
|
|
122
|
+
'/department/', // Department
|
|
123
|
+
])
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it('should return correct template values productItemListElement first item do not have skuId and other number', () => {
|
|
127
|
+
const mock = [
|
|
128
|
+
...productItemListElementMock,
|
|
129
|
+
{ item: '/slug-product-test/p', name: 'test', position: 1 },
|
|
130
|
+
] // PDP slug with skuId
|
|
131
|
+
const result = getPDPTemplateValues({
|
|
132
|
+
itemListElement: mock,
|
|
133
|
+
})
|
|
134
|
+
expect(result).toEqual([
|
|
135
|
+
'/slug-product-test/p', // PDP slug without skuId
|
|
136
|
+
'/department/category/subcategory/subcategory2/subcategory3/', // Subcategory tree
|
|
137
|
+
'/department/category/subcategory/subcategory2/', // Subcategory tree
|
|
138
|
+
'/department/category/subcategory/', // Subcategory
|
|
139
|
+
'/department/category/', // Category
|
|
140
|
+
'/department/', // Department
|
|
141
|
+
])
|
|
142
|
+
})
|
|
143
|
+
})
|
|
66
144
|
})
|