CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-schematics--angular

Angular schematics collection providing code generators for Angular applications, components, services, and other constructs.

Pending
Overview
Eval results
Files

ast-utilities.mddocs/

AST Utilities

Utilities for parsing, analyzing, and modifying TypeScript Abstract Syntax Trees (AST) to programmatically update Angular code. These functions enable precise code modifications for schematics.

Capabilities

Node Finding

Functions for locating specific nodes within TypeScript AST structures.

/**
 * Finds a node of a specific kind with required text content
 * @param node - Root node to search from
 * @param kind - TypeScript syntax kind to find
 * @param text - Text content to match (required)
 * @returns Found node or null if not found
 */
function findNode(
  node: ts.Node, 
  kind: ts.SyntaxKind, 
  text: string
): ts.Node | null;

/**
 * Gets all nodes from a source file
 * @param sourceFile - TypeScript source file
 * @returns Array of all nodes in the file
 */
function getSourceNodes(sourceFile: ts.SourceFile): ts.Node[];

/**
 * Finds all nodes of a specific kind
 * @param node - Root node to search from
 * @param kind - TypeScript syntax kind to find
 * @param max - Maximum number of nodes to find
 * @returns Array of found nodes
 */
function findNodes(
  node: ts.Node, 
  kind: ts.SyntaxKind, 
  max?: number
): ts.Node[];

Usage Example:

import { findNode, findNodes } from '@schematics/angular/utility/ast-utils';
import * as ts from 'typescript';

export function findImports(): Rule {
  return (tree: Tree) => {
    const source = tree.readText('/src/app/app.module.ts');
    const sourceFile = ts.createSourceFile('app.module.ts', source, ts.ScriptTarget.Latest);
    
    // Find import declarations
    const imports = findNodes(sourceFile, ts.SyntaxKind.ImportDeclaration);
    
    // Find specific import
    const angularCoreImport = findNode(sourceFile, ts.SyntaxKind.ImportDeclaration, '@angular/core');
    
    return tree;
  };
}

Module Modifications

Functions for adding imports, declarations, and providers to Angular modules.

/**
 * Adds an import statement to an Angular module
 * @param source - Source file containing the module
 * @param modulePath - Path to the module file
 * @param symbolName - Name of the symbol to import
 * @param fileName - File to import from
 * @returns Array of changes to apply
 */
function addImportToModule(
  source: ts.SourceFile,
  modulePath: string,
  symbolName: string,
  fileName: string
): Change[];

/**
 * Adds a declaration to an Angular module's declarations array
 * @param source - Source file containing the module
 * @param modulePath - Path to the module file
 * @param classifiedName - Name of the component/directive/pipe
 * @param importPath - Path to import the declaration from
 * @returns Array of changes to apply
 */
function addDeclarationToModule(
  source: ts.SourceFile,
  modulePath: string,
  classifiedName: string,
  importPath: string
): Change[];

/**
 * Adds an export to an Angular module's exports array
 * @param source - Source file containing the module
 * @param modulePath - Path to the module file
 * @param classifiedName - Name of the item to export
 * @param importPath - Path to import the export from
 * @returns Array of changes to apply
 */
function addExportToModule(
  source: ts.SourceFile,
  modulePath: string,
  classifiedName: string,
  importPath: string
): Change[];

/**
 * Adds a provider to an Angular module's providers array
 * @param source - Source file containing the module
 * @param modulePath - Path to the module file
 * @param classifiedName - Name of the provider
 * @param importPath - Path to import the provider from
 * @returns Array of changes to apply
 */
function addProviderToModule(
  source: ts.SourceFile,
  modulePath: string,
  classifiedName: string,
  importPath: string
): Change[];

/**
 * Adds a component to bootstrap array in Angular module
 * @param source - Source file containing the module
 * @param modulePath - Path to the module file
 * @param classifiedName - Name of the component to bootstrap
 * @param importPath - Path to import the component from
 * @returns Array of changes to apply
 */
function addBootstrapToModule(
  source: ts.SourceFile,
  modulePath: string,
  classifiedName: string,
  importPath: string
): Change[];

Usage Example:

import { 
  addDeclarationToModule, 
  addImportToModule 
} from '@schematics/angular/utility/ast-utils';
import { applyToUpdateRecorder } from '@schematics/angular/utility/change';

export function addComponentToModule(): Rule {
  return (tree: Tree) => {
    const modulePath = '/src/app/app.module.ts';
    const source = tree.readText(modulePath);
    const sourceFile = ts.createSourceFile(modulePath, source, ts.ScriptTarget.Latest);
    
    // Add import and declaration
    const changes = [
      ...addImportToModule(sourceFile, modulePath, 'MyComponent', './my-component/my-component'),
      ...addDeclarationToModule(sourceFile, modulePath, 'MyComponent', './my-component/my-component')
    ];
    
    // Apply changes
    const recorder = tree.beginUpdate(modulePath);
    applyToUpdateRecorder(recorder, changes);
    tree.commitUpdate(recorder);
    
    return tree;
  };
}

Import Management

Functions for adding and managing import statements.

/**
 * Inserts an import statement into a source file
 * @param source - Source file to modify
 * @param fileToEdit - Path to the file being edited
 * @param symbolName - Name of the symbol to import
 * @param fileName - File to import from
 * @param isDefault - Whether this is a default import
 * @returns Change object representing the import insertion
 */
function insertImport(
  source: ts.SourceFile,
  fileToEdit: string,
  symbolName: string,
  fileName: string,
  isDefault?: boolean
): Change;

/**
 * Inserts text after the last occurrence of specified nodes
 * @param nodes - Array of nodes to search through
 * @param toInsert - Text to insert
 * @param file - File path for the change
 * @param fallbackPos - Position to use if no nodes found
 * @returns Change object representing the insertion
 */
function insertAfterLastOccurrence(
  nodes: ts.Node[],
  toInsert: string,
  file: string,
  fallbackPos?: number
): Change;

Decorator Analysis

Functions for analyzing and working with TypeScript decorators.

/**
 * Gets decorator metadata from a source file
 * @param source - Source file to analyze
 * @param identifier - Decorator name to find (e.g., 'Component')
 * @param module - Module the decorator is imported from (e.g., '@angular/core')
 * @returns Array of nodes representing decorator metadata
 */
function getDecoratorMetadata(
  source: ts.SourceFile,
  identifier: string,
  module: string
): ts.Node[];

/**
 * Adds a symbol to NgModule metadata (imports, declarations, providers, etc.)
 * @param source - Source file containing NgModule
 * @param ngModulePath - Path to the NgModule file
 * @param metadataField - Field to add to ('imports', 'declarations', 'providers', etc.)
 * @param symbolName - Name of the symbol to add
 * @param importPath - Optional import path for the symbol
 * @returns Array of changes to apply
 */
function addSymbolToNgModuleMetadata(
  source: ts.SourceFile,
  ngModulePath: string,
  metadataField: string,
  symbolName: string,
  importPath?: string
): Change[];

Module Discovery

Functions for finding and working with Angular modules.

/**
 * Gets the path to the app module from main.ts
 * @param host - Tree host
 * @param mainPath - Path to main.ts file
 * @returns Path to the app module
 */
function getAppModulePath(host: Tree, mainPath: string): string;

/**
 * Finds the module file from options and directory structure
 * @param host - Tree host  
 * @param generateDir - Directory where files are being generated
 * @returns Path to the module file
 */
function findModule(host: Tree, generateDir: string): string;

/**
 * Finds module from schematic options
 * @param host - Tree host
 * @param options - Options containing module information
 * @returns Path to module file or undefined
 */
function findModuleFromOptions(host:Tree, options: ModuleOptions): string | undefined;

interface ModuleOptions {
  module?: string;
  name: string;
  path?: string;
  flat?: boolean;
}

Routing Utilities

Functions for working with Angular routing configuration.

/**
 * Adds a route declaration to a module
 * @param source - Source file containing routes
 * @param fileToAdd - File path being modified
 * @param routeLiteral - Route configuration as string
 * @returns Array of changes to apply
 */
function addRouteDeclarationToModule(
  source: ts.SourceFile,
  fileToAdd: string,
  routeLiteral: string
): Change[];

/**
 * Gets the RouterModule declaration from a source file
 * @param source - Source file to search
 * @returns Expression node for RouterModule or undefined
 */
function getRouterModuleDeclaration(source: ts.SourceFile): ts.Expression | undefined;

/**
 * Checks if an import is already present in the source file
 * @param source - Source file to check
 * @param className - Class name to look for
 * @param importPath - Import path to look for
 * @returns True if import already exists
 */
function isImported(
  source: ts.SourceFile,
  className: string,
  importPath: string
): boolean;

/**
 * Gets metadata field from decorator
 * @param source - Source file containing decorator
 * @param identifier - Decorator name
 * @param module - Module the decorator is from
 * @param field - Metadata field to get
 * @returns Array of nodes for the field
 */
function getMetadataField(
  source: ts.SourceFile,
  identifier: string,
  module: string,
  field: string
): ts.Node[];

/**
 * Checks if source file has a top-level identifier
 * @param source - Source file to check
 * @param name - Identifier name to look for
 * @returns True if identifier exists at top level
 */
function hasTopLevelIdentifier(source: ts.SourceFile, name: string): boolean;

Change System

Change Types

/**
 * Abstract base class for representing code changes
 */
abstract class Change {
  /** File path this change applies to */
  readonly path: string | null;
  /** Order for applying multiple changes */
  readonly order: number;  
  /** Human-readable description of the change */
  readonly description: string;
  
  /**
   * Applies this change to an UpdateRecorder
   * @param host - UpdateRecorder to apply changes to
   * @returns Modified UpdateRecorder
   */
  abstract apply(host: UpdateRecorder): UpdateRecorder;
}

/**
 * Change that inserts text at a specific position
 */
class InsertChange extends Change {
  constructor(path: string, pos: number, toAdd: string);
}

/**
 * Change that removes text from a specific position and length
 */
class RemoveChange extends Change {
  constructor(path: string, pos: number, length: number);
}

/**
 * Change that replaces text at a specific position
 */
class ReplaceChange extends Change {
  constructor(path: string, pos: number, oldText: string, newText: string);
}

/**
 * Change that does nothing (no-op)
 */
class NoopChange extends Change {
  constructor();
}

Applying Changes

/**
 * Applies an array of changes to an UpdateRecorder
 * @param recorder - UpdateRecorder to apply changes to
 * @param changes - Array of changes to apply
 */
function applyToUpdateRecorder(recorder: UpdateRecorder, changes: Change[]): void;

Usage Example:

import { applyToUpdateRecorder, InsertChange } from '@schematics/angular/utility/change';

export function addImport(): Rule {
  return (tree: Tree) => {
    const filePath = '/src/app/app.component.ts';
    const changes = [
      new InsertChange(filePath, 0, "import { Component } from '@angular/core';\n")
    ];
    
    const recorder = tree.beginUpdate(filePath);
    applyToUpdateRecorder(recorder, changes);
    tree.commitUpdate(recorder);
    
    return tree;
  };
}

Install with Tessl CLI

npx tessl i tessl/npm-schematics--angular

docs

ast-utilities.md

dependency-management.md

index.md

schematics.md

standalone-utilities.md

workspace-utilities.md

tile.json