@faststore/core 2.2.78 → 3.0.1

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 (252) hide show
  1. package/.babelrc.js +12 -0
  2. package/.next/BUILD_ID +1 -1
  3. package/.next/build-manifest.json +89 -89
  4. package/.next/cache/.tsbuildinfo +1 -1
  5. package/.next/cache/config.json +3 -3
  6. package/.next/cache/eslint/.cache_1gneedd +1 -1
  7. package/.next/cache/webpack/client-production/0.pack +0 -0
  8. package/.next/cache/webpack/client-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/images-manifest.json +1 -1
  12. package/.next/next-minimal-server.js.nft.json +1 -0
  13. package/.next/next-server.js.nft.json +1 -1
  14. package/.next/prerender-manifest.js +1 -0
  15. package/.next/prerender-manifest.json +1 -1
  16. package/.next/react-loadable-manifest.json +17 -17
  17. package/.next/required-server-files.json +1 -1
  18. package/.next/routes-manifest.json +1 -1
  19. package/.next/server/chunks/119.js +1 -0
  20. package/.next/server/chunks/12.js +1 -0
  21. package/.next/server/chunks/187.js +1 -0
  22. package/.next/server/chunks/202.js +1 -0
  23. package/.next/server/chunks/24.js +1 -0
  24. package/.next/server/chunks/242.js +1 -0
  25. package/.next/server/chunks/247.js +1 -0
  26. package/.next/server/chunks/344.js +1 -0
  27. package/.next/server/chunks/404.js +1 -434
  28. package/.next/server/chunks/414.js +1 -0
  29. package/.next/server/chunks/484.js +1 -0
  30. package/.next/server/chunks/493.js +1 -0
  31. package/.next/server/chunks/498.js +1 -0
  32. package/.next/server/chunks/540.js +1 -0
  33. package/.next/server/chunks/57.js +1 -434
  34. package/.next/server/chunks/624.js +1 -0
  35. package/.next/server/chunks/640.js +6 -0
  36. package/.next/server/chunks/646.js +279 -0
  37. package/.next/server/chunks/659.js +9 -0
  38. package/.next/server/chunks/679.js +1 -0
  39. package/.next/server/chunks/693.js +1 -58
  40. package/.next/server/chunks/694.js +1 -0
  41. package/.next/server/chunks/779.js +1 -58
  42. package/.next/server/chunks/82.js +8 -0
  43. package/.next/server/chunks/857.js +1 -0
  44. package/.next/server/chunks/859.js +4 -957
  45. package/.next/server/chunks/881.js +1 -0
  46. package/.next/server/chunks/917.js +1 -0
  47. package/.next/server/chunks/936.js +1 -0
  48. package/.next/server/chunks/96.js +1 -0
  49. package/.next/server/chunks/997.js +1 -0
  50. package/.next/server/functions-config-manifest.json +1 -0
  51. package/.next/server/middleware-build-manifest.js +1 -1
  52. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  53. package/.next/server/next-font-manifest.js +1 -0
  54. package/.next/server/next-font-manifest.json +1 -0
  55. package/.next/server/pages/404.js +1 -391
  56. package/.next/server/pages/404.js.nft.json +1 -1
  57. package/.next/server/pages/500.js +1 -395
  58. package/.next/server/pages/500.js.nft.json +1 -1
  59. package/.next/server/pages/[...slug].js +1 -1071
  60. package/.next/server/pages/[...slug].js.nft.json +1 -1
  61. package/.next/server/pages/[slug]/p.js +1 -2315
  62. package/.next/server/pages/[slug]/p.js.nft.json +1 -1
  63. package/.next/server/pages/_app.js +1 -301
  64. package/.next/server/pages/_app.js.nft.json +1 -1
  65. package/.next/server/pages/_document.js +1 -363
  66. package/.next/server/pages/_document.js.nft.json +1 -1
  67. package/.next/server/pages/_error.js +1 -164
  68. package/.next/server/pages/_error.js.nft.json +1 -1
  69. package/.next/server/pages/account.js +1 -370
  70. package/.next/server/pages/account.js.nft.json +1 -1
  71. package/.next/server/pages/api/graphql.js +1 -3085
  72. package/.next/server/pages/api/graphql.js.nft.json +1 -1
  73. package/.next/server/pages/api/health/live.js +1 -31
  74. package/.next/server/pages/api/health/live.js.nft.json +1 -1
  75. package/.next/server/pages/api/health/ready.js +1 -31
  76. package/.next/server/pages/api/health/ready.js.nft.json +1 -1
  77. package/.next/server/pages/api/preview.js +1 -137
  78. package/.next/server/pages/api/preview.js.nft.json +1 -1
  79. package/.next/server/pages/checkout.js +1 -370
  80. package/.next/server/pages/checkout.js.nft.json +1 -1
  81. package/.next/server/pages/en-US/404.html +2 -2
  82. package/.next/server/pages/en-US/404.json +1 -1
  83. package/.next/server/pages/en-US/500.html +2 -2
  84. package/.next/server/pages/en-US/500.json +1 -1
  85. package/.next/server/pages/en-US/account.html +2 -2
  86. package/.next/server/pages/en-US/checkout.html +2 -2
  87. package/.next/server/pages/en-US/login.html +2 -2
  88. package/.next/server/pages/en-US/login.json +1 -1
  89. package/.next/server/pages/en-US/s.html +2 -2
  90. package/.next/server/pages/en-US.html +4 -4
  91. package/.next/server/pages/en-US.json +1 -1
  92. package/.next/server/pages/index.js +1 -439
  93. package/.next/server/pages/index.js.nft.json +1 -1
  94. package/.next/server/pages/login.js +1 -382
  95. package/.next/server/pages/login.js.nft.json +1 -1
  96. package/.next/server/pages/s.js +1 -554
  97. package/.next/server/pages/s.js.nft.json +1 -1
  98. package/.next/server/pages-manifest.json +1 -18
  99. package/.next/server/webpack-api-runtime.js +1 -229
  100. package/.next/server/webpack-runtime.js +1 -229
  101. package/.next/static/Xf_-r26LvSZnfqjpm_a71/_buildManifest.js +1 -0
  102. package/.next/static/chunks/104-d42a7ff6c8b8dd89.js +1 -0
  103. package/.next/static/chunks/161-b39fe2f79ff7bc85.js +1 -0
  104. package/.next/static/chunks/202.c7d8a71173edecfb.js +1 -0
  105. package/.next/static/chunks/217.01bc0ad07edd6f1b.js +1 -0
  106. package/.next/static/chunks/247.52b3924429a474c6.js +1 -0
  107. package/.next/static/chunks/484.b82b73b1d8c37e02.js +1 -0
  108. package/.next/static/chunks/540.6c62d2536d42a1e0.js +1 -0
  109. package/.next/static/chunks/575-853fb8b1ba4ce8c4.js +14 -0
  110. package/.next/static/chunks/624.d3de62b4562a33f3.js +1 -0
  111. package/.next/static/chunks/629-b7b5ef6f15ecba9d.js +1 -0
  112. package/.next/static/chunks/65.da22595d53beae76.js +1 -0
  113. package/.next/static/chunks/758.b53ee01b506973e0.js +1 -0
  114. package/.next/static/chunks/857.d2299cfe995af21d.js +1 -0
  115. package/.next/static/chunks/framework-8e279965036b6169.js +33 -0
  116. package/.next/static/chunks/main-6f63f6746cc029db.js +1 -0
  117. package/.next/static/chunks/pages/404-1334d11ab8467b3d.js +1 -0
  118. package/.next/static/chunks/pages/500-449c5bd51f98423f.js +1 -0
  119. package/.next/static/chunks/pages/[...slug]-7c8ec664c28eca52.js +1 -0
  120. package/.next/static/chunks/pages/[slug]/p-a4f7d7c00fdf4157.js +1 -0
  121. package/.next/static/chunks/pages/_app-6516d0c2c7e0e686.js +68 -0
  122. package/.next/static/chunks/pages/_error-fbf331a03642b495.js +1 -0
  123. package/.next/static/chunks/pages/account-dbc5c028225cd1ac.js +1 -0
  124. package/.next/static/chunks/pages/checkout-29ae2c37eaf172e1.js +1 -0
  125. package/.next/static/chunks/pages/index-00798cca3b47590d.js +1 -0
  126. package/.next/static/chunks/pages/login-c4d2c856008df5ac.js +1 -0
  127. package/.next/static/chunks/pages/s-dacaed02ad104d73.js +1 -0
  128. package/.next/static/chunks/webpack-1c08d77cfe1b8585.js +1 -0
  129. package/.next/static/css/{021de9c7b050d301.css → 0d45c82d8887a269.css} +1 -1
  130. package/.next/static/css/{e772e7786bb4dee9.css → 211c7542af66d8b4.css} +1 -1
  131. package/.next/static/css/{df588bb98c0b0ca6.css → 2980acad3f8e1028.css} +1 -1
  132. package/.next/static/css/{510895065f32ed2f.css → 4c4d90eb8cb1d2b7.css} +1 -1
  133. package/.next/static/css/{938781cdc945862e.css → 821a5219786be653.css} +1 -1
  134. package/.next/static/css/{def381bf7c69fa2e.css → 96e3fddf695d6aa9.css} +1 -1
  135. package/.next/static/css/{6a7fdc5a21fbead5.css → b9d9ba1b04f3160d.css} +1 -1
  136. package/.next/static/css/{9558da13053ac066.css → cff9aafa16fccc9c.css} +1 -1
  137. package/.next/static/css/{7e897ebb936fac09.css → d586715f4f707df4.css} +1 -1
  138. package/.next/static/css/{cb7d1fcea42fab9c.css → e32410b31c666cb2.css} +1 -1
  139. package/.next/trace +91 -82
  140. package/.turbo/turbo-build.log +37 -42
  141. package/.turbo/turbo-lint.log +0 -3
  142. package/.turbo/turbo-test.log +9 -9
  143. package/@generated/gql.ts +196 -0
  144. package/@generated/{graphql/index.ts → graphql.ts} +718 -252
  145. package/@generated/index.ts +1 -0
  146. package/@generated/persisted-documents.json +13 -0
  147. package/api/index.ts +1 -1
  148. package/cms/faststore/content-types.json +18 -0
  149. package/cms/faststore/sections.json +73 -0
  150. package/codegen.ts +61 -0
  151. package/index.ts +1 -0
  152. package/jest.config.js +9 -1
  153. package/next.config.js +2 -0
  154. package/package.json +14 -10
  155. package/src/components/product/ProductCard/ProductCard.tsx +4 -4
  156. package/src/components/search/Filter/Filter.tsx +4 -3
  157. package/src/components/sections/EmptyState/DefaultComponents.ts +5 -0
  158. package/src/components/sections/EmptyState/EmptyState.tsx +91 -8
  159. package/src/components/sections/EmptyState/OverriddenDefaultEmptyState.ts +15 -0
  160. package/src/components/sections/ProductDetails/ProductDetails.tsx +6 -6
  161. package/src/components/ui/Image/Image.tsx +1 -1
  162. package/src/customizations/src/fragments/ClientManyProducts.ts +3 -3
  163. package/src/customizations/src/fragments/ClientProduct.ts +3 -3
  164. package/src/customizations/src/fragments/ClientProductGallery.ts +3 -3
  165. package/src/customizations/src/fragments/ClientSearchSuggestions.ts +3 -3
  166. package/src/customizations/src/fragments/ClientShippingSimulation.ts +3 -3
  167. package/src/customizations/src/fragments/ClientTopSearchSuggestions.ts +3 -3
  168. package/src/customizations/src/fragments/ServerCollectionPage.ts +3 -3
  169. package/src/customizations/src/fragments/ServerProduct.ts +3 -3
  170. package/src/pages/404.tsx +32 -30
  171. package/src/pages/500.tsx +32 -34
  172. package/src/pages/[...slug].tsx +4 -4
  173. package/src/pages/[slug]/p.tsx +7 -7
  174. package/src/pages/api/graphql.ts +10 -4
  175. package/src/pages/login.tsx +31 -8
  176. package/src/sdk/cart/index.ts +3 -3
  177. package/src/sdk/graphql/prefetchQuery.ts +4 -3
  178. package/src/sdk/graphql/request.ts +67 -8
  179. package/src/sdk/graphql/useLazyQuery.ts +4 -3
  180. package/src/sdk/graphql/useQuery.ts +7 -3
  181. package/src/sdk/newsletter/useNewsletter.ts +4 -4
  182. package/src/sdk/product/usePageProductsQuery.ts +3 -3
  183. package/src/sdk/product/useProductGalleryQuery.ts +10 -8
  184. package/src/sdk/product/useProductQuery.ts +3 -3
  185. package/src/sdk/product/useProductsPrefetch.ts +5 -3
  186. package/src/sdk/product/useProductsQuery.ts +3 -4
  187. package/src/sdk/search/useSuggestions.ts +3 -3
  188. package/src/sdk/search/useTopSearch.ts +3 -4
  189. package/src/sdk/session/index.ts +4 -4
  190. package/src/sdk/shipping/index.ts +3 -3
  191. package/src/server/generator/schema.ts +1 -1
  192. package/src/server/index.ts +11 -6
  193. package/src/typings/overrides.ts +3 -2
  194. package/test/server/index.test.ts +6 -1
  195. package/.babelrc +0 -4
  196. package/.next/cache/next-server.js.nft.json +0 -1
  197. package/.next/server/chunks/117.js +0 -427
  198. package/.next/server/chunks/177.js +0 -125
  199. package/.next/server/chunks/183.js +0 -122
  200. package/.next/server/chunks/184.js +0 -61
  201. package/.next/server/chunks/289.js +0 -243
  202. package/.next/server/chunks/312.js +0 -676
  203. package/.next/server/chunks/350.js +0 -2898
  204. package/.next/server/chunks/386.js +0 -200
  205. package/.next/server/chunks/574.js +0 -145
  206. package/.next/server/chunks/576.js +0 -122
  207. package/.next/server/chunks/585.js +0 -639
  208. package/.next/server/chunks/632.js +0 -514
  209. package/.next/server/chunks/661.js +0 -1451
  210. package/.next/server/chunks/676.js +0 -32
  211. package/.next/server/chunks/719.js +0 -84
  212. package/.next/server/chunks/74.js +0 -4152
  213. package/.next/server/chunks/825.js +0 -4074
  214. package/.next/server/chunks/854.js +0 -72
  215. package/.next/server/chunks/863.js +0 -111
  216. package/.next/server/chunks/898.js +0 -711
  217. package/.next/server/chunks/903.js +0 -1926
  218. package/.next/server/chunks/98.js +0 -163
  219. package/.next/server/chunks/988.js +0 -211
  220. package/.next/static/JJRI44e-3F3WVhD-DxmO2/_buildManifest.js +0 -1
  221. package/.next/static/chunks/223-cb77217cce52d45c.js +0 -1
  222. package/.next/static/chunks/251.11f5198fc8bef3a4.js +0 -1
  223. package/.next/static/chunks/386.d01e0db26c523f0f.js +0 -1
  224. package/.next/static/chunks/397-0d3aada1012cd78b.js +0 -1
  225. package/.next/static/chunks/574.70612be06fd1365f.js +0 -1
  226. package/.next/static/chunks/585.6561778b7763b79e.js +0 -1
  227. package/.next/static/chunks/651.7142f31ce1e052b3.js +0 -1
  228. package/.next/static/chunks/675-479a97aecebead97.js +0 -1
  229. package/.next/static/chunks/741.52f7fb873418346f.js +0 -1
  230. package/.next/static/chunks/800.5d92de2974baf641.js +0 -1
  231. package/.next/static/chunks/881-57643fb90f59e576.js +0 -1
  232. package/.next/static/chunks/98.40c7e17d9de4eb8f.js +0 -1
  233. package/.next/static/chunks/988.afda042dd9ba11d1.js +0 -1
  234. package/.next/static/chunks/framework-dfd14d7ce6600b03.js +0 -1
  235. package/.next/static/chunks/main-e4e873ee741162eb.js +0 -1
  236. package/.next/static/chunks/pages/404-e106cb9a78182f5f.js +0 -1
  237. package/.next/static/chunks/pages/500-d28aa4a8ce88bddd.js +0 -1
  238. package/.next/static/chunks/pages/[...slug]-c4abcc133f85d9d0.js +0 -1
  239. package/.next/static/chunks/pages/[slug]/p-4a75b11857b82b5c.js +0 -1
  240. package/.next/static/chunks/pages/_app-30b9666307e4b3b1.js +0 -1
  241. package/.next/static/chunks/pages/_error-319451dea77827a6.js +0 -1
  242. package/.next/static/chunks/pages/account-bf9c88a9cac80d8a.js +0 -1
  243. package/.next/static/chunks/pages/checkout-6ca76c1e88a28ac4.js +0 -1
  244. package/.next/static/chunks/pages/index-629ba146ae5f0ecf.js +0 -1
  245. package/.next/static/chunks/pages/login-d2af0de13ea75848.js +0 -1
  246. package/.next/static/chunks/pages/s-d729254b91430d1c.js +0 -1
  247. package/.next/static/chunks/webpack-54ce04ec11860b0b.js +0 -1
  248. package/@generated/graphql/persisted.json +0 -13
  249. package/codegen.yml +0 -23
  250. package/src/components/sections/EmptyState/Overrides.tsx +0 -14
  251. package/.next/static/{JJRI44e-3F3WVhD-DxmO2 → Xf_-r26LvSZnfqjpm_a71}/_ssgManifest.js +0 -0
  252. package/@generated/{graphql/schema.graphql → schema.graphql} +508 -508
@@ -1,9 +1,9 @@
1
- import { gql } from '@faststore/graphql-utils'
1
+ import { gql } from '@generated'
2
2
 
3
- export const fragment = gql`
3
+ export const fragment = gql(`
4
4
  fragment ServerCollectionPage on Query {
5
5
  collection(slug: $slug) {
6
6
  id
7
7
  }
8
8
  }
9
- `
9
+ `)
@@ -1,9 +1,9 @@
1
- import { gql } from '@faststore/graphql-utils'
1
+ import { gql } from '@generated'
2
2
 
3
- export const fragment = gql`
3
+ export const fragment = gql(`
4
4
  fragment ServerProduct on Query {
5
5
  product(locator: $locator) {
6
6
  id: productID
7
7
  }
8
8
  }
9
- `
9
+ `)
package/src/pages/404.tsx CHANGED
@@ -1,48 +1,44 @@
1
+ import { Locator } from '@vtex/client-cms'
2
+ import { GetStaticProps } from 'next'
1
3
  import { NextSeo } from 'next-seo'
2
- import { useRouter } from 'next/router'
3
4
  import GlobalSections, {
4
5
  GlobalSectionsData,
5
6
  getGlobalSectionsData,
6
7
  } from 'src/components/cms/GlobalSections'
7
- import { GetStaticProps } from 'next'
8
- import { Locator } from '@vtex/client-cms'
9
-
10
- import { Icon as UIIcon } from '@faststore/ui'
11
- import EmptyState from 'src/components/sections/EmptyState'
8
+ import type { ComponentType } from 'react'
12
9
 
13
- const useErrorState = () => {
14
- const router = useRouter()
15
- const { pathname, asPath } = router
10
+ import RenderSections from 'src/components/cms/RenderSections'
11
+ import { OverriddenDefaultEmptyState as EmptyState } from 'src/components/sections/EmptyState/OverriddenDefaultEmptyState'
12
+ import CUSTOM_COMPONENTS from 'src/customizations/src/components'
13
+ import { PageContentType, getPage } from 'src/server/cms'
16
14
 
17
- return {
18
- fromUrl: asPath ?? pathname,
19
- }
15
+ /* A list of components that can be used in the CMS. */
16
+ const COMPONENTS: Record<string, ComponentType<any>> = {
17
+ EmptyState,
18
+ ...CUSTOM_COMPONENTS,
20
19
  }
21
20
 
22
21
  type Props = {
22
+ page: PageContentType
23
23
  globalSections: GlobalSectionsData
24
24
  }
25
25
 
26
- function Page({ globalSections }: Props) {
27
- const { fromUrl } = useErrorState()
28
-
26
+ function Page({ page: { sections }, globalSections }: Props) {
29
27
  return (
30
28
  <GlobalSections {...globalSections}>
31
29
  <NextSeo noindex nofollow />
30
+ {/*
31
+ WARNING: Do not import or render components from any
32
+ other folder than '../components/sections' in here.
33
+
34
+ This is necessary to keep the integration with the CMS
35
+ easy and consistent, enabling the change and reorder
36
+ of elements on this page.
32
37
 
33
- <EmptyState
34
- title="Not Found: 404"
35
- titleIcon={
36
- <UIIcon
37
- name="CircleWavyWarning"
38
- width={56}
39
- height={56}
40
- weight="thin"
41
- />
42
- }
43
- >
44
- <p>This app could not find url {fromUrl}</p>
45
- </EmptyState>
38
+ If needed, wrap your component in a <Section /> component
39
+ (not the HTML tag) before rendering it here.
40
+ */}
41
+ <RenderSections sections={sections} components={COMPONENTS} />
46
42
  </GlobalSections>
47
43
  )
48
44
  }
@@ -52,10 +48,16 @@ export const getStaticProps: GetStaticProps<
52
48
  Record<string, string>,
53
49
  Locator
54
50
  > = async ({ previewData }) => {
55
- const globalSections = await getGlobalSectionsData(previewData)
51
+ const [page, globalSections] = await Promise.all([
52
+ getPage<PageContentType>({
53
+ ...(previewData?.contentType === '404' && previewData),
54
+ contentType: '404',
55
+ }),
56
+ getGlobalSectionsData(previewData),
57
+ ])
56
58
 
57
59
  return {
58
- props: { globalSections },
60
+ props: { page, globalSections },
59
61
  }
60
62
  }
61
63
 
package/src/pages/500.tsx CHANGED
@@ -1,53 +1,45 @@
1
1
  import { Locator } from '@vtex/client-cms'
2
2
  import { GetStaticProps } from 'next'
3
3
  import { NextSeo } from 'next-seo'
4
- import { useRouter } from 'next/router'
5
4
  import GlobalSections, {
6
5
  GlobalSectionsData,
7
6
  getGlobalSectionsData,
8
7
  } from 'src/components/cms/GlobalSections'
8
+ import type { ComponentType } from 'react'
9
9
 
10
- import { Icon as UIIcon } from '@faststore/ui'
11
- import EmptyState from 'src/components/sections/EmptyState'
10
+ import RenderSections from 'src/components/cms/RenderSections'
11
+ import { OverriddenDefaultEmptyState as EmptyState } from 'src/components/sections/EmptyState/OverriddenDefaultEmptyState'
12
+ import CUSTOM_COMPONENTS from 'src/customizations/src/components'
13
+ import { PageContentType, getPage } from 'src/server/cms'
12
14
 
13
- type Props = {
14
- globalSections: GlobalSectionsData
15
+ /* A list of components that can be used in the CMS. */
16
+ const COMPONENTS: Record<string, ComponentType<any>> = {
17
+ EmptyState,
18
+ ...CUSTOM_COMPONENTS,
15
19
  }
16
20
 
17
- const useErrorState = () => {
18
- const router = useRouter()
19
- const { errorId, fromUrl } = router.query
20
-
21
- return {
22
- errorId,
23
- fromUrl,
24
- }
21
+ type Props = {
22
+ page: PageContentType
23
+ globalSections: GlobalSectionsData
25
24
  }
26
25
 
27
- function Page({ globalSections }: Props) {
28
- const { errorId, fromUrl } = useErrorState()
29
-
26
+ function Page({ page: { sections }, globalSections }: Props) {
30
27
  return (
31
28
  <GlobalSections {...globalSections}>
32
29
  <NextSeo noindex nofollow />
33
30
 
34
- <EmptyState
35
- title="500"
36
- titleIcon={
37
- <UIIcon
38
- name="CircleWavyWarning"
39
- width={56}
40
- height={56}
41
- weight="thin"
42
- />
43
- }
44
- >
45
- <h2>Internal Server Error</h2>
31
+ {/*
32
+ WARNING: Do not import or render components from any
33
+ other folder than '../components/sections' in here.
34
+
35
+ This is necessary to keep the integration with the CMS
36
+ easy and consistent, enabling the change and reorder
37
+ of elements on this page.
46
38
 
47
- <div>
48
- The server errored with id {errorId} when visiting page {fromUrl}
49
- </div>
50
- </EmptyState>
39
+ If needed, wrap your component in a <Section /> component
40
+ (not the HTML tag) before rendering it here.
41
+ */}
42
+ <RenderSections sections={sections} components={COMPONENTS} />
51
43
  </GlobalSections>
52
44
  )
53
45
  }
@@ -57,10 +49,16 @@ export const getStaticProps: GetStaticProps<
57
49
  Record<string, string>,
58
50
  Locator
59
51
  > = async ({ previewData }) => {
60
- const globalSections = await getGlobalSectionsData(previewData)
52
+ const [page, globalSections] = await Promise.all([
53
+ getPage<PageContentType>({
54
+ ...(previewData?.contentType === '500' && previewData),
55
+ contentType: '500',
56
+ }),
57
+ getGlobalSectionsData(previewData),
58
+ ])
61
59
 
62
60
  return {
63
- props: { globalSections },
61
+ props: { page, globalSections },
64
62
  }
65
63
  }
66
64
 
@@ -1,7 +1,7 @@
1
1
  import { isNotFoundError } from '@faststore/api'
2
- import { gql } from '@faststore/graphql-utils'
3
2
  import type { GetStaticPaths, GetStaticProps } from 'next'
4
3
 
4
+ import { gql } from '@generated'
5
5
  import type {
6
6
  ServerCollectionPageQueryQuery,
7
7
  ServerCollectionPageQueryQueryVariables,
@@ -52,7 +52,7 @@ function Page({ globalSections, type, ...otherProps }: Props) {
52
52
  )
53
53
  }
54
54
 
55
- const query = gql`
55
+ const query = gql(`
56
56
  query ServerCollectionPageQuery($slug: String!) {
57
57
  ...ServerCollectionPage
58
58
  collection(slug: $slug) {
@@ -75,7 +75,7 @@ const query = gql`
75
75
  }
76
76
  }
77
77
  }
78
- `
78
+ `)
79
79
 
80
80
  export const getStaticProps: GetStaticProps<
81
81
  Props,
@@ -106,7 +106,7 @@ export const getStaticProps: GetStaticProps<
106
106
  ServerCollectionPageQueryQuery
107
107
  >({
108
108
  variables: { slug },
109
- operationName: query,
109
+ operation: query,
110
110
  }),
111
111
  getPage<PLPContentType>({
112
112
  ...(previewData?.contentType === 'plp' ? previewData : null),
@@ -1,14 +1,14 @@
1
1
  import { isNotFoundError } from '@faststore/api'
2
- import { gql } from '@faststore/graphql-utils'
3
2
  import type { Locator } from '@vtex/client-cms'
4
3
  import type { GetStaticPaths, GetStaticProps } from 'next'
5
4
  import { BreadcrumbJsonLd, NextSeo, ProductJsonLd } from 'next-seo'
6
5
  import type { ComponentType } from 'react'
7
6
  import deepmerge from 'deepmerge'
8
7
 
9
- import type {
10
- ServerProductQueryQuery,
11
- ServerProductQueryQueryVariables,
8
+ import { gql } from '@generated'
9
+ import {
10
+ type ServerProductQueryQuery,
11
+ type ServerProductQueryQueryVariables,
12
12
  } from '@generated/graphql'
13
13
  import RenderSections from 'src/components/cms/RenderSections'
14
14
  import BannerNewsletter from 'src/components/sections/BannerNewsletter/BannerNewsletter'
@@ -134,7 +134,7 @@ function Page({ data: server, sections, globalSections, offers, meta }: Props) {
134
134
  )
135
135
  }
136
136
 
137
- const query = gql`
137
+ const query = gql(`
138
138
  query ServerProductQuery($locator: [IStoreSelectedFacet!]!) {
139
139
  ...ServerProduct
140
140
  product(locator: $locator) {
@@ -192,7 +192,7 @@ const query = gql`
192
192
  ...ProductDetailsFragment_product
193
193
  }
194
194
  }
195
- `
195
+ `)
196
196
 
197
197
  export const getStaticProps: GetStaticProps<
198
198
  Props,
@@ -203,7 +203,7 @@ export const getStaticProps: GetStaticProps<
203
203
  const [searchResult, cmsPage, globalSections] = await Promise.all([
204
204
  execute<ServerProductQueryQueryVariables, ServerProductQueryQuery>({
205
205
  variables: { locator: [{ key: 'slug', value: slug }] },
206
- operationName: query,
206
+ operation: query,
207
207
  }),
208
208
  getPage<PDPContentType>({
209
209
  ...(previewData?.contentType === 'pdp' ? previewData : null),
@@ -23,11 +23,12 @@ const replaceSetCookieDomain = (request: NextApiRequest, setCookie: string) => {
23
23
  }
24
24
 
25
25
  const parseRequest = (request: NextApiRequest) => {
26
- const { operationName, variables, query } =
26
+ const { operationName, operationHash, variables, query } =
27
27
  request.method === 'POST'
28
28
  ? request.body
29
29
  : {
30
30
  operationName: request.query.operationName,
31
+ operationHash: request.query.operationHash,
31
32
  variables: JSON.parse(
32
33
  typeof request.query.variables === 'string'
33
34
  ? request.query.variables
@@ -37,7 +38,12 @@ const parseRequest = (request: NextApiRequest) => {
37
38
  }
38
39
 
39
40
  return {
40
- operationName,
41
+ operation: {
42
+ __meta__: {
43
+ operationName,
44
+ operationHash,
45
+ },
46
+ },
41
47
  variables,
42
48
  // Do not allow queries in production, only for devMode so we can use graphql tools
43
49
  // like introspection etc. In production, we only accept known queries for better
@@ -53,12 +59,12 @@ const handler: NextApiHandler = async (request, response) => {
53
59
  return
54
60
  }
55
61
 
56
- const { operationName, variables, query } = parseRequest(request)
62
+ const { operation, variables, query } = parseRequest(request)
57
63
 
58
64
  try {
59
65
  const { data, errors, extensions } = await execute(
60
66
  {
61
- operationName,
67
+ operation,
62
68
  variables,
63
69
  query,
64
70
  },
@@ -1,5 +1,6 @@
1
1
  import { useEffect } from 'react'
2
2
  import { NextSeo } from 'next-seo'
3
+ import type { ComponentType } from 'react'
3
4
 
4
5
  import storeConfig from '../../faststore.config'
5
6
  import GlobalSections, {
@@ -8,15 +9,23 @@ import GlobalSections, {
8
9
  } from 'src/components/cms/GlobalSections'
9
10
  import { GetStaticProps } from 'next'
10
11
  import { Locator } from '@vtex/client-cms'
12
+ import RenderSections from 'src/components/cms/RenderSections'
13
+ import { OverriddenDefaultEmptyState as EmptyState } from 'src/components/sections/EmptyState/OverriddenDefaultEmptyState'
14
+ import CUSTOM_COMPONENTS from 'src/customizations/src/components'
15
+ import { PageContentType, getPage } from 'src/server/cms'
11
16
 
12
- import { Loader as UILoader } from '@faststore/ui'
13
- import EmptyState from 'src/components/sections/EmptyState'
17
+ /* A list of components that can be used in the CMS. */
18
+ const COMPONENTS: Record<string, ComponentType<any>> = {
19
+ EmptyState,
20
+ ...CUSTOM_COMPONENTS,
21
+ }
14
22
 
15
23
  type Props = {
24
+ page: PageContentType
16
25
  globalSections: GlobalSectionsData
17
26
  }
18
27
 
19
- function Page({ globalSections }: Props) {
28
+ function Page({ page: { sections }, globalSections }: Props) {
20
29
  useEffect(() => {
21
30
  const loginUrl = new URL(storeConfig.loginUrl)
22
31
  const incomingParams = new URLSearchParams(window.location.search)
@@ -31,10 +40,18 @@ function Page({ globalSections }: Props) {
31
40
  return (
32
41
  <GlobalSections {...globalSections}>
33
42
  <NextSeo noindex nofollow />
43
+ {/*
44
+ WARNING: Do not import or render components from any
45
+ other folder than '../components/sections' in here.
46
+
47
+ This is necessary to keep the integration with the CMS
48
+ easy and consistent, enabling the change and reorder
49
+ of elements on this page.
34
50
 
35
- <EmptyState title="Loading">
36
- <UILoader />
37
- </EmptyState>
51
+ If needed, wrap your component in a <Section /> component
52
+ (not the HTML tag) before rendering it here.
53
+ */}
54
+ <RenderSections sections={sections} components={COMPONENTS} />
38
55
  </GlobalSections>
39
56
  )
40
57
  }
@@ -44,10 +61,16 @@ export const getStaticProps: GetStaticProps<
44
61
  Record<string, string>,
45
62
  Locator
46
63
  > = async ({ previewData }) => {
47
- const globalSections = await getGlobalSectionsData(previewData)
64
+ const [page, globalSections] = await Promise.all([
65
+ getPage<PageContentType>({
66
+ ...(previewData?.contentType === 'login' && previewData),
67
+ contentType: 'login',
68
+ }),
69
+ getGlobalSectionsData(previewData),
70
+ ])
48
71
 
49
72
  return {
50
- props: { globalSections },
73
+ props: { page, globalSections },
51
74
  }
52
75
  }
53
76
 
@@ -1,8 +1,8 @@
1
- import { gql } from '@faststore/graphql-utils'
2
1
  import type { Cart as SDKCart, CartItem as SDKCartItem } from '@faststore/sdk'
3
2
  import { createCartStore } from '@faststore/sdk'
4
3
  import { useMemo } from 'react'
5
4
 
5
+ import { gql } from '@generated'
6
6
  import type {
7
7
  CartItemFragment,
8
8
  CartMessageFragment,
@@ -23,7 +23,7 @@ export interface Cart extends SDKCart<CartItem> {
23
23
  shouldSplitItem?: boolean
24
24
  }
25
25
 
26
- export const ValidateCartMutation = gql`
26
+ export const ValidateCartMutation = gql(`
27
27
  mutation ValidateCartMutation($cart: IStoreCart!, $session: IStoreSession!) {
28
28
  validateCart(cart: $cart, session: $session) {
29
29
  order {
@@ -82,7 +82,7 @@ export const ValidateCartMutation = gql`
82
82
  valueReference
83
83
  }
84
84
  }
85
- `
85
+ `)
86
86
 
87
87
  const isGift = (item: CartItem) => item.price === 0
88
88
 
@@ -4,17 +4,18 @@ import type { Cache } from 'swr'
4
4
  import { request } from './request'
5
5
  import { getKey } from './useQuery'
6
6
  import type { RequestOptions } from './request'
7
+ import { TypedDocumentString } from '@generated/graphql'
7
8
 
8
9
  export const prefetchQuery = <Data, Variables = Record<string, unknown>>(
9
- operationName: string,
10
+ operation: TypedDocumentString<any, any>,
10
11
  variables: Variables,
11
12
  { cache, ...options }: Partial<RequestOptions> & { cache: Cache }
12
13
  ) => {
13
- const key = getKey(operationName, variables)
14
+ const key = getKey(operation['__meta__']['operationName'], variables)
14
15
 
15
16
  if (cache.get(key)) {
16
17
  return
17
18
  }
18
19
 
19
- mutate(key, request<Data, Variables>(operationName, variables, options))
20
+ mutate(key, request<Data, Variables>(operation, variables, options))
20
21
  }
@@ -1,20 +1,33 @@
1
- import { request as baseRequest } from '@faststore/graphql-utils'
2
- import type { RequestOptions as GraphQLRequestOptions } from '@faststore/graphql-utils'
1
+ import { TypedDocumentString } from '@generated/graphql'
3
2
 
4
- export type RequestOptions = Omit<
5
- GraphQLRequestOptions,
6
- 'operationName' | 'variables'
7
- >
3
+ export type RequestOptions = Omit<BaseRequestOptions, 'operation' | 'variables'>
4
+
5
+ export interface GraphQLResponse<D = any> {
6
+ data: D
7
+ errors: any[]
8
+ }
9
+
10
+ export interface BaseRequestOptions<V = any> {
11
+ operation: TypedDocumentString<any, any>
12
+ variables: V
13
+ fetchOptions?: RequestInit
14
+ }
15
+
16
+ const DEFAULT_HEADERS_BY_VERB: Record<string, Record<string, string>> = {
17
+ POST: {
18
+ 'Content-Type': 'application/json',
19
+ },
20
+ }
8
21
 
9
22
  export const request = async <Query = unknown, Variables = unknown>(
10
- operationName: string,
23
+ operation: TypedDocumentString<any, any>,
11
24
  variables: Variables,
12
25
  options?: RequestOptions
13
26
  ) => {
14
27
  const { data, errors } = await baseRequest<Variables, Query>('/api/graphql', {
15
28
  ...options,
16
29
  variables,
17
- operationName,
30
+ operation,
18
31
  })
19
32
 
20
33
  if (errors?.length) {
@@ -23,3 +36,49 @@ export const request = async <Query = unknown, Variables = unknown>(
23
36
 
24
37
  return data
25
38
  }
39
+
40
+ /* This piece of code was taken out of @faststore/graphql-utils */
41
+ const baseRequest = async <V = any, D = any>(
42
+ endpoint: string,
43
+ { operation, variables, fetchOptions }: BaseRequestOptions<V>
44
+ ): Promise<GraphQLResponse<D>> => {
45
+ const { operationName, operationHash } = operation['__meta__']
46
+
47
+ // Uses method from fetchOptions.
48
+ // If no one is passed, figure out with via heuristic
49
+ const method =
50
+ fetchOptions?.method !== undefined
51
+ ? fetchOptions.method.toUpperCase()
52
+ : operationName.endsWith('Query')
53
+ ? 'GET'
54
+ : 'POST'
55
+
56
+ const params = new URLSearchParams({
57
+ operationName,
58
+ operationHash,
59
+ ...(method === 'GET' && { variables: JSON.stringify(variables) }),
60
+ })
61
+
62
+ const body =
63
+ method === 'POST'
64
+ ? JSON.stringify({
65
+ operationName,
66
+ operationHash,
67
+ variables,
68
+ })
69
+ : undefined
70
+
71
+ const url = `${endpoint}?${params.toString()}`
72
+
73
+ const response = await fetch(url, {
74
+ method,
75
+ body,
76
+ ...fetchOptions,
77
+ headers: {
78
+ ...DEFAULT_HEADERS_BY_VERB[method],
79
+ ...fetchOptions?.headers,
80
+ },
81
+ })
82
+
83
+ return response.json()
84
+ }
@@ -3,21 +3,22 @@ import useSWR from 'swr'
3
3
  import { request } from './request'
4
4
  import { DEFAULT_OPTIONS, getKey } from './useQuery'
5
5
  import type { QueryOptions } from './useQuery'
6
+ import { TypedDocumentString } from '@generated/graphql'
6
7
 
7
8
  export const useLazyQuery = <Data, Variables = Record<string, unknown>>(
8
- operationName: string,
9
+ operation: TypedDocumentString<any, any>,
9
10
  variables: Variables,
10
11
  options?: QueryOptions
11
12
  ) => {
12
13
  const response = useSWR<Data | null>(
13
- getKey(operationName, variables),
14
+ getKey(operation['__meta__']['operationName'], variables),
14
15
  () => null,
15
16
  DEFAULT_OPTIONS
16
17
  )
17
18
 
18
19
  const execute = async (queryVariables: Variables) => {
19
20
  const data = await request<Data, Variables>(
20
- operationName,
21
+ operation,
21
22
  queryVariables,
22
23
  options
23
24
  )
@@ -3,6 +3,7 @@ import type { SWRConfiguration } from 'swr'
3
3
 
4
4
  import { request } from './request'
5
5
  import type { RequestOptions } from './request'
6
+ import { TypedDocumentString } from '@generated/graphql'
6
7
 
7
8
  export type QueryOptions = SWRConfiguration &
8
9
  RequestOptions & { doNotRun?: boolean }
@@ -22,18 +23,21 @@ export const DEFAULT_OPTIONS = {
22
23
  }
23
24
 
24
25
  export const useQuery = <Data, Variables = Record<string, unknown>>(
25
- operationName: string,
26
+ operation: TypedDocumentString<any, any>,
26
27
  variables: Variables,
27
28
  options?: QueryOptions
28
29
  ) =>
29
30
  useSWR<Data>(
30
- () => (options?.doNotRun ? null : getKey(operationName, variables)),
31
+ () =>
32
+ options?.doNotRun
33
+ ? null
34
+ : getKey(operation['__meta__']['operationName'], variables),
31
35
  {
32
36
  fetcher: () => {
33
37
  return new Promise((resolve) => {
34
38
  setTimeout(async () => {
35
39
  resolve(
36
- await request<Data, Variables>(operationName, variables, options)
40
+ await request<Data, Variables>(operation, variables, options)
37
41
  )
38
42
  })
39
43
  })
@@ -1,18 +1,18 @@
1
- import { gql } from '@faststore/graphql-utils'
1
+ import { gql } from '@generated'
2
2
 
3
3
  import type {
4
4
  SubscribeToNewsletterMutation as Mutation,
5
5
  SubscribeToNewsletterMutationVariables as Variables,
6
- } from '../../../@generated/graphql/index'
6
+ } from '../../../@generated/graphql'
7
7
  import { useLazyQuery } from '../graphql/useLazyQuery'
8
8
 
9
- export const mutation = gql`
9
+ export const mutation = gql(`
10
10
  mutation SubscribeToNewsletter($data: IPersonNewsletter!) {
11
11
  subscribeToNewsletter(data: $data) {
12
12
  id
13
13
  }
14
14
  }
15
- `
15
+ `)
16
16
 
17
17
  export const useNewsletter = () => {
18
18
  const [subscribeUser, { data, error, isValidating: loading }] = useLazyQuery<
@@ -1,5 +1,5 @@
1
- import { gql } from '@faststore/graphql-utils'
2
1
  import { useSearch } from '@faststore/sdk'
2
+ import { gql } from '@generated'
3
3
  import {
4
4
  ClientManyProductsQueryQuery,
5
5
  ClientManyProductsQueryQueryVariables,
@@ -30,7 +30,7 @@ export const useGalleryPage = (page: number) => {
30
30
  return useGalleryPageCallback(page)
31
31
  }
32
32
 
33
- export const query = gql`
33
+ export const query = gql(`
34
34
  query ClientManyProductsQuery(
35
35
  $first: Int!
36
36
  $after: String
@@ -58,7 +58,7 @@ export const query = gql`
58
58
  }
59
59
  }
60
60
  }
61
- `
61
+ `)
62
62
 
63
63
  const getKey = (object: any) => JSON.stringify(object)
64
64