File tree Expand file tree Collapse file tree 3 files changed +69
-2
lines changed
Expand file tree Collapse file tree 3 files changed +69
-2
lines changed Original file line number Diff line number Diff line change @@ -157,13 +157,16 @@ var Model = sequelize.define('User', {
157157
158158import {attributeFields } from ' graphql-sequelize' ;
159159
160+ var cache = {}; // Reusable cache of enum types
160161attributeFields (Model, {
161162 // ... options
162163 exclude: [], // array of model attributes to ignore - default: []
163164 only: [], // only generate definitions for these model attributes - default: null
164165 globalId: true , // return an relay global id field - default: false
165166 map: {}, // rename fields - default: {}
166167 allowNull: false , // disable wrapping mandatory fields in `GraphQLNonNull` - default: false
168+ commentToDescription: false , // convert model comment to GraphQL description - default: false
169+ cache: cache, // Cache enum types to prevent duplicate type name error - default: {}
167170});
168171
169172/*
Original file line number Diff line number Diff line change @@ -3,6 +3,7 @@ import { GraphQLNonNull, GraphQLEnumType } from 'graphql';
33import { globalIdField } from 'graphql-relay' ;
44
55module . exports = function ( Model , options = { } ) {
6+ var cache = options . cache || { } ;
67 var result = Object . keys ( Model . rawAttributes ) . reduce ( function ( memo , key ) {
78 if ( options . exclude && ~ options . exclude . indexOf ( key ) ) return memo ;
89 if ( options . only && ! ~ options . only . indexOf ( key ) ) return memo ;
@@ -24,7 +25,18 @@ module.exports = function (Model, options = {}) {
2425 } ;
2526
2627 if ( memo [ key ] . type instanceof GraphQLEnumType ) {
27- memo [ key ] . type . name = `${ Model . name } ${ key } EnumType` ;
28+ var typeName = `${ Model . name } ${ key } EnumType` ;
29+ /*
30+ Cache enum types to prevent duplicate type name error
31+ when calling attributeFields multiple times on the same model
32+ */
33+ if ( cache [ typeName ] ) {
34+ memo [ key ] . type = cache [ typeName ] ;
35+ } else {
36+ memo [ key ] . type . name = typeName ;
37+ cache [ typeName ] = memo [ key ] . type ;
38+ }
39+
2840 }
2941
3042 if ( ! options . allowNull ) {
Original file line number Diff line number Diff line change @@ -14,7 +14,9 @@ import {
1414 GraphQLNonNull ,
1515 GraphQLBoolean ,
1616 GraphQLEnumType ,
17- GraphQLList
17+ GraphQLList ,
18+ GraphQLObjectType ,
19+ GraphQLSchema
1820} from 'graphql' ;
1921
2022import {
@@ -197,6 +199,56 @@ describe('attributeFields', function () {
197199 expect ( fields . enumTwo . type . getValues ( ) [ 0 ] . value ) . to . equal ( 'foo_bar' ) ;
198200 } ) ;
199201
202+ it ( 'should not create multiple enum types with same name when using cache' , function ( ) {
203+
204+ // Create Schema
205+ var schemaFn = function ( fields1 , fields2 ) {
206+ return function ( ) {
207+ var object1 = new GraphQLObjectType ( {
208+ name : 'Object1' ,
209+ fields : fields1
210+ } ) ;
211+ var object2 = new GraphQLObjectType ( {
212+ name : 'Object2' ,
213+ fields : fields2
214+ } ) ;
215+ return new GraphQLSchema ( {
216+ query : new GraphQLObjectType ( {
217+ name : 'RootQueryType' ,
218+ fields : {
219+ object1 : {
220+ type : object1 ,
221+ resolve : function ( ) {
222+ return { } ;
223+ }
224+ } ,
225+ object2 : {
226+ type : object2 ,
227+ resolve : function ( ) {
228+ return { } ;
229+ }
230+ }
231+ }
232+ } )
233+ } ) ;
234+ }
235+ } ;
236+
237+ // Bad: Will create multiple/duplicate types with same name
238+ var fields1a = attributeFields ( Model ) ;
239+ var fields2a = attributeFields ( Model ) ;
240+
241+ expect ( schemaFn ( fields1a , fields2a ) ) . to . throw ( Error ) ;
242+
243+ // Good: Will use cache and not create mutliple/duplicate types with same name
244+ var cache = { } ;
245+ var fields1b = attributeFields ( Model , { cache : cache } ) ;
246+ var fields2b = attributeFields ( Model , { cache : cache } ) ;
247+
248+ expect ( schemaFn ( fields1b , fields2b ) ) . to . not . throw ( Error ) ;
249+
250+ } ) ;
251+
200252 describe ( 'with non-default primary key' , function ( ) {
201253 var ModelWithoutId ;
202254 var modelName = Math . random ( ) . toString ( ) ;
You can’t perform that action at this time.
0 commit comments