UNPKG

@indexea/scaffold-svelte

Version:

This is the scaffolding of Indexea search, on which you can adjust the typography and style of the search interface

164 lines (151 loc) 4.72 kB
/*** * openapi of indexea */ import { v4 as uuidv4 } from 'uuid'; import { Configuration, WidgetsApi, SearchApi, SearchWidgetHotWordsScopeEnum, WidgetBean, SearchWord, AutoCompleteItem } from '@indexea/sdk' /** * A simple wrapper for the Indexea API */ export class Indexea { _config: Configuration; _widget: string; accessToken: string; searchApi: SearchApi; widgetApi: WidgetsApi; /** * initialize an indexea api wrapper * @param endpoint remote endpoint url, ex: `https://api.indexea.com/v1` * @param widget widget identifier */ constructor(endpoint: string, accessToken: string, widget: string) { this._widget = widget; this.accessToken = accessToken; this._config = new Configuration({ basePath: endpoint, headers: { accept: 'application/json' }, accessToken: () => { return accessToken }, credentials: 'include', middleware: [], queryParamsStringify }); this.searchApi = new SearchApi(this._config) this.widgetApi = new WidgetsApi(this._config) } /** * get widget detail * @returns */ async widget(): Promise<WidgetBean> { return this.widgetApi.widgetDetail({ ident: this._widget }).catch(rejectError) } /** * execute search on widget * @param query query id * @param q search keyword * @param params search parameters, generally, it is an aggregation parameter filter condition * @param from * @param size * @returns */ async search(query: number, q: string, params: any, from: number, size: number): Promise<object> { let args = { widget: this._widget, query, q, params, from, size, userid: getUserId(), xToken: this.accessToken }; return this.searchApi.searchWidgetSearch(args).catch(rejectError); } /** * get hotwords of query * @param query query id * @param scope * @param count * @returns */ async hotwords(query: number, scope: SearchWidgetHotWordsScopeEnum, count: number): Promise<Array<SearchWord>> { return this.searchApi .searchWidgetHotWords({ widget: this._widget, query, scope, count, xToken: this.accessToken }) .catch(rejectError) } /** * get auto complete items for search box * @param query query id * @param q search keyword * @param size * @returns */ async autocomplete(query: number, q: string, size: number): Promise<Array<AutoCompleteItem>> { return this.searchApi.searchWidgetAutoComplete({ widget: this._widget, query, q, userid: getUserId(), size, xToken: this.accessToken }) .catch(rejectError) } /** * call this method when use click on a search result item. * @param actionId * @param docId * @returns */ async click(actionId: string, docId: string): Promise<boolean> { return this.searchApi.searchClick({ widget: this._widget, actionId, docId, userid: getUserId(), xToken: this.accessToken }) } } /** * The unique identifier of the visitor, which will be transmitted to the search service through the header * @returns */ function getUserId() { var userid: string = window.localStorage.getItem('idx_userid') || ''; if (!userid) { userid = uuidv4(); //Date.now().toString(36) + Math.random().toString(36); window.localStorage.setItem('idx_userid', userid); } return userid; } /** * Object to url request parameters * @param obj * @returns */ function queryParamsStringify(obj: Record<string, any>): string { return Object.entries(obj).filter(([key, value]) => key && value != undefined) .map(([key, value]) => { if (typeof value !== 'object') { return joinKV(key, value) } if (Array.isArray(value)) { // Array type, using multiple keys, such as a=1&a=2&a=3 becomes a=[1,2,3] during backend processing return value.filter(v => v).map(v => joinKV(key, v)).join('&') } return queryParamsStringify(value) }) .join('&') } /** * Concatenate url request parameters * @param key * @param value * @returns */ function joinKV(key: string, value: any) { return encodeURIComponent(key) + '=' + encodeURIComponent(value); } /** * global error handler * @param {*} fn_reject * @param {*} err */ function rejectError(err: any) { try { return err.response .json() .then((json: any) => Promise.reject(json)) .catch((e: { error: any; message: any; }) => Promise.reject({ error: e.error || err.status || 999, message: e.message || err.statusText || 'Unknown error' }) ) } catch (e) { return Promise.reject({ error: err.error || err.status || 999, message: err.message || err.statusText || 'Unknown error' }) } }