hunk.code_window: export interface TargetDefinition {
       builder: string;
       configurations?: Record<string, Record<string, JsonValue | undefined> | undefined>;
       options?: Record<string, JsonValue | undefined>;
   }
  
hunk.labels: keep keep keep add keep keep keep
hunk.after_edit:     defaultConfiguration?: string;
  
hunk.file_path: etc/api/angular_devkit/core/src/_golden-api.d.ts
hunk.type: add
file: /**
   * @license
   * Copyright Google Inc. All Rights Reserved.
   *
   * 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
   */
  import {
    Observable,
    concat,
    defer as deferObservable,
    from as observableFrom,
    isObservable,
    of as observableOf,
  } from 'rxjs';
  import {
    concatMap,
    ignoreElements,
    map,
    mergeMap,
  } from 'rxjs/operators';
  import { FileAlreadyExistException, FileDoesNotExistException } from '../exception/exception';
  import {
    Action,
    CreateFileAction,
    DeleteFileAction,
    OverwriteFileAction,
    RenameFileAction,
    UnknownActionException,
  } from '../tree/action';
  import { Tree } from '../tree/interface';
  
  
  export interface Sink {
    commit(tree: Tree): Observable<void>;
  }
  
  
  const Noop = function() {};
  
  
  export abstract class SimpleSinkBase implements Sink {
    preCommitAction: (action: Action) => void
                                       | Action
                                       | PromiseLike<Action>
                                       | Observable<Action> = Noop;
    postCommitAction: (action: Action) => void | Observable<void> = Noop;
    preCommit: () => void | Observable<void> = Noop;
    postCommit: () => void | Observable<void> = Noop;
  
    protected abstract _validateFileExists(p: string): Observable<boolean>;
  
    protected abstract _overwriteFile(path: string, content: Buffer): Observable<void>;
    protected abstract _createFile(path: string, content: Buffer): Observable<void>;
    protected abstract _renameFile(path: string, to: string): Observable<void>;
    protected abstract _deleteFile(path: string): Observable<void>;
  
    protected abstract _done(): Observable<void>;
  
    protected _fileAlreadyExistException(path: string): void {
      throw new FileAlreadyExistException(path);
    }
    protected _fileDoesNotExistException(path: string): void {
      throw new FileDoesNotExistException(path);
    }
  
    protected _validateOverwriteAction(action: OverwriteFileAction): Observable<void> {
      return this._validateFileExists(action.path)
        .pipe(map(b => { if (!b) { this._fileDoesNotExistException(action.path); } }));
    }
    protected _validateCreateAction(action: CreateFileAction): Observable<void> {
      return this._validateFileExists(action.path)
        .pipe(map(b => { if (b) { this._fileAlreadyExistException(action.path); } }));
    }
    protected _validateRenameAction(action: RenameFileAction): Observable<void> {
      return this._validateFileExists(action.path).pipe(
        map(b => { if (!b) { this._fileDoesNotExistException(action.path); } }),
        mergeMap(() => this._validateFileExists(action.to)),
        map(b => { if (b) { this._fileAlreadyExistException(action.to); } }));
    }
    protected _validateDeleteAction(action: DeleteFileAction): Observable<void> {
      return this._validateFileExists(action.path)
        .pipe(map(b => { if (!b) { this._fileDoesNotExistException(action.path); } }));
    }
  
    validateSingleAction(action: Action): Observable<void> {
      switch (action.kind) {
        case 'o': return this._validateOverwriteAction(action);
        case 'c': return this._validateCreateAction(action);
        case 'r': return this._validateRenameAction(action);
        case 'd': return this._validateDeleteAction(action);
        default: throw new UnknownActionException(action);
      }
    }
  
    commitSingleAction(action: Action): Observable<void> {
      return concat(
        this.validateSingleAction(action),
        new Observable<void>(observer => {
          let committed = null;
          switch (action.kind) {
            case 'o': committed = this._overwriteFile(action.path, action.content); break;
            case 'c': committed = this._createFile(action.path, action.content); break;
            case 'r': committed = this._renameFile(action.path, action.to); break;
            case 'd': committed = this._deleteFile(action.path); break;
          }
  
          if (committed) {
            committed.subscribe(observer);
          } else {
            observer.complete();
          }
        }),
      ).pipe(ignoreElements());
    }
  
    commit(tree: Tree): Observable<void> {
      const actions = observableFrom(tree.actions);
  
      return concat(
        (this.preCommit() || observableOf(null)),
        deferObservable(() => actions).pipe(
          concatMap(action => {
            const maybeAction = this.preCommitAction(action);
  
            if (isObservable(maybeAction) || isPromiseLike(maybeAction)) {
              return maybeAction;
            }
  
            return observableOf(maybeAction || action);
          }),
          concatMap(action => {
            return concat(
              this.commitSingleAction(action).pipe(ignoreElements()),
              observableOf(action),
            );
          }),
          concatMap(action => this.postCommitAction(action) || observableOf(null)),
        ),
        deferObservable(() => this._done()),
        deferObservable(() => this.postCommit() || observableOf(null)),
      ).pipe(ignoreElements());
    }
  }
  
  function isPromiseLike<T, U = unknown>(value: U | PromiseLike<T>): value is PromiseLike<T> {
    return !!value && typeof (value as PromiseLike<T>).then === 'function';
  }
  