@klevu/core
Version:
Typescript SDK that simplifies development on Klevu backend. Klevu provides advanced AI-powered search and discovery solutions for online retailers.
319 lines (318 loc) • 14.7 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.kmcRecommendation = exports.KMCRecommendationLogic = void 0;
const config_js_1 = require("../../config.js");
const lastClickedProducts_js_1 = require("../../store/lastClickedProducts.js");
const personalisation_js_1 = require("../../modifiers/personalisation/personalisation.js");
const KlevuTypeOfRecord_js_1 = require("../../models/KlevuTypeOfRecord.js");
const fetch_js_1 = require("../../connection/fetch.js");
const KlevuTypeOfRequest_js_1 = require("../../models/KlevuTypeOfRequest.js");
const usersession_js_1 = require("../../resolvers/usersession.js");
var KMCRecommendationPagetype;
(function (KMCRecommendationPagetype) {
KMCRecommendationPagetype["Home"] = "HOME";
KMCRecommendationPagetype["Category"] = "CATEGORY";
KMCRecommendationPagetype["Product"] = "PRODUCT";
KMCRecommendationPagetype["Checkout"] = "CHECKOUT";
})(KMCRecommendationPagetype || (KMCRecommendationPagetype = {}));
var KMCRecommendationLogic;
(function (KMCRecommendationLogic) {
KMCRecommendationLogic["Trending"] = "TRENDING";
KMCRecommendationLogic["TrendingPersonalized"] = "TRENDING_PERSONALIZED";
KMCRecommendationLogic["NewestArrivals"] = "NEWEST_ARRIVALS";
KMCRecommendationLogic["RecentlyViewed"] = "RECENTLY_VIEWED";
KMCRecommendationLogic["HandPicked"] = "HAND_PICKED";
KMCRecommendationLogic["OtherAlsoViewed"] = "OTHER_ALSO_VIEWED";
KMCRecommendationLogic["Similar"] = "SIMILAR";
KMCRecommendationLogic["BoughtTogether"] = "BOUGHT_TOGETHER";
KMCRecommendationLogic["BoughtTogetherPDP"] = "BOUGHT_TOGETHER_PDP";
KMCRecommendationLogic["VisuallySimilar"] = "VISUALLY_SIMILAR";
KMCRecommendationLogic["Custom"] = "CUSTOM_LOGIC";
})(KMCRecommendationLogic || (exports.KMCRecommendationLogic = KMCRecommendationLogic = {}));
/**
* Fetches products based on KMC recommendation. Provide id created in KMC
*
* @category RecommendationQuery
* @param recommendationId Id of recommendation in the backend
* @returns
*/
function kmcRecommendation(recommendationId, options, ...modifiers) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
let kmcConfig;
try {
let advFilterParams = "";
if ((options === null || options === void 0 ? void 0 : options.categoryPath) ||
(options === null || options === void 0 ? void 0 : options.currentProductId) ||
(options === null || options === void 0 ? void 0 : options.itemGroupId)) {
advFilterParams = "?";
advFilterParams += options.categoryPath
? `&cp=${options.categoryPath}`
: "";
advFilterParams += options.currentProductId
? `&pid=${options.currentProductId}`
: "";
advFilterParams += options.itemGroupId
? `&gpid=${options.itemGroupId}`
: "";
}
const userSegments = usersession_js_1.KlevuUserSession.getDefault().getSegments();
advFilterParams +=
userSegments.length > 0
? `${advFilterParams.length > 0 ? "&" : "?"}sids=${userSegments.join(",")}`
: "";
const conf = config_js_1.KlevuConfig.getDefault();
kmcConfig = yield (0, fetch_js_1.get)(`${conf.recommendationsApiUrl}${conf.apiKey}/settings/${recommendationId}${advFilterParams}`);
}
catch (e) {
console.warn("Failed to fetch given KMC recommendation");
return {
klevuFunctionId: "kmcRecommendation",
};
}
if (!kmcConfig) {
throw new Error("Couldn't fetch KMC config");
}
const configOverride = new config_js_1.KlevuConfig({
apiKey: config_js_1.KlevuConfig.getDefault().apiKey,
url: `https://${kmcConfig.search.basePath}`,
});
if (kmcConfig.metadata.action === "HIDE_RECOMMENDATION" ||
kmcConfig.metadata.action === "STATIC_CONTENT") {
return {
klevuFunctionId: "kmcRecommendation",
queries: [
{
id: (_a = options === null || options === void 0 ? void 0 : options.id) !== null && _a !== void 0 ? _a : "kmcRecommendation",
typeOfRequest: KlevuTypeOfRequest_js_1.KlevuTypeOfRequest.Skip,
},
],
params: {
kmcConfig,
},
modifiers: kmcConfig.metadata.action === "STATIC_CONTENT" ? modifiers : undefined,
};
}
const payload = JSON.parse(kmcConfig.search.payload);
const queries = payload.recordQueries.map((query) => {
var _a;
return (Object.assign(Object.assign({}, query), { id: (_a = options === null || options === void 0 ? void 0 : options.id) !== null && _a !== void 0 ? _a : "kmcrecommendation" }));
});
if (kmcConfig.metadata.pageType === KMCRecommendationPagetype.Home &&
kmcConfig.metadata.logic === KMCRecommendationLogic.RecentlyViewed) {
const last10 = lastClickedProducts_js_1.KlevuLastClickedProducts.getLastClickedLatestsFirst(10);
for (const q of queries) {
if (!q.settings) {
q.settings = {};
}
q.settings.customANDQuery = `id:(${last10.join(" OR ")})`;
q.settings.topIds = last10.map((id) => ({ key: "id", value: id }));
}
}
if (kmcConfig.metadata.pageType === KMCRecommendationPagetype.Category &&
[
KMCRecommendationLogic.Trending,
KMCRecommendationLogic.TrendingPersonalized,
KMCRecommendationLogic.NewestArrivals,
KMCRecommendationLogic.Custom,
].includes(kmcConfig.metadata.logic)) {
if (!options || !options.categoryPath) {
throw new Error("'categoryPath' is required for Category recommendation");
}
for (const q of queries) {
if (!q.settings) {
q.settings = {};
}
if (!q.settings.query) {
q.settings.query = {};
}
q.settings.query.categoryPath = options === null || options === void 0 ? void 0 : options.categoryPath;
}
}
if (kmcConfig.metadata.logic === KMCRecommendationLogic.TrendingPersonalized) {
modifiers.push((0, personalisation_js_1.personalisation)());
}
if (kmcConfig.metadata.pageType === KMCRecommendationPagetype.Product &&
[
KMCRecommendationLogic.OtherAlsoViewed,
KMCRecommendationLogic.Similar,
].includes(kmcConfig.metadata.logic)) {
if (!options || !options.currentProductId) {
throw new Error("'currentProductId' is required for Product recommendation");
}
for (const q of queries) {
if (!q.settings) {
q.settings = {};
}
if (!q.settings.context) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
q.settings.context = {};
}
if (options.itemGroupId) {
q.settings.excludeIds = [
{
key: "itemGroupId",
value: options.itemGroupId,
},
];
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
q.settings.context.recentObjects = [
{
typeOfRecord: KlevuTypeOfRecord_js_1.KlevuTypeOfRecord.Product,
records: [
{
id: options.currentProductId,
},
],
},
];
}
}
if (kmcConfig.metadata.pageType === KMCRecommendationPagetype.Product &&
[
KMCRecommendationLogic.BoughtTogetherPDP,
KMCRecommendationLogic.Custom,
].includes(kmcConfig.metadata.logic)) {
if (!options || !options.currentProductId) {
throw new Error("'currentProductId' is required for Product recommendation");
}
for (const q of queries) {
if (!q.settings) {
q.settings = {};
}
if (!q.settings.context) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
q.settings.context = {};
}
if (options.itemGroupId) {
q.settings.excludeIds = [
{
key: "itemGroupId",
value: options.itemGroupId,
},
];
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
q.settings.context.recentObjects = [
{
typeOfRecord: KlevuTypeOfRecord_js_1.KlevuTypeOfRecord.Product,
records: [
{
id: options.currentProductId,
},
],
},
];
}
}
// only VisuallySimilar uses sourceObjects
if (kmcConfig.metadata.pageType === KMCRecommendationPagetype.Product &&
kmcConfig.metadata.logic === KMCRecommendationLogic.VisuallySimilar) {
if (!options || !options.currentProductId) {
throw new Error("'currentProductId' is required for Product recommendation");
}
for (const q of queries) {
if (!q.settings) {
q.settings = {};
}
if (!q.settings.context) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
q.settings.context = {};
}
if (options.itemGroupId) {
q.settings.excludeIds = [
{
key: "itemGroupId",
value: options.itemGroupId,
},
];
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
q.settings.context.sourceObjects = [
{
typeOfRecord: KlevuTypeOfRecord_js_1.KlevuTypeOfRecord.Product,
records: [
{
id: options.currentProductId,
},
],
},
];
if (options.itemGroupId) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
q.settings.context.sourceObjects[0].records.push({
itemGroupId: options.itemGroupId,
});
}
}
}
if (kmcConfig.metadata.pageType === KMCRecommendationPagetype.Checkout &&
[
KMCRecommendationLogic.BoughtTogether,
KMCRecommendationLogic.Custom,
].includes(kmcConfig.metadata.logic)) {
if (!options || !options.cartProductIds) {
throw new Error("'cartProductIds' is required for Checkout recommendation");
}
for (const q of queries) {
if (!q.settings) {
q.settings = {};
}
if (!q.settings.context) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
q.settings.context = {};
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
q.settings.context.recentObjects = [
{
typeOfRecord: KlevuTypeOfRecord_js_1.KlevuTypeOfRecord.Product,
records: options.cartProductIds.map((id) => ({ id })),
},
];
}
}
if (kmcConfig.metadata.productThreshold) {
modifiers.push({
klevuModifierId: "kmcThreshold",
onResult: (response) => {
var _a, _b;
const copy = Object.assign({}, response);
for (const qr of (_b = (_a = copy.apiResponse) === null || _a === void 0 ? void 0 : _a.queryResults) !== null && _b !== void 0 ? _b : []) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (qr.records.length < kmcConfig.metadata.productThreshold) {
qr.records = [];
}
}
return response;
},
});
}
for (const q of queries) {
if (!q.settings) {
q.settings = {};
}
q.settings = Object.assign(Object.assign({}, q.settings), options);
}
return {
klevuFunctionId: "kmcRecommendation",
// eslint-disable-next-line @typescript-eslint/no-explicit-any
queries,
params: {
kmcConfig,
},
modifiers,
configOverride,
};
});
}
exports.kmcRecommendation = kmcRecommendation;