or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

file-system-actions.mdindex.mdnode-tools.mdoutput-sinks.mdrule-system.mdschematic-engine.mdtemplate-engine.mdtree-operations.mdworkflow.md
tile.json

index.mddocs/

Angular Schematics

Angular Schematics is a powerful scaffolding and code generation library that enables developers to create, transform, and manage filesystem changes in a purely descriptive way without side effects. It provides a comprehensive set of tools including Schematics (generators), Collections (metadata containers), Rules (transformation functions), Trees (staging areas for changes), and Actions (atomic operations), all designed to work together in a deterministic and reversible manner.

Package Information

  • Package Name: @angular-devkit/schematics
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @angular-devkit/schematics

Core Imports

import {
  Rule,
  Source,
  Tree,
  SchematicContext,
  chain,
  apply,
  mergeWith,
  template,
  move,
  url,
  empty,
  noop
} from "@angular-devkit/schematics";

For engine functionality:

import {
  Engine,
  Schematic,
  Collection,
  SchematicEngine
} from "@angular-devkit/schematics";

For sinks:

import {
  HostSink,
  DryRunSink
} from "@angular-devkit/schematics";

For testing:

import {
  SchematicTestRunner,
  UnitTestTree
} from "@angular-devkit/schematics/testing";

For format validation:

import {
  standardFormats,
  htmlSelectorFormat,
  pathFormat
} from "@angular-devkit/schematics";

For workflow:

import {
  BaseWorkflow,
  Workflow,
  WorkflowExecutionContext
} from "@angular-devkit/schematics";

For Node.js tools:

import {
  NodeModulesEngineHost,
  NodeModulesTestEngineHost,
  validateOptionsWithSchema
} from "@angular-devkit/schematics/tools";

Basic Usage

import {
  Rule,
  SchematicContext,
  Tree,
  apply,
  url,
  template,
  move,
  chain,
  mergeWith
} from "@angular-devkit/schematics";

// Define a simple schematic rule
function mySchematic(options: any): Rule {
  return (tree: Tree, context: SchematicContext) => {
    // Create a new file
    tree.create('/hello.txt', 'Hello World!');
    
    return tree;
  };
}

// Complex schematic with templates
function generateComponent(options: { name: string; path: string }): Rule {
  return chain([
    // Apply templates from URL source
    mergeWith(
      apply(url('./files'), [
        template({
          ...options,
          classify: (str: string) => str.charAt(0).toUpperCase() + str.slice(1),
          dasherize: (str: string) => str.replace(/[A-Z]/g, '-$&').toLowerCase()
        }),
        move(options.path)
      ])
    )
  ]);
}

Architecture

Angular Schematics is built around several core concepts:

  • Trees: Virtual file system representations that stage changes without side effects
  • Rules: Pure functions that transform trees, composable and chainable
  • Sources: Functions that create trees from external sources (URLs, templates, etc.)
  • Actions: Atomic operations (create, update, delete, rename) applied to the file system
  • Engine: Orchestrates schematic execution with collections and metadata
  • Sinks: Output destinations for committing tree changes (filesystem, dry-run, etc.)

Capabilities

Tree Operations

Core virtual file system operations for reading, writing, and manipulating files and directories in a staging environment.

interface Tree {
  // Structural operations
  branch(): Tree;
  merge(other: Tree, strategy?: MergeStrategy): void;
  
  // Read operations
  read(path: string): Buffer | null;
  readText(path: string): string;
  readJson(path: string): JsonValue;
  exists(path: string): boolean;
  get(path: string): FileEntry | null;
  getDir(path: string): DirEntry;
  
  // Write operations  
  create(path: string, content: Buffer | string): void;
  overwrite(path: string, content: Buffer | string): void;
  delete(path: string): void;
  rename(from: string, to: string): void;
  
  // Advanced operations
  beginUpdate(path: string): UpdateRecorder;
  commitUpdate(record: UpdateRecorder): void;
  apply(action: Action, strategy?: MergeStrategy): void;
  visit(visitor: FileVisitor): void;
}

const Tree: TreeConstructor;

interface TreeConstructor {
  empty(): Tree;
  branch(tree: Tree): Tree;
  merge(tree: Tree, other: Tree, strategy?: MergeStrategy): Tree;
  partition(tree: Tree, predicate: FilePredicate<boolean>): [Tree, Tree];
  optimize(tree: Tree): Tree;
}

Tree Operations

Rule System

Composable transformation functions that modify trees in a functional, predictable way. Rules are the building blocks of schematics.

type Rule = (tree: Tree, context: SchematicContext) => 
  Tree | Observable<Tree> | Rule | Promise<void | Tree | Rule> | void;

type Source = (context: SchematicContext) => Tree | Observable<Tree>;

type RuleFactory<T> = (options: T) => Rule;

// Core rule functions
function chain(rules: Iterable<Rule> | AsyncIterable<Rule>): Rule;
function apply(source: Source, rules: Rule[]): Source;
function mergeWith(source: Source, strategy?: MergeStrategy): Rule;
function noop(): Rule;
function empty(): Source;
function source(tree: Tree): Source;

Rule System

Template Engine

Template processing system for generating files with dynamic content using popular template syntaxes and path transformations.

function template<T>(options: T): Rule;
function contentTemplate<T>(options: T): Rule;
function pathTemplate<T>(options: T): Rule;
function applyTemplates<T>(options: T): Rule;
function renameTemplateFiles(): Rule;

function applyContentTemplate<T>(options: T): FileOperator;
function applyPathTemplate<T>(data: T, options?: PathTemplateOptions): FileOperator;

Template Engine

Schematic Engine

Execution engine for running schematics with metadata, collections, and workflow orchestration. Handles schematic discovery and execution.

interface Engine<CollectionMetadataT, SchematicMetadataT> {
  readonly defaultMergeStrategy: MergeStrategy;
  readonly workflow: Workflow | null;
  
  createCollection(name: string, requester?: Collection<CollectionMetadataT, SchematicMetadataT>): Collection<CollectionMetadataT, SchematicMetadataT>;
  createSchematic(name: string, collection: Collection<CollectionMetadataT, SchematicMetadataT>): Schematic<CollectionMetadataT, SchematicMetadataT>;
  executePostTasks(): Observable<void>;
}

interface SchematicContext {
  readonly debug: boolean;
  readonly engine: Engine<any, any>;
  readonly logger: logging.LoggerApi;
  readonly schematic: Schematic<any, any>;
  readonly strategy: MergeStrategy;
  readonly interactive: boolean;
  
  addTask<T>(task: TaskConfigurationGenerator<T>, dependencies?: Array<TaskId>): TaskId;
}

class SchematicEngine<CollectionT, SchematicT> implements Engine<CollectionT, SchematicT> {
  constructor(host: EngineHost<CollectionT, SchematicT>, workflow?: Workflow);
}

Schematic Engine

Output Sinks

Output destination system for committing tree changes to various targets including filesystem and dry-run reporting.

interface Sink {
  commit(tree: Tree): Observable<void>;
}

class HostSink extends SimpleSinkBase {
  constructor(host: virtualFs.Host, force?: boolean);
}

class DryRunSink extends SimpleSinkBase {
  readonly reporter: Observable<DryRunEvent>;
  constructor(host: virtualFs.Host | string, force?: boolean);
}

Output Sinks

File System Actions

Low-level atomic operations for file system modifications that can be applied to trees and tracked for optimization.

interface Action {
  readonly id: number;
  readonly parent: number;
  readonly path: Path;
}

interface CreateFileAction extends Action {
  readonly kind: 'c';
  readonly content: Buffer;
}

interface OverwriteFileAction extends Action {
  readonly kind: 'o';
  readonly content: Buffer;
}

interface RenameFileAction extends Action {
  readonly kind: 'r';
  readonly to: Path;
}

interface DeleteFileAction extends Action {
  readonly kind: 'd';
}

class ActionList {
  create(path: Path, content: Buffer): void;
  overwrite(path: Path, content: Buffer): void;
  rename(path: Path, to: Path): void;
  delete(path: Path): void;
  optimize(): void;
}

File System Actions

Workflow System

High-level orchestration for schematic execution with lifecycle management, error handling, and context propagation.

interface Workflow {
  readonly context: Readonly<WorkflowExecutionContext>;
  execute(options: Partial<WorkflowExecutionContext> & RequiredWorkflowExecutionContext): Observable<void>;
}

abstract class BaseWorkflow implements Workflow {
  readonly engine: Engine<{}, {}>;
  readonly engineHost: EngineHost<{}, {}>;
  readonly registry: schema.SchemaRegistry;
  readonly reporter: Observable<DryRunEvent>;
  readonly lifeCycle: Observable<LifeCycleEvent>;
}

Workflow System

Node.js Tools

Node.js-specific utilities for working with npm packages, module resolution, and testing environments.

class NodeModulesEngineHost extends FileSystemEngineHostBase {
  constructor(paths?: string[]);
}

class NodeModulesTestEngineHost extends NodeModulesEngineHost {
  readonly tasks: TaskConfiguration[];
  registerCollection(collectionName: string, collectionPath: string): void;
  registerTaskExecutor<T>(factory: TaskExecutorFactory<T>): void;
}

function validateOptionsWithSchema(registry: schema.SchemaRegistry): OptionTransform<object, object>;

Node.js Tools

Testing Utilities

Testing infrastructure for unit testing schematics with isolated tree environments and collection execution.

class SchematicTestRunner {
  constructor(collectionName: string, collectionPath: string);
  
  readonly engine: SchematicEngine<{}, {}>;
  readonly logger: logging.Logger;
  
  runSchematic<SchematicSchemaT>(
    schematicName: string,
    options?: SchematicSchemaT,
    tree?: Tree
  ): Promise<UnitTestTree>;
  
  runSchematicAsync<SchematicSchemaT>(
    schematicName: string,
    options?: SchematicSchemaT, 
    tree?: Tree
  ): Observable<UnitTestTree>;
  
  callRule(rule: Rule, tree: Tree, parentContext?: Partial<SchematicContext>): Observable<Tree>;
}

class UnitTestTree extends DelegateTree {
  readonly files: string[];
  readContent(path: string): string;
}

Format Validation

Schema format validators for validating string patterns in schematic options.

const standardFormats: SchemaFormat[];

const htmlSelectorFormat: SchemaFormat;
const pathFormat: SchemaFormat;

function formatValidator(
  data: JsonValue,
  dataSchema: JsonObject,
  formats: SchemaFormat[]
): Promise<SchemaValidatorResult>;

Types

Core Types

enum MergeStrategy {
  Default = 0,
  Error = 1,
  AllowOverwriteConflict = 2,
  AllowCreationConflict = 4,
  AllowDeleteConflict = 8,
  ContentOnly = 2,
  Overwrite = 14
}

type FilePredicate<T> = (path: Path, entry?: Readonly<FileEntry> | null) => T;
type FileVisitor = FilePredicate<void>;
type FileOperator = (entry: FileEntry) => FileEntry | null;

interface FileEntry {
  readonly path: Path;
  readonly content: Buffer;
}

interface DirEntry {
  readonly parent: DirEntry | null;
  readonly path: Path;
  readonly subdirs: PathFragment[];
  readonly subfiles: PathFragment[];
  
  dir(name: PathFragment): DirEntry;
  file(name: PathFragment): FileEntry | null;
  visit(visitor: FileVisitor): void;
}

interface UpdateRecorder {
  insertLeft(index: number, content: Buffer | string): UpdateRecorder;
  insertRight(index: number, content: Buffer | string): UpdateRecorder;
  remove(index: number, length: number): UpdateRecorder;
}

Exception Types

class SchematicsException extends Error {}

class FileDoesNotExistException extends SchematicsException {
  constructor(path: string);
}

class FileAlreadyExistException extends SchematicsException {
  constructor(path: string);
}

class ContentHasMutatedException extends SchematicsException {
  constructor(path: string);
}

class MergeConflictException extends SchematicsException {
  constructor(path: string);
}