From ec173a53f482418d9106968f36bb74ca08524a07 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Wed, 23 Oct 2024 21:15:15 -0700 Subject: [PATCH 1/2] fix(delegate): discriminator fields should be removed from unchecked create/update input types Fixes #1763 --- .../src/plugins/enhancer/enhance/index.ts | 19 ++++---- tests/regression/tests/issue-1763.test.ts | 47 +++++++++++++++++++ 2 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 tests/regression/tests/issue-1763.test.ts diff --git a/packages/schema/src/plugins/enhancer/enhance/index.ts b/packages/schema/src/plugins/enhancer/enhance/index.ts index ff2e00b6a..7f17b4c0c 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,20 @@ 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 concreteModelNames = delegateInfo.map(([_, concretes]) => concretes.flatMap((c) => c.name)); + const concreteCreateUpdateInputRegex = new RegExp( + `^(${concreteModelNames.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, + }, + }); +} `, + }, + ], + } + ); + }); +}); From 5d75fe306cb5db340de2c47dd96bf80b5026ba84 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Wed, 23 Oct 2024 21:28:59 -0700 Subject: [PATCH 2/2] update --- packages/schema/src/plugins/enhancer/enhance/index.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/schema/src/plugins/enhancer/enhance/index.ts b/packages/schema/src/plugins/enhancer/enhance/index.ts index 7f17b4c0c..34cf26640 100644 --- a/packages/schema/src/plugins/enhancer/enhance/index.ts +++ b/packages/schema/src/plugins/enhancer/enhance/index.ts @@ -542,9 +542,13 @@ export function enhance(prisma: any, context?: EnhancementContext<${authTypePara // remove discriminator field from the create/update input because discriminator cannot be set directly const typeName = typeAlias.getName(); - const concreteModelNames = delegateInfo.map(([_, concretes]) => concretes.flatMap((c) => c.name)); + 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( - `^(${concreteModelNames.join('|')})(Unchecked)?(Create|Update).*Input$` + `^(${allModelNames.join('|')})(Unchecked)?(Create|Update).*Input$` ); const match = typeName.match(concreteCreateUpdateInputRegex);