import { DataTypeConfig , DataTypeFields , DataTypeVersion } from '@terascope/types' ; import * as ts from '@terascope/utils' ; import { mapping } from './types/mapping' ; type ConcatStrType = string | undefined | ( ( string | undefined ) [ ] ) ; export function concatUniqueStrings ( ... values ) { const set = new Set < string > ( ) ; values . forEach ( ( vals ) => { if ( Array . isArray ( vals ) ) { vals . forEach ( ( val ) => { const v = ts . trim ( val ) ; if ( v ) set . add ( v ) ; } ) ; } else if ( vals ) { const v = ts . trim ( vals ) ; if ( v ) set . add ( v ) ; } } ) ; return [ ... set ] ; } export function joinStrings ( ... values ) { return concatUniqueStrings ( ... values ) . join ( '\n' ) ; } export function validateDataTypeConfig ( config ) { if ( ! config || ts . isEmpty ( config ) ) { throw new Error ( 'Missing data type config' ) ; } if ( config . version == null ) { throw new Error ( 'Missing version in data type config' ) ; } const version = ts . toInteger ( config . version ) as DataTypeVersion | false ; if ( ! version || mapping [ version ] == null ) { throw new Error ( `Unknown data type version ${ version }` ) ; } if ( ! config . fields || ! ts . isPlainObject ( config . fields ) ) { throw new Error ( 'Invalid fields was specified in data type config' ) ; } const fields = { } ; for ( const [ _field , typeDef ] of Object . entries ( config . fields ) ) { const field = _field ? ts . unescapeString ( _field ) . trim ( ) : '' ; if ( ! field || ! validateField ( field ) ) { throw new Error ( `Invalid field "${ field }" in data type config` ) ; } if ( ! typeDef || ! ts . isPlainObject ( typeDef ) || ! typeDef . type ) { throw new Error ( `Invalid type config for field "${ field }" in data type config` ) ; } fields [ field ] = typeDef ; } return { version , fields , } ; } function _testFieldRegex ( field ) { return /^[^.]*[a-zA-Z0-9-_.]*[^.]*$/ . test ( field ) ; } export function validateField ( field ) { if ( ! field || ! ts . isString ( field ) ) return false ; if ( ! _testFieldRegex ( field ) ) return false ; return ! field . includes ( '..' ) ; }