@faststore/api 1.9.8 → 1.9.14

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/dist/index.d.ts CHANGED
@@ -51,8 +51,10 @@ export declare const getResolvers: (options: Options) => {
51
51
  description?: string | undefined;
52
52
  canonical?: string | undefined;
53
53
  }, unknown, any>>;
54
- StoreFacet: Record<string, import("./platforms/vtex").Resolver<import("./platforms/vtex/clients/search/types/FacetSearchResult").Facet, unknown, any>>;
55
- StoreFacetValue: Record<string, import("./platforms/vtex").Resolver<import("./platforms/vtex/clients/search/types/FacetSearchResult").FacetValue, unknown, any>>;
54
+ StoreFacet: Record<string, import("./platforms/vtex").Resolver<import("./platforms/vtex/clients/search/types/FacetSearchResult").Facet<import("./platforms/vtex/clients/search/types/FacetSearchResult").FacetValueBoolean | import("./platforms/vtex/clients/search/types/FacetSearchResult").FacetValueRange>, unknown, any>>;
55
+ StoreFacetBoolean: Record<string, import("./platforms/vtex").Resolver<import("./platforms/vtex/clients/search/types/FacetSearchResult").Facet<import("./platforms/vtex/clients/search/types/FacetSearchResult").FacetValueBoolean>, unknown, any>>;
56
+ StoreFacetRange: Record<string, import("./platforms/vtex").Resolver<import("./platforms/vtex/clients/search/types/FacetSearchResult").Facet<import("./platforms/vtex/clients/search/types/FacetSearchResult").FacetValueRange>, unknown, any>>;
57
+ StoreFacetValueBoolean: Record<string, import("./platforms/vtex").Resolver<import("./platforms/vtex/clients/search/types/FacetSearchResult").FacetValueBoolean, unknown, any>>;
56
58
  StoreOffer: Record<string, import("./platforms/vtex").Resolver<import("./platforms/vtex/utils/enhanceCommercialOffer").EnhancedCommercialOffer<import("./platforms/vtex/clients/search/types/ProductSearchResult").Seller, import("./platforms/vtex/clients/search/types/ProductSearchResult").Item & {
57
59
  isVariantOf: import("./platforms/vtex/clients/search/types/ProductSearchResult").Product;
58
60
  } & {
@@ -1,6 +1,6 @@
1
1
  import type { Context, Options } from '../../index';
2
2
  import type { SelectedFacet } from '../../utils/facets';
3
- import type { FacetSearchResult } from './types/FacetSearchResult';
3
+ import type { Facet, FacetValueBoolean, FacetSearchResult } from './types/FacetSearchResult';
4
4
  import type { ProductSearchResult, Suggestion } from './types/ProductSearchResult';
5
5
  export declare type Sort = 'price:desc' | 'price:asc' | 'orders:desc' | 'name:desc' | 'name:asc' | 'release:desc' | 'discount:desc' | '';
6
6
  export interface SearchArgs {
@@ -17,6 +17,7 @@ export interface ProductLocator {
17
17
  field: 'id' | 'slug';
18
18
  value: string;
19
19
  }
20
+ export declare const isFacetBoolean: (facet: Facet) => facet is Facet<FacetValueBoolean>;
20
21
  export declare const IntelligentSearch: ({ account, environment, hideUnavailableItems }: Options, ctx: Context) => {
21
22
  facets: (args: Omit<SearchArgs, 'type'>) => Promise<FacetSearchResult>;
22
23
  products: (args: Omit<SearchArgs, 'type'>) => Promise<ProductSearchResult>;
@@ -3,26 +3,26 @@ export interface FacetSearchResult {
3
3
  facets: Facet[];
4
4
  breadcrumb: Breadcrumb;
5
5
  }
6
- export interface Facet {
6
+ export interface Facet<T = FacetValueBoolean | FacetValueRange> {
7
7
  type: FilterType;
8
8
  name: string;
9
9
  hidden: boolean;
10
- values: FacetValue[];
10
+ values: T[];
11
11
  quantity?: number;
12
- key?: string;
12
+ key: string;
13
13
  }
14
- export interface FacetValue {
14
+ export interface FacetValueBoolean {
15
15
  quantity: number;
16
16
  name: string;
17
17
  key: string;
18
18
  value: string;
19
- selected?: boolean;
20
- range?: {
19
+ selected: boolean;
20
+ }
21
+ export interface FacetValueRange {
22
+ range: {
21
23
  from: number;
22
24
  to: number;
23
25
  };
24
- children?: FacetValue[];
25
- id?: string;
26
26
  }
27
27
  interface Breadcrumb {
28
28
  href: string;
@@ -1,3 +1,4 @@
1
+ import type { SearchArgs } from './clients/search';
1
2
  import type { Loaders } from './loaders';
2
3
  import type { Clients } from './clients';
3
4
  import type { Channel } from './utils/channel';
@@ -26,6 +27,7 @@ export interface Context {
26
27
  channel: Required<Channel>;
27
28
  locale: string;
28
29
  flags: FeatureFlags;
30
+ searchArgs?: Omit<SearchArgs, 'type'>;
29
31
  };
30
32
  headers: Record<string, string>;
31
33
  }
@@ -79,8 +81,10 @@ export declare const getResolvers: (_: Options) => {
79
81
  description?: string | undefined;
80
82
  canonical?: string | undefined;
81
83
  }, unknown, any>>;
82
- StoreFacet: Record<string, Resolver<import("./clients/search/types/FacetSearchResult").Facet, unknown, any>>;
83
- StoreFacetValue: Record<string, Resolver<import("./clients/search/types/FacetSearchResult").FacetValue, unknown, any>>;
84
+ StoreFacet: Record<string, Resolver<import("./clients/search/types/FacetSearchResult").Facet<import("./clients/search/types/FacetSearchResult").FacetValueBoolean | import("./clients/search/types/FacetSearchResult").FacetValueRange>, unknown, any>>;
85
+ StoreFacetBoolean: Record<string, Resolver<import("./clients/search/types/FacetSearchResult").Facet<import("./clients/search/types/FacetSearchResult").FacetValueBoolean>, unknown, any>>;
86
+ StoreFacetRange: Record<string, Resolver<import("./clients/search/types/FacetSearchResult").Facet<import("./clients/search/types/FacetSearchResult").FacetValueRange>, unknown, any>>;
87
+ StoreFacetValueBoolean: Record<string, Resolver<import("./clients/search/types/FacetSearchResult").FacetValueBoolean, unknown, any>>;
84
88
  StoreOffer: Record<string, Resolver<import("./utils/enhanceCommercialOffer").EnhancedCommercialOffer<import("./clients/search/types/ProductSearchResult").Seller, import("./clients/search/types/ProductSearchResult").Item & {
85
89
  isVariantOf: import("./clients/search/types/ProductSearchResult").Product;
86
90
  } & {
@@ -95,7 +99,7 @@ export declare const getResolvers: (_: Options) => {
95
99
  } & {
96
100
  attachmentsValues?: import("./clients/commerce/types/OrderForm").Attachment[] | undefined;
97
101
  }, unknown, any>>;
98
- StoreSearchResult: Record<string, Resolver<Pick<import("./clients/search").SearchArgs, "hideUnavailableItems" | "query" | "page" | "count" | "sort" | "selectedFacets" | "fuzzy">, unknown, any>>;
102
+ StoreSearchResult: Record<string, Resolver<Pick<SearchArgs, "hideUnavailableItems" | "query" | "page" | "count" | "sort" | "selectedFacets" | "fuzzy">, unknown, any>>;
99
103
  StorePropertyValue: Record<string, Resolver<import("../..").IStorePropertyValue, unknown, any>>;
100
104
  ObjectOrString: import("graphql").GraphQLScalarType;
101
105
  Query: {
@@ -0,0 +1,3 @@
1
+ import type { Resolver } from '..';
2
+ import type { FacetValueBoolean } from '../clients/search/types/FacetSearchResult';
3
+ export declare const StoreFacetValueBoolean: Record<string, Resolver<FacetValueBoolean>>;
@@ -1,5 +1,7 @@
1
+ import type { FacetValueBoolean, Facet, FacetValueRange } from '../clients/search/types/FacetSearchResult';
1
2
  import type { Resolver } from '..';
2
- import type { Facet } from '../clients/search/types/FacetSearchResult';
3
3
  declare type Root = Facet;
4
4
  export declare const StoreFacet: Record<string, Resolver<Root>>;
5
+ export declare const StoreFacetBoolean: Record<string, Resolver<Facet<FacetValueBoolean>>>;
6
+ export declare const StoreFacetRange: Record<string, Resolver<Facet<FacetValueRange>>>;
5
7
  export {};
@@ -13,6 +13,7 @@ export declare const transformSelectedFacet: ({ key, value }: SelectedFacet) =>
13
13
  key: string;
14
14
  value: string;
15
15
  };
16
+ export declare const parseRange: (range: string) => [number, number] | null;
16
17
  export declare const findSlug: (facets?: SelectedFacet[] | null | undefined) => string | null;
17
18
  export declare const findSkuId: (facets?: SelectedFacet[] | null | undefined) => string | null;
18
19
  export declare const findLocale: (facets?: SelectedFacet[] | null | undefined) => string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/api",
3
- "version": "1.9.8",
3
+ "version": "1.9.14",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -37,6 +37,7 @@
37
37
  "express-graphql": "^0.12.0",
38
38
  "graphql": "^15.6.0",
39
39
  "jest-transform-graphql": "^2.1.0",
40
+ "shared": "^1.9.14",
40
41
  "ts-jest": "25.5.1",
41
42
  "tsdx": "^0.14.1",
42
43
  "tslib": "^2.3.1",
@@ -45,5 +46,5 @@
45
46
  "peerDependencies": {
46
47
  "graphql": "^15.6.0"
47
48
  },
48
- "gitHead": "f8e0cb3d43978426228addcc28055e537eaf7752"
49
+ "gitHead": "d37facb5b238781bb18ce48afb1b245e5c53038b"
49
50
  }
@@ -321,17 +321,29 @@ export type StoreCurrency = {
321
321
  symbol: Scalars['String'];
322
322
  };
323
323
 
324
- /** Search facet information. */
325
- export type StoreFacet = {
326
- __typename?: 'StoreFacet';
324
+ export type StoreFacet = StoreFacetBoolean | StoreFacetRange;
325
+
326
+ /** Search facet boolean information. */
327
+ export type StoreFacetBoolean = {
328
+ __typename?: 'StoreFacetBoolean';
329
+ /** Facet key. */
330
+ key: Scalars['String'];
331
+ /** Facet label. */
332
+ label: Scalars['String'];
333
+ /** Array with information on each facet value. */
334
+ values: Array<StoreFacetValueBoolean>;
335
+ };
336
+
337
+ /** Search facet range information. */
338
+ export type StoreFacetRange = {
339
+ __typename?: 'StoreFacetRange';
327
340
  /** Facet key. */
328
341
  key: Scalars['String'];
329
342
  /** Facet label. */
330
343
  label: Scalars['String'];
331
- /** Facet type. Possible values are `BOOLEAN` and `RANGE`. */
332
- type: StoreFacetType;
344
+ max: StoreFacetValueRange;
333
345
  /** Array with information on each facet value. */
334
- values: Array<StoreFacetValue>;
346
+ min: StoreFacetValueRange;
335
347
  };
336
348
 
337
349
  /** Search facet type. */
@@ -343,8 +355,8 @@ export const enum StoreFacetType {
343
355
  };
344
356
 
345
357
  /** Information of a specific facet value. */
346
- export type StoreFacetValue = {
347
- __typename?: 'StoreFacetValue';
358
+ export type StoreFacetValueBoolean = {
359
+ __typename?: 'StoreFacetValueBoolean';
348
360
  /** Facet value label. */
349
361
  label: Scalars['String'];
350
362
  /** Number of items with this facet. */
@@ -355,6 +367,12 @@ export type StoreFacetValue = {
355
367
  value: Scalars['String'];
356
368
  };
357
369
 
370
+ export type StoreFacetValueRange = {
371
+ __typename?: 'StoreFacetValueRange';
372
+ absolute: Scalars['Float'];
373
+ selected: Scalars['Float'];
374
+ };
375
+
358
376
  /** Image. */
359
377
  export type StoreImage = {
360
378
  __typename?: 'StoreImage';
@@ -2,7 +2,11 @@ import { fetchAPI } from '../fetch'
2
2
  import type { IStoreSelectedFacet } from '../../../../__generated__/schema'
3
3
  import type { Context, Options } from '../../index'
4
4
  import type { SelectedFacet } from '../../utils/facets'
5
- import type { FacetSearchResult } from './types/FacetSearchResult'
5
+ import type {
6
+ Facet,
7
+ FacetValueBoolean,
8
+ FacetSearchResult,
9
+ } from './types/FacetSearchResult'
6
10
  import type {
7
11
  ProductSearchResult,
8
12
  Suggestion,
@@ -38,6 +42,10 @@ const POLICY_KEY = 'trade-policy'
38
42
  const REGION_KEY = 'region-id'
39
43
  const CHANNEL_KEYS = new Set([POLICY_KEY, REGION_KEY])
40
44
 
45
+ export const isFacetBoolean = (
46
+ facet: Facet
47
+ ): facet is Facet<FacetValueBoolean> => facet.type === 'TEXT'
48
+
41
49
  export const IntelligentSearch = (
42
50
  { account, environment, hideUnavailableItems }: Options,
43
51
  ctx: Context
@@ -4,27 +4,28 @@ export interface FacetSearchResult {
4
4
  breadcrumb: Breadcrumb
5
5
  }
6
6
 
7
- export interface Facet {
7
+ export interface Facet<T = FacetValueBoolean | FacetValueRange> {
8
8
  type: FilterType
9
9
  name: string
10
10
  hidden: boolean
11
- values: FacetValue[]
11
+ values: T[]
12
12
  quantity?: number
13
- key?: string
13
+ key: string
14
14
  }
15
15
 
16
- export interface FacetValue {
16
+ export interface FacetValueBoolean {
17
17
  quantity: number
18
18
  name: string
19
19
  key: string
20
20
  value: string
21
- selected?: boolean
22
- range?: {
21
+ selected: boolean
22
+ }
23
+
24
+ export interface FacetValueRange {
25
+ range: {
23
26
  from: number
24
27
  to: number
25
28
  }
26
- children?: FacetValue[]
27
- id?: string
28
29
  }
29
30
 
30
31
  interface Breadcrumb {
@@ -1,24 +1,29 @@
1
1
  import { getClients } from './clients'
2
+ import type { SearchArgs } from './clients/search'
2
3
  import { getLoaders } from './loaders'
3
4
  import { StoreAggregateOffer } from './resolvers/aggregateOffer'
4
5
  import { StoreAggregateRating } from './resolvers/aggregateRating'
5
6
  import { StoreCollection } from './resolvers/collection'
6
- import { StoreFacet } from './resolvers/facet'
7
- import { StoreFacetValue } from './resolvers/facetValue'
7
+ import {
8
+ StoreFacet,
9
+ StoreFacetBoolean,
10
+ StoreFacetRange,
11
+ } from './resolvers/facet'
12
+ import { StoreFacetValueBoolean } from './resolvers/faceValue'
8
13
  import { Mutation } from './resolvers/mutation'
14
+ import { ObjectOrString } from './resolvers/objectOrString'
9
15
  import { StoreOffer } from './resolvers/offer'
10
16
  import { StoreProduct } from './resolvers/product'
11
17
  import { StoreProductGroup } from './resolvers/productGroup'
18
+ import { StorePropertyValue } from './resolvers/propertyValue'
12
19
  import { Query } from './resolvers/query'
13
20
  import { StoreReview } from './resolvers/review'
14
21
  import { StoreSearchResult } from './resolvers/searchResult'
15
22
  import { StoreSeo } from './resolvers/seo'
16
- import { ObjectOrString } from './resolvers/objectOrString'
17
- import { StorePropertyValue } from './resolvers/propertyValue'
23
+ import ChannelMarshal from './utils/channel'
18
24
  import type { Loaders } from './loaders'
19
25
  import type { Clients } from './clients'
20
26
  import type { Channel } from './utils/channel'
21
- import ChannelMarshal from './utils/channel'
22
27
 
23
28
  export interface Options {
24
29
  platform: 'vtex'
@@ -48,6 +53,7 @@ export interface Context {
48
53
  channel: Required<Channel>
49
54
  locale: string
50
55
  flags: FeatureFlags
56
+ searchArgs?: Omit<SearchArgs, 'type'>
51
57
  }
52
58
  headers: Record<string, string>
53
59
  }
@@ -65,7 +71,9 @@ const Resolvers = {
65
71
  StoreProduct,
66
72
  StoreSeo,
67
73
  StoreFacet,
68
- StoreFacetValue,
74
+ StoreFacetBoolean,
75
+ StoreFacetRange,
76
+ StoreFacetValueBoolean,
69
77
  StoreOffer,
70
78
  StoreAggregateRating,
71
79
  StoreReview,
@@ -77,16 +85,18 @@ const Resolvers = {
77
85
  Mutation,
78
86
  }
79
87
 
80
- export const getContextFactory = (options: Options) => (ctx: any): Context => {
81
- ctx.storage = {
82
- channel: ChannelMarshal.parse(options.channel),
83
- flags: options.flags ?? {},
84
- locale: options.locale,
85
- }
86
- ctx.clients = getClients(options, ctx)
87
- ctx.loaders = getLoaders(options, ctx)
88
+ export const getContextFactory =
89
+ (options: Options) =>
90
+ (ctx: any): Context => {
91
+ ctx.storage = {
92
+ channel: ChannelMarshal.parse(options.channel),
93
+ flags: options.flags ?? {},
94
+ locale: options.locale,
95
+ }
96
+ ctx.clients = getClients(options, ctx)
97
+ ctx.loaders = getLoaders(options, ctx)
88
98
 
89
- return ctx
90
- }
99
+ return ctx
100
+ }
91
101
 
92
102
  export const getResolvers = (_: Options) => Resolvers
@@ -0,0 +1,12 @@
1
+ import type { Resolver } from '..'
2
+ import type { FacetValueBoolean } from '../clients/search/types/FacetSearchResult'
3
+
4
+ export const StoreFacetValueBoolean: Record<
5
+ string,
6
+ Resolver<FacetValueBoolean>
7
+ > = {
8
+ value: ({ value }) => value,
9
+ label: ({ name }) => name || 'unknown',
10
+ selected: ({ selected }) => selected,
11
+ quantity: ({ quantity }) => quantity,
12
+ }
@@ -1,11 +1,72 @@
1
+ import { parseRange } from '../utils/facets'
2
+ import { min } from '../utils/orderStatistics'
3
+ import type {
4
+ FacetValueBoolean,
5
+ Facet,
6
+ FacetValueRange,
7
+ } from '../clients/search/types/FacetSearchResult'
1
8
  import type { Resolver } from '..'
2
- import type { Facet } from '../clients/search/types/FacetSearchResult'
3
9
 
4
10
  type Root = Facet
5
11
 
6
12
  export const StoreFacet: Record<string, Resolver<Root>> = {
7
- key: ({ key }) => key ?? '',
8
- label: ({ name }) => name ?? 'unknown',
9
- values: ({ values }) => values,
10
- type: ({ type }) => (type === 'TEXT' ? 'BOOLEAN' : 'RANGE'),
13
+ __resolveType: ({ type }) =>
14
+ type === 'TEXT' ? 'StoreFacetBoolean' : 'StoreFacetRange',
15
+ }
16
+
17
+ export const StoreFacetBoolean: Record<
18
+ string,
19
+ Resolver<Facet<FacetValueBoolean>>
20
+ > = {
21
+ key: ({ key }) => key,
22
+ label: ({ name }) => name,
23
+ values: ({ values }) => values.sort((a, b) => a.name.localeCompare(b.name)),
24
+ }
25
+
26
+ export const StoreFacetRange: Record<
27
+ string,
28
+ Resolver<Facet<FacetValueRange>>
29
+ > = {
30
+ key: ({ key }) => key,
31
+ label: ({ name }) => name,
32
+ min: ({ values, key }, _, { storage: { searchArgs } }) => {
33
+ /**
34
+ * Fetch the selected range the user queried.
35
+ *
36
+ * This is necessary because, differently from boolean facets, Search API does
37
+ * not return the selected values, making us have to implement it in here
38
+ */
39
+ const selectedRange = parseRange(
40
+ searchArgs?.selectedFacets?.find((facet) => facet.key === key)?.value ??
41
+ ''
42
+ )
43
+
44
+ const facet = min(values, (a, b) => a.range.from - b.range.from)
45
+ const globalMin = facet?.range.from ?? 0
46
+
47
+ return {
48
+ selected: selectedRange?.[0] ?? globalMin,
49
+ absolute: globalMin,
50
+ }
51
+ },
52
+ max: ({ values, key }, _, { storage: { searchArgs } }) => {
53
+ /**
54
+ * Fetch the selected range the user queried.
55
+ *
56
+ * This is necessary because, differently from boolean facets, Search API does
57
+ * not return the selected values, making us have to implement it in here
58
+ */
59
+ const selectedRange = parseRange(
60
+ searchArgs?.selectedFacets?.find((facet) => facet.key === key)?.value ??
61
+ ''
62
+ )
63
+
64
+ const facet = min(values, (a, b) => b.range.to - a.range.to)
65
+ const globalMax = facet?.range.to ?? 0
66
+
67
+ return {
68
+ selected: selectedRange?.[1] ?? globalMax,
69
+ absolute: globalMax,
70
+ }
71
+ },
11
72
  }
@@ -87,7 +87,7 @@ export const StoreOffer: Record<string, Resolver<Root>> = {
87
87
  },
88
88
  listPrice: (root) => {
89
89
  if (isSearchItem(root)) {
90
- return root.ListPrice
90
+ return root.ListPrice ?? 0
91
91
  }
92
92
 
93
93
  if (isOrderFormItem(root)) {
@@ -1,11 +1,11 @@
1
+ import { enhanceSku } from '../utils/enhanceSku'
1
2
  import type { Resolver } from '..'
2
3
  import type { SearchArgs } from '../clients/search'
3
4
  import type { Facet } from '../clients/search/types/FacetSearchResult'
4
- import { enhanceSku } from '../utils/enhanceSku'
5
5
 
6
6
  type Root = Omit<SearchArgs, 'type'>
7
7
 
8
- const REMOVED_FACETS_FROM_COLLECTION_PAGE = ['departamento', 'Departamento']
8
+ const isRootFacet = (facet: Facet) => facet.key === 'category-1'
9
9
 
10
10
  export const StoreSearchResult: Record<string, Resolver<Root>> = {
11
11
  suggestions: async (searchArgs, _, ctx) => {
@@ -90,33 +90,16 @@ export const StoreSearchResult: Record<string, Resolver<Root>> = {
90
90
  clients: { search: is },
91
91
  } = ctx
92
92
 
93
- const { facets } = await is.facets(searchArgs)
94
-
95
- const isCollectionPage = !searchArgs.query
96
- const filteredFacets = facets?.reduce((acc, currentFacet) => {
97
- const shouldFilterFacet = REMOVED_FACETS_FROM_COLLECTION_PAGE.includes(
98
- currentFacet.name
99
- )
100
-
101
- const shouldRemoveFacetFromCollectionPage =
102
- isCollectionPage && shouldFilterFacet
93
+ ctx.storage.searchArgs = searchArgs
103
94
 
104
- if (shouldRemoveFacetFromCollectionPage) {
105
- return acc
106
- }
107
-
108
- currentFacet.values.sort((a, b) => {
109
- const firstItemLabel = a.name ?? ''
110
- const secondItemLabel = b.name ?? ''
95
+ const { facets = [] } = await is.facets(searchArgs)
111
96
 
112
- return firstItemLabel.localeCompare(secondItemLabel)
113
- })
114
-
115
- acc.push(currentFacet)
97
+ const isCollectionPage = !searchArgs.query
116
98
 
117
- return acc
118
- }, [] as Facet[])
99
+ const filteredFacets = facets
100
+ // Remove root facet on category pages
101
+ .filter((facet) => !isCollectionPage || !isRootFacet(facet))
119
102
 
120
- return filteredFacets ?? []
103
+ return filteredFacets
121
104
  },
122
105
  }
@@ -29,11 +29,29 @@ export const transformSelectedFacet = ({ key, value }: SelectedFacet) => {
29
29
  return [] // remove this facet from search
30
30
  }
31
31
 
32
+ case 'price': {
33
+ return { key, value: value.replace('-to-', ':') }
34
+ }
35
+
32
36
  default:
33
37
  return { key, value }
34
38
  }
35
39
  }
36
40
 
41
+ export const parseRange = (range: string): [number, number] | null => {
42
+ const splitted = range.split(':').map(Number)
43
+
44
+ if (
45
+ splitted.length !== 2 ||
46
+ Number.isNaN(splitted[0]) ||
47
+ Number.isNaN(splitted[1])
48
+ ) {
49
+ return null
50
+ }
51
+
52
+ return splitted as [number, number]
53
+ }
54
+
37
55
  export const findSlug = (facets?: Maybe<SelectedFacet[]>) =>
38
56
  facets?.find((x) => x.key === 'slug')?.value ?? null
39
57
 
@@ -1,7 +1,9 @@
1
+ union StoreFacet = StoreFacetRange | StoreFacetBoolean
2
+
1
3
  """
2
- Search facet information.
4
+ Search facet range information.
3
5
  """
4
- type StoreFacet {
6
+ type StoreFacetRange {
5
7
  """
6
8
  Facet key.
7
9
  """
@@ -13,17 +15,37 @@ type StoreFacet {
13
15
  """
14
16
  Array with information on each facet value.
15
17
  """
16
- values: [StoreFacetValue!]!
18
+ min: StoreFacetValueRange!
19
+ max: StoreFacetValueRange!
20
+ }
21
+
22
+ """
23
+ Search facet boolean information.
24
+ """
25
+ type StoreFacetBoolean {
26
+ """
27
+ Facet key.
28
+ """
29
+ key: String!
30
+ """
31
+ Facet label.
32
+ """
33
+ label: String!
17
34
  """
18
- Facet type. Possible values are `BOOLEAN` and `RANGE`.
35
+ Array with information on each facet value.
19
36
  """
20
- type: StoreFacetType!
37
+ values: [StoreFacetValueBoolean!]!
38
+ }
39
+
40
+ type StoreFacetValueRange {
41
+ absolute: Float!
42
+ selected: Float!
21
43
  }
22
44
 
23
45
  """
24
46
  Information of a specific facet value.
25
47
  """
26
- type StoreFacetValue {
48
+ type StoreFacetValueBoolean {
27
49
  """
28
50
  Facet value.
29
51
  """
@@ -1,5 +0,0 @@
1
- import type { Resolver } from '..';
2
- import type { FacetValue } from '../clients/search/types/FacetSearchResult';
3
- declare type Root = FacetValue;
4
- export declare const StoreFacetValue: Record<string, Resolver<Root>>;
5
- export {};
@@ -1,12 +0,0 @@
1
- import type { Resolver } from '..'
2
- import type { FacetValue } from '../clients/search/types/FacetSearchResult'
3
-
4
- type Root = FacetValue
5
-
6
- export const StoreFacetValue: Record<string, Resolver<Root>> = {
7
- value: ({ value, range }) =>
8
- value ?? `${range?.from ?? ''}-to-${range?.to ?? ''}`,
9
- label: ({ name }) => name || 'unknown',
10
- selected: ({ selected }) => selected,
11
- quantity: ({ quantity }) => quantity,
12
- }