@@ -5,13 +5,10 @@ var isFunction = require('lodash/isFunction');
55var _find = require ( 'lodash/find' ) ;
66var _extend = require ( 'lodash/extend' ) ;
77var _transform = require ( 'lodash/transform' ) ;
8- var _merge = require ( 'lodash/merge' ) ;
9- var _get = require ( 'lodash/get' ) ;
10- var _set = require ( 'lodash/set' ) ;
118var Inflector = require ( './inflector' ) ;
129
1310module . exports = function ( jsonapi , data , opts ) {
14- var alreadyIncluded = { } ;
11+ var alreadyIncluded = [ ] ;
1512
1613 function isComplexType ( obj ) {
1714 return Array . isArray ( obj ) || isPlainObject ( obj ) ;
@@ -28,34 +25,30 @@ module.exports = function (jsonapi, data, opts) {
2825 }
2926 }
3027
31- function findIncluded ( relationshipData , relationshipName , from ) {
28+ function findIncluded ( relationshipData , ancestry ) {
3229 return new Promise ( function ( resolve ) {
33- if ( ! jsonapi . included || ! relationshipData ) { return resolve ( null ) ; }
30+ if ( ! jsonapi . included || ! relationshipData ) { resolve ( null ) ; }
3431
3532 var included = _find ( jsonapi . included , {
3633 id : relationshipData . id ,
3734 type : relationshipData . type
3835 } ) ;
3936
40- var path = [
41- from . type ,
42- from . id ,
43- relationshipName ,
44- relationshipData . type ,
45- relationshipData . id ,
46- ]
47-
48- // Check if the include is already processed (prevent circular
49- // references).
50- if ( _get ( alreadyIncluded , path , false ) ) {
51- return resolve ( null ) ;
52- } else {
53- _merge ( alreadyIncluded , _set ( { } , path , true ) ) ;
54- }
55-
5637 if ( included ) {
38+ // To prevent circular references, check if the record type
39+ // has already been processed in this thread
40+ if ( ancestry . indexOf ( included . type ) > - 1 ) {
41+ return Promise
42+ . all ( [ extractAttributes ( included ) ] )
43+ . then ( function ( results ) {
44+ var attributes = results [ 0 ] ;
45+ var relationships = results [ 1 ] ;
46+ resolve ( _extend ( attributes , relationships ) ) ;
47+ } ) ;
48+ }
49+
5750 return Promise
58- . all ( [ extractAttributes ( included ) , extractRelationships ( included ) ] )
51+ . all ( [ extractAttributes ( included ) , extractRelationships ( included , ancestry + ':' + included . type + included . id ) ] )
5952 . then ( function ( results ) {
6053 var attributes = results [ 0 ] ;
6154 var relationships = results [ 1 ] ;
@@ -105,7 +98,7 @@ module.exports = function (jsonapi, data, opts) {
10598 return dest ;
10699 }
107100
108- function extractRelationships ( from ) {
101+ function extractRelationships ( from , ancestry ) {
109102 if ( ! from . relationships ) { return ; }
110103
111104 var dest = { } ;
@@ -119,15 +112,15 @@ module.exports = function (jsonapi, data, opts) {
119112 } else if ( Array . isArray ( relationship . data ) ) {
120113 return Promise
121114 . all ( relationship . data . map ( function ( relationshipData ) {
122- return extractIncludes ( relationshipData , key , from ) ;
115+ return extractIncludes ( relationshipData , ancestry ) ;
123116 } ) )
124117 . then ( function ( includes ) {
125118 if ( includes ) { dest [ keyForAttribute ( key ) ] = includes ; }
126119 } ) ;
127120 } else {
128- return extractIncludes ( relationship . data , key , from )
129- . then ( function ( include ) {
130- if ( include ) { dest [ keyForAttribute ( key ) ] = include ; }
121+ return extractIncludes ( relationship . data , ancestry )
122+ . then ( function ( includes ) {
123+ if ( includes ) { dest [ keyForAttribute ( key ) ] = includes ; }
131124 } ) ;
132125 }
133126 } ) )
@@ -136,8 +129,8 @@ module.exports = function (jsonapi, data, opts) {
136129 } ) ;
137130 }
138131
139- function extractIncludes ( relationshipData , relationshipName , from ) {
140- return findIncluded ( relationshipData , relationshipName , from )
132+ function extractIncludes ( relationshipData , ancestry ) {
133+ return findIncluded ( relationshipData , ancestry )
141134 . then ( function ( included ) {
142135 var valueForRelationship = getValueForRelationship ( relationshipData ,
143136 included ) ;
@@ -154,7 +147,7 @@ module.exports = function (jsonapi, data, opts) {
154147
155148 this . perform = function ( ) {
156149 return Promise
157- . all ( [ extractAttributes ( data ) , extractRelationships ( data ) ] )
150+ . all ( [ extractAttributes ( data ) , extractRelationships ( data , data . type + data . id ) ] )
158151 . then ( function ( results ) {
159152 var attributes = results [ 0 ] ;
160153 var relationships = results [ 1 ] ;
@@ -165,7 +158,6 @@ module.exports = function (jsonapi, data, opts) {
165158 record . links = jsonapi . links ;
166159 }
167160
168-
169161 // If option is present, transform record
170162 if ( opts && opts . transform ) {
171163 record = opts . transform ( record ) ;
@@ -176,7 +168,7 @@ module.exports = function (jsonapi, data, opts) {
176168 } ;
177169} ;
178170
179- } , { "./inflector" :5 , "lodash/extend" :158 , "lodash/find" :159 , "lodash/get" : 163 , "lodash/ isFunction" :171 , "lodash/isPlainObject" :176 , "lodash/merge" : 184 , "lodash/set" : 188 , "lodash/ transform" :196 } ] , 2 :[ function ( require , module , exports ) {
171+ } , { "./inflector" :5 , "lodash/extend" :158 , "lodash/find" :159 , "lodash/isFunction" :171 , "lodash/isPlainObject" :176 , "lodash/transform" :195 } ] , 2 :[ function ( require , module , exports ) {
180172'use strict' ;
181173var isFunction = require ( 'lodash/isFunction' ) ;
182174var DeserializerUtils = require ( './deserializer-utils' ) ;
@@ -623,7 +615,7 @@ module.exports = function (collectionName, record, payload, opts) {
623615 } ;
624616} ;
625617
626- } , { "./inflector" :5 , "lodash/each" :156 , "lodash/find" :159 , "lodash/identity" :165 , "lodash/isFunction" :171 , "lodash/isNil" :173 , "lodash/isPlainObject" :176 , "lodash/keys" :179 , "lodash/mapKeys" :181 , "lodash/mapValues" :182 , "lodash/merge" :184 , "lodash/pick" :185 , "lodash/pickBy" :186 , "lodash/transform" :196 } ] , 7 :[ function ( require , module , exports ) {
618+ } , { "./inflector" :5 , "lodash/each" :156 , "lodash/find" :159 , "lodash/identity" :165 , "lodash/isFunction" :171 , "lodash/isNil" :173 , "lodash/isPlainObject" :176 , "lodash/keys" :179 , "lodash/mapKeys" :181 , "lodash/mapValues" :182 , "lodash/merge" :184 , "lodash/pick" :185 , "lodash/pickBy" :186 , "lodash/transform" :195 } ] , 7 :[ function ( require , module , exports ) {
627619'use strict' ;
628620var isFunction = require ( 'lodash/isFunction' ) ;
629621var _mapValues = require ( 'lodash/mapValues' ) ;
@@ -815,7 +807,7 @@ Inflections.prototype.clear = function(scope) {
815807module . exports = Inflections ;
816808
817809} ) . call ( this , require ( '_process' ) , typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : { } )
818- } , { "./hasProp" :14 , "./icPart" :15 , "./remove" :17 , "_process" :197 } ] , 10 :[ function ( require , module , exports ) {
810+ } , { "./hasProp" :14 , "./icPart" :15 , "./remove" :17 , "_process" :196 } ] , 10 :[ function ( require , module , exports ) {
819811'use strict' ;
820812
821813var Inflections = require ( './Inflections' ) ;
@@ -1144,7 +1136,7 @@ Transliterator.prototype.transliterate = function(string, replacement) {
11441136module . exports = Transliterator ;
11451137
11461138} ) . call ( this , require ( '_process' ) , typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : { } )
1147- } , { "_process" :197 } ] , 13 :[ function ( require , module , exports ) {
1139+ } , { "_process" :196 } ] , 13 :[ function ( require , module , exports ) {
11481140'use strict' ;
11491141
11501142function enDefaults ( inflect ) {
@@ -2628,7 +2620,7 @@ function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, sta
26282620
26292621module . exports = baseMergeDeep ;
26302622
2631- } , { "./_assignMergeValue" :37 , "./_cloneBuffer" :78 , "./_cloneTypedArray" :79 , "./_copyArray" :80 , "./_initCloneObject" :110 , "./_safeGet" :140 , "./isArguments" :166 , "./isArray" :167 , "./isArrayLikeObject" :169 , "./isBuffer" :170 , "./isFunction" :171 , "./isObject" :174 , "./isPlainObject" :176 , "./isTypedArray" :178 , "./toPlainObject" :194 } ] , 64 :[ function ( require , module , exports ) {
2623+ } , { "./_assignMergeValue" :37 , "./_cloneBuffer" :78 , "./_cloneTypedArray" :79 , "./_copyArray" :80 , "./_initCloneObject" :110 , "./_safeGet" :140 , "./isArguments" :166 , "./isArray" :167 , "./isArrayLikeObject" :169 , "./isBuffer" :170 , "./isFunction" :171 , "./isObject" :174 , "./isPlainObject" :176 , "./isTypedArray" :178 , "./toPlainObject" :193 } ] , 64 :[ function ( require , module , exports ) {
26322624var basePickBy = require ( './_basePickBy' ) ,
26332625 hasIn = require ( './hasIn' ) ;
26342626
@@ -2938,7 +2930,7 @@ function castPath(value, object) {
29382930
29392931module . exports = castPath ;
29402932
2941- } , { "./_isKey" :114 , "./_stringToPath" :151 , "./isArray" :167 , "./toString" :195 } ] , 77 :[ function ( require , module , exports ) {
2933+ } , { "./_isKey" :114 , "./_stringToPath" :151 , "./isArray" :167 , "./toString" :194 } ] , 77 :[ function ( require , module , exports ) {
29422934var Uint8Array = require ( './_Uint8Array' ) ;
29432935
29442936/**
@@ -3729,7 +3721,7 @@ var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
37293721
37303722module . exports = getSymbols ;
37313723
3732- } , { "./_arrayFilter" :32 , "./stubArray" :189 } ] , 101 :[ function ( require , module , exports ) {
3724+ } , { "./_arrayFilter" :32 , "./stubArray" :188 } ] , 101 :[ function ( require , module , exports ) {
37333725var arrayPush = require ( './_arrayPush' ) ,
37343726 getPrototype = require ( './_getPrototype' ) ,
37353727 getSymbols = require ( './_getSymbols' ) ,
@@ -3756,7 +3748,7 @@ var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
37563748
37573749module . exports = getSymbolsIn ;
37583750
3759- } , { "./_arrayPush" :35 , "./_getPrototype" :98 , "./_getSymbols" :100 , "./stubArray" :189 } ] , 102 :[ function ( require , module , exports ) {
3751+ } , { "./_arrayPush" :35 , "./_getPrototype" :98 , "./_getSymbols" :100 , "./stubArray" :188 } ] , 102 :[ function ( require , module , exports ) {
37603752var DataView = require ( './_DataView' ) ,
37613753 Map = require ( './_Map' ) ,
37623754 Promise = require ( './_Promise' ) ,
@@ -5182,7 +5174,7 @@ function findIndex(array, predicate, fromIndex) {
51825174
51835175module . exports = findIndex ;
51845176
5185- } , { "./_baseFindIndex" :43 , "./_baseIteratee" :57 , "./toInteger" :192 } ] , 161 :[ function ( require , module , exports ) {
5177+ } , { "./_baseFindIndex" :43 , "./_baseIteratee" :57 , "./toInteger" :191 } ] , 161 :[ function ( require , module , exports ) {
51865178var baseFlatten = require ( './_baseFlatten' ) ;
51875179
51885180/**
@@ -5519,7 +5511,7 @@ var isBuffer = nativeIsBuffer || stubFalse;
55195511
55205512module . exports = isBuffer ;
55215513
5522- } , { "./_root" :139 , "./stubFalse" :190 } ] , 171 :[ function ( require , module , exports ) {
5514+ } , { "./_root" :139 , "./stubFalse" :189 } ] , 171 :[ function ( require , module , exports ) {
55235515var baseGetTag = require ( './_baseGetTag' ) ,
55245516 isObject = require ( './isObject' ) ;
55255517
@@ -6183,43 +6175,6 @@ function property(path) {
61836175module . exports = property ;
61846176
61856177} , { "./_baseProperty" :66 , "./_basePropertyDeep" :67 , "./_isKey" :114 , "./_toKey" :152 } ] , 188 :[ function ( require , module , exports ) {
6186- var baseSet = require ( './_baseSet' ) ;
6187-
6188- /**
6189- * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
6190- * it's created. Arrays are created for missing index properties while objects
6191- * are created for all other missing properties. Use `_.setWith` to customize
6192- * `path` creation.
6193- *
6194- * **Note:** This method mutates `object`.
6195- *
6196- * @static
6197- * @memberOf _
6198- * @since 3.7.0
6199- * @category Object
6200- * @param {Object } object The object to modify.
6201- * @param {Array|string } path The path of the property to set.
6202- * @param {* } value The value to set.
6203- * @returns {Object } Returns `object`.
6204- * @example
6205- *
6206- * var object = { 'a': [{ 'b': { 'c': 3 } }] };
6207- *
6208- * _.set(object, 'a[0].b.c', 4);
6209- * console.log(object.a[0].b.c);
6210- * // => 4
6211- *
6212- * _.set(object, ['x', '0', 'y', 'z'], 5);
6213- * console.log(object.x[0].y.z);
6214- * // => 5
6215- */
6216- function set ( object , path , value ) {
6217- return object == null ? object : baseSet ( object , path , value ) ;
6218- }
6219-
6220- module . exports = set ;
6221-
6222- } , { "./_baseSet" :69 } ] , 189 :[ function ( require , module , exports ) {
62236178/**
62246179 * This method returns a new empty array.
62256180 *
@@ -6244,7 +6199,7 @@ function stubArray() {
62446199
62456200module . exports = stubArray ;
62466201
6247- } , { } ] , 190 :[ function ( require , module , exports ) {
6202+ } , { } ] , 189 :[ function ( require , module , exports ) {
62486203/**
62496204 * This method returns `false`.
62506205 *
@@ -6264,7 +6219,7 @@ function stubFalse() {
62646219
62656220module . exports = stubFalse ;
62666221
6267- } , { } ] , 191 :[ function ( require , module , exports ) {
6222+ } , { } ] , 190 :[ function ( require , module , exports ) {
62686223var toNumber = require ( './toNumber' ) ;
62696224
62706225/** Used as references for various `Number` constants. */
@@ -6308,7 +6263,7 @@ function toFinite(value) {
63086263
63096264module . exports = toFinite ;
63106265
6311- } , { "./toNumber" :193 } ] , 192 :[ function ( require , module , exports ) {
6266+ } , { "./toNumber" :192 } ] , 191 :[ function ( require , module , exports ) {
63126267var toFinite = require ( './toFinite' ) ;
63136268
63146269/**
@@ -6346,7 +6301,7 @@ function toInteger(value) {
63466301
63476302module . exports = toInteger ;
63486303
6349- } , { "./toFinite" :191 } ] , 193 :[ function ( require , module , exports ) {
6304+ } , { "./toFinite" :190 } ] , 192 :[ function ( require , module , exports ) {
63506305var isObject = require ( './isObject' ) ,
63516306 isSymbol = require ( './isSymbol' ) ;
63526307
@@ -6414,7 +6369,7 @@ function toNumber(value) {
64146369
64156370module . exports = toNumber ;
64166371
6417- } , { "./isObject" :174 , "./isSymbol" :177 } ] , 194 :[ function ( require , module , exports ) {
6372+ } , { "./isObject" :174 , "./isSymbol" :177 } ] , 193 :[ function ( require , module , exports ) {
64186373var copyObject = require ( './_copyObject' ) ,
64196374 keysIn = require ( './keysIn' ) ;
64206375
@@ -6448,7 +6403,7 @@ function toPlainObject(value) {
64486403
64496404module . exports = toPlainObject ;
64506405
6451- } , { "./_copyObject" :81 , "./keysIn" :180 } ] , 195 :[ function ( require , module , exports ) {
6406+ } , { "./_copyObject" :81 , "./keysIn" :180 } ] , 194 :[ function ( require , module , exports ) {
64526407var baseToString = require ( './_baseToString' ) ;
64536408
64546409/**
@@ -6478,7 +6433,7 @@ function toString(value) {
64786433
64796434module . exports = toString ;
64806435
6481- } , { "./_baseToString" :72 } ] , 196 :[ function ( require , module , exports ) {
6436+ } , { "./_baseToString" :72 } ] , 195 :[ function ( require , module , exports ) {
64826437var arrayEach = require ( './_arrayEach' ) ,
64836438 baseCreate = require ( './_baseCreate' ) ,
64846439 baseForOwn = require ( './_baseForOwn' ) ,
@@ -6545,7 +6500,7 @@ function transform(object, iteratee, accumulator) {
65456500
65466501module . exports = transform ;
65476502
6548- } , { "./_arrayEach" :31 , "./_baseCreate" :41 , "./_baseForOwn" :46 , "./_baseIteratee" :57 , "./_getPrototype" :98 , "./isArray" :167 , "./isBuffer" :170 , "./isFunction" :171 , "./isObject" :174 , "./isTypedArray" :178 } ] , 197 :[ function ( require , module , exports ) {
6503+ } , { "./_arrayEach" :31 , "./_baseCreate" :41 , "./_baseForOwn" :46 , "./_baseIteratee" :57 , "./_getPrototype" :98 , "./isArray" :167 , "./isBuffer" :170 , "./isFunction" :171 , "./isObject" :174 , "./isTypedArray" :178 } ] , 196 :[ function ( require , module , exports ) {
65496504// shim for using process in browser
65506505var process = module . exports = { } ;
65516506
0 commit comments