Skip to content
This repository has been archived by the owner on Mar 23, 2023. It is now read-only.

Commit

Permalink
Add Extensions metadata Decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
hihuz committed Jan 9, 2020
1 parent fe6b306 commit be3c0be
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/decorators/Extensions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { MethodAndPropDecorator } from "./types";
import { SymbolKeysNotSupportedError } from "../errors";
import { getMetadataStorage } from "../metadata/getMetadataStorage";

export function Extensions(
extensions: Record<string, any>,
): MethodAndPropDecorator & ClassDecorator;
export function Extensions(
extensions: Record<string, any>,
): MethodDecorator | PropertyDecorator | ClassDecorator {
return (targetOrPrototype, propertyKey, descriptor) => {
if (typeof propertyKey === "symbol") {
throw new SymbolKeysNotSupportedError();
}
if (propertyKey) {
getMetadataStorage().collectExtensionsFieldMetadata({
target: targetOrPrototype.constructor,
fieldName: propertyKey,
extensions,
});
} else {
getMetadataStorage().collectExtensionsClassMetadata({
target: targetOrPrototype as Function,
extensions,
});
}
};
}
1 change: 1 addition & 0 deletions src/decorators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
1 change: 1 addition & 0 deletions src/metadata/definitions/class-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ export interface ClassMetadata {
description?: string;
isAbstract?: boolean;
directives?: DirectiveMetadata[];
extensions?: Record<string, any>;
simpleResolvers?: boolean;
}
10 changes: 10 additions & 0 deletions src/metadata/definitions/extensions-metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export interface ExtensionsClassMetadata {
target: Function;
extensions: Record<string, any>;
}

export interface ExtensionsFieldMetadata {
target: Function;
fieldName: string;
extensions: Record<string, any>;
}
1 change: 1 addition & 0 deletions src/metadata/definitions/field-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ export interface FieldMetadata {
roles?: any[];
middlewares?: Array<Middleware<any>>;
directives?: DirectiveMetadata[];
extensions?: Record<string, any>;
simple?: boolean;
}
1 change: 1 addition & 0 deletions src/metadata/definitions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
1 change: 1 addition & 0 deletions src/metadata/definitions/resolver-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface BaseResolverMetadata {
roles?: any[];
middlewares?: Array<Middleware<any>>;
directives?: DirectiveMetadata[];
extensions?: Record<string, any>;
}

export interface ResolverMetadata extends BaseResolverMetadata {
Expand Down
33 changes: 33 additions & 0 deletions src/metadata/metadata-storage.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {
ResolverMetadata,
ClassMetadata,
ExtensionsClassMetadata,
ExtensionsFieldMetadata,
FieldMetadata,
ParamMetadata,
FieldResolverMetadata,
Expand All @@ -20,6 +22,7 @@ import {
mapMiddlewareMetadataToArray,
mapSuperFieldResolverHandlers,
ensureReflectMetadataExists,
flattenExtensions,
} from "./utils";
import { ObjectClassMetadata } from "./definitions/object-class-metdata";
import { InterfaceClassMetadata } from "./definitions/interface-class-metadata";
Expand All @@ -40,6 +43,8 @@ export class MetadataStorage {
middlewares: MiddlewareMetadata[] = [];
classDirectives: DirectiveClassMetadata[] = [];
fieldDirectives: DirectiveFieldMetadata[] = [];
classExtensions: ExtensionsClassMetadata[] = [];
fieldExtensions: ExtensionsFieldMetadata[] = [];

private resolverClasses: ResolverClassMetadata[] = [];
private fields: FieldMetadata[] = [];
Expand Down Expand Up @@ -108,6 +113,13 @@ export class MetadataStorage {
this.fieldDirectives.push(definition);
}

collectExtensionsClassMetadata(definition: ExtensionsClassMetadata) {
this.classExtensions.push(definition);
}
collectExtensionsFieldMetadata(definition: ExtensionsFieldMetadata) {
this.fieldExtensions.push(definition);
}

build() {
// TODO: disable next build attempts

Expand Down Expand Up @@ -143,6 +155,8 @@ export class MetadataStorage {
this.middlewares = [];
this.classDirectives = [];
this.fieldDirectives = [];
this.classExtensions = [];
this.fieldExtensions = [];

this.resolverClasses = [];
this.fields = [];
Expand All @@ -167,6 +181,7 @@ export class MetadataStorage {
field.directives = this.fieldDirectives
.filter(it => it.target === field.target && it.fieldName === field.name)
.map(it => it.directive);
field.extensions = this.findFieldExtensions(field.target, field.name);
});
def.fields = fields;
}
Expand All @@ -175,6 +190,9 @@ export class MetadataStorage {
.filter(it => it.target === def.target)
.map(it => it.directive);
}
if (!def.extensions) {
def.extensions = this.findClassExtensions(def.target);
}
});
}

Expand All @@ -196,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.findFieldExtensions(def.target, def.methodName);
});
}

Expand All @@ -206,6 +225,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.findFieldExtensions(def.target, def.methodName);
def.getObjectType =
def.kind === "external"
? this.resolverClasses.find(resolver => resolver.target === def.target)!.getObjectType
Expand Down Expand Up @@ -236,6 +256,7 @@ export class MetadataStorage {
middlewares: def.middlewares!,
params: def.params!,
directives: def.directives,
extensions: def.extensions,
};
this.collectClassFieldMetadata(fieldMetadata);
objectType.fields!.push(fieldMetadata);
Expand Down Expand Up @@ -286,4 +307,16 @@ export class MetadataStorage {
}
return authorizedField.roles;
}

private findClassExtensions(target: Function): Record<string, any> {
return this.classExtensions
.filter(entry => entry.target === target)
.reduce(flattenExtensions, {});
}

private findFieldExtensions(target: Function, fieldName: string): Record<string, any> {
return this.fieldExtensions
.filter(entry => entry.target === target && entry.fieldName === fieldName)
.reduce(flattenExtensions, {});
}
}
9 changes: 9 additions & 0 deletions src/metadata/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {
BaseResolverMetadata,
MiddlewareMetadata,
FieldResolverMetadata,
ExtensionsClassMetadata,
ExtensionsFieldMetadata,
} from "./definitions";
import { Middleware } from "../interfaces/Middleware";
import { isThrowing } from "../helpers/isThrowing";
Expand Down Expand Up @@ -57,3 +59,10 @@ export function ensureReflectMetadataExists() {
throw new ReflectMetadataMissingError();
}
}

export function flattenExtensions(
extensions: Record<string, any>,
entry: ExtensionsClassMetadata | ExtensionsFieldMetadata,
): Record<string, any> {
return { ...extensions, ...entry.extensions };
}
5 changes: 5 additions & 0 deletions src/schema/schema-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ export abstract class SchemaGenerator {
name: objectType.name,
description: objectType.description,
astNode: getObjectTypeDefinitionNode(objectType.name, objectType.directives),
extensions: objectType.extensions,
interfaces: () => {
let interfaces = interfaceClasses.map<GraphQLInterfaceType>(
interfaceClass =>
Expand Down Expand Up @@ -330,6 +331,7 @@ export abstract class SchemaGenerator {
deprecationReason: field.deprecationReason,
astNode: getFieldDefinitionNode(field.name, type, field.directives),
extensions: {
...field.extensions,
complexity: field.complexity,
},
};
Expand Down Expand Up @@ -379,6 +381,7 @@ export abstract class SchemaGenerator {
type: new GraphQLInputObjectType({
name: inputType.name,
description: inputType.description,
extensions: inputType.extensions,
fields: () => {
let fields = inputType.fields!.reduce<GraphQLInputFieldConfigMap>(
(fieldsMap, field) => {
Expand All @@ -399,6 +402,7 @@ export abstract class SchemaGenerator {
type,
defaultValue: field.typeOptions.defaultValue,
astNode: getInputValueDefinitionNode(field.name, type, field.directives),
extensions: field.extensions,
};
return fieldsMap;
},
Expand Down Expand Up @@ -497,6 +501,7 @@ export abstract class SchemaGenerator {
deprecationReason: handler.deprecationReason,
astNode: getFieldDefinitionNode(handler.schemaName, type, handler.directives),
extensions: {
...handler.extensions,
complexity: handler.complexity,
},
};
Expand Down

0 comments on commit be3c0be

Please sign in to comment.