Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 3 additions & 4 deletions packages/runtime/src/client/crud-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -631,16 +631,15 @@ export type FindArgs<
skip?: number;
take?: number;
orderBy?: OrArray<OrderBy<Schema, Model, true, false>>;
}
} & Distinct<Schema, Model> &
Cursor<Schema, Model>
: {}) &
(AllowFilter extends true
? {
where?: WhereInput<Schema, Model>;
}
: {}) &
SelectIncludeOmit<Schema, Model, Collection> &
Distinct<Schema, Model> &
Cursor<Schema, Model>;
SelectIncludeOmit<Schema, Model, Collection>;

export type FindManyArgs<Schema extends SchemaDef, Model extends GetModels<Schema>> = FindArgs<Schema, Model, true>;
export type FindFirstArgs<Schema extends SchemaDef, Model extends GetModels<Schema>> = FindArgs<Schema, Model, false>;
Expand Down
19 changes: 19 additions & 0 deletions packages/runtime/src/client/crud/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -593,8 +593,27 @@ export class InputValidator<Schema extends SchemaDef> {
.union([
z.literal(true),
z.strictObject({
...(fieldDef.array || fieldDef.optional
? {
// to-many relations and optional to-one relations are filterable
where: z.lazy(() => this.makeWhereSchema(fieldDef.type, false)).optional(),
}
: {}),
select: z.lazy(() => this.makeSelectSchema(fieldDef.type)).optional(),
include: z.lazy(() => this.makeIncludeSchema(fieldDef.type)).optional(),
omit: z.lazy(() => this.makeOmitSchema(fieldDef.type)).optional(),
...(fieldDef.array
? {
// to-many relations can be ordered, skipped, taken, and cursor-located
orderBy: z
.lazy(() => this.makeOrderBySchema(fieldDef.type, true, false))
.optional(),
skip: this.makeSkipSchema().optional(),
take: this.makeTakeSchema().optional(),
cursor: this.makeCursorSchema(fieldDef.type).optional(),
distinct: this.makeDistinctSchema(fieldDef.type).optional(),
}
: {}),
}),
])
.optional();
Expand Down
48 changes: 48 additions & 0 deletions packages/runtime/test/client-api/find.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,54 @@ describe.each(createClientSpecs(PG_DB_NAME))('Client find tests for $provider',
expect(r?.posts[0]?.createdAt).toBeInstanceOf(Date);
expect(r?.posts[0]?.published).toBeTypeOf('boolean');

await expect(
client.user.findUnique({
where: { id: user.id },
select: {
posts: { where: { published: true }, select: { title: true }, orderBy: { createdAt: 'desc' } },
},
}),
).resolves.toMatchObject({
posts: [expect.objectContaining({ title: 'Post1' })],
});

await expect(
client.user.findUnique({
where: { id: user.id },
select: {
posts: { orderBy: { title: 'asc' }, skip: 1, take: 1, distinct: ['title'] },
},
}),
).resolves.toMatchObject({
posts: [expect.objectContaining({ title: 'Post2' })],
});

await expect(
client.post.findFirst({
select: { author: { select: { email: true } } },
}),
).resolves.toMatchObject({
author: { email: expect.any(String) },
});

await expect(
client.user.findUnique({
where: { id: user.id },
include: {
profile: { where: { bio: 'My bio' } },
},
}),
).resolves.toMatchObject({ profile: expect.any(Object) });

await expect(
client.user.findUnique({
where: { id: user.id },
include: {
profile: { where: { bio: 'Other bio' } },
},
}),
).resolves.toMatchObject({ profile: null });

await expect(
client.user.findUnique({
where: { id: user.id },
Expand Down