author Jeremy Daly <jeremy@jeremydaly.com>
 *  license import { error } from './utils' ; import checkAttribute from './checkAttribute' ; import Table from '../classes/Table' ; export type ProjectionAttributesTable = { [ key ] : ProjectionAttributes ; } ; export type ProjectionAttributes = string | ProjectionAttributeType | ( string | ProjectionAttributeType ) [ ] ; export type ProjectionAttributeType = { [ key ] : string | string [ ] ; } ; export default ( attributes , table , entity , type = false ) => { let index = 0 ; const attrs = Array . isArray ( attributes ) ? attributes : typeof attributes === 'string' ? attributes . split ( ',' ) . map ( x => x . trim ( ) ) : [ attributes ] ; if ( ! table || ! table . Table || Object . keys ( table . Table . attributes ) . length == 0 ) { error ( `Tables must be valid and contain attributes` ) ; } if ( type && table . Table . entityField ) attrs . push ( table . Table . entityField ) ; let names = { } ; let tableAttrs = [ ] ; let entities = { } ; for ( const attribute of attrs ) { if ( typeof attribute === 'string' ) { const attr = checkAttribute ( attribute , ( entity ? table [ entity ] . schema . attributes : table . Table . attributes ) ) ; if ( ! Object . values ( names ) . includes ( attr ) ) { names [ `#proj${ ++ index }` ] = attr ; tableAttrs . push ( attribute ) ; } } else if ( typeof attribute === 'object' ) { for ( const entity in attribute ) { if ( table [ entity ] ) { if ( ! entities [ entity ] ) entities [ entity ] = [ ] ; const ent_attrs = Array . isArray ( attribute [ entity ] ) ? attribute [ entity ] : typeof attribute [ entity ] === 'string' ? String ( attribute [ entity ] ) . split ( ',' ) . map ( x => x . trim ( ) ) : error ( `Only arrays or strings are supported` ) ; for ( const ent_attribute of ent_attrs ) { if ( typeof ent_attribute != 'string' ) error ( `Entity projections must be string values` ) ; const attr = checkAttribute ( ent_attribute , table [ entity ] . schema . attributes ) ; if ( ! Object . values ( names ) . includes ( attr ) ) { names [ `#proj${ ++ index }` ] = attr ; } entities [ entity ] . push ( attr ) ; } } else { error ( `'${ entity }' is not a valid entity on this table` ) ; } } } else { error ( `'${ typeof attribute }' is an invalid type. Projections require strings or arrays` ) ; } } return { names , projections : Object . keys ( names ) . join ( ',' ) , entities : Object . keys ( entities ) . reduce ( ( acc , ent ) => { return Object . assign ( acc , { [ ent ] : [ ... new Set ( [ ... entities [ ent ] , ... tableAttrs ] ) ] } ) ; } , { } ) , tableAttrs } ; } ;