Skip to content

Commit 7b0071f

Browse files
committed
feat: support prisma-client generator provider
1 parent 2459eb2 commit 7b0071f

17 files changed

+205
-56
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,14 @@ pnpm add prisma-class-validator-generator
6464

6565
1. Add the generator to your Prisma schema:
6666

67+
> **Heads up:** Keep a Prisma Client generator in the same schema. Both `provider = "prisma-client"` (recommended) and `provider = "prisma-client-js"` are supported.
68+
6769
```prisma
70+
generator client {
71+
provider = "prisma-client" // or "prisma-client-js"
72+
output = "../generated/prisma-client" // required when using prisma-client
73+
}
74+
6875
generator class_validator {
6976
provider = "prisma-class-validator-generator"
7077
output = "./generated" // optional, defaults to ./generated
@@ -472,4 +479,4 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
472479
<a href="https://github.com/omar-dulaimi/prisma-class-validator-generator/issues">🐛 Report Issues</a> •
473480
<a href="https://github.com/omar-dulaimi/prisma-class-validator-generator/discussions">💬 Discussions</a>
474481
</p>
475-
</div>
482+
</div>

prisma/schema.prisma

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
generator client {
2-
provider = "prisma-client-js"
2+
provider = "prisma-client"
3+
output = "../generated/prisma-client"
34
}
45

56
generator class_validator {

src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ generatorHandler({
55
onManifest: () => ({
66
defaultOutput: './generated',
77
prettyName: 'Prisma Class Validator Generator',
8-
requiresGenerators: ['prisma-client-js'],
98
}),
109
onGenerate: generate,
1110
});

src/prisma-generator.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ export interface GeneratorConfig {
1515
separateRelationFields: boolean;
1616
}
1717

18+
const SUPPORTED_PRISMA_CLIENT_PROVIDERS = new Set([
19+
'prisma-client',
20+
'prisma-client-js',
21+
]);
22+
1823
export async function generate(options: GeneratorOptions) {
1924
const outputDir = parseEnvValue(options.generator.output as EnvValue);
2025

@@ -27,10 +32,16 @@ export async function generate(options: GeneratorOptions) {
2732
await fs.mkdir(outputDir, { recursive: true });
2833
await removeDir(outputDir, true);
2934

30-
const prismaClientProvider = options.otherGenerators.find(
31-
(it) => parseEnvValue(it.provider) === 'prisma-client-js',
35+
const prismaClientProvider = options.otherGenerators.find((it) =>
36+
SUPPORTED_PRISMA_CLIENT_PROVIDERS.has(parseEnvValue(it.provider)),
3237
);
3338

39+
if (!prismaClientProvider) {
40+
throw new Error(
41+
'Prisma Class Validator Generator requires a Prisma Client generator with provider "prisma-client" or "prisma-client-js".',
42+
);
43+
}
44+
3445
const prismaClientDmmf = await getDMMF({
3546
datamodel: options.datamodel,
3647
previewFeatures: prismaClientProvider?.previewFeatures || [],

tests/basic-generation.test.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
1-
import { exec } from 'child_process';
2-
import { promisify } from 'util';
31
import { existsSync, readFileSync } from 'fs';
42
import { describe, it, expect, beforeAll } from 'vitest';
53
import path from 'path';
6-
7-
const execAsync = promisify(exec);
4+
import {
5+
ensureGeneratorBuilt,
6+
runPrismaGenerate,
7+
} from './utils/prisma-test-helpers';
88

99
describe('Basic Class Validator Generation', () => {
1010
beforeAll(async () => {
11-
// Build the generator first
12-
await execAsync('npm run build');
11+
await ensureGeneratorBuilt();
1312
}, 60000);
1413

1514
it('should generate basic models with class validators', async () => {
1615
const schemaPath = path.resolve(__dirname, 'schemas/basic.prisma');
1716
const outputPath = path.resolve(__dirname, 'generated/basic');
1817

19-
// Generate using the basic schema
20-
await execAsync(`npx prisma generate --schema="${schemaPath}"`);
18+
await runPrismaGenerate({ schemaPath });
2119

2220
// Check if generated files exist
2321
expect(existsSync(path.join(outputPath, 'models', 'User.model.ts'))).toBe(

tests/comprehensive-schema.test.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
1-
import { exec } from 'child_process';
2-
import { promisify } from 'util';
31
import { existsSync, readFileSync } from 'fs';
42
import { describe, it, expect, beforeAll } from 'vitest';
53
import path from 'path';
6-
7-
const execAsync = promisify(exec);
4+
import {
5+
ensureGeneratorBuilt,
6+
runPrismaGenerate,
7+
} from './utils/prisma-test-helpers';
88

99
describe('Comprehensive Schema Generation', () => {
1010
beforeAll(async () => {
11-
// Build the generator first
12-
await execAsync('npm run build');
11+
await ensureGeneratorBuilt();
1312
}, 60000);
1413

1514
it('should generate comprehensive models with enums and relations', async () => {
1615
const schemaPath = path.resolve(__dirname, 'schemas/comprehensive.prisma');
1716
const outputPath = path.resolve(__dirname, 'generated/comprehensive');
1817

19-
// Generate using the comprehensive schema
20-
await execAsync(`npx prisma generate --schema="${schemaPath}"`);
18+
await runPrismaGenerate({ schemaPath });
2119

2220
// Check if generated files exist
2321
expect(existsSync(path.join(outputPath, 'models', 'User.model.ts'))).toBe(
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { existsSync } from 'fs';
2+
import { describe, it, expect, beforeAll } from 'vitest';
3+
import path from 'path';
4+
import {
5+
ensureGeneratorBuilt,
6+
runPrismaGenerate,
7+
} from './utils/prisma-test-helpers';
8+
9+
const schemaPath = path.resolve(
10+
__dirname,
11+
'schemas/prisma-client-js-provider.prisma',
12+
);
13+
const classValidatorOutput = path.resolve(
14+
__dirname,
15+
'generated/providers/prisma-client-js-class-validator',
16+
);
17+
18+
19+
describe('Prisma Client JS generator provider', () => {
20+
beforeAll(async () => {
21+
await ensureGeneratorBuilt();
22+
}, 60000);
23+
24+
it('generates artifacts when using provider = "prisma-client-js"', async () => {
25+
await runPrismaGenerate({ schemaPath });
26+
27+
expect(
28+
existsSync(path.join(classValidatorOutput, 'models', 'User.model.ts')),
29+
).toBe(true);
30+
expect(
31+
existsSync(path.join(classValidatorOutput, 'helpers', 'index.ts')),
32+
).toBe(true);
33+
});
34+
});
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { existsSync } from 'fs';
2+
import { describe, it, expect, beforeAll } from 'vitest';
3+
import path from 'path';
4+
import {
5+
ensureGeneratorBuilt,
6+
runPrismaGenerate,
7+
} from './utils/prisma-test-helpers';
8+
9+
const schemaPath = path.resolve(
10+
__dirname,
11+
'schemas/prisma-client-provider.prisma',
12+
);
13+
const classValidatorOutput = path.resolve(
14+
__dirname,
15+
'generated/providers/prisma-client-class-validator',
16+
);
17+
const prismaClientOutput = path.resolve(
18+
__dirname,
19+
'generated/providers/prisma-client',
20+
);
21+
22+
describe('Prisma Client generator provider', () => {
23+
beforeAll(async () => {
24+
await ensureGeneratorBuilt();
25+
}, 60000);
26+
27+
it('generates artifacts when using provider = "prisma-client"', async () => {
28+
await runPrismaGenerate({ schemaPath });
29+
30+
expect(
31+
existsSync(path.join(classValidatorOutput, 'models', 'User.model.ts')),
32+
).toBe(true);
33+
expect(
34+
existsSync(path.join(classValidatorOutput, 'helpers', 'index.ts')),
35+
).toBe(true);
36+
expect(existsSync(prismaClientOutput)).toBe(true);
37+
});
38+
});

tests/relation-splitting.test.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
1-
import { exec } from 'child_process';
2-
import { promisify } from 'util';
31
import { existsSync, readFileSync } from 'fs';
42
import { describe, it, expect, beforeAll } from 'vitest';
53
import path from 'path';
6-
7-
const execAsync = promisify(exec);
4+
import {
5+
ensureGeneratorBuilt,
6+
runPrismaGenerate,
7+
} from './utils/prisma-test-helpers';
88

99
describe('Relation Splitting Generation', () => {
1010
beforeAll(async () => {
11-
// Build the generator first
12-
await execAsync('npm run build');
13-
14-
// Generate models for full-features schema
11+
await ensureGeneratorBuilt();
1512
const schemaPath = path.resolve(__dirname, 'schemas/full-features.prisma');
16-
await execAsync(`npx prisma generate --schema="${schemaPath}"`);
13+
await runPrismaGenerate({ schemaPath });
1714
}, 60000);
1815

1916
it('should generate separate base and relation classes', () => {

tests/schemas/basic.prisma

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
generator client {
2-
provider = "prisma-client-js"
2+
provider = "prisma-client"
3+
output = "../generated/basic-client"
34
}
45

56
generator class_validator {
@@ -30,4 +31,4 @@ model Post {
3031
author User? @relation(fields: [authorId], references: [id])
3132
authorId Int?
3233
rating Float
33-
}
34+
}

0 commit comments

Comments
 (0)