File tree Expand file tree Collapse file tree 2 files changed +22
-11
lines changed
packages/orm/src/client/zod Expand file tree Collapse file tree 2 files changed +22
-11
lines changed Original file line number Diff line number Diff line change @@ -1126,6 +1126,10 @@ export class ZodSchemaFactory<
11261126 ) {
11271127 const fields : Record < string , ZodType > = { } ;
11281128 const sort = z . union ( [ z . literal ( 'asc' ) , z . literal ( 'desc' ) ] ) ;
1129+ const refineAtMostOneKey = ( s : ZodObject ) =>
1130+ s . refine ( ( v : object ) => Object . keys ( v ) . length <= 1 , {
1131+ message : 'Each orderBy element must have at most one key' ,
1132+ } ) ;
11291133 const nextOpts = this . nextOptions ( options ) ;
11301134 for ( const [ field , fieldDef ] of this . getModelFields ( model ) ) {
11311135 if ( fieldDef . relation ) {
@@ -1139,9 +1143,8 @@ export class ZodSchemaFactory<
11391143 nextOpts ,
11401144 ) ;
11411145 if ( fieldDef . array ) {
1142- relationOrderBy = relationOrderBy . extend ( {
1143- _count : sort ,
1144- } ) ;
1146+ // safeExtend drops existing refinements, so re-apply after extending
1147+ relationOrderBy = refineAtMostOneKey ( relationOrderBy . safeExtend ( { _count : sort } ) ) ;
11451148 }
11461149 return relationOrderBy . optional ( ) ;
11471150 } ) ;
@@ -1172,7 +1175,7 @@ export class ZodSchemaFactory<
11721175 }
11731176 }
11741177
1175- return z . strictObject ( fields ) ;
1178+ return refineAtMostOneKey ( z . strictObject ( fields ) ) ;
11761179 }
11771180
11781181 @cache ( )
Original file line number Diff line number Diff line change @@ -126,13 +126,6 @@ describe('Client find tests ', () => {
126126 email : 'u2@test.com' ,
127127 } ) ;
128128
129- // multiple sorting conditions in one object
130- await expect (
131- client . user . findFirst ( {
132- orderBy : { role : 'asc' , email : 'desc' } ,
133- } ) ,
134- ) . resolves . toMatchObject ( { email : 'u2@test.com' } ) ;
135-
136129 // multiple sorting conditions in array
137130 await expect (
138131 client . user . findFirst ( {
@@ -1189,6 +1182,21 @@ describe('Client find tests ', () => {
11891182 expect ( result3 ?. _count . posts ) . toBe ( 1 ) ;
11901183 } ) ;
11911184
1185+ it ( 'rejects orderBy array elements with multiple keys' , async ( ) => {
1186+ await createUser ( client , 'u1@test.com' ) ;
1187+
1188+ // zero keys is valid
1189+ await expect ( client . user . findMany ( { orderBy : [ { } ] } ) ) . resolves . toBeDefined ( ) ;
1190+
1191+ // single key is valid
1192+ await expect ( client . user . findMany ( { orderBy : [ { email : 'asc' } ] } ) ) . resolves . toBeDefined ( ) ;
1193+
1194+ // multiple keys in one element is rejected
1195+ await expect (
1196+ client . user . findMany ( { orderBy : [ { email : 'asc' , role : 'desc' } ] } as any ) ,
1197+ ) . toBeRejectedByValidation ( ) ;
1198+ } ) ;
1199+
11921200 it ( 'supports $expr' , async ( ) => {
11931201 await createUser ( client , 'yiming@gmail.com' ) ;
11941202 await createUser ( client , 'yiming@zenstack.dev' ) ;
You can’t perform that action at this time.
0 commit comments