or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

binary-resolution.mdcli-utilities.mddatabase-operations.mdengine-commands.mderror-handling.mdgenerators.mdindex.mdsyntax-highlighting.mdtracing.mdutilities.md

generators.mddocs/

0

# Generator System and Management

1

2

The generator system domain provides comprehensive generator lifecycle management including initialization, execution, cleanup, and registry management for both JSON-RPC and in-process generators.

3

4

## Classes

5

6

### Abstract Generator Base Class

7

8

#### `Generator`

9

10

Abstract base class for all generator implementations providing common interface and lifecycle management.

11

12

```typescript { .api }

13

abstract class Generator {

14

abstract init(): Promise<void>

15

abstract generate(): Promise<void>

16

abstract setOptions(options: GeneratorOptions): void

17

abstract setBinaryPaths(binaryPaths: BinaryPaths): void

18

abstract getPrettyName(): string

19

abstract getProvider(): string

20

abstract stop(): void

21

}

22

```

23

24

**Methods:**

25

- `init(): Promise<void>` - Initialize the generator

26

- `generate(): Promise<void>` - Execute generation process

27

- `setOptions(options: GeneratorOptions): void` - Set generator options

28

- `setBinaryPaths(binaryPaths: BinaryPaths): void` - Set binary paths for engines

29

- `getPrettyName(): string` - Get display name for UI

30

- `getProvider(): string` - Get provider name/identifier

31

- `stop(): void` - Stop and cleanup the generator

32

33

### JSON-RPC Generator Implementation

34

35

#### `JsonRpcGenerator`

36

37

Generator implementation for JSON-RPC based external generators that communicate via process IPC.

38

39

```typescript { .api }

40

class JsonRpcGenerator extends Generator {

41

constructor(

42

executablePath: string,

43

config: GeneratorConfig,

44

isNode?: boolean

45

)

46

}

47

```

48

49

**Constructor Parameters:**

50

- `executablePath: string` - Path to the generator executable

51

- `config: GeneratorConfig` - Generator configuration

52

- `isNode?: boolean` - Whether the generator is a Node.js process

53

54

**Example:**

55

```typescript

56

const generator = new JsonRpcGenerator(

57

'/path/to/prisma-client-generator',

58

{

59

name: 'client',

60

provider: 'prisma-client-js',

61

output: './node_modules/.prisma/client',

62

config: {},

63

binaryTargets: ['native']

64

},

65

true // is Node.js

66

)

67

68

await generator.init()

69

await generator.generate()

70

generator.stop()

71

```

72

73

### In-Process Generator Implementation

74

75

#### `InProcessGenerator`

76

77

Generator implementation for in-process generators that run directly within the same Node.js process.

78

79

```typescript { .api }

80

class InProcessGenerator extends Generator {

81

constructor(config: GeneratorConfig, generator: IGenerator)

82

}

83

```

84

85

**Constructor Parameters:**

86

- `config: GeneratorConfig` - Generator configuration

87

- `generator: IGenerator` - Generator implementation interface

88

89

**Example:**

90

```typescript

91

const inProcessGen = new InProcessGenerator(

92

config,

93

{

94

onManifest: () => Promise.resolve(manifest),

95

onGenerate: (options) => Promise.resolve()

96

}

97

)

98

```

99

100

## Functions

101

102

### Generator Factory Functions

103

104

#### `getGenerators(options)`

105

106

Factory function that creates and initializes all generators from schema configuration.

107

108

```typescript { .api }

109

function getGenerators(options: GetGeneratorOptions): Promise<Generator[]>

110

```

111

112

**GetGeneratorOptions:**

113

```typescript { .api }

114

interface GetGeneratorOptions {

115

schemaPath?: string // Path to schema file

116

cwd?: string // Current working directory

117

schemaContent?: string // Schema content (alternative to schemaPath)

118

generators?: GeneratorConfig[] // Explicit generator configurations

119

generatorRegistry?: GeneratorRegistry // Registry of available generators

120

skipDownload?: boolean // Skip binary downloads

121

printDownloadProgress?: boolean // Show download progress

122

version?: string // Prisma version

123

engineVersion?: string // Engine version

124

}

125

```

126

127

**Returns:** `Promise<Generator[]>` - Array of initialized generators

128

129

**Example:**

130

```typescript

131

const generators = await getGenerators({

132

schemaPath: './prisma/schema.prisma',

133

cwd: process.cwd(),

134

printDownloadProgress: true,

135

skipDownload: false

136

})

137

138

console.log(`Initialized ${generators.length} generators`)

139

140

// Run all generators

141

for (const generator of generators) {

142

await generator.generate()

143

console.log(`✓ ${generator.getPrettyName()}`)

144

}

145

146

// Cleanup

147

generators.forEach(gen => gen.stop())

148

```

149

150

#### `getGenerator(options)`

151

152

Shortcut function for getting a single generator instance (useful for testing and single-generator scenarios).

153

154

```typescript { .api }

155

function getGenerator(options: GetGeneratorOptions): Promise<Generator>

156

```

157

158

**Parameters:** Same as `getGenerators`

159

160

**Returns:** `Promise<Generator>` - Single generator instance

161

162

**Example:**

163

```typescript

164

const generator = await getGenerator({

165

schemaContent: `

166

generator client {

167

provider = "prisma-client-js"

168

output = "./generated/client"

169

}

170

`,

171

cwd: process.cwd()

172

})

173

174

await generator.generate()

175

```

176

177

### Generator Utility Functions

178

179

#### `fixBinaryTargets(schemaBinaryTargets, runtimeBinaryTarget)`

180

181

Fixes binary targets by adding native or runtime target as needed to ensure generators can run properly.

182

183

```typescript { .api }

184

function fixBinaryTargets(

185

schemaBinaryTargets: BinaryTargetsEnvValue[],

186

runtimeBinaryTarget: BinaryTarget | string

187

): BinaryTargetsEnvValue[]

188

```

189

190

**Parameters:**

191

- `schemaBinaryTargets: BinaryTargetsEnvValue[]` - Binary targets from schema

192

- `runtimeBinaryTarget: BinaryTarget | string` - Runtime binary target

193

194

**Returns:** `BinaryTargetsEnvValue[]` - Fixed binary targets including necessary runtime targets

195

196

**Example:**

197

```typescript

198

import { fixBinaryTargets, getBinaryTargetForCurrentPlatform } from '@prisma/internals'

199

200

const schemaBinaryTargets = [{ fromEnvVar: null, value: 'linux-musl' }]

201

const runtimeTarget = getBinaryTargetForCurrentPlatform()

202

203

const fixedTargets = fixBinaryTargets(schemaBinaryTargets, runtimeTarget)

204

console.log('Fixed binary targets:', fixedTargets)

205

// Ensures current platform is included if not already specified

206

```

207

208

#### `printGeneratorConfig(config)`

209

210

Formats generator configuration as a readable string for debugging and logging.

211

212

```typescript { .api }

213

function printGeneratorConfig(config: GeneratorConfig): string

214

```

215

216

**Parameters:**

217

- `config: GeneratorConfig` - Generator configuration to format

218

219

**Returns:** `string` - Formatted configuration string

220

221

**Example:**

222

```typescript

223

const config: GeneratorConfig = {

224

name: 'client',

225

provider: 'prisma-client-js',

226

output: './generated/client',

227

config: { engineType: 'binary' },

228

binaryTargets: ['native', 'linux-musl']

229

}

230

231

console.log(printGeneratorConfig(config))

232

// Output:

233

// generator client {

234

// provider = "prisma-client-js"

235

// output = "./generated/client"

236

// engineType = "binary"

237

// binaryTargets = ["native", "linux-musl"]

238

// }

239

```

240

241

## Types and Interfaces

242

243

### Registry Types

244

245

#### `GeneratorRegistry`

246

247

Registry mapping generator providers to their implementations.

248

249

```typescript { .api }

250

type GeneratorRegistry = Record<string, GeneratorRegistryEntry>

251

```

252

253

#### `GeneratorRegistryEntry`

254

255

Union type for registry entries supporting both RPC and in-process generators.

256

257

```typescript { .api }

258

type GeneratorRegistryEntry =

259

| {

260

type: 'rpc'

261

generatorPath: string

262

isNode?: boolean

263

}

264

| {

265

type: 'in-process'

266

generator: IGenerator

267

}

268

```

269

270

**RPC Registry Entry:**

271

- `type: 'rpc'` - Indicates JSON-RPC generator

272

- `generatorPath: string` - Path to generator executable

273

- `isNode?: boolean` - Whether generator is Node.js based

274

275

**In-Process Registry Entry:**

276

- `type: 'in-process'` - Indicates in-process generator

277

- `generator: IGenerator` - Generator implementation

278

279

**Example:**

280

```typescript

281

const registry: GeneratorRegistry = {

282

'prisma-client-js': {

283

type: 'rpc',

284

generatorPath: './node_modules/.prisma/client/generator-build/index.js',

285

isNode: true

286

},

287

'custom-generator': {

288

type: 'in-process',

289

generator: {

290

onManifest: () => Promise.resolve(customManifest),

291

onGenerate: (options) => customGenerate(options)

292

}

293

}

294

}

295

```

296

297

### Generator Interface Types

298

299

#### `IGenerator`

300

301

Interface for in-process generator implementations.

302

303

```typescript { .api }

304

interface IGenerator {

305

onManifest(config: GeneratorConfig): Promise<GeneratorManifest>

306

onGenerate(options: GeneratorOptions): Promise<void>

307

}

308

```

309

310

**Methods:**

311

- `onManifest(config: GeneratorConfig): Promise<GeneratorManifest>` - Return generator manifest

312

- `onGenerate(options: GeneratorOptions): Promise<void>` - Execute generation

313

314

#### `GeneratorManifest`

315

316

Manifest describing generator capabilities and requirements.

317

318

```typescript { .api }

319

interface GeneratorManifest {

320

prettyName?: string // Display name

321

defaultOutput?: string // Default output directory

322

denylist?: string[] // Unsupported features

323

requiresGenerators?: string[] // Required other generators

324

requiresEngines?: string[] // Required engine binaries

325

version: string // Generator version

326

}

327

```

328

329

#### `BinaryPaths`

330

331

Paths to engine binaries required by generators.

332

333

```typescript { .api }

334

interface BinaryPaths {

335

queryEngine?: string // Query engine binary path

336

schemaEngine?: string // Schema engine binary path

337

libqueryEngine?: string // Query engine library path

338

migrationEngine?: string // Migration engine binary path (legacy)

339

}

340

```

341

342

## Examples

343

344

### Complete Generator Lifecycle Management

345

346

```typescript

347

import {

348

getGenerators,

349

printGeneratorConfig,

350

fixBinaryTargets,

351

getBinaryTargetForCurrentPlatform

352

} from '@prisma/internals'

353

354

async function runGenerationPipeline() {

355

try {

356

// Get all generators from schema

357

const generators = await getGenerators({

358

schemaPath: './prisma/schema.prisma',

359

cwd: process.cwd(),

360

printDownloadProgress: true

361

})

362

363

console.log(`Found ${generators.length} generators`)

364

365

// Initialize all generators

366

for (const generator of generators) {

367

console.log(`Initializing ${generator.getPrettyName()}...`)

368

await generator.init()

369

}

370

371

// Set binary paths for all generators

372

const binaryPaths = {

373

queryEngine: '/path/to/query-engine',

374

schemaEngine: '/path/to/schema-engine'

375

}

376

377

generators.forEach(gen => {

378

gen.setBinaryPaths(binaryPaths)

379

})

380

381

// Generate with each generator

382

for (const generator of generators) {

383

const startTime = Date.now()

384

385

console.log(`Generating ${generator.getPrettyName()}...`)

386

await generator.generate()

387

388

const duration = Date.now() - startTime

389

console.log(`✓ Generated ${generator.getPrettyName()} (${duration}ms)`)

390

}

391

392

console.log('All generators completed successfully')

393

394

} catch (error) {

395

console.error('Generation failed:', error)

396

throw error

397

} finally {

398

// Always cleanup generators

399

if (generators) {

400

generators.forEach(gen => {

401

try {

402

gen.stop()

403

} catch (stopError) {

404

console.warn(`Failed to stop generator: ${stopError.message}`)

405

}

406

})

407

}

408

}

409

}

410

```

411

412

### Custom In-Process Generator

413

414

```typescript

415

import { InProcessGenerator, type IGenerator, type GeneratorManifest } from '@prisma/internals'

416

417

// Define custom generator

418

const customGenerator: IGenerator = {

419

async onManifest(config): Promise<GeneratorManifest> {

420

return {

421

prettyName: 'Custom TypeScript Generator',

422

defaultOutput: './generated/custom',

423

version: '1.0.0',

424

requiresEngines: ['queryEngine']

425

}

426

},

427

428

async onGenerate(options) {

429

console.log('Generating custom TypeScript files...')

430

431

// Access DMMF for model information

432

const models = options.dmmf.datamodel.models

433

434

for (const model of models) {

435

// Generate custom TypeScript interfaces

436

const interfaceCode = generateInterface(model)

437

438

// Write to output directory

439

const outputPath = path.join(options.generator.output!, `${model.name}.ts`)

440

await fs.writeFile(outputPath, interfaceCode)

441

}

442

443

console.log(`Generated files for ${models.length} models`)

444

}

445

}

446

447

// Create generator config

448

const config: GeneratorConfig = {

449

name: 'custom',

450

provider: 'custom-ts-generator',

451

output: './generated/custom',

452

config: {},

453

binaryTargets: ['native']

454

}

455

456

// Create and use generator

457

const generator = new InProcessGenerator(config, customGenerator)

458

459

await generator.init()

460

await generator.generate()

461

generator.stop()

462

```

463

464

### Generator Registry Management

465

466

```typescript

467

import {

468

getGenerators,

469

type GeneratorRegistry,

470

type GeneratorRegistryEntry

471

} from '@prisma/internals'

472

473

// Create custom registry

474

const customRegistry: GeneratorRegistry = {

475

// Built-in Prisma generators

476

'prisma-client-js': {

477

type: 'rpc',

478

generatorPath: require.resolve('@prisma/client/generator-build/index.js'),

479

isNode: true

480

},

481

482

// Custom external generator

483

'custom-external': {

484

type: 'rpc',

485

generatorPath: './custom-generators/external-gen',

486

isNode: false

487

},

488

489

// Custom in-process generator

490

'custom-internal': {

491

type: 'in-process',

492

generator: customGenerator

493

}

494

}

495

496

// Use generators with custom registry

497

async function runWithCustomRegistry() {

498

const generators = await getGenerators({

499

schemaContent: `

500

generator client {

501

provider = "prisma-client-js"

502

output = "./generated/client"

503

}

504

505

generator custom {

506

provider = "custom-internal"

507

output = "./generated/custom"

508

}

509

`,

510

generatorRegistry: customRegistry,

511

cwd: process.cwd()

512

})

513

514

// Process generators

515

for (const gen of generators) {

516

console.log(`Processing: ${gen.getProvider()}`)

517

await gen.init()

518

await gen.generate()

519

}

520

521

// Cleanup

522

generators.forEach(gen => gen.stop())

523

}

524

```

525

526

### Binary Target Management

527

528

```typescript

529

import {

530

fixBinaryTargets,

531

getBinaryTargetForCurrentPlatform,

532

type BinaryTargetsEnvValue

533

} from '@prisma/internals'

534

535

function manageBinaryTargets(generatorConfig: GeneratorConfig) {

536

// Get current platform

537

const currentPlatform = getBinaryTargetForCurrentPlatform()

538

console.log('Current platform:', currentPlatform)

539

540

// Convert string array to BinaryTargetsEnvValue format

541

const schemaBinaryTargets: BinaryTargetsEnvValue[] =

542

generatorConfig.binaryTargets.map(target => ({

543

fromEnvVar: null,

544

value: target

545

}))

546

547

// Fix binary targets to ensure current platform is included

548

const fixedTargets = fixBinaryTargets(schemaBinaryTargets, currentPlatform)

549

550

// Update generator config

551

const updatedConfig: GeneratorConfig = {

552

...generatorConfig,

553

binaryTargets: fixedTargets.map(t => t.value)

554

}

555

556

console.log('Original targets:', generatorConfig.binaryTargets)

557

console.log('Fixed targets:', updatedConfig.binaryTargets)

558

559

return updatedConfig

560

}

561

```