import { FieldType } from '@terascope/types' ; import * as ts from '@terascope/utils' ; import { Repository , RecordInput , InputType } from '../interfaces' ; import { isString , isArray } from '../validations/field-validator' ; export const repository = { renameField : { fn : renameField , config : { from : { type : FieldType . String } , to : { type : FieldType . String } } , primary_input_type : InputType . Object , output_type : FieldType . Object , } , setField : { fn : setField , config : { field : { type : FieldType . String } , value : { type : FieldType . Any } } , primary_input_type : InputType . Object , output_type : FieldType . Object , } , dropFields : { fn : dropFields , config : { fields : { type : FieldType . String , array : true } } , primary_input_type : InputType . Object , output_type : FieldType . Object , } , copyField : { fn : copyField , config : { from : { type : FieldType . String } , to : { type : FieldType . String } } , primary_input_type : InputType . Object , output_type : FieldType . Object } , dedupe : { fn : dedupe , config : { } , output_type : FieldType . Any , primary_input_type : InputType . Array } , } ; example param { * } record param { { from : string ; to : string } } args returns export function renameField ( input , _parentContext , args ) { if ( ts . isNil ( input ) ) return null ; _validateArgs ( args , [ 'from' , 'to' ] ) ; const { from , to } = args ; if ( ! isString ( from ) || ! isString ( to ) ) throw new Error ( 'Invalid parameters, from/to must be supplied be be a string' ) ; if ( isArray ( input ) ) { return input . map ( ( data ) => _migrate ( data , from , to ) ) . filter ( ts . isNotNil ) ; } return _migrate ( input , from , to ) ; } function _migrate ( doc , from , to ) { if ( ! ts . isObjectEntity ( doc ) ) return null ; doc [ to ] = doc [ from ] ; delete doc [ from ] ; return doc ; } example param { * } record param { { field : string ; value : any } } args returns export function setField ( input , _parentContext , args ) { if ( ts . isNil ( input ) ) return null ; _validateArgs ( args , [ 'field' , 'value' ] ) ; const { field , value } = args ; if ( ! isString ( field ) || value === undefined ) throw new Error ( 'Invalid parameters, please set field/value' ) ; if ( isArray ( input ) ) { return input . map ( ( data ) => { if ( ! ts . isObjectEntity ( data ) ) return null ; data [ field ] = value ; return data ; } ) . filter ( ts . isNotNil ) ; } if ( ! ts . isObjectEntity ( input ) ) return null ; input [ field ] = value ; return input ; } example param { * } record param { { fields : string [ ] } } args returns export function dropFields ( input , _parentContext , args ) { if ( ts . isNil ( input ) ) return null ; _validateArgs ( args , [ 'fields' ] ) ; const { fields } = args ; if ( ! fields . every ( isString ) ) throw new Error ( 'Invalid parameters, field must be supplied and be a string' ) ; if ( isArray ( input ) ) { return input . map ( ( data ) => _removeKeys ( data , fields ) ) . filter ( ts . isNotNil ) ; } return _removeKeys ( input , fields ) ; } function _removeKeys ( obj , fields ) { if ( ! ts . isObjectEntity ( obj ) ) return null ; for ( const field of fields ) { delete obj [ field ] ; } if ( Object . keys ( obj ) . length === 0 ) return null ; return obj ; } example param { * } record param { { from : string ; to : string } } args returns export function copyField ( input , _parentContext , args ) { if ( ts . isNil ( input ) ) return null ; _validateArgs ( args , [ 'from' , 'to' ] ) ; const { from , to } = args ; if ( ! isString ( from ) || ! isString ( to ) ) throw new Error ( 'Invalid parameters, field/copyTo must be supplied and be a string' ) ; if ( isArray ( input ) ) { return input . map ( ( data ) => _copyField ( data , from , to ) ) . filter ( ts . isNotNil ) ; } return _copyField ( input , from , to ) ; } function _copyField ( doc , from , to ) { if ( ! ts . isObjectEntity ( doc ) ) return null ; if ( doc [ from ] !== undefined ) doc [ to ] = doc [ from ] ; return doc ; } function _validateArgs ( args , fields ) { if ( ts . isNil ( args ) ) throw new Error ( 'Paramter args must be provided' ) ; for ( const key of fields ) { if ( args [ key ] === undefined ) throw new Error ( `key ${ key } was not provided on args, it is required` ) ; } } example param { * } record param { { field : string ; query : string } } args returns export function transformRecord ( _input , _parentContext , _args ) { return null ; } example param { any [ ] } input returns { any [ ] | null } export function dedupe < T = any > ( input , _parentContext ? ) { if ( ts . isNil ( input ) ) return null ; if ( ! isArray ( input ) ) throw new Error ( `Input must be an array, received ${ ts . getTypeOf ( input ) }` ) ; const deduped = new Map < any , true > ( ) ; const results = [ ] ; for ( const value of input ) { if ( ts . isNotNil ( value ) ) { if ( ts . isPlainObject ( value ) && ! ts . isEmpty ( value ) ) { const sorted = ts . sortKeys ( value , { deep : true } ) ; const json = JSON . stringify ( sorted ) ; if ( ! deduped . has ( json ) ) { results . push ( value ) ; deduped . set ( json , true ) ; } } else if ( ! deduped . has ( value ) ) { results . push ( value ) ; deduped . set ( value , true ) ; } } } return results ; }