UNPKG

addsearch-js-client

Version:

AddSearch API JavaScript client

326 lines 20.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); require("es6-promise/auto"); const api_1 = require("./api"); const util_1 = require("./util"); /* eslint-enable @typescript-eslint/no-explicit-any */ /** * Fetch search results of search suggestions from the Addsearch API */ const executeApiFetch = function (apiHostname, sitekey, type, settings, cb, fuzzyRetry, customFilterObject, recommendOptions) { var _a, _b, _c, _d, _e, _f, _g, _h; /* eslint-disable @typescript-eslint/no-explicit-any */ const settingToQueryParam = function (setting, key) { if (setting || setting === false) { return '&' + key + '=' + setting; } return ''; }; /* eslint-enable @typescript-eslint/no-explicit-any */ // Validate query type if (type !== 'search' && type !== 'ai-answers' && type !== 'suggest' && type !== 'autocomplete' && type !== 'recommend') { cb({ error: { response: api_1.RESPONSE_BAD_REQUEST, message: 'invalid query type' } }); return; } let keyword = ''; let queryParamsString = ''; let requestPayloadObject = {}; // API Path (eq. /search, /suggest, /autocomplete/document-field) let apiEndpoint = null; let apiPath = null; // Search if (type === 'search') { // Path apiPath = type; // Keyword keyword = settings === null || settings === void 0 ? void 0 : settings.keyword; // Boolean operators (AND, OR, NOT) uppercase keyword = (settings === null || settings === void 0 ? void 0 : settings.enableLogicalOperators) ? keyword.replace(/ and /g, ' AND ').replace(/ or /g, ' OR ').replace(/ not /g, ' NOT ') : keyword.replace(/ AND /g, ' and ').replace(/ OR /g, ' or ').replace(/ NOT /g, ' not '); // Escape keyword = encodeURIComponent(keyword); // Fuzzy let fuzzy = settings === null || settings === void 0 ? void 0 : settings.fuzzy; if (fuzzy === 'retry') { // First call, non fuzzy if (fuzzyRetry !== true) { fuzzy = false; } // Second call, fuzzy else { fuzzy = true; } } // GET Parameters queryParamsString = settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.lang, 'lang') + settingToQueryParam(fuzzy, 'fuzzy') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.collectAnalytics, 'collectAnalytics') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.postfixWildcard, 'postfixWildcard') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.categories, 'categories') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.priceFromCents, 'priceFromCents') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.priceToCents, 'priceToCents') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.dateFrom, 'dateFrom') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.dateTo, 'dateTo') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.paging.page, 'page') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.paging.pageSize, 'limit') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.shuffleAndLimitTo, 'shuffleAndLimitTo') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.jwt, 'jwt') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.resultType, 'resultType') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.userToken, 'userToken') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.numFacets, 'numFacets') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.cacheResponseTime, 'cacheResponseWithTtlSeconds') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.searchOperator, 'defaultOperator') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.analyticsTag, 'analyticsTag'); // POST Parameters requestPayloadObject = Object.assign(Object.assign({}, requestPayloadObject), { language: settings === null || settings === void 0 ? void 0 : settings.lang, fuzzy: fuzzy !== true && fuzzy !== false ? fuzzy : JSON.stringify(fuzzy), collectAnalytics: settings === null || settings === void 0 ? void 0 : settings.collectAnalytics, postfixWildcard: settings === null || settings === void 0 ? void 0 : settings.postfixWildcard, categories: (settings === null || settings === void 0 ? void 0 : settings.categories) ? settings === null || settings === void 0 ? void 0 : settings.categories.split(',') : undefined, priceFromCents: (settings === null || settings === void 0 ? void 0 : settings.priceFromCents) ? parseInt(settings === null || settings === void 0 ? void 0 : settings.priceFromCents, 10) : undefined, priceToCents: (settings === null || settings === void 0 ? void 0 : settings.priceToCents) ? parseInt(settings === null || settings === void 0 ? void 0 : settings.priceToCents, 10) : undefined, dateFrom: settings === null || settings === void 0 ? void 0 : settings.dateFrom, dateTo: settings === null || settings === void 0 ? void 0 : settings.dateTo, paging: { page: (_a = settings === null || settings === void 0 ? void 0 : settings.paging.page) !== null && _a !== void 0 ? _a : 1, pageSize: (_b = settings === null || settings === void 0 ? void 0 : settings.paging.pageSize) !== null && _b !== void 0 ? _b : 10, shuffleAndLimitTo: (_c = settings === null || settings === void 0 ? void 0 : settings.shuffleAndLimitTo) !== null && _c !== void 0 ? _c : undefined, sortByField: settings === null || settings === void 0 ? void 0 : settings.paging.sortBy, sortOrder: settings === null || settings === void 0 ? void 0 : settings.paging.sortOrder }, jwt: settings === null || settings === void 0 ? void 0 : settings.jwt, resultType: settings === null || settings === void 0 ? void 0 : settings.resultType, userToken: (_d = settings === null || settings === void 0 ? void 0 : settings.userToken) !== null && _d !== void 0 ? _d : undefined, numFacets: settings === null || settings === void 0 ? void 0 : settings.numFacets, cacheResponseWithTtlSeconds: (_e = settings === null || settings === void 0 ? void 0 : settings.cacheResponseTime) !== null && _e !== void 0 ? _e : undefined, defaultOperator: (_f = settings === null || settings === void 0 ? void 0 : settings.searchOperator) !== null && _f !== void 0 ? _f : undefined, analyticsTag: settings === null || settings === void 0 ? void 0 : settings.analyticsTag }); // Add sortBy and sortOrder if (Array.isArray(settings === null || settings === void 0 ? void 0 : settings.paging.sortBy) && (settings === null || settings === void 0 ? void 0 : settings.paging.sortBy.length) > 1) { settings === null || settings === void 0 ? void 0 : settings.paging.sortBy.forEach(function (value, index) { queryParamsString = queryParamsString + settingToQueryParam(value, 'sort') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.paging.sortOrder[index], 'order'); }); } else { queryParamsString = queryParamsString + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.paging.sortBy, 'sort') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.paging.sortOrder, 'order'); } // Add custom field filters if (settings === null || settings === void 0 ? void 0 : settings.customFieldFilters) { const customFieldFiltersValues = {}; for (let i = 0; i < (settings === null || settings === void 0 ? void 0 : settings.customFieldFilters.length); i++) { queryParamsString = queryParamsString + '&customField=' + (settings === null || settings === void 0 ? void 0 : settings.customFieldFilters[i]); const decodedCustomFieldFilter = decodeURIComponent(settings === null || settings === void 0 ? void 0 : settings.customFieldFilters[i]); const customFieldFilterPair = decodedCustomFieldFilter.split('='); const customFieldName = customFieldFilterPair[0]; const customFieldValue = customFieldFilterPair[1]; customFieldFiltersValues[customFieldName] = customFieldValue; } requestPayloadObject = Object.assign(Object.assign({}, requestPayloadObject), { customField: (0, util_1.isEmptyObject)(customFieldFiltersValues) ? undefined : customFieldFiltersValues }); } // Add facet fields if (settings === null || settings === void 0 ? void 0 : settings.facetFields) { const facetFieldsValues = []; for (let i = 0; i < (settings === null || settings === void 0 ? void 0 : settings.facetFields.length); i++) { queryParamsString = queryParamsString + '&facet=' + (settings === null || settings === void 0 ? void 0 : settings.facetFields[i]); facetFieldsValues.push(settings === null || settings === void 0 ? void 0 : settings.facetFields[i]); } requestPayloadObject = Object.assign(Object.assign({}, requestPayloadObject), { facet: facetFieldsValues.length > 0 ? facetFieldsValues : undefined }); } // Range facets if (settings === null || settings === void 0 ? void 0 : settings.rangeFacets) { queryParamsString = queryParamsString + '&rangeFacets=' + encodeURIComponent(JSON.stringify(settings === null || settings === void 0 ? void 0 : settings.rangeFacets)); requestPayloadObject = Object.assign(Object.assign({}, requestPayloadObject), { rangeFacets: settings === null || settings === void 0 ? void 0 : settings.rangeFacets }); } // Hierarchical facets if (settings === null || settings === void 0 ? void 0 : settings.hierarchicalFacetSetting) { queryParamsString = queryParamsString + '&hierarchicalFacets=' + encodeURIComponent(JSON.stringify(settings === null || settings === void 0 ? void 0 : settings.hierarchicalFacetSetting)); requestPayloadObject = Object.assign(Object.assign({}, requestPayloadObject), { hierarchicalFacets: settings === null || settings === void 0 ? void 0 : settings.hierarchicalFacetSetting }); } // Stats fields if (settings === null || settings === void 0 ? void 0 : settings.statsFields) { const statsFieldsValues = []; for (let i = 0; i < (settings === null || settings === void 0 ? void 0 : settings.statsFields.length); i++) { queryParamsString = queryParamsString + '&fieldStat=' + (settings === null || settings === void 0 ? void 0 : settings.statsFields[i]); statsFieldsValues.push(settings === null || settings === void 0 ? void 0 : settings.statsFields[i]); } requestPayloadObject = Object.assign(Object.assign({}, requestPayloadObject), { statsFields: statsFieldsValues }); } // Personalization events if ((settings === null || settings === void 0 ? void 0 : settings.personalizationEvents) && Array.isArray(settings === null || settings === void 0 ? void 0 : settings.personalizationEvents)) { const personalizationEventsValues = []; for (let i = 0; i < (settings === null || settings === void 0 ? void 0 : settings.personalizationEvents.length); i++) { const obj = settings === null || settings === void 0 ? void 0 : settings.personalizationEvents[i]; const key = Object.keys(obj)[0]; queryParamsString = queryParamsString + '&personalizationEvent=' + encodeURIComponent(key + '=' + obj[key]); personalizationEventsValues.push(obj); } requestPayloadObject = Object.assign(Object.assign({}, requestPayloadObject), { personalizationEvents: personalizationEventsValues }); } // Filter object if (customFilterObject) { queryParamsString = queryParamsString + '&filter=' + encodeURIComponent(JSON.stringify(customFilterObject)); requestPayloadObject = Object.assign(Object.assign({}, requestPayloadObject), { filter: customFilterObject }); } else if (settings === null || settings === void 0 ? void 0 : settings.filterObject) { queryParamsString = queryParamsString + '&filter=' + encodeURIComponent(JSON.stringify(settings === null || settings === void 0 ? void 0 : settings.filterObject)); requestPayloadObject = Object.assign(Object.assign({}, requestPayloadObject), { filter: (0, util_1.isEmptyObject)(settings === null || settings === void 0 ? void 0 : settings.filterObject) ? undefined : settings === null || settings === void 0 ? void 0 : settings.filterObject }); } apiEndpoint = 'https://' + apiHostname + '/v1/' + apiPath + '/' + sitekey + '?term=' + keyword + queryParamsString; } // Ai Answers else if (type === 'ai-answers') { // TODO use apiHostname instead of hardcoded URL api_1.apiInstance .post(`https://${apiHostname}/v2/indices/${sitekey}/conversations`, { question: settings === null || settings === void 0 ? void 0 : settings.keyword }) .then(function (response) { if (response.data.response) { cb(response.data.response); } else { cb({ error: { response: api_1.RESPONSE_SERVER_ERROR, message: 'Could not get ai-answers response in the expected data format' } }); } }) .catch(function (error) { console.error(error); cb({ error: { response: api_1.RESPONSE_SERVER_ERROR, message: 'invalid server response' } }); }); } // Suggest else if (type === 'suggest') { apiPath = type; queryParamsString = settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.suggestionsSize, 'size') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.lang, 'language'); requestPayloadObject = Object.assign(Object.assign({}, requestPayloadObject), { size: settings === null || settings === void 0 ? void 0 : settings.suggestionsSize, language: settings === null || settings === void 0 ? void 0 : settings.lang }); keyword = settings === null || settings === void 0 ? void 0 : settings.suggestionsPrefix; apiEndpoint = 'https://' + apiHostname + '/v1/' + apiPath + '/' + sitekey + '?term=' + keyword + queryParamsString; } // Autocomplete else if (type === 'autocomplete') { apiPath = 'autocomplete/document-field'; queryParamsString = settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.autocomplete.field, 'source') + settingToQueryParam(settings === null || settings === void 0 ? void 0 : settings.autocomplete.size, 'size'); keyword = (settings === null || settings === void 0 ? void 0 : settings.autocomplete.prefix) || ''; apiEndpoint = 'https://' + apiHostname + '/v1/' + apiPath + '/' + sitekey + '?term=' + keyword + queryParamsString; requestPayloadObject = Object.assign(Object.assign({}, requestPayloadObject), { source: settings === null || settings === void 0 ? void 0 : settings.autocomplete.field, size: settings === null || settings === void 0 ? void 0 : settings.autocomplete.size }); } else if (type === 'recommend') { if ((recommendOptions === null || recommendOptions === void 0 ? void 0 : recommendOptions.type) === 'RELATED_ITEMS') { queryParamsString = settingToQueryParam(recommendOptions.itemId, 'itemId'); apiPath = 'recommendations/index/' + sitekey + '/block/' + recommendOptions.blockId + '?' + queryParamsString; requestPayloadObject = Object.assign(Object.assign({}, requestPayloadObject), { itemId: (_g = recommendOptions.itemId) !== null && _g !== void 0 ? _g : undefined, blockId: recommendOptions.blockId }); } else if ((recommendOptions === null || recommendOptions === void 0 ? void 0 : recommendOptions.type) === 'FREQUENTLY_BOUGHT_TOGETHER') { queryParamsString = settingToQueryParam(recommendOptions.itemId, 'itemId'); apiPath = 'recommendations/' + sitekey + '?configurationKey=' + recommendOptions.configurationKey + queryParamsString; requestPayloadObject = Object.assign(Object.assign({}, requestPayloadObject), { itemId: (_h = recommendOptions.itemId) !== null && _h !== void 0 ? _h : undefined, configurationKey: recommendOptions.configurationKey }); } apiEndpoint = 'https://' + apiHostname + '/v1/' + apiPath; } // Handle API response for all types except ai-answers if (type !== 'ai-answers') { const handleApiResponse = function (response) { var _a, _b, _c; const json = response.data; // Search again with fuzzy=true if no hits if (type === 'search' && (settings === null || settings === void 0 ? void 0 : settings.fuzzy) === 'retry' && json.total_hits === 0 && fuzzyRetry !== true) { executeApiFetch(apiHostname, sitekey, type, settings, cb, true); } else { // Cap fuzzy results to one page as quality decreases quickly if (fuzzyRetry === true) { json.total_hits = Math.min((_a = json.total_hits) !== null && _a !== void 0 ? _a : Infinity, (_c = (_b = settings === null || settings === void 0 ? void 0 : settings.paging) === null || _b === void 0 ? void 0 : _b.pageSize) !== null && _c !== void 0 ? _c : Infinity); } // Callback cb(json); } }; const handleApiError = function (error) { console.error(error); cb({ error: { response: api_1.RESPONSE_SERVER_ERROR, message: 'invalid server response' } }); }; if ((settings === null || settings === void 0 ? void 0 : settings.apiMethod) === 'POST' && ['search', 'suggest', 'autocomplete'].includes(type)) { apiEndpoint = 'https://' + apiHostname + '/v1/' + apiPath + '/' + sitekey; const term = type === 'search' ? decodeURIComponent(keyword) : keyword; requestPayloadObject = Object.assign({ term }, requestPayloadObject); api_1.apiInstance .post(apiEndpoint, requestPayloadObject) .then(handleApiResponse) .catch(handleApiError); } else { api_1.apiInstance .get(apiEndpoint) .then(handleApiResponse) .catch(handleApiError); } } }; exports.default = executeApiFetch; //# sourceMappingURL=apifetch.js.map