@faststore/core 2.1.90 → 2.2.0-alpha.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 (149) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +31 -31
  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/next-server.js.nft.json +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/next-server.js.nft.json +1 -1
  12. package/.next/prerender-manifest.json +1 -1
  13. package/.next/react-loadable-manifest.json +1 -1
  14. package/.next/routes-manifest.json +1 -1
  15. package/.next/server/chunks/{907.js → 112.js} +422 -278
  16. package/.next/server/chunks/177.js +3 -3
  17. package/.next/server/chunks/183.js +1 -1
  18. package/.next/server/chunks/184.js +4 -4
  19. package/.next/server/chunks/186.js +7 -7
  20. package/.next/server/chunks/289.js +32 -29
  21. package/.next/server/chunks/312.js +67 -67
  22. package/.next/server/chunks/350.js +98 -41
  23. package/.next/server/chunks/483.js +43 -42
  24. package/.next/server/chunks/52.js +4007 -0
  25. package/.next/server/chunks/53.js +6 -6
  26. package/.next/server/chunks/530.js +22 -22
  27. package/.next/server/chunks/574.js +2 -2
  28. package/.next/server/chunks/576.js +1 -1
  29. package/.next/server/chunks/{933.js → 647.js} +33 -117
  30. package/.next/server/chunks/676.js +2 -2
  31. package/.next/server/chunks/693.js +3 -3
  32. package/.next/server/chunks/71.js +103 -61
  33. package/.next/server/chunks/74.js +268 -271
  34. package/.next/server/chunks/753.js +73 -28
  35. package/.next/server/chunks/779.js +8 -8
  36. package/.next/server/chunks/817.js +4007 -0
  37. package/.next/server/chunks/825.js +89 -89
  38. package/.next/server/chunks/854.js +4 -4
  39. package/.next/server/chunks/859.js +12 -12
  40. package/.next/server/chunks/98.js +4 -4
  41. package/.next/server/chunks/988.js +10 -10
  42. package/.next/server/middleware-build-manifest.js +1 -1
  43. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  44. package/.next/server/pages/404.js +42 -42
  45. package/.next/server/pages/404.js.nft.json +1 -1
  46. package/.next/server/pages/500.js +42 -42
  47. package/.next/server/pages/500.js.nft.json +1 -1
  48. package/.next/server/pages/[...slug].js +293 -171
  49. package/.next/server/pages/[...slug].js.nft.json +1 -1
  50. package/.next/server/pages/[slug]/p.js +645 -663
  51. package/.next/server/pages/[slug]/p.js.nft.json +1 -1
  52. package/.next/server/pages/_app.js +18 -18
  53. package/.next/server/pages/_app.js.nft.json +1 -1
  54. package/.next/server/pages/_document.js +30 -30
  55. package/.next/server/pages/_document.js.nft.json +1 -1
  56. package/.next/server/pages/_error.js +8 -8
  57. package/.next/server/pages/account.js +42 -42
  58. package/.next/server/pages/account.js.nft.json +1 -1
  59. package/.next/server/pages/api/graphql.js +146 -61
  60. package/.next/server/pages/api/graphql.js.nft.json +1 -1
  61. package/.next/server/pages/api/health/live.js +2 -2
  62. package/.next/server/pages/api/health/ready.js +2 -2
  63. package/.next/server/pages/api/preview.js +3 -3
  64. package/.next/server/pages/checkout.js +40 -40
  65. package/.next/server/pages/checkout.js.nft.json +1 -1
  66. package/.next/server/pages/en-US/404.html +2 -2
  67. package/.next/server/pages/en-US/500.html +2 -2
  68. package/.next/server/pages/en-US/account.html +2 -2
  69. package/.next/server/pages/en-US/checkout.html +2 -2
  70. package/.next/server/pages/en-US/login.html +2 -2
  71. package/.next/server/pages/en-US/s.html +2 -2
  72. package/.next/server/pages/en-US.html +2 -2
  73. package/.next/server/pages/index.js +53 -53
  74. package/.next/server/pages/index.js.nft.json +1 -1
  75. package/.next/server/pages/login.js +44 -44
  76. package/.next/server/pages/login.js.nft.json +1 -1
  77. package/.next/server/pages/s.js +183 -101
  78. package/.next/server/pages/s.js.nft.json +1 -1
  79. package/.next/server/pages-manifest.json +2 -2
  80. package/.next/static/chunks/{238-e5e4b2094f0e1df8.js → 238-86838f629f3d0aa4.js} +1 -1
  81. package/.next/static/chunks/{243-df6d1b248f7b4d3c.js → 243-ef9e49ef3df579c0.js} +1 -1
  82. package/.next/static/chunks/{709.7bc5a25ce30abda6.js → 709.daf1eddebf1e7952.js} +1 -1
  83. package/.next/static/chunks/932-33f45603c7d12a4b.js +1 -0
  84. package/.next/static/chunks/pages/[...slug]-362204c7e0b533cf.js +1 -0
  85. package/.next/static/chunks/pages/[slug]/p-885042c4b2b4f8ed.js +1 -0
  86. package/.next/static/chunks/pages/{index-d521ce4f4e2b89a6.js → index-79b05b0071c02fff.js} +1 -1
  87. package/.next/static/chunks/pages/s-e1bb00f8de6a386e.js +1 -0
  88. package/.next/static/chunks/{webpack-352e624909554726.js → webpack-88d120cefa1c4c09.js} +1 -1
  89. package/.next/static/wPqgZ8bYrPY473PZzuIX_/_buildManifest.js +1 -0
  90. package/.next/trace +80 -80
  91. package/.turbo/turbo-build.log +8 -6
  92. package/.turbo/turbo-test.log +25 -0
  93. package/@generated/graphql/index.ts +183 -79
  94. package/@generated/graphql/persisted.json +5 -5
  95. package/@generated/graphql/schema.graphql +1053 -0
  96. package/api/index.ts +15 -0
  97. package/codegen.yml +2 -1
  98. package/generate.sh +71 -0
  99. package/index.ts +15 -0
  100. package/jest.config.js +6 -0
  101. package/package.json +33 -18
  102. package/src/components/cms/RenderSections.tsx +4 -5
  103. package/src/components/product/ProductGrid/ProductGrid.tsx +4 -3
  104. package/src/components/sections/Breadcrumb/Breadcrumb.tsx +17 -22
  105. package/src/components/sections/CrossSellingShelf/CrossSellingShelf.tsx +8 -6
  106. package/src/components/sections/ProductDetails/ProductDetails.tsx +23 -33
  107. package/src/components/sections/ProductGallery/ProductGallery.tsx +15 -26
  108. package/src/components/sections/ProductShelf/ProductShelf.tsx +1 -1
  109. package/src/components/sections/ProductTiles/ProductTiles.tsx +4 -3
  110. package/src/components/templates/ProductListingPage/ProductListing.tsx +95 -0
  111. package/src/components/templates/ProductListingPage/ProductListingPage.tsx +34 -68
  112. package/src/components/templates/SearchPage/SearchPage.tsx +81 -0
  113. package/src/components/templates/SearchPage/index.ts +2 -0
  114. package/src/components/ui/ProductGallery/ProductGallery.tsx +24 -16
  115. package/src/components/ui/ProductGallery/ProductGalleryPage.tsx +8 -7
  116. package/src/components/ui/ProductGallery/useDelayedFacets.ts +3 -3
  117. package/src/components/ui/ProductShelf/ProductShelf.tsx +3 -2
  118. package/src/customizations/fragments/ClientProduct.ts +9 -0
  119. package/src/customizations/fragments/ClientProductGallery.ts +19 -0
  120. package/src/customizations/fragments/ClientProducts.ts +19 -0
  121. package/src/customizations/fragments/ServerCollectionPage.ts +9 -0
  122. package/src/customizations/fragments/ServerProductPage.ts +9 -0
  123. package/src/customizations/graphql/thirdParty/resolvers/index.ts +3 -0
  124. package/src/customizations/graphql/vtex/resolvers/index.ts +3 -0
  125. package/src/pages/[...slug].tsx +5 -3
  126. package/src/pages/[slug]/p.tsx +38 -18
  127. package/src/pages/s.tsx +22 -34
  128. package/src/sdk/graphql/useQuery.ts +17 -13
  129. package/src/sdk/overrides/PageProvider.tsx +78 -0
  130. package/src/sdk/product/useLocalizedVariables.ts +33 -0
  131. package/src/sdk/product/usePageProductsQuery.ts +139 -0
  132. package/src/{components/sections/ProductGallery/useGalleryQuery.ts → sdk/product/useProductGalleryQuery.ts} +12 -13
  133. package/src/sdk/product/{useProduct.ts → useProductQuery.ts} +10 -7
  134. package/src/sdk/product/useProductsPrefetch.ts +72 -0
  135. package/src/sdk/product/useProductsQuery.ts +17 -63
  136. package/src/server/generator/generateGraphQLSchemaFile.ts +3 -0
  137. package/src/server/generator/schema.ts +82 -0
  138. package/src/server/index.ts +34 -21
  139. package/src/server/options.ts +16 -0
  140. package/test/server/index.test.ts +146 -0
  141. package/.next/server/chunks/487.js +0 -9142
  142. package/.next/server/chunks/650.js +0 -9142
  143. package/.next/static/7SuqEgCuf5UtY9Gx-CYYB/_buildManifest.js +0 -1
  144. package/.next/static/chunks/603-d1c069aa8a349c86.js +0 -1
  145. package/.next/static/chunks/pages/[...slug]-ca533c74c22cb787.js +0 -1
  146. package/.next/static/chunks/pages/[slug]/p-7bb760bb3fcfc0bb.js +0 -1
  147. package/.next/static/chunks/pages/s-0e516ab36bb49c99.js +0 -1
  148. package/src/components/ui/ProductGallery/usePageProducts.ts +0 -48
  149. /package/.next/static/{7SuqEgCuf5UtY9Gx-CYYB → wPqgZ8bYrPY473PZzuIX_}/_ssgManifest.js +0 -0
@@ -1,26 +1,23 @@
1
1
  import { gql } from '@faststore/graphql-utils'
2
- import { useCallback, useMemo } from 'react'
3
- import { useSWRConfig } from 'swr'
4
2
 
5
- import { ITEMS_PER_SECTION } from 'src/constants'
6
3
  import type {
7
- ProductsQueryQuery,
8
- ProductsQueryQueryVariables,
4
+ ClientProductsQueryQuery,
5
+ ClientProductsQueryQueryVariables,
9
6
  } from '@generated/graphql'
10
7
 
11
- import { prefetchQuery } from '../graphql/prefetchQuery'
12
- import { useQuery } from '../graphql/useQuery'
13
- import { useSession } from '../session'
14
8
  import type { QueryOptions } from '../graphql/useQuery'
9
+ import { useQuery } from '../graphql/useQuery'
10
+ import { useLocalizedVariables } from './useLocalizedVariables'
15
11
 
16
12
  export const query = gql`
17
- query ProductsQuery(
13
+ query ClientProductsQuery(
18
14
  $first: Int!
19
15
  $after: String
20
16
  $sort: StoreSort!
21
17
  $term: String!
22
18
  $selectedFacets: [IStoreSelectedFacet!]!
23
19
  ) {
20
+ ...ClientProducts
24
21
  search(
25
22
  first: $first
26
23
  after: $after
@@ -42,66 +39,23 @@ export const query = gql`
42
39
  }
43
40
  `
44
41
 
45
- const toArray = <T>(x: T[] | T | undefined) =>
46
- Array.isArray(x) ? x : x ? [x] : []
47
-
48
- export const useLocalizedVariables = ({
49
- first,
50
- after,
51
- sort,
52
- term,
53
- selectedFacets,
54
- }: Partial<ProductsQueryQueryVariables>) => {
55
- const { channel, locale } = useSession()
56
-
57
- return useMemo(() => {
58
- const facets = toArray(selectedFacets)
59
-
60
- return {
61
- first: first ?? ITEMS_PER_SECTION,
62
- after: after ?? '0',
63
- sort: sort ?? ('score_desc' as const),
64
- term: term ?? '',
65
- selectedFacets: [
66
- ...facets,
67
- { key: 'channel', value: channel ?? '' },
68
- { key: 'locale', value: locale },
69
- ],
70
- }
71
- }, [selectedFacets, first, after, sort, term, channel, locale])
72
- }
73
-
74
42
  /**
75
- * Use this hook for fetching a list of products, like in search results and shelves
43
+ * Use this hook for fetching a list of products, like shelves and tiles
76
44
  */
77
45
  export const useProductsQuery = (
78
- variables: Partial<ProductsQueryQueryVariables>,
46
+ variables: Partial<ClientProductsQueryQueryVariables>,
79
47
  options?: QueryOptions
80
48
  ) => {
81
49
  const localizedVariables = useLocalizedVariables(variables)
82
50
 
83
- const { data } = useQuery<ProductsQueryQuery, ProductsQueryQueryVariables>(
84
- query,
85
- localizedVariables,
86
- {
87
- fallbackData: null,
88
- suspense: true,
89
- ...options,
90
- }
91
- )
92
-
93
- return data?.search?.products
94
- }
95
-
96
- export const useProductsQueryPrefetch = (
97
- variables: ProductsQueryQueryVariables,
98
- options?: QueryOptions
99
- ) => {
100
- const localizedVariables = useLocalizedVariables(variables)
101
- const { cache } = useSWRConfig()
51
+ const { data } = useQuery<
52
+ ClientProductsQueryQuery,
53
+ ClientProductsQueryQueryVariables
54
+ >(query, localizedVariables, {
55
+ fallbackData: null,
56
+ suspense: true,
57
+ ...options,
58
+ })
102
59
 
103
- return useCallback(
104
- () => prefetchQuery(query, localizedVariables, { cache, ...options }),
105
- [localizedVariables, cache, options]
106
- )
60
+ return data
107
61
  }
@@ -0,0 +1,3 @@
1
+ import { writeGraphqlSchemaFile, getMergedSchema } from './schema'
2
+
3
+ writeGraphqlSchemaFile(getMergedSchema())
@@ -0,0 +1,82 @@
1
+ import { writeFileSync } from 'fs-extra'
2
+ import { getSchema, getTypeDefs } from '@faststore/api'
3
+ import { printSchemaWithDirectives } from '@graphql-tools/utils'
4
+ import { loadFilesSync } from '@graphql-tools/load-files'
5
+ import { mergeTypeDefs } from '@graphql-tools/merge'
6
+ import { buildASTSchema } from 'graphql'
7
+ import type { GraphQLSchema } from 'graphql'
8
+ import type { TypeSource } from '@graphql-tools/utils'
9
+
10
+ import { apiOptions } from '../options'
11
+
12
+ export function getTypeDefsFromFolder(
13
+ customPath: string | string[]
14
+ ): TypeSource {
15
+ const basePath = ['src', 'customizations', 'graphql']
16
+
17
+ const pathArray = Array.isArray(customPath) ? customPath : [customPath]
18
+
19
+ return (
20
+ loadFilesSync([...basePath, ...pathArray, 'typeDefs'], {
21
+ extensions: ['graphql'],
22
+ }) ??
23
+ loadFilesSync([...basePath, ...pathArray, 'typedefs'], {
24
+ extensions: ['graphql'],
25
+ })
26
+ )
27
+ }
28
+
29
+ export function getCustomSchema(typeDefs: TypeSource[]) {
30
+ try {
31
+ const mergedTypeDefs = mergeTypeDefs(typeDefs)
32
+
33
+ const schema = buildASTSchema(mergedTypeDefs)
34
+
35
+ return schema
36
+ } catch (e) {
37
+ console.error(
38
+ 'An error occurred while attempting to merge the GraphQL Schema Extensions. Check the custom typeDefs and resolvers located in the "customizations/graphql/" directory. The changes since the last successful schema merge will be ignored.'
39
+ )
40
+
41
+ throw e
42
+ }
43
+ }
44
+
45
+ export function getNativeTypeDefs() {
46
+ return getTypeDefs() as TypeSource
47
+ }
48
+
49
+ export function getVTEXExtensionsTypeDefs() {
50
+ return getTypeDefsFromFolder('vtex')
51
+ }
52
+
53
+ export function getThirdPartyExtensionsTypeDefs() {
54
+ return getTypeDefsFromFolder('thirdParty')
55
+ }
56
+
57
+ export const nativeApiSchema = getSchema(apiOptions)
58
+
59
+ // Schema with no resolvers - used to generate schema.graphql file
60
+ export const getMergedSchema = (): GraphQLSchema =>
61
+ getCustomSchema(
62
+ [
63
+ getNativeTypeDefs(),
64
+ getVTEXExtensionsTypeDefs(),
65
+ getThirdPartyExtensionsTypeDefs(),
66
+ ].filter(Boolean)
67
+ )
68
+
69
+ export function writeGraphqlSchemaFile(apiSchema: GraphQLSchema) {
70
+ try {
71
+ writeFileSync(
72
+ [process.cwd(), '@generated', 'graphql', 'schema.graphql'].join('/'),
73
+ printSchemaWithDirectives(apiSchema)
74
+ )
75
+
76
+ console.log('Schema GraphQL file generated successfully')
77
+ } catch (e) {
78
+ console.error('An error occurred while generating the GraphQL schema file')
79
+
80
+ throw e
81
+ }
82
+ }
@@ -1,20 +1,32 @@
1
1
  /* eslint-disable react-hooks/rules-of-hooks */
2
+ import path from 'path'
2
3
  import type { FormatErrorHandler } from '@envelop/core'
3
4
  import {
4
5
  envelop,
5
- useAsyncSchema,
6
+ useSchema,
6
7
  useExtendContext,
7
8
  useMaskedErrors,
8
9
  } from '@envelop/core'
9
10
  import { useGraphQlJit } from '@envelop/graphql-jit'
10
11
  import { useParserCache } from '@envelop/parser-cache'
11
12
  import { useValidationCache } from '@envelop/validation-cache'
12
- import { getContextFactory, getSchema, isFastStoreError } from '@faststore/api'
13
+ import type { CacheControl, Maybe } from '@faststore/api'
14
+ import {
15
+ getContextFactory,
16
+ getResolvers,
17
+ isFastStoreError,
18
+ } from '@faststore/api'
13
19
  import { GraphQLError } from 'graphql'
14
- import type { Maybe, Options as APIOptions, CacheControl } from '@faststore/api'
20
+ import { makeExecutableSchema } from '@graphql-tools/schema'
21
+ import { loadFilesSync } from '@graphql-tools/load-files'
22
+ import type { TypeSource } from '@graphql-tools/utils'
15
23
 
16
24
  import persisted from '../../@generated/graphql/persisted.json'
17
- import storeConfig from '../../faststore.config'
25
+
26
+ import vtexExtensionsResolvers from '../customizations/graphql/vtex/resolvers'
27
+ import thirdPartyResolvers from '../customizations/graphql/thirdParty/resolvers'
28
+
29
+ import { apiOptions } from './options'
18
30
 
19
31
  interface ExecuteOptions<V = Record<string, unknown>> {
20
32
  operationName: string
@@ -24,21 +36,6 @@ interface ExecuteOptions<V = Record<string, unknown>> {
24
36
 
25
37
  const persistedQueries = new Map(Object.entries(persisted))
26
38
 
27
- const apiOptions: APIOptions = {
28
- platform: storeConfig.platform as APIOptions['platform'],
29
- account: storeConfig.api.storeId,
30
- environment: storeConfig.api.environment as APIOptions['environment'],
31
- hideUnavailableItems: storeConfig.api.hideUnavailableItems,
32
- incrementAddress: storeConfig.api.incrementAddress,
33
- channel: storeConfig.session.channel,
34
- locale: storeConfig.session.locale,
35
- flags: {
36
- enableOrderFormSync: true,
37
- },
38
- }
39
-
40
- export const apiSchema = getSchema(apiOptions)
41
-
42
39
  const apiContextFactory = getContextFactory(apiOptions)
43
40
 
44
41
  const formatError: FormatErrorHandler = (err) => {
@@ -51,10 +48,26 @@ const formatError: FormatErrorHandler = (err) => {
51
48
  return new GraphQLError('Sorry, something went wrong.')
52
49
  }
53
50
 
54
- const getEnvelop = async () =>
51
+ function loadGeneratedSchema(): TypeSource {
52
+ return loadFilesSync(path.join(process.cwd(), '@generated', 'graphql'), {
53
+ extensions: ['graphql'],
54
+ })
55
+ }
56
+
57
+ function getFinalAPISchema() {
58
+ const generatedSchema = loadGeneratedSchema()
59
+ const nativeResolvers = getResolvers(apiOptions)
60
+
61
+ return makeExecutableSchema({
62
+ typeDefs: generatedSchema,
63
+ resolvers: [nativeResolvers, vtexExtensionsResolvers, thirdPartyResolvers],
64
+ })
65
+ }
66
+
67
+ export const getEnvelop = async () =>
55
68
  envelop({
56
69
  plugins: [
57
- useAsyncSchema(apiSchema),
70
+ useSchema(getFinalAPISchema()),
58
71
  useExtendContext(apiContextFactory),
59
72
  useMaskedErrors({ formatError }),
60
73
  useGraphQlJit(),
@@ -0,0 +1,16 @@
1
+ import type { Options as APIOptions } from '@faststore/api'
2
+
3
+ import storeConfig from '../../faststore.config'
4
+
5
+ export const apiOptions: APIOptions = {
6
+ platform: storeConfig.platform as APIOptions['platform'],
7
+ account: storeConfig.api.storeId,
8
+ environment: storeConfig.api.environment as APIOptions['environment'],
9
+ hideUnavailableItems: storeConfig.api.hideUnavailableItems,
10
+ incrementAddress: storeConfig.api.incrementAddress,
11
+ channel: storeConfig.session.channel,
12
+ locale: storeConfig.session.locale,
13
+ flags: {
14
+ enableOrderFormSync: true,
15
+ },
16
+ }
@@ -0,0 +1,146 @@
1
+ import { assertValidSchema } from 'graphql'
2
+
3
+ import { execute, getEnvelop } from '../../src/server'
4
+ import {
5
+ getTypeDefsFromFolder,
6
+ getMergedSchema,
7
+ } from '../../src/server/generator/schema'
8
+ import storeConfig from '../../faststore.config'
9
+
10
+ const TYPES = [
11
+ 'StoreAggregateOffer',
12
+ 'StoreAggregateRating',
13
+ 'StoreAuthor',
14
+ 'StoreBrand',
15
+ 'StoreListItem',
16
+ 'StoreBreadcrumbList',
17
+ 'StoreCartMessage',
18
+ 'StoreCart',
19
+ 'IStoreCart',
20
+ 'StoreCollectionType',
21
+ 'StoreCollectionFacet',
22
+ 'StoreCollectionMeta',
23
+ 'StoreCollection',
24
+ 'StoreFacet',
25
+ 'StoreFacetRange',
26
+ 'StoreFacetBoolean',
27
+ 'StoreFacetValueRange',
28
+ 'StoreFacetValueBoolean',
29
+ 'StoreImage',
30
+ 'IStoreImage',
31
+ 'StoreOffer',
32
+ 'IStoreOffer',
33
+ 'StoreOrder',
34
+ 'IStoreOrder',
35
+ 'StoreOrganization',
36
+ 'IStoreOrganization',
37
+ 'StorePageInfo',
38
+ 'StoreProduct',
39
+ 'IStoreProduct',
40
+ 'StoreProductGroup',
41
+ 'StorePropertyValue',
42
+ 'StoreProductEdge',
43
+ 'StoreProductConnection',
44
+ 'StoreCollectionEdge',
45
+ 'StoreCollectionConnection',
46
+ 'StoreSort',
47
+ 'IStoreSelectedFacet',
48
+ 'StoreSearchResult',
49
+ 'StoreReviewRating',
50
+ 'StoreReview',
51
+ 'StoreSeo',
52
+ 'StoreStatus',
53
+ 'IShippingItem',
54
+ 'ShippingData',
55
+ 'LogisticsItem',
56
+ 'LogisticsInfo',
57
+ 'ShippingSLA',
58
+ 'DeliveryIds',
59
+ 'PickupStoreInfo',
60
+ 'PickupAddress',
61
+ 'MessageInfo',
62
+ 'MessageFields',
63
+ ]
64
+
65
+ const QUERIES = [
66
+ 'product',
67
+ 'collection',
68
+ 'search',
69
+ 'allProducts',
70
+ 'allCollections',
71
+ 'shipping',
72
+ 'redirect',
73
+ 'sellers',
74
+ ]
75
+
76
+ const MUTATIONS = ['validateCart', 'validateSession', 'subscribeToNewsletter']
77
+
78
+ describe('FastStore GraphQL Layer', () => {
79
+ describe('@faststore/api', () => {
80
+ const nativeSchema = getMergedSchema()
81
+
82
+ it('should return a valid GraphQL schema', async () => {
83
+ // `assertValidSchema()` will throw an error if the schema is invalid, and
84
+ // return nothing if it is valid. That's why we're checking for `undefined`.
85
+ expect(assertValidSchema(nativeSchema)).toBeUndefined()
86
+ })
87
+
88
+ it('should return a valid GraphQL schema contain all expected types', async () => {
89
+ TYPES.forEach((typeName) => {
90
+ expect(nativeSchema.getType(typeName)).toBeDefined()
91
+ })
92
+ })
93
+
94
+ it('should return a valid GraphQL schema contain all expected queries', async () => {
95
+ const queryFields = nativeSchema.getQueryType()?.getFields() ?? {}
96
+
97
+ expect(Object.keys(queryFields)).toEqual(QUERIES)
98
+ })
99
+
100
+ it('should return a valid GraphQL schema contain all expected mutations', async () => {
101
+ const mutationFields = nativeSchema.getMutationType()?.getFields() ?? {}
102
+
103
+ expect(Object.keys(mutationFields)).toEqual(MUTATIONS)
104
+ })
105
+ })
106
+
107
+ describe('VTEX API Extension', () => {
108
+ it('getTypeDefsFromFolder function should return an Array', () => {
109
+ const typeDefs = getTypeDefsFromFolder('vtex')
110
+ expect(typeDefs).toBeInstanceOf(Array)
111
+ })
112
+ })
113
+
114
+ describe('Third Party API Extension', () => {
115
+ it('getTypeDefsFromFolder function should return an Array', () => {
116
+ const typeDefs = getTypeDefsFromFolder('thirdParty')
117
+ expect(typeDefs).toBeInstanceOf(Array)
118
+ })
119
+ })
120
+
121
+ describe('Final Schema after merging', () => {
122
+ it('should return a valid merged GraphQL schema', async () => {
123
+ const schema = getMergedSchema()
124
+
125
+ // `assertValidSchema()` will throw an error if the schema is invalid, and
126
+ // return nothing if it is valid. That's why we're checking for `undefined`.
127
+ expect(assertValidSchema(schema)).toBeUndefined()
128
+ })
129
+ })
130
+
131
+ describe('Envelop', () => {
132
+ it('should exist with its plugins', async () => {
133
+ const envelop = await getEnvelop()
134
+ expect(envelop).toBeDefined()
135
+ expect(envelop._plugins).toHaveLength(6)
136
+ })
137
+
138
+ it('should handle options and execute', async () => {
139
+ const result = await execute({
140
+ variables: { slug: storeConfig.cypress.pages.collection.slice(1) },
141
+ operationName: 'ServerCollectionPageQuery',
142
+ })
143
+ expect(result.data).toBeDefined()
144
+ })
145
+ })
146
+ })