/** * @license * Copyright Google LLC 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 { logging } from '@angular-devkit/core'; import { Observable } from 'rxjs'; import { Url } from 'url'; import { FileEntry, MergeStrategy, Tree } from '../tree/interface'; import { Workflow } from '../workflow/interface'; export interface TaskConfiguration { name: string; dependencies?: Array; options?: T; } export interface TaskConfigurationGenerator { toConfiguration(): TaskConfiguration; } export declare type TaskExecutor = (options: T | undefined, context: SchematicContext) => Promise | Observable; export interface TaskExecutorFactory { readonly name: string; create(options?: T): Promise | Observable; } export interface TaskId { readonly id: number; } export interface TaskInfo { readonly id: number; readonly priority: number; readonly configuration: TaskConfiguration; readonly context: SchematicContext; } export interface ExecutionOptions { scope: string; interactive: boolean; } /** * The description (metadata) of a collection. This type contains every information the engine * needs to run. The CollectionMetadataT type parameter contains additional metadata that you * want to store while remaining type-safe. */ export declare type CollectionDescription = CollectionMetadataT & { readonly name: string; readonly extends?: string[]; }; /** * The description (metadata) of a schematic. This type contains every information the engine * needs to run. The SchematicMetadataT and CollectionMetadataT type parameters contain additional * metadata that you want to store while remaining type-safe. */ export declare type SchematicDescription = SchematicMetadataT & { readonly collection: CollectionDescription; readonly name: string; readonly private?: boolean; readonly hidden?: boolean; }; /** * The Host for the Engine. Specifically, the piece of the tooling responsible for resolving * collections and schematics descriptions. The SchematicMetadataT and CollectionMetadataT type * parameters contain additional metadata that you want to store while remaining type-safe. */ export interface EngineHost { createCollectionDescription(name: string, requester?: CollectionDescription): CollectionDescription; listSchematicNames(collection: CollectionDescription, includeHidden?: boolean): string[]; createSchematicDescription(name: string, collection: CollectionDescription): SchematicDescription | null; getSchematicRuleFactory(schematic: SchematicDescription, collection: CollectionDescription): RuleFactory; createSourceFromUrl(url: Url, context: TypedSchematicContext): Source | null; transformOptions(schematic: SchematicDescription, options: OptionT, context?: TypedSchematicContext): Observable; transformContext(context: TypedSchematicContext): TypedSchematicContext | void; createTaskExecutor(name: string): Observable; hasTaskExecutor(name: string): boolean; readonly defaultMergeStrategy?: MergeStrategy; } /** * The root Engine for creating and running schematics and collections. Everything related to * a schematic execution starts from this interface. * * CollectionMetadataT is, by default, a generic Collection metadata type. This is used throughout * the engine typings so that you can use a type that's merged into descriptions, while being * type-safe. * * SchematicMetadataT is a type that contains additional typing for the Schematic Description. */ export interface Engine { createCollection(name: string, requester?: Collection): Collection; createContext(schematic: Schematic, parent?: Partial>, executionOptions?: Partial): TypedSchematicContext; createSchematic(name: string, collection: Collection): Schematic; createSourceFromUrl(url: Url, context: TypedSchematicContext): Source; transformOptions(schematic: Schematic, options: OptionT, context?: TypedSchematicContext): Observable; executePostTasks(): Observable; readonly defaultMergeStrategy: MergeStrategy; readonly workflow: Workflow | null; } /** * A Collection as created by the Engine. This should be used by the tool to create schematics, * or by rules to create other schematics as well. */ export interface Collection { readonly description: CollectionDescription; readonly baseDescriptions?: Array>; createSchematic(name: string, allowPrivate?: boolean): Schematic; listSchematicNames(includeHidden?: boolean): string[]; } /** * A Schematic as created by the Engine. This should be used by the tool to execute the main * schematics, or by rules to execute other schematics as well. */ export interface Schematic { readonly description: SchematicDescription; readonly collection: Collection; call(options: OptionT, host: Observable, parentContext?: Partial>, executionOptions?: Partial): Observable; } /** * A SchematicContext. Contains information necessary for Schematics to execute some rules, for * example when using another schematics, as we need the engine and collection. */ export interface TypedSchematicContext { readonly debug: boolean; readonly engine: Engine; readonly logger: logging.LoggerApi; readonly schematic: Schematic; readonly strategy: MergeStrategy; readonly interactive: boolean; addTask(task: TaskConfigurationGenerator, dependencies?: Array): TaskId; } /** * This is used by the Schematics implementations in order to avoid needing to have typing from * the tooling. Schematics are not specific to a tool. */ export declare type SchematicContext = TypedSchematicContext<{}, {}>; /** * A rule factory, which is normally the way schematics are implemented. Returned by the tooling * after loading a schematic description. */ export declare type RuleFactory = (options: T) => Rule; /** * A FileOperator applies changes synchronously to a FileEntry. An async operator returns * asynchronously. We separate them so that the type system can catch early errors. */ export declare type FileOperator = (entry: FileEntry) => FileEntry | null; export declare type AsyncFileOperator = (tree: FileEntry) => Observable; /** * A source is a function that generates a Tree from a specific context. A rule transforms a tree * into another tree from a specific context. In both cases, an Observable can be returned if * the source or the rule are asynchronous. Only the last Tree generated in the observable will * be used though. * * We obfuscate the context of Source and Rule because the schematic implementation should not * know which types is the schematic or collection metadata, as they are both tooling specific. */ export declare type Source = (context: SchematicContext) => Tree | Observable; export declare type Rule = (tree: Tree, context: SchematicContext) => Tree | Observable | Rule | Promise | void;