@faststore/core 3.0.15 → 3.0.17

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 (58) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +15 -15
  3. package/.next/cache/.tsbuildinfo +1 -1
  4. package/.next/cache/config.json +3 -3
  5. package/.next/cache/eslint/.cache_1gneedd +1 -1
  6. package/.next/cache/webpack/client-production/0.pack +0 -0
  7. package/.next/cache/webpack/client-production/index.pack +0 -0
  8. package/.next/cache/webpack/server-production/0.pack +0 -0
  9. package/.next/cache/webpack/server-production/index.pack +0 -0
  10. package/.next/next-minimal-server.js.nft.json +1 -1
  11. package/.next/next-server.js.nft.json +1 -1
  12. package/.next/prerender-manifest.js +1 -1
  13. package/.next/prerender-manifest.json +1 -1
  14. package/.next/routes-manifest.json +1 -1
  15. package/.next/server/chunks/646.js +2 -2
  16. package/.next/server/chunks/659.js +2 -2
  17. package/.next/server/functions-config-manifest.json +1 -1
  18. package/.next/server/middleware-build-manifest.js +1 -1
  19. package/.next/server/pages/404.js +1 -1
  20. package/.next/server/pages/500.js +1 -1
  21. package/.next/server/pages/[...slug].js +1 -1
  22. package/.next/server/pages/[slug]/p.js +1 -1
  23. package/.next/server/pages/api/preview.js +1 -1
  24. package/.next/server/pages/en-US/404.html +2 -2
  25. package/.next/server/pages/en-US/500.html +2 -2
  26. package/.next/server/pages/en-US/account.html +2 -2
  27. package/.next/server/pages/en-US/checkout.html +2 -2
  28. package/.next/server/pages/en-US/login.html +2 -2
  29. package/.next/server/pages/en-US/s.html +2 -2
  30. package/.next/server/pages/en-US.html +2 -2
  31. package/.next/server/pages/index.js +1 -1
  32. package/.next/server/pages/login.js +1 -1
  33. package/.next/server/pages/s.js +1 -1
  34. package/.next/static/{CQN373YhXlHGMNoI7Y6BQ → GuDWclSYmL3r-NEqsUOG2}/_buildManifest.js +1 -1
  35. package/.next/static/chunks/104-4f83b1d87ad36358.js +1 -0
  36. package/.next/static/chunks/pages/{[...slug]-506fd56c3ad48553.js → [...slug]-bcaf61b01157d8cb.js} +1 -1
  37. package/.next/static/chunks/pages/[slug]/{p-a4f7d7c00fdf4157.js → p-5fb8fe2c80ec1608.js} +1 -1
  38. package/.next/static/chunks/pages/{index-00798cca3b47590d.js → index-cd109119d65df8e3.js} +1 -1
  39. package/.next/static/chunks/pages/{s-e78f09767764a172.js → s-26e475975386c51a.js} +1 -1
  40. package/.next/trace +91 -91
  41. package/.turbo/turbo-build.log +1 -1
  42. package/.turbo/turbo-test.log +9 -9
  43. package/cms/faststore/content-types.json +14 -1
  44. package/package.json +2 -2
  45. package/src/components/cms/GlobalSections.tsx +4 -4
  46. package/src/components/templates/LandingPage/LandingPage.tsx +6 -6
  47. package/src/components/templates/ProductListingPage/ProductListing.tsx +4 -4
  48. package/src/components/templates/ProductListingPage/ProductListingPage.tsx +1 -1
  49. package/src/pages/[...slug].tsx +8 -32
  50. package/src/pages/[slug]/p.tsx +6 -25
  51. package/src/pages/index.tsx +3 -3
  52. package/src/pages/s.tsx +3 -3
  53. package/src/server/{cms.ts → cms/index.ts} +35 -57
  54. package/src/server/cms/pdp.ts +82 -0
  55. package/src/server/cms/plp.ts +74 -0
  56. package/src/utils/utilities.ts +118 -0
  57. package/.next/static/chunks/104-35697aed442af6cd.js +0 -1
  58. /package/.next/static/{CQN373YhXlHGMNoI7Y6BQ → GuDWclSYmL3r-NEqsUOG2}/_ssgManifest.js +0 -0
@@ -1,6 +1,6 @@
1
1
  $ yarn partytown & yarn generate && next build
2
- $ partytown copylib ./public/~partytown
3
2
  $ faststore generate-graphql -c
3
+ $ partytown copylib ./public/~partytown
4
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
@@ -1,23 +1,23 @@
1
1
  $ jest
2
- PASS test/server/index.test.ts (21.226 s)
2
+ PASS test/server/index.test.ts (21.812 s)
3
3
  FastStore GraphQL Layer
4
4
  @faststore/api
5
- ✓ should return a valid GraphQL schema (9 ms)
6
- ✓ should return a valid GraphQL schema contain all expected types (4 ms)
5
+ ✓ should return a valid GraphQL schema (8 ms)
6
+ ✓ should return a valid GraphQL schema contain all expected types (10 ms)
7
7
  ✓ should return a valid GraphQL schema contain all expected queries (1 ms)
8
8
  ✓ should return a valid GraphQL schema contain all expected mutations (1 ms)
9
9
  VTEX API Extension
10
- ✓ getTypeDefsFromFolder function should return an Array (9 ms)
10
+ ✓ getTypeDefsFromFolder function should return an Array (8 ms)
11
11
  Third Party API Extension
12
- ✓ getTypeDefsFromFolder function should return an Array (5 ms)
12
+ ✓ getTypeDefsFromFolder function should return an Array (7 ms)
13
13
  Final Schema after merging
14
- ✓ should return a valid merged GraphQL schema (24 ms)
14
+ ✓ should return a valid merged GraphQL schema (27 ms)
15
15
  Envelop
16
- ✓ should exist with its plugins (35 ms)
17
- ✓ should handle options and execute (389 ms)
16
+ ✓ should exist with its plugins (32 ms)
17
+ ✓ should handle options and execute (584 ms)
18
18
 
19
19
  Test Suites: 1 passed, 1 total
20
20
  Tests: 9 passed, 9 total
21
21
  Snapshots: 0 total
22
- Time: 21.294 s
22
+ Time: 21.888 s
23
23
  Ran all test suites.
@@ -129,11 +129,24 @@
129
129
  "id": "plp",
130
130
  "name": "Product List Page",
131
131
  "scopes": ["plp"],
132
- "isSingleton": true,
133
132
  "configurationSchemaSets": [
134
133
  {
135
134
  "name": "Settings",
136
135
  "configurations": [
136
+ {
137
+ "name": "template",
138
+ "schema": {
139
+ "title": "Template",
140
+ "type": "object",
141
+ "properties": {
142
+ "value": {
143
+ "title": "PLP template value (e.g. Slug: /department/category/subcategory)",
144
+ "type": "string",
145
+ "description": "PLP slug template (e.g. /office or /office/chairs) representing the /department/category/subcategory template). If this field is left empty, the generic PLP template will be applied."
146
+ }
147
+ }
148
+ }
149
+ },
137
150
  {
138
151
  "name": "productGallery",
139
152
  "schema": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/core",
3
- "version": "3.0.15",
3
+ "version": "3.0.17",
4
4
  "license": "MIT",
5
5
  "repository": "vtex/faststore",
6
6
  "browserslist": "supports es6-module and not dead",
@@ -128,5 +128,5 @@
128
128
  "node": "18.19.0",
129
129
  "yarn": "1.19.1"
130
130
  },
131
- "gitHead": "0285725a6a9ace13dcbbb77b734ee1e48a93f7fb"
131
+ "gitHead": "ae2fd5e80daef2a86a865cbd615e3fa0d475d959"
132
132
  }
@@ -1,17 +1,17 @@
1
1
  import { Locator, Section } from '@vtex/client-cms'
2
+ import storeConfig from 'faststore.config'
2
3
  import type { ComponentType } from 'react'
3
4
  import { PropsWithChildren, lazy } from 'react'
4
- import storeConfig from 'faststore.config'
5
5
  import CUSTOM_COMPONENTS from 'src/customizations/src/components'
6
- import { PageContentType, getPage, getPageByVersionId } from 'src/server/cms'
6
+ import { PageContentType, getPage } from 'src/server/cms'
7
7
 
8
8
  import Toast from 'src/components/common/Toast'
9
9
  import RenderSections from './RenderSections'
10
10
 
11
11
  import { OverriddenDefaultAlert as Alert } from 'src/components/sections/Alert/OverriddenDefaultAlert'
12
+ import Footer from 'src/components/sections/Footer'
12
13
  import { OverriddenDefaultNavbar as Navbar } from 'src/components/sections/Navbar/OverriddenDefaultNavbar'
13
14
  import { OverriddenDefaultRegionBar as RegionBar } from 'src/components/sections/RegionBar/OverriddenDefaultRegionBar'
14
- import Footer from 'src/components/sections/Footer'
15
15
 
16
16
  const RegionModal = lazy(() => import('src/components/region/RegionModal'))
17
17
  const CartSidebar = lazy(() => import('src/components/cart/CartSidebar'))
@@ -56,7 +56,7 @@ export const getGlobalSectionsData = async (
56
56
  const page = cmsData[GLOBAL_SECTIONS_CONTENT_TYPE][0]
57
57
 
58
58
  if (page) {
59
- const pageData = await getPageByVersionId<PageContentType>({
59
+ const pageData = await getPage<PageContentType>({
60
60
  contentType: GLOBAL_SECTIONS_CONTENT_TYPE,
61
61
  documentId: page.documentId,
62
62
  versionId: page.versionId,
@@ -1,18 +1,18 @@
1
+ import type { Locator } from '@vtex/client-cms'
1
2
  import { NextSeo, SiteLinksSearchBoxJsonLd } from 'next-seo'
2
3
  import type { ComponentType } from 'react'
3
- import type { Locator } from '@vtex/client-cms'
4
4
 
5
- import MissingContentError from 'src/sdk/error/MissingContentError/MissingContentError'
6
5
  import RenderSections from 'src/components/cms/RenderSections'
7
6
  import { OverriddenDefaultBannerText as BannerText } from 'src/components/sections/BannerText/OverriddenDefaultBannerText'
8
7
  import { OverriddenDefaultHero as Hero } from 'src/components/sections/Hero/OverriddenDefaultHero'
8
+ import Incentives from 'src/components/sections/Incentives'
9
9
  import { OverriddenDefaultNewsletter as Newsletter } from 'src/components/sections/Newsletter/OverriddenDefaultNewsletter'
10
10
  import { OverriddenDefaultProductShelf as ProductShelf } from 'src/components/sections/ProductShelf/OverriddenDefaultProductShelf'
11
- import Incentives from 'src/components/sections/Incentives'
12
11
  import ProductTiles from 'src/components/sections/ProductTiles'
13
- import { getPage, getPageByVersionId } from 'src/server/cms'
14
- import type { PageContentType } from 'src/server/cms'
15
12
  import CUSTOM_COMPONENTS from 'src/customizations/src/components'
13
+ import MissingContentError from 'src/sdk/error/MissingContentError/MissingContentError'
14
+ import type { PageContentType } from 'src/server/cms'
15
+ import { getPage } from 'src/server/cms'
16
16
 
17
17
  import storeConfig from 'faststore.config'
18
18
 
@@ -92,7 +92,7 @@ export const getLandingPageBySlug = async (
92
92
  })
93
93
 
94
94
  if (pageBySlug) {
95
- const landingPageData = await getPageByVersionId<PageContentType>({
95
+ const landingPageData = await getPage<PageContentType>({
96
96
  contentType: 'landingPage',
97
97
  documentId: pageBySlug.documentId,
98
98
  versionId: pageBySlug.versionId,
@@ -1,24 +1,24 @@
1
+ import { useSearch } from '@faststore/sdk'
1
2
  import type { ServerCollectionPageQueryQuery } from '@generated/graphql'
3
+ import deepmerge from 'deepmerge'
2
4
  import { OverriddenDefaultBreadcrumb as Breadcrumb } from 'src/components/sections/Breadcrumb/OverriddenDefaultBreadcrumb'
3
5
  import { OverriddenDefaultHero as Hero } from 'src/components/sections/Hero/OverriddenDefaultHero'
4
6
  import { OverriddenDefaultProductGallery as ProductGallery } from 'src/components/sections/ProductGallery/OverriddenDefaultProductGallery'
5
7
  import { OverriddenDefaultProductShelf as ProductShelf } from 'src/components/sections/ProductShelf/OverriddenDefaultProductShelf'
6
8
  import ScrollToTopButton from 'src/components/sections/ScrollToTopButton'
7
9
  import { ITEMS_PER_PAGE } from 'src/constants'
8
- import deepmerge from 'deepmerge'
9
- import { useSearch } from '@faststore/sdk'
10
10
 
11
11
  import type { ComponentType } from 'react'
12
12
  import RenderSections from 'src/components/cms/RenderSections'
13
13
  import CUSTOM_COMPONENTS from 'src/customizations/src/components'
14
- import { PLPContentType } from 'src/server/cms'
14
+ import { PLPContentType } from 'src/server/cms/plp'
15
15
 
16
+ import PageProvider, { PLPContext } from 'src/sdk/overrides/PageProvider'
16
17
  import {
17
18
  useCreateUseGalleryPage,
18
19
  UseGalleryPageContext,
19
20
  } from 'src/sdk/product/usePageProductsQuery'
20
21
  import { useProductGalleryQuery } from 'src/sdk/product/useProductGalleryQuery'
21
- import PageProvider, { PLPContext } from 'src/sdk/overrides/PageProvider'
22
22
 
23
23
  export type ProductListingPageProps = {
24
24
  data: ServerCollectionPageQueryQuery
@@ -12,7 +12,7 @@ import type { ServerCollectionPageQueryQuery } from '@generated/graphql'
12
12
  import { ITEMS_PER_PAGE } from 'src/constants'
13
13
  import { useApplySearchState } from 'src/sdk/search/state'
14
14
 
15
- import { PLPContentType } from 'src/server/cms'
15
+ import { PLPContentType } from 'src/server/cms/plp'
16
16
 
17
17
  import storeConfig from '../../../../faststore.config'
18
18
  import ProductListing from './ProductListing'
@@ -1,6 +1,5 @@
1
1
  import { isNotFoundError } from '@faststore/api'
2
2
  import type { GetStaticPaths, GetStaticProps } from 'next'
3
- import storeConfig from 'faststore.config'
4
3
 
5
4
  import { gql } from '@generated'
6
5
  import type {
@@ -15,19 +14,15 @@ import GlobalSections, {
15
14
  getGlobalSectionsData,
16
15
  GlobalSectionsData,
17
16
  } from 'src/components/cms/GlobalSections'
18
- import {
19
- getPage,
20
- getPageByVersionId,
21
- PageContentType,
22
- PLPContentType,
23
- } from 'src/server/cms'
24
- import ProductListingPage, {
25
- ProductListingPageProps,
26
- } from 'src/components/templates/ProductListingPage'
27
17
  import LandingPage, {
28
18
  getLandingPageBySlug,
29
19
  LandingPageProps,
30
20
  } from 'src/components/templates/LandingPage'
21
+ import ProductListingPage, {
22
+ ProductListingPageProps,
23
+ } from 'src/components/templates/ProductListingPage'
24
+ import { PageContentType } from 'src/server/cms'
25
+ import { getPLP, PLPContentType } from 'src/server/cms/plp'
31
26
 
32
27
  type BaseProps = {
33
28
  globalSections: GlobalSectionsData
@@ -106,7 +101,7 @@ export const getStaticProps: GetStaticProps<
106
101
  }
107
102
  }
108
103
 
109
- const [{ data, errors = [] }] = await Promise.all([
104
+ const [{ data, errors = [] }, cmsPage] = await Promise.all([
110
105
  execute<
111
106
  ServerCollectionPageQueryQueryVariables,
112
107
  ServerCollectionPageQueryQuery
@@ -114,28 +109,9 @@ export const getStaticProps: GetStaticProps<
114
109
  variables: { slug },
115
110
  operation: query,
116
111
  }),
112
+ getPLP(slug, previewData),
117
113
  ])
118
114
 
119
- let pageData
120
-
121
- if (storeConfig.cms.data) {
122
- const cmsData = JSON.parse(storeConfig.cms.data)
123
- const page = cmsData['plp'][0]
124
-
125
- if (page) {
126
- pageData = await getPageByVersionId<PLPContentType>({
127
- contentType: 'plp',
128
- documentId: page.documentId,
129
- versionId: page.versionId,
130
- })
131
- }
132
- } else {
133
- pageData = await getPage<PLPContentType>({
134
- ...(previewData?.contentType === 'plp' ? previewData : null),
135
- contentType: 'plp',
136
- })
137
- }
138
-
139
115
  const notFound = errors.find(isNotFoundError)
140
116
 
141
117
  if (notFound) {
@@ -152,7 +128,7 @@ export const getStaticProps: GetStaticProps<
152
128
  return {
153
129
  props: {
154
130
  data,
155
- page: pageData,
131
+ page: cmsPage,
156
132
  globalSections: await globalSectionsPromise,
157
133
  type: 'plp',
158
134
  key: slug,
@@ -1,9 +1,9 @@
1
1
  import { isNotFoundError } from '@faststore/api'
2
2
  import type { Locator } from '@vtex/client-cms'
3
+ import deepmerge from 'deepmerge'
3
4
  import type { GetStaticPaths, GetStaticProps } from 'next'
4
5
  import { BreadcrumbJsonLd, NextSeo, ProductJsonLd } from 'next-seo'
5
6
  import type { ComponentType } from 'react'
6
- import deepmerge from 'deepmerge'
7
7
 
8
8
  import { gql } from '@generated'
9
9
  import {
@@ -20,16 +20,15 @@ import CUSTOM_COMPONENTS from 'src/customizations/src/components'
20
20
  import { useSession } from 'src/sdk/session'
21
21
  import { mark } from 'src/sdk/tests/mark'
22
22
  import { execute } from 'src/server'
23
- import type { PDPContentType } from 'src/server/cms'
24
- import { getPage, getPageByVersionId } from 'src/server/cms'
25
23
 
24
+ import storeConfig from 'faststore.config'
26
25
  import GlobalSections, {
27
26
  GlobalSectionsData,
28
27
  getGlobalSectionsData,
29
28
  } from 'src/components/cms/GlobalSections'
30
- import storeConfig from 'faststore.config'
31
- import { useProductQuery } from 'src/sdk/product/useProductQuery'
32
29
  import PageProvider, { PDPContext } from 'src/sdk/overrides/PageProvider'
30
+ import { useProductQuery } from 'src/sdk/product/useProductQuery'
31
+ import { PDPContentType, getPDP } from 'src/server/cms/pdp'
33
32
 
34
33
  /**
35
34
  * Sections: Components imported from each store's custom components and '../components/sections' only.
@@ -208,26 +207,6 @@ export const getStaticProps: GetStaticProps<
208
207
  getGlobalSectionsData(previewData),
209
208
  ])
210
209
 
211
- let cmsPage
212
-
213
- if (storeConfig.cms.data) {
214
- const cmsData = JSON.parse(storeConfig.cms.data)
215
- const page = cmsData['pdp'][0]
216
-
217
- if (page) {
218
- cmsPage = getPageByVersionId<PDPContentType>({
219
- contentType: 'pdp',
220
- documentId: page.documentId,
221
- versionId: page.versionId,
222
- })
223
- }
224
- } else {
225
- cmsPage = getPage<PDPContentType>({
226
- ...(previewData?.contentType === 'pdp' ? previewData : null),
227
- contentType: 'pdp',
228
- })
229
- }
230
-
231
210
  const { data, errors = [] } = searchResult
232
211
 
233
212
  const notFound = errors.find(isNotFoundError)
@@ -242,6 +221,8 @@ export const getStaticProps: GetStaticProps<
242
221
  throw errors[0]
243
222
  }
244
223
 
224
+ const cmsPage: PDPContentType = await getPDP(slug, data.product, previewData)
225
+
245
226
  const { seo } = data.product
246
227
  const title = seo.title || storeConfig.seo.title
247
228
  const description = seo.description || storeConfig.seo.description
@@ -6,14 +6,14 @@ import type { ComponentType } from 'react'
6
6
  import RenderSections from 'src/components/cms/RenderSections'
7
7
  import { OverriddenDefaultBannerText as BannerText } from 'src/components/sections/BannerText/OverriddenDefaultBannerText'
8
8
  import { OverriddenDefaultHero as Hero } from 'src/components/sections/Hero/OverriddenDefaultHero'
9
+ import Incentives from 'src/components/sections/Incentives'
9
10
  import { OverriddenDefaultNewsletter as Newsletter } from 'src/components/sections/Newsletter/OverriddenDefaultNewsletter'
10
11
  import { OverriddenDefaultProductShelf as ProductShelf } from 'src/components/sections/ProductShelf/OverriddenDefaultProductShelf'
11
- import Incentives from 'src/components/sections/Incentives'
12
12
  import ProductTiles from 'src/components/sections/ProductTiles'
13
13
  import CUSTOM_COMPONENTS from 'src/customizations/src/components'
14
14
  import { mark } from 'src/sdk/tests/mark'
15
15
  import type { PageContentType } from 'src/server/cms'
16
- import { getPage, getPageByVersionId } from 'src/server/cms'
16
+ import { getPage } from 'src/server/cms'
17
17
 
18
18
  import GlobalSections, {
19
19
  GlobalSectionsData,
@@ -92,7 +92,7 @@ export const getStaticProps: GetStaticProps<
92
92
  const page = cmsData['home'][0]
93
93
 
94
94
  if (page) {
95
- const pageData = await getPageByVersionId<PageContentType>({
95
+ const pageData = await getPage<PageContentType>({
96
96
  contentType: 'home',
97
97
  documentId: page.documentId,
98
98
  versionId: page.versionId,
package/src/pages/s.tsx CHANGED
@@ -14,14 +14,14 @@ import { useApplySearchState } from 'src/sdk/search/state'
14
14
  import { mark } from 'src/sdk/tests/mark'
15
15
 
16
16
  import { Locator } from '@vtex/client-cms'
17
+ import storeConfig from 'faststore.config'
17
18
  import { GetStaticProps } from 'next'
18
19
  import GlobalSections, {
19
20
  getGlobalSectionsData,
20
21
  GlobalSectionsData,
21
22
  } from 'src/components/cms/GlobalSections'
22
- import { getPage, getPageByVersionId, SearchContentType } from 'src/server/cms'
23
- import storeConfig from 'faststore.config'
24
23
  import SearchPage from 'src/components/templates/SearchPage/SearchPage'
24
+ import { getPage, SearchContentType } from 'src/server/cms'
25
25
 
26
26
  type Props = {
27
27
  page: SearchContentType
@@ -125,7 +125,7 @@ export const getStaticProps: GetStaticProps<
125
125
  const page = cmsData['search'][0]
126
126
 
127
127
  if (page) {
128
- const pageData = await getPageByVersionId<SearchContentType>({
128
+ const pageData = await getPage<SearchContentType>({
129
129
  contentType: 'search',
130
130
  documentId: page.documentId,
131
131
  versionId: page.versionId,
@@ -1,14 +1,9 @@
1
1
  import type { ContentData, ContentTypeOptions, Locator } from '@vtex/client-cms'
2
2
  import ClientCMS from '@vtex/client-cms'
3
3
 
4
- import config from '../../faststore.config'
5
- import MultipleContentError from 'src/sdk/error/MultipleContentError'
6
4
  import MissingContentError from 'src/sdk/error/MissingContentError'
7
-
8
- export const clientCMS = new ClientCMS({
9
- workspace: config.api.workspace,
10
- tenant: config.api.storeId,
11
- })
5
+ import MultipleContentError from 'src/sdk/error/MultipleContentError'
6
+ import config from '../../../faststore.config'
12
7
 
13
8
  export type Options =
14
9
  | Locator
@@ -17,54 +12,6 @@ export type Options =
17
12
  filters?: Partial<ContentTypeOptions>
18
13
  }
19
14
 
20
- const isLocator = (x: any): x is Locator =>
21
- typeof x.contentType === 'string' &&
22
- (typeof x.releaseId === 'string' || typeof x.documentId === 'string')
23
-
24
- export const getPage = async <T extends ContentData>(options: Options) => {
25
- const result = await (isLocator(options)
26
- ? clientCMS.getCMSPage(options).then((page) => ({ data: [page] }))
27
- : clientCMS.getCMSPagesByContentType(options.contentType, options.filters))
28
-
29
- const pages = result.data
30
-
31
- if (!pages[0]) {
32
- throw new MissingContentError(options)
33
- }
34
-
35
- if (pages.length !== 1) {
36
- throw new MultipleContentError(options)
37
- }
38
-
39
- return pages[0] as T
40
- }
41
-
42
- export type VersionOptions = {
43
- contentType: string
44
- documentId: string
45
- versionId: string
46
- }
47
-
48
- export const getPageByVersionId = async <T extends ContentData>(
49
- options: VersionOptions
50
- ) => {
51
- const result = await clientCMS
52
- .getCMSPage(options)
53
- .then((page) => ({ data: [page] }))
54
-
55
- const pages = result.data
56
-
57
- if (!pages[0]) {
58
- throw new MissingContentError(options)
59
- }
60
-
61
- if (pages.length !== 1) {
62
- throw new MultipleContentError(options)
63
- }
64
-
65
- return pages[0] as T
66
- }
67
-
68
15
  type ProductGallerySettings = {
69
16
  settings: {
70
17
  productGallery: {
@@ -74,8 +21,6 @@ type ProductGallerySettings = {
74
21
  }
75
22
  }
76
23
 
77
- export type PDPContentType = ContentData
78
- export type PLPContentType = ContentData & ProductGallerySettings
79
24
  export type SearchContentType = ContentData & ProductGallerySettings
80
25
 
81
26
  export type PageContentType = ContentData & {
@@ -88,3 +33,36 @@ export type PageContentType = ContentData & {
88
33
  }
89
34
  }
90
35
  }
36
+
37
+ const isLocator = (x: any): x is Locator =>
38
+ typeof x.contentType === 'string' &&
39
+ (typeof x.releaseId === 'string' ||
40
+ typeof x.documentId === 'string' ||
41
+ typeof x.versionId === 'string')
42
+
43
+ export const clientCMS = new ClientCMS({
44
+ workspace: config.api.workspace,
45
+ tenant: config.api.storeId,
46
+ })
47
+
48
+ export const getCMSPage = async (options: Options) => {
49
+ return await (isLocator(options)
50
+ ? clientCMS.getCMSPage(options).then((page) => ({ data: [page] }))
51
+ : clientCMS.getCMSPagesByContentType(options.contentType, options.filters))
52
+ }
53
+
54
+ export const getPage = async <T extends ContentData>(options: Options) => {
55
+ const result = await getCMSPage(options)
56
+
57
+ const pages = result.data
58
+
59
+ if (!pages[0]) {
60
+ throw new MissingContentError(options)
61
+ }
62
+
63
+ if (pages.length !== 1) {
64
+ throw new MultipleContentError(options)
65
+ }
66
+
67
+ return pages[0] as T
68
+ }
@@ -0,0 +1,82 @@
1
+ import { ServerProductQueryQuery } from '@generated/graphql'
2
+ import type { ContentData, Locator } from '@vtex/client-cms'
3
+ import MissingContentError from 'src/sdk/error/MissingContentError'
4
+ import { findBestPDPTemplate } from 'src/utils/utilities'
5
+ import { Options, getCMSPage, getPage } from '.'
6
+ import config from '../../../faststore.config'
7
+
8
+ type PDPSettings = {
9
+ settings: {
10
+ template?: {
11
+ value?: string
12
+ }
13
+ }
14
+ }
15
+
16
+ type PDPfromCmsEnvData = {
17
+ documentId: string
18
+ versionId: string
19
+ } & PDPSettings
20
+
21
+ export type PDPContentType = ContentData & PDPSettings
22
+
23
+ export const getPDP = async (
24
+ slug: string,
25
+ product: ServerProductQueryQuery['product'],
26
+ previewData: Locator
27
+ ) => {
28
+ if (config.cms.data) {
29
+ const cmsData = JSON.parse(config.cms.data)
30
+ const allPDPsFromCmsEnvData: PDPfromCmsEnvData[] = cmsData['pdp']
31
+
32
+ return await getPDPFromCmsEnvData(
33
+ `/${slug}/p`,
34
+ product,
35
+ allPDPsFromCmsEnvData,
36
+ {
37
+ ...(previewData?.contentType === 'pdp' ? previewData : null),
38
+ contentType: 'pdp',
39
+ }
40
+ )
41
+ }
42
+
43
+ return (await getPDPFromCms(`/${slug}/p`, product, {
44
+ ...(previewData?.contentType === 'pdp' ? previewData : null),
45
+ contentType: 'pdp',
46
+ })) as PDPContentType
47
+ }
48
+
49
+ const getPDPFromCmsEnvData = async (
50
+ slug: string,
51
+ product: ServerProductQueryQuery['product'],
52
+ allPDPsFromCMSData: PDPfromCmsEnvData[],
53
+ options: Options
54
+ ): Promise<PDPContentType> => {
55
+ const pages: PDPfromCmsEnvData[] = allPDPsFromCMSData ?? []
56
+
57
+ if (!pages[0]) {
58
+ throw new MissingContentError(options)
59
+ }
60
+
61
+ const template = findBestPDPTemplate(pages, slug, product)
62
+
63
+ return getPage<PDPContentType>({
64
+ contentType: 'pdp',
65
+ documentId: template.documentId as string,
66
+ versionId: template.versionId,
67
+ })
68
+ }
69
+
70
+ const getPDPFromCms = async (
71
+ slug: string,
72
+ product: ServerProductQueryQuery['product'],
73
+ options: Options
74
+ ): Promise<Partial<PDPContentType>> => {
75
+ const pages = (await getCMSPage(options)).data
76
+
77
+ if (!pages[0]) {
78
+ throw new MissingContentError(options)
79
+ }
80
+
81
+ return findBestPDPTemplate(pages, slug, product)
82
+ }
@@ -0,0 +1,74 @@
1
+ import { ContentData, Locator } from '@vtex/client-cms'
2
+ import MissingContentError from 'src/sdk/error/MissingContentError'
3
+ import { findBestPLPTemplate } from 'src/utils/utilities'
4
+ import config from '../../../faststore.config'
5
+ import { Options, getCMSPage, getPage } from '../cms'
6
+
7
+ type PLPSettings = {
8
+ settings: {
9
+ template?: {
10
+ value?: string
11
+ }
12
+ productGallery: {
13
+ itemsPerPage: number
14
+ sortBySelection: string
15
+ }
16
+ }
17
+ }
18
+
19
+ type PLPfromCmsEnvData = {
20
+ documentId: string
21
+ versionId: string
22
+ } & PLPSettings
23
+
24
+ export type PLPContentType = ContentData & PLPSettings
25
+
26
+ export const getPLP = async (slug: string, previewData: Locator) => {
27
+ if (config.cms.data) {
28
+ const cmsData = JSON.parse(config.cms.data)
29
+ const allPLPsFromCmsEnvData: PLPfromCmsEnvData[] = cmsData['plp']
30
+
31
+ return await getPLPFromCmsEnvData(`/${slug}/p`, allPLPsFromCmsEnvData, {
32
+ ...(previewData?.contentType === 'plp' ? previewData : null),
33
+ contentType: 'plp',
34
+ })
35
+ }
36
+
37
+ return (await getPLPFromCms(`/${slug}/p`, {
38
+ ...(previewData?.contentType === 'plp' ? previewData : null),
39
+ contentType: 'plp',
40
+ })) as PLPContentType
41
+ }
42
+
43
+ const getPLPFromCmsEnvData = async (
44
+ slug: string,
45
+ allPLPsFromCMSData: PLPfromCmsEnvData[],
46
+ options: Options
47
+ ): Promise<PLPContentType> => {
48
+ const pages: PLPfromCmsEnvData[] = allPLPsFromCMSData ?? []
49
+
50
+ if (!pages[0]) {
51
+ throw new MissingContentError(options)
52
+ }
53
+
54
+ const template = findBestPLPTemplate(pages, slug)
55
+
56
+ return getPage<PLPContentType>({
57
+ contentType: 'plp',
58
+ documentId: template.documentId as string,
59
+ versionId: template.versionId,
60
+ })
61
+ }
62
+
63
+ export const getPLPFromCms = async (
64
+ slug: string,
65
+ options: Options
66
+ ): Promise<Partial<PLPContentType>> => {
67
+ const pages = (await getCMSPage(options)).data
68
+
69
+ if (!pages[0]) {
70
+ throw new MissingContentError(options)
71
+ }
72
+
73
+ return findBestPLPTemplate(pages, slug)
74
+ }