CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-yeoman-generator

Rails-inspired generator system that provides scaffolding for your apps

Overview
Eval results
Files

file-system.mddocs/

File System Operations

Template rendering, file copying, and destination management with support for EJS templating and conflict resolution through mem-fs-editor integration.

Capabilities

Template Operations

Methods for reading, copying, and rendering template files with EJS processing.

/**
 * Read file from templates folder
 * Shortcut for this.fs.read(this.templatePath(filepath))
 */
readTemplate(...args: Parameters<MemFsEditor['read']>): ReturnType<MemFsEditor['read']>;

/**
 * Copy file from templates folder to destination folder
 * Shortcut for this.fs.copy(this.templatePath(from), this.destinationPath(to))
 */
copyTemplate(...args: Parameters<MemFsEditor['copy']>): ReturnType<MemFsEditor['copy']>;

/**
 * Async copy file from templates folder to destination folder
 */
async copyTemplateAsync(...args: Parameters<MemFsEditor['copyAsync']>): ReturnType<MemFsEditor['copyAsync']>;

Usage Examples:

export default class MyGenerator extends Generator {
  writing() {
    // Read template content
    const content = this.readTemplate('config.json');
    
    // Copy template file
    this.copyTemplate('static-file.js', 'src/static-file.js');
    
    // Copy multiple files with options
    this.copyTemplate(  
      'assets/**/*',
      'public/',
      { globOptions: { dot: true } }
    );
  }
  
  async install() {
    // Async copy for large files
    await this.copyTemplateAsync('large-asset.bin', 'assets/large-asset.bin');
  }
}

Template Rendering

Render EJS templates with data substitution and processing.

/**
 * Copy a template from templates folder to the destination with EJS processing
 * @param source - Template file, absolute or relative to templatePath()
 * @param destination - Destination, absolute or relative to destinationPath()  
 * @param templateData - EJS data for template processing
 * @param templateOptions - EJS processing options
 * @param copyOptions - mem-fs-editor copy options
 */
renderTemplate<D extends TemplateData = TemplateData>(
  source: string | string[],
  destination: string | string[],
  templateData?: string | D,
  templateOptions?: TemplateOptions,
  copyOptions?: CopyOptions
): void;

/**
 * Async version of renderTemplate
 */
async renderTemplateAsync<D extends TemplateData = TemplateData>(
  source: string | string[],
  destination: string | string[],
  templateData?: string | D,
  templateOptions?: TemplateOptions,
  copyOptions?: CopyOptions
): Promise<void>;

Usage Examples:

export default class MyGenerator extends Generator {
  async prompting() {
    this.answers = await this.prompt([
      { name: 'name', message: 'Project name?' },
      { name: 'author', message: 'Author name?' }
    ]);
  }
  
  writing() {
    // Render template with data
    this.renderTemplate(
      'package.json.ejs',
      'package.json',
      {
        name: this.answers.name,
        author: this.answers.author,
        version: '1.0.0'
      }
    );
    
    // Render with custom EJS options
    this.renderTemplate(
      'config.js.ejs',
      'config/config.js',
      this.answers,
      { 
        delimiter: '?',  // Use <?= %> instead of <%= %>
        openDelimiter: '[',
        closeDelimiter: ']'
      }
    );
  }
}

Batch Template Rendering

Render multiple templates with conditional logic.

/**
 * Copy multiple templates from templates folder to the destination
 * @param templates - Array of template configurations
 * @param templateData - Default EJS data for all templates
 */
renderTemplates<D extends TemplateData = TemplateData>(
  templates: Templates<D, typeof this>,
  templateData?: string | D
): void;

/**
 * Async version of renderTemplates
 */
async renderTemplatesAsync<D extends TemplateData = TemplateData>(
  templates: Templates<D, typeof this>,
  templateData?: string | D
): Promise<void>;

// Template configuration type
interface Template<D extends TemplateData, G> {
  source: string;
  destination?: string;
  when?: (data: D, generator: G) => boolean;
  copyOptions?: CopyOptions;
  templateData?: TemplateData;
  templateOptions?: TemplateOptions;
}

type Templates<D extends TemplateData, G> = Array<Template<D, G>>;

Usage Examples:

export default class MyGenerator extends Generator {
  writing() {
    const templates = [
      {
        source: 'src/index.js.ejs',
        destination: 'src/index.js'
      },
      {
        source: 'test/test.js.ejs', 
        destination: 'test/index.test.js',
        when: (data) => data.includeTests
      },
      {
        source: 'docker/Dockerfile.ejs',
        destination: 'Dockerfile',
        when: (data) => data.useDocker,
        templateData: { baseImage: 'node:18' }
      }
    ];
    
    this.renderTemplates(templates, this.answers);
  }
}

Destination File Operations

Methods for reading, writing, and manipulating files in the destination directory.

/**
 * Read file from destination folder
 * Shortcut for this.fs.read(this.destinationPath(filepath))
 */
readDestination(...args: Parameters<MemFsEditor['read']>): ReturnType<MemFsEditor['read']>;

/**
 * Read JSON file from destination folder
 * Shortcut for this.fs.readJSON(this.destinationPath(filepath))
 */
readDestinationJSON(...args: Parameters<MemFsEditor['readJSON']>): ReturnType<MemFsEditor['readJSON']>;

/**
 * Write file to destination folder
 * Shortcut for this.fs.write(this.destinationPath(filepath))
 */  
writeDestination(...args: Parameters<MemFsEditor['write']>): ReturnType<MemFsEditor['write']>;

/**
 * Write JSON file to destination folder
 * Shortcut for this.fs.writeJSON(this.destinationPath(filepath))
 */
writeDestinationJSON(...args: Parameters<MemFsEditor['writeJSON']>): ReturnType<MemFsEditor['writeJSON']>;

/**
 * Delete file from destination folder
 * Shortcut for this.fs.delete(this.destinationPath(filepath))
 */
deleteDestination(...args: Parameters<MemFsEditor['delete']>): ReturnType<MemFsEditor['delete']>;

/**
 * Check if file exists in destination folder
 * Shortcut for this.fs.exists(this.destinationPath(filepath))
 */
existsDestination(...args: Parameters<MemFsEditor['exists']>): ReturnType<MemFsEditor['exists']>;

/**
 * Copy file within destination folder
 * Shortcut for this.fs.copy(this.destinationPath(from), this.destinationPath(to))
 */
copyDestination(...args: Parameters<MemFsEditor['copy']>): ReturnType<MemFsEditor['copy']>;

/**
 * Move file within destination folder
 * Shortcut for this.fs.move(this.destinationPath(from), this.destinationPath(to))
 */
moveDestination(...args: Parameters<MemFsEditor['move']>): ReturnType<MemFsEditor['move']>;

Usage Examples:

export default class MyGenerator extends Generator {
  writing() {
    // Check if file exists before overwriting
    if (!this.existsDestination('src/config.js')) {
      this.writeDestination('src/config.js', 'module.exports = {};');
    }
    
    // Read existing package.json and modify
    const pkg = this.readDestinationJSON('package.json', {});
    pkg.scripts = pkg.scripts || {};
    pkg.scripts.start = 'node src/index.js';
    this.writeDestinationJSON('package.json', pkg);
    
    // Backup existing file
    if (this.existsDestination('config.json')) {
      this.copyDestination('config.json', 'config.json.bak');
    }
  }
  
  end() {
    // Clean up temporary files
    this.deleteDestination('temp-config.json');
  }
}

Template Data Utilities

Utility methods for preparing template data from configuration.

/**
 * Utility method to get formatted data for templates
 * @param path - Path to the storage key, or undefined for all config
 * @returns Data to be passed to the templates
 */
_templateData<D extends TemplateData = TemplateData>(path?: string): D;

Usage Example:

export default class MyGenerator extends Generator {
  writing() {
    // Get all configuration as template data
    const allData = this._templateData();
    
    // Get specific configuration path
    const userPrefs = this._templateData('user.preferences');
    
    this.renderTemplate('app.js.ejs', 'src/app.js', allData);
  }
}

Types

// Template data (EJS data)
type TemplateData = Record<string, any>;

// Template options (EJS options)  
interface TemplateOptions {
  context?: any;
  delimiter?: string;
  openDelimiter?: string;
  closeDelimiter?: string;
  debug?: boolean;
  compileDebug?: boolean;
  client?: boolean;
  escape?: (markup: string) => string;
  filename?: string;
  root?: string | string[];
  views?: string[];
  cache?: boolean;
  outputFunctionName?: string;
  localsName?: string;
  rmWhitespace?: boolean;
  async?: boolean;
}

// Copy options from mem-fs-editor
interface CopyOptions {
  fromBasePath?: string;
  ignoreNoMatch?: boolean;
  globOptions?: any;
  processDestinationPath?: (dest: string) => string;
}

// Template configuration for batch rendering
interface Template<D extends TemplateData, G> {
  source: string;
  destination?: string;
  when?: (data: D, generator: G) => boolean;
  copyOptions?: CopyOptions;
  templateData?: TemplateData;
  templateOptions?: TemplateOptions;
}

type Templates<D extends TemplateData, G> = Array<Template<D, G>>;

Install with Tessl CLI

npx tessl i tessl/npm-yeoman-generator

docs

command-execution.md

command-line.md

configuration.md

core-generator.md

file-system.md

git-integration.md

index.md

package-management.md

task-lifecycle.md

user-interaction.md

tile.json