UNPKG

9.05 kBTypeScriptView Raw
1/**
2 * @license
3 * Copyright Google LLC All Rights Reserved.
4 *
5 * Use of this source code is governed by an MIT-style license that can be
6 * found in the LICENSE file at https://angular.io/license
7 */
8/// <reference types="@types/node/url" />
9/// <reference types="@types/node/ts4.8/url" />
10import { logging } from '@angular-devkit/core';
11import { Observable } from 'rxjs';
12import { Url } from 'url';
13import { FileEntry, MergeStrategy, Tree } from '../tree/interface';
14import { Workflow } from '../workflow/interface';
15export interface TaskConfiguration<T = {}> {
16 name: string;
17 dependencies?: Array<TaskId>;
18 options?: T;
19}
20export interface TaskConfigurationGenerator<T = {}> {
21 toConfiguration(): TaskConfiguration<T>;
22}
23export type TaskExecutor<T = {}> = (options: T | undefined, context: SchematicContext) => Promise<void> | Observable<void>;
24export interface TaskExecutorFactory<T> {
25 readonly name: string;
26 create(options?: T): Promise<TaskExecutor> | Observable<TaskExecutor>;
27}
28export interface TaskId {
29 readonly id: number;
30}
31export interface TaskInfo {
32 readonly id: number;
33 readonly priority: number;
34 readonly configuration: TaskConfiguration;
35 readonly context: SchematicContext;
36}
37export interface ExecutionOptions {
38 scope: string;
39 interactive: boolean;
40}
41/**
42 * The description (metadata) of a collection. This type contains every information the engine
43 * needs to run. The CollectionMetadataT type parameter contains additional metadata that you
44 * want to store while remaining type-safe.
45 */
46export type CollectionDescription<CollectionMetadataT extends object> = CollectionMetadataT & {
47 readonly name: string;
48 readonly extends?: string[];
49};
50/**
51 * The description (metadata) of a schematic. This type contains every information the engine
52 * needs to run. The SchematicMetadataT and CollectionMetadataT type parameters contain additional
53 * metadata that you want to store while remaining type-safe.
54 */
55export type SchematicDescription<CollectionMetadataT extends object, SchematicMetadataT extends object> = SchematicMetadataT & {
56 readonly collection: CollectionDescription<CollectionMetadataT>;
57 readonly name: string;
58 readonly private?: boolean;
59 readonly hidden?: boolean;
60};
61/**
62 * The Host for the Engine. Specifically, the piece of the tooling responsible for resolving
63 * collections and schematics descriptions. The SchematicMetadataT and CollectionMetadataT type
64 * parameters contain additional metadata that you want to store while remaining type-safe.
65 */
66export interface EngineHost<CollectionMetadataT extends object, SchematicMetadataT extends object> {
67 createCollectionDescription(name: string, requester?: CollectionDescription<CollectionMetadataT>): CollectionDescription<CollectionMetadataT>;
68 listSchematicNames(collection: CollectionDescription<CollectionMetadataT>, includeHidden?: boolean): string[];
69 createSchematicDescription(name: string, collection: CollectionDescription<CollectionMetadataT>): SchematicDescription<CollectionMetadataT, SchematicMetadataT> | null;
70 getSchematicRuleFactory<OptionT extends object>(schematic: SchematicDescription<CollectionMetadataT, SchematicMetadataT>, collection: CollectionDescription<CollectionMetadataT>): RuleFactory<OptionT>;
71 createSourceFromUrl(url: Url, context: TypedSchematicContext<CollectionMetadataT, SchematicMetadataT>): Source | null;
72 transformOptions<OptionT extends object, ResultT extends object>(schematic: SchematicDescription<CollectionMetadataT, SchematicMetadataT>, options: OptionT, context?: TypedSchematicContext<CollectionMetadataT, SchematicMetadataT>): Observable<ResultT>;
73 transformContext(context: TypedSchematicContext<CollectionMetadataT, SchematicMetadataT>): TypedSchematicContext<CollectionMetadataT, SchematicMetadataT> | void;
74 createTaskExecutor(name: string): Observable<TaskExecutor>;
75 hasTaskExecutor(name: string): boolean;
76 readonly defaultMergeStrategy?: MergeStrategy;
77}
78/**
79 * The root Engine for creating and running schematics and collections. Everything related to
80 * a schematic execution starts from this interface.
81 *
82 * CollectionMetadataT is, by default, a generic Collection metadata type. This is used throughout
83 * the engine typings so that you can use a type that's merged into descriptions, while being
84 * type-safe.
85 *
86 * SchematicMetadataT is a type that contains additional typing for the Schematic Description.
87 */
88export interface Engine<CollectionMetadataT extends object, SchematicMetadataT extends object> {
89 createCollection(name: string, requester?: Collection<CollectionMetadataT, SchematicMetadataT>): Collection<CollectionMetadataT, SchematicMetadataT>;
90 createContext(schematic: Schematic<CollectionMetadataT, SchematicMetadataT>, parent?: Partial<TypedSchematicContext<CollectionMetadataT, SchematicMetadataT>>, executionOptions?: Partial<ExecutionOptions>): TypedSchematicContext<CollectionMetadataT, SchematicMetadataT>;
91 createSchematic(name: string, collection: Collection<CollectionMetadataT, SchematicMetadataT>): Schematic<CollectionMetadataT, SchematicMetadataT>;
92 createSourceFromUrl(url: Url, context: TypedSchematicContext<CollectionMetadataT, SchematicMetadataT>): Source;
93 transformOptions<OptionT extends object, ResultT extends object>(schematic: Schematic<CollectionMetadataT, SchematicMetadataT>, options: OptionT, context?: TypedSchematicContext<CollectionMetadataT, SchematicMetadataT>): Observable<ResultT>;
94 executePostTasks(): Observable<void>;
95 readonly defaultMergeStrategy: MergeStrategy;
96 readonly workflow: Workflow | null;
97}
98/**
99 * A Collection as created by the Engine. This should be used by the tool to create schematics,
100 * or by rules to create other schematics as well.
101 */
102export interface Collection<CollectionMetadataT extends object, SchematicMetadataT extends object> {
103 readonly description: CollectionDescription<CollectionMetadataT>;
104 readonly baseDescriptions?: Array<CollectionDescription<CollectionMetadataT>>;
105 createSchematic(name: string, allowPrivate?: boolean): Schematic<CollectionMetadataT, SchematicMetadataT>;
106 listSchematicNames(includeHidden?: boolean): string[];
107}
108/**
109 * A Schematic as created by the Engine. This should be used by the tool to execute the main
110 * schematics, or by rules to execute other schematics as well.
111 */
112export interface Schematic<CollectionMetadataT extends object, SchematicMetadataT extends object> {
113 readonly description: SchematicDescription<CollectionMetadataT, SchematicMetadataT>;
114 readonly collection: Collection<CollectionMetadataT, SchematicMetadataT>;
115 call<OptionT extends object>(options: OptionT, host: Observable<Tree>, parentContext?: Partial<TypedSchematicContext<CollectionMetadataT, SchematicMetadataT>>, executionOptions?: Partial<ExecutionOptions>): Observable<Tree>;
116}
117/**
118 * A SchematicContext. Contains information necessary for Schematics to execute some rules, for
119 * example when using another schematics, as we need the engine and collection.
120 */
121export interface TypedSchematicContext<CollectionMetadataT extends object, SchematicMetadataT extends object> {
122 readonly debug: boolean;
123 readonly engine: Engine<CollectionMetadataT, SchematicMetadataT>;
124 readonly logger: logging.LoggerApi;
125 readonly schematic: Schematic<CollectionMetadataT, SchematicMetadataT>;
126 readonly strategy: MergeStrategy;
127 readonly interactive: boolean;
128 addTask<T extends object>(task: TaskConfigurationGenerator<T>, dependencies?: Array<TaskId>): TaskId;
129}
130/**
131 * This is used by the Schematics implementations in order to avoid needing to have typing from
132 * the tooling. Schematics are not specific to a tool.
133 */
134export type SchematicContext = TypedSchematicContext<{}, {}>;
135/**
136 * A rule factory, which is normally the way schematics are implemented. Returned by the tooling
137 * after loading a schematic description.
138 */
139export type RuleFactory<T extends object> = (options: T) => Rule;
140/**
141 * A FileOperator applies changes synchronously to a FileEntry. An async operator returns
142 * asynchronously. We separate them so that the type system can catch early errors.
143 */
144export type FileOperator = (entry: FileEntry) => FileEntry | null;
145export type AsyncFileOperator = (tree: FileEntry) => Observable<FileEntry | null>;
146/**
147 * A source is a function that generates a Tree from a specific context. A rule transforms a tree
148 * into another tree from a specific context. In both cases, an Observable can be returned if
149 * the source or the rule are asynchronous. Only the last Tree generated in the observable will
150 * be used though.
151 *
152 * We obfuscate the context of Source and Rule because the schematic implementation should not
153 * know which types is the schematic or collection metadata, as they are both tooling specific.
154 */
155export type Source = (context: SchematicContext) => Tree | Observable<Tree>;
156export type Rule = (tree: Tree, context: SchematicContext) => Tree | Observable<Tree> | Rule | Promise<void | Rule> | void;