import type { ExtendedResolveParams } from '../index' ; import { NestedAliasesMap } from './aliases' ; import { isObject } from 'graphql-compose' ; export function projectionHelper ( resolveParams , aliases ? ) { const projection = resolveParams . projection ; if ( projection ) { if ( projection [ '*' ] ) { return ; } const flatProjection = dotifyWithAliases ( projection , aliases ) ; if ( Object . keys ( flatProjection ) . length > 0 ) { resolveParams . query = resolveParams . query . select ( flatProjection ) ; } } } export type ProjectionOperator = Record < string , any > ; export type FlatDottedObject = Record < string , boolean | ProjectionOperator > ; export function dotifyWithAliases ( obj , aliases ? ) { const res = { } ; dotifyRecurse ( obj , res , aliases ) ; return res ; } /**
 * Nested projection converts to `flat` dotted mongoose projection.
 * If you model has aliases, then pass here result from `prepareNestedAliases()`
 */ function dotifyRecurse ( obj , res , aliases ? , prefix ? ) { Object . keys ( obj ) . forEach ( ( key ) => { const value = obj [ key ] ; let newKey ; if ( aliases && aliases ?. [ key ] ) { const alias = aliases ?. [ key ] ; let aliasValue ; if ( typeof alias === 'string' ) { aliasValue = alias ; } else if ( isObject ( alias ) ) { aliasValue = alias ?. __selfAlias ; } newKey = aliasValue || key ; } else { newKey = key ; } if ( prefix ) { newKey = `${ prefix }.${ newKey }` ; } if ( value && ( value . $meta || value . $slice || value . $elemMatch || value . $ ) ) { res [ newKey ] = value ; } else if ( isObject ( value ) && Object . keys ( value ) . length > 0 ) { let subAliases ; if ( aliases && isObject ( aliases ?. [ key ] ) ) { subAliases = ( aliases as any ) [ key ] ; } dotifyRecurse ( value , res , subAliases , newKey ) ; } else { res [ newKey ] = ! ! value ; } } ) ; }