fix(@angular-devkit/architect): support all observable types as build results

Fixes #14579
This commit is contained in:
Charles Lyding 2019-05-29 21:06:49 -04:00 committed by Alex Eagle
parent 5a100c7768
commit 19ed795cb1
3 changed files with 22 additions and 13 deletions

View File

@ -38,7 +38,7 @@ export declare type BuilderInput = json.JsonObject & RealBuilderInput;
export declare type BuilderOutput = json.JsonObject & RealBuilderOutput; export declare type BuilderOutput = json.JsonObject & RealBuilderOutput;
export declare type BuilderOutputLike = Observable<BuilderOutput> | Promise<BuilderOutput> | BuilderOutput; export declare type BuilderOutputLike = SubscribableOrPromise<BuilderOutput> | BuilderOutput;
export declare type BuilderProgress = json.JsonObject & RealBuilderProgress & TypedBuilderProgress; export declare type BuilderProgress = json.JsonObject & RealBuilderProgress & TypedBuilderProgress;
@ -60,6 +60,8 @@ export interface BuilderRun {
export declare function createBuilder<OptT extends json.JsonObject, OutT extends BuilderOutput = BuilderOutput>(fn: BuilderHandlerFn<OptT>): Builder<OptT>; export declare function createBuilder<OptT extends json.JsonObject, OutT extends BuilderOutput = BuilderOutput>(fn: BuilderHandlerFn<OptT>): Builder<OptT>;
export declare function isBuilderOutput(obj: any): obj is BuilderOutput;
export interface ScheduleOptions { export interface ScheduleOptions {
analytics?: analytics.Analytics; analytics?: analytics.Analytics;
logger?: logging.Logger; logger?: logging.Logger;

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import { analytics, experimental, json, logging } from '@angular-devkit/core'; import { analytics, experimental, json, logging } from '@angular-devkit/core';
import { Observable, from } from 'rxjs'; import { Observable, SubscribableOrPromise, from } from 'rxjs';
import { switchMap } from 'rxjs/operators'; import { switchMap } from 'rxjs/operators';
import { Schema as RealBuilderInput, Target as RealTarget } from './input-schema'; import { Schema as RealBuilderInput, Target as RealTarget } from './input-schema';
import { Schema as RealBuilderOutput } from './output-schema'; import { Schema as RealBuilderOutput } from './output-schema';
@ -250,8 +250,16 @@ export interface BuilderContext {
/** /**
* An accepted return value from a builder. Can be either an Observable, a Promise or a vector. * An accepted return value from a builder. Can be either an Observable, a Promise or a vector.
*/ */
export type BuilderOutputLike = Observable<BuilderOutput> | Promise<BuilderOutput> | BuilderOutput; export type BuilderOutputLike = SubscribableOrPromise<BuilderOutput> | BuilderOutput;
// tslint:disable-next-line:no-any
export function isBuilderOutput(obj: any): obj is BuilderOutput {
if (!obj || typeof obj.then === 'function' || typeof obj.subscribe === 'function') {
return false;
}
return typeof obj.success === 'boolean';
}
/** /**
* A builder handler function. The function signature passed to `createBuilder()`. * A builder handler function. The function signature passed to `createBuilder()`.

View File

@ -5,8 +5,8 @@
* Use of this source code is governed by an MIT-style license that can be * Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import { analytics, experimental, isPromise, json, logging } from '@angular-devkit/core'; import { analytics, experimental, json, logging } from '@angular-devkit/core';
import { Observable, Subscription, from, isObservable, of, throwError } from 'rxjs'; import { Observable, Subscription, from, of, throwError } from 'rxjs';
import { tap } from 'rxjs/operators'; import { tap } from 'rxjs/operators';
import { import {
BuilderContext, BuilderContext,
@ -14,11 +14,11 @@ import {
BuilderInfo, BuilderInfo,
BuilderInput, BuilderInput,
BuilderOutput, BuilderOutput,
BuilderOutputLike,
BuilderProgressState, BuilderProgressState,
ScheduleOptions, ScheduleOptions,
Target, Target,
TypedBuilderProgress, TypedBuilderProgress,
isBuilderOutput,
targetStringFromTarget, targetStringFromTarget,
} from './api'; } from './api';
import { Builder, BuilderSymbol, BuilderVersionSymbol } from './internal'; import { Builder, BuilderSymbol, BuilderVersionSymbol } from './internal';
@ -189,19 +189,18 @@ export function createBuilder<
}; };
context.reportRunning(); context.reportRunning();
let result: BuilderOutputLike; let result;
try { try {
result = fn(i.options as OptT, context); result = fn(i.options as OptT, context);
if (isBuilderOutput(result)) {
result = of(result);
} else {
result = from(result);
}
} catch (e) { } catch (e) {
result = throwError(e); result = throwError(e);
} }
if (isPromise(result)) {
result = from(result);
} else if (!isObservable(result)) {
result = of(result);
}
// Manage some state automatically. // Manage some state automatically.
progress({ state: BuilderProgressState.Running, current: 0, total: 1 }, context); progress({ state: BuilderProgressState.Running, current: 0, total: 1 }, context);
subscriptions.push(result.pipe( subscriptions.push(result.pipe(