Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support multiple levels inheritance #863

Merged
merged 1 commit into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions packages/schema/src/language-server/zmodel-scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,22 +73,31 @@ export class ZModelScopeComputation extends DefaultScopeComputation {
if (decl.$type === 'DataModel') {
const dataModel = decl as DataModel;
dataModel.$resolvedFields = [...dataModel.fields];
dataModel.superTypes.forEach((superType) => {
const superTypeDecl = superType.ref;
if (superTypeDecl) {
superTypeDecl.fields.forEach((field) => {
const cloneField = Object.assign({}, field);
cloneField.$isInherited = true;
const mutable = cloneField as Mutable<AstNode>;
// update container
mutable.$container = dataModel;
dataModel.$resolvedFields.push(cloneField);
});
}
this.getRecursiveSuperTypes(dataModel).forEach((superType) => {
superType.fields.forEach((field) => {
const cloneField = Object.assign({}, field);
cloneField.$isInherited = true;
const mutable = cloneField as Mutable<AstNode>;
// update container
mutable.$container = dataModel;
dataModel.$resolvedFields.push(cloneField);
});
});
}
});
}

private getRecursiveSuperTypes(dataModel: DataModel): DataModel[] {
const result: DataModel[] = [];
dataModel.superTypes.forEach((superType) => {
const superTypeDecl = superType.ref;
if (superTypeDecl) {
result.push(superTypeDecl);
result.push(...this.getRecursiveSuperTypes(superTypeDecl));
}
});
return result;
}
}

export class ZModelScopeProvider extends DefaultScopeProvider {
Expand Down
40 changes: 40 additions & 0 deletions packages/schema/tests/generator/prisma-generator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,46 @@ describe('Prisma generator test', () => {
expect(todo?.documentation?.replace(/\s/g, '')).toBe(`@@allow('read', owner == auth())`.replace(/\s/g, ''));
});

it('multiple level inheritance', async () => {
const model = await loadModel(`
datasource db {
provider = 'postgresql'
url = env('URL')
}

abstract model Base {
id String @id @default(cuid())

createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}

abstract model BaseDeletable extends Base {
deleted Boolean @default(false) @omit

@@deny('read', deleted)
}

model Test1 extends BaseDeletable {
@@allow('all', true)
}
`);

const { name } = tmp.fileSync({ postfix: '.prisma' });
await new PrismaSchemaGenerator().generate(model, {
name: 'Prisma',
provider: '@core/prisma',
schemaPath: 'schema.zmodel',
output: name,
format: true,
});

const content = fs.readFileSync(name, 'utf-8');
const expected = fs.readFileSync(path.join(__dirname, './prisma/multi-level-inheritance.prisma'), 'utf-8');

expect(content).toBe(expected);
});

it('format prisma', async () => {
const model = await loadModel(`
datasource db {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//////////////////////////////////////////////////////////////////////////////////////////////
// DO NOT MODIFY THIS FILE //
// This file is automatically generated by ZenStack CLI and should not be manually updated. //
//////////////////////////////////////////////////////////////////////////////////////////////

datasource db {
provider = "postgresql"
url = env("URL")
}

/// @@deny('read', deleted)
/// @@allow('all', true)
model Test1 {
id String @id() @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt()
/// @omit
deleted Boolean @default(false)
}
33 changes: 33 additions & 0 deletions packages/schema/tests/schema/abstract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,37 @@ describe('Abstract Schema Tests', () => {
model Foo extends Base {}
`);
});

it('multiple level inheritance', async () => {
await loadModel(`
datasource db {
provider = 'postgresql'
url = env('DATABASE_URL')
}

generator js {
provider = 'prisma-client-js'
}

abstract model Base1 {
id String @id @default(cuid())
}

abstract model Base2 extends Base1 {
fieldA String
}

model A extends Base2 {
field String
b B[]
}

model B {
id String @id @default(cuid())
a A @relation(fields: [aId], references: [id])
aId String
}

`);
});
});
Loading