Skip to content

Commit 5db6910

Browse files
authored
fix(zod): delegate aux fields appearing in WhereUniqueInput schemas (#2029)
Fixes #2028
1 parent 5194ebe commit 5db6910

File tree

3 files changed

+120
-4
lines changed

3 files changed

+120
-4
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -565,10 +565,10 @@ export type Enhanced<Client> =
565565
const structure = iface.getStructure();
566566

567567
// filter out aux fields
568-
structure.properties = structure.properties?.filter((p) => !p.name.startsWith(DELEGATE_AUX_RELATION_PREFIX));
568+
structure.properties = structure.properties?.filter((p) => !p.name.includes(DELEGATE_AUX_RELATION_PREFIX));
569569

570570
// filter out aux methods
571-
structure.methods = structure.methods?.filter((m) => !m.name.startsWith(DELEGATE_AUX_RELATION_PREFIX));
571+
structure.methods = structure.methods?.filter((m) => !m.name.includes(DELEGATE_AUX_RELATION_PREFIX));
572572

573573
if (delegateInfo.some(([delegate]) => `${delegate.name}Delegate` === iface.getName())) {
574574
// delegate models cannot be created directly, remove create/createMany/upsert
@@ -850,7 +850,7 @@ export type Enhanced<Client> =
850850
private findAuxDecls(node: Node) {
851851
return node
852852
.getDescendantsOfKind(SyntaxKind.PropertySignature)
853-
.filter((n) => n.getName().startsWith(DELEGATE_AUX_RELATION_PREFIX));
853+
.filter((n) => n.getName().includes(DELEGATE_AUX_RELATION_PREFIX));
854854
}
855855

856856
private saveSourceFile(sf: SourceFile) {

packages/schema/src/plugins/zod/generator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ export class ZodSchemaGenerator {
244244
const moduleNames: string[] = [];
245245
for (let i = 0; i < inputObjectTypes.length; i += 1) {
246246
// exclude delegate aux fields
247-
const fields = inputObjectTypes[i]?.fields?.filter((f) => !f.name.startsWith(DELEGATE_AUX_RELATION_PREFIX));
247+
const fields = inputObjectTypes[i]?.fields?.filter((f) => !f.name.includes(DELEGATE_AUX_RELATION_PREFIX));
248248
const name = inputObjectTypes[i]?.name;
249249

250250
if (!generateUnchecked && name.includes('Unchecked')) {
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import { createPostgresDb, loadSchema } from '@zenstackhq/testtools';
2+
3+
describe('issue 2028', () => {
4+
it('regression', async () => {
5+
const dbUrl = await createPostgresDb('issue-2028');
6+
const { enhance, zodSchemas } = await loadSchema(
7+
`
8+
enum FooType {
9+
Bar
10+
Baz
11+
}
12+
13+
model User {
14+
id String @id @default(cuid())
15+
userFolders UserFolder[]
16+
@@allow('all', true)
17+
}
18+
19+
model Foo {
20+
id String @id @default(cuid())
21+
type FooType
22+
23+
userFolders UserFolder[]
24+
25+
@@delegate(type)
26+
@@allow('all', true)
27+
}
28+
29+
model Bar extends Foo {
30+
name String
31+
}
32+
33+
model Baz extends Foo {
34+
age Int
35+
}
36+
37+
model UserFolder {
38+
id String @id @default(cuid())
39+
userId String
40+
fooId String
41+
42+
user User @relation(fields: [userId], references: [id])
43+
foo Foo @relation(fields: [fooId], references: [id])
44+
45+
@@unique([userId, fooId])
46+
@@allow('all', true)
47+
}
48+
`,
49+
{
50+
fullZod: true,
51+
provider: 'postgresql',
52+
dbUrl,
53+
}
54+
);
55+
// Ensure Zod Schemas don't include the delegate fields
56+
expect(
57+
zodSchemas.objects.UserFolderWhereUniqueInputObjectSchema.safeParse({
58+
userId_delegate_aux_UserFolder_fooId_Bar: {
59+
userId: '1',
60+
fooId: '2',
61+
},
62+
}).success
63+
).toBeFalsy();
64+
65+
expect(
66+
zodSchemas.objects.UserFolderWhereUniqueInputObjectSchema.safeParse({
67+
userId_delegate_aux_UserFolder_fooId_Baz: {
68+
userId: '1',
69+
fooId: '2',
70+
},
71+
}).success
72+
).toBeFalsy();
73+
74+
// Ensure we can query by the CompoundUniqueInput
75+
const db = enhance();
76+
const user = await db.user.create({ data: {} });
77+
const bar = await db.bar.create({ data: { name: 'bar' } });
78+
const baz = await db.baz.create({ data: { age: 1 } });
79+
80+
const userFolderA = await db.userFolder.create({
81+
data: {
82+
userId: user.id,
83+
fooId: bar.id,
84+
},
85+
});
86+
87+
const userFolderB = await db.userFolder.create({
88+
data: {
89+
userId: user.id,
90+
fooId: baz.id,
91+
},
92+
});
93+
94+
await expect(
95+
db.userFolder.findUnique({
96+
where: {
97+
userId_fooId: {
98+
userId: user.id,
99+
fooId: bar.id,
100+
},
101+
},
102+
})
103+
).resolves.toMatchObject(userFolderA);
104+
105+
await expect(
106+
db.userFolder.findUnique({
107+
where: {
108+
userId_fooId: {
109+
userId: user.id,
110+
fooId: baz.id,
111+
},
112+
},
113+
})
114+
).resolves.toMatchObject(userFolderB);
115+
});
116+
});

0 commit comments

Comments
 (0)