Skip to content

Commit e74d75f

Browse files
authored
Merge pull request #68 from Cactucs/master
Allow circular references
2 parents 16323ab + 6ace1fb commit e74d75f

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

src/specs/object.type-factory.spec.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ describe('objectTypeFactory', function () {
3636
@D.ObjectType()
3737
class Obj { @D.Field() title: string; }
3838
const GQLType: any = objectTypeFactory(Obj);
39-
assert(GQLType._typeConfig.name === 'Obj');
40-
assert(GQLType._typeConfig.fields.title.type instanceof graphql.GraphQLScalarType);
39+
assert(GQLType.name === 'Obj');
40+
assert(GQLType.getFields().title.type instanceof graphql.GraphQLScalarType);
4141
});
4242

4343
it('returns GraphQLInputObjectType with a class annotated by @InputObjectType', function () {
@@ -62,11 +62,30 @@ describe('objectTypeFactory', function () {
6262
@D.InputObjectType()
6363
class Obj { @D.Field() title: string; @D.Field({ type: undefined }) nested: {}; }
6464
try {
65-
const GQLType: any = objectTypeFactory(Obj, true);
65+
const GQLType = objectTypeFactory(Obj, true);
66+
GQLType.getFields();
6667
assert.fail();
6768
} catch (e) {
6869
const err = e as SchemaFactoryError;
6970
assert(err.type === SchemaFactoryErrorType.NO_FIELD);
7071
}
7172
});
73+
74+
it('returns GraphQLObjectType if includes circular references', function () {
75+
@D.ObjectType()
76+
class Obj { @D.Field() circle: Obj; }
77+
const GQLType = objectTypeFactory(Obj);
78+
assert(GQLType.name === 'Obj');
79+
assert((GQLType.getFields().circle.type as graphql.GraphQLObjectType).getFields().circle.type instanceof graphql.GraphQLObjectType);
80+
});
81+
82+
it('allows thunk circular dependecies', function () {
83+
@D.ObjectType()
84+
class A { @D.Field({type: () => B}) circle: any; } // tslint:disable-line:no-use-before-declare
85+
@D.ObjectType()
86+
class B { @D.Field({type: () => A}) circle: any; }
87+
const GQLType = objectTypeFactory(A);
88+
assert(GQLType.name === 'A');
89+
assert((GQLType.getFields().circle.type as graphql.GraphQLObjectType).getFields().circle.type instanceof graphql.GraphQLObjectType);
90+
});
7291
});

src/type-factory/field.type-factory.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,11 @@ function convertType(typeFn: Function, metadata: FieldMetadata | ArgumentMetadat
4444
returnType = objectTypeFactory(typeFn, isInput);
4545
}
4646
} else {
47-
returnType = metadata.type;
47+
try {
48+
returnType = typeof metadata.type === 'function' ? metadata.type() : metadata.type;
49+
} catch (e) {
50+
returnType = metadata.type;
51+
}
4852

4953
if (returnType && returnType.prototype && getMetadataArgsStorage().filterUnionTypeByClass(returnType).length > 0) {
5054
returnType = unionTypeFactory(returnType, isInput);

src/type-factory/object.type-factory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export function objectTypeFactory(target: Function, isInput: boolean = false): g
4646
SchemaFactoryErrorType.NO_FIELD);
4747
}
4848

49-
const fields = fieldMetadataList.reduce((map, fieldMetadata) => {
49+
const fields = () => fieldMetadataList.reduce((map, fieldMetadata) => {
5050
let field = fieldTypeFactory(fieldMetadata.target, fieldMetadata.field, isInput);
5151
if (!field) {
5252
throw new SchemaFactoryError(`@ObjectType()'s ${fieldMetadata.field.name} is annotated by @Field() but no type could be inferred`,

0 commit comments

Comments
 (0)