@indexea/widgets
Version:
This is the web components of Indexea, which contains multiple components such as SearchBox, SearchDialog, RecommListBox, etc
255 lines (231 loc) • 6.74 kB
text/typescript
/***
* openapi of indexea
*/
import { v4 as uuidv4 } from 'uuid';
import {
Configuration,
WidgetsApi,
SearchApi,
RecommendApi,
SearchWidgetHotWordsScopeEnum,
SearchHistoriesStrategyEnum
} from '@indexea/sdk'
export class Indexea {
private widgetIdent: string;
private searchApi: SearchApi;
private widgetApi: WidgetsApi;
private p_token: string;
private p_userid: string;
constructor(ident: string, props: any = {}) {
var config = cfg(props);
this.searchApi = new SearchApi(config);
this.widgetApi = new WidgetsApi(config);
this.widgetIdent = ident;
this.p_token = props['accessToken'];
this.p_userid = props['userid'];
}
get() {
return this.widgetApi.widgetDetail({ ident: this.widgetIdent, xToken: this.p_token }).catch(rejectError)
}
/**
* search on widget
* @param {*} query
* @param {*} q
* @param {*} original
* @param {*} params
* @param {*} from
* @param {*} size
* @returns
*/
wsearch(query: number, q: string, original: string, params: any, from: number, size: number) {
return this.searchApi
.searchWidgetSearch({ widget: this.widgetIdent, query, q, params, from, size, userid: this.p_userid || userid(), xToken: this.p_token, original })
.catch(rejectError)
}
/**
* get hotwords by query
* @param {*} query
* @param {*} scope
* @param {*} count
* @returns
*/
hotwords(query: number, scope: SearchWidgetHotWordsScopeEnum, count: number) {
return this.searchApi
.searchWidgetHotWords({ widget: this.widgetIdent, query, scope, count, userid: this.p_userid || userid(), xToken: this.p_token })
.catch(rejectError)
}
/**
* get search histories of user
* @param query
* @param count
* @returns
*/
histories(query: number, count: number) {
return this.searchApi
.searchHistories({ widget: this.widgetIdent, strategy: SearchHistoriesStrategyEnum.Recent, query, size: count, userid: this.p_userid || userid(), xToken: this.p_token })
.catch(rejectError);
}
autocomplete(query: number, q: string, size: number) {
return this.searchApi.searchWidgetAutoComplete({ widget: this.widgetIdent, query, q, userid: this.p_userid || userid(), size, xToken: this.p_token })
.catch(rejectError)
}
/**
* click on search result
* @param actionId
* @param docId
* @returns
*/
click(actionId: string, docId: string) {
return this.searchApi.searchClick({ widget: this.widgetIdent, actionId, docId, userid: this.p_userid || userid(), xToken: this.p_token })
}
static getField(obj: any, key: string) {
return getFieldValue(obj, key);
}
static getFields(obj: any, keys: Array<string>) {
var newobj = {};
keys.filter(k => k).forEach((k) => (newobj[k] = getFieldValue(obj, k)));
return newobj;
}
static evalTempl(templ: string): string {
try {
return eval(templ);
} catch (e) {
console.log(e);
return e.message;
}
}
}
export class IndexeaRecomm {
private recommIdent: string;
private recommApi: RecommendApi
private p_token: string;
private p_userid: string;
constructor(ident: string, props: any = {}) {
var config = cfg(props);
this.recommApi = new RecommendApi(config);
this.recommIdent = ident;
this.p_token = props['accessToken'];
this.p_userid = props['userid'];
}
get() {
return this.recommApi.recommendDetail({ ident: this.recommIdent, xToken: this.p_token }).catch(rejectError);
}
/**
* fetch recomm results
* @param {*} query
* @param {*} q
* @param {*} params
* @param {*} from
* @param {*} size
* @returns
*/
fetch(condition: { [key: string]: string; }, from: number, count: number) {
return this.recommApi.recommendFetch({ ident: this.recommIdent, condition, from, count, userid: this.p_userid || userid(), xToken: this.p_token })
.catch(rejectError)
}
/**
* click on recommend result
* @param actionId
* @param docId
* @returns
*/
click(actionId: string, docId: string) {
return this.recommApi.recommendClick({ ident: this.recommIdent, userid: this.p_userid || userid(), actionId, docId, xToken: this.p_token })
.catch(rejectError);
}
}
function cfg(props: any = {}) {
return new Configuration({
basePath: props.basePath,
headers: { accept: 'application/json' },
accessToken: () => props.accessToken || '',
credentials: 'include',
middleware: [],
queryParamsStringify
});
}
/**
* get value of object, support nest field such as user.name
* @param fields
* @param key
* @returns
*/
function getFieldValue(fields: any, key: string) {
if (!key) return null;
var v = fields[key];
if (!v) {
//nest properties like user.region.city
var keys = key.split(".");
for (var i = 0; i < keys.length; i++) {
v = v ? v[keys[i]] : fields[keys[i]];
if (typeof v != "object") {
break;
}
}
}
return v || "";
}
/**
* The unique identifier of the visitor, which will be transmitted to the search service through the header
* @returns
*/
function userid() {
const KEY = "idx_userid";
var uid: string = window.localStorage.getItem(KEY) || '';
if (!uid) {
uid = uuidv4(); //Date.now().toString(36) + Math.random().toString(36);
window.localStorage.setItem(KEY, uid);
}
return uid;
}
/**
* 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 => Promise.reject(json))
.catch(e =>
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'
})
}
}