11/* @flow */
2+ /* eslint-disable no-use-before-define */
23
3- import { GraphQLInt , GraphQLInputObjectType , GraphQLNonNull } from 'graphql/type' ;
4+ import TypeComposer from '../../../../graphql-compose/src/typeComposer' ;
5+ import { GraphQLNonNull } from 'graphql/type' ;
6+ import getIndexesFromModel from '../../utils/getIndexesFromModel' ;
47import { toDottedObject } from '../../utils' ;
58import type {
69 GraphQLFieldConfigArgumentMap ,
710 ExtendedResolveParams ,
811 MongooseModelT ,
12+ GraphQLObjectType ,
13+ filterHelperArgsOpts ,
914} from '../../definition' ;
1015
11- export type filterHelperArgsGenOpts = {
12- filterTypeName : string ,
13- isRequired ?: boolean ,
14- } ;
15-
16- export const filterHelperArgsGen = (
17- model : MongooseModelT ,
18- opts : filterHelperArgsGenOpts ,
16+ export const filterHelperArgs = (
17+ gqType : GraphQLObjectType ,
18+ opts : filterHelperArgsOpts ,
1919) : GraphQLFieldConfigArgumentMap => {
2020 if ( ! opts . filterTypeName ) {
2121 throw new Error ( 'You should provide `filterTypeName` in options.' ) ;
2222 }
23+ const composer = new TypeComposer ( gqType ) ;
24+
25+ const removeFields = [ ] ;
26+ if ( opts . removeFields ) {
27+ if ( Array . isArray ( opts . removeFields ) ) {
28+ removeFields . push ( ...opts . removeFields ) ;
29+ } else {
30+ removeFields . push ( opts . removeFields ) ;
31+ }
32+ }
33+
34+ if ( opts . onlyIndexed ) {
35+ if ( ! opts . model ) {
36+ throw new Error ( 'You should provide `model` in options with mongoose model '
37+ + 'for deriving index fields.' ) ;
38+ }
39+
40+ const indexedFieldNames = getIndexedFieldNames ( opts . model ) ;
41+ Object . keys ( composer . getFields ( ) ) . forEach ( fieldName => {
42+ if ( indexedFieldNames . indexOf ( fieldName ) === - 1 ) {
43+ removeFields . push ( fieldName ) ;
44+ }
45+ } ) ;
46+ }
2347
24- const filterType = new GraphQLInputObjectType ( {
25- name : opts . filterTypeName ,
26- fields : {
27- age : {
28- name : 'age' ,
29- type : GraphQLInt , // TODO just mock, should be changed in future
30- } ,
31- } ,
32- } ) ;
48+
49+ const inputComposer = composer . getInputTypeComposer ( ) . clone ( opts . filterTypeName ) ;
50+ inputComposer . removeField ( removeFields ) ;
51+
52+ if ( opts . requiredFields ) {
53+ inputComposer . makeFieldsRequired ( opts . requiredFields ) ;
54+ }
3355
3456 return {
3557 filter : {
3658 name : 'filter' ,
37- type : opts . isRequired ? new GraphQLNonNull ( filterType ) : filterType ,
38- description : 'Filter by indexed fields' ,
59+ type : opts . isRequired
60+ ? new GraphQLNonNull ( inputComposer . getType ( ) )
61+ : inputComposer . getType ( ) ,
62+ description : opts . onlyIndexed
63+ ? 'Filter only by indexed fields'
64+ : 'Filter by fields' ,
3965 } ,
4066 } ;
4167} ;
@@ -46,3 +72,15 @@ export function filterHelper(resolveParams: ExtendedResolveParams): void {
4672 resolveParams . query = resolveParams . query . where ( toDottedObject ( filter ) ) ; // eslint-disable-line
4773 }
4874}
75+
76+ export function getIndexedFieldNames ( model : MongooseModelT ) : string [ ] {
77+ const indexes = getIndexesFromModel ( model ) ;
78+
79+ const fieldNames = [ ] ;
80+ indexes . forEach ( ( indexData ) => {
81+ const keys = Object . keys ( indexData ) ;
82+ fieldNames . push ( keys [ 0 ] ) ;
83+ } ) ;
84+
85+ return fieldNames ;
86+ }
0 commit comments