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

rule-system.mddocs/

Rule System

Composable transformation functions that modify trees in a functional, predictable way. Rules are the building blocks of schematics, allowing for complex file system transformations through simple, composable functions.

Capabilities

Core Rule Types

The fundamental types that power the rule system.

/**
 * A function that transforms a tree, can be sync or async
 */
type Rule = (tree: Tree, context: SchematicContext) => 
  Tree | Observable<Tree> | Rule | Promise<void | Tree | Rule> | void;

/**
 * A function that creates a tree from context
 */
type Source = (context: SchematicContext) => Tree | Observable<Tree>;

/**
 * Factory function that creates rules from options
 */
type RuleFactory<T> = (options: T) => Rule;

/**
 * Function that operates on individual files
 */
type FileOperator = (entry: FileEntry) => FileEntry | null;

Basic Rule Functions

Core functions for creating and combining rules.

/**
 * Creates a source that returns the given tree
 */
function source(tree: Tree): Source;

/**
 * Creates a source that returns an empty tree
 */
function empty(): Source;

/**
 * Returns a rule that does nothing (identity function)
 */
function noop(): Rule;

/**
 * Chains multiple rules into a single rule that executes sequentially
 */
function chain(rules: Iterable<Rule> | AsyncIterable<Rule>): Rule;

/**
 * Applies multiple rules to a source and returns the transformed source
 */
function apply(source: Source, rules: Rule[]): Source;

/**
 * Merges input tree with the source tree using specified strategy
 */
function mergeWith(source: Source, strategy?: MergeStrategy): Rule;

Usage Examples:

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

// Simple rule that creates a file
function createReadme(): Rule {
  return (tree: Tree, context: SchematicContext) => {
    tree.create('/README.md', '# My Project\n\nThis is a generated project.');
    return tree;
  };
}

// Chain multiple rules together
function setupProject(): Rule {
  return chain([
    createReadme(),
    createPackageJson(),
    createGitignore()
  ]);
}

// Apply rules to a source
function generateFromTemplate(templateUrl: string, options: any): Rule {
  return mergeWith(
    apply(url(templateUrl), [
      template(options),
      move('/src')
    ])
  );
}

Tree Filtering and Transformation Rules

Rules for filtering and transforming files within trees.

/**
 * Filters tree files based on predicate function
 */
function filter(predicate: FilePredicate<boolean>): Rule;

/**
 * Applies file operator to each file in the tree
 */
function forEach(operator: FileOperator): Rule;

/**
 * Conditionally applies file operator based on predicate
 */
function when(predicate: FilePredicate<boolean>, operator: FileOperator): FileOperator;

/**
 * Executes rule on a branch and merges back to original tree
 */
function branchAndMerge(rule: Rule, strategy?: MergeStrategy): Rule;

/**
 * Partitions tree, applies different rules to each partition, then merges
 */
function partitionApplyMerge(
  predicate: FilePredicate<boolean>, 
  ruleYes: Rule, 
  ruleNo?: Rule
): Rule;

/**
 * Composes multiple file operators into a single operator
 */
function composeFileOperators(operators: FileOperator[]): FileOperator;

/**
 * Applies rules to a subtree at the specified path
 */
function applyToSubtree(path: string, rules: Rule[]): Rule;

Usage Examples:

import { 
  filter, 
  forEach, 
  when, 
  branchAndMerge,
  partitionApplyMerge 
} from "@angular-devkit/schematics";

// Filter only TypeScript files
const onlyTsFiles = filter((path) => path.endsWith('.ts'));

// Transform all files with uppercase content
const uppercaseContent = forEach((entry) => {
  return {
    ...entry,
    content: Buffer.from(entry.content.toString().toUpperCase())
  };
});

// Conditionally modify files
const addHeader = when(
  (path) => path.endsWith('.ts'),
  (entry) => ({
    ...entry,
    content: Buffer.from(`// Generated file\n${entry.content.toString()}`)
  })
);

// Work on a branch to avoid conflicts
const safeTransform = branchAndMerge(
  chain([
    filter((path) => path.includes('/src/')),
    forEach(addHeader)
  ])
);

Movement Rules

Rules for moving and organizing files within the tree.

/**
 * Moves files or directories from one path to another
 * @param from - Source path pattern or specific path
 * @param to - Destination path (optional, defaults to root)
 */
function move(from: string, to?: string): Rule;

Usage Examples:

import { move } from "@angular-devkit/schematics";

// Move all files from /temp to /src
const moveToSrc = move('/temp', '/src');

// Move files with a specific pattern
const moveComponents = move('/components', '/src/app/components');

Schematic Execution Rules

Rules for executing other schematics within the current schematic.

/**
 * Runs a schematic from the same collection
 */
function schematic<OptionT>(
  schematicName: string,
  options: OptionT,
  executionOptions?: Partial<ExecutionOptions>
): Rule;

/**
 * Runs a schematic from a different collection
 */
function externalSchematic<OptionT>(
  collectionName: string,
  schematicName: string,
  options: OptionT,
  executionOptions?: Partial<ExecutionOptions>
): Rule;

Usage Examples:

import { schematic, externalSchematic } from "@angular-devkit/schematics";

// Run another schematic from same collection
function generateWithComponent(options: any): Rule {
  return chain([
    schematic('component', {
      name: options.componentName,
      path: options.path
    }),
    // Additional rules...
  ]);
}

// Run schematic from external collection  
function generateWithAngularMaterial(): Rule {
  return externalSchematic('@angular/material', 'nav', {
    name: 'main-nav'
  });
}

URL Source Rules

Rules for creating sources from external URLs and local file systems.

/**
 * Creates a source from a URL string (file://, http://, etc.)
 */
function url(urlString: string): Source;

Usage Examples:

import { url, apply, template, move } from "@angular-devkit/schematics";

// Load templates from local file system
function generateFromLocalTemplate(options: any): Rule {
  return mergeWith(
    apply(url('./files'), [
      template({
        ...options,
        classify: (str: string) => str.charAt(0).toUpperCase() + str.slice(1)
      }),
      move(options.path || '/')
    ])
  );
}

// Load from HTTP URL (if supported by host)
function generateFromRemoteTemplate(options: any): Rule {
  return mergeWith(
    apply(url('https://example.com/templates'), [
      template(options)
    ])
  );
}

Rule Execution Utilities

Utilities for executing rules and sources with proper error handling.

/**
 * Calls a source function and returns observable tree
 */
function callSource(source: Source, context: SchematicContext): Observable<Tree>;

/**
 * Calls a rule function and returns observable tree
 */
function callRule(
  rule: Rule,
  input: Tree | Observable<Tree>,
  context: SchematicContext
): Observable<Tree>;

Random Generation Rules

Utility for generating random test files.

/**
 * Creates a source with randomly generated files for testing
 */
function random(options: RandomOptions): Source;

interface RandomOptions {
  /** Number of files to generate */
  count?: number;
  /** File content options */
  content?: {
    /** Minimum content length */
    minLength?: number;
    /** Maximum content length */
    maxLength?: number;
  };
  /** Path generation options */
  path?: {
    /** Path depth range */
    depth?: [number, number];
    /** File extension options */
    extensions?: string[];
  };
}

Exception Classes

Exception types that can be thrown during rule execution.

/**
 * Thrown when a rule returns an invalid result
 */
class InvalidRuleResultException extends SchematicsException {
  constructor(result?: any);
}

/**
 * Thrown when a source returns an invalid result
 */
class InvalidSourceResultException extends SchematicsException {
  constructor(result?: any);
}

Advanced Usage Patterns

Complex Rule Composition:

import {
  Rule,
  chain,
  apply,
  mergeWith,
  url,
  template,
  move,
  filter,
  forEach,
  when,
  branchAndMerge
} from "@angular-devkit/schematics";

function complexSchematic(options: ComplexOptions): Rule {
  return (tree: Tree, context: SchematicContext) => {
    // Conditional logic in rules
    const rules: Rule[] = [];
    
    if (options.generateComponent) {
      rules.push(
        mergeWith(
          apply(url('./component-files'), [
            template(options),
            move(options.componentPath)
          ])
        )
      );
    }
    
    if (options.generateService) {
      rules.push(
        mergeWith(
          apply(url('./service-files'), [
            template(options),
            move(options.servicePath)
          ])
        )
      );
    }
    
    // Process existing files
    rules.push(
      branchAndMerge(
        chain([
          filter((path) => path.endsWith('.ts')),
          forEach(
            when(
              (path) => path.includes('/src/'),
              (entry) => ({
                ...entry,
                content: Buffer.from(
                  addImports(entry.content.toString(), options.imports)
                )
              })
            )
          )
        ])
      )
    );
    
    return chain(rules)(tree, context);
  };
}

Type Definitions

interface ExecutionOptions {
  interactive: boolean;
  dryRun: boolean;
  force: boolean;
  defaults: boolean;
}

type TaskId = symbol;

interface TaskConfigurationGenerator<T> {
  name: string;
  options: T;
}