interface ICollectionFormatter { [ type ] : { re : RegExp ; startWith : string ; endWith : string ; format : ( quoteKey : boolean , key : any , quoteValue ? : boolean , value ? : any ) => string ; } ; } const collectionMap = { list : { re : /^list<(.*)>$/ , startWith : '[' , endWith : ']' , format : ( quoteKey , key ) => ( quoteKey ? `'${ key }'` : key ) , } , map : { re : /^map<(.*),\s*(.*)>$/ , startWith : '{' , endWith : '}' , format : ( quoteKey , key , quoteValue , value ) => `${ quoteKey ? `'${ key }'` : key }: ${ quoteValue ? `'${ value }'` : value }` , } , set : { re : /^set<(.*)>$/ , startWith : '{' , endWith : '}' , format : ( quoteKey , key ) => ( quoteKey ? `'${ key }'` : key ) , } , } ; export const collectionTypes = new Set ( Object . keys ( collectionMap ) ) ; param columnType export function isCollectionType ( columnType ) { return Object . values ( collectionMap ) . some ( ( { re } ) => re . test ( columnType ) ) ; } param columnType param rowValue export function getCollectionRowValueAsString ( columnType , rowValue ) { if ( ! rowValue ) { return '' ; } const needsQuotes = [ 'ascii' , 'text' , 'varchar' ] ; for ( const [ collectionType , config ] of Object . entries ( collectionMap ) ) { if ( columnType . includes ( collectionType ) ) { const { re , format , startWith , endWith } = config ; const matches = re . exec ( columnType ) ; if ( matches ) { const [ , keyType , valueType ] = matches ; needsQuotes . includes ( keyType ) ; const quoteKey = needsQuotes . includes ( keyType ) ; let content ; if ( valueType ) { const quoteValue = ! ! valueType && needsQuotes . includes ( valueType ) ; content = Object . entries ( rowValue ) . map ( ( [ key , value ] ) => format ( quoteKey , key , quoteValue , value ) ) . join ( ', ' ) ; } else { content = rowValue . map ( ( value ) => format ( quoteKey , value ) ) . join ( ', ' ) ; } return `${ startWith } ${ content } ${ endWith }` ; } } } return rowValue ; }