UNPKG

first-npm-package-nicule

Version:

This isi first npm package

87 lines (69 loc) 3.67 kB
import { HrefFormatterProvider } from 'first-npm-package-nicule/core'; import { ReflectiveInjector, Type } from '@angular/core'; import { makePropDecorator } from '../../google-decorator-factories'; import { BindDecorator } from '../bind.decorator'; // import { HypermediaStore } from 'hypermedia/core/services/hypermedia.store'; import { TOKEN_PROVIDER } from '../../token-provider'; import { PARENT_ENTITY } from '../../parent-entity'; import { HypermediaStore } from '../../../core/services/hypermedia.store'; type TokenProviderType = { useClass: Type<any> } | { useFactory: any, deps?: Array<any> } | { useExisting: Type<any> }; interface LinkedEntityOptions<T> { as?: Type<T>; authorize?: boolean; tokenProvider?: TokenProviderType; } export interface BindLinkedEntityDecorator { <T>(classList: Array<string>, options?: LinkedEntityOptions<T>): any; new <T>(classList: Array<string>, options?: LinkedEntityOptions<T>): any; } function guid(): string { function s4(): string { return Math.floor((Math.random() + 1) * 0x10000) .toString(16) .substring(1); } return `${s4()}${s4()}-${s4()}-${s4()}-${s4()}-${s4()}${s4()}${s4()}`; } export const LinkedEntity: BindLinkedEntityDecorator = makePropDecorator('BindLinkedEntity', <T>(classList: Array<string>, options: LinkedEntityOptions<T> = {}) => { return ({ binding: { priority: 1, bind: (({ entities = [] }, fieldName, injector, parent) => { let tokenOverride; if (entities.length === 0) { return undefined; } const { href } = entities.find(({ class: classes }) => classList.every(clazz => classes.includes(clazz))) || {} as any; if (!href) { return undefined; } if (!/^(http|https):\/\//.test(href)) { return undefined; } if (options && options.tokenProvider) { injector = ReflectiveInjector.resolveAndCreate([{ provide: PARENT_ENTITY, useValue: parent }, { provide: TOKEN_PROVIDER, ...options.tokenProvider }], injector); const tokenProvider = injector.get(TOKEN_PROVIDER); tokenOverride = tokenProvider.getToken(); } const formatterProvider = injector.get(HrefFormatterProvider); const formatter = formatterProvider.getHrefFormatterForHref(href); const scope = (formatter === undefined) ? 'external' : formatter.getScope(); const path = (formatter === undefined) ? href : formatter.makePathFromHref(href); const { authorize, as } = options; const selector = injector .get(HypermediaStore) .select(`${path}?noCache=${guid()}`, scope, authorize, tokenOverride); selector .intercept(0, ({ class: classes }) => { console.log("linked-entity-decorator: intercepted 0 response exception"); // prevents from redirecting to disconnected error page }); if (!as) { return selector; } return selector.as(as); }) } as BindDecorator }) as any; });