UNPKG

@klevu/core

Version:

Typescript SDK that simplifies development on Klevu backend. Klevu provides advanced AI-powered search and discovery solutions for online retailers.

318 lines (317 loc) 14.3 kB
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()); }); }; import { KlevuConfig } from "../../config.js"; import { KlevuLastClickedProducts } from "../../store/lastClickedProducts.js"; import { personalisation } from "../../modifiers/personalisation/personalisation.js"; import { KlevuTypeOfRecord } from "../../models/KlevuTypeOfRecord.js"; import { get } from "../../connection/fetch.js"; import { KlevuTypeOfRequest } from "../../models/KlevuTypeOfRequest.js"; import { KlevuUserSession } from "../../resolvers/usersession.js"; var KMCRecommendationPagetype; (function (KMCRecommendationPagetype) { KMCRecommendationPagetype["Home"] = "HOME"; KMCRecommendationPagetype["Category"] = "CATEGORY"; KMCRecommendationPagetype["Product"] = "PRODUCT"; KMCRecommendationPagetype["Checkout"] = "CHECKOUT"; })(KMCRecommendationPagetype || (KMCRecommendationPagetype = {})); export 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 || (KMCRecommendationLogic = {})); /** * Fetches products based on KMC recommendation. Provide id created in KMC * * @category RecommendationQuery * @param recommendationId Id of recommendation in the backend * @returns */ export 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 conf = KlevuConfig.getDefault(); // Only fetch user segments if user session is enabled const userSegments = conf.disableUserSession ? [] : KlevuUserSession.getDefault().getSegments(); advFilterParams += userSegments.length > 0 ? `${advFilterParams.length > 0 ? "&" : "?"}sids=${userSegments.join(",")}` : ""; kmcConfig = yield 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 KlevuConfig({ apiKey: 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.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 = 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(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.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.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.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.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, }; }); }