Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 0 additions & 88 deletions src/decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ export const GQ_QUERY_KEY = 'gq_query';
export const GQ_MUTATION_KEY = 'gq_mutation';
export const GQ_SUBSCRIPTION_KEY = 'gq_subscription';
export const GQ_FIELDS_KEY = 'gq_fields';
export const GQ_VALUES_KEY = 'gq_values';
export const GQ_OBJECT_METADATA_KEY = 'gq_object_type';
export const GQ_ENUM_METADATA_KEY = 'gq_enum_type';
export const GQ_DESCRIPTION_KEY = 'gq_description';

export interface TypeMetadata {
Expand Down Expand Up @@ -54,18 +52,6 @@ export interface ObjectTypeMetadata {
isInput?: boolean;
}

export interface EnumTypeMetadata {
name?: string;
description?: string;
values?: EnumValueMetadata[];
}

export interface EnumValueMetadata {
name: string;
value?: any;
description?: string;
}

export interface DefaultOption {
description?: string;
}
Expand Down Expand Up @@ -119,32 +105,6 @@ function createOrSetObjectTypeMetadata(target: any, metadata: ObjectTypeMetadata
}
}

function createOrSetEnumTypeMetadata(target: any, metadata: EnumTypeMetadata) {
if (!Reflect.hasMetadata(GQ_ENUM_METADATA_KEY, target.prototype)) {
let mergedMetadata = mergeDescriptionMetadata(target, metadata);
Reflect.defineMetadata(GQ_ENUM_METADATA_KEY, mergedMetadata, target.prototype);
} else {
const originalMetadata = Reflect.getMetadata(GQ_ENUM_METADATA_KEY, target.prototype) as EnumTypeMetadata;
Object.assign(originalMetadata, metadata);
}
}

function createOrSetValueTypeMetadata(target: any, metadata: EnumValueMetadata) {
let valueDefs: EnumValueMetadata[];
if (!Reflect.hasMetadata(GQ_VALUES_KEY, target)) {
valueDefs = [];
Reflect.defineMetadata(GQ_VALUES_KEY, valueDefs, target);
} else {
valueDefs = Reflect.getMetadata(GQ_VALUES_KEY, target);
}
const def = valueDefs.find(d => d.name === metadata.name);
if (!def) {
let propertyDescriptionMetadata = getPropertyDescriptionMetadata(target, metadata.name);
Object.assign(metadata, propertyDescriptionMetadata);
valueDefs.push(metadata);
}
}

function createOrSetFieldTypeMetadata(target: any, metadata: FieldTypeMetadata) {
let fieldDefs: FieldTypeMetadata[];
if (!Reflect.hasMetadata(GQ_FIELDS_KEY, target)) {
Expand Down Expand Up @@ -202,13 +162,6 @@ export function getFieldMetadata(target: any, name: string) {
return (<FieldTypeMetadata[]>Reflect.getMetadata(GQ_FIELDS_KEY, target)).find(m => m.name === name);
}

export function getValueMetadata(target: any, name: string) {
if (!Reflect.hasMetadata(GQ_VALUES_KEY, target)) {
return null;
}
return (<EnumValueMetadata[]>Reflect.getMetadata(GQ_VALUES_KEY, target)).find(m => m.name === name);
}

function setArgumentMetadata(target: any, propertyKey: any, index: number, metadata: ArgumentMetadata) {
const fieldMetadata = getFieldMetadata(target, propertyKey);
if (fieldMetadata && fieldMetadata.args && fieldMetadata.args[index]) {
Expand Down Expand Up @@ -258,11 +211,6 @@ function setDescriptionMetadata(description: string, target: any, propertyKey: s
name: propertyKey,
description: description,
});
} else if (getValueMetadata(target, propertyKey) != null) {
createOrSetValueTypeMetadata(target, {
name: propertyKey,
description: description,
});
} else {
createPropertyDescriptionMetadata(target, description, propertyKey);
}
Expand All @@ -271,10 +219,6 @@ function setDescriptionMetadata(description: string, target: any, propertyKey: s
createOrSetObjectTypeMetadata(target, {
description: description,
});
} else if (Reflect.hasMetadata(GQ_ENUM_METADATA_KEY, target.prototype)) {
createOrSetEnumTypeMetadata(target, {
description: description,
});
} else {
createDescriptionMetadata(target, description);
}
Expand Down Expand Up @@ -321,22 +265,6 @@ function setPaginationMetadata(target: any, propertyKey: string, methodDescripto
};
}


export function EnumType(option?: DefaultOption) {
return function (target: any) {
createOrSetEnumTypeMetadata(target, {
name: target.name,
});

if (option) {
// description
if (option.description) {
setDescriptionMetadata(option.description, target);
}
}
} as Function;
}

export function ObjectType(option?: DefaultOption) {
return function (target: any) {
createOrSetObjectTypeMetadata(target, {
Expand Down Expand Up @@ -415,22 +343,6 @@ export function Field(option?: FieldOption) {
} as Function;
}

export function Value(value?: any, option?: DefaultOption) {
return function (target: any, propertyKey: any) {
createOrSetValueTypeMetadata(target, {
name: propertyKey,
value: value,
});

if (option) {
// description
if (option.description) {
setDescriptionMetadata(option.description, target, propertyKey);
}
}
} as Function;
}

export function NonNull() {
return function (target: any, propertyKey: any, index?: number) {
setNonNullMetadata(target, propertyKey, index);
Expand Down
48 changes: 48 additions & 0 deletions src/decorator/enum-type.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { EnumOption, EnumValueOption } from '../metadata';
import { getMetadataArgsStorage } from '../metadata-builder';

/**
* It can be used just like {@link ObjectType} in order to create {@link GraphQLEnumType} objects.
* See [GraphQL Documentation - Enum Types]{@http://graphql.org/learn/schema/#enumeration-types}
*
* @param option Options for a Enum Type
*/
export function EnumType(option?: EnumOption) {
return function (target: any) {
getMetadataArgsStorage().enums.push({
target: target,
name: target.name,
description: option ? option.description : null,
});
} as Function;
}

/**
* Used to define a value for an {@link EnumType} definition.
*
* Example usage:
*
* ```typescript
* @EnumType()
* class MyEnum {
* @Value('1', {description: 'Value One'})
* VALUE_ONE: string;
*
* @Value('2', {description: 'Value Two'})
* VALUE_TWO: string;
* }
*```
*
* @param value Value to be assigned to the property at schema level
* @param option Options for a Enum Value
*/
export function Value(value: any, option?: EnumValueOption) {
return function (target: any, propertyKey: any, methodDescriptor: any) {
getMetadataArgsStorage().enumValues.push({
target: target,
name: propertyKey,
value: value,
description: option ? option.description : null,
});
} as Function;
}
1 change: 1 addition & 0 deletions src/decorator/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './enum-type.decorator';
export * from './union-type.decorator';
9 changes: 6 additions & 3 deletions src/decorator/union-type.decorator.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { MetadataStorage } from '../metadata-storage';
import { getMetadataArgsStorage } from '../metadata-builder';
import { UnionOption } from '../metadata';

/**
* Union Type. ref: http://graphql.org/learn/schema/#union-types
* Union Type.
* See [GraphQL Documentation - Union Types]{@link http://graphql.org/learn/schema/#union-types}
*
* @param option Options for a Union Type
*/
export function UnionType<T>(option: UnionOption<T>) {
return function (target: any) {
MetadataStorage.addUnionMetadata({
getMetadataArgsStorage().union.push({
target: target,
name: target.name,
types: option.types,
resolver: option.resolver,
Expand Down
32 changes: 0 additions & 32 deletions src/enum.type-factory.ts

This file was deleted.

13 changes: 5 additions & 8 deletions src/field_type_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,21 @@ import {
ArgumentMetadata,
ContextMetadata,
FieldTypeMetadata,
GQ_ENUM_METADATA_KEY,
GQ_FIELDS_KEY,
GQ_OBJECT_METADATA_KEY,
Middleware,
RootMetadata,
TypeMetadata,
} from './decorator';
import { MetadataStorage } from './metadata-storage';
import { getMetadataArgsStorage } from './metadata-builder';

import { SchemaFactoryError, SchemaFactoryErrorType } from './schema_factory';

import { IoCContainer } from './ioc-container';
import { OrderByTypeFactory } from './order-by.type-factory';
import { PaginationType } from './pagination.type';
import { enumTypeFactory } from './enum.type-factory';
import { objectTypeFactory } from './object_type_factory';
import { unionTypeFactory } from './type-factory';
import { unionTypeFactory, enumTypeFactory } from './type-factory';


export interface ResolverHolder {
Expand Down Expand Up @@ -53,13 +51,12 @@ function convertType(typeFn: Function, metadata: TypeMetadata, isInput: boolean,
} else {
returnType = metadata.explicitType;

if (returnType && returnType.prototype && MetadataStorage.containsUnionMetadata(returnType.name)) {
returnType = unionTypeFactory(returnType.name, isInput);
if (returnType && returnType.prototype && getMetadataArgsStorage().filterUnionTypeByClass(returnType).length > 0) {
returnType = unionTypeFactory(returnType, isInput);
} else if (returnType && returnType.prototype && Reflect.hasMetadata(GQ_OBJECT_METADATA_KEY, returnType.prototype)) {
// recursively call objectFactory
returnType = objectTypeFactory(returnType, isInput);
} else if (returnType && returnType.prototype && Reflect.hasMetadata(GQ_ENUM_METADATA_KEY, returnType.prototype)) {
let enumMetadata = Reflect.getMetadata(GQ_ENUM_METADATA_KEY, returnType.prototype);
} else if (returnType && returnType.prototype && getMetadataArgsStorage().filterEnumsByClass(returnType).length > 0) {
returnType = enumTypeFactory(returnType);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/metadata-builder/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './metadata-args.storage';
export * from './metadata.builder';
36 changes: 36 additions & 0 deletions src/metadata-builder/metadata-args.storage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {
EnumTypeArg,
EnumValueArg,
UnionTypeArgs,
} from '../metadata/args';

/**
* Gets metadata args storage.
* Metadata args storage follows the best practices and stores metadata in a global variable.
*/
export function getMetadataArgsStorage(): MetadataArgsStorage {
if (!(global as any).graphqlSchemaMetadataArgsStorage) {
(global as any).graphqlSchemaMetadataArgsStorage = new MetadataArgsStorage();
}

return (global as any).graphqlSchemaMetadataArgsStorage;
}

export class MetadataArgsStorage {
enums: EnumTypeArg[] = [];
enumValues: EnumValueArg[] = [];
union: UnionTypeArgs[] = [];

filterEnumsByClass(target: any): EnumTypeArg[] {
return this.enums.filter(item => item.target === target);
}

filterEnumValuesByClass(target: any): EnumValueArg[] {
return this.enumValues.filter(item => item.target === target.prototype);
}

filterUnionTypeByClass(target: any): UnionTypeArgs[] {
return this.union.filter(item => item.target === target);
}
}

57 changes: 57 additions & 0 deletions src/metadata-builder/metadata.builder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import {
EnumTypeMetadata,
EnumValueMetadata,
UnionTypeMetadata,
} from '../metadata/types';

import { getMetadataArgsStorage } from './metadata-args.storage';

/**
* Gets metadata builder
* Metadata builder follows the best practices and stores metadata in a global variable.
*/
export function getMetadataBuilder(): MetadataBuilder {
if (!(global as any).graphqlSchemaMetadataBuilder) {
(global as any).graphqlSchemaMetadataBuilder = new MetadataBuilder();
}

return (global as any).graphqlSchemaMetadataBuilder;
}

export class MetadataBuilder {

buildEnumMetadata(target: any): EnumTypeMetadata[] | undefined {
return getMetadataArgsStorage()
.filterEnumsByClass(target)
.map(enumArg => ({
target: enumArg.target,
name: enumArg.name,
description: enumArg.description,
values: this.buildEnumValueMetadata(target),
}));
}

buildUnionTypeMetadata(target: any): UnionTypeMetadata[] | undefined {
return getMetadataArgsStorage()
.filterUnionTypeByClass(target)
.map(unionArg => ({
target: unionArg.target,
name: unionArg.name,
resolver: unionArg.resolver,
types: unionArg.types,
description: unionArg.description,
}));
}

protected buildEnumValueMetadata(target: any): EnumValueMetadata[] | undefined {
return getMetadataArgsStorage()
.filterEnumValuesByClass(target)
.map(enumValueArg => ({
target: enumValueArg.target,
name: enumValueArg.name,
value: enumValueArg.value,
description: enumValueArg.description,
}));
}

}
1 change: 0 additions & 1 deletion src/metadata-storage/index.ts

This file was deleted.

Loading