CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-loopback--build

A comprehensive set of build tools and configurations for LoopBack 4 and TypeScript projects providing CLI commands for compilation, linting, testing, and coverage

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

process-management.mddocs/

Process Management

Core utilities for running CLI commands and managing child processes with intelligent module resolution and cross-platform support.

Capabilities

CLI Execution

Execute CLI tools with automatic module resolution and project-first dependency lookup.

/**
 * Run a CLI command with intelligent module resolution
 * @param cli - CLI module path (e.g., "typescript/lib/tsc", "eslint/bin/eslint")
 * @param args - Command line arguments to pass to the CLI
 * @param options - Execution options for process control and module resolution
 * @returns ChildProcess when executed, string when dry run
 */
function runCLI(
  cli: string,
  args: string[],
  options?: RunCLIOptions
): ChildProcess | string;

interface RunCLIOptions {
  dryRun?: boolean;                    // Return command string instead of executing
  cwd?: string;                        // Working directory for execution
  resolveFromProjectFirst?: boolean;   // Try project dependencies before @loopback/build
  nodeArgs?: string[];                 // Additional Node.js arguments
  stdio?: string;                      // stdio configuration
  env?: Record<string, string>;        // Environment variables
}

Usage Examples:

import { runCLI } from "@loopback/build";

// Run TypeScript compiler
const tscProcess = runCLI(
  "typescript/lib/tsc", 
  ["--project", "tsconfig.json"]
);

// Run with custom Node.js arguments
const eslintProcess = runCLI(
  "eslint/bin/eslint",
  ["src/", "--fix"],
  { nodeArgs: ["--max-old-space-size=4096"] }
);

// Dry run to see command
const command = runCLI(
  "prettier/bin/prettier.cjs",
  ["--write", "**/*.ts"],
  { dryRun: true }
);
console.log(command); // "node /path/to/prettier.cjs --write **/*.ts"

// Custom working directory
runCLI("mocha/bin/mocha", ["test/"], { cwd: "/path/to/project" });

Shell Command Execution

Execute shell commands with JSON-safe argument handling and cross-platform support.

/**
 * Run a shell command with cross-platform support
 * @param command - Command to execute (must be in PATH or absolute path)
 * @param args - Command arguments (automatically JSON-quoted for safety)
 * @param options - Execution options for process control
 * @returns ChildProcess when executed, string when dry run
 */
function runShell(
  command: string,
  args: string[],
  options?: RunShellOptions
): ChildProcess | string;

interface RunShellOptions {
  dryRun?: boolean;                  // Return command string instead of executing
  cwd?: string;                      // Working directory for execution
  stdio?: string;                    // stdio configuration
  env?: Record<string, string>;      // Environment variables
  shell?: boolean;                   // Enable shell execution (default: true)
}

Usage Examples:

import { runShell } from "@loopback/build";

// Run npm commands
const npmProcess = runShell("npm", ["install", "--save-dev", "typescript"]);

// Run git commands
const gitProcess = runShell("git", ["add", "."]);

// Run with custom environment
const envProcess = runShell("node", ["script.js"], {
  env: { NODE_ENV: "production", DEBUG: "myapp:*" }
});

// Dry run to see command
const command = runShell("docker", ["build", "-t", "myapp", "."], { dryRun: true });
console.log(command); // 'docker "build" "-t" "myapp" "."'

Module Resolution

Intelligent module resolution that prioritizes project dependencies over bundled tools.

/**
 * Resolve CLI module path with project-first resolution
 * @param cli - CLI module path to resolve
 * @param options - Resolution options
 * @returns Absolute path to the resolved CLI module
 */
function resolveCLI(
  cli: string, 
  options?: { resolveFromProjectFirst?: boolean }
): string;

/**
 * Resolve CLI from project dependencies only
 * @param cli - CLI module path to resolve
 * @param projectRootDir - Project root directory (defaults to process.cwd())
 * @returns Absolute path to CLI module or undefined if not found
 */
function resolveCLIFromProject(
  cli: string, 
  projectRootDir?: string
): string | undefined;

/**
 * Extract package name from CLI module path
 * @param cli - CLI module path (e.g., "typescript/lib/tsc", "@babel/cli/bin/babel")
 * @returns Package name (e.g., "typescript", "@babel/cli")
 */
function getPackageName(cli: string): string;

Resolution Examples:

import { resolveCLI, resolveCLIFromProject, getPackageName } from "@loopback/build";

// Resolve TypeScript compiler
const tscPath = resolveCLI("typescript/lib/tsc");
// Returns: "/project/node_modules/typescript/lib/tsc.js" (project version)
// Falls back to: "/node_modules/@loopback/build/node_modules/typescript/lib/tsc.js"

// Force resolution from project only
const projectTsc = resolveCLIFromProject("typescript/lib/tsc");
// Returns: "/project/node_modules/typescript/lib/tsc.js" or undefined

// Extract package names
const pkgName1 = getPackageName("typescript/lib/tsc");          // "typescript"
const pkgName2 = getPackageName("@babel/cli/bin/babel");        // "@babel/cli"
const pkgName3 = getPackageName("eslint/bin/eslint");           // "eslint"

// Skip project resolution (use bundled version)
const bundledEslint = resolveCLI("eslint/bin/eslint", { 
  resolveFromProjectFirst: false 
});

Configuration and Utility Functions

Helper functions for configuration file discovery and CLI option processing.

/**
 * Get configuration file with fallback support
 * @param name - Preferred configuration file name
 * @param defaultName - Default fallback file name
 * @returns Path to discovered configuration file
 */
function getConfigFile(name: string, defaultName?: string): string;

/**
 * Get root directory of @loopback/build module
 * @returns Absolute path to @loopback/build root directory
 */
function getRootDir(): string;

/**
 * Get root directory of current npm package
 * @returns Absolute path to current working directory
 */
function getPackageDir(): string;

/**
 * Check if CLI options contain specified option names
 * @param opts - Array of CLI option strings
 * @param optionNames - Option names to check for
 * @returns True if any option name is found
 */
function isOptionSet(opts: string[], ...optionNames: string[]): boolean;

/**
 * Check if project has Mocha configuration files
 * @returns True if any Mocha config file exists in project
 */
function mochaConfiguredForProject(): boolean;

Utility Examples:

import { 
  getConfigFile, 
  getRootDir, 
  getPackageDir, 
  isOptionSet,
  mochaConfiguredForProject 
} from "@loopback/build";

// Find configuration files
const tsconfigPath = getConfigFile("tsconfig.build.json", "tsconfig.json");
const eslintrcPath = getConfigFile(".eslintrc.js", ".eslintrc.json");

// Get directory paths
const buildToolsRoot = getRootDir();    // "/node_modules/@loopback/build"
const projectRoot = getPackageDir();    // "/current/working/directory"

// Check CLI options
const opts = ["--fix", "--ext", ".ts", "src/"];
const hasFixFlag = isOptionSet(opts, "--fix");              // true
const hasConfigFlag = isOptionSet(opts, "-c", "--config");  // false
const hasExtFlag = isOptionSet(opts, "--ext");              // true

// Check project configuration
const hasMochaConfig = mochaConfiguredForProject();
// Checks for: .mocharc.js, .mocharc.json, .mocharc.yaml, .mocharc.yml

Process Management and Error Handling

Comprehensive process management with proper error handling and exit code propagation.

/**
 * Process management features:
 * - Proper stdio inheritance for interactive commands
 * - Exit code propagation to parent process
 * - Signal handling for graceful shutdowns
 * - Cross-platform process spawning
 * - Environment variable inheritance and customization
 */

interface ProcessFeatures {
  stdioInheritance: "inherit";           // Pass stdio to child processes
  exitCodePropagation: boolean;          // Set process.exitCode on child exit
  signalHandling: boolean;               // Handle SIGTERM, SIGINT, etc.
  crossPlatform: boolean;                // Windows and Unix compatibility
  environmentVariables: boolean;         // Custom env var support
}

Error Handling Examples:

import { runCLI, runShell } from "@loopback/build";

// Error handling with callbacks
const child = runCLI("eslint/bin/eslint", ["src/"]);

child.on('close', (code, signal) => {
  if (code !== 0) {
    console.error(`ESLint exited with code ${code}`);
    process.exit(code);
  }
});

// Shell command error handling
const shellChild = runShell("npm", ["test"]);

shellChild.on('error', (error) => {
  console.error('Failed to start process:', error);
});

shellChild.on('close', (code, signal) => {
  if (signal === 'SIGKILL') {
    console.warn('Process was killed');
  }
});

Advanced Usage Patterns

Advanced patterns for complex build workflows and integrations.

Pipeline Execution:

import { runCLI, runShell } from "@loopback/build";

async function buildPipeline() {
  // Clean build artifacts
  await new Promise(resolve => {
    const clean = runShell("rm", ["-rf", "dist"]);
    clean.on('close', resolve);
  });
  
  // Compile TypeScript
  await new Promise(resolve => {
    const tsc = runCLI("typescript/lib/tsc", []);
    tsc.on('close', resolve);
  });
  
  // Run tests
  await new Promise(resolve => {
    const mocha = runCLI("mocha/bin/mocha", ["dist/__tests__"]);
    mocha.on('close', resolve);
  });
}

Custom Tool Integration:

import { runCLI, resolveCLI } from "@loopback/build";

// Custom TypeScript plugin workflow
function runWithTTypescript() {
  try {
    // Try to use project's ttypescript
    const ttscPath = resolveCLI("ttypescript/lib/tsc");
    return runCLI("ttypescript/lib/tsc", process.argv.slice(2));
  } catch (error) {
    // Fall back to regular TypeScript
    console.warn("ttypescript not found, using regular tsc");
    return runCLI("typescript/lib/tsc", process.argv.slice(2));
  }
}

// Conditional tool execution
function runLinter(fix = false) {
  const args = ["."];
  if (fix) args.unshift("--fix");
  
  return runCLI("eslint/bin/eslint", args, {
    nodeArgs: ["--max-old-space-size=4096"] // More memory for large projects
  });
}

TypeScript Path Resolution

Special handling for TypeScript installation path discovery.

/**
 * Resolved path to TypeScript installation
 * Points to the directory containing TypeScript package
 */
const typeScriptPath: string;

// Usage example:
import { typeScriptPath } from "@loopback/build";
import path from "path";

const tscBin = path.join(typeScriptPath, "bin", "tsc");
const tsLib = path.join(typeScriptPath, "lib");

docs

code-coverage.md

code-formatting.md

code-linting.md

file-cleanup.md

index.md

process-management.md

test-execution.md

typescript-compilation.md

tile.json