CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-nestjs--schematics

Angular-style schematics for the NestJS framework, enabling generation of application components through a command-line interface.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

utilities.mddocs/

Utility Library

Comprehensive toolkit for TypeScript/JavaScript code manipulation, module management, and project structure operations. Provides AST parsers, file system helpers, and NestJS-specific utilities for programmatic code generation and modification.

Capabilities

Module Management

MetadataManager

Manages metadata entries within @Module decorators, allowing programmatic insertion of providers, controllers, imports, and exports.

/**
 * Manages metadata entries within @Module decorators
 */
class MetadataManager {
  /**
   * Insert metadata entry into a module decorator
   * @param metadata - Type of metadata ('providers', 'controllers', 'imports', 'exports')
   * @param symbol - Symbol name to insert
   * @param staticOptions - Optional static configuration
   * @returns Updated content or undefined if insertion failed
   */
  insert(
    metadata: string, 
    symbol: string, 
    staticOptions?: DeclarationOptions['staticOptions']
  ): string | undefined;
}

Usage Examples:

import { MetadataManager } from '@nestjs/schematics';

const manager = new MetadataManager();

// Insert provider into module
const updatedContent = manager.insert('providers', 'UserService');

// Insert with static options
const updatedContent2 = manager.insert('providers', 'ConfigService', {
  name: 'CONFIG_OPTIONS',
  value: 'configOptions'
});

ModuleDeclarator

Main orchestrator for module imports and metadata declarations, combining import and metadata operations.

/**
 * Main orchestrator for module imports and metadata declarations
 */
class ModuleDeclarator {
  /**
   * Declare module imports and metadata
   * @param content - Source file content
   * @param options - Declaration configuration
   * @returns Updated file content
   */
  declare(content: string, options: DeclarationOptions): string;
}

interface DeclarationOptions {
  /** Metadata type to modify */
  metadata: string;
  /** Symbol to declare */
  symbol: string;
  /** Symbol type (class, function, etc.) */
  type?: string;
  /** Static options for configuration */
  staticOptions?: {
    name: string;
    value: string;
  };
}

Usage Examples:

import { ModuleDeclarator } from '@nestjs/schematics';

const declarator = new ModuleDeclarator();

// Declare service in module
const updatedContent = declarator.declare(moduleContent, {
  metadata: 'providers',
  symbol: 'UserService',
  type: 'class'
});

// Declare controller with import
const updatedContent2 = declarator.declare(moduleContent, {
  metadata: 'controllers',
  symbol: 'AuthController',
  type: 'class'
});

ModuleImportDeclarator

Handles import statement declarations in TypeScript files.

/**
 * Declares module imports in TypeScript files
 */
class ModuleImportDeclarator {
  /**
   * Declare import statements in file content
   * @param content - Source file content
   * @param options - Import declaration options
   * @returns Updated file content with imports
   */
  declare(content: string, options: DeclarationOptions): string;
}

ModuleMetadataDeclarator

Handles metadata declarations within module decorators.

/**
 * Declares metadata in TypeScript files
 */
class ModuleMetadataDeclarator {
  /**
   * Declare metadata in module decorators
   * @param content - Source file content
   * @param options - Metadata declaration options
   * @returns Updated file content with metadata
   */
  declare(content: string, options: DeclarationOptions): string;
}

File System Operations

ModuleFinder

Locates module files within directory structures, supporting various naming conventions and patterns.

/**
 * Finds module files in directory structures
 */
class ModuleFinder {
  /**
   * Find module file based on options
   * @param options - Search configuration
   * @returns Path to found module or null
   */
  find(options: FindOptions): Path | null;
}

interface FindOptions {
  /** Module name to search for */
  name: string;
  /** Base path to search in */
  path: Path;
}

Usage Examples:

import { ModuleFinder } from '@nestjs/schematics';

const finder = new ModuleFinder();

// Find app module
const appModulePath = finder.find({
  name: 'app',
  path: '/src' as Path
});

// Find specific module
const userModulePath = finder.find({
  name: 'users',
  path: '/src/users' as Path
});

PathSolver

Computes relative paths between different locations in the project structure.

/**
 * Computes relative paths between locations
 */
class PathSolver {
  /**
   * Calculate relative path between two locations
   * @param from - Source path
   * @param to - Target path
   * @returns Relative path string
   */
  relative(from: Path, to: Path): string;
}

Usage Examples:

import { PathSolver } from '@nestjs/schematics';

const solver = new PathSolver();

// Calculate import path
const relativePath = solver.relative(
  '/src/users/users.controller.ts' as Path,
  '/src/users/users.service.ts' as Path
);
// Result: './users.service'

Name and Path Processing

NameParser

Parses names and paths for schematics, handling various naming conventions and path structures.

/**
 * Parses names and paths for schematics
 */
class NameParser {
  /**
   * Parse name and path options into location structure
   * @param options - Parsing configuration
   * @returns Parsed location with name and path
   */
  parse(options: ParseOptions): Location;
}

interface ParseOptions {
  /** Component name (can include path) */
  name: string;
  /** Base path for generation */
  path?: string;
}

interface Location {
  /** Parsed component name */
  name: string;
  /** Resolved path */
  path: Path;
}

Usage Examples:

import { NameParser } from '@nestjs/schematics';

const parser = new NameParser();

// Parse simple name
const location1 = parser.parse({ name: 'user-service' });
// Result: { name: 'user-service', path: '.' }

// Parse name with path
const location2 = parser.parse({ 
  name: 'auth/auth-service',
  path: 'src/modules'
});
// Result: { name: 'auth-service', path: 'src/modules/auth' }

// Parse kebab-case to different formats
const location3 = parser.parse({ name: 'user-profile-service' });
// Handles conversion to UserProfileService, user-profile-service, etc.

JSON File Operations

JSONFile

Advanced JSON file manipulation with AST parsing, supporting comments and complex modifications.

/**
 * JSON file manipulation with AST parsing
 */
class JSONFile {
  /**
   * Get value at JSON path
   * @param jsonPath - Array representing path to value
   * @returns Value at path or undefined
   */
  get(jsonPath: JSONPath): unknown;

  /**
   * Modify value at JSON path
   * @param jsonPath - Array representing path to value
   * @param value - New value to set
   * @param insertInOrder - Optional insertion order function
   */
  modify(
    jsonPath: JSONPath, 
    value: JsonValue | undefined, 
    insertInOrder?: InsertionIndex | false
  ): void;

  /**
   * Remove value at JSON path
   * @param jsonPath - Array representing path to remove
   */
  remove(jsonPath: JSONPath): void;
}

type JSONPath = (string | number)[];
type InsertionIndex = (properties: string[]) => number;
type JsonValue = string | number | boolean | null | JsonObject | JsonArray;
interface JsonObject { [key: string]: JsonValue; }
interface JsonArray extends Array<JsonValue> {}

Usage Examples:

import { JSONFile } from '@nestjs/schematics';

// Create JSONFile instance from tree
const packageJson = new JSONFile(tree, 'package.json');

// Get dependency version
const nestVersion = packageJson.get(['dependencies', '@nestjs/core']);

// Add new dependency
packageJson.modify(['dependencies', 'lodash'], '^4.17.21');

// Add script with ordered insertion
packageJson.modify(['scripts', 'test:e2e'], 'jest --config ./test/jest-e2e.json', 
  (props) => props.sort().indexOf('test:e2e')
);

// Remove devDependency
packageJson.remove(['devDependencies', 'old-package']);

String and Formatting Utilities

Formatting Functions

Various string formatting utilities for consistent naming conventions.

/**
 * Normalize string to kebab-case or snake_case
 * @param str - Input string
 * @returns Normalized string
 */
function normalizeToKebabOrSnakeCase(str: string): string;

Usage Examples:

import { normalizeToKebabOrSnakeCase } from '@nestjs/schematics';

// Convert various formats
const kebab1 = normalizeToKebabOrSnakeCase('UserService'); // 'user-service'
const kebab2 = normalizeToKebabOrSnakeCase('user_profile'); // 'user-profile'
const kebab3 = normalizeToKebabOrSnakeCase('API_KEY'); // 'api-key'

Object Manipulation

Object Sorting

Utilities for organizing object properties in consistent order.

/**
 * Sort object properties in place by keys
 * @param object - Object to sort
 * @returns Sorted object
 */
function inPlaceSortByKeys(object: Record<string, any>): Record<string, any>;

Usage Examples:

import { inPlaceSortByKeys } from '@nestjs/schematics';

const config = {
  providers: ['ServiceA'],
  imports: ['ModuleB'],
  controllers: ['ControllerC'],
  exports: ['ServiceA']
};

// Sort for consistent output
const sortedConfig = inPlaceSortByKeys(config);
// Result: { controllers: [...], exports: [...], imports: [...], providers: [...] }

Source Root Management

Source Root Helpers

Utilities for managing source root directories in projects.

/**
 * Check if generation is happening in root directory
 * @param host - Virtual file system tree
 * @param extraFiles - Additional files to check for
 * @returns True if in root directory
 */
function isInRootDirectory(host: Tree, extraFiles?: string[]): boolean;

/**
 * Merge source root configuration into options
 * @param options - Schematic options
 * @returns Rule for merging source root
 */
function mergeSourceRoot<T>(options: T): Rule;

Usage Examples:

import { isInRootDirectory, mergeSourceRoot } from '@nestjs/schematics';

// Check if in root
const inRoot = isInRootDirectory(tree, ['nest-cli.json']);

// Apply source root merging
return chain([
  mergeSourceRoot(options),
  // ... other rules
]);

Dependency Management

Dependencies Utilities

Functions for managing package.json dependencies programmatically.

/**
 * Add dependency to package.json
 * @param tree - Virtual file system
 * @param dependency - Dependency specification
 * @param pkgJsonPath - Optional package.json path
 */
function addPackageJsonDependency(
  tree: Tree, 
  dependency: NodeDependency, 
  pkgJsonPath?: string
): void;

/**
 * Get dependency from package.json
 * @param tree - Virtual file system
 * @param name - Dependency name
 * @param pkgJsonPath - Optional package.json path
 * @returns Dependency specification or null
 */
function getPackageJsonDependency(
  tree: Tree, 
  name: string, 
  pkgJsonPath?: string
): NodeDependency | null;

interface NodeDependency {
  type: NodeDependencyType;
  name: string;
  version: string;
  overwrite?: boolean;
}

enum NodeDependencyType {
  Default = 'dependencies',
  Dev = 'devDependencies',
  Peer = 'peerDependencies',
  Optional = 'optionalDependencies'
}

Usage Examples:

import { 
  addPackageJsonDependency, 
  getPackageJsonDependency, 
  NodeDependencyType 
} from '@nestjs/schematics';

// Add production dependency
addPackageJsonDependency(tree, {
  type: NodeDependencyType.Default,
  name: '@nestjs/jwt',
  version: '^8.0.0'
});

// Add dev dependency
addPackageJsonDependency(tree, {
  type: NodeDependencyType.Dev,
  name: '@types/jest',
  version: '^27.0.0',
  overwrite: true
});

// Check existing dependency
const existing = getPackageJsonDependency(tree, '@nestjs/core');
if (existing) {
  console.log(`Found ${existing.name}@${existing.version}`);
}

File Reading System

Reader Interface

Abstract interface for file reading operations with sync and async support.

/**
 * Interface for file reading operations
 */
interface Reader {
  /** List available files */
  list(): string[] | Promise<string[]>;
  
  /** Read file content (async) */
  read(name: string): string | Promise<string>;
  
  /** Read file content (sync) */
  readSync(name: string): string;
  
  /** Read any of the specified files (async) */
  readAnyOf(filenames: string[]): string | Promise<string | undefined>;
  
  /** Read any of the specified files (sync) */
  readSyncAnyOf(filenames: string[]): string | undefined;
}

FileSystemReader

Concrete implementation of Reader for file system operations.

/**
 * File system implementation of Reader interface
 */
class FileSystemReader implements Reader {
  /**
   * Create file system reader
   * @param directory - Base directory for file operations
   */
  constructor(private readonly directory: string);
  
  list(): string[];
  read(name: string): string;
  readSync(name: string): string;
  readAnyOf(filenames: string[]): string | undefined;
  readSyncAnyOf(filenames: string[]): string | undefined;
}

Usage Examples:

import { FileSystemReader } from '@nestjs/schematics';

// Create reader for templates directory
const reader = new FileSystemReader('./templates');

// List available template files
const templates = reader.list();

// Read specific template
const controllerTemplate = reader.readSync('controller.template.ts');

// Read any available config file
const config = reader.readSyncAnyOf([
  'nest-cli.json',
  'angular.json',
  '.nestcli.json'
]);

Default Constants

Pre-configured values for consistent project generation.

/** Default application author */
const DEFAULT_AUTHOR: string = '';

/** Default application description */
const DEFAULT_DESCRIPTION: string = '';

/** Default programming language */
const DEFAULT_LANGUAGE: string = 'ts';

/** Default application version */
const DEFAULT_VERSION: string = '0.0.1';

/** Default source path name */
const DEFAULT_PATH_NAME: string = 'src';

/** Default libraries path for monorepo */
const DEFAULT_LIB_PATH: string = 'libs';

/** Default applications path for monorepo */
const DEFAULT_APPS_PATH: string = 'apps';

/** Default application name */
const DEFAULT_APP_NAME: string = 'app';

/** Default directory entry for app */
const DEFAULT_DIR_ENTRY_APP: string = 'main';

/** Test environment identifier */
const TEST_ENV: string = 'test';

/** Project type constants */
const PROJECT_TYPE: {
  readonly LIBRARY: 'library';
  readonly APPLICATION: 'application';
};

Integration with Angular DevKit

All utilities are designed to work seamlessly with Angular DevKit's schematic system:

// Common Angular DevKit types used throughout utilities
type Tree = import('@angular-devkit/schematics').Tree;
type Rule = import('@angular-devkit/schematics').Rule;
type SchematicContext = import('@angular-devkit/schematics').SchematicContext;
type Path = import('@angular-devkit/core').Path;

These utilities provide the foundation for all NestJS schematics, enabling consistent and reliable code generation across the entire framework ecosystem.

docs

index.md

schematics.md

utilities.md

tile.json