@@ -1121,19 +1121,12 @@ describe('build-schema', () => {
11211121
11221122 const expectedSchema : JsonSchema = {
11231123 definitions : {
1124- ProductWithRelations : {
1125- title : 'ProductWithRelations ' ,
1124+ Product : {
1125+ title : 'Product ' ,
11261126 type : 'object' ,
1127- description :
1128- `(tsType: ProductWithRelations, ` +
1129- `schemaOptions: { includeRelations: true })` ,
11301127 properties : {
11311128 id : { type : 'number' } ,
11321129 categoryId : { type : 'number' } ,
1133- category : {
1134- $ref : '#/definitions/CategoryWithRelations' ,
1135- } ,
1136- foreignKey : 'categoryId' as JsonSchema ,
11371130 } ,
11381131 additionalProperties : false ,
11391132 } ,
@@ -1143,7 +1136,7 @@ describe('build-schema', () => {
11431136 products : {
11441137 type : 'array' ,
11451138 items : {
1146- $ref : '#/definitions/ProductWithRelations ' ,
1139+ $ref : '#/definitions/Product ' ,
11471140 } ,
11481141 } ,
11491142 } ,
@@ -1175,27 +1168,20 @@ describe('build-schema', () => {
11751168 }
11761169 const expectedSchema : JsonSchema = {
11771170 definitions : {
1178- ProductWithRelations : {
1179- title : 'ProductWithRelations ' ,
1171+ Product : {
1172+ title : 'Product ' ,
11801173 type : 'object' ,
1181- description :
1182- `(tsType: ProductWithRelations, ` +
1183- `schemaOptions: { includeRelations: true })` ,
11841174 properties : {
11851175 id : { type : 'number' } ,
11861176 categoryId : { type : 'number' } ,
1187- category : {
1188- $ref : '#/definitions/CategoryWithoutPropWithRelations' ,
1189- } ,
1190- foreignKey : 'categoryId' as JsonSchema ,
11911177 } ,
11921178 additionalProperties : false ,
11931179 } ,
11941180 } ,
11951181 properties : {
11961182 products : {
11971183 type : 'array' ,
1198- items : { $ref : '#/definitions/ProductWithRelations ' } ,
1184+ items : { $ref : '#/definitions/Product ' } ,
11991185 } ,
12001186 } ,
12011187 additionalProperties : false ,
@@ -1213,6 +1199,52 @@ describe('build-schema', () => {
12131199 expect ( jsonSchemaWithoutProp ) . to . deepEqual ( expectedSchema ) ;
12141200 } ) ;
12151201
1202+ it ( 'does not produce circular $ref chains for bidirectional relations' , ( ) => {
1203+ @model ( )
1204+ class Order extends Entity {
1205+ @property ( { id : true } )
1206+ id : number ;
1207+
1208+ @belongsTo ( ( ) => Customer )
1209+ customerId : number ;
1210+ }
1211+
1212+ @model ( )
1213+ class Customer extends Entity {
1214+ @property ( { id : true } )
1215+ id : number ;
1216+
1217+ @hasMany ( ( ) => Order )
1218+ orders ?: Order [ ] ;
1219+ }
1220+
1221+ const schema = getJsonSchema ( Customer , { includeRelations : true } ) ;
1222+
1223+ // orders items should reference plain Order, not OrderWithRelations
1224+ expect ( schema . properties ) . to . containDeep ( {
1225+ orders : {
1226+ type : 'array' ,
1227+ items : { $ref : '#/definitions/Order' } ,
1228+ } ,
1229+ } ) ;
1230+
1231+ // The Order definition should be plain — no nested definitions,
1232+ // no customer navigational property
1233+ const orderDef = schema . definitions ?. Order as JsonSchema ;
1234+ expect ( orderDef ) . to . be . ok ( ) ;
1235+ expect ( orderDef . definitions ) . to . be . undefined ( ) ;
1236+ expect ( orderDef . properties ) . to . not . have . property ( 'customer' ) ;
1237+
1238+ // No WithRelations keys should appear in definitions
1239+ const defKeys = Object . keys ( schema . definitions ?? { } ) ;
1240+ for ( const key of defKeys ) {
1241+ expect ( key ) . to . not . match (
1242+ / W i t h R e l a t i o n s / ,
1243+ `definitions should not contain WithRelations keys, found: ${ key } ` ,
1244+ ) ;
1245+ }
1246+ } ) ;
1247+
12161248 it ( 'gets cached JSON schema with relation links if one exists' , ( ) => {
12171249 @model ( )
12181250 class Product extends Entity {
0 commit comments