diff --git a/packages/schema/src/plugins/enhancer/enhance/index.ts b/packages/schema/src/plugins/enhancer/enhance/index.ts index ff2e00b6a..34cf26640 100644 --- a/packages/schema/src/plugins/enhancer/enhance/index.ts +++ b/packages/schema/src/plugins/enhancer/enhance/index.ts @@ -515,15 +515,11 @@ export function enhance(prisma: any, context?: EnhancementContext<${authTypePara return source; } - private removeCreateFromDelegateInput( - typeAlias: TypeAliasDeclaration, - delegateModels: DelegateInfo, - source: string - ) { + private removeCreateFromDelegateInput(typeAlias: TypeAliasDeclaration, delegateInfo: DelegateInfo, source: string) { // remove create/connectOrCreate/upsert fields from delegate's input types because // delegate models cannot be created directly const typeName = typeAlias.getName(); - const delegateModelNames = delegateModels.map(([delegate]) => delegate.name); + const delegateModelNames = delegateInfo.map(([delegate]) => delegate.name); const delegateCreateUpdateInputRegex = new RegExp( `^(${delegateModelNames.join('|')})(Unchecked)?(Create|Update).*Input$` ); @@ -538,17 +534,24 @@ export function enhance(prisma: any, context?: EnhancementContext<${authTypePara return source; } - private readonly ModelCreateUpdateInputRegex = /(\S+)(Unchecked)?(Create|Update).*Input/; - private removeDiscriminatorFromConcreteInput( typeAlias: TypeAliasDeclaration, - _delegateInfo: DelegateInfo, + delegateInfo: DelegateInfo, source: string ) { // remove discriminator field from the create/update input because discriminator cannot be set directly const typeName = typeAlias.getName(); - const match = typeName.match(this.ModelCreateUpdateInputRegex); + const delegateModelNames = delegateInfo.map(([delegate]) => delegate.name); + const concreteModelNames = delegateInfo + .map(([_, concretes]) => concretes.flatMap((c) => c.name)) + .flatMap((name) => name); + const allModelNames = [...new Set([...delegateModelNames, ...concreteModelNames])]; + const concreteCreateUpdateInputRegex = new RegExp( + `^(${allModelNames.join('|')})(Unchecked)?(Create|Update).*Input$` + ); + + const match = typeName.match(concreteCreateUpdateInputRegex); if (match) { const modelName = match[1]; const dataModel = this.model.declarations.find( diff --git a/tests/regression/tests/issue-1763.test.ts b/tests/regression/tests/issue-1763.test.ts new file mode 100644 index 000000000..d5ea1d401 --- /dev/null +++ b/tests/regression/tests/issue-1763.test.ts @@ -0,0 +1,47 @@ +import { loadSchema } from '@zenstackhq/testtools'; + +describe('issue 1763', () => { + it('regression', async () => { + await loadSchema( + ` + model Post { + id Int @id @default(autoincrement()) + name String + + type String + @@delegate(type) + + // full access by author + @@allow('all', true) + } + + model ConcretePost extends Post { + age Int + } + `, + { + compile: true, + extraSourceFiles: [ + { + name: 'main.ts', + content: ` +import { PrismaClient as Prisma } from '@prisma/client'; +import { enhance } from '@zenstackhq/runtime'; + +async function test() { + const prisma = new Prisma(); + const db = enhance(prisma); + await db.concretePost.create({ + data: { + id: 5, + name: 'a name', + age: 20, + }, + }); +} `, + }, + ], + } + ); + }); +});