Skip to content

Commit 87551ce

Browse files
authored
Merge pull request #31 from indigotech/feature/refactor-object-type
Feature - Refactor @ObjectType and @InputObjectType
2 parents 5265153 + 93c8fa8 commit 87551ce

26 files changed

+191
-182
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"scripts": {
1010
"build": "rimraf lib && tsc",
1111
"lint": "tslint \"src/**/*.ts\"",
12-
"test": "npm run build && npm run lint && mocha lib/**/*.spec.js",
12+
"test": "npm run build && npm run lint && mocha lib/*.spec.js lib/**/*.spec.js",
1313
"watch": "tsc -w",
1414
"watch-test": "mocha lib/**/*.spec.js --watch"
1515
},

src/decorator.spec.ts

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,34 @@
11
import 'reflect-metadata';
22
import * as D from './decorator';
33
import * as graphql from 'graphql';
4-
import { FieldTypeMetadata, GQ_FIELDS_KEY, getFieldMetadata, GQ_OBJECT_METADATA_KEY, ObjectTypeMetadata } from './decorator';
4+
import { FieldTypeMetadata, GQ_FIELDS_KEY, getFieldMetadata } from './decorator';
5+
import { ObjectTypeMetadata } from './metadata/types';
6+
import { getMetadataBuilder } from './metadata-builder';
7+
58
const assert = require('assert');
69

710
describe('Decorators', function () {
811
describe('@ObjectType', function () {
912
it('creates a ObjectTypeMetadata which isInput is false', function () {
1013
@D.ObjectType() class Obj { @D.Field() someField: any; }
11-
const actual = Reflect.getMetadata(GQ_OBJECT_METADATA_KEY, Obj.prototype) as ObjectTypeMetadata;
14+
const actual = getMetadataBuilder().buildObjectTypeMetadata(Obj)[0];
1215
assert(actual.isInput === false);
1316
assert(actual.name === 'Obj');
1417
});
1518

16-
it('sets description to ObjectTypeMetadata with @Description', function () {
17-
@D.Description('this is a object type') @D.ObjectType()
18-
class Obj { @D.Field() someField: any; }
19-
const actual = Reflect.getMetadata(GQ_OBJECT_METADATA_KEY, Obj.prototype) as ObjectTypeMetadata;
20-
assert(actual.isInput === false);
21-
assert(actual.name === 'Obj');
22-
assert(actual.description === 'this is a object type');
23-
});
2419
});
2520

2621
describe('@InputObjectType', function () {
2722
it('creates a ObjectTypeMetadata which isInput is true', function () {
2823
@D.InputObjectType() class Obj { @D.Field() someField: any; }
29-
const actual = Reflect.getMetadata(GQ_OBJECT_METADATA_KEY, Obj.prototype) as ObjectTypeMetadata;
24+
const actual = getMetadataBuilder().buildObjectTypeMetadata(Obj)[0];
3025
assert(actual.isInput === true);
3126
assert(actual.name === 'Obj');
3227
});
3328

3429
it('sets description to ObjectTypeMetadata which isInput is true with description option', function () {
3530
@D.InputObjectType({ description: 'some input' }) class Obj { }
36-
const actual = Reflect.getMetadata(GQ_OBJECT_METADATA_KEY, Obj.prototype) as ObjectTypeMetadata;
31+
const actual = getMetadataBuilder().buildObjectTypeMetadata(Obj)[0];
3732
assert(actual.isInput === true);
3833
assert(actual.description === 'some input');
3934
});

src/decorator.ts

Lines changed: 1 addition & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ export const GQ_QUERY_KEY = 'gq_query';
1515
export const GQ_MUTATION_KEY = 'gq_mutation';
1616
export const GQ_SUBSCRIPTION_KEY = 'gq_subscription';
1717
export const GQ_FIELDS_KEY = 'gq_fields';
18-
export const GQ_OBJECT_METADATA_KEY = 'gq_object_type';
1918
export const GQ_DESCRIPTION_KEY = 'gq_description';
2019

2120
export interface TypeMetadata {
@@ -46,12 +45,6 @@ export interface FieldTypeMetadata extends RootMetadata {
4645
context?: ContextMetadata;
4746
}
4847

49-
export interface ObjectTypeMetadata {
50-
name?: string;
51-
description?: string;
52-
isInput?: boolean;
53-
}
54-
5548
export interface DefaultOption {
5649
description?: string;
5750
}
@@ -95,16 +88,6 @@ function mergeDescriptionMetadata(target: any, sourceMetadata: any): any {
9588
return sourceMetadata;
9689
}
9790

98-
function createOrSetObjectTypeMetadata(target: any, metadata: ObjectTypeMetadata) {
99-
if (!Reflect.hasMetadata(GQ_OBJECT_METADATA_KEY, target.prototype)) {
100-
let mergedMetadata = mergeDescriptionMetadata(target, metadata);
101-
Reflect.defineMetadata(GQ_OBJECT_METADATA_KEY, mergedMetadata, target.prototype);
102-
} else {
103-
const originalMetadata = Reflect.getMetadata(GQ_OBJECT_METADATA_KEY, target.prototype) as ObjectTypeMetadata;
104-
Object.assign(originalMetadata, metadata);
105-
}
106-
}
107-
10891
function createOrSetFieldTypeMetadata(target: any, metadata: FieldTypeMetadata) {
10992
let fieldDefs: FieldTypeMetadata[];
11093
if (!Reflect.hasMetadata(GQ_FIELDS_KEY, target)) {
@@ -215,13 +198,7 @@ function setDescriptionMetadata(description: string, target: any, propertyKey: s
215198
createPropertyDescriptionMetadata(target, description, propertyKey);
216199
}
217200
} else {
218-
if (Reflect.hasMetadata(GQ_OBJECT_METADATA_KEY, target.prototype)) {
219-
createOrSetObjectTypeMetadata(target, {
220-
description: description,
221-
});
222-
} else {
223-
createDescriptionMetadata(target, description);
224-
}
201+
createDescriptionMetadata(target, description);
225202
}
226203
}
227204

@@ -265,38 +242,6 @@ function setPaginationMetadata(target: any, propertyKey: string, methodDescripto
265242
};
266243
}
267244

268-
export function ObjectType(option?: DefaultOption) {
269-
return function (target: any) {
270-
createOrSetObjectTypeMetadata(target, {
271-
name: target.name,
272-
isInput: false,
273-
});
274-
275-
if (option) {
276-
// description
277-
if (option.description) {
278-
setDescriptionMetadata(option.description, target);
279-
}
280-
}
281-
} as Function;
282-
}
283-
284-
export function InputObjectType(option?: DefaultOption) {
285-
return function (target: any) {
286-
createOrSetObjectTypeMetadata(target, {
287-
name: target.name,
288-
isInput: true,
289-
});
290-
291-
if (option) {
292-
// description
293-
if (option.description) {
294-
setDescriptionMetadata(option.description, target);
295-
}
296-
}
297-
} as Function;
298-
}
299-
300245
export function Field(option?: FieldOption) {
301246
return function (target: any, propertyKey: any, methodDescriptor?: any) {
302247
createOrSetFieldTypeMetadata(target, {

src/decorator/enum-type.decorator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { getMetadataArgsStorage } from '../metadata-builder';
55
* It can be used just like {@link ObjectType} in order to create {@link GraphQLEnumType} objects.
66
* See [GraphQL Documentation - Enum Types]{@http://graphql.org/learn/schema/#enumeration-types}
77
*
8-
* @param option Options for a Enum Type
8+
* @param option Options for an Enum Type
99
*/
1010
export function EnumType(option?: EnumOption) {
1111
return function (target: any) {

src/decorator/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from './enum-type.decorator';
22
export * from './union-type.decorator';
3+
export * from './object-type.decorator';
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { ObjectOption } from '../metadata/options';
2+
import { getMetadataArgsStorage } from '../metadata-builder';
3+
4+
/**
5+
* It is used to create {@link GraphQLObjectType} objects.
6+
* See [GraphQL Documentation - Object Types]{@http://graphql.org/learn/schema/#object-types-and-fields}
7+
*
8+
* @param option Options for an Object Type
9+
*/
10+
export function ObjectType(option?: ObjectOption) {
11+
return CreateObjectType(false, option);
12+
}
13+
14+
/**
15+
* It is used to create {@link GraphQLInputObjectType} objects.
16+
* See [GraphQL Documentation - Input Types]{@http://graphql.org/learn/schema/#input-types}
17+
*
18+
* @param option Options for an Input Object Type
19+
*/
20+
export function InputObjectType(option?: ObjectOption) {
21+
return CreateObjectType(true, option);
22+
}
23+
24+
function CreateObjectType(isInput: boolean, option?: ObjectOption) {
25+
return function (target: any) {
26+
getMetadataArgsStorage().objects.push({
27+
target: target,
28+
name: target.name,
29+
description: option ? option.description : null,
30+
isInput: isInput,
31+
});
32+
};
33+
}
34+

src/decorator/union-type.decorator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { UnionOption } from '../metadata';
55
* Union Type.
66
* See [GraphQL Documentation - Union Types]{@link http://graphql.org/learn/schema/#union-types}
77
*
8-
* @param option Options for a Union Type
8+
* @param option Options for an Union Type
99
*/
1010
export function UnionType<T>(option: UnionOption<T>) {
1111
return function (target: any) {

src/field_type_factory.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as graphql from 'graphql';
33

44
import { fieldTypeFactory, resolverFactory, clearFieldTypeCache } from './field_type_factory';
55

6-
import { clearObjectTypeRepository } from './object_type_factory';
6+
import { clearObjectTypeRepository } from './type-factory';
77

88
const assert = require('assert');
99

src/field_type_factory.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
ContextMetadata,
66
FieldTypeMetadata,
77
GQ_FIELDS_KEY,
8-
GQ_OBJECT_METADATA_KEY,
98
Middleware,
109
RootMetadata,
1110
TypeMetadata,
@@ -17,7 +16,7 @@ import { SchemaFactoryError, SchemaFactoryErrorType } from './schema_factory';
1716
import { IoCContainer } from './ioc-container';
1817
import { OrderByTypeFactory } from './order-by.type-factory';
1918
import { PaginationType } from './pagination.type';
20-
import { objectTypeFactory } from './object_type_factory';
19+
import { objectTypeFactory } from './type-factory';
2120
import { unionTypeFactory, enumTypeFactory } from './type-factory';
2221

2322

@@ -44,7 +43,7 @@ function convertType(typeFn: Function, metadata: TypeMetadata, isInput: boolean,
4443
returnType = graphql.GraphQLString;
4544
} else if (typeFn === Boolean) {
4645
returnType = graphql.GraphQLBoolean;
47-
} else if (typeFn && typeFn.prototype && Reflect.hasMetadata(GQ_OBJECT_METADATA_KEY, typeFn.prototype)) {
46+
} else if (typeFn && typeFn.prototype && getMetadataArgsStorage().filterObjectTypeByClass(typeFn).length > 0) {
4847
// recursively call objectFactory
4948
returnType = objectTypeFactory(typeFn, isInput);
5049
}
@@ -53,7 +52,7 @@ function convertType(typeFn: Function, metadata: TypeMetadata, isInput: boolean,
5352

5453
if (returnType && returnType.prototype && getMetadataArgsStorage().filterUnionTypeByClass(returnType).length > 0) {
5554
returnType = unionTypeFactory(returnType, isInput);
56-
} else if (returnType && returnType.prototype && Reflect.hasMetadata(GQ_OBJECT_METADATA_KEY, returnType.prototype)) {
55+
} else if (returnType && returnType.prototype && getMetadataArgsStorage().filterObjectTypeByClass(returnType).length > 0) {
5756
// recursively call objectFactory
5857
returnType = objectTypeFactory(returnType, isInput);
5958
} else if (returnType && returnType.prototype && getMetadataArgsStorage().filterEnumsByClass(returnType).length > 0) {

src/metadata-builder/metadata-args.storage.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
EnumTypeArg,
33
EnumValueArg,
44
UnionTypeArgs,
5+
ObjectTypeArg,
56
} from '../metadata/args';
67

78
/**
@@ -20,6 +21,7 @@ export class MetadataArgsStorage {
2021
enums: EnumTypeArg[] = [];
2122
enumValues: EnumValueArg[] = [];
2223
union: UnionTypeArgs[] = [];
24+
objects: ObjectTypeArg[] = [];
2325

2426
filterEnumsByClass(target: any): EnumTypeArg[] {
2527
return this.enums.filter(item => item.target === target);
@@ -32,5 +34,9 @@ export class MetadataArgsStorage {
3234
filterUnionTypeByClass(target: any): UnionTypeArgs[] {
3335
return this.union.filter(item => item.target === target);
3436
}
37+
38+
filterObjectTypeByClass(target: any): ObjectTypeArg[] {
39+
return this.objects.filter(item => item.target === target);
40+
}
3541
}
3642

0 commit comments

Comments
 (0)