@@ -29,27 +29,58 @@ THE SOFTWARE.
2929// deno-fmt-ignore-file
3030
3131import { Guard } from '../../guard/index.ts'
32- import { type TIntersect , type TProperties } from '../../type/index.ts'
32+ import { type TIntersect , type TProperties , type TSchema , IsObject } from '../../type/index.ts'
3333import { FromType } from './from-type.ts'
3434import { Callback } from './callback.ts'
3535
36+ // ------------------------------------------------------------------
37+ // ProcessIntersectSchemas
38+ // ------------------------------------------------------------------
39+ // Processes intersection schemas while tracking which properties have been
40+ // handled to prevent duplicate codec execution. When the same property appears
41+ // in multiple schemas within an intersection, only the first occurrence is
42+ // processed to avoid running codecs multiple times.
43+ function ProcessIntersectSchemas (
44+ direction : string ,
45+ context : TProperties ,
46+ schemas : TSchema [ ] ,
47+ value : unknown
48+ ) : unknown {
49+ const processedKeys = new Set < string > ( )
50+
51+ for ( const schema of schemas ) {
52+ if ( IsObject ( schema ) ) {
53+ // For object schemas, manually process properties that haven't been seen yet
54+ if ( ! Guard . IsObjectNotArray ( value ) ) continue
55+
56+ for ( const key of Guard . Keys ( schema . properties ) ) {
57+ if ( ! processedKeys . has ( key ) && Guard . HasPropertyKey ( value , key ) ) {
58+ // Process this property through its codec
59+ value [ key ] = FromType ( direction , context , schema . properties [ key ] , value [ key ] )
60+ processedKeys . add ( key )
61+ }
62+ }
63+ } else {
64+ // For non-object schemas, process the entire value
65+ value = FromType ( direction , context , schema , value )
66+ }
67+ }
68+
69+ return value
70+ }
3671// ------------------------------------------------------------------
3772// Decode
3873// ------------------------------------------------------------------
3974function Decode ( direction : string , context : TProperties , type : TIntersect , value : unknown ) : unknown {
40- for ( const schema of type . allOf ) {
41- value = FromType ( direction , context , schema , value )
42- }
75+ value = ProcessIntersectSchemas ( direction , context , type . allOf , value )
4376 return Callback ( direction , context , type , value )
4477}
4578// ------------------------------------------------------------------
4679// Encode
4780// ------------------------------------------------------------------
4881function Encode ( direction : string , context : TProperties , type : TIntersect , value : unknown ) : unknown {
4982 let exterior = Callback ( direction , context , type , value )
50- for ( const schema of type . allOf ) {
51- exterior = FromType ( direction , context , schema , exterior )
52- }
83+ exterior = ProcessIntersectSchemas ( direction , context , type . allOf , exterior )
5384 return exterior
5485}
5586export function FromIntersect ( direction : string , context : TProperties , type : TIntersect , value : unknown ) : unknown {
0 commit comments