UNPKG

first-npm-package-nicule

Version:

This isi first npm package

52 lines (39 loc) 1.82 kB
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; } } @Injectable() export class ReflectiveModelBinderFactory { constructor(private injector: Injector) { } make<T>(type: Type<T>): ReflectiveModelBinder { return new ReflectiveModelBinder(type, this.injector); } }