import { get , isPlainObject } from 'lodash' ; import { Filter , FilterMeta } from './meta_filter' ; import { IIndexPattern , IFieldType } from '../../index_patterns' ; export type PhraseFilterMeta = FilterMeta & { params ? : { query : string ; } ; field ? : any ; index ? : any ; } ; export type PhraseFilter = Filter & { meta : PhraseFilterMeta ; script ? : { script : { source ? : any ; lang ? : string ; params : any ; } ; } ; } ; type PhraseFilterValue = string | number | boolean ; export const isPhraseFilter = ( filter ) : filter is PhraseFilter => { const isMatchPhraseQuery = filter && filter . query && filter . query . match_phrase ; const isDeprecatedMatchPhraseQuery = filter && filter . query && filter . query . match && Object . values ( filter . query . match ) . find ( ( params ) => params . type === 'phrase' ) ; return Boolean ( isMatchPhraseQuery || isDeprecatedMatchPhraseQuery ) ; } ; export const isScriptedPhraseFilter = ( filter ) : filter is PhraseFilter => Boolean ( get ( filter , 'script.script.params.value' ) ) ; export const getPhraseFilterField = ( filter ) => { const queryConfig = filter . query . match_phrase || filter . query . match ; return Object . keys ( queryConfig ) [ 0 ] ; } ; export const getPhraseFilterValue = ( filter ) : PhraseFilterValue => { const queryConfig = filter . query . match_phrase || filter . query . match ; const queryValue = Object . values ( queryConfig ) [ 0 ] as any ; return isPlainObject ( queryValue ) ? queryValue . query : queryValue ; } ; export const buildPhraseFilter = ( field , value , indexPattern ) : PhraseFilter => { const convertedValue = getConvertedValueForField ( field , value ) ; if ( field . scripted ) { return { meta : { index : indexPattern . id , field : field . name } as PhraseFilterMeta , script : getPhraseScript ( field , value ) , } ; } else { return { meta : { index : indexPattern . id } , query : { match_phrase : { [ field . name ] : convertedValue , } , } , } as PhraseFilter ; } } ; export const getPhraseScript = ( field , value ) => { const convertedValue = getConvertedValueForField ( field , value ) ; const script = buildInlineScriptForPhraseFilter ( field ) ; return { script : { source : script , lang : field . lang , params : { value : convertedValue , } , } , } ; } ; export const getConvertedValueForField = ( field , value ) => { if ( typeof value !== 'boolean' && field . type === 'boolean' ) { if ( [ 1 , 'true' ] . includes ( value ) ) { return true ; } else if ( [ 0 , 'false' ] . includes ( value ) ) { return false ; } else { throw new Error ( `${ value } is not a valid boolean value for boolean field ${ field . name }` ) ; } } return value ; } ; param { object } scriptedField returns { string } export const buildInlineScriptForPhraseFilter = ( scriptedField ) => { if ( scriptedField . lang === 'painless' ) { return ( `boolean compare(Supplier s, def v) {return s.get() == v;}` + `compare(() -> { ${ scriptedField . script } }, params.value);` ) ; } else { return `(${ scriptedField . script }) == value` ; } } ;