0
# Binary Resolution and Platform Utilities
1
2
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.
3
4
## Functions
5
6
### Binary Resolution
7
8
#### `resolveBinary(name, proposedPath?)`
9
10
Resolves the path to a Prisma engine binary, handling various installation scenarios and platform-specific requirements.
11
12
```typescript { .api }
13
function resolveBinary(
14
name: BinaryType,
15
proposedPath?: string
16
): Promise<string>
17
```
18
19
**Parameters:**
20
- `name: BinaryType` - Type of binary to resolve (QueryEngine, SchemaEngine, etc.)
21
- `proposedPath?: string` - Optional proposed path to check first
22
23
**Returns:** `Promise<string>` - Resolved absolute path to the binary
24
25
**Example:**
26
```typescript
27
import { resolveBinary, BinaryType } from '@prisma/internals'
28
29
// Resolve query engine binary
30
const queryEnginePath = await resolveBinary(BinaryType.QueryEngine)
31
console.log('Query Engine:', queryEnginePath)
32
33
// Resolve with proposed path
34
const schemaEnginePath = await resolveBinary(
35
BinaryType.SchemaEngine,
36
'/custom/path/to/schema-engine'
37
)
38
console.log('Schema Engine:', schemaEnginePath)
39
40
// Resolve all engine binaries
41
const engines = [
42
BinaryType.QueryEngine,
43
BinaryType.SchemaEngine
44
]
45
46
for (const engine of engines) {
47
try {
48
const path = await resolveBinary(engine)
49
console.log(`${engine}: ${path}`)
50
} catch (error) {
51
console.error(`Failed to resolve ${engine}:`, error.message)
52
}
53
}
54
```
55
56
## Types and Enums
57
58
### Binary Types
59
60
#### `BinaryType`
61
62
Enumeration of available Prisma engine binary types.
63
64
```typescript { .api }
65
enum BinaryType {
66
QueryEngine = 'query-engine',
67
SchemaEngine = 'schema-engine',
68
LibqueryEngine = 'libquery-engine',
69
MigrationEngine = 'migration-engine' // Legacy
70
}
71
```
72
73
**Binary Type Descriptions:**
74
- `QueryEngine` - Main query execution engine
75
- `SchemaEngine` - Schema operations and migrations
76
- `LibqueryEngine` - Query engine library (for library mode)
77
- `MigrationEngine` - Legacy migration engine (deprecated)
78
79
## Constants
80
81
### Environment Variable Mapping
82
83
#### `engineEnvVarMap`
84
85
Mapping of engine types to their corresponding environment variable names for custom binary paths.
86
87
```typescript { .api }
88
const engineEnvVarMap: {
89
[BinaryType.QueryEngine]: 'PRISMA_QUERY_ENGINE_BINARY'
90
[BinaryType.SchemaEngine]: 'PRISMA_SCHEMA_ENGINE_BINARY'
91
[BinaryType.LibqueryEngine]: 'PRISMA_LIBQUERY_ENGINE_BINARY'
92
[BinaryType.MigrationEngine]: 'PRISMA_MIGRATION_ENGINE_BINARY'
93
}
94
```
95
96
**Usage:**
97
```typescript
98
import { engineEnvVarMap, BinaryType } from '@prisma/internals'
99
100
// Get environment variable name for query engine
101
const queryEngineEnvVar = engineEnvVarMap[BinaryType.QueryEngine]
102
console.log(queryEngineEnvVar) // 'PRISMA_QUERY_ENGINE_BINARY'
103
104
// Check if custom binary path is set
105
const customPath = process.env[queryEngineEnvVar]
106
if (customPath) {
107
console.log('Custom query engine path:', customPath)
108
}
109
```
110
111
## Platform Detection Functions
112
113
### Platform Information
114
115
#### `getBinaryTargetForCurrentPlatform()`
116
117
Detects the binary target identifier for the current platform and architecture.
118
119
```typescript { .api }
120
function getBinaryTargetForCurrentPlatform(): BinaryTarget
121
```
122
123
**Returns:** `BinaryTarget` - Platform-specific binary target identifier
124
125
**Example Platform Targets:**
126
- `linux-musl` - Linux with musl libc
127
- `linux-openssl-1.1.x` - Linux with OpenSSL 1.1.x
128
- `linux-openssl-3.0.x` - Linux with OpenSSL 3.0.x
129
- `darwin` - macOS Intel
130
- `darwin-arm64` - macOS Apple Silicon
131
- `windows` - Windows
132
- `debian-openssl-1.1.x` - Debian-based systems
133
- `rhel-openssl-1.0.x` - Red Hat Enterprise Linux
134
135
#### `getNodeAPIName()`
136
137
Gets the Node.js API name for the current platform and Node.js version.
138
139
```typescript { .api }
140
function getNodeAPIName(): string
141
```
142
143
**Returns:** `string` - Node.js API identifier (e.g., 'node-api')
144
145
## Types
146
147
### Platform Types
148
149
#### `BinaryTarget`
150
151
Type representing supported binary target platforms.
152
153
```typescript { .api }
154
type BinaryTarget =
155
| 'native'
156
| 'linux-musl'
157
| 'linux-openssl-1.0.x'
158
| 'linux-openssl-1.1.x'
159
| 'linux-openssl-3.0.x'
160
| 'debian-openssl-1.0.x'
161
| 'debian-openssl-1.1.x'
162
| 'debian-openssl-3.0.x'
163
| 'rhel-openssl-1.0.x'
164
| 'rhel-openssl-1.1.x'
165
| 'rhel-openssl-3.0.x'
166
| 'linux-arm64-openssl-1.0.x'
167
| 'linux-arm64-openssl-1.1.x'
168
| 'linux-arm64-openssl-3.0.x'
169
| 'linux-arm-openssl-1.0.x'
170
| 'linux-arm-openssl-1.1.x'
171
| 'linux-arm-openssl-3.0.x'
172
| 'linux-musl-openssl-3.0.x'
173
| 'linux-nixos'
174
| 'darwin'
175
| 'darwin-arm64'
176
| 'windows'
177
| 'freebsd11'
178
| 'freebsd12'
179
| 'freebsd13'
180
| 'freebsd14'
181
| 'freebsd15'
182
| 'openbsd'
183
| 'netbsd'
184
| 'arm'
185
```
186
187
## Examples
188
189
### Complete Binary Resolution Setup
190
191
```typescript
192
import {
193
resolveBinary,
194
BinaryType,
195
getBinaryTargetForCurrentPlatform,
196
getNodeAPIName,
197
engineEnvVarMap
198
} from '@prisma/internals'
199
200
interface EngineConfig {
201
queryEngine: string
202
schemaEngine: string
203
libqueryEngine?: string
204
}
205
206
async function setupEngineConfiguration(): Promise<EngineConfig> {
207
console.log('Setting up Prisma engines...')
208
209
// Detect current platform
210
const platform = getBinaryTargetForCurrentPlatform()
211
const nodeAPI = getNodeAPIName()
212
213
console.log(`Platform: ${platform}`)
214
console.log(`Node API: ${nodeAPI}`)
215
216
// Check for custom engine paths from environment
217
const customPaths: Partial<Record<BinaryType, string>> = {}
218
219
for (const [binaryType, envVar] of Object.entries(engineEnvVarMap)) {
220
const customPath = process.env[envVar]
221
if (customPath) {
222
customPaths[binaryType as BinaryType] = customPath
223
console.log(`Custom ${binaryType} path: ${customPath}`)
224
}
225
}
226
227
// Resolve all required engine binaries
228
const [queryEngine, schemaEngine] = await Promise.all([
229
resolveBinary(BinaryType.QueryEngine, customPaths[BinaryType.QueryEngine]),
230
resolveBinary(BinaryType.SchemaEngine, customPaths[BinaryType.SchemaEngine])
231
])
232
233
// Optionally resolve library engine
234
let libqueryEngine: string | undefined
235
try {
236
libqueryEngine = await resolveBinary(
237
BinaryType.LibqueryEngine,
238
customPaths[BinaryType.LibqueryEngine]
239
)
240
} catch (error) {
241
console.warn('Library query engine not available:', error.message)
242
}
243
244
const config: EngineConfig = {
245
queryEngine,
246
schemaEngine,
247
libqueryEngine
248
}
249
250
console.log('Engine configuration:')
251
console.log(`Query Engine: ${config.queryEngine}`)
252
console.log(`Schema Engine: ${config.schemaEngine}`)
253
if (config.libqueryEngine) {
254
console.log(`Library Query Engine: ${config.libqueryEngine}`)
255
}
256
257
return config
258
}
259
```
260
261
### Platform-Specific Binary Management
262
263
```typescript
264
import {
265
getBinaryTargetForCurrentPlatform,
266
BinaryType,
267
type BinaryTarget
268
} from '@prisma/internals'
269
270
interface PlatformInfo {
271
target: BinaryTarget
272
isLinux: boolean
273
isMacOS: boolean
274
isWindows: boolean
275
isARM: boolean
276
openSSLVersion?: string
277
supportsLibraryMode: boolean
278
}
279
280
function analyzePlatform(): PlatformInfo {
281
const target = getBinaryTargetForCurrentPlatform()
282
283
const info: PlatformInfo = {
284
target,
285
isLinux: target.startsWith('linux') || target.startsWith('debian') || target.startsWith('rhel'),
286
isMacOS: target.startsWith('darwin'),
287
isWindows: target === 'windows',
288
isARM: target.includes('arm64') || target.includes('arm'),
289
supportsLibraryMode: !target.includes('musl') // musl doesn't support library mode well
290
}
291
292
// Extract OpenSSL version from target
293
const openSSLMatch = target.match(/openssl-(\d+\.\d+\.x)/)
294
if (openSSLMatch) {
295
info.openSSLVersion = openSSLMatch[1]
296
}
297
298
return info
299
}
300
301
async function setupPlatformSpecificEngines() {
302
const platformInfo = analyzePlatform()
303
304
console.log('Platform Analysis:')
305
console.log(`Target: ${platformInfo.target}`)
306
console.log(`Linux: ${platformInfo.isLinux}`)
307
console.log(`macOS: ${platformInfo.isMacOS}`)
308
console.log(`Windows: ${platformInfo.isWindows}`)
309
console.log(`ARM Architecture: ${platformInfo.isARM}`)
310
console.log(`OpenSSL Version: ${platformInfo.openSSLVersion || 'Not detected'}`)
311
console.log(`Library Mode Support: ${platformInfo.supportsLibraryMode}`)
312
313
// Always resolve query and schema engines
314
const requiredEngines = [BinaryType.QueryEngine, BinaryType.SchemaEngine]
315
const enginePaths: Record<string, string> = {}
316
317
for (const engineType of requiredEngines) {
318
try {
319
const path = await resolveBinary(engineType)
320
enginePaths[engineType] = path
321
console.log(`✓ ${engineType}: ${path}`)
322
} catch (error) {
323
console.error(`✗ Failed to resolve ${engineType}: ${error.message}`)
324
throw new Error(`Required engine ${engineType} not available`)
325
}
326
}
327
328
// Conditionally resolve library engine based on platform support
329
if (platformInfo.supportsLibraryMode) {
330
try {
331
const libPath = await resolveBinary(BinaryType.LibqueryEngine)
332
enginePaths[BinaryType.LibqueryEngine] = libPath
333
console.log(`✓ ${BinaryType.LibqueryEngine}: ${libPath}`)
334
} catch (error) {
335
console.warn(`⚠ Library engine not available: ${error.message}`)
336
}
337
} else {
338
console.log(`ℹ Library mode not supported on ${platformInfo.target}`)
339
}
340
341
return { platformInfo, enginePaths }
342
}
343
```
344
345
### Environment Variable Configuration
346
347
```typescript
348
import {
349
engineEnvVarMap,
350
BinaryType,
351
resolveBinary
352
} from '@prisma/internals'
353
354
class EnginePathManager {
355
private customPaths: Map<BinaryType, string> = new Map()
356
357
/**
358
* Load custom engine paths from environment variables
359
*/
360
loadFromEnvironment(): void {
361
console.log('Loading custom engine paths from environment...')
362
363
for (const [binaryType, envVar] of Object.entries(engineEnvVarMap)) {
364
const customPath = process.env[envVar]
365
if (customPath) {
366
this.customPaths.set(binaryType as BinaryType, customPath)
367
console.log(`${binaryType}: ${customPath} (from ${envVar})`)
368
}
369
}
370
371
if (this.customPaths.size === 0) {
372
console.log('No custom engine paths configured')
373
}
374
}
375
376
/**
377
* Set custom path for specific engine
378
*/
379
setCustomPath(engine: BinaryType, path: string): void {
380
this.customPaths.set(engine, path)
381
console.log(`Set custom ${engine} path: ${path}`)
382
}
383
384
/**
385
* Get custom path for engine, if configured
386
*/
387
getCustomPath(engine: BinaryType): string | undefined {
388
return this.customPaths.get(engine)
389
}
390
391
/**
392
* Resolve engine binary with custom path consideration
393
*/
394
async resolve(engine: BinaryType): Promise<string> {
395
const customPath = this.getCustomPath(engine)
396
return await resolveBinary(engine, customPath)
397
}
398
399
/**
400
* Resolve all engines
401
*/
402
async resolveAll(): Promise<Record<BinaryType, string>> {
403
const engines = Object.values(BinaryType)
404
const results: Partial<Record<BinaryType, string>> = {}
405
406
await Promise.all(
407
engines.map(async (engine) => {
408
try {
409
results[engine] = await this.resolve(engine)
410
} catch (error) {
411
console.warn(`Could not resolve ${engine}: ${error.message}`)
412
}
413
})
414
)
415
416
return results as Record<BinaryType, string>
417
}
418
419
/**
420
* Generate environment variable export commands
421
*/
422
generateEnvExports(): string[] {
423
const exports: string[] = []
424
425
for (const [engine, path] of this.customPaths) {
426
const envVar = engineEnvVarMap[engine]
427
exports.push(`export ${envVar}="${path}"`)
428
}
429
430
return exports
431
}
432
}
433
434
// Usage
435
async function manageEngineConfiguration() {
436
const manager = new EnginePathManager()
437
438
// Load from environment
439
manager.loadFromEnvironment()
440
441
// Set custom paths programmatically
442
manager.setCustomPath(BinaryType.QueryEngine, '/opt/prisma/query-engine')
443
manager.setCustomPath(BinaryType.SchemaEngine, '/opt/prisma/schema-engine')
444
445
// Resolve all engines
446
const enginePaths = await manager.resolveAll()
447
console.log('Resolved engine paths:', enginePaths)
448
449
// Generate export commands for deployment
450
const exports = manager.generateEnvExports()
451
console.log('\nEnvironment exports for deployment:')
452
exports.forEach(exp => console.log(exp))
453
}
454
```
455
456
### Binary Validation and Health Check
457
458
```typescript
459
import {
460
resolveBinary,
461
BinaryType,
462
getBinaryTargetForCurrentPlatform
463
} from '@prisma/internals'
464
import { execFile } from 'child_process'
465
import { promisify } from 'util'
466
import { access, constants } from 'fs'
467
468
const execFileAsync = promisify(execFile)
469
const accessAsync = promisify(access)
470
471
interface BinaryHealthStatus {
472
engine: BinaryType
473
path: string
474
exists: boolean
475
executable: boolean
476
version?: string
477
error?: string
478
}
479
480
async function checkBinaryHealth(engine: BinaryType): Promise<BinaryHealthStatus> {
481
const status: BinaryHealthStatus = {
482
engine,
483
path: '',
484
exists: false,
485
executable: false
486
}
487
488
try {
489
// Resolve binary path
490
status.path = await resolveBinary(engine)
491
492
// Check if file exists
493
try {
494
await accessAsync(status.path, constants.F_OK)
495
status.exists = true
496
} catch {
497
status.exists = false
498
status.error = 'Binary file not found'
499
return status
500
}
501
502
// Check if executable
503
try {
504
await accessAsync(status.path, constants.X_OK)
505
status.executable = true
506
} catch {
507
status.executable = false
508
status.error = 'Binary not executable'
509
return status
510
}
511
512
// Get version information
513
try {
514
const { stdout } = await execFileAsync(status.path, ['--version'], {
515
timeout: 5000
516
})
517
status.version = stdout.trim()
518
} catch (error) {
519
status.error = `Version check failed: ${error.message}`
520
}
521
522
} catch (error) {
523
status.error = `Resolution failed: ${error.message}`
524
}
525
526
return status
527
}
528
529
async function performEngineHealthCheck(): Promise<void> {
530
console.log('Performing Prisma Engine Health Check...')
531
console.log(`Platform: ${getBinaryTargetForCurrentPlatform()}`)
532
console.log('=' .repeat(60))
533
534
const engines = [BinaryType.QueryEngine, BinaryType.SchemaEngine]
535
const results: BinaryHealthStatus[] = []
536
537
for (const engine of engines) {
538
const status = await checkBinaryHealth(engine)
539
results.push(status)
540
541
const icon = status.exists && status.executable && !status.error ? '✓' : '✗'
542
543
console.log(`${icon} ${engine}`)
544
console.log(` Path: ${status.path || 'Not resolved'}`)
545
console.log(` Exists: ${status.exists}`)
546
console.log(` Executable: ${status.executable}`)
547
548
if (status.version) {
549
console.log(` Version: ${status.version}`)
550
}
551
552
if (status.error) {
553
console.log(` Error: ${status.error}`)
554
}
555
556
console.log()
557
}
558
559
// Summary
560
const healthy = results.filter(r => r.exists && r.executable && !r.error)
561
const total = results.length
562
563
console.log('=' .repeat(60))
564
console.log(`Health Check Summary: ${healthy.length}/${total} engines healthy`)
565
566
if (healthy.length < total) {
567
const issues = results.filter(r => !r.exists || !r.executable || r.error)
568
console.log('\nIssues found:')
569
issues.forEach(issue => {
570
console.log(`- ${issue.engine}: ${issue.error || 'Unknown issue'}`)
571
})
572
573
process.exit(1)
574
}
575
576
console.log('All engines are healthy and ready!')
577
}
578
```