CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-prisma--generator-helper

Helper utility for creating Prisma generators with JSON-RPC communication

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

process-management.mddocs/

Process Management

Advanced generator process management for scenarios requiring direct control over subprocess communication, such as integrating with existing generator executables or implementing custom process lifecycle management.

Capabilities

GeneratorProcess Class

Manages generator subprocess communication via JSON-RPC over stdin/stderr. Use this when you need fine-grained control over process lifecycle or are integrating with existing generator binaries.

/**
 * Manages generator subprocess communication
 * @param pathOrCommand - Path to generator executable or command
 * @param options - Configuration options for the process
 */
class GeneratorProcess {
  constructor(pathOrCommand: string, options?: GeneratorProcessOptions);
  
  /** Initialize the generator process */
  init(): Promise<void>;
  /** Get generator manifest information */
  getManifest(config: GeneratorConfig): Promise<GeneratorManifest | null>;
  /** Execute code generation */
  generate(options: GeneratorOptions): Promise<void>;
  /** Stop the generator process gracefully */
  stop(): void;
}

interface GeneratorProcessOptions {
  /** Whether the generator is a Node.js process (affects spawn behavior) */
  isNode?: boolean;
}

Usage Examples:

import { GeneratorProcess } from "@prisma/generator-helper";

// Managing a Node.js generator
const nodeGenerator = new GeneratorProcess("./my-generator.js", { 
  isNode: true 
});

await nodeGenerator.init();

// Get generator information
const manifest = await nodeGenerator.getManifest({
  name: "my-generator",
  provider: { value: "./my-generator.js", fromEnvVar: null },
  output: { value: "./generated", fromEnvVar: null },
  config: {},
  binaryTargets: [],
  previewFeatures: [],
  sourceFilePath: "schema.prisma"
});

// Execute generation
await nodeGenerator.generate(generatorOptions);

// Clean shutdown
nodeGenerator.stop();
// Managing a binary generator
const binaryGenerator = new GeneratorProcess("./my-generator-binary");

try {
  await binaryGenerator.init();
  await binaryGenerator.generate(options);
} catch (error) {
  if (error instanceof GeneratorError) {
    console.error(`Generator failed: ${error.message}`);
    if (error.code) console.error(`Error code: ${error.code}`);
    if (error.data) console.error(`Additional data:`, error.data);
  }
} finally {
  binaryGenerator.stop();
}

Process Initialization

Initialize the generator subprocess and establish communication channels.

/**
 * Initialize the generator process and establish communication
 * @throws GeneratorError if process fails to start or lacks permissions
 */
init(): Promise<void>;

The init() method handles:

  • Spawning the generator process with appropriate stdio configuration
  • Setting up JSON-RPC communication over stdin/stderr
  • Configuring environment variables (PRISMA_GENERATOR_INVOCATION: 'true')
  • Error handling for common issues like permission problems (EACCES)

Manifest Retrieval

Get generator metadata and capabilities from the subprocess.

/**
 * Get generator manifest information
 * @param config - Generator configuration from Prisma schema
 * @returns Generator manifest or null if not supported
 * @throws GeneratorError if communication fails
 */
getManifest(config: GeneratorConfig): Promise<GeneratorManifest | null>;

Code Generation

Execute the code generation process with full Prisma schema information.

/**
 * Execute code generation with provided options
 * @param options - Complete generator options including DMMF, datasources, etc.
 * @throws GeneratorError if generation fails
 */
generate(options: GeneratorOptions): Promise<void>;

Process Termination

Gracefully terminate the generator subprocess with proper signal handling.

/**
 * Stop the generator process gracefully
 * Sends SIGTERM first, then SIGKILL after 2 seconds if process doesn't exit
 */
stop(): void;

The stop() method implements a two-phase shutdown:

  1. Sends SIGTERM signal for graceful shutdown
  2. Waits up to 2 seconds for process to exit
  3. Sends SIGKILL if process is still running

Error Handling

GeneratorError Class

Specialized error class for generator process failures with additional context.

/**
 * Custom error class for generator failures
 * @param message - Error description
 * @param code - Optional error code from JSON-RPC response
 * @param data - Optional additional error data (may include stack trace)
 */
class GeneratorError extends Error {
  name: "GeneratorError";
  
  constructor(
    message: string,
    code?: number,
    data?: any
  );
  
  /** JSON-RPC error code if available */
  code?: number;
  /** Additional error data (stack traces, context) */
  data?: any;
}

Common error scenarios:

  • Permission errors: When generator executable lacks execute permissions
  • Communication errors: When JSON-RPC communication fails
  • Generation errors: When the generator process encounters internal errors
  • Process termination: When generator process exits unexpectedly

Error Handling Patterns

import { GeneratorProcess, GeneratorError } from "@prisma/generator-helper";

const generator = new GeneratorProcess("./my-generator");

try {
  await generator.init();
  await generator.generate(options);
} catch (error) {
  if (error instanceof GeneratorError) {
    // Handle generator-specific errors
    console.error(`Generator error: ${error.message}`);
    
    if (error.code === -32000) {
      console.error("Internal generator error");
    }
    
    if (error.data?.stack) {
      console.error("Generator stack trace:", error.data.stack);
    }
  } else if (error.code === 'EACCES') {
    // Handle permission errors
    console.error(`Generator executable needs execute permissions: chmod +x ./my-generator`);
  } else {
    // Handle other errors
    console.error("Unexpected error:", error);
  }
} finally {
  generator.stop();
}

Install with Tessl CLI

npx tessl i tessl/npm-prisma--generator-helper

docs

index.md

process-management.md

tile.json