UNPKG

coveo-search-ui

Version:

Coveo JavaScript Search Framework

250 lines (211 loc) • 8.04 kB
import { IQueryResults } from '../rest/QueryResults'; import { IQueryResult } from '../rest/QueryResult'; import { IQuery } from '../rest/Query'; import { Assert } from '../misc/Assert'; import { Utils } from '../utils/Utils'; import * as _ from 'underscore'; declare let crypto: Crypto; export class QueryUtils { static createGuid(): string { let guid: string; let success: boolean = false; if (typeof crypto != 'undefined' && typeof crypto.getRandomValues != 'undefined') { try { guid = QueryUtils.generateWithCrypto(); success = true; } catch (e) { success = false; } } if (!success) { guid = QueryUtils.generateWithRandom(); } return guid; } // This method is a fallback as it's generate a lot of collisions in Chrome. static generateWithRandom(): string { // http://stackoverflow.com/a/2117523 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { let r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8; return v.toString(16); }); } static generateWithCrypto(): string { let buf = new Uint16Array(8); crypto.getRandomValues(buf); let S4 = function (num) { let ret = num.toString(16); while (ret.length < 4) { ret = '0' + ret; } return ret; }; const prefix = function (str: string, version: number) { return version + str.slice(1); }; return ( S4(buf[0]) + S4(buf[1]) + '-' + S4(buf[2]) + '-' + prefix(S4(buf[3]), 4) + '-' + S4(buf[4]) + '-' + S4(buf[5]) + S4(buf[6]) + S4(buf[7]) ); } static setStateObjectOnQueryResults(state: any, results: IQueryResults) { QueryUtils.setPropertyOnResults(results, 'state', state); } static setStateObjectOnQueryResult(state: any, result: IQueryResult) { QueryUtils.setPropertyOnResult(result, 'state', state); } static setSearchInterfaceObjectOnQueryResult(searchInterface, result: IQueryResult) { QueryUtils.setPropertyOnResult(result, 'searchInterface', searchInterface); } static setIndexAndUidOnQueryResults(query: IQuery, results: IQueryResults, queryUid: string, pipeline: string, splitTestRun: string) { Assert.exists(query); Assert.exists(results); let index = query.firstResult; QueryUtils.setPropertyOnResults(results, 'queryUid', queryUid); QueryUtils.setPropertyOnResults(results, 'pipeline', pipeline); QueryUtils.setPropertyOnResults(results, 'splitTestRun', splitTestRun); QueryUtils.setPropertyOnResults(results, 'index', index, () => ++index); } static setTermsToHighlightOnQueryResults(query: IQuery, results: IQueryResults) { QueryUtils.setPropertyOnResults(results, 'termsToHighlight', results.termsToHighlight); QueryUtils.setPropertyOnResults(results, 'phrasesToHighlight', results.phrasesToHighlight); } static splitFlags(flags: string, delimiter: string = ';') { Assert.exists(flags); return flags.split(delimiter); } static isAttachment(result: IQueryResult) { return _.contains(QueryUtils.splitFlags(result.flags), 'IsAttachment'); } static containsAttachment(result: IQueryResult) { return _.contains(QueryUtils.splitFlags(result.flags), 'ContainsAttachment'); } static hasHTMLVersion(result: IQueryResult) { return _.contains(QueryUtils.splitFlags(result.flags), 'HasHtmlVersion'); } static hasThumbnail(result: IQueryResult) { return _.contains(QueryUtils.splitFlags(result.flags), 'HasThumbnail'); } static hasExcerpt(result: IQueryResult) { return result.excerpt != undefined && result.excerpt != ''; } static getAuthor(result: IQueryResult): string { return result.raw['author']; } static getUriHash(result: IQueryResult): string { return result.raw['urihash']; } static getObjectType(result: IQueryResult): string { return result.raw['objecttype']; } static getCollection(result: IQueryResult): string { return result.raw['collection'] || 'default'; } static getSource(result: IQueryResult): string { return result.raw['source']; } static getLanguage(result: IQueryResult): string[] { return result.raw['language']; } static getPermanentId(result: IQueryResult): { fieldValue: string; fieldUsed: string } { let fieldValue; let fieldUsed; let permanentId = Utils.getFieldValue(result, 'permanentid'); if (permanentId) { fieldUsed = 'permanentid'; fieldValue = permanentId; } else { fieldUsed = 'urihash'; fieldValue = Utils.getFieldValue(result, 'urihash'); } return { fieldValue: fieldValue, fieldUsed: fieldUsed }; } static quoteAndEscapeIfNeeded(str: string, forceEscape = false): string { Assert.isString(str); return !forceEscape && (QueryUtils.isAtomicString(str) || QueryUtils.isRangeString(str) || QueryUtils.isRangeWithoutOuterBoundsString(str)) ? str : QueryUtils.quoteAndEscape(str); } static quoteAndEscape(str: string): string { Assert.isString(str); return `"${QueryUtils.escapeString(str)}"`; } static escapeString(str: string): string { Assert.isString(str); return str.replace(/"/g, ' '); } static isAtomicString(str: string): boolean { Assert.isString(str); return /^\d+(\.\d+)?$|^[\d\w]+$/.test(str); } static isRangeString(str: string): boolean { Assert.isString(str); return /^\d+(\.\d+)?\.\.\d+(\.\d+)?$|^\d{4}\/\d{2}\/\d{2}@\d{2}:\d{2}:\d{2}\.\.\d{4}\/\d{2}\/\d{2}@\d{2}:\d{2}:\d{2}$/.test(str); } static isRangeWithoutOuterBoundsString(str: string): boolean { Assert.isString(str); return /^\d+(\.\d+)?$|^\d{4}\/\d{2}\/\d{2}@\d{2}:\d{2}:\d{2}$/.test(str); } static buildFieldExpression(field: string, operator: string, values: string[], forceEscape = false) { Assert.isNonEmptyString(field); Assert.stringStartsWith(field, '@'); Assert.isNonEmptyString(operator); Assert.isLargerOrEqualsThan(1, values.length); if (values.length == 1) { return field + operator + QueryUtils.quoteAndEscapeIfNeeded(values[0], forceEscape); } else { return field + operator + '(' + _.map(values, str => QueryUtils.quoteAndEscapeIfNeeded(str, forceEscape)).join(',') + ')'; } } static buildFieldNotEqualExpression(field: string, values: string[], forceEscape = false) { Assert.isNonEmptyString(field); Assert.stringStartsWith(field, '@'); Assert.isLargerOrEqualsThan(1, values.length); let filter: string; if (values.length == 1) { filter = field + '==' + QueryUtils.quoteAndEscapeIfNeeded(values[0], forceEscape); } else { filter = field + '==' + '(' + _.map(values, str => QueryUtils.quoteAndEscapeIfNeeded(str, forceEscape)).join(',') + ')'; } return '(NOT ' + filter + ')'; } public static setPropertyOnResults(results: IQueryResults, property: string, value: any, afterOneLoop?: () => any) { _.each(results.results, (result: IQueryResult) => { QueryUtils.setPropertyOnResult(result, property, value); value = afterOneLoop ? afterOneLoop() : value; }); } public static setPropertyOnResult(result: IQueryResult, property: string, value: any) { result[property] = value; _.each(result.childResults, (child: IQueryResult) => { child[property] = value; }); if (!Utils.isNullOrUndefined(result.parentResult)) { result.parentResult[property] = value; } } public static isStratusAgnosticField(fieldToVerify: string, fieldToMatch: string): boolean { let checkForSystem = /^(@?)(sys)?(.*)/i; let matchFieldToVerify = checkForSystem.exec(fieldToVerify); let matchFieldToMatch = checkForSystem.exec(fieldToMatch); if (matchFieldToVerify && matchFieldToMatch) { return (matchFieldToVerify[1] + matchFieldToVerify[3]).toLowerCase() == (matchFieldToMatch[1] + matchFieldToMatch[3]).toLowerCase(); } return false; } }