Skip to content

Commit a60ae2a

Browse files
genuymc9
andauthored
fix: improve support for new prisma-client generator (#2171)
Co-authored-by: ymc9 <[email protected]>
1 parent 0c1b4e3 commit a60ae2a

File tree

2 files changed

+80
-7
lines changed

2 files changed

+80
-7
lines changed

packages/schema/src/plugins/enhancer/enhance/index.ts

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,13 @@ export class EnhancerGenerator {
121121
}
122122

123123
// reexport PrismaClient types (original or fixed)
124-
const modelsTs = this.project.createSourceFile(
125-
path.join(this.outDir, 'models.ts'),
126-
`export * from '${resultPrismaTypeImport}';`,
127-
{ overwrite: true }
128-
);
124+
const modelsTsContent = `export * from '${resultPrismaTypeImport}';${
125+
this.isNewPrismaClientGenerator ? "\nexport * from './json-types';" : ''
126+
}`;
127+
128+
const modelsTs = this.project.createSourceFile(path.join(this.outDir, 'models.ts'), modelsTsContent, {
129+
overwrite: true,
130+
});
129131
this.saveSourceFile(modelsTs);
130132

131133
const authDecl = getAuthDecl(getDataModelAndTypeDefs(this.model));
@@ -241,7 +243,7 @@ export function enhance<DbClient extends object>(prisma: DbClient, context?: Enh
241243
private createLogicalPrismaImports(prismaImport: string, prismaClientImport: string, target: string) {
242244
const prismaTargetImport = target === 'edge' ? `${prismaImport}/edge` : prismaImport;
243245
return `import { Prisma as _Prisma, PrismaClient as _PrismaClient } from '${prismaTargetImport}';
244-
import type { InternalArgs, DynamicClientExtensionThis } from '${prismaImport}/runtime/library';
246+
import type { InternalArgs, DynamicClientExtensionThis } from '@prisma/client/runtime/library';
245247
import type * as _P from '${prismaClientImport}';
246248
import type { Prisma, PrismaClient } from '${prismaClientImport}';
247249
export type { PrismaClient };
@@ -490,6 +492,14 @@ export type Enhanced<Client> =
490492
private async processClientTypesNewPrismaGenerator(prismaClientDir: string, delegateInfo: DelegateInfo) {
491493
const project = new Project();
492494

495+
// Create a shared file for all JSON fields type definitions
496+
const jsonFieldsFile = project.createSourceFile(path.join(this.outDir, 'json-types.ts'), undefined, {
497+
overwrite: true,
498+
});
499+
500+
this.generateExtraTypes(jsonFieldsFile);
501+
await saveSourceFile(jsonFieldsFile);
502+
493503
for (const d of this.model.declarations.filter(isDataModel)) {
494504
const fileName = `${prismaClientDir}/models/${d.name}.ts`;
495505
const sf = project.addSourceFileAtPath(fileName);
@@ -502,6 +512,23 @@ export type Enhanced<Client> =
502512
throw new PluginError(name, `Unexpected syntax list structure in ${fileName}`);
503513
}
504514

515+
sfNew.addStatements('import $Types = runtime.Types;');
516+
517+
// Add import for json-types if this model has JSON type fields
518+
const modelWithJsonFields = this.modelsWithJsonTypeFields.find((m) => m.name === d.name);
519+
if (modelWithJsonFields) {
520+
// Get the specific types that are used in this model
521+
const getTypedJsonFields = (model: DataModel) => {
522+
return model.fields.filter((f) => isTypeDef(f.type.reference?.ref));
523+
};
524+
const jsonFieldTypes = getTypedJsonFields(modelWithJsonFields);
525+
const typeNames = [...new Set(jsonFieldTypes.map((field) => field.type.reference!.$refText))];
526+
527+
if (typeNames.length > 0) {
528+
sfNew.addStatements(`import type { ${typeNames.join(', ')} } from "../../json-types";`);
529+
}
530+
}
531+
505532
syntaxList.getChildren().forEach((node) => {
506533
if (Node.isInterfaceDeclaration(node)) {
507534
sfNew.addInterface(this.transformInterface(node, delegateInfo));
@@ -913,7 +940,7 @@ export type Enhanced<Client> =
913940
return source;
914941
}
915942

916-
private async generateExtraTypes(sf: SourceFile) {
943+
private generateExtraTypes(sf: SourceFile) {
917944
for (const decl of this.model.declarations) {
918945
if (isTypeDef(decl)) {
919946
generateTypeDefType(sf, decl);
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { loadSchema } from '@zenstackhq/testtools';
2+
3+
describe('issue 2168', () => {
4+
it('regression', async () => {
5+
await loadSchema(
6+
`
7+
datasource db {
8+
provider = "sqlite"
9+
url = "file:./test.db"
10+
11+
}
12+
13+
generator client {
14+
provider = "prisma-client"
15+
output = "../generated/prisma"
16+
moduleFormat = "cjs"
17+
}
18+
19+
model User {
20+
id Int @id
21+
profile Profile @json
22+
}
23+
24+
type Profile {
25+
age Int
26+
}
27+
`,
28+
{
29+
compile: true,
30+
addPrelude: false,
31+
output: './generated/zenstack',
32+
prismaLoadPath: './generated/prisma/client',
33+
extraSourceFiles: [
34+
{
35+
name: 'main.ts',
36+
content: `
37+
import type { Profile } from './generated/zenstack/models';
38+
const profile: Profile = { age: 18 };
39+
console.log(profile);
40+
`,
41+
},
42+
],
43+
}
44+
);
45+
});
46+
});

0 commit comments

Comments
 (0)