@@ -14,17 +14,35 @@ interface IBaseEntity {
1414}
1515import Ajv , { ValidateFunction , ErrorObject , AnySchema , AnySchemaObject } from 'ajv' ;
1616
17+ function resolveRef ( ref : string , definitions : Record < string , any > ) : any {
18+ const match = ref . match ( / ^ # \/ d e f i n i t i o n s \/ ( .+ ) $ / ) ;
19+ if ( ! match ) throw new Error ( `Unsupported $ref format: ${ ref } ` ) ;
20+ const key = match [ 1 ] ;
21+ const resolved = definitions [ key ] ;
22+ if ( ! resolved ) throw new Error ( `Could not resolve $ref: ${ ref } ` ) ;
23+ return resolved ;
24+ }
25+
1726function collectAndRemoveAllSchemas (
1827 schema : any ,
1928 path : string [ ] ,
2029 key : string ,
21- results : any [ ]
30+ results : any [ ] ,
31+ definitions : Record < string , any >
2232) : void {
2333 if ( ! schema || typeof schema !== 'object' ) return ;
2434
25- // Base case: found the key
35+ // 🔁 If it's a $ref, resolve it
36+ if ( typeof schema === 'object' && schema . $ref ) {
37+ schema = resolveRef ( schema . $ref , definitions ) ;
38+ }
39+
40+ // Base case: found the key in properties
2641 if ( path . length === 0 && schema . properties ?. [ key ] ) {
27- results . push ( schema . properties [ key ] ) ;
42+ let fieldSchema = schema . properties [ key ] ;
43+
44+
45+ results . push ( fieldSchema ) ;
2846 delete schema . properties [ key ] ;
2947
3048 if ( Array . isArray ( schema . required ) ) {
@@ -35,38 +53,38 @@ function collectAndRemoveAllSchemas(
3553
3654 const [ next , ...rest ] = path ;
3755
38- // Dive into nested property
56+ // Dive into nested propertiess
3957 if ( schema . properties ?. [ next ] ) {
40- collectAndRemoveAllSchemas ( schema . properties [ next ] , rest , key , results ) ;
58+ collectAndRemoveAllSchemas ( schema . properties [ next ] , rest , key , results , definitions ) ;
4159 }
4260
43- // Dive into oneOf / anyOf / allOf branches
61+ // Dive into oneOf / anyOf / allOf
4462 for ( const comb of [ 'oneOf' , 'anyOf' , 'allOf' ] ) {
4563 if ( Array . isArray ( schema [ comb ] ) ) {
4664 for ( const subSchema of schema [ comb ] ) {
47- collectAndRemoveAllSchemas ( subSchema , path , key , results ) ;
65+ collectAndRemoveAllSchemas ( subSchema , path , key , results , definitions ) ;
4866 }
4967 }
5068 }
5169}
5270
53-
5471function restructureSchemaFromFieldMap (
5572 schema : AnySchemaObject ,
5673 fieldMap : Record < string , string >
5774) : AnySchemaObject {
5875 const cloned = JSON . parse ( JSON . stringify ( schema ) ) ;
76+ const definitions = cloned . definitions || { } ;
5977 const toAdd : Record < string , any > = { } ;
6078
6179 for ( const [ aliasName , fieldPath ] of Object . entries ( fieldMap ) ) {
6280 const parts = fieldPath . split ( '.' ) ;
6381 if ( parts . length <= 1 ) continue ;
6482
65- const propKey = parts . pop ( ) ! ; // use non-null assertion
83+ const propKey = parts . pop ( ) ! ;
6684 const parentPath = parts ;
6785
6886 const collectedSchemas : any [ ] = [ ] ;
69- collectAndRemoveAllSchemas ( cloned , parentPath , propKey , collectedSchemas ) ;
87+ collectAndRemoveAllSchemas ( cloned , parentPath , propKey , collectedSchemas , definitions ) ;
7088
7189 if ( collectedSchemas . length === 1 ) {
7290 toAdd [ aliasName ] = collectedSchemas [ 0 ] ;
@@ -139,14 +157,16 @@ abstract class BaseEntity implements IBaseEntity {
139157 reverseMap [ path ] = alias ;
140158 }
141159
142- schema = restructureSchemaFromFieldMap ( rawSchema , fieldMap ) ;
160+ // compile to dereference the schema
161+ const validator = ajv . compile ( rawSchema ) ;
162+ const resolvedSchema = validator . schema as AnySchemaObject ;
163+ restructureSchemaFromFieldMap ( rawSchema , fieldMap ) ;
143164
144165 const schemaProperties = schema . properties || { } ;
145166 const schemaDefs : any = schema . definitions ;
146167
147168 for ( const [ schemaProp , schemaDef ] of Object . entries ( schemaProperties ) ) {
148169 const propName = reverseMap [ schemaProp ] || schemaProp ;
149-
150170 // Inject definitions into subschema if needed
151171 if ( typeof schemaDef === 'object' && schemaDefs ) {
152172 ( schemaDef as any ) . definitions = schemaDefs ;
0 commit comments