2020-01-07 12:51:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								'use strict' ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								const  _  =  require ( 'lodash' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  utils  =  require ( './utils' ) ( ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Build  a  mongo  query 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options  -  Query  options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . model  -  The  model  you  are  querying 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . filers  -  An  object  with  the  possible  filters  ( start ,  limit ,  sort ,  where ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . populate  -  An  array  of  paths  to  populate 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ param  { boolean }  options . aggregate  -  Force  aggregate  function  to  use  group  by  feature 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-29 16:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  buildQuery  =  ( {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  model , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  filters  =  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  populate  =  [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  aggregate  =  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  =  { } )  =>  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  deepFilters  =  ( filters . where  ||  [ ] ) . filter ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ( {  field  } )  =>  field . split ( '.' ) . length  >  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( deepFilters . length  ===  0  &&  aggregate  ===  false )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  buildSimpleQuery ( {  model ,  filters ,  populate  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  buildDeepQuery ( {  model ,  filters ,  populate  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Builds  a  simple  find  query  when  there  are  no  deep  filters 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options  -  Query  options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . model  -  The  model  you  are  querying 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . filers  -  An  object  with  the  possible  filters  ( start ,  limit ,  sort ,  where ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . populate  -  An  array  of  paths  to  populate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  buildSimpleQuery  =  ( {  model ,  filters ,  populate  } )  =>  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  {  where  =  [ ]  }  =  filters ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 18:18:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  const  wheres  =  where . map ( buildWhereClause ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  findCriteria  =  wheres . length  >  0  ?  {  $and :  wheres  }  :  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-25 18:18:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  let  query  =  model . find ( findCriteria ) . populate ( populate ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  query  =  applyQueryParams ( {  query ,  filters  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  Object . assign ( query ,  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-29 16:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Override count to use countDocuments on simple find query
 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    count ( ... args )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  query . countDocuments ( ... args ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Builds  a  deep  aggregate  query  when  there  are  deep  filters 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options  -  Query  options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . model  -  The  model  you  are  querying 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . filers  -  An  object  with  the  possible  filters  ( start ,  limit ,  sort ,  where ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . populate  -  An  array  of  paths  to  populate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  buildDeepQuery  =  ( {  model ,  filters ,  populate  } )  =>  {  
						 
					
						
							
								
									
										
										
										
											2019-03-29 16:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  // Build a tree of paths to populate based on the filtering and the populate option
 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  const  {  populatePaths ,  wherePaths  }  =  computePopulatedPaths ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    model , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    populate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    where :  filters . where , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-29 16:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  // Init the query
 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  let  query  =  model 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-29 16:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    . aggregate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      buildQueryAggregate ( model ,  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        paths :  _ . merge ( { } ,  populatePaths ,  wherePaths ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    . append ( buildQueryMatches ( model ,  filters ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Overrides  the  promise  to  rehydrate  mongoose  docs  after  the  aggregation  query 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    then ( ... args )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  query 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 12:07:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        . append ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          $project :  {  _id :  true  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . then ( results  =>  results . map ( el  =>  el . _id ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . then ( ids  =>  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  ( ids . length  ===  0 )  return  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  query  =  model 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . find ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              _id :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                $in :  ids , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . populate ( populate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          return  applyQueryParams ( {  query ,  filters  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        . then ( ... args ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    catch ( ... args )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  this . then ( r  =>  r ) . catch ( ... args ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Maps  to  query . count 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    count ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-29 16:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  query 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . count ( 'count' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . then ( results  =>  _ . get ( results ,  [ '0' ,  'count' ] ,  0 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-29 16:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Maps  to  query  group 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    group ( ... args )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  query . group ( ... args ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Returns  an  array  of  plain  JS  object  instead  of  mongoose  documents 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    lean ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-29 16:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      // Returns plain js objects without the transformations we normally do on find
 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      return  this . then ( results  =>  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  results . map ( r  =>  r . toObject ( {  transform :  false  } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
									
										
										
										
											2019-03-29 16:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Apply  sort  limit  and  start  params 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ param  { Object }  options  -  Options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . query  -  Mongoose  query 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . filters  -  Filters  object 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  applyQueryParams  =  ( {  query ,  filters  } )  =>  {  
						 
					
						
							
								
									
										
										
										
											2019-03-29 16:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  // Apply sort param
 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( _ . has ( filters ,  'sort' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  sortFilter  =  filters . sort . reduce ( ( acc ,  sort )  =>  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      const  {  field ,  order  }  =  sort ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      acc [ field ]  =  order  ===  'asc'  ?  1  :  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  acc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    query  =  query . sort ( sortFilter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-29 16:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  // Apply start param
 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( _ . has ( filters ,  'start' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    query  =  query . skip ( filters . start ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-29 16:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  // Apply limit param
 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( _ . has ( filters ,  'limit' )  &&  filters . limit  >=  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    query  =  query . limit ( filters . limit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  query ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns  a  tree  of  the  paths  to  populate  both  for  population  and  deep  filtering  purposes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options  -  Options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . model  -  Model  from  which  to  populate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . populate  -  Paths  to  populate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . where  -  Where  clauses  we  need  to  populate  to  filters 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  computePopulatedPaths  =  ( {  model ,  populate  =  [ ] ,  where  =  [ ]  } )  =>  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  castedPopulatePaths  =  populate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    . map ( el  =>  ( Array . isArray ( el )  ?  el . join ( '.' )  :  el ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    . map ( path  =>  findModelPath ( {  rootModel :  model ,  path  } ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    . map ( path  =>  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      const  assocModel  =  findModelByPath ( {  rootModel :  model ,  path  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // autoload morph relations
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      let  extraPaths  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( assocModel )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        extraPaths  =  assocModel . associations 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          . filter ( assoc  =>  assoc . nature . toLowerCase ( ) . indexOf ( 'morph' )  !==  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          . map ( assoc  =>  ` ${ path } . ${ assoc . alias } ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  [ path ,  ... extraPaths ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    . reduce ( ( acc ,  paths )  =>  acc . concat ( paths ) ,  [ ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 12:11:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  const  castedWherePaths  =  where 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    . map ( ( {  field  } )  =>  findModelPath ( {  rootModel :  model ,  path :  field  } ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    . filter ( path  =>  ! ! path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    populatePaths :  pathsToTree ( castedPopulatePaths ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    wherePaths :  pathsToTree ( castedWherePaths ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Builds  an  object  based  on  paths : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     'articles' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     'articles.tags.cateogry' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     'articles.tags.label' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  ]  =>  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   articles :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     tags :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *       category :  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *       label :  { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Array < string > }  paths  -  A  list  of  paths  to  transform 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-29 16:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  pathsToTree  =  paths  =>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  paths . reduce ( ( acc ,  path )  =>  _ . merge ( acc ,  _ . set ( { } ,  path ,  { } ) ) ,  { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Builds  the  aggregations  pipeling  of  the  query 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  model  -  Queried  model 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options  -  Options 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-29 16:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . paths  -  A  tree  of  paths  to  aggregate  e . g  {  article  :  {  tags  :  {  label :  { } } } } 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  buildQueryAggregate  =  ( model ,  {  paths  }  =  { } )  =>  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  Object . keys ( paths ) . reduce ( ( acc ,  key )  =>  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  acc . concat ( buildLookup ( {  model ,  key ,  paths :  paths [ key ]  } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								  } ,  [ ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
									
										
										
										
											2019-03-29 16:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Builds  a  lookup  aggregation  for  a  specific  key 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options  -  Options 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . model  -  Queried  model 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-29 16:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ param  { string }  options . key  -  The  attribute  name  to  lookup  on  the  model 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . paths  -  A  tree  of  paths  to  aggregate  inside  the  current  lookup  e . g  {  {  tags  :  {  label :  { } } } 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  buildLookup  =  ( {  model ,  key ,  paths  } )  =>  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  assoc  =  model . associations . find ( a  =>  a . alias  ===  key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  assocModel  =  findModelByAssoc ( {  assoc  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( ! assocModel )  return  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      $lookup :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        from :  assocModel . collectionName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        as :  assoc . alias , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        let :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          localId :  '$_id' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          localAlias :  ` $ ${ assoc . alias } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        pipeline :  [ ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          . concat ( buildLookupMatch ( {  assoc  } ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          . concat ( buildQueryAggregate ( assocModel ,  {  paths  } ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 12:07:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Build  a  lookup  match  expression  ( equivalent  to  a  SQL  join  condition ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-29 16:53:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ param  { Object }  options  -  Options 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . assoc  -  The  association  on  which  is  based  the  ematching  xpression 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  buildLookupMatch  =  ( {  assoc  } )  =>  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  switch  ( assoc . nature )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'oneToOne' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          $match :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $expr :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              $eq :  [ ` $ ${ assoc . via } ` ,  '$$localId' ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'oneToMany' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $match :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          $expr :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $eq :  [ ` $ ${ assoc . via } ` ,  '$$localId' ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'oneWay' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'manyToOne' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $match :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          $expr :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $eq :  [ '$$localAlias' ,  '$_id' ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-07 12:51:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  'manyWay' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $match :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          $expr :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $in :  [ '$_id' ,  '$$localAlias' ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  'manyToMany' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( assoc . dominant  ===  true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          $match :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $expr :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              $in :  [ '$_id' ,  '$$localAlias' ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $match :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          $expr :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $in :  [ '$$localId' ,  ` $ ${ assoc . via } ` ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'manyToManyMorph' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'oneToManyMorph' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  [ 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-29 16:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          $unwind :  {  path :  ` $ ${ assoc . via } ` ,  preserveNullAndEmptyArrays :  true  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          $match :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $expr :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              $and :  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                {  $eq :  [ ` $ ${ assoc . via } .ref ` ,  '$$localId' ]  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                {  $eq :  [ ` $ ${ assoc . via } . ${ assoc . filter } ` ,  assoc . alias ]  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Match  query  for  lookups 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  model  -  Mongoose  model 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  filters  -  Filters  object 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  buildQueryMatches  =  ( model ,  filters )  =>  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( _ . has ( filters ,  'where' )  &&  Array . isArray ( filters . where ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  filters . where . map ( whereClause  =>  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        $match :  buildWhereClause ( formatWhereClause ( model ,  whereClause ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  [ ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Cast  values 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { * }  value  -  Value  to  cast 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-28 17:12:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  formatValue  =  value  =>  utils . valueToId ( value ) ;  
						 
					
						
							
								
									
										
										
										
											2019-03-22 17:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Builds  a  where  clause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options  -  Options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { string }  options . field  -  Where  clause  field 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { string }  options . operator  -  Where  clause  operator 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { * }  options . value  -  Where  clause  alue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								const  buildWhereClause  =  ( {  field ,  operator ,  value  } )  =>  {  
						 
					
						
							
								
									
										
										
										
											2019-03-28 17:12:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( Array . isArray ( value )  &&  ! [ 'in' ,  'nin' ] . includes ( operator ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 17:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-28 17:12:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      $or :  value . map ( val  =>  buildWhereClause ( {  field ,  operator ,  value :  val  } ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 17:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-28 17:12:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  const  val  =  formatValue ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								  switch  ( operator )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'eq' : 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 17:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  {  [ field ] :  val  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    case  'ne' : 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 17:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  {  [ field ] :  {  $ne :  val  }  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    case  'lt' : 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 17:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  {  [ field ] :  {  $lt :  val  }  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    case  'lte' : 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 17:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  {  [ field ] :  {  $lte :  val  }  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    case  'gt' : 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 17:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  {  [ field ] :  {  $gt :  val  }  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    case  'gte' : 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 17:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  {  [ field ] :  {  $gte :  val  }  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    case  'in' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [ field ] :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 17:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          $in :  Array . isArray ( val )  ?  val  :  [ val ] , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'nin' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [ field ] :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 17:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          $nin :  Array . isArray ( val )  ?  val  :  [ val ] , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'contains' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [ field ] :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 17:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          $regex :  ` ${ val } ` , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								          $options :  'i' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'ncontains' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [ field ] :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 17:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          $not :  new  RegExp ( val ,  'i' ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'containss' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [ field ] :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 17:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          $regex :  ` ${ val } ` , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'ncontainss' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [ field ] :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 17:58:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          $not :  new  RegExp ( val ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-04 19:10:17 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  'null' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  value  ?  {  [ field ] :  {  $eq :  null  }  }  :  {  [ field ] :  {  $ne :  null  }  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-29 16:09:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      throw  new  Error ( ` Unhandled whereClause :  ${ field }   ${ operator }   ${ value } ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Add  primaryKey  on  relation  where  clause  for  lookups  match 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  model  -  Mongoose  model 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  whereClause  -  Where  clause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { string }  whereClause . field  -  Where  clause  field 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { string }  whereClause . operator  -  Where  clause  operator 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { * }  whereClause . value  -  Where  clause  alue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  formatWhereClause  =  ( model ,  {  field ,  operator ,  value  } )  =>  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  {  assoc ,  model :  assocModel  }  =  getAssociationFromFieldKey ( model ,  field ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  shouldFieldBeSuffixed  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assoc  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ! _ . endsWith ( field ,  assocModel . primaryKey )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ( [ 'in' ,  'nin' ] . includes ( operator )  ||  // When using in or nin operators we want to apply the filter on the relation's primary key and not the relation itself
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ( [ 'eq' ,  'ne' ] . includes ( operator )  &&  utils . isMongoId ( value ) ) ) ;  // Only suffix the field if the operators are eq or ne and the value is a valid mongo id
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    field :  shouldFieldBeSuffixed  ?  ` ${ field } . ${ assocModel . primaryKey } `  :  field , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    operator , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    value , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns  an  association  from  a  path  starting  from  model 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  model  -  Mongoose  model 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { string }  fieldKey  -  Relation  path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  getAssociationFromFieldKey  =  ( model ,  fieldKey )  =>  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  let  tmpModel  =  model ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								  let  assoc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  parts  =  fieldKey . split ( '.' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( let  key  of  parts )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    assoc  =  tmpModel . associations . find ( ast  =>  ast . alias  ===  key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( assoc )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      tmpModel  =  findModelByAssoc ( {  assoc  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assoc , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    model :  tmpModel , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
									
										
										
										
											2019-07-05 03:05:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Returns  a  model  from  a  relation  path  and  a  root  model 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ param  { Object }  options  -  Options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . rootModel  -  Mongoose  model 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { string }  options . path  -  Relation  path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  findModelByPath  =  ( {  rootModel ,  path  } )  =>  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  parts  =  path . split ( '.' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  let  tmpModel  =  rootModel ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( let  part  of  parts )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  assoc  =  tmpModel . associations . find ( ast  =>  ast . alias  ===  part ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( assoc )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      tmpModel  =  findModelByAssoc ( {  assoc  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  tmpModel ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 14:57:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns  a  model  path  from  an  attribute  path  and  a  root  model 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options  -  Options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { Object }  options . rootModel  -  Mongoose  model 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { string }  options . path  -  Attribute  path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  findModelPath  =  ( {  rootModel ,  path  } )  =>  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  parts  =  path . split ( '.' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  let  tmpModel  =  rootModel ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  let  tmpPath  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( let  part  of  parts )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  assoc  =  tmpModel . associations . find ( ast  =>  ast . alias  ===  part ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 12:11:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( assoc )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      tmpModel  =  findModelByAssoc ( {  assoc  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      tmpPath . push ( part ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  return  tmpPath . length  >  0  ?  tmpPath . join ( '.' )  :  null ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-22 12:16:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  findModelByAssoc  =  ( {  assoc  } )  =>  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  {  models  }  =  strapi . plugins [ assoc . plugin ]  ||  strapi ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  models [ assoc . model  ||  assoc . collection ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
									
										
										
										
											2019-03-13 19:27:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								module . exports  =  buildQuery ;