Helper utility for creating Prisma generators with JSON-RPC communication
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
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();
}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:
PRISMA_GENERATOR_INVOCATION: 'true')EACCES)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>;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>;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:
SIGTERM signal for graceful shutdownSIGKILL if process is still runningSpecialized 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:
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