ing
This commit is contained in:
parent
d08a77a279
commit
4992e39e3f
6
src/ts/@loafer/core/constants/decorator.ts
Normal file
6
src/ts/@loafer/core/constants/decorator.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
export enum DecoratorType {
|
||||
CLASS,
|
||||
PROPERTY,
|
||||
PARAMETER,
|
||||
METHOD,
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
export * from './types';
|
||||
export * from './reflect';
|
|
@ -4,3 +4,6 @@ export const DESIGN_TYPE = 'design:type';
|
|||
export const DESIGN_PARAMTYPES = 'design:paramtypes';
|
||||
// used to access design time return type
|
||||
export const DESIGN_RETURNTYPE = 'design:returntype';
|
||||
|
||||
// used to access design time return type
|
||||
export const REFLECT_META = 'loafer:reflectmeta';
|
||||
|
|
|
@ -1,10 +1,3 @@
|
|||
export type Construtorable<T> = {new(...args: any[]): T};
|
||||
export type ClassType = Object;
|
||||
export type PropertyType = string | symbol;
|
||||
|
||||
export enum DecoratorType {
|
||||
CLASS,
|
||||
PROPERTY,
|
||||
PARAMETER,
|
||||
METHOD,
|
||||
}
|
||||
|
|
90
src/ts/@loafer/core/decorator/Decorator.ts
Normal file
90
src/ts/@loafer/core/decorator/Decorator.ts
Normal file
|
@ -0,0 +1,90 @@
|
|||
import {
|
||||
ClassType,
|
||||
Construtorable,
|
||||
} from '@loafer/core/constants/types';
|
||||
import * as ReflectConstants from '@loafer/core/constants/reflect';
|
||||
import Reflection from '@loafer/core/reflect/Reflection';
|
||||
import Class from '@loafer/core/reflect/Class';
|
||||
import DecoratorType from './DecoratorType';
|
||||
|
||||
export class Decorator {
|
||||
public static create = (Annotation: Construtorable<any>) => {
|
||||
return (...handlerArgs: any[]) => {
|
||||
let annotation = new Annotation(...handlerArgs);
|
||||
|
||||
return (...decoratorArgs: any[]) => {
|
||||
let decoratorType: DecoratorType = Decorator._detectDecoratorType(name, annotation, decoratorArgs);
|
||||
let type = typeof decoratorArgs[0] === 'function' ? decoratorArgs[0].prototype : decoratorArgs[0];
|
||||
|
||||
let reflection: Reflection = Reflect.getMetadata(ReflectConstants.REFLECT_META, type);
|
||||
if (undefined === reflection) {
|
||||
reflection = new Reflection(type);
|
||||
Reflect.defineMetadata(ReflectConstants.REFLECT_META, reflection, type);
|
||||
}
|
||||
|
||||
switch(decoratorType) {
|
||||
case DecoratorType.CLASS:
|
||||
reflection.addClassAnnotation(annotation);
|
||||
return annotation.onClassDecorator.apply(annotation, decoratorArgs);
|
||||
case DecoratorType.PROPERTY:
|
||||
reflection.addPropertyAnnotation(annotation, decoratorArgs[1]);
|
||||
return annotation.onPropertyDecorator.apply(annotation, decoratorArgs);
|
||||
case DecoratorType.METHOD:
|
||||
reflection.addMethodAnnotation(annotation, decoratorArgs[1]);
|
||||
return annotation.onMethodDecorator.apply(annotation, decoratorArgs);
|
||||
case DecoratorType.PARAMETER:
|
||||
reflection.addParameterAnnotation(annotation, decoratorArgs[1], decoratorArgs[2]);
|
||||
return annotation.onParameterDecorator.apply(annotation, decoratorArgs);
|
||||
default:
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
public static get = (targetType: ClassType) => {
|
||||
let reflection: Reflection = Reflect.getMetadata(ReflectConstants.REFLECT_META, targetType);
|
||||
if (undefined === reflection) {
|
||||
return undefined;
|
||||
}
|
||||
return reflection.getClass();
|
||||
}
|
||||
|
||||
private static _detectDecoratorType(name: string, annotation: any, args: any[]): DecoratorType {
|
||||
let params = [];
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (args[i]) {
|
||||
params.push(args[i]);
|
||||
}
|
||||
}
|
||||
const paramCount = params.length;
|
||||
let decoratorType: DecoratorType;
|
||||
|
||||
if (1 === paramCount) {
|
||||
if ('onClassDecorator' in annotation) {
|
||||
throw new Error(`Cannot apply @${name} decorator on Class.`);
|
||||
}
|
||||
decoratorType = DecoratorType.CLASS;
|
||||
} else if (2 === paramCount) {
|
||||
if ('onPropertyDecorator' in annotation) {
|
||||
throw new Error(`Cannot apply @${name} decorator on Property.`);
|
||||
}
|
||||
decoratorType = DecoratorType.PROPERTY;
|
||||
} else if (3 === paramCount) {
|
||||
if(typeof args[2] === 'number') {
|
||||
if ('onParameterDecorator' in annotation) {
|
||||
throw new Error(`Cannot apply @${name} decorator on Parameter.`);
|
||||
}
|
||||
decoratorType = DecoratorType.PARAMETER;
|
||||
} else {
|
||||
if ('onMethodDecorator' in annotation) {
|
||||
throw new Error(`Cannot apply @${name} decorator on Method.`);
|
||||
}
|
||||
decoratorType = DecoratorType.METHOD;
|
||||
}
|
||||
} else {
|
||||
throw new Error(`@${name} decorator is not valid here!`);
|
||||
}
|
||||
|
||||
return decoratorType;
|
||||
}
|
||||
}
|
9
src/ts/@loafer/core/decorator/DecoratorHandler.ts
Normal file
9
src/ts/@loafer/core/decorator/DecoratorHandler.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
export interface DecoratorHandler {
|
||||
onClassDecorator?: <TFunction extends Function>(target: TFunction) => TFunction | void;
|
||||
onPropertyDecorator?: (target: Object, propertyKey: string | symbol) => void;
|
||||
onMethodDecorator?: <T>(target: Object, propertyKey: string | symbol,
|
||||
descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
|
||||
onParameterDecorator?: (target: Object, propertyKey: string | symbol, parameterIndex: number) => void;
|
||||
}
|
||||
|
||||
export default DecoratorHandler;
|
8
src/ts/@loafer/core/decorator/DecoratorType.ts
Normal file
8
src/ts/@loafer/core/decorator/DecoratorType.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
export enum DecoratorType {
|
||||
CLASS = 'Class',
|
||||
PROPERTY = 'Property',
|
||||
METHOD = 'Method',
|
||||
PARAMETER = 'Parameter',
|
||||
}
|
||||
|
||||
export default DecoratorType;
|
3
src/ts/@loafer/core/decorator/index.ts
Normal file
3
src/ts/@loafer/core/decorator/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export * from './Decorator';
|
||||
export * from './DecoratorHandler';
|
||||
export * from './DecoratorType';
|
33
src/ts/@loafer/core/reflect/AnnotatedElement.ts
Normal file
33
src/ts/@loafer/core/reflect/AnnotatedElement.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
import {
|
||||
ClassType,
|
||||
} from '@loafer/core/constants/types';
|
||||
|
||||
export abstract class AnnotatedElement {
|
||||
private _annotationMap: Map<ClassType, any>;
|
||||
|
||||
protected constructor() {
|
||||
this._annotationMap = new Map();
|
||||
}
|
||||
|
||||
public getDeclaredAnnotation(type: ClassType): any {
|
||||
return this._annotationMap.get(type);
|
||||
}
|
||||
public getDeclaredAnnotations(): IterableIterator<any> {
|
||||
return this._annotationMap.values();
|
||||
}
|
||||
|
||||
public addAnnotation(annotation: any): void {
|
||||
const type: ClassType = Object.getPrototypeOf(annotation);
|
||||
this._annotationMap.set(type, annotation);
|
||||
}
|
||||
|
||||
public hasAnnotation(type: ClassType): boolean {
|
||||
return this._annotationMap.has(type);
|
||||
}
|
||||
|
||||
// public abstract getAnnotation(type: ClassType): any;
|
||||
// public abstract getAnnotations(): IterableIterator<any>;
|
||||
|
||||
}
|
||||
|
||||
export default AnnotatedElement;
|
75
src/ts/@loafer/core/reflect/Class.ts
Normal file
75
src/ts/@loafer/core/reflect/Class.ts
Normal file
|
@ -0,0 +1,75 @@
|
|||
import {
|
||||
ClassType,
|
||||
PropertyType,
|
||||
} from '@loafer/core/constants/types';
|
||||
|
||||
import AnnotatedElement from './AnnotatedElement';
|
||||
import Constructor from './Constructor';
|
||||
import Property from './Property';
|
||||
import Method from './Method';
|
||||
|
||||
|
||||
export class Class extends AnnotatedElement {
|
||||
private _type: ClassType;
|
||||
private _name: PropertyType;
|
||||
private _constructor: Constructor;
|
||||
private _properties: Map<PropertyType, Property>;
|
||||
private _methodes: Map<PropertyType, Method>;
|
||||
|
||||
public constructor(type: ClassType, parameterTypes: ClassType[]) {
|
||||
super();
|
||||
this._type = type;
|
||||
this._name = this._type.constructor.name;
|
||||
this._constructor = new Constructor(parameterTypes);
|
||||
this._properties = new Map();
|
||||
this._methodes = new Map();
|
||||
}
|
||||
|
||||
public get Type(): ClassType {
|
||||
return this._type;
|
||||
}
|
||||
|
||||
public get Name(): PropertyType {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
public get Constructor(): Constructor {
|
||||
return this._constructor;
|
||||
}
|
||||
|
||||
public addProperty(propertyKey: PropertyType, type: ClassType): Property {
|
||||
if (this._properties.has(propertyKey)) {
|
||||
throw new Error(`Property[${propertyKey}:${type.constructor.name}] on Class[${this._name}] is exist already`);
|
||||
}
|
||||
let proerty = new Property(type, propertyKey);
|
||||
this._properties.set(propertyKey, proerty);
|
||||
return proerty;
|
||||
}
|
||||
|
||||
public getProperty(propertyKey: PropertyType): Property {
|
||||
return this._properties.get(propertyKey);
|
||||
}
|
||||
|
||||
public hasProperty(propertyKey: PropertyType): boolean {
|
||||
return this._properties.has(propertyKey);
|
||||
}
|
||||
|
||||
public addMethod(propertyKey: PropertyType, parameterTypes: ClassType[], returnType: ClassType): Method {
|
||||
if (this._methodes.has(propertyKey)) {
|
||||
throw new Error(`Method[${propertyKey}:${returnType.constructor.name}] on Class[${this._name}] is exist already`);
|
||||
}
|
||||
let method = new Method(propertyKey, parameterTypes, returnType);
|
||||
this._methodes.set(propertyKey, method);
|
||||
return method;
|
||||
}
|
||||
|
||||
public getMethod(propertyKey: PropertyType): Method {
|
||||
return this._methodes.get(propertyKey);
|
||||
}
|
||||
|
||||
public hasMethod(propertyKey: PropertyType): boolean {
|
||||
return this._methodes.has(propertyKey);
|
||||
}
|
||||
}
|
||||
|
||||
export default Class;
|
15
src/ts/@loafer/core/reflect/Constructor.ts
Normal file
15
src/ts/@loafer/core/reflect/Constructor.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import {
|
||||
ClassType,
|
||||
} from '@loafer/core/constants/types';
|
||||
|
||||
import Executable from '@loafer/core/reflect/Executable';
|
||||
|
||||
|
||||
export class Constructor extends Executable {
|
||||
|
||||
public constructor(parameterTypes: ClassType[]) {
|
||||
super(parameterTypes);
|
||||
}
|
||||
}
|
||||
|
||||
export default Constructor;
|
30
src/ts/@loafer/core/reflect/Executable.ts
Normal file
30
src/ts/@loafer/core/reflect/Executable.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import {
|
||||
ClassType,
|
||||
} from '@loafer/core/constants/types';
|
||||
|
||||
import AnnotatedElement from './AnnotatedElement';
|
||||
import Parameter from '@loafer/core/reflect/Parameter';
|
||||
|
||||
export abstract class Executable extends AnnotatedElement {
|
||||
protected _parameters: Parameter[];
|
||||
|
||||
public constructor(parameterTypes: ClassType[]) {
|
||||
super();
|
||||
|
||||
this._parameters = [];
|
||||
parameterTypes.forEach((currentValue, index, array) => {
|
||||
this._parameters.push(new Parameter(currentValue, index));
|
||||
});
|
||||
}
|
||||
|
||||
public get Parameters(): Parameter[] {
|
||||
return this._parameters;
|
||||
}
|
||||
|
||||
public getParameter(index: number): Parameter {
|
||||
return this._parameters[index];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Executable;
|
32
src/ts/@loafer/core/reflect/Method.ts
Normal file
32
src/ts/@loafer/core/reflect/Method.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
import {
|
||||
ClassType,
|
||||
PropertyType,
|
||||
} from '@loafer/core/constants/types';
|
||||
|
||||
import Executable from '@loafer/core/reflect/Executable';
|
||||
|
||||
|
||||
export class Method extends Executable {
|
||||
private _name: PropertyType;
|
||||
private _returnType: ClassType;
|
||||
|
||||
public constructor(name: PropertyType, parameterTypes: ClassType[], returnType: ClassType) {
|
||||
super(parameterTypes);
|
||||
this._name = name;
|
||||
this._returnType = returnType;
|
||||
}
|
||||
|
||||
public get Name(): PropertyType {
|
||||
return this._name;
|
||||
}
|
||||
public get ReturnType(): ClassType {
|
||||
return this._returnType;
|
||||
}
|
||||
|
||||
public set ReturnType(returnType: ClassType) {
|
||||
this._returnType = returnType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Method;
|
29
src/ts/@loafer/core/reflect/Parameter.ts
Normal file
29
src/ts/@loafer/core/reflect/Parameter.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import {
|
||||
ClassType,
|
||||
} from '@loafer/core/constants/types';
|
||||
|
||||
import AnnotatedElement from './AnnotatedElement';
|
||||
import Constructor from './Constructor';
|
||||
|
||||
|
||||
export class Parameter extends AnnotatedElement {
|
||||
private _type: ClassType;
|
||||
private _index: number;
|
||||
|
||||
public constructor(type: ClassType, index: number) {
|
||||
super();
|
||||
this._type = type;
|
||||
this._index = index;
|
||||
}
|
||||
|
||||
public get Type(): ClassType {
|
||||
return this._type;
|
||||
}
|
||||
|
||||
public get Index(): number {
|
||||
return this._index;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Parameter;
|
29
src/ts/@loafer/core/reflect/Property.ts
Normal file
29
src/ts/@loafer/core/reflect/Property.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import {
|
||||
ClassType,
|
||||
PropertyType,
|
||||
} from '@loafer/core/constants/types';
|
||||
|
||||
import AnnotatedElement from './AnnotatedElement';
|
||||
import Constructor from './Constructor';
|
||||
|
||||
|
||||
export class Property extends AnnotatedElement {
|
||||
private _type: ClassType;
|
||||
private _name: PropertyType;
|
||||
|
||||
public constructor(type: ClassType, name: PropertyType) {
|
||||
super();
|
||||
this._type = type;
|
||||
this._name = name;
|
||||
}
|
||||
|
||||
public get Name(): PropertyType {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
public get Type(): ClassType {
|
||||
return this._type;
|
||||
}
|
||||
}
|
||||
|
||||
export default Property;
|
106
src/ts/@loafer/core/reflect/Reflection.ts
Normal file
106
src/ts/@loafer/core/reflect/Reflection.ts
Normal file
|
@ -0,0 +1,106 @@
|
|||
import {
|
||||
ClassType,
|
||||
PropertyType,
|
||||
} from '@loafer/core/constants/types';
|
||||
|
||||
import * as ReflectConstants from '@loafer/core/constants/reflect';
|
||||
|
||||
import AnnotatedElement from './AnnotatedElement';
|
||||
import Class from './Class';
|
||||
|
||||
export class Reflection {
|
||||
private _clazz: Class;
|
||||
|
||||
public constructor(type: ClassType) {
|
||||
let parameterTypes: any[] = Reflect.getMetadata(ReflectConstants.DESIGN_PARAMTYPES, type.constructor);
|
||||
|
||||
this._clazz = new Class(type, this.convertParamTypes(parameterTypes));
|
||||
}
|
||||
|
||||
/**
|
||||
* getClass
|
||||
*/
|
||||
public getClass(): Class {
|
||||
return this._clazz;
|
||||
}
|
||||
|
||||
public addClassAnnotation(annotation: any): void {
|
||||
let parameterTypes: any[] = Reflect.getMetadata(ReflectConstants.DESIGN_PARAMTYPES, this._clazz.Type);
|
||||
|
||||
const {valid, name} = this.validateAnnotation(annotation, this._clazz);
|
||||
if (!valid) {
|
||||
throw new Error(`Cannot apply @${name} decorator multiple times on Class[${this._clazz.Name}].`);
|
||||
}
|
||||
|
||||
this._clazz.addAnnotation(annotation);
|
||||
}
|
||||
public addPropertyAnnotation(annotation: any, propertyKey: PropertyType): void {
|
||||
let propertyType: any = Reflect.getMetadata(ReflectConstants.DESIGN_TYPE, this._clazz.Type, propertyKey);
|
||||
|
||||
let property = this._clazz.getProperty(propertyKey);
|
||||
if (undefined === property) {
|
||||
property = this._clazz.addProperty(propertyKey, propertyType.prototype);
|
||||
}
|
||||
|
||||
const {valid, name} = this.validateAnnotation(annotation, property);
|
||||
if (!valid) {
|
||||
throw new Error(`Cannot apply @${name} decorator multiple times on Property[${this._clazz.Name}:${propertyKey}].`);
|
||||
}
|
||||
|
||||
property.addAnnotation(annotation);
|
||||
}
|
||||
public addMethodAnnotation(annotation: any, propertyKey: PropertyType): void {
|
||||
let parameterTypes: any[] = Reflect.getMetadata(ReflectConstants.DESIGN_PARAMTYPES, this._clazz.Type, propertyKey);
|
||||
let returnType: any = Reflect.getMetadata(ReflectConstants.DESIGN_RETURNTYPE, this._clazz.Type, propertyKey);
|
||||
|
||||
let method = this._clazz.getMethod(propertyKey);
|
||||
if (undefined === method) {
|
||||
method = this._clazz.addMethod(propertyKey, this.convertParamTypes(parameterTypes), returnType.prototype);
|
||||
}
|
||||
|
||||
const {valid, name} = this.validateAnnotation(annotation, method);
|
||||
if (!valid) {
|
||||
throw new Error(`Cannot apply @${name} decorator multiple times on Method[${this._clazz.Name}:${propertyKey}].`);
|
||||
}
|
||||
|
||||
method.addAnnotation(annotation);
|
||||
}
|
||||
public addParameterAnnotation(annotation: any, propertyKey: PropertyType, parameterIndex: number): void {
|
||||
let parameterTypes: any[] = Reflect.getMetadata(ReflectConstants.DESIGN_PARAMTYPES, this._clazz.Type, propertyKey);
|
||||
let returnType: any = Reflect.getMetadata(ReflectConstants.DESIGN_RETURNTYPE, this._clazz.Type, propertyKey);
|
||||
|
||||
let method = this._clazz.getMethod(propertyKey);
|
||||
if (undefined === method) {
|
||||
method = this._clazz.addMethod(propertyKey, this.convertParamTypes(parameterTypes), returnType.prototype);
|
||||
}
|
||||
|
||||
let parameter = method.getParameter(parameterIndex);
|
||||
|
||||
const {valid, name} = this.validateAnnotation(annotation, parameter);
|
||||
if (!valid) {
|
||||
throw new Error(`Cannot apply @${name} decorator multiple times on Parameter[${this._clazz.Name}:${propertyKey}(${parameterIndex}})].`);
|
||||
}
|
||||
|
||||
parameter.addAnnotation(annotation);
|
||||
}
|
||||
|
||||
private validateAnnotation(annotation: any, element: AnnotatedElement): {valid: boolean, name: string} {
|
||||
const annotationType: ClassType = Object.getPrototypeOf(annotation);
|
||||
const name: string = annotationType.constructor.name;
|
||||
|
||||
if (element.hasAnnotation(annotationType)) {
|
||||
return {valid: false, name: name};
|
||||
}
|
||||
return {valid: true, name: name};
|
||||
}
|
||||
|
||||
private convertParamTypes(parameterTypes: any[]): ClassType[] {
|
||||
let returnTypes: ClassType[] = [];
|
||||
parameterTypes.forEach((currentValue, index, array) => {
|
||||
returnTypes.push(currentValue.prototype);
|
||||
});
|
||||
return returnTypes;
|
||||
}
|
||||
}
|
||||
|
||||
export default Reflection;
|
8
src/ts/@loafer/core/reflect/index.ts
Normal file
8
src/ts/@loafer/core/reflect/index.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
export * from './AnnotatedElement';
|
||||
export * from './Class';
|
||||
export * from './Constructor';
|
||||
export * from './Executable';
|
||||
export * from './Method';
|
||||
export * from './Parameter';
|
||||
export * from './Property';
|
||||
export * from './Reflection';
|
|
@ -1,46 +0,0 @@
|
|||
export interface DecoratorFactory {
|
||||
classDecorator?: ClassDecorator;
|
||||
propertyDecorator?: PropertyDecorator;
|
||||
parameterDecorator?: ParameterDecorator;
|
||||
methodDecorator?: MethodDecorator;
|
||||
}
|
||||
|
||||
const createDecorator = (name: string, decoratorFactory: DecoratorFactory) => {
|
||||
return (...args: any[]) => {
|
||||
let params = [];
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (args[i]) {
|
||||
params.push(args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
switch(params.length) {
|
||||
case 1:
|
||||
if (undefined !== decoratorFactory.classDecorator) {
|
||||
return decoratorFactory.classDecorator.apply(this, args);
|
||||
}
|
||||
throw new Error(`Cannot apply @${name} decorator on Class.`);
|
||||
case 2:
|
||||
case 1:
|
||||
if (undefined !== decoratorFactory.propertyDecorator) {
|
||||
return decoratorFactory.propertyDecorator.apply(this, args);
|
||||
}
|
||||
throw new Error(`Cannot apply @${name} decorator on Property.`);
|
||||
case 3:
|
||||
if(typeof args[2] === 'number') {
|
||||
if (undefined !== decoratorFactory.parameterDecorator) {
|
||||
return decoratorFactory.parameterDecorator.apply(this, args);
|
||||
}
|
||||
throw new Error(`Cannot apply @${name} decorator on Parameter.`);
|
||||
}
|
||||
if (undefined !== decoratorFactory.methodDecorator) {
|
||||
return decoratorFactory.methodDecorator.apply(this, args);
|
||||
}
|
||||
throw new Error(`Cannot apply @${name} decorator on Method.`);
|
||||
default:
|
||||
throw new Error(`@${name} decorators are not valid here!`);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default createDecorator;
|
|
@ -1,27 +0,0 @@
|
|||
import {
|
||||
ClassType,
|
||||
} from '@loafer/core/constants';
|
||||
|
||||
export type MetadataDefinable<T> = {new(clazz: ClassType): T};
|
||||
|
||||
const getClassMetadata = <DefinitionType>(clazz: ClassType,
|
||||
metadataKey: any,
|
||||
definitionType: MetadataDefinable<DefinitionType>,
|
||||
isCreate: boolean = false): DefinitionType => {
|
||||
|
||||
let definition: DefinitionType;
|
||||
if (Reflect.hasOwnMetadata(metadataKey, clazz) !== true) {
|
||||
if (!isCreate) {
|
||||
return undefined;
|
||||
}
|
||||
definition = Object.create(definitionType.prototype);
|
||||
definition.constructor.call(definition, clazz);
|
||||
|
||||
Reflect.defineMetadata(metadataKey, definition, clazz);
|
||||
} else {
|
||||
definition = Reflect.getMetadata(metadataKey, clazz);
|
||||
}
|
||||
return definition;
|
||||
};
|
||||
|
||||
export default getClassMetadata;
|
|
@ -2,7 +2,11 @@ import InjectConfig from '@loafer/pouches/decorator/InjectConfig';
|
|||
import InjectDefinition from '@loafer/pouches/definition/InjectDefinition';
|
||||
import createDecorator from '@loafer/core/util/decorators/createDecorator';
|
||||
import { getInjectDefinition } from '@loafer/pouches/util/metadata';
|
||||
|
||||
import {
|
||||
ClassType,
|
||||
DESIGN_TYPE,
|
||||
PropertyType,
|
||||
} from '@loafer/core/constants';
|
||||
const Inject = (injectConfig: InjectConfig = {}) => createDecorator('Inject', {
|
||||
propertyDecorator: (target: Object, propertyKey: string | symbol): void => {
|
||||
let injectDefinition: InjectDefinition = getInjectDefinition(target, InjectDefinition, true);
|
||||
|
@ -16,3 +20,6 @@ const Inject = (injectConfig: InjectConfig = {}) => createDecorator('Inject', {
|
|||
});
|
||||
|
||||
export default Inject;
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user