From 9dfef7030d19527ab2f08f096fdda32f0c028bde Mon Sep 17 00:00:00 2001 From: Sylvain Boulade Date: Wed, 8 Jan 2020 17:27:14 +0100 Subject: [PATCH] Add Extensions metadata Decorator --- src/decorators/Extensions.ts | 15 +++++++++++++++ src/decorators/index.ts | 1 + src/metadata/definitions/extensions-metadata.ts | 5 +++++ src/metadata/definitions/field-metadata.ts | 1 + src/metadata/definitions/index.ts | 1 + src/metadata/definitions/resolver-metadata.ts | 1 + src/metadata/metadata-storage.ts | 15 +++++++++++++++ src/schema/schema-generator.ts | 3 +++ 8 files changed, 42 insertions(+) create mode 100644 src/decorators/Extensions.ts create mode 100644 src/metadata/definitions/extensions-metadata.ts diff --git a/src/decorators/Extensions.ts b/src/decorators/Extensions.ts new file mode 100644 index 000000000..ca94aa172 --- /dev/null +++ b/src/decorators/Extensions.ts @@ -0,0 +1,15 @@ +import { SymbolKeysNotSupportedError } from "../errors"; +import { getMetadataStorage } from "../metadata/getMetadataStorage"; + +export function Extensions(extensions: Record): MethodDecorator | PropertyDecorator { + return (target, propertyKey, descriptor) => { + if (typeof propertyKey === "symbol") { + throw new SymbolKeysNotSupportedError(); + } + getMetadataStorage().collectExtensionsMetadata({ + target: target.constructor, + fieldName: propertyKey, + extensions, + }); + }; +} diff --git a/src/decorators/index.ts b/src/decorators/index.ts index 3d2c77065..720d8f11c 100644 --- a/src/decorators/index.ts +++ b/src/decorators/index.ts @@ -6,6 +6,7 @@ export { createParamDecorator } from "./createParamDecorator"; export { createMethodDecorator } from "./createMethodDecorator"; export { Ctx } from "./Ctx"; export { Directive } from "./Directive"; +export { Extensions } from "./Extensions"; export { registerEnumType } from "./enums"; export { Field, FieldOptions } from "./Field"; export { FieldResolver } from "./FieldResolver"; diff --git a/src/metadata/definitions/extensions-metadata.ts b/src/metadata/definitions/extensions-metadata.ts new file mode 100644 index 000000000..376c5b94a --- /dev/null +++ b/src/metadata/definitions/extensions-metadata.ts @@ -0,0 +1,5 @@ +export interface ExtensionsMetadata { + target: Function; + fieldName: string; + extensions: Record; +} diff --git a/src/metadata/definitions/field-metadata.ts b/src/metadata/definitions/field-metadata.ts index 0c0855cf7..4398860c5 100644 --- a/src/metadata/definitions/field-metadata.ts +++ b/src/metadata/definitions/field-metadata.ts @@ -17,5 +17,6 @@ export interface FieldMetadata { roles?: any[]; middlewares?: Array>; directives?: DirectiveMetadata[]; + extensions?: Record; simple?: boolean; } diff --git a/src/metadata/definitions/index.ts b/src/metadata/definitions/index.ts index 70a7d6ea9..ff67f5906 100644 --- a/src/metadata/definitions/index.ts +++ b/src/metadata/definitions/index.ts @@ -2,6 +2,7 @@ export * from "./authorized-metadata"; export * from "./class-metadata"; export * from "./directive-metadata"; export * from "./enum-metadata"; +export * from "./extensions-metadata"; export * from "./field-metadata"; export * from "./middleware-metadata"; export * from "./param-metadata"; diff --git a/src/metadata/definitions/resolver-metadata.ts b/src/metadata/definitions/resolver-metadata.ts index be349ba34..43c0845a9 100644 --- a/src/metadata/definitions/resolver-metadata.ts +++ b/src/metadata/definitions/resolver-metadata.ts @@ -22,6 +22,7 @@ export interface BaseResolverMetadata { roles?: any[]; middlewares?: Array>; directives?: DirectiveMetadata[]; + extensions?: Record; } export interface ResolverMetadata extends BaseResolverMetadata { diff --git a/src/metadata/metadata-storage.ts b/src/metadata/metadata-storage.ts index 74b3c2d0c..115605e99 100644 --- a/src/metadata/metadata-storage.ts +++ b/src/metadata/metadata-storage.ts @@ -1,6 +1,7 @@ import { ResolverMetadata, ClassMetadata, + ExtensionsMetadata, FieldMetadata, ParamMetadata, FieldResolverMetadata, @@ -40,6 +41,7 @@ export class MetadataStorage { middlewares: MiddlewareMetadata[] = []; classDirectives: DirectiveClassMetadata[] = []; fieldDirectives: DirectiveFieldMetadata[] = []; + extensions: ExtensionsMetadata[] = []; private resolverClasses: ResolverClassMetadata[] = []; private fields: FieldMetadata[] = []; @@ -108,6 +110,10 @@ export class MetadataStorage { this.fieldDirectives.push(definition); } + collectExtensionsMetadata(definition: ExtensionsMetadata) { + this.extensions.push(definition); + } + build() { // TODO: disable next build attempts @@ -143,6 +149,7 @@ export class MetadataStorage { this.middlewares = []; this.classDirectives = []; this.fieldDirectives = []; + this.extensions = []; this.resolverClasses = []; this.fields = []; @@ -196,6 +203,7 @@ export class MetadataStorage { def.directives = this.fieldDirectives .filter(it => it.target === def.target && it.fieldName === def.methodName) .map(it => it.directive); + def.extensions = this.findExtensions(def.target, def.methodName); }); } @@ -206,6 +214,7 @@ export class MetadataStorage { def.directives = this.fieldDirectives .filter(it => it.target === def.target && it.fieldName === def.methodName) .map(it => it.directive); + def.extensions = this.findExtensions(def.target, def.methodName); def.getObjectType = def.kind === "external" ? this.resolverClasses.find(resolver => resolver.target === def.target)!.getObjectType @@ -286,4 +295,10 @@ export class MetadataStorage { } return authorizedField.roles; } + + private findExtensions(target: Function, fieldName: string): Record { + return this.extensions + .filter(entry => entry.target === target && entry.fieldName === fieldName) + .reduce((extensions, entry) => ({ ...extensions, ...entry.extensions }), {}); + } } diff --git a/src/schema/schema-generator.ts b/src/schema/schema-generator.ts index f649d1b33..c6cc01b56 100644 --- a/src/schema/schema-generator.ts +++ b/src/schema/schema-generator.ts @@ -330,6 +330,7 @@ export abstract class SchemaGenerator { deprecationReason: field.deprecationReason, astNode: getFieldDefinitionNode(field.name, type, field.directives), extensions: { + ...field.extensions, complexity: field.complexity, }, }; @@ -399,6 +400,7 @@ export abstract class SchemaGenerator { type, defaultValue: field.typeOptions.defaultValue, astNode: getInputValueDefinitionNode(field.name, type, field.directives), + extensions: field.extensions, }; return fieldsMap; }, @@ -497,6 +499,7 @@ export abstract class SchemaGenerator { deprecationReason: handler.deprecationReason, astNode: getFieldDefinitionNode(handler.schemaName, type, handler.directives), extensions: { + ...handler.extensions, complexity: handler.complexity, }, };