All files route-decorators.ts

100% Statements 38/38
100% Branches 18/18
100% Functions 10/10
100% Lines 33/33
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73  1x 1x     134x   134x 402x   402x     134x       766x 199x 766x 1016x 92x       766x     199x     146x 80x   66x               1x 239x 155x   155x 155x   155x 50x     155x 148x 2x     146x   146x 245x     146x 146x 132x            
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { combineLatest } from 'rxjs/observable/combineLatest';
 
function extractRoutes(parent, routeProperty): Observable<any>[] {
    let routes = [];
 
    while (parent) {
        routes.push(parent[routeProperty]);
 
        parent = parent.parent;
    }
 
    return routes;
}
 
function extractValues(routes, args, config, cb): void {
    const stream$ = combineLatest(of(null), ...routes, (...routeValues) => {
            const values = routeValues.reduce((obj, route) => {
                args.forEach(arg => {
                    if (route && route[arg] !== undefined) {
                        obj[arg] = route[arg];
                    }
                });
 
                return obj;
            }, {});
 
            return args.length === 1 ? values[args[0]] : values;
        });
 
    if (config.observable === false) {
        stream$.subscribe(cb);
    } else {
        cb(stream$);
    }
}
 
export interface RouteXxlConfig {
    observable?: boolean;
}
 
export function routeDecoratorFactory(routeProperty) {
    return function (...args: Array<string | RouteXxlConfig>): any {
        const config = (typeof args[args.length - 1] === 'object' ? args.pop() : {}) as RouteXxlConfig;
 
        return (target: any, key: string, index: number): void => {
            const ngOnInit = target.ngOnInit;
 
            if (!args.length) {
                args = [key.replace(/\$$/, '')];
            }
 
            target.ngOnInit = function (): void {
                if (!this.route) {
                    throw(`${target.constructor.name} uses the ${routeProperty} @decorator without a 'route' property`);
                }
 
                const routes = routeProperty === 'queryParams' ? [this.route.queryParams] : extractRoutes(this.route, routeProperty);
 
                extractValues(routes, args, config, values => {
                    this[key] = values;
                });
 
                this.ngOnInit = ngOnInit;
                if (ngOnInit) {
                    this.ngOnInit();
                }
            };
        };
    };
}