CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-prisma--internals

Comprehensive internal utility library for Prisma's CLI operations, schema management, generator handling, and engine interactions

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

binary-resolution.mddocs/

Binary Resolution and Platform Utilities

The binary resolution domain provides engine binary path resolution and platform-specific operations, ensuring Prisma engines can be located and executed correctly across different platforms and deployment environments.

Functions

Binary Resolution

resolveBinary(name, proposedPath?)

Resolves the path to a Prisma engine binary, handling various installation scenarios and platform-specific requirements.

function resolveBinary(
  name: BinaryType,
  proposedPath?: string
): Promise<string>

Parameters:

  • name: BinaryType - Type of binary to resolve (QueryEngine, SchemaEngine, etc.)
  • proposedPath?: string - Optional proposed path to check first

Returns: Promise<string> - Resolved absolute path to the binary

Example:

import { resolveBinary, BinaryType } from '@prisma/internals'

// Resolve query engine binary
const queryEnginePath = await resolveBinary(BinaryType.QueryEngine)
console.log('Query Engine:', queryEnginePath)

// Resolve with proposed path
const schemaEnginePath = await resolveBinary(
  BinaryType.SchemaEngine,
  '/custom/path/to/schema-engine'
)
console.log('Schema Engine:', schemaEnginePath)

// Resolve all engine binaries
const engines = [
  BinaryType.QueryEngine,
  BinaryType.SchemaEngine
]

for (const engine of engines) {
  try {
    const path = await resolveBinary(engine)
    console.log(`${engine}: ${path}`)
  } catch (error) {
    console.error(`Failed to resolve ${engine}:`, error.message)
  }
}

Types and Enums

Binary Types

BinaryType

Enumeration of available Prisma engine binary types.

enum BinaryType {
  QueryEngine = 'query-engine',
  SchemaEngine = 'schema-engine',
  LibqueryEngine = 'libquery-engine',
  MigrationEngine = 'migration-engine'  // Legacy
}

Binary Type Descriptions:

  • QueryEngine - Main query execution engine
  • SchemaEngine - Schema operations and migrations
  • LibqueryEngine - Query engine library (for library mode)
  • MigrationEngine - Legacy migration engine (deprecated)

Constants

Environment Variable Mapping

engineEnvVarMap

Mapping of engine types to their corresponding environment variable names for custom binary paths.

const engineEnvVarMap: {
  [BinaryType.QueryEngine]: 'PRISMA_QUERY_ENGINE_BINARY'
  [BinaryType.SchemaEngine]: 'PRISMA_SCHEMA_ENGINE_BINARY'
  [BinaryType.LibqueryEngine]: 'PRISMA_LIBQUERY_ENGINE_BINARY'
  [BinaryType.MigrationEngine]: 'PRISMA_MIGRATION_ENGINE_BINARY'
}

Usage:

import { engineEnvVarMap, BinaryType } from '@prisma/internals'

// Get environment variable name for query engine
const queryEngineEnvVar = engineEnvVarMap[BinaryType.QueryEngine]
console.log(queryEngineEnvVar) // 'PRISMA_QUERY_ENGINE_BINARY'

// Check if custom binary path is set
const customPath = process.env[queryEngineEnvVar]
if (customPath) {
  console.log('Custom query engine path:', customPath)
}

Platform Detection Functions

Platform Information

getBinaryTargetForCurrentPlatform()

Detects the binary target identifier for the current platform and architecture.

function getBinaryTargetForCurrentPlatform(): BinaryTarget

Returns: BinaryTarget - Platform-specific binary target identifier

Example Platform Targets:

  • linux-musl - Linux with musl libc
  • linux-openssl-1.1.x - Linux with OpenSSL 1.1.x
  • linux-openssl-3.0.x - Linux with OpenSSL 3.0.x
  • darwin - macOS Intel
  • darwin-arm64 - macOS Apple Silicon
  • windows - Windows
  • debian-openssl-1.1.x - Debian-based systems
  • rhel-openssl-1.0.x - Red Hat Enterprise Linux

getNodeAPIName()

Gets the Node.js API name for the current platform and Node.js version.

function getNodeAPIName(): string

Returns: string - Node.js API identifier (e.g., 'node-api')

Types

Platform Types

BinaryTarget

Type representing supported binary target platforms.

type BinaryTarget = 
  | 'native'
  | 'linux-musl'
  | 'linux-openssl-1.0.x'  
  | 'linux-openssl-1.1.x'
  | 'linux-openssl-3.0.x'
  | 'debian-openssl-1.0.x'
  | 'debian-openssl-1.1.x'
  | 'debian-openssl-3.0.x'
  | 'rhel-openssl-1.0.x'
  | 'rhel-openssl-1.1.x'
  | 'rhel-openssl-3.0.x'
  | 'linux-arm64-openssl-1.0.x'
  | 'linux-arm64-openssl-1.1.x'
  | 'linux-arm64-openssl-3.0.x'
  | 'linux-arm-openssl-1.0.x'
  | 'linux-arm-openssl-1.1.x'
  | 'linux-arm-openssl-3.0.x'
  | 'linux-musl-openssl-3.0.x'
  | 'linux-nixos'
  | 'darwin'
  | 'darwin-arm64'
  | 'windows'
  | 'freebsd11'
  | 'freebsd12'
  | 'freebsd13'
  | 'freebsd14'
  | 'freebsd15'
  | 'openbsd'
  | 'netbsd'
  | 'arm'

Examples

Complete Binary Resolution Setup

import {
  resolveBinary,
  BinaryType,
  getBinaryTargetForCurrentPlatform,
  getNodeAPIName,
  engineEnvVarMap
} from '@prisma/internals'

interface EngineConfig {
  queryEngine: string
  schemaEngine: string
  libqueryEngine?: string
}

async function setupEngineConfiguration(): Promise<EngineConfig> {
  console.log('Setting up Prisma engines...')
  
  // Detect current platform
  const platform = getBinaryTargetForCurrentPlatform()
  const nodeAPI = getNodeAPIName()
  
  console.log(`Platform: ${platform}`)
  console.log(`Node API: ${nodeAPI}`)
  
  // Check for custom engine paths from environment
  const customPaths: Partial<Record<BinaryType, string>> = {}
  
  for (const [binaryType, envVar] of Object.entries(engineEnvVarMap)) {
    const customPath = process.env[envVar]
    if (customPath) {
      customPaths[binaryType as BinaryType] = customPath
      console.log(`Custom ${binaryType} path: ${customPath}`)
    }
  }
  
  // Resolve all required engine binaries
  const [queryEngine, schemaEngine] = await Promise.all([
    resolveBinary(BinaryType.QueryEngine, customPaths[BinaryType.QueryEngine]),
    resolveBinary(BinaryType.SchemaEngine, customPaths[BinaryType.SchemaEngine])
  ])
  
  // Optionally resolve library engine
  let libqueryEngine: string | undefined
  try {
    libqueryEngine = await resolveBinary(
      BinaryType.LibqueryEngine,
      customPaths[BinaryType.LibqueryEngine]
    )
  } catch (error) {
    console.warn('Library query engine not available:', error.message)
  }
  
  const config: EngineConfig = {
    queryEngine,
    schemaEngine,
    libqueryEngine
  }
  
  console.log('Engine configuration:')
  console.log(`Query Engine: ${config.queryEngine}`)
  console.log(`Schema Engine: ${config.schemaEngine}`)
  if (config.libqueryEngine) {
    console.log(`Library Query Engine: ${config.libqueryEngine}`)
  }
  
  return config
}

Platform-Specific Binary Management

import {
  getBinaryTargetForCurrentPlatform,
  BinaryType,
  type BinaryTarget
} from '@prisma/internals'

interface PlatformInfo {
  target: BinaryTarget
  isLinux: boolean
  isMacOS: boolean
  isWindows: boolean
  isARM: boolean
  openSSLVersion?: string
  supportsLibraryMode: boolean
}

function analyzePlatform(): PlatformInfo {
  const target = getBinaryTargetForCurrentPlatform()
  
  const info: PlatformInfo = {
    target,
    isLinux: target.startsWith('linux') || target.startsWith('debian') || target.startsWith('rhel'),
    isMacOS: target.startsWith('darwin'),
    isWindows: target === 'windows',
    isARM: target.includes('arm64') || target.includes('arm'),
    supportsLibraryMode: !target.includes('musl') // musl doesn't support library mode well
  }
  
  // Extract OpenSSL version from target
  const openSSLMatch = target.match(/openssl-(\d+\.\d+\.x)/)
  if (openSSLMatch) {
    info.openSSLVersion = openSSLMatch[1]
  }
  
  return info
}

async function setupPlatformSpecificEngines() {
  const platformInfo = analyzePlatform()
  
  console.log('Platform Analysis:')
  console.log(`Target: ${platformInfo.target}`)
  console.log(`Linux: ${platformInfo.isLinux}`)
  console.log(`macOS: ${platformInfo.isMacOS}`)
  console.log(`Windows: ${platformInfo.isWindows}`)
  console.log(`ARM Architecture: ${platformInfo.isARM}`)
  console.log(`OpenSSL Version: ${platformInfo.openSSLVersion || 'Not detected'}`)
  console.log(`Library Mode Support: ${platformInfo.supportsLibraryMode}`)
  
  // Always resolve query and schema engines
  const requiredEngines = [BinaryType.QueryEngine, BinaryType.SchemaEngine]
  const enginePaths: Record<string, string> = {}
  
  for (const engineType of requiredEngines) {
    try {
      const path = await resolveBinary(engineType)
      enginePaths[engineType] = path
      console.log(`✓ ${engineType}: ${path}`)
    } catch (error) {
      console.error(`✗ Failed to resolve ${engineType}: ${error.message}`)
      throw new Error(`Required engine ${engineType} not available`)
    }
  }
  
  // Conditionally resolve library engine based on platform support
  if (platformInfo.supportsLibraryMode) {
    try {
      const libPath = await resolveBinary(BinaryType.LibqueryEngine)
      enginePaths[BinaryType.LibqueryEngine] = libPath
      console.log(`✓ ${BinaryType.LibqueryEngine}: ${libPath}`)
    } catch (error) {
      console.warn(`⚠ Library engine not available: ${error.message}`)
    }
  } else {
    console.log(`ℹ Library mode not supported on ${platformInfo.target}`)
  }
  
  return { platformInfo, enginePaths }
}

Environment Variable Configuration

import {
  engineEnvVarMap,
  BinaryType,
  resolveBinary
} from '@prisma/internals'

class EnginePathManager {
  private customPaths: Map<BinaryType, string> = new Map()
  
  /**
   * Load custom engine paths from environment variables
   */
  loadFromEnvironment(): void {
    console.log('Loading custom engine paths from environment...')
    
    for (const [binaryType, envVar] of Object.entries(engineEnvVarMap)) {
      const customPath = process.env[envVar]
      if (customPath) {
        this.customPaths.set(binaryType as BinaryType, customPath)
        console.log(`${binaryType}: ${customPath} (from ${envVar})`)
      }
    }
    
    if (this.customPaths.size === 0) {
      console.log('No custom engine paths configured')
    }
  }
  
  /**
   * Set custom path for specific engine
   */
  setCustomPath(engine: BinaryType, path: string): void {
    this.customPaths.set(engine, path)
    console.log(`Set custom ${engine} path: ${path}`)
  }
  
  /**
   * Get custom path for engine, if configured
   */
  getCustomPath(engine: BinaryType): string | undefined {
    return this.customPaths.get(engine)
  }
  
  /**
   * Resolve engine binary with custom path consideration
   */
  async resolve(engine: BinaryType): Promise<string> {
    const customPath = this.getCustomPath(engine)
    return await resolveBinary(engine, customPath)
  }
  
  /**
   * Resolve all engines
   */
  async resolveAll(): Promise<Record<BinaryType, string>> {
    const engines = Object.values(BinaryType)
    const results: Partial<Record<BinaryType, string>> = {}
    
    await Promise.all(
      engines.map(async (engine) => {
        try {
          results[engine] = await this.resolve(engine)
        } catch (error) {
          console.warn(`Could not resolve ${engine}: ${error.message}`)
        }
      })
    )
    
    return results as Record<BinaryType, string>
  }
  
  /**
   * Generate environment variable export commands
   */
  generateEnvExports(): string[] {
    const exports: string[] = []
    
    for (const [engine, path] of this.customPaths) {
      const envVar = engineEnvVarMap[engine]
      exports.push(`export ${envVar}="${path}"`)
    }
    
    return exports
  }
}

// Usage
async function manageEngineConfiguration() {
  const manager = new EnginePathManager()
  
  // Load from environment
  manager.loadFromEnvironment()
  
  // Set custom paths programmatically
  manager.setCustomPath(BinaryType.QueryEngine, '/opt/prisma/query-engine')
  manager.setCustomPath(BinaryType.SchemaEngine, '/opt/prisma/schema-engine')
  
  // Resolve all engines
  const enginePaths = await manager.resolveAll()
  console.log('Resolved engine paths:', enginePaths)
  
  // Generate export commands for deployment
  const exports = manager.generateEnvExports()
  console.log('\nEnvironment exports for deployment:')
  exports.forEach(exp => console.log(exp))
}

Binary Validation and Health Check

import {
  resolveBinary,
  BinaryType,
  getBinaryTargetForCurrentPlatform
} from '@prisma/internals'
import { execFile } from 'child_process'
import { promisify } from 'util'
import { access, constants } from 'fs'

const execFileAsync = promisify(execFile)
const accessAsync = promisify(access)

interface BinaryHealthStatus {
  engine: BinaryType
  path: string
  exists: boolean
  executable: boolean
  version?: string
  error?: string
}

async function checkBinaryHealth(engine: BinaryType): Promise<BinaryHealthStatus> {
  const status: BinaryHealthStatus = {
    engine,
    path: '',
    exists: false,
    executable: false
  }
  
  try {
    // Resolve binary path
    status.path = await resolveBinary(engine)
    
    // Check if file exists
    try {
      await accessAsync(status.path, constants.F_OK)
      status.exists = true
    } catch {
      status.exists = false
      status.error = 'Binary file not found'
      return status
    }
    
    // Check if executable
    try {
      await accessAsync(status.path, constants.X_OK)
      status.executable = true
    } catch {
      status.executable = false
      status.error = 'Binary not executable'
      return status
    }
    
    // Get version information
    try {
      const { stdout } = await execFileAsync(status.path, ['--version'], {
        timeout: 5000
      })
      status.version = stdout.trim()
    } catch (error) {
      status.error = `Version check failed: ${error.message}`
    }
    
  } catch (error) {
    status.error = `Resolution failed: ${error.message}`
  }
  
  return status
}

async function performEngineHealthCheck(): Promise<void> {
  console.log('Performing Prisma Engine Health Check...')
  console.log(`Platform: ${getBinaryTargetForCurrentPlatform()}`)
  console.log('=' .repeat(60))
  
  const engines = [BinaryType.QueryEngine, BinaryType.SchemaEngine]
  const results: BinaryHealthStatus[] = []
  
  for (const engine of engines) {
    const status = await checkBinaryHealth(engine)
    results.push(status)
    
    const icon = status.exists && status.executable && !status.error ? '✓' : '✗'
    
    console.log(`${icon} ${engine}`)
    console.log(`  Path: ${status.path || 'Not resolved'}`)
    console.log(`  Exists: ${status.exists}`)
    console.log(`  Executable: ${status.executable}`)
    
    if (status.version) {
      console.log(`  Version: ${status.version}`)
    }
    
    if (status.error) {
      console.log(`  Error: ${status.error}`)
    }
    
    console.log()
  }
  
  // Summary
  const healthy = results.filter(r => r.exists && r.executable && !r.error)
  const total = results.length
  
  console.log('=' .repeat(60))
  console.log(`Health Check Summary: ${healthy.length}/${total} engines healthy`)
  
  if (healthy.length < total) {
    const issues = results.filter(r => !r.exists || !r.executable || r.error)
    console.log('\nIssues found:')
    issues.forEach(issue => {
      console.log(`- ${issue.engine}: ${issue.error || 'Unknown issue'}`)
    })
    
    process.exit(1)
  }
  
  console.log('All engines are healthy and ready!')
}

Install with Tessl CLI

npx tessl i tessl/npm-prisma--internals

docs

binary-resolution.md

cli-utilities.md

database-operations.md

engine-commands.md

error-handling.md

generators.md

index.md

syntax-highlighting.md

tracing.md

utilities.md

tile.json