@reactionary/provider-algolia 0.3.1 → 0.3.3
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/README.md +12 -4
- package/core/initialize.js +6 -2
- package/index.js +1 -0
- package/package.json +2 -2
- package/providers/analytics.provider.js +7 -7
- package/providers/index.js +1 -0
- package/providers/product-recommendations.provider.js +174 -0
- package/providers/product-search.provider.js +7 -5
- package/schema/capabilities.schema.js +2 -1
- package/schema/product-recommendation.schema.js +9 -0
- package/src/index.d.ts +1 -0
- package/src/providers/index.d.ts +1 -0
- package/src/providers/product-recommendations.provider.d.ts +58 -0
- package/src/providers/product-search.provider.d.ts +4 -2
- package/src/schema/capabilities.schema.d.ts +1 -0
- package/src/schema/product-recommendation.schema.d.ts +8 -0
package/README.md
CHANGED
|
@@ -38,11 +38,19 @@ You can have more, for use with facets, and additional searchable fields, but th
|
|
|
38
38
|
|
|
39
39
|
The `objectID` corrosponds to your productIdentifier, and `variantID` should match your SKU
|
|
40
40
|
|
|
41
|
+
## Analytics
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
The Algolia analytics provider maps the following tracked event types to data tracked in Algolia:
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
- AnalyticsMutationProductSummaryViewEvent => ViewedObjectIDs
|
|
46
|
+
- AnalyticsMutationProductSummaryClickEvent => ClickedObjectIDsAfterSearch / ClickedObjectIDs
|
|
47
|
+
- AnalyticsMutationProductAddToCartEvent => AddedToCartObjectIDsAfterSearch / AddedToCartObjectIDs
|
|
48
|
+
- AnalyticsMutationPurchaseEvent => PurchasedObjectIDs
|
|
45
49
|
|
|
46
|
-
|
|
50
|
+
The `AfterSearch` variants are (with the exception of purchase) preferred by the provider in the cases where Algolia is the source of the events. For search or recommendation this would typically be the case, but not necesarily for users arriving on a PDP as a direct target from a search or a link.
|
|
47
51
|
|
|
48
|
-
|
|
52
|
+
Note that we do not map `PurchasedObjectIDsAfterSearch` as it would require us to persist the search query ID that lead to the add-to-cart occuring on the cart items. This currently seems like an excess burden to impose on the cart interface.
|
|
53
|
+
|
|
54
|
+
The `ConvertedObjectIDs` and `ConvertedObjectIDsAfterSearch` are not mapped as they seem superfluous by all accounts in a product-purchase based flow. They could likely be used for other types of conversions in a more general setup, such as a customer finishing reading an article.
|
|
55
|
+
|
|
56
|
+
Finally the events that are related to filtering are not mapped, as they are by all accounts deprecated and no longer influence any of the recommendation or personalization features.
|
package/core/initialize.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AlgoliaProductSearchProvider } from "../providers/product-search.provider.js";
|
|
2
2
|
import { AlgoliaAnalyticsProvider } from "../providers/analytics.provider.js";
|
|
3
|
+
import { AlgoliaProductRecommendationsProvider } from "../providers/product-recommendations.provider.js";
|
|
3
4
|
function withAlgoliaCapabilities(configuration, capabilities) {
|
|
4
5
|
return (cache, context) => {
|
|
5
6
|
const client = {};
|
|
6
7
|
if (capabilities.productSearch) {
|
|
7
|
-
client.productSearch = new
|
|
8
|
+
client.productSearch = new AlgoliaProductSearchProvider(cache, context, configuration);
|
|
8
9
|
}
|
|
9
10
|
if (capabilities.analytics) {
|
|
10
11
|
client.analytics = new AlgoliaAnalyticsProvider(cache, context, configuration);
|
|
11
12
|
}
|
|
13
|
+
if (capabilities.productRecommendations) {
|
|
14
|
+
client.productRecommendations = new AlgoliaProductRecommendationsProvider(configuration, cache, context);
|
|
15
|
+
}
|
|
12
16
|
return client;
|
|
13
17
|
};
|
|
14
18
|
}
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reactionary/provider-algolia",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"types": "src/index.d.ts",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@reactionary/core": "0.3.
|
|
7
|
+
"@reactionary/core": "0.3.3",
|
|
8
8
|
"algoliasearch": "^5.23.4",
|
|
9
9
|
"zod": "4.1.9"
|
|
10
10
|
},
|
|
@@ -2,13 +2,13 @@ import {
|
|
|
2
2
|
AnalyticsProvider
|
|
3
3
|
} from "@reactionary/core";
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
algoliasearch
|
|
6
6
|
} from "algoliasearch";
|
|
7
7
|
class AlgoliaAnalyticsProvider extends AnalyticsProvider {
|
|
8
8
|
constructor(cache, requestContext, config) {
|
|
9
9
|
super(cache, requestContext);
|
|
10
10
|
this.config = config;
|
|
11
|
-
this.client =
|
|
11
|
+
this.client = algoliasearch(this.config.appId, this.config.apiKey).initInsights({});
|
|
12
12
|
}
|
|
13
13
|
async processProductAddToCart(event) {
|
|
14
14
|
if (event.source && event.source.type === "search") {
|
|
@@ -21,7 +21,7 @@ class AlgoliaAnalyticsProvider extends AnalyticsProvider {
|
|
|
21
21
|
userToken: this.context.session.identityContext.personalizationKey,
|
|
22
22
|
queryID: event.source.identifier.key
|
|
23
23
|
};
|
|
24
|
-
this.client.pushEvents({
|
|
24
|
+
const response = await this.client.pushEvents({
|
|
25
25
|
events: [algoliaEvent]
|
|
26
26
|
});
|
|
27
27
|
}
|
|
@@ -37,7 +37,7 @@ class AlgoliaAnalyticsProvider extends AnalyticsProvider {
|
|
|
37
37
|
positions: [event.position],
|
|
38
38
|
queryID: event.source.identifier.key
|
|
39
39
|
};
|
|
40
|
-
this.client.pushEvents({
|
|
40
|
+
const response = await this.client.pushEvents({
|
|
41
41
|
events: [algoliaEvent]
|
|
42
42
|
});
|
|
43
43
|
}
|
|
@@ -51,7 +51,7 @@ class AlgoliaAnalyticsProvider extends AnalyticsProvider {
|
|
|
51
51
|
objectIDs: event.products.map((x) => x.key),
|
|
52
52
|
userToken: this.context.session.identityContext.personalizationKey
|
|
53
53
|
};
|
|
54
|
-
this.client.pushEvents({
|
|
54
|
+
const response = await this.client.pushEvents({
|
|
55
55
|
events: [algoliaEvent]
|
|
56
56
|
});
|
|
57
57
|
}
|
|
@@ -62,10 +62,10 @@ class AlgoliaAnalyticsProvider extends AnalyticsProvider {
|
|
|
62
62
|
eventType: "conversion",
|
|
63
63
|
eventSubtype: "purchase",
|
|
64
64
|
index: this.config.indexName,
|
|
65
|
-
objectIDs: event.order.items.map((x) => x.
|
|
65
|
+
objectIDs: event.order.items.map((x) => x.variant.sku),
|
|
66
66
|
userToken: this.context.session.identityContext.personalizationKey
|
|
67
67
|
};
|
|
68
|
-
this.client.pushEvents({
|
|
68
|
+
const response = await this.client.pushEvents({
|
|
69
69
|
events: [algoliaEvent]
|
|
70
70
|
});
|
|
71
71
|
}
|
package/providers/index.js
CHANGED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ProductRecommendationsProvider
|
|
3
|
+
} from "@reactionary/core";
|
|
4
|
+
import { recommendClient } from "algoliasearch";
|
|
5
|
+
class AlgoliaProductRecommendationsProvider extends ProductRecommendationsProvider {
|
|
6
|
+
constructor(config, cache, context) {
|
|
7
|
+
super(cache, context);
|
|
8
|
+
this.config = config;
|
|
9
|
+
}
|
|
10
|
+
getRecommendClient() {
|
|
11
|
+
return recommendClient(this.config.appId, this.config.apiKey);
|
|
12
|
+
}
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
14
|
+
getRecommendationThreshold(_algorithm) {
|
|
15
|
+
return 10;
|
|
16
|
+
}
|
|
17
|
+
getQueryParametersForRecommendations(algorithm) {
|
|
18
|
+
return {
|
|
19
|
+
userToken: this.context.session.identityContext?.personalizationKey || "anonymous",
|
|
20
|
+
analytics: true,
|
|
21
|
+
analyticsTags: ["reactionary", algorithm],
|
|
22
|
+
clickAnalytics: true
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get frequently bought together recommendations using Algolia Recommend
|
|
27
|
+
*/
|
|
28
|
+
async getFrequentlyBoughtTogetherRecommendations(query) {
|
|
29
|
+
const client = this.getRecommendClient();
|
|
30
|
+
try {
|
|
31
|
+
const response = await client.getRecommendations({
|
|
32
|
+
requests: [
|
|
33
|
+
{
|
|
34
|
+
indexName: this.config.indexName,
|
|
35
|
+
model: "bought-together",
|
|
36
|
+
objectID: query.sourceProduct.key,
|
|
37
|
+
maxRecommendations: query.numberOfRecommendations,
|
|
38
|
+
threshold: this.getRecommendationThreshold("bought-together"),
|
|
39
|
+
queryParameters: this.getQueryParametersForRecommendations("bought-together")
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
});
|
|
43
|
+
const result = [];
|
|
44
|
+
if (response.results) {
|
|
45
|
+
for (const res of response.results) {
|
|
46
|
+
result.push(...this.parseRecommendation(res, query));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error("Error fetching frequently bought together recommendations:", error);
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get similar product recommendations using Algolia Recommend
|
|
57
|
+
*/
|
|
58
|
+
async getSimilarProductsRecommendations(query) {
|
|
59
|
+
const client = this.getRecommendClient();
|
|
60
|
+
try {
|
|
61
|
+
const response = await client.getRecommendations({
|
|
62
|
+
requests: [
|
|
63
|
+
{
|
|
64
|
+
indexName: this.config.indexName,
|
|
65
|
+
model: "looking-similar",
|
|
66
|
+
objectID: query.sourceProduct.key,
|
|
67
|
+
maxRecommendations: query.numberOfRecommendations,
|
|
68
|
+
threshold: this.getRecommendationThreshold("looking-similar"),
|
|
69
|
+
queryParameters: this.getQueryParametersForRecommendations("looking-similar")
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
});
|
|
73
|
+
const result = [];
|
|
74
|
+
if (response.results) {
|
|
75
|
+
for (const res of response.results) {
|
|
76
|
+
result.push(...this.parseRecommendation(res, query));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error("Error fetching similar product recommendations:", error);
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get related product recommendations using Algolia Recommend
|
|
87
|
+
*/
|
|
88
|
+
async getRelatedProductsRecommendations(query) {
|
|
89
|
+
const client = this.getRecommendClient();
|
|
90
|
+
try {
|
|
91
|
+
const response = await client.getRecommendations({
|
|
92
|
+
requests: [
|
|
93
|
+
{
|
|
94
|
+
indexName: this.config.indexName,
|
|
95
|
+
model: "related-products",
|
|
96
|
+
objectID: query.sourceProduct.key,
|
|
97
|
+
maxRecommendations: query.numberOfRecommendations,
|
|
98
|
+
threshold: this.getRecommendationThreshold("related-products"),
|
|
99
|
+
queryParameters: this.getQueryParametersForRecommendations("related-products")
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
});
|
|
103
|
+
const result = [];
|
|
104
|
+
if (response.results) {
|
|
105
|
+
for (const res of response.results) {
|
|
106
|
+
result.push(...this.parseRecommendation(res, query));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.error("Error fetching related product recommendations:", error);
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get trending in category recommendations using Algolia Recommend
|
|
117
|
+
*/
|
|
118
|
+
async getTrendingInCategoryRecommendations(query) {
|
|
119
|
+
const client = this.getRecommendClient();
|
|
120
|
+
try {
|
|
121
|
+
const response = await client.getRecommendations({
|
|
122
|
+
requests: [
|
|
123
|
+
{
|
|
124
|
+
indexName: this.config.indexName,
|
|
125
|
+
model: "trending-items",
|
|
126
|
+
facetName: "categories",
|
|
127
|
+
facetValue: query.sourceCategory.key,
|
|
128
|
+
maxRecommendations: query.numberOfRecommendations,
|
|
129
|
+
threshold: this.getRecommendationThreshold("trending-items"),
|
|
130
|
+
queryParameters: this.getQueryParametersForRecommendations("trending-items")
|
|
131
|
+
}
|
|
132
|
+
]
|
|
133
|
+
});
|
|
134
|
+
const result = [];
|
|
135
|
+
if (response.results) {
|
|
136
|
+
for (const res of response.results) {
|
|
137
|
+
result.push(...this.parseRecommendation(res, query));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return result;
|
|
141
|
+
} catch (error) {
|
|
142
|
+
console.error("Error fetching trending in category recommendations:", error);
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
parseRecommendation(res, query) {
|
|
147
|
+
const result = [];
|
|
148
|
+
for (const hit of res.hits) {
|
|
149
|
+
const recommendationIdentifier = {
|
|
150
|
+
key: res.queryID || "x",
|
|
151
|
+
algorithm: query.algorithm,
|
|
152
|
+
abTestID: res.abTestID,
|
|
153
|
+
abTestVariantID: res.abTestVariantID
|
|
154
|
+
};
|
|
155
|
+
const recommendation = this.parseSingle(hit, recommendationIdentifier);
|
|
156
|
+
result.push(recommendation);
|
|
157
|
+
}
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Maps Algolia recommendation results to ProductRecommendation format
|
|
162
|
+
*/
|
|
163
|
+
parseSingle(hit, recommendationIdentifier) {
|
|
164
|
+
return {
|
|
165
|
+
recommendationIdentifier,
|
|
166
|
+
product: {
|
|
167
|
+
key: hit.objectID
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
export {
|
|
173
|
+
AlgoliaProductRecommendationsProvider
|
|
174
|
+
};
|
|
@@ -23,8 +23,8 @@ import {
|
|
|
23
23
|
success
|
|
24
24
|
} from "@reactionary/core";
|
|
25
25
|
import { algoliasearch } from "algoliasearch";
|
|
26
|
-
class
|
|
27
|
-
constructor(
|
|
26
|
+
class AlgoliaProductSearchProvider extends ProductSearchProvider {
|
|
27
|
+
constructor(cache, context, config) {
|
|
28
28
|
super(cache, context);
|
|
29
29
|
this.config = config;
|
|
30
30
|
}
|
|
@@ -136,7 +136,9 @@ class AlgoliaSearchProvider extends ProductSearchProvider {
|
|
|
136
136
|
term: query.search.term,
|
|
137
137
|
facets: query.search.facets,
|
|
138
138
|
filters: query.search.filters,
|
|
139
|
-
paginationOptions: query.search.paginationOptions
|
|
139
|
+
paginationOptions: query.search.paginationOptions,
|
|
140
|
+
index: body.index || "",
|
|
141
|
+
key: body.queryID || ""
|
|
140
142
|
},
|
|
141
143
|
pageNumber: (body.page || 0) + 1,
|
|
142
144
|
pageSize: body.hitsPerPage || 0,
|
|
@@ -177,7 +179,7 @@ __decorateClass([
|
|
|
177
179
|
inputSchema: ProductSearchQueryByTermSchema,
|
|
178
180
|
outputSchema: ProductSearchResultSchema
|
|
179
181
|
})
|
|
180
|
-
],
|
|
182
|
+
], AlgoliaProductSearchProvider.prototype, "queryByTerm", 1);
|
|
181
183
|
export {
|
|
182
|
-
|
|
184
|
+
AlgoliaProductSearchProvider
|
|
183
185
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ProductRecommendationIdentifierSchema } from "@reactionary/core";
|
|
2
|
+
import z from "zod";
|
|
3
|
+
const AlgoliaProductSearchIdentifierSchema = ProductRecommendationIdentifierSchema.extend({
|
|
4
|
+
abTestID: z.number().optional(),
|
|
5
|
+
abTestVariantID: z.number().optional()
|
|
6
|
+
});
|
|
7
|
+
export {
|
|
8
|
+
AlgoliaProductSearchIdentifierSchema
|
|
9
|
+
};
|
package/src/index.d.ts
CHANGED
package/src/providers/index.d.ts
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { type Cache, ProductRecommendationsProvider, type ProductRecommendation, type ProductRecommendationAlgorithmFrequentlyBoughtTogetherQuery, type ProductRecommendationAlgorithmSimilarProductsQuery, type ProductRecommendationAlgorithmRelatedProductsQuery, type ProductRecommendationAlgorithmTrendingInCategoryQuery, type RequestContext, type ProductRecommendationsQuery } from '@reactionary/core';
|
|
2
|
+
import { type RecommendationsResults, type RecommendClient, type RecommendSearchParams } from 'algoliasearch';
|
|
3
|
+
import type { AlgoliaConfiguration } from '../schema/configuration.schema.js';
|
|
4
|
+
import type { AlgoliaProductRecommendationIdentifier } from '../schema/product-recommendation.schema.js';
|
|
5
|
+
interface AlgoliaRecommendHit {
|
|
6
|
+
objectID: string;
|
|
7
|
+
sku?: string;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* AlgoliaProductRecommendationsProvider
|
|
12
|
+
*
|
|
13
|
+
* Provides product recommendations using Algolia's Recommend API.
|
|
14
|
+
* Supports frequentlyBoughtTogether, similar, related, and trendingInCategory algorithms.
|
|
15
|
+
*
|
|
16
|
+
* Note: This requires Algolia Recommend to be enabled and AI models to be trained.
|
|
17
|
+
* See: https://www.algolia.com/doc/guides/algolia-recommend/overview/
|
|
18
|
+
*/
|
|
19
|
+
export declare class AlgoliaProductRecommendationsProvider extends ProductRecommendationsProvider {
|
|
20
|
+
protected config: AlgoliaConfiguration;
|
|
21
|
+
constructor(config: AlgoliaConfiguration, cache: Cache, context: RequestContext);
|
|
22
|
+
protected getRecommendClient(): RecommendClient;
|
|
23
|
+
protected getRecommendationThreshold(_algorithm: string): number;
|
|
24
|
+
protected getQueryParametersForRecommendations(algorithm: string): RecommendSearchParams;
|
|
25
|
+
/**
|
|
26
|
+
* Get frequently bought together recommendations using Algolia Recommend
|
|
27
|
+
*/
|
|
28
|
+
protected getFrequentlyBoughtTogetherRecommendations(query: ProductRecommendationAlgorithmFrequentlyBoughtTogetherQuery): Promise<ProductRecommendation[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Get similar product recommendations using Algolia Recommend
|
|
31
|
+
*/
|
|
32
|
+
protected getSimilarProductsRecommendations(query: ProductRecommendationAlgorithmSimilarProductsQuery): Promise<ProductRecommendation[]>;
|
|
33
|
+
/**
|
|
34
|
+
* Get related product recommendations using Algolia Recommend
|
|
35
|
+
*/
|
|
36
|
+
protected getRelatedProductsRecommendations(query: ProductRecommendationAlgorithmRelatedProductsQuery): Promise<ProductRecommendation[]>;
|
|
37
|
+
/**
|
|
38
|
+
* Get trending in category recommendations using Algolia Recommend
|
|
39
|
+
*/
|
|
40
|
+
protected getTrendingInCategoryRecommendations(query: ProductRecommendationAlgorithmTrendingInCategoryQuery): Promise<ProductRecommendation[]>;
|
|
41
|
+
protected parseRecommendation(res: RecommendationsResults, query: ProductRecommendationsQuery): {
|
|
42
|
+
[x: string]: unknown;
|
|
43
|
+
recommendationIdentifier: {
|
|
44
|
+
[x: string]: unknown;
|
|
45
|
+
key: string;
|
|
46
|
+
algorithm: string;
|
|
47
|
+
};
|
|
48
|
+
product: {
|
|
49
|
+
[x: string]: unknown;
|
|
50
|
+
key: string;
|
|
51
|
+
};
|
|
52
|
+
}[];
|
|
53
|
+
/**
|
|
54
|
+
* Maps Algolia recommendation results to ProductRecommendation format
|
|
55
|
+
*/
|
|
56
|
+
protected parseSingle(hit: AlgoliaRecommendHit, recommendationIdentifier: AlgoliaProductRecommendationIdentifier): ProductRecommendation;
|
|
57
|
+
}
|
|
58
|
+
export {};
|
|
@@ -11,9 +11,9 @@ interface AlgoliaNativeRecord {
|
|
|
11
11
|
name?: string;
|
|
12
12
|
variants: Array<AlgoliaNativeVariant>;
|
|
13
13
|
}
|
|
14
|
-
export declare class
|
|
14
|
+
export declare class AlgoliaProductSearchProvider extends ProductSearchProvider {
|
|
15
15
|
protected config: AlgoliaConfiguration;
|
|
16
|
-
constructor(
|
|
16
|
+
constructor(cache: Cache, context: RequestContext, config: AlgoliaConfiguration);
|
|
17
17
|
queryByTerm(payload: ProductSearchQueryByTerm): Promise<Result<ProductSearchResult>>;
|
|
18
18
|
createCategoryNavigationFilter(payload: ProductSearchQueryCreateNavigationFilter): Promise<Result<FacetValueIdentifier>>;
|
|
19
19
|
protected parseSingle(body: AlgoliaNativeRecord): {
|
|
@@ -39,6 +39,8 @@ export declare class AlgoliaSearchProvider extends ProductSearchProvider {
|
|
|
39
39
|
pageNumber: number;
|
|
40
40
|
pageSize: number;
|
|
41
41
|
};
|
|
42
|
+
index: string;
|
|
43
|
+
key: string;
|
|
42
44
|
};
|
|
43
45
|
pageNumber: number;
|
|
44
46
|
pageSize: number;
|
|
@@ -2,5 +2,6 @@ import type { z } from 'zod';
|
|
|
2
2
|
export declare const AlgoliaCapabilitiesSchema: z.ZodObject<{
|
|
3
3
|
analytics: z.ZodOptional<z.ZodBoolean>;
|
|
4
4
|
productSearch: z.ZodOptional<z.ZodBoolean>;
|
|
5
|
+
productRecommendations: z.ZodOptional<z.ZodBoolean>;
|
|
5
6
|
}, z.core.$loose>;
|
|
6
7
|
export type AlgoliaCapabilities = z.infer<typeof AlgoliaCapabilitiesSchema>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
export declare const AlgoliaProductSearchIdentifierSchema: z.ZodObject<{
|
|
3
|
+
key: z.ZodString;
|
|
4
|
+
algorithm: z.ZodString;
|
|
5
|
+
abTestID: z.ZodOptional<z.ZodNumber>;
|
|
6
|
+
abTestVariantID: z.ZodOptional<z.ZodNumber>;
|
|
7
|
+
}, z.z.core.$loose>;
|
|
8
|
+
export type AlgoliaProductRecommendationIdentifier = z.infer<typeof AlgoliaProductSearchIdentifierSchema>;
|