@graphcommerce/algolia-products 9.1.0-canary.28 → 9.1.0-canary.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/mesh/resolvers.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { AlgoliasearchResponse, MeshContext, Resolvers } from '@graphcommerce/graphql-mesh'
1
+ import type { AlgoliasearchResponse, Resolvers } from '@graphcommerce/graphql-mesh'
2
2
  import { hasSelectionSetPath } from '@graphcommerce/graphql-mesh'
3
3
  import type { GraphQLError, GraphQLResolveInfo } from 'graphql'
4
4
  import { algoliaFacetsToAggregations, getCategoryList } from './algoliaFacetsToAggregations'
@@ -7,11 +7,13 @@ import { algoliaHitToMagentoProduct } from './algoliaHitToMagentoProduct'
7
7
  import { getAlgoliaSettings } from './getAlgoliaSettings'
8
8
  import { getAttributeList } from './getAttributeList'
9
9
  import { getGroupId } from './getGroupId'
10
+ import { getIndexName } from './getIndexName'
10
11
  import { getSearchResults } from './getSearchResults'
11
12
  import { getSearchSuggestions } from './getSearchSuggestions'
12
13
  import { isSuggestionsEnabled } from './getSearchSuggestionsInput'
13
14
  import { getStoreConfig } from './getStoreConfig'
14
- import { sortingOptions } from './sortOptions'
15
+ import { sortAggregations } from './sortAggregations'
16
+ import { sortFieldsOptions } from './sortFieldOptions'
15
17
 
16
18
  function isAlgoliaResponse<T extends object>(
17
19
  root: T,
@@ -42,12 +44,15 @@ export const resolvers: Resolvers = {
42
44
  aggregations: async (root, _args, context) => {
43
45
  if (!isAlgoliaResponse(root)) return root.aggregations ?? null
44
46
 
45
- return algoliaFacetsToAggregations(
46
- root.algoliaSearchResults?.facets,
47
- await getAttributeList(context),
48
- await getStoreConfig(context),
49
- await getCategoryList(context),
50
- getGroupId(context),
47
+ return sortAggregations(
48
+ algoliaFacetsToAggregations(
49
+ root.algoliaSearchResults?.facets,
50
+ await getAttributeList(context),
51
+ await getStoreConfig(context),
52
+ await getCategoryList(context),
53
+ getGroupId(context),
54
+ ),
55
+ root.algoliaSearchResults?.renderingContent,
51
56
  )
52
57
  },
53
58
 
@@ -55,12 +60,10 @@ export const resolvers: Resolvers = {
55
60
  if (isAlgoliaResponse(root)) {
56
61
  return {
57
62
  default: 'relevance',
58
- options: Object.values(
59
- sortingOptions(
60
- await getAlgoliaSettings(context),
61
- await getAttributeList(context),
62
- context,
63
- ),
63
+ options: sortFieldsOptions(
64
+ await getAlgoliaSettings(context),
65
+ await getAttributeList(context),
66
+ context,
64
67
  ),
65
68
  }
66
69
  }
@@ -69,13 +72,13 @@ export const resolvers: Resolvers = {
69
72
 
70
73
  total_count: (root) => {
71
74
  if (!isAlgoliaResponse(root)) return root.total_count ?? null
72
- return root.algoliaSearchResults?.nbHits
75
+ return root.algoliaSearchResults?.nbHits ?? null
73
76
  },
74
77
 
75
78
  page_info: (root) => {
76
79
  if (!isAlgoliaResponse(root)) return root.page_info ?? null
77
80
  return {
78
- current_page: root.algoliaSearchResults.page + 1,
81
+ current_page: (root.algoliaSearchResults.page ?? 0) + 1,
79
82
  page_size: root.algoliaSearchResults.hitsPerPage,
80
83
  total_pages: root.algoliaSearchResults.nbPages,
81
84
  }
@@ -97,23 +100,6 @@ export const resolvers: Resolvers = {
97
100
  return items
98
101
  },
99
102
  },
100
- Customer: {
101
- group_id: {
102
- resolve: async (root, args, context, info) => {
103
- const { headers } = context as MeshContext & {
104
- headers?: Record<string, string | undefined>
105
- }
106
- if (!headers?.authorization) return 0
107
- const customer = await context.m2rest.Query.m2rest_GetV1CustomersMe({
108
- root,
109
- context,
110
- info,
111
- autoSelectionSetWithDepth: 10,
112
- })
113
- return customer?.group_id ?? null
114
- },
115
- },
116
- },
117
103
  Query: {
118
104
  products: async (root, args, context, info) => {
119
105
  const isAgolia = (args.filter?.engine?.in ?? [args.filter?.engine?.eq])[0] === 'algolia'
@@ -127,7 +113,6 @@ export const resolvers: Resolvers = {
127
113
  getSearchSuggestions(args.search, context)
128
114
 
129
115
  const searchResults = hasSearchRequest(info) ? getSearchResults(args, context, info) : null
130
-
131
116
  if (isGraphQLError(await searchResults))
132
117
  return context.m2.Query.products({ root, args, context, info })
133
118
 
@@ -135,6 +120,7 @@ export const resolvers: Resolvers = {
135
120
  algoliaSearchResults: await searchResults,
136
121
  suggestions: (await searchSuggestsions) || null,
137
122
  algolia_queryID: (await searchResults)?.queryID,
123
+ algolia_indexName: getIndexName(context),
138
124
  }
139
125
  },
140
126
  },
@@ -0,0 +1,23 @@
1
+ import type { Aggregation, AlgoliasearchResponse } from '@graphcommerce/graphql-mesh'
2
+
3
+ /** Sort the aggregations based on the ordering given by Algolia. */
4
+ export function sortAggregations(
5
+ aggregations: Aggregation[],
6
+ renderingContent: AlgoliasearchResponse['renderingContent'],
7
+ ) {
8
+ const order = renderingContent?.facetOrdering?.facets?.order
9
+ /** @todo: Algolia also supports sorting the attribute values. */
10
+ // const values = renderingContent?.facetOrdering?.values?.additionalProperties
11
+
12
+ if (!order) return aggregations
13
+
14
+ return aggregations
15
+ .sort(
16
+ (a, b) =>
17
+ (order.indexOf(a.attribute_code) ?? Infinity) -
18
+ (order.indexOf(b.attribute_code) ?? Infinity),
19
+ )
20
+ .filter((value) =>
21
+ order.find((sortedAttributeCode) => value.attribute_code === sortedAttributeCode),
22
+ )
23
+ }
@@ -1,21 +1,16 @@
1
- import type {
2
- AlgoliasettingsResponse,
3
- MeshContext,
4
- ProductAttributeSortInput,
5
- SortEnum,
6
- SortField,
7
- } from '@graphcommerce/graphql-mesh'
1
+ import type { MeshContext, SortEnum, SortField } from '@graphcommerce/graphql-mesh'
8
2
  import { nonNullable } from '@graphcommerce/magento-customer'
3
+ import type { GetAlgoliaSettingsReturn } from './getAlgoliaSettings'
9
4
  import type { AttributeList } from './getAttributeList'
10
5
  import { getIndexName } from './getIndexName'
11
6
 
12
7
  export type SortingOptions = Record<string, SortField & { dirs: SortEnum[] }>
13
8
 
14
- export async function sortingOptions(
15
- settings: AlgoliasettingsResponse,
9
+ export function sortFieldsOptions(
10
+ settings: GetAlgoliaSettingsReturn,
16
11
  attributeList: AttributeList,
17
12
  context: MeshContext,
18
- ): Promise<SortingOptions> {
13
+ ): SortField[] {
19
14
  const sortRecord: SortingOptions = {
20
15
  relevance: { label: 'Relevance', value: 'relevance', dirs: ['DESC'] },
21
16
  }
@@ -48,29 +43,10 @@ export async function sortingOptions(
48
43
  label: attributeList.find((attr) => attr.code === attributeCode)?.label,
49
44
  dirs: [curr.dir],
50
45
  }
51
- } else {
46
+ } else if (!sortRecord[attributeCode].dirs.includes(curr.dir)) {
52
47
  sortRecord[attributeCode].dirs.push(curr.dir)
53
48
  }
54
49
  }, {})
55
50
 
56
- return sortRecord
57
- }
58
-
59
- export async function getSortedIndex(
60
- context: MeshContext,
61
- settings: Promise<AlgoliasettingsResponse>,
62
- sortInput: ProductAttributeSortInput | null = {},
63
- ): Promise<string> {
64
- const baseIndex = getIndexName(context)
65
- // const availableSorting = Object.values(sortOptions)
66
- const [attr, dir] = Object.entries(sortInput ?? {}).filter(nonNullable)?.[0] ?? []
67
- if (!attr || !dir) return baseIndex
68
-
69
- const found = (await settings).replicas?.find(
70
- (replica) =>
71
- replica?.startsWith(`virtual(${baseIndex}_${attr}`) &&
72
- replica?.endsWith(`${dir?.toLowerCase()})`),
73
- )
74
-
75
- return found ? found?.slice(8, -1) : baseIndex
51
+ return Object.values(sortRecord)
76
52
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@graphcommerce/algolia-products",
3
3
  "homepage": "https://www.graphcommerce.org/",
4
4
  "repository": "github:graphcommerce-org/graphcommerce",
5
- "version": "9.1.0-canary.28",
5
+ "version": "9.1.0-canary.31",
6
6
  "sideEffects": false,
7
7
  "prettier": "@graphcommerce/prettier-config-pwa",
8
8
  "eslintConfig": {
@@ -15,14 +15,14 @@
15
15
  "generate": "tsx scripts/generate-spec.mts"
16
16
  },
17
17
  "peerDependencies": {
18
- "@graphcommerce/google-datalayer": "^9.1.0-canary.28",
19
- "@graphcommerce/graphql": "^9.1.0-canary.28",
20
- "@graphcommerce/graphql-mesh": "^9.1.0-canary.28",
21
- "@graphcommerce/magento-customer": "^9.1.0-canary.28",
22
- "@graphcommerce/magento-product": "^9.1.0-canary.28",
23
- "@graphcommerce/magento-search": "^9.1.0-canary.28",
24
- "@graphcommerce/next-config": "^9.1.0-canary.28",
25
- "@graphcommerce/next-ui": "^9.1.0-canary.28",
18
+ "@graphcommerce/google-datalayer": "^9.1.0-canary.31",
19
+ "@graphcommerce/graphql": "^9.1.0-canary.31",
20
+ "@graphcommerce/graphql-mesh": "^9.1.0-canary.31",
21
+ "@graphcommerce/magento-customer": "^9.1.0-canary.31",
22
+ "@graphcommerce/magento-product": "^9.1.0-canary.31",
23
+ "@graphcommerce/magento-search": "^9.1.0-canary.31",
24
+ "@graphcommerce/next-config": "^9.1.0-canary.31",
25
+ "@graphcommerce/next-ui": "^9.1.0-canary.31",
26
26
  "react": "^18.2.0"
27
27
  },
28
28
  "devDependencies": {
@@ -31,6 +31,9 @@ type AlgoliaProductHitAdditionalProperties {
31
31
  rating_summary: String
32
32
  thumbnail_url: String
33
33
  image_url: String
34
+
35
+ description: String
36
+ short_description: String
34
37
  }
35
38
 
36
39
  type Algoliahit {
@@ -57,4 +60,5 @@ input CategoryFilterInput {
57
60
 
58
61
  type Products {
59
62
  algolia_queryID: String
63
+ algolia_indexName: String
60
64
  }
@@ -1,8 +1,8 @@
1
- import yaml from 'js-yaml'
2
1
  import { writeFile } from 'node:fs/promises'
2
+ import conf from '@graphcommerce/prettier-config-pwa'
3
+ import yaml from 'js-yaml'
3
4
  import type { OpenAPIV3 } from 'openapi-types'
4
5
  import prettier from 'prettier'
5
- import conf from '@graphcommerce/prettier-config-pwa'
6
6
  import { algoliaSchemaBaseFilter } from './base-schema-filter.mjs'
7
7
 
8
8
  const response = await fetch(
@@ -33,7 +33,7 @@ const newSchema: OpenAPIV3.Document = {
33
33
  const keys = ['post', 'get', 'put', 'delete', 'patch', 'options'] as const
34
34
 
35
35
  keys.forEach((method) => {
36
- if (!newValue[method]?.['x-acl']?.some((value: string) => acl.includes(value))) {
36
+ if (!newValue[method]?.['x-acl']?.every((value: string) => acl.includes(value))) {
37
37
  newValue[method] = undefined
38
38
  }
39
39
  })