CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-yeoman-environment

Handles the lifecycle and bootstrapping of generators in a specific environment

Overview
Eval results
Files

generator-management.mddocs/

Generator Management

Registration, instantiation, and execution of generators with metadata management and lifecycle control.

Capabilities

Generator Registration

Register generators with the environment by path, constructor, or module.

/**
 * Register a generator by path or constructor
 * Available on Environment and EnvironmentBase instances
 * @param pathOrStub - Generator path, constructor, or module
 * @param meta - Optional metadata for the generator
 * @returns Generator metadata object
 */
register(pathOrStub: unknown, meta?: Partial<BaseGeneratorMeta>): GeneratorMeta;

Usage Examples:

import { createEnv } from "yeoman-environment";

const env = createEnv();

// Register by file path
const meta1 = env.register("./generators/app/index.js", {
  namespace: "myapp:app"
});

// Register by module path
const meta2 = env.register("generator-webapp/generators/app", {
  namespace: "webapp:app"
});

// Register with custom metadata
const meta3 = env.register(MyGeneratorClass, {
  namespace: "custom:generator",
  packagePath: "/path/to/package"
});

Generator Retrieval

Get generator instances or constructors from the registry.

/**
 * Get generator instance by namespace or path
 * @param namespaceOrPath - Generator namespace or Yeoman namespace object
 * @returns Generator instance or undefined if not found
 */
get<C>(namespaceOrPath: string | YeomanNamespace): Promise<C | undefined>;

/**
 * Find generator metadata by namespace or path
 * @param namespaceOrPath - Generator namespace or Yeoman namespace object
 * @returns Generator metadata or undefined if not found
 */
findMeta(namespaceOrPath: string | YeomanNamespace): Promise<GeneratorMeta | undefined>;

/**
 * Require and return a generator constructor
 * Available on Environment instances
 * @param namespace - Generator namespace to require
 * @returns Generator constructor or undefined
 */
requireGenerator(namespace: string): Promise<BaseGeneratorConstructor | undefined>;

/**
 * Get generator metadata by namespace
 * @param namespace - Generator namespace
 * @returns Generator metadata or undefined
 */
getGeneratorMeta(namespace: string): GeneratorMeta | undefined;

Usage Examples:

// Get generator instance
const generator = await env.get<MyGenerator>("webapp:app");

// Find metadata
const meta = await env.findMeta("webapp:app");

// Require constructor
const GeneratorClass = await env.requireGenerator("webapp:app");

// Get metadata directly
const storedMeta = env.getGeneratorMeta("webapp:app");

Generator Creation

Create and instantiate generator instances with arguments.

/**
 * Create generator instance with arguments
 * @param namespaceOrPath - Generator namespace, path, or constructor
 * @param args - Arguments to pass to generator constructor
 * @returns Generator instance
 */
create<G>(namespaceOrPath: string | GetGeneratorConstructor<G>, ...args: any[]): Promise<G>;

/**
 * Instantiate generator from constructor
 * @param generator - Generator constructor
 * @param args - Arguments to pass to constructor
 * @returns Generator instance
 */
instantiate<G>(generator: GetGeneratorConstructor<G>, ...args: any[]): Promise<G>;

/**
 * Compose with another generator
 * @param generator - Generator to compose with (namespace or constructor)
 * @param args - Arguments for the generator
 * @returns Composed generator instance
 */
composeWith<G>(generator: string | GetGeneratorConstructor<G>, ...args: any[]): Promise<G>;

Usage Examples:

// Create generator with arguments
const generator = await env.create("webapp:app", ["MyApp"], {
  skipInstall: true,
  framework: "react"
});

// Instantiate from constructor
const GeneratorClass = await env.requireGenerator("webapp:app");
const instance = await env.instantiate(GeneratorClass, ["MyApp"]);

// Compose with another generator
const subGenerator = await env.composeWith("webapp:component", ["UserCard"], {
  style: "css",
  test: true
});

Generator Execution

Execute generators with queue management and lifecycle control.

/**
 * Run a generator instance
 * @param generator - Generator to run
 */
runGenerator(generator: BaseGenerator): Promise<void>;

/**
 * Queue generator for execution
 * @param generator - Generator to queue
 * @param queueOptions - Queue options
 * @returns Queued generator
 */
queueGenerator<G>(generator: G, queueOptions?: { schedule?: boolean }): Promise<G>;

/**
 * Execute a generator by namespace with arguments
 * Available on Environment instances
 * @param generatorNamespace - Namespace of generator to run
 * @param args - Arguments to pass to generator
 */
execute(generatorNamespace: string, args?: string[]): Promise<void>;

/**
 * Main run method for executing generators
 * Available on Environment instances
 * @param args - Arguments for the generator
 * @param options - Options for execution
 */
run(args?: string[], options?: any): Promise<void>;

Usage Examples:

// Execute by namespace
await env.execute("webapp:app", ["MyApp", "--skip-install"]);

// Run with options
await env.run(["webapp:app", "MyApp"], { 
  skipInstall: true,
  force: true 
});

// Queue and run manually
const generator = await env.create("webapp:app", ["MyApp"]);
await env.queueGenerator(generator);
await env.runGenerator(generator);

Registry Management

Manage the generator registry and get information about registered generators.

/**
 * Get all registered generator namespaces
 * Available on Environment instances
 * @returns Array of namespace strings
 */
namespaces(): string[];

/**
 * Get metadata for all registered generators
 * Available on Environment instances
 * @returns Object mapping namespaces to generator metadata
 */
getGeneratorsMeta(): Record<string, GeneratorMeta>;

/**
 * Get names of all registered generators
 * Available on Environment instances
 * @returns Array of generator names
 */
getGeneratorNames(): string[];

/**
 * Check if package is registered
 * @param packageNamespace - Package namespace to check
 * @returns True if registered
 */
isPackageRegistered(packageNamespace: string): boolean;

/**
 * Get all registered package namespaces
 * @returns Array of registered package namespaces
 */
getRegisteredPackages(): string[];

/**
 * Get package path for a namespace
 * Available on Environment instances
 * @param namespace - Generator namespace to look up
 * @returns Package path or undefined if not found
 */
getPackagePath(namespace: string): string | undefined;

/**
 * Get all package paths for a namespace
 * Available on Environment instances
 * @param namespace - Generator namespace to look up
 * @returns Array of package paths
 */
getPackagePaths(namespace: string): string[];

Usage Examples:

// Get all registered namespaces
const allNamespaces = env.namespaces();
console.log("Registered generators:", allNamespaces);

// Get all metadata
const allMeta = env.getGeneratorsMeta();

// Check if generator is registered
if (env.isPackageRegistered("webapp")) {
  console.log("WebApp generator is available");
}

// Get package information
const packagePath = env.getPackagePath("webapp:app");
const allPaths = env.getPackagePaths("webapp");

Namespace Management

Handle namespace resolution and aliasing.

/**
 * Convert filepath to namespace
 * @param filepath - File path to convert
 * @param lookups - Optional lookup paths
 * @returns Generator namespace
 */
namespace(filepath: string, lookups?: string[]): string;

/**
 * Set or get namespace aliases
 * @param match - String or regex to match
 * @param value - Replacement value (optional for getter)
 * @returns Alias value or this for setter
 */
alias(match: string | RegExp, value?: string): string | this;

Usage Examples:

// Convert path to namespace
const namespace = env.namespace("./generators/app/index.js");
console.log(namespace); // "myapp:app"

// Set alias
env.alias(/^webapp:(.*)/, "web:$1");

// Get resolved alias
const aliased = env.alias("webapp:app"); // Returns "web:app"

Task Queue Management

Manage the execution queue and task priorities.

/**
 * Queue a task for execution at specified priority
 * @param priority - Task priority/queue name
 * @param task - Task function to execute
 * @param options - Task options
 */
queueTask(priority: string, task: () => void | Promise<void>, options?: any): void;

/**
 * Add custom priority to execution queue
 * @param priority - Priority name
 * @param before - Priority to insert before
 */
addPriority(priority: string, before?: string): void;

/**
 * Get root generator instance
 * @returns Root generator
 */
rootGenerator<G>(): G;

Usage Examples:

// Queue custom task
env.queueTask("writing", async () => {
  console.log("Custom writing task");
}, { once: true });

// Add custom priority
env.addPriority("custom-step", "writing");

// Get root generator
const root = env.rootGenerator();

Version Management

Get version information for packages and the environment.

/**
 * Get version of a package or the environment itself
 * @param packageName - Package name (optional, defaults to environment version)
 * @returns Version string or undefined if not found
 */
getVersion(packageName?: string): string | undefined;

Usage Examples:

// Get environment version
const envVersion = env.getVersion();
console.log("Environment version:", envVersion);

// Get package version
const reactVersion = env.getVersion("react");

Feature Discovery

Find generators that support specific features.

/**
 * Find generators with a specific feature
 * @param featureName - Feature name to search for
 * @returns Array of generators supporting the feature
 */
findFeature(featureName: string): Array<{ generatorId: string; feature: any }>;

Usage Examples:

// Find generators supporting TypeScript
const tsGenerators = env.findFeature("typescript");
console.log("TypeScript-enabled generators:", tsGenerators);

Metadata Types

interface BaseGeneratorMeta {
  /** Generator namespace (e.g., 'angular:component') */
  namespace: string;
  /** Resolved path to generator file */
  resolved?: string;
  /** Path to package containing generator */
  packagePath?: string;
}

interface GeneratorMeta extends BaseGeneratorMeta {
  /** Create generator instance with arguments */
  instantiate(...args: any[]): Promise<BaseGenerator>;
  /** Create generator instance for help display */
  instantiateHelp(): Promise<BaseGenerator>;
}

type YeomanNamespace = {
  /** Package namespace portion */
  packageNamespace: string;
  /** Generator name portion */
  generator?: string;
  /** Scope prefix (e.g., @angular) */
  scope?: string;
  /** Instance identifier */
  instanceId?: string;
};

interface GetGeneratorConstructor<T = BaseGenerator> {
  new (...args: any[]): T;
}

interface BaseGenerator {
  /** Generator arguments */
  arguments: any[];
  /** Generator options */
  options: any;
  /** Run the generator */
  run(): Promise<void>;
}

Install with Tessl CLI

npx tessl i tessl/npm-yeoman-environment

docs

cli.md

environment.md

filesystem.md

generator-discovery.md

generator-management.md

index.md

module-lookup.md

tile.json