@@ -189,6 +189,12 @@ function KeyPath(fieldOrOptions?: string | KeyPathOptions, options?: KeyPathOpti
189189 if ( arguments . length === 0 ) {
190190 return ( target : any , propertyKey : string | symbol ) => {
191191 const constructor = target . constructor as Function ;
192+
193+ // Get existing individual keypaths or create new array
194+ const existingKeypaths = Reflect . getMetadata ( "individual_keypaths" , constructor ) || [ ] ;
195+ existingKeypaths . push ( propertyKey as string ) ;
196+ Reflect . defineMetadata ( "individual_keypaths" , existingKeypaths , constructor ) ;
197+
192198 const metadata : KeyPathMetadata = {
193199 fields : propertyKey as string ,
194200 options : undefined
@@ -202,6 +208,14 @@ function KeyPath(fieldOrOptions?: string | KeyPathOptions, options?: KeyPathOpti
202208 return ( target : any , propertyKey ?: string | symbol ) => {
203209 const constructor = target . constructor as Function ;
204210 const field = propertyKey ? propertyKey as string : fieldOrOptions ;
211+
212+ // Track individual property keypaths for validation only if it's a property decorator
213+ if ( propertyKey ) {
214+ const existingKeypaths = Reflect . getMetadata ( "individual_keypaths" , constructor ) || [ ] ;
215+ existingKeypaths . push ( propertyKey as string ) ;
216+ Reflect . defineMetadata ( "individual_keypaths" , existingKeypaths , constructor ) ;
217+ }
218+
205219 const metadata : KeyPathMetadata = {
206220 fields : field ,
207221 options : options
@@ -214,6 +228,12 @@ function KeyPath(fieldOrOptions?: string | KeyPathOptions, options?: KeyPathOpti
214228 if ( typeof fieldOrOptions === 'object' && ! Array . isArray ( fieldOrOptions ) ) {
215229 return ( target : any , propertyKey : string | symbol ) => {
216230 const constructor = target . constructor as Function ;
231+
232+ // Get existing individual keypaths or create new array
233+ const existingKeypaths = Reflect . getMetadata ( "individual_keypaths" , constructor ) || [ ] ;
234+ existingKeypaths . push ( propertyKey as string ) ;
235+ Reflect . defineMetadata ( "individual_keypaths" , existingKeypaths , constructor ) ;
236+
217237 const metadata : KeyPathMetadata = {
218238 fields : propertyKey as string ,
219239 options : fieldOrOptions
@@ -254,6 +274,14 @@ function DataClass(options: DataClassOptions = {}): ClassDecorator {
254274 if ( ! keyPathMetadata ) {
255275 throw new Error ( `No keypath field defined for the class ${ target . name } .` ) ;
256276 }
277+
278+ // Check for multiple property-level @KeyPath decorators (which is invalid)
279+ // This is different from composite keys which are defined at class level
280+ const individualKeypaths = Reflect . getMetadata ( "individual_keypaths" , target ) || [ ] ;
281+ if ( individualKeypaths . length > 1 ) {
282+ throw new Error ( `Only one keypath field can be defined for the class ${ target . name } .` ) ;
283+ }
284+
257285 const version = options . version || 1 ;
258286 Reflect . defineMetadata ( "dataclass" , true , target ) ;
259287 Reflect . defineMetadata ( "version" , version , target ) ;
0 commit comments