0
# Engine Commands and Schema Operations
1
2
The engine commands domain provides comprehensive schema processing capabilities using WASM-based engines for formatting, validation, DMMF generation, and configuration extraction.
3
4
## Functions
5
6
### Schema Formatting
7
8
#### `formatSchema(options, formattingOptions?)`
9
10
Formats Prisma schema files using the WASM formatter with customizable formatting options.
11
12
```typescript { .api }
13
function formatSchema(
14
options: { schemas: MultipleSchemas },
15
formattingOptions?: Partial<DocumentFormattingParams['options']>
16
): Promise<MultipleSchemas>
17
```
18
19
**Parameters:**
20
- `options: { schemas: MultipleSchemas }` - Schemas to format
21
- `formattingOptions?: Partial<DocumentFormattingParams['options']>` - Formatting configuration
22
23
**DocumentFormattingParams Options:**
24
```typescript { .api }
25
interface DocumentFormattingParams {
26
options?: {
27
tabSize?: number // Tab size (default: 2)
28
insertSpaces?: boolean // Use spaces instead of tabs (default: true)
29
}
30
}
31
```
32
33
**Returns:** `Promise<MultipleSchemas>` - Formatted schemas
34
35
**Example:**
36
```typescript
37
const formatted = await formatSchema(
38
{ schemas: loadedSchemas },
39
{ tabSize: 4, insertSpaces: true }
40
)
41
```
42
43
### Configuration Extraction
44
45
#### `getConfig(options)`
46
47
Extracts and parses configuration from Prisma schema using the WASM engine.
48
49
```typescript { .api }
50
function getConfig(options: GetConfigOptions): Promise<ConfigMetaFormat>
51
```
52
53
**GetConfigOptions:**
54
```typescript { .api }
55
interface GetConfigOptions {
56
schemas: SchemaFileInput // Schema input
57
cwd?: string // Current working directory
58
ignoreEnvVarErrors?: boolean // Ignore environment variable errors
59
}
60
```
61
62
**Returns:** `Promise<ConfigMetaFormat>` - Parsed configuration with datasources, generators, and warnings
63
64
**Example:**
65
```typescript
66
const config = await getConfig({
67
schemas: schemaResult.schemas,
68
cwd: process.cwd(),
69
ignoreEnvVarErrors: false
70
})
71
72
console.log(`Found ${config.datasources.length} datasources`)
73
console.log(`Found ${config.generators.length} generators`)
74
if (config.warnings.length > 0) {
75
console.warn('Configuration warnings:', config.warnings)
76
}
77
```
78
79
#### `getDirectUrl(ds)`
80
81
Extracts the direct URL from a datasource configuration.
82
83
```typescript { .api }
84
function getDirectUrl(ds: DataSource): EnvValue | undefined
85
```
86
87
**Parameters:**
88
- `ds: DataSource` - Datasource object
89
90
**Returns:** `EnvValue | undefined` - Direct URL environment value if defined
91
92
#### `getEffectiveUrl(ds)`
93
94
Gets the effective URL from a datasource (direct URL takes precedence over regular URL).
95
96
```typescript { .api }
97
function getEffectiveUrl(ds: DataSource): EnvValue
98
```
99
100
**Parameters:**
101
- `ds: DataSource` - Datasource object
102
103
**Returns:** `EnvValue` - Effective URL environment value
104
105
#### `resolveUrl(envValue?)`
106
107
Resolves URL string from environment value configuration.
108
109
```typescript { .api }
110
function resolveUrl(envValue?: EnvValue): string | undefined
111
```
112
113
**Parameters:**
114
- `envValue?: EnvValue` - Environment value configuration
115
116
**Returns:** `string | undefined` - Resolved URL string
117
118
**Example:**
119
```typescript
120
const config = await getConfig({ schemas })
121
for (const datasource of config.datasources) {
122
const directUrl = getDirectUrl(datasource)
123
const effectiveUrl = getEffectiveUrl(datasource)
124
const resolvedUrl = resolveUrl(effectiveUrl)
125
126
console.log(`Datasource: ${datasource.name}`)
127
console.log(`Direct URL: ${directUrl ? 'defined' : 'not defined'}`)
128
console.log(`Resolved URL: ${resolvedUrl}`)
129
}
130
```
131
132
### DMMF Generation
133
134
#### `getDMMF(options)`
135
136
Generates Data Model Meta Format (DMMF) from Prisma schema using the WASM engine.
137
138
```typescript { .api }
139
function getDMMF(options: GetDMMFOptions): Promise<DMMF.Document>
140
```
141
142
**GetDMMFOptions:**
143
```typescript { .api }
144
interface GetDMMFOptions {
145
datamodel: SchemaFileInput // Schema input
146
previewFeatures?: string[] // Preview features to enable
147
}
148
```
149
150
**Returns:** `Promise<DMMF.Document>` - Generated DMMF document containing models, enums, types, and mappings
151
152
**Example:**
153
```typescript
154
const dmmf = await getDMMF({
155
datamodel: schemaResult.schemas,
156
previewFeatures: ['typedSql', 'views']
157
})
158
159
console.log(`Models: ${dmmf.datamodel.models.length}`)
160
console.log(`Enums: ${dmmf.datamodel.enums.length}`)
161
console.log(`Types: ${dmmf.datamodel.types.length}`)
162
163
// Access model information
164
for (const model of dmmf.datamodel.models) {
165
console.log(`Model ${model.name}: ${model.fields.length} fields`)
166
}
167
```
168
169
### Schema Validation
170
171
#### `validate(options)`
172
173
Validates Prisma schema without generating DMMF, throwing error if validation fails.
174
175
```typescript { .api }
176
function validate(options: ValidateOptions): void
177
```
178
179
**ValidateOptions:**
180
```typescript { .api }
181
interface ValidateOptions {
182
schemas: SchemaFileInput // Schema input to validate
183
cwd?: string // Current working directory
184
}
185
```
186
187
**Throws:** Error if validation fails
188
189
**Example:**
190
```typescript
191
try {
192
validate({
193
schemas: schemaResult.schemas,
194
cwd: process.cwd()
195
})
196
console.log('Schema validation passed')
197
} catch (error) {
198
console.error('Schema validation failed:', error.message)
199
}
200
```
201
202
### Schema Linting
203
204
#### `lintSchema(options)`
205
206
Lints Prisma schema and returns array of diagnostics (warnings and errors).
207
208
```typescript { .api }
209
function lintSchema(options: { schemas: MultipleSchemas }): LintDiagnostic[]
210
```
211
212
**Parameters:**
213
- `options: { schemas: MultipleSchemas }` - Schemas to lint
214
215
**Returns:** `LintDiagnostic[]` - Array of lint diagnostics
216
217
#### `getLintWarningsAsText(lintDiagnostics)`
218
219
Converts lint diagnostics to formatted text warnings for display.
220
221
```typescript { .api }
222
function getLintWarningsAsText(lintDiagnostics: LintDiagnostic[]): string
223
```
224
225
**Parameters:**
226
- `lintDiagnostics: LintDiagnostic[]` - Lint diagnostics to format
227
228
**Returns:** `string` - Formatted warning text
229
230
#### `handleLintPanic<T>(tryCb)`
231
232
Handles panics during schema linting operations by converting them to RustPanic errors.
233
234
```typescript { .api }
235
function handleLintPanic<T>(tryCb: () => T): T
236
```
237
238
**Parameters:**
239
- `tryCb: () => T` - Callback function that might panic
240
241
**Returns:** `T` - Result or throws RustPanic
242
243
**Example:**
244
```typescript
245
const diagnostics = lintSchema({ schemas: loadedSchemas })
246
247
const warnings = diagnostics.filter(d => d.is_warning)
248
const errors = diagnostics.filter(d => !d.is_warning)
249
250
if (warnings.length > 0) {
251
console.warn('Lint warnings:')
252
console.warn(getLintWarningsAsText(warnings))
253
}
254
255
if (errors.length > 0) {
256
console.error('Lint errors:')
257
console.error(getLintWarningsAsText(errors))
258
}
259
```
260
261
### Schema Merging
262
263
#### `mergeSchemas(options)`
264
265
Merges multiple schema files into a single schema string.
266
267
```typescript { .api }
268
function mergeSchemas(options: MergeSchemasOptions): string
269
```
270
271
**MergeSchemasOptions:**
272
```typescript { .api }
273
interface MergeSchemasOptions {
274
schemas: MultipleSchemas // Multiple schema files to merge
275
}
276
```
277
278
**Returns:** `string` - Merged schema string
279
280
**Example:**
281
```typescript
282
const mergedSchema = mergeSchemas({
283
schemas: {
284
'schema.prisma': schemaContent1,
285
'models.prisma': schemaContent2,
286
'enums.prisma': schemaContent3
287
}
288
})
289
290
console.log('Merged schema length:', mergedSchema.length)
291
```
292
293
### Engine Information
294
295
#### `getEnginesInfo(enginesInfo)`
296
297
Gets formatted engine information and collects any errors encountered.
298
299
```typescript { .api }
300
function getEnginesInfo(enginesInfo: BinaryInfoMatrix): readonly [string, Error[]]
301
```
302
303
**Parameters:**
304
- `enginesInfo: BinaryInfoMatrix` - Engine information matrix
305
306
**Returns:** `readonly [string, Error[]]` - Tuple of version message and array of errors
307
308
#### `resolveEngine(binaryName)`
309
310
Resolves engine path and version information for a specific binary type.
311
312
```typescript { .api }
313
function resolveEngine(binaryName: BinaryType): Promise<EngineInfo>
314
```
315
316
**Parameters:**
317
- `binaryName: BinaryType` - Type of binary to resolve
318
319
**Returns:** `Promise<EngineInfo>` - Engine information including path and version
320
321
#### `getEngineVersion(enginePath?, binaryName?)`
322
323
Gets version information from an engine binary.
324
325
```typescript { .api }
326
function getEngineVersion(
327
enginePath?: string,
328
binaryName?: BinaryType
329
): Promise<string>
330
```
331
332
**Parameters:**
333
- `enginePath?: string` - Optional engine path
334
- `binaryName?: BinaryType` - Binary type
335
336
**Returns:** `Promise<string>` - Engine version string
337
338
**Example:**
339
```typescript
340
// Get query engine information
341
const queryEngineInfo = await resolveEngine(BinaryType.QueryEngine)
342
343
if (queryEngineInfo.path._tag === 'Right') {
344
console.log('Query engine path:', queryEngineInfo.path.right)
345
}
346
347
if (queryEngineInfo.version._tag === 'Right') {
348
console.log('Query engine version:', queryEngineInfo.version.right)
349
}
350
351
// Get version directly
352
const version = await getEngineVersion()
353
console.log('Engine version:', version)
354
```
355
356
## WASM Integration and Schema Engine Loading
357
358
### WASM Namespace
359
360
#### `wasm`
361
362
WebAssembly integration namespace providing access to Prisma Schema WASM modules and Schema Engine WASM functionality.
363
364
```typescript { .api }
365
namespace wasm {
366
// WASM modules
367
const prismaSchemaWasm: typeof import('@prisma/prisma-schema-wasm')
368
type SchemaEngineWasm = import('@prisma/schema-engine-wasm').SchemaEngine
369
370
// Version information
371
const prismaSchemaWasmVersion: string // e.g. "4.3.0-18.a39215673171b87177b86233206a5d65f2558857"
372
const schemaEngineWasmVersion: string // e.g. "4.3.0-18.a39215673171b87177b86233206a5d65f2558857"
373
}
374
```
375
376
#### `wasm.prismaSchemaWasm`
377
378
Direct export of the Prisma Schema WASM module for schema processing operations.
379
380
```typescript { .api }
381
const prismaSchemaWasm: typeof import('@prisma/prisma-schema-wasm')
382
```
383
384
**Usage:**
385
```typescript
386
import { wasm } from '@prisma/internals'
387
388
// Use the Prisma Schema WASM module directly
389
const result = wasm.prismaSchemaWasm.format(schemaContent, formatOptions)
390
```
391
392
#### `wasm.SchemaEngineWasm`
393
394
Type export for the WASM-based schema engine.
395
396
```typescript { .api }
397
type SchemaEngineWasm = import('@prisma/schema-engine-wasm').SchemaEngine
398
```
399
400
#### `wasm.prismaSchemaWasmVersion`
401
402
Version string for the Prisma Schema WASM package dependency.
403
404
```typescript { .api }
405
const prismaSchemaWasmVersion: string
406
```
407
408
#### `wasm.schemaEngineWasmVersion`
409
410
Version string for the Schema Engine WASM package dependency.
411
412
```typescript { .api }
413
const schemaEngineWasmVersion: string
414
```
415
416
**Example:**
417
```typescript
418
import { wasm } from '@prisma/internals'
419
420
console.log('WASM Versions:')
421
console.log(`Prisma Schema WASM: ${wasm.prismaSchemaWasmVersion}`)
422
console.log(`Schema Engine WASM: ${wasm.schemaEngineWasmVersion}`)
423
```
424
425
### WASM Schema Engine Loader
426
427
#### `wasmSchemaEngineLoader`
428
429
Singleton loader for WASM-based schema engine instances with efficient caching and WebAssembly integration.
430
431
```typescript { .api }
432
const wasmSchemaEngineLoader: {
433
loadSchemaEngine(
434
input: ConstructorOptions,
435
debug: (arg: string) => void,
436
adapter: ErrorCapturingSqlDriverAdapterFactory
437
): Promise<SchemaEngineInstance>
438
}
439
```
440
441
#### `wasmSchemaEngineLoader.loadSchemaEngine(input, debug, adapter)`
442
443
Loads and initializes a WASM schema engine instance with caching for efficiency.
444
445
```typescript { .api }
446
function loadSchemaEngine(
447
input: ConstructorOptions,
448
debug: (arg: string) => void,
449
adapter: ErrorCapturingSqlDriverAdapterFactory
450
): Promise<SchemaEngineInstance>
451
```
452
453
**Parameters:**
454
- `input: ConstructorOptions` - Schema engine constructor options
455
- `debug: (arg: string) => void` - Debug logging function
456
- `adapter: ErrorCapturingSqlDriverAdapterFactory` - SQL driver adapter factory
457
458
**Returns:** `Promise<SchemaEngineInstance>` - Initialized schema engine instance
459
460
**Caching Behavior:**
461
- Creates WASM instance only once for efficiency
462
- Reuses cached instance across multiple calls
463
- Prevents WebAssembly binding conflicts from multiple instantiations
464
465
**Example:**
466
```typescript
467
import { wasmSchemaEngineLoader } from '@prisma/internals'
468
469
async function initializeSchemaEngine() {
470
const debugLogger = (message: string) => {
471
console.log(`[Schema Engine Debug]: ${message}`)
472
}
473
474
const constructorOptions = {
475
// Schema engine configuration options
476
datamodel: schemaContent,
477
logQueries: true,
478
logLevel: 'info'
479
}
480
481
const sqlAdapter = createSqlDriverAdapterFactory()
482
483
try {
484
const schemaEngine = await wasmSchemaEngineLoader.loadSchemaEngine(
485
constructorOptions,
486
debugLogger,
487
sqlAdapter
488
)
489
490
console.log('WASM Schema Engine loaded successfully')
491
return schemaEngine
492
} catch (error) {
493
console.error('Failed to load WASM Schema Engine:', error.message)
494
throw error
495
}
496
}
497
498
// Multiple calls will reuse the same WASM instance internally
499
const engine1 = await wasmSchemaEngineLoader.loadSchemaEngine(opts1, debug, adapter)
500
const engine2 = await wasmSchemaEngineLoader.loadSchemaEngine(opts2, debug, adapter)
501
// Both use the same underlying WASM module instance
502
```
503
504
**Internal Architecture:**
505
```typescript
506
// Simplified internal structure
507
const wasmSchemaEngineLoader = {
508
async loadSchemaEngine(input, debug, adapter) {
509
// Singleton pattern - create WASM instance only once
510
if (loadedWasmInstance === undefined) {
511
const wasmModule = await getSchemaEngineWasModule() // Load .wasm file
512
const runtime = await import('@prisma/schema-engine-wasm/schema_engine_bg')
513
514
// WebAssembly instantiation with wasm-bindgen integration
515
const instance = new WebAssembly.Instance(wasmModule, {
516
'./schema_engine_bg.js': runtime
517
})
518
519
runtime.__wbg_set_wasm(instance.exports)
520
const wbindgen_start = instance.exports.__wbindgen_start as () => void
521
wbindgen_start()
522
523
loadedWasmInstance = runtime.SchemaEngine
524
}
525
526
return await loadedWasmInstance.new(input, debug, adapter)
527
}
528
}
529
```
530
531
### Error Path Processing
532
533
#### `relativizePathInPSLError(message)`
534
535
Converts absolute paths in PSL (Prisma Schema Language) error messages to relative paths for better readability.
536
537
```typescript { .api }
538
function relativizePathInPSLError(message: string): string
539
```
540
541
**Parameters:**
542
- `message: string` - Error message containing absolute paths
543
544
**Returns:** `string` - Error message with relativized paths
545
546
## Types and Interfaces
547
548
### Configuration Types
549
550
#### `ConfigMetaFormat`
551
552
Complete configuration extracted from Prisma schema.
553
554
```typescript { .api }
555
interface ConfigMetaFormat {
556
datasources: DataSource[] // Parsed datasources
557
generators: GeneratorConfig[] // Parsed generators
558
warnings: string[] // Configuration warnings
559
}
560
```
561
562
#### `GetDMMFOptions`
563
564
Options for DMMF generation.
565
566
```typescript { .api }
567
interface GetDMMFOptions {
568
datamodel: SchemaFileInput // Schema input
569
previewFeatures?: string[] // Preview features to enable
570
}
571
```
572
573
### Engine Information Types
574
575
#### `EngineInfo`
576
577
Information about an engine binary including path and version.
578
579
```typescript { .api }
580
interface EngineInfo {
581
fromEnvVar: O.Option<string> // Environment variable name if resolved from env
582
path: E.Either<Error, string> // Engine path or error
583
version: E.Either<Error, string> // Engine version or error
584
}
585
```
586
587
#### `BinaryMatrix<T>`
588
589
Type matrix for different binary types.
590
591
```typescript { .api }
592
type BinaryMatrix<T> = {
593
'query-engine': T
594
'schema-engine': T
595
}
596
```
597
598
#### `BinaryInfoMatrix`
599
600
Engine information for each binary type.
601
602
```typescript { .api }
603
type BinaryInfoMatrix = BinaryMatrix<EngineInfo>
604
```
605
606
### Linting Types
607
608
#### `LintDiagnostic`
609
610
Union type representing lint warnings or errors.
611
612
```typescript { .api }
613
type LintDiagnostic = LintWarning | LintError
614
```
615
616
#### `LintWarning`
617
618
Lint warning diagnostic information.
619
620
```typescript { .api }
621
interface LintWarning {
622
is_warning: true // Indicates this is a warning
623
start: number // Start position in schema
624
end: number // End position in schema
625
text: string // Warning message text
626
}
627
```
628
629
#### `LintError`
630
631
Lint error diagnostic information.
632
633
```typescript { .api }
634
interface LintError {
635
is_warning: false // Indicates this is an error
636
start: number // Start position in schema
637
end: number // End position in schema
638
text: string // Error message text
639
}
640
```
641
642
### Schema Input Types
643
644
#### `SchemaFileInput`
645
646
Input type for schema content that can be a string or MultipleSchemas.
647
648
```typescript { .api }
649
type SchemaFileInput = string | MultipleSchemas
650
```
651
652
#### `MultipleSchemas`
653
654
Object representing multiple schema files with their content.
655
656
```typescript { .api }
657
type MultipleSchemas = {
658
[filename: string]: string // Filename to content mapping
659
}
660
```
661
662
## Examples
663
664
### Complete Schema Processing Workflow
665
666
```typescript
667
import {
668
getConfig,
669
validate,
670
formatSchema,
671
getDMMF,
672
lintSchema,
673
getLintWarningsAsText
674
} from '@prisma/internals'
675
676
async function processSchema(schemas: MultipleSchemas) {
677
// 1. Validate schema
678
try {
679
validate({ schemas, cwd: process.cwd() })
680
console.log('✓ Schema validation passed')
681
} catch (error) {
682
console.error('✗ Schema validation failed:', error.message)
683
return
684
}
685
686
// 2. Lint schema
687
const diagnostics = lintSchema({ schemas })
688
if (diagnostics.length > 0) {
689
const warnings = getLintWarningsAsText(diagnostics)
690
console.warn('Lint diagnostics:\n', warnings)
691
}
692
693
// 3. Format schema
694
const formatted = await formatSchema(
695
{ schemas },
696
{ tabSize: 2, insertSpaces: true }
697
)
698
console.log('✓ Schema formatted')
699
700
// 4. Extract configuration
701
const config = await getConfig({
702
schemas: formatted,
703
cwd: process.cwd()
704
})
705
console.log(`✓ Found ${config.datasources.length} datasources, ${config.generators.length} generators`)
706
707
// 5. Generate DMMF
708
const dmmf = await getDMMF({
709
datamodel: formatted,
710
previewFeatures: ['typedSql']
711
})
712
console.log(`✓ Generated DMMF with ${dmmf.datamodel.models.length} models`)
713
714
return {
715
formatted,
716
config,
717
dmmf,
718
diagnostics
719
}
720
}
721
```
722
723
### Engine Version Checking
724
725
```typescript
726
import {
727
resolveEngine,
728
getEngineVersion,
729
getEnginesInfo,
730
BinaryType
731
} from '@prisma/internals'
732
733
async function checkEngineVersions() {
734
const engines = ['query-engine', 'schema-engine'] as const
735
const engineInfo: any = {}
736
737
for (const engineType of engines) {
738
try {
739
const info = await resolveEngine(BinaryType[engineType])
740
engineInfo[engineType] = info
741
742
console.log(`${engineType}:`)
743
if (info.path._tag === 'Right') {
744
console.log(` Path: ${info.path.right}`)
745
}
746
if (info.version._tag === 'Right') {
747
console.log(` Version: ${info.version.right}`)
748
}
749
if (info.fromEnvVar._tag === 'Some') {
750
console.log(` From env var: ${info.fromEnvVar.value}`)
751
}
752
} catch (error) {
753
console.error(`Failed to resolve ${engineType}:`, error.message)
754
}
755
}
756
757
// Get formatted summary
758
const [summary, errors] = getEnginesInfo(engineInfo)
759
console.log('\nEngine Summary:')
760
console.log(summary)
761
762
if (errors.length > 0) {
763
console.error('Errors:', errors.map(e => e.message))
764
}
765
}
766
```
767
768
### URL Resolution from Datasources
769
770
```typescript
771
import {
772
getConfig,
773
getDirectUrl,
774
getEffectiveUrl,
775
resolveUrl
776
} from '@prisma/internals'
777
778
async function analyzeDatasourceUrls(schemas: MultipleSchemas) {
779
const config = await getConfig({ schemas })
780
781
for (const datasource of config.datasources) {
782
console.log(`\nDatasource: ${datasource.name}`)
783
console.log(`Provider: ${datasource.provider}`)
784
785
// Check for direct URL
786
const directUrl = getDirectUrl(datasource)
787
if (directUrl) {
788
console.log('Direct URL configured: Yes')
789
const resolvedDirectUrl = resolveUrl(directUrl)
790
if (resolvedDirectUrl) {
791
console.log(`Direct URL: ${resolvedDirectUrl}`)
792
}
793
} else {
794
console.log('Direct URL configured: No')
795
}
796
797
// Get effective URL (direct takes precedence)
798
const effectiveUrl = getEffectiveUrl(datasource)
799
const resolvedUrl = resolveUrl(effectiveUrl)
800
if (resolvedUrl) {
801
console.log(`Effective URL: ${resolvedUrl}`)
802
}
803
}
804
}
805
```