first-npm-package-nicule
Version:
This isi first npm package
52 lines (39 loc) • 1.82 kB
text/typescript
import { Injectable, Injector, Type } from '@angular/core';
import { Hypermedia } from 'first-npm-package-nicule/core';
import { BindDecorator } from '../binders/bind.decorator';
import { getPropertyMetadata } from '../google-decorator-factories';
class ReflectiveModelBinder {
binders: Array<{ name: string; annotation: BindDecorator; }>;
constructor(private type: Type<any>,
private injector: Injector) {
this.binders = this.getPropertyBinders(type);
}
getPropertyBinders<T>(type: Type<T>): Array<{ name: string; annotation: BindDecorator; }> {
const metadata = getPropertyMetadata(type) || {};
return Object
.keys(metadata)
.map(name => ({ name, annotation: (metadata[name].find(annotation => annotation.binding) || {}).binding }))
.filter(({ annotation }) => annotation)
.sort((a, b) => {
if (a.annotation.priority === b.annotation.priority) {
return 0;
}
return a.annotation.priority < b.annotation.priority ? -1 : 1;
});
}
bind<T>(hypermedia: Hypermedia): T {
const typeInstance = new this.type();
this.binders.forEach(binder => {
const bindingResult = binder.annotation.bind(hypermedia, binder.name, this.injector, typeInstance);
typeInstance[binder.name] = bindingResult === undefined ? typeInstance[binder.name] : bindingResult;
});
return typeInstance as T;
}
}
()
export class ReflectiveModelBinderFactory {
constructor(private injector: Injector) { }
make<T>(type: Type<T>): ReflectiveModelBinder {
return new ReflectiveModelBinder(type, this.injector);
}
}