@faststore/core 3.0.150 → 3.0.152

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 (64) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +26 -26
  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/3202.js +1 -1
  16. package/.next/server/chunks/350.js +1 -1
  17. package/.next/server/chunks/5484.js +1 -1
  18. package/.next/server/chunks/5671.js +1 -1
  19. package/.next/server/chunks/9646.js +3 -2
  20. package/.next/server/middleware-build-manifest.js +1 -1
  21. package/.next/server/pages/[...slug].js +1 -1
  22. package/.next/server/pages/api/graphql.js +1 -1
  23. package/.next/server/pages/en-US/404.html +1 -1
  24. package/.next/server/pages/en-US/404.json +1 -1
  25. package/.next/server/pages/en-US/500.html +1 -1
  26. package/.next/server/pages/en-US/500.json +1 -1
  27. package/.next/server/pages/en-US/account.html +1 -1
  28. package/.next/server/pages/en-US/account.json +1 -1
  29. package/.next/server/pages/en-US/checkout.html +1 -1
  30. package/.next/server/pages/en-US/checkout.json +1 -1
  31. package/.next/server/pages/en-US/login.html +1 -1
  32. package/.next/server/pages/en-US/login.json +1 -1
  33. package/.next/server/pages/en-US/s.html +1 -1
  34. package/.next/server/pages/en-US/s.json +1 -1
  35. package/.next/server/pages/en-US.html +2 -2
  36. package/.next/server/pages/en-US.json +1 -1
  37. package/.next/server/pages/s.js +1 -1
  38. package/.next/server/pages-manifest.json +1 -1
  39. package/.next/static/{lGVnz_12piw54w7FhWXZY → 03UTa7YuWpYhZyEUa_cAu}/_buildManifest.js +1 -1
  40. package/.next/static/chunks/{202.adc31e548eafb936.js → 202.2a784500752e6a56.js} +1 -1
  41. package/.next/static/chunks/{484.3e4d0dcb4c646a45.js → 484.755bc4e4fb57ebb9.js} +1 -1
  42. package/.next/static/chunks/{707-83d159430b49c007.js → 707-6818d9951a83f35f.js} +1 -1
  43. package/.next/static/chunks/973-d39dc88330d50aca.js +1 -0
  44. package/.next/static/chunks/pages/{[...slug]-7251a2458aa75965.js → [...slug]-0db45ebf94081661.js} +1 -1
  45. package/.next/static/chunks/pages/{s-9002e83fb35c96b7.js → s-7ad120ac3e73cbea.js} +1 -1
  46. package/.next/static/chunks/{webpack-39f5c3558a96182c.js → webpack-ab89187244c136e9.js} +1 -1
  47. package/.next/trace +98 -98
  48. package/.turbo/turbo-build.log +4 -4
  49. package/.turbo/turbo-lint.log +1 -1
  50. package/.turbo/turbo-test.log +5 -5
  51. package/@generated/gql.ts +2 -2
  52. package/@generated/graphql.ts +16 -4
  53. package/@generated/persisted-documents.json +2 -2
  54. package/@generated/schema.graphql +2 -0
  55. package/package.json +9 -9
  56. package/src/components/cms/home/Components.ts +50 -0
  57. package/src/components/templates/SearchPage/SearchWrapper.tsx +6 -5
  58. package/src/sdk/analytics/platform/vtex/search.ts +29 -1
  59. package/src/sdk/analytics/types.ts +14 -0
  60. package/src/sdk/product/useProductGalleryQuery.ts +44 -2
  61. package/src/sdk/search/state.ts +6 -1
  62. package/src/sdk/search/useSuggestions.ts +3 -3
  63. package/.next/static/chunks/973-840ef2154b9d2940.js +0 -1
  64. /package/.next/static/{lGVnz_12piw54w7FhWXZY → 03UTa7YuWpYhZyEUa_cAu}/_ssgManifest.js +0 -0
@@ -38,8 +38,8 @@ https://nextjs.org/telemetry
38
38
  Collecting page data ...
39
39
  Generating static pages (0/7) ...
40
40
 
41
41
  Generating static pages (1/7)
42
- Warning: Dynamic Content not found for the page: home. Refer to the Dynamic Content documentation at https://developers.vtex.com/docs/guides/faststore/dynamic-content-overview for mapping the page and the corresponding data-fetching function.
43
42
 
44
43
  Generating static pages (3/7)
44
+ Warning: Dynamic Content not found for the page: home. Refer to the Dynamic Content documentation at https://developers.vtex.com/docs/guides/faststore/dynamic-content-overview for mapping the page and the corresponding data-fetching function.
45
45
 
46
46
  Generating static pages (5/7)
47
47
 
48
48
  ✓ Generating static pages (7/7)
49
49
  Finalizing page optimization ...
@@ -49,7 +49,7 @@ Route (pages) Size First Load JS
49
49
  ┌ ● / 1.23 kB 139 kB
50
50
  ├ └ css/197e314c5a03eabd.css 740 B
51
51
  ├ /_app 0 B 91 kB
52
- ├ ● /[...slug] 2.79 kB 152 kB
52
+ ├ ● /[...slug] 2.79 kB 153 kB
53
53
  ├ └ css/e47f1a002bdcf76f.css 2.38 kB
54
54
  ├ ● /[slug]/p 12.3 kB 150 kB
55
55
  ├ └ css/9b6bba2472d272ec.css 10.5 kB
@@ -67,11 +67,11 @@ Route (pages) Size First Load JS
67
67
  ├ chunks/framework-8e279965036b6169.js 45.4 kB
68
68
  ├ chunks/main-029f1328cfee9686.js 33.1 kB
69
69
  ├ chunks/pages/_app-cb1c3a94f987c5c8.js 9.87 kB
70
- ├ chunks/webpack-39f5c3558a96182c.js 2.73 kB
70
+ ├ chunks/webpack-ab89187244c136e9.js 2.74 kB
71
71
  └ css/ee0556daedda6306.css 3.07 kB
72
72
 
73
73
  λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
74
74
  ○ (Static) automatically rendered as static HTML (uses no initial props)
75
75
  ● (SSG) automatically generated as static HTML + JSON (uses getStaticProps)
76
76
 
77
- Done in 76.19s.
77
+ Done in 71.36s.
@@ -1,4 +1,4 @@
1
1
  yarn run v1.22.22
2
2
  $ next lint
3
3
  ✔ No ESLint warnings or errors
4
- Done in 6.32s.
4
+ Done in 6.03s.
@@ -1,12 +1,12 @@
1
1
  yarn run v1.22.22
2
2
  $ jest
3
- PASS test/server/cms/index.test.ts (35.931 s)
4
- PASS test/utils/multipleTemplates.test.ts (36.352 s)
5
- PASS test/server/index.test.ts (39.939 s)
3
+ PASS test/utils/multipleTemplates.test.ts (34.286 s)
4
+ PASS test/server/cms/index.test.ts (34.42 s)
5
+ PASS test/server/index.test.ts (38.295 s)
6
6
 
7
7
  Test Suites: 3 passed, 3 total
8
8
  Tests: 19 passed, 19 total
9
9
  Snapshots: 0 total
10
- Time: 41.087 s
10
+ Time: 39.241 s
11
11
  Ran all test suites.
12
- Done in 43.17s.
12
+ Done in 40.61s.
package/@generated/gql.ts CHANGED
@@ -44,7 +44,7 @@ const documents = {
44
44
  types.SubscribeToNewsletterDocument,
45
45
  '\n query ClientManyProductsQuery(\n $first: Int!\n $after: String\n $sort: StoreSort!\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]!\n ) {\n ...ClientManyProducts\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n edges {\n node {\n ...ProductSummary_product\n }\n }\n }\n }\n }\n':
46
46
  types.ClientManyProductsQueryDocument,
47
- '\n query ClientProductGalleryQuery(\n $first: Int!\n $after: String!\n $sort: StoreSort!\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]!\n ) {\n ...ClientProductGallery\n redirect(term: $term, selectedFacets: $selectedFacets) {\n url\n }\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n }\n facets {\n ...Filter_facets\n }\n metadata {\n ...SearchEvent_metadata\n }\n }\n }\n\n fragment SearchEvent_metadata on SearchMetadata {\n isTermMisspelled\n logicalOperator\n }\n':
47
+ '\n query ClientProductGalleryQuery(\n $first: Int!\n $after: String!\n $sort: StoreSort!\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]!\n ) {\n ...ClientProductGallery\n redirect(term: $term, selectedFacets: $selectedFacets) {\n url\n }\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n }\n facets {\n ...Filter_facets\n }\n metadata {\n ...SearchEvent_metadata\n }\n }\n }\n\n fragment SearchEvent_metadata on SearchMetadata {\n isTermMisspelled\n logicalOperator\n fuzzy\n }\n':
48
48
  types.ClientProductGalleryQueryDocument,
49
49
  '\n query ClientProductQuery($locator: [IStoreSelectedFacet!]!) {\n ...ClientProduct\n product(locator: $locator) {\n ...ProductDetailsFragment_product\n }\n }\n':
50
50
  types.ClientProductQueryDocument,
@@ -158,7 +158,7 @@ export function gql(
158
158
  * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
159
159
  */
160
160
  export function gql(
161
- source: '\n query ClientProductGalleryQuery(\n $first: Int!\n $after: String!\n $sort: StoreSort!\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]!\n ) {\n ...ClientProductGallery\n redirect(term: $term, selectedFacets: $selectedFacets) {\n url\n }\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n }\n facets {\n ...Filter_facets\n }\n metadata {\n ...SearchEvent_metadata\n }\n }\n }\n\n fragment SearchEvent_metadata on SearchMetadata {\n isTermMisspelled\n logicalOperator\n }\n'
161
+ source: '\n query ClientProductGalleryQuery(\n $first: Int!\n $after: String!\n $sort: StoreSort!\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]!\n ) {\n ...ClientProductGallery\n redirect(term: $term, selectedFacets: $selectedFacets) {\n url\n }\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n }\n facets {\n ...Filter_facets\n }\n metadata {\n ...SearchEvent_metadata\n }\n }\n }\n\n fragment SearchEvent_metadata on SearchMetadata {\n isTermMisspelled\n logicalOperator\n fuzzy\n }\n'
162
162
  ): typeof import('./graphql').ClientProductGalleryQueryDocument
163
163
  /**
164
164
  * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
@@ -523,6 +523,8 @@ export type QueryShippingArgs = {
523
523
 
524
524
  /** Search result. */
525
525
  export type SearchMetadata = {
526
+ /** Indicates how the search engine corrected the misspelled word by using fuzzy logic. */
527
+ fuzzy: Maybe<Scalars['String']['output']>
526
528
  /** Indicates if the search term was misspelled. */
527
529
  isTermMisspelled: Scalars['Boolean']['output']
528
530
  /** Logical operator used to run the search. */
@@ -1504,13 +1506,18 @@ export type ClientProductGalleryQueryQuery = {
1504
1506
  max: { selected: number; absolute: number }
1505
1507
  }
1506
1508
  >
1507
- metadata: { isTermMisspelled: boolean; logicalOperator: string } | null
1509
+ metadata: {
1510
+ isTermMisspelled: boolean
1511
+ logicalOperator: string
1512
+ fuzzy: string | null
1513
+ } | null
1508
1514
  }
1509
1515
  }
1510
1516
 
1511
1517
  export type SearchEvent_MetadataFragment = {
1512
1518
  isTermMisspelled: boolean
1513
1519
  logicalOperator: string
1520
+ fuzzy: string | null
1514
1521
  }
1515
1522
 
1516
1523
  export type ClientProductQueryQueryVariables = Exact<{
@@ -1597,7 +1604,11 @@ export type ClientSearchSuggestionsQueryQuery = {
1597
1604
  }>
1598
1605
  }
1599
1606
  products: { pageInfo: { totalCount: number } }
1600
- metadata: { isTermMisspelled: boolean; logicalOperator: string } | null
1607
+ metadata: {
1608
+ isTermMisspelled: boolean
1609
+ logicalOperator: string
1610
+ fuzzy: string | null
1611
+ } | null
1601
1612
  }
1602
1613
  }
1603
1614
 
@@ -2047,6 +2058,7 @@ export const SearchEvent_MetadataFragmentDoc = new TypedDocumentString(
2047
2058
  fragment SearchEvent_metadata on SearchMetadata {
2048
2059
  isTermMisspelled
2049
2060
  logicalOperator
2061
+ fuzzy
2050
2062
  }
2051
2063
  `,
2052
2064
  { fragmentName: 'SearchEvent_metadata' }
@@ -2099,7 +2111,7 @@ export const ClientManyProductsQueryDocument = {
2099
2111
  export const ClientProductGalleryQueryDocument = {
2100
2112
  __meta__: {
2101
2113
  operationName: 'ClientProductGalleryQuery',
2102
- operationHash: '177fe68cb385737b0901fc9e105f0a4813e18a20',
2114
+ operationHash: 'bfc40da32b60f9404a4adb96b0856e3fbb04b076',
2103
2115
  },
2104
2116
  } as unknown as TypedDocumentString<
2105
2117
  ClientProductGalleryQueryQuery,
@@ -2117,7 +2129,7 @@ export const ClientProductQueryDocument = {
2117
2129
  export const ClientSearchSuggestionsQueryDocument = {
2118
2130
  __meta__: {
2119
2131
  operationName: 'ClientSearchSuggestionsQuery',
2120
- operationHash: '4d9f934764d8578aea08673b8ba57e8bf738f534',
2132
+ operationHash: '47e48eaee91d16a4237eb2c1241bc2ed3e2ad9bb',
2121
2133
  },
2122
2134
  } as unknown as TypedDocumentString<
2123
2135
  ClientSearchSuggestionsQueryQuery,
@@ -4,9 +4,9 @@
4
4
  "c2b3f8bff73ebf6ac79d758c66cabbc21ba9fcc0": "fragment CartItem on StoreOffer { itemOffered { ...CartProductItem } listPrice listPriceWithTaxes price priceWithTaxes quantity seller { identifier } } fragment CartMessage on StoreCartMessage { status text } fragment CartProductItem on StoreProduct { additionalProperty { name propertyID value valueReference } brand { name } gtin image { alternateName url } isVariantOf { name productGroupID skuVariants { activeVariations availableVariations slugsMap } } name sku unitMultiplier } mutation ValidateCartMutation($cart: IStoreCart!, $session: IStoreSession!) { validateCart(cart: $cart, session: $session) { messages { ...CartMessage } order { acceptedOffer { ...CartItem } orderNumber shouldSplitItem } } }",
5
5
  "feb7005103a859e2bc8cf2360d568806fd88deba": "mutation SubscribeToNewsletter($data: IPersonNewsletter!) { subscribeToNewsletter(data: $data) { id } }",
6
6
  "ad2eb78cfccb9dbd5a9f2d1e150cc70fea5da99a": "fragment ClientManyProducts on Query { search( first: $first after: $after sort: $sort term: $term selectedFacets: $selectedFacets ) { products { pageInfo { totalCount } } } } fragment ProductSummary_product on StoreProduct { additionalProperty { name propertyID value valueReference } advertisement { adId adResponseId } brand { brandName: name } brand { name } gtin image { alternateName url } isVariantOf { name productGroupID } name offers { lowPrice lowPriceWithTaxes offers { availability listPrice listPriceWithTaxes price quantity seller { identifier } } } id: productID sku slug } query ClientManyProductsQuery($after: String, $first: Int!, $selectedFacets: [IStoreSelectedFacet!]!, $sort: StoreSort!, $term: String!) { search( first: $first after: $after sort: $sort term: $term selectedFacets: $selectedFacets ) { products { edges { node { ...ProductSummary_product } } pageInfo { totalCount } } } ...ClientManyProducts }",
7
- "177fe68cb385737b0901fc9e105f0a4813e18a20": "fragment ClientProductGallery on Query { search( first: $first after: $after sort: $sort term: $term selectedFacets: $selectedFacets ) { products { pageInfo { totalCount } } } } fragment Filter_facets on StoreFacet { ... on StoreFacetBoolean { __typename key label values { label quantity selected value } } ... on StoreFacetRange { __typename key label max { absolute selected } min { absolute selected } } } fragment SearchEvent_metadata on SearchMetadata { isTermMisspelled logicalOperator } query ClientProductGalleryQuery($after: String!, $first: Int!, $selectedFacets: [IStoreSelectedFacet!]!, $sort: StoreSort!, $term: String!) { redirect(term: $term, selectedFacets: $selectedFacets) { url } search( first: $first after: $after sort: $sort term: $term selectedFacets: $selectedFacets ) { facets { ...Filter_facets } metadata { ...SearchEvent_metadata } products { pageInfo { totalCount } } } ...ClientProductGallery }",
7
+ "bfc40da32b60f9404a4adb96b0856e3fbb04b076": "fragment ClientProductGallery on Query { search( first: $first after: $after sort: $sort term: $term selectedFacets: $selectedFacets ) { products { pageInfo { totalCount } } } } fragment Filter_facets on StoreFacet { ... on StoreFacetBoolean { __typename key label values { label quantity selected value } } ... on StoreFacetRange { __typename key label max { absolute selected } min { absolute selected } } } fragment SearchEvent_metadata on SearchMetadata { fuzzy isTermMisspelled logicalOperator } query ClientProductGalleryQuery($after: String!, $first: Int!, $selectedFacets: [IStoreSelectedFacet!]!, $sort: StoreSort!, $term: String!) { redirect(term: $term, selectedFacets: $selectedFacets) { url } search( first: $first after: $after sort: $sort term: $term selectedFacets: $selectedFacets ) { facets { ...Filter_facets } metadata { ...SearchEvent_metadata } products { pageInfo { totalCount } } } ...ClientProductGallery }",
8
8
  "7d121ef8d4dc99174e64e4429a9b977b8bbebed8": "fragment CartProductItem on StoreProduct { additionalProperty { name propertyID value valueReference } brand { name } gtin image { alternateName url } isVariantOf { name productGroupID skuVariants { activeVariations availableVariations slugsMap } } name sku unitMultiplier } fragment ClientProduct on Query { product(locator: $locator) { id: productID } } fragment ProductDetailsFragment_product on StoreProduct { additionalProperty { name propertyID value valueReference } brand { name } description gtin image { alternateName url } isVariantOf { name productGroupID skuVariants { activeVariations availableVariations slugsMap } } name offers { lowPrice lowPriceWithTaxes offers { availability listPrice listPriceWithTaxes price priceWithTaxes seller { identifier } } } id: productID sku unitMultiplier ...CartProductItem } query ClientProductQuery($locator: [IStoreSelectedFacet!]!) { product(locator: $locator) { ...ProductDetailsFragment_product } ...ClientProduct }",
9
- "4d9f934764d8578aea08673b8ba57e8bf738f534": "fragment ClientSearchSuggestions on Query { search(first: 5, term: $term, selectedFacets: $selectedFacets) { suggestions { terms { value } } } } fragment ProductSummary_product on StoreProduct { additionalProperty { name propertyID value valueReference } advertisement { adId adResponseId } brand { brandName: name } brand { name } gtin image { alternateName url } isVariantOf { name productGroupID } name offers { lowPrice lowPriceWithTaxes offers { availability listPrice listPriceWithTaxes price quantity seller { identifier } } } id: productID sku slug } fragment SearchEvent_metadata on SearchMetadata { isTermMisspelled logicalOperator } query ClientSearchSuggestionsQuery($selectedFacets: [IStoreSelectedFacet!], $term: String!) { search(first: 5, term: $term, selectedFacets: $selectedFacets) { metadata { ...SearchEvent_metadata } products { pageInfo { totalCount } } suggestions { products { ...ProductSummary_product } terms { value } } } ...ClientSearchSuggestions }",
9
+ "47e48eaee91d16a4237eb2c1241bc2ed3e2ad9bb": "fragment ClientSearchSuggestions on Query { search(first: 5, term: $term, selectedFacets: $selectedFacets) { suggestions { terms { value } } } } fragment ProductSummary_product on StoreProduct { additionalProperty { name propertyID value valueReference } advertisement { adId adResponseId } brand { brandName: name } brand { name } gtin image { alternateName url } isVariantOf { name productGroupID } name offers { lowPrice lowPriceWithTaxes offers { availability listPrice listPriceWithTaxes price quantity seller { identifier } } } id: productID sku slug } fragment SearchEvent_metadata on SearchMetadata { fuzzy isTermMisspelled logicalOperator } query ClientSearchSuggestionsQuery($selectedFacets: [IStoreSelectedFacet!], $term: String!) { search(first: 5, term: $term, selectedFacets: $selectedFacets) { metadata { ...SearchEvent_metadata } products { pageInfo { totalCount } } suggestions { products { ...ProductSummary_product } terms { value } } } ...ClientSearchSuggestions }",
10
10
  "e2385b0f11726d0068f96548f57a8dd441c064e3": "fragment ClientTopSearchSuggestions on Query { search(first: 5, term: $term, selectedFacets: $selectedFacets) { suggestions { terms { value } } } } query ClientTopSearchSuggestionsQuery($selectedFacets: [IStoreSelectedFacet!], $term: String!) { search(first: 5, term: $term, selectedFacets: $selectedFacets) { suggestions { terms { value } } } ...ClientTopSearchSuggestions }",
11
11
  "1e69c734ed31bd9e763a34fe9660f5bbad3fd143": "mutation ValidateSession($search: String!, $session: IStoreSession!) { validateSession(session: $session, search: $search) { addressType b2b { customerId } channel country currency { code symbol } deliveryMode { deliveryChannel deliveryMethod deliveryWindow { endDate startDate } } geoCoordinates { latitude longitude } locale person { email familyName givenName id } postalCode } }",
12
12
  "d6667f1de2a26b94b9b55f4b25d7d823f82635a0": "fragment ClientShippingSimulation on Query { shipping(items: $items, postalCode: $postalCode, country: $country) { address { city } } } query ClientShippingSimulationQuery($country: String!, $items: [IShippingItem!]!, $postalCode: String!) { shipping(items: $items, postalCode: $postalCode, country: $country) { address { city neighborhood state } logisticsInfo { slas { availableDeliveryWindows { endDateUtc listPrice price startDateUtc } carrier localizedEstimates price shippingEstimate } } } ...ClientShippingSimulation }"
@@ -545,6 +545,8 @@ type SearchMetadata {
545
545
  isTermMisspelled: Boolean!
546
546
  """Logical operator used to run the search."""
547
547
  logicalOperator: String!
548
+ """Indicates how the search engine corrected the misspelled word by using fuzzy logic."""
549
+ fuzzy: String
548
550
  }
549
551
 
550
552
  """Search result."""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/core",
3
- "version": "3.0.150",
3
+ "version": "3.0.152",
4
4
  "license": "MIT",
5
5
  "repository": "vtex/faststore",
6
6
  "browserslist": "supports es6-module and not dead",
@@ -43,12 +43,12 @@
43
43
  "@envelop/graphql-jit": "^8.0.3",
44
44
  "@envelop/parser-cache": "^6.0.2",
45
45
  "@envelop/validation-cache": "^6.0.2",
46
- "@faststore/api": "^3.0.150",
47
- "@faststore/components": "^3.0.150",
48
- "@faststore/graphql-utils": "^3.0.150",
49
- "@faststore/lighthouse": "^3.0.150",
50
- "@faststore/sdk": "^3.0.150",
51
- "@faststore/ui": "^3.0.150",
46
+ "@faststore/api": "^3.0.152",
47
+ "@faststore/components": "^3.0.152",
48
+ "@faststore/graphql-utils": "^3.0.152",
49
+ "@faststore/lighthouse": "^3.0.152",
50
+ "@faststore/sdk": "^3.0.152",
51
+ "@faststore/ui": "^3.0.152",
52
52
  "@graphql-codegen/cli": "5.0.2",
53
53
  "@graphql-codegen/client-preset": "4.2.6",
54
54
  "@graphql-codegen/typescript": "4.0.7",
@@ -87,7 +87,7 @@
87
87
  "devDependencies": {
88
88
  "@cypress/code-coverage": "^3.12.1",
89
89
  "@envelop/testing": "^6.0.0",
90
- "@faststore/eslint-config": "^3.0.150",
90
+ "@faststore/eslint-config": "^3.0.152",
91
91
  "@lhci/cli": "^0.9.0",
92
92
  "@testing-library/cypress": "^10.0.1",
93
93
  "@types/cypress": "^1.1.3",
@@ -128,5 +128,5 @@
128
128
  "node": "18.19.0",
129
129
  "yarn": "1.19.1"
130
130
  },
131
- "gitHead": "5d33a0289de83e8319b4be2f5b28932570a22775"
131
+ "gitHead": "98f762825022beee952d25f893b012f35f335cb0"
132
132
  }
@@ -0,0 +1,50 @@
1
+ import dynamic from 'next/dynamic'
2
+ import { ComponentType } from 'react'
3
+
4
+ import { OverriddenDefaultHero as Hero } from 'src/components/sections/Hero/OverriddenDefaultHero'
5
+ import Incentives from 'src/components/sections/Incentives'
6
+ import { default as GLOBAL_COMPONENTS } from '../global/Components'
7
+
8
+ import CUSTOM_COMPONENTS from 'src/customizations/src/components'
9
+
10
+ const BannerText = dynamic(
11
+ () =>
12
+ import(
13
+ /* webpackChunkName: "BannerText" */ 'src/components/sections/BannerText/OverriddenDefaultBannerText'
14
+ ).then((mod) => ({ default: mod.OverriddenDefaultBannerText })),
15
+ { ssr: false }
16
+ )
17
+ const Newsletter = dynamic(
18
+ () =>
19
+ import(
20
+ /* webpackChunkName: "Newsletter" */ 'src/components/sections/Newsletter/OverriddenDefaultNewsletter'
21
+ ).then((mod) => ({ default: mod.OverriddenDefaultNewsletter })),
22
+ { ssr: false }
23
+ )
24
+ const ProductShelf = dynamic(
25
+ () =>
26
+ import(
27
+ /* webpackChunkName: "ProductShelf" */ 'src/components/sections/ProductShelf/OverriddenDefaultProductShelf'
28
+ ).then((mod) => ({ default: mod.OverriddenDefaultProductShelf })),
29
+ { ssr: false }
30
+ )
31
+ const ProductTiles = dynamic(
32
+ () =>
33
+ import(
34
+ /* webpackChunkName: "ProductTiles" */ 'src/components/sections/ProductTiles'
35
+ ),
36
+ { ssr: false }
37
+ )
38
+
39
+ const COMPONENTS: Record<string, ComponentType<any>> = {
40
+ ...GLOBAL_COMPONENTS,
41
+ Hero,
42
+ Incentives,
43
+ BannerText,
44
+ Newsletter,
45
+ ProductShelf,
46
+ ProductTiles,
47
+ ...CUSTOM_COMPONENTS,
48
+ }
49
+
50
+ export default COMPONENTS
@@ -1,12 +1,12 @@
1
- import { useRouter } from 'next/router'
2
1
  import { useSearch } from '@faststore/sdk'
2
+ import { useRouter } from 'next/router'
3
3
 
4
- import type { SearchContentType } from 'src/server/cms'
5
- import type { SearchPageContextType } from 'src/pages/s'
6
- import { useProductGalleryQuery } from 'src/sdk/product/useProductGalleryQuery'
7
- import Section from 'src/components/sections/Section'
8
4
  import EmptyState from 'src/components/sections/EmptyState'
9
5
  import ProductGalleryStyles from 'src/components/sections/ProductGallery/section.module.scss'
6
+ import Section from 'src/components/sections/Section'
7
+ import type { SearchPageContextType } from 'src/pages/s'
8
+ import { useProductGalleryQuery } from 'src/sdk/product/useProductGalleryQuery'
9
+ import type { SearchContentType } from 'src/server/cms'
10
10
 
11
11
  import SearchPage from './SearchPage'
12
12
 
@@ -37,6 +37,7 @@ export default function SearchWrapper({
37
37
  const {
38
38
  state: { term, sort, selectedFacets },
39
39
  } = useSearch()
40
+
40
41
  const { data: pageProductGalleryData, isValidating } = useProductGalleryQuery(
41
42
  {
42
43
  term,
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import type { AnalyticsEvent } from '@faststore/sdk'
5
5
  import type {
6
+ IntelligentSearchAutocompleteQueryEvent,
6
7
  IntelligentSearchQueryEvent,
7
8
  SearchSelectItemEvent,
8
9
  } from '../../types'
@@ -66,6 +67,15 @@ type SearchEvent =
66
67
  url: string
67
68
  type: 'search.query'
68
69
  }
70
+ | {
71
+ text: string
72
+ misspelled: boolean
73
+ match: number
74
+ operator: string
75
+ locale: string
76
+ url: string
77
+ type: 'search.autocomplete.query'
78
+ }
69
79
 
70
80
  const sendEvent = (options: SearchEvent & { url?: string }) =>
71
81
  fetch(`https://sp.vtex.com/event-api/v1/${config.api.storeId}/event`, {
@@ -86,7 +96,11 @@ const isFullTextSearch = (url: URL) =>
86
96
  /^\/s(\/)?$/g.test(url.pathname)
87
97
 
88
98
  const handleEvent = (
89
- event: AnalyticsEvent | SearchSelectItemEvent | IntelligentSearchQueryEvent
99
+ event:
100
+ | AnalyticsEvent
101
+ | SearchSelectItemEvent
102
+ | IntelligentSearchQueryEvent
103
+ | IntelligentSearchAutocompleteQueryEvent
90
104
  ) => {
91
105
  switch (event.name) {
92
106
  case 'search_select_item': {
@@ -128,6 +142,20 @@ const handleEvent = (
128
142
  break
129
143
  }
130
144
 
145
+ case 'intelligent_search_autocomplete_query': {
146
+ sendEvent({
147
+ type: 'search.autocomplete.query',
148
+ url: event.params.url,
149
+ text: event.params.term,
150
+ misspelled: event.params.isTermMisspelled,
151
+ match: event.params.totalCount,
152
+ operator: event.params.logicalOperator,
153
+ locale: event.params.locale,
154
+ })
155
+
156
+ break
157
+ }
158
+
131
159
  default:
132
160
  }
133
161
  }
@@ -34,3 +34,17 @@ export interface IntelligentSearchQueryEvent {
34
34
  name: 'intelligent_search_query'
35
35
  params: IntelligentSearchQueryParams
36
36
  }
37
+
38
+ export interface IntelligentSearchAutocompleteQueryParams {
39
+ url: string
40
+ locale: string
41
+ term: string
42
+ logicalOperator: string
43
+ isTermMisspelled: boolean
44
+ totalCount: number
45
+ }
46
+
47
+ export interface IntelligentSearchAutocompleteQueryEvent {
48
+ name: 'intelligent_search_autocomplete_query'
49
+ params: IntelligentSearchAutocompleteQueryParams
50
+ }
@@ -3,6 +3,7 @@ import { useQuery } from 'src/sdk/graphql/useQuery'
3
3
  import { useSession } from 'src/sdk/session'
4
4
  import { useLocalizedVariables } from './useLocalizedVariables'
5
5
 
6
+ import { useSearch } from '@faststore/sdk'
6
7
  import { Facet } from '@faststore/sdk/dist/types'
7
8
  import type {
8
9
  ClientManyProductsQueryQueryVariables,
@@ -53,6 +54,7 @@ export const query = gql(`
53
54
  fragment SearchEvent_metadata on SearchMetadata {
54
55
  isTermMisspelled
55
56
  logicalOperator
57
+ fuzzy
56
58
  }
57
59
  `)
58
60
 
@@ -63,6 +65,14 @@ type ProductGalleryQueryOptions = {
63
65
  term: ClientManyProductsQueryQueryVariables['term']
64
66
  }
65
67
 
68
+ export const findFacetValue = (
69
+ facets: Facet[],
70
+ searchParam: string
71
+ ): string | null => {
72
+ const facet = facets.find(({ key }) => key === searchParam)
73
+ return facet?.value ?? null
74
+ }
75
+
66
76
  export const useProductGalleryQuery = ({
67
77
  term,
68
78
  sort,
@@ -70,6 +80,7 @@ export const useProductGalleryQuery = ({
70
80
  itemsPerPage,
71
81
  }: ProductGalleryQueryOptions) => {
72
82
  const { locale } = useSession()
83
+ const { state, setState } = useSearch()
73
84
  const localizedVariables = useLocalizedVariables({
74
85
  first: itemsPerPage,
75
86
  after: '0',
@@ -78,9 +89,12 @@ export const useProductGalleryQuery = ({
78
89
  selectedFacets,
79
90
  })
80
91
 
81
- return useQuery<Query, Variables>(query, localizedVariables, {
92
+ const fuzzyFacetValue = findFacetValue(selectedFacets, 'fuzzy')
93
+ const operatorFacetValue = findFacetValue(selectedFacets, 'operator')
94
+
95
+ const queryResult = useQuery<Query, Variables>(query, localizedVariables, {
82
96
  onSuccess: (data) => {
83
- if (data && term) {
97
+ if (data && term && fuzzyFacetValue && operatorFacetValue) {
84
98
  import('@faststore/sdk').then(({ sendAnalyticsEvent }) => {
85
99
  sendAnalyticsEvent<IntelligentSearchQueryEvent>({
86
100
  name: 'intelligent_search_query',
@@ -97,4 +111,32 @@ export const useProductGalleryQuery = ({
97
111
  }
98
112
  },
99
113
  })
114
+
115
+ // If there is no fuzzy or operator facet, we need to add them to the selectedFacets and re-fetch the query
116
+ const shouldRefetchQuery =
117
+ !queryResult.error && (!fuzzyFacetValue || !operatorFacetValue)
118
+
119
+ if (shouldRefetchQuery) {
120
+ if (queryResult.data) {
121
+ setState({
122
+ ...state,
123
+ selectedFacets: [
124
+ ...selectedFacets,
125
+ {
126
+ key: 'fuzzy',
127
+ value: queryResult.data.search.metadata?.fuzzy ?? 'auto',
128
+ },
129
+ {
130
+ key: 'operator',
131
+ value: queryResult.data.search.metadata?.logicalOperator ?? 'and',
132
+ },
133
+ ],
134
+ })
135
+ }
136
+
137
+ // The first result is not relevant, return null data to avoid rendering the page while the query is being re-fetched
138
+ return { ...queryResult, isValidating: true, data: null }
139
+ }
140
+
141
+ return queryResult
100
142
  }
@@ -5,7 +5,12 @@ export const useApplySearchState = () => {
5
5
  const router = useRouter()
6
6
 
7
7
  return useCallback(
8
- (url: URL) => router.push(`${url.pathname}${url.search}`),
8
+ (url: URL) => {
9
+ const newUrl = `${url.pathname}${url.search}`
10
+ return url.searchParams.has('fuzzy') && url.searchParams.has('operator')
11
+ ? router.replace(newUrl)
12
+ : router.push(newUrl)
13
+ },
9
14
  [router]
10
15
  )
11
16
  }
@@ -7,7 +7,7 @@ import type {
7
7
  ClientSearchSuggestionsQueryQuery as Query,
8
8
  ClientSearchSuggestionsQueryQueryVariables as Variables,
9
9
  } from '@generated/graphql'
10
- import type { IntelligentSearchQueryEvent } from '../analytics/types'
10
+ import type { IntelligentSearchAutocompleteQueryEvent } from '../analytics/types'
11
11
 
12
12
  import { useSession } from '../session'
13
13
 
@@ -55,8 +55,8 @@ function useSuggestions(term: string) {
55
55
  onSuccess: (callbackData) => {
56
56
  if (callbackData && term) {
57
57
  import('@faststore/sdk').then(({ sendAnalyticsEvent }) => {
58
- sendAnalyticsEvent<IntelligentSearchQueryEvent>({
59
- name: 'intelligent_search_query',
58
+ sendAnalyticsEvent<IntelligentSearchAutocompleteQueryEvent>({
59
+ name: 'intelligent_search_autocomplete_query',
60
60
  params: {
61
61
  locale,
62
62
  term,