|
7 | 7 | */
|
8 | 8 | import { BaseException, isObservable } from '@angular-devkit/core';
|
9 | 9 | import { Observable, of as observableOf, throwError } from 'rxjs';
|
10 |
| -import { last, mergeMap, tap } from 'rxjs/operators'; |
| 10 | +import { defaultIfEmpty, last, mergeMap, tap } from 'rxjs/operators'; |
11 | 11 | import { Rule, SchematicContext, Source } from '../engine/interface';
|
12 | 12 | import { Tree, TreeSymbol } from '../tree/interface';
|
13 | 13 |
|
@@ -51,55 +51,53 @@ export class InvalidSourceResultException extends BaseException {
|
51 | 51 |
|
52 | 52 |
|
53 | 53 | export function callSource(source: Source, context: SchematicContext): Observable<Tree> {
|
54 |
| - const result = source(context) as object; |
| 54 | + const result = source(context); |
55 | 55 |
|
56 |
| - if (result === undefined) { |
57 |
| - return throwError(new InvalidSourceResultException(result)); |
58 |
| - } else if (TreeSymbol in result) { |
59 |
| - return observableOf(result as Tree); |
60 |
| - } else if (isObservable(result)) { |
| 56 | + if (isObservable(result)) { |
61 | 57 | // Only return the last Tree, and make sure it's a Tree.
|
62 |
| - return (result as Observable<Tree>).pipe( |
| 58 | + return result.pipe( |
| 59 | + defaultIfEmpty(), |
63 | 60 | last(),
|
64 | 61 | tap(inner => {
|
65 |
| - if (!(TreeSymbol in inner)) { |
| 62 | + if (!inner || !(TreeSymbol in inner)) { |
66 | 63 | throw new InvalidSourceResultException(inner);
|
67 | 64 | }
|
68 | 65 | }),
|
69 | 66 | );
|
| 67 | + } else if (result && TreeSymbol in result) { |
| 68 | + return observableOf(result); |
70 | 69 | } else {
|
71 | 70 | return throwError(new InvalidSourceResultException(result));
|
72 | 71 | }
|
73 | 72 | }
|
74 | 73 |
|
75 | 74 |
|
76 |
| -export function callRule(rule: Rule, |
77 |
| - input: Observable<Tree>, |
78 |
| - context: SchematicContext): Observable<Tree> { |
| 75 | +export function callRule( |
| 76 | + rule: Rule, |
| 77 | + input: Observable<Tree>, |
| 78 | + context: SchematicContext, |
| 79 | +): Observable<Tree> { |
79 | 80 | return input.pipe(mergeMap(inputTree => {
|
80 |
| - const result = rule(inputTree, context) as object; |
| 81 | + const result = rule(inputTree, context); |
81 | 82 |
|
82 | 83 | if (result === undefined) {
|
83 | 84 | return observableOf(inputTree);
|
84 |
| - } else if (TreeSymbol in result) { |
85 |
| - return observableOf(result as Tree); |
86 | 85 | } else if (typeof result == 'function') {
|
87 | 86 | // This is considered a Rule, chain the rule and return its output.
|
88 | 87 | return callRule(result, input, context);
|
89 | 88 | } else if (isObservable(result)) {
|
90 |
| - const obs = result as Observable<Tree>; |
91 |
| - |
92 | 89 | // Only return the last Tree, and make sure it's a Tree.
|
93 |
| - return obs.pipe( |
| 90 | + return result.pipe( |
| 91 | + defaultIfEmpty(), |
94 | 92 | last(),
|
95 | 93 | tap(inner => {
|
96 |
| - if (!(TreeSymbol in inner)) { |
| 94 | + if (!inner || !(TreeSymbol in inner)) { |
97 | 95 | throw new InvalidRuleResultException(inner);
|
98 | 96 | }
|
99 | 97 | }),
|
100 | 98 | );
|
101 |
| - } else if (result === undefined) { |
102 |
| - return observableOf(inputTree); |
| 99 | + } else if (TreeSymbol in result) { |
| 100 | + return observableOf(result); |
103 | 101 | } else {
|
104 | 102 | return throwError(new InvalidRuleResultException(result));
|
105 | 103 | }
|
|
0 commit comments