addsearch-js-client
Version:
AddSearch API JavaScript client
326 lines • 20.9 kB
JavaScript
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
;