Skip to content

Commit 7b44731

Browse files
committed
fix: relation selection input validation issue
1 parent 1ac89c1 commit 7b44731

File tree

3 files changed

+70
-4
lines changed

3 files changed

+70
-4
lines changed

packages/runtime/src/client/crud-types.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -631,16 +631,15 @@ export type FindArgs<
631631
skip?: number;
632632
take?: number;
633633
orderBy?: OrArray<OrderBy<Schema, Model, true, false>>;
634-
}
634+
} & Distinct<Schema, Model> &
635+
Cursor<Schema, Model>
635636
: {}) &
636637
(AllowFilter extends true
637638
? {
638639
where?: WhereInput<Schema, Model>;
639640
}
640641
: {}) &
641-
SelectIncludeOmit<Schema, Model, Collection> &
642-
Distinct<Schema, Model> &
643-
Cursor<Schema, Model>;
642+
SelectIncludeOmit<Schema, Model, Collection>;
644643

645644
export type FindManyArgs<Schema extends SchemaDef, Model extends GetModels<Schema>> = FindArgs<Schema, Model, true>;
646645
export type FindFirstArgs<Schema extends SchemaDef, Model extends GetModels<Schema>> = FindArgs<Schema, Model, false>;

packages/runtime/src/client/crud/validator.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,8 +593,27 @@ export class InputValidator<Schema extends SchemaDef> {
593593
.union([
594594
z.literal(true),
595595
z.strictObject({
596+
...(fieldDef.array || fieldDef.optional
597+
? {
598+
// to-many relations and optional to-one relations are filterable
599+
where: z.lazy(() => this.makeWhereSchema(fieldDef.type, false)).optional(),
600+
}
601+
: {}),
596602
select: z.lazy(() => this.makeSelectSchema(fieldDef.type)).optional(),
597603
include: z.lazy(() => this.makeIncludeSchema(fieldDef.type)).optional(),
604+
omit: z.lazy(() => this.makeOmitSchema(fieldDef.type)).optional(),
605+
...(fieldDef.array
606+
? {
607+
// to-many relations can be ordered, skipped, taken, and cursor-located
608+
orderBy: z
609+
.lazy(() => this.makeOrderBySchema(fieldDef.type, true, false))
610+
.optional(),
611+
skip: this.makeSkipSchema().optional(),
612+
take: this.makeTakeSchema().optional(),
613+
cursor: this.makeCursorSchema(fieldDef.type).optional(),
614+
distinct: this.makeDistinctSchema(fieldDef.type).optional(),
615+
}
616+
: {}),
598617
}),
599618
])
600619
.optional();

packages/runtime/test/client-api/find.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,54 @@ describe.each(createClientSpecs(PG_DB_NAME))('Client find tests for $provider',
637637
expect(r?.posts[0]?.createdAt).toBeInstanceOf(Date);
638638
expect(r?.posts[0]?.published).toBeTypeOf('boolean');
639639

640+
await expect(
641+
client.user.findUnique({
642+
where: { id: user.id },
643+
select: {
644+
posts: { where: { published: true }, select: { title: true }, orderBy: { createdAt: 'desc' } },
645+
},
646+
}),
647+
).resolves.toMatchObject({
648+
posts: [expect.objectContaining({ title: 'Post1' })],
649+
});
650+
651+
await expect(
652+
client.user.findUnique({
653+
where: { id: user.id },
654+
select: {
655+
posts: { orderBy: { title: 'asc' }, skip: 1, take: 1, distinct: ['title'] },
656+
},
657+
}),
658+
).resolves.toMatchObject({
659+
posts: [expect.objectContaining({ title: 'Post2' })],
660+
});
661+
662+
await expect(
663+
client.post.findFirst({
664+
select: { author: { select: { email: true } } },
665+
}),
666+
).resolves.toMatchObject({
667+
author: { email: expect.any(String) },
668+
});
669+
670+
await expect(
671+
client.user.findUnique({
672+
where: { id: user.id },
673+
include: {
674+
profile: { where: { bio: 'My bio' } },
675+
},
676+
}),
677+
).resolves.toMatchObject({ profile: expect.any(Object) });
678+
679+
await expect(
680+
client.user.findUnique({
681+
where: { id: user.id },
682+
include: {
683+
profile: { where: { bio: 'Other bio' } },
684+
},
685+
}),
686+
).resolves.toMatchObject({ profile: null });
687+
640688
await expect(
641689
client.user.findUnique({
642690
where: { id: user.id },

0 commit comments

Comments
 (0)