@@ -4,13 +4,10 @@ var isFunction = require('lodash/isFunction');
44var _find = require ( 'lodash/find' ) ;
55var _extend = require ( 'lodash/extend' ) ;
66var _transform = require ( 'lodash/transform' ) ;
7- var _merge = require ( 'lodash/merge' ) ;
8- var _get = require ( 'lodash/get' ) ;
9- var _set = require ( 'lodash/set' ) ;
107var Inflector = require ( './inflector' ) ;
118
129module . exports = function ( jsonapi , data , opts ) {
13- var alreadyIncluded = { } ;
10+ var alreadyIncluded = [ ] ;
1411
1512 function isComplexType ( obj ) {
1613 return Array . isArray ( obj ) || isPlainObject ( obj ) ;
@@ -27,34 +24,30 @@ module.exports = function (jsonapi, data, opts) {
2724 }
2825 }
2926
30- function findIncluded ( relationshipData , relationshipName , from ) {
27+ function findIncluded ( relationshipData , ancestry ) {
3128 return new Promise ( function ( resolve ) {
32- if ( ! jsonapi . included || ! relationshipData ) { return resolve ( null ) ; }
29+ if ( ! jsonapi . included || ! relationshipData ) { resolve ( null ) ; }
3330
3431 var included = _find ( jsonapi . included , {
3532 id : relationshipData . id ,
3633 type : relationshipData . type
3734 } ) ;
3835
39- var path = [
40- from . type ,
41- from . id ,
42- relationshipName ,
43- relationshipData . type ,
44- relationshipData . id ,
45- ]
46-
47- // Check if the include is already processed (prevent circular
48- // references).
49- if ( _get ( alreadyIncluded , path , false ) ) {
50- return resolve ( null ) ;
51- } else {
52- _merge ( alreadyIncluded , _set ( { } , path , true ) ) ;
53- }
54-
5536 if ( included ) {
37+ // To prevent circular references, check if the record type
38+ // has already been processed in this thread
39+ if ( ancestry . indexOf ( included . type ) > - 1 ) {
40+ return Promise
41+ . all ( [ extractAttributes ( included ) ] )
42+ . then ( function ( results ) {
43+ var attributes = results [ 0 ] ;
44+ var relationships = results [ 1 ] ;
45+ resolve ( _extend ( attributes , relationships ) ) ;
46+ } ) ;
47+ }
48+
5649 return Promise
57- . all ( [ extractAttributes ( included ) , extractRelationships ( included ) ] )
50+ . all ( [ extractAttributes ( included ) , extractRelationships ( included , ` ${ ancestry } : ${ included . type } ${ included . id } ` ) ] )
5851 . then ( function ( results ) {
5952 var attributes = results [ 0 ] ;
6053 var relationships = results [ 1 ] ;
@@ -104,7 +97,7 @@ module.exports = function (jsonapi, data, opts) {
10497 return dest ;
10598 }
10699
107- function extractRelationships ( from ) {
100+ function extractRelationships ( from , ancestry ) {
108101 if ( ! from . relationships ) { return ; }
109102
110103 var dest = { } ;
@@ -118,15 +111,15 @@ module.exports = function (jsonapi, data, opts) {
118111 } else if ( Array . isArray ( relationship . data ) ) {
119112 return Promise
120113 . all ( relationship . data . map ( function ( relationshipData ) {
121- return extractIncludes ( relationshipData , key , from ) ;
114+ return extractIncludes ( relationshipData , ancestry ) ;
122115 } ) )
123116 . then ( function ( includes ) {
124117 if ( includes ) { dest [ keyForAttribute ( key ) ] = includes ; }
125118 } ) ;
126119 } else {
127- return extractIncludes ( relationship . data , key , from )
128- . then ( function ( include ) {
129- if ( include ) { dest [ keyForAttribute ( key ) ] = include ; }
120+ return extractIncludes ( relationship . data , ancestry )
121+ . then ( function ( includes ) {
122+ if ( includes ) { dest [ keyForAttribute ( key ) ] = includes ; }
130123 } ) ;
131124 }
132125 } ) )
@@ -135,8 +128,8 @@ module.exports = function (jsonapi, data, opts) {
135128 } ) ;
136129 }
137130
138- function extractIncludes ( relationshipData , relationshipName , from ) {
139- return findIncluded ( relationshipData , relationshipName , from )
131+ function extractIncludes ( relationshipData , ancestry ) {
132+ return findIncluded ( relationshipData , ancestry )
140133 . then ( function ( included ) {
141134 var valueForRelationship = getValueForRelationship ( relationshipData ,
142135 included ) ;
@@ -153,7 +146,7 @@ module.exports = function (jsonapi, data, opts) {
153146
154147 this . perform = function ( ) {
155148 return Promise
156- . all ( [ extractAttributes ( data ) , extractRelationships ( data ) ] )
149+ . all ( [ extractAttributes ( data ) , extractRelationships ( data , ` ${ data . type } ${ data . id } ` ) ] )
157150 . then ( function ( results ) {
158151 var attributes = results [ 0 ] ;
159152 var relationships = results [ 1 ] ;
@@ -164,7 +157,6 @@ module.exports = function (jsonapi, data, opts) {
164157 record . links = jsonapi . links ;
165158 }
166159
167-
168160 // If option is present, transform record
169161 if ( opts && opts . transform ) {
170162 record = opts . transform ( record ) ;
0 commit comments