@faststore/api 1.9.9 → 1.9.11
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/CHANGELOG.md +11 -0
- package/dist/__generated__/schema.d.ts +23 -8
- package/dist/api.cjs.development.js +254 -194
- package/dist/api.cjs.development.js.map +1 -1
- package/dist/api.cjs.production.min.js +1 -1
- package/dist/api.cjs.production.min.js.map +1 -1
- package/dist/api.esm.js +254 -194
- package/dist/api.esm.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/platforms/vtex/clients/search/index.d.ts +2 -1
- package/dist/platforms/vtex/clients/search/types/FacetSearchResult.d.ts +8 -8
- package/dist/platforms/vtex/index.d.ts +7 -3
- package/dist/platforms/vtex/resolvers/faceValue.d.ts +3 -0
- package/dist/platforms/vtex/resolvers/facet.d.ts +3 -1
- package/dist/platforms/vtex/utils/facets.d.ts +1 -0
- package/package.json +2 -2
- package/src/__generated__/schema.ts +26 -8
- package/src/platforms/vtex/clients/search/index.ts +9 -1
- package/src/platforms/vtex/clients/search/types/FacetSearchResult.ts +9 -8
- package/src/platforms/vtex/index.ts +14 -6
- package/src/platforms/vtex/resolvers/faceValue.ts +12 -0
- package/src/platforms/vtex/resolvers/facet.ts +66 -5
- package/src/platforms/vtex/resolvers/offer.ts +1 -1
- package/src/platforms/vtex/resolvers/searchResult.ts +9 -26
- package/src/platforms/vtex/utils/facets.ts +18 -0
- package/src/typeDefs/facet.graphql +28 -6
- package/dist/platforms/vtex/resolvers/facetValue.d.ts +0 -5
- package/src/platforms/vtex/resolvers/facetValue.ts +0 -12
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
|
|
55
|
-
|
|
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:
|
|
10
|
+
values: T[];
|
|
11
11
|
quantity?: number;
|
|
12
|
-
key
|
|
12
|
+
key: string;
|
|
13
13
|
}
|
|
14
|
-
export interface
|
|
14
|
+
export interface FacetValueBoolean {
|
|
15
15
|
quantity: number;
|
|
16
16
|
name: string;
|
|
17
17
|
key: string;
|
|
18
18
|
value: string;
|
|
19
|
-
selected
|
|
20
|
-
|
|
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
|
|
83
|
-
|
|
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<
|
|
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: {
|
|
@@ -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.
|
|
3
|
+
"version": "1.9.11",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -45,5 +45,5 @@
|
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"graphql": "^15.6.0"
|
|
47
47
|
},
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "78e4520e4588669f0f3382ccd441737b98c57d11"
|
|
49
49
|
}
|
|
@@ -321,17 +321,29 @@ export type StoreCurrency = {
|
|
|
321
321
|
symbol: Scalars['String'];
|
|
322
322
|
};
|
|
323
323
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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
|
-
|
|
332
|
-
type: StoreFacetType;
|
|
344
|
+
max: StoreFacetValueRange;
|
|
333
345
|
/** Array with information on each facet value. */
|
|
334
|
-
|
|
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
|
|
347
|
-
__typename?: '
|
|
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 {
|
|
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:
|
|
11
|
+
values: T[]
|
|
12
12
|
quantity?: number
|
|
13
|
-
key
|
|
13
|
+
key: string
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export interface
|
|
16
|
+
export interface FacetValueBoolean {
|
|
17
17
|
quantity: number
|
|
18
18
|
name: string
|
|
19
19
|
key: string
|
|
20
20
|
value: string
|
|
21
|
-
selected
|
|
22
|
-
|
|
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 {
|
|
7
|
-
|
|
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
|
|
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
|
-
|
|
74
|
+
StoreFacetBoolean,
|
|
75
|
+
StoreFacetRange,
|
|
76
|
+
StoreFacetValueBoolean,
|
|
69
77
|
StoreOffer,
|
|
70
78
|
StoreAggregateRating,
|
|
71
79
|
StoreReview,
|
|
@@ -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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
}
|
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
acc.push(currentFacet)
|
|
97
|
+
const isCollectionPage = !searchArgs.query
|
|
116
98
|
|
|
117
|
-
|
|
118
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
35
|
+
Array with information on each facet value.
|
|
19
36
|
"""
|
|
20
|
-
|
|
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
|
|
48
|
+
type StoreFacetValueBoolean {
|
|
27
49
|
"""
|
|
28
50
|
Facet value.
|
|
29
51
|
"""
|
|
@@ -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
|
-
}
|