diff --git a/browserify/jsonapi-serializer.js b/browserify/jsonapi-serializer.js index 0ee2ae9..68e4db7 100644 --- a/browserify/jsonapi-serializer.js +++ b/browserify/jsonapi-serializer.js @@ -37,7 +37,7 @@ module.exports = function (jsonapi, data, opts) { if (included) { // To prevent circular references, check if the record type // has already been processed in this thread - if (ancestry.indexOf(included.type) > -1) { + if (ancestry.indexOf(included.type + included.id) > -1) { return Promise .all([extractAttributes(included)]) .then(function (results) { @@ -48,11 +48,19 @@ module.exports = function (jsonapi, data, opts) { } return Promise - .all([extractAttributes(included), extractRelationships(included, ancestry + ':' + included.type + included.id)]) + .all([extractAttributes(included), extractRelationships(included, ancestry + ':' + included.type + included.id), extractLinks(included)]) .then(function (results) { var attributes = results[0]; var relationships = results[1]; - resolve(_extend(attributes, relationships)); + var links = results[2]; + const record = _extend(attributes, relationships); + + // Links + if (links) { + record.links = links; + } + + resolve(record) }); } else { return resolve(null); @@ -145,17 +153,29 @@ module.exports = function (jsonapi, data, opts) { }); } + function extractLinks(from) { + if (from.links) { + return from.links; + } + if (jsonapi.links) { + return jsonapi.links; + } + return undefined; + } + this.perform = function () { return Promise - .all([extractAttributes(data), extractRelationships(data, data.type + data.id)]) + .all([extractAttributes(data), extractRelationships(data, data.type + data.id), extractLinks(data)]) .then(function (results) { var attributes = results[0]; var relationships = results[1]; + var links = results[2]; + var record = _extend(attributes, relationships); // Links - if (jsonapi.links) { - record.links = jsonapi.links; + if (links) { + record.links = links; } // If option is present, transform record diff --git a/lib/deserializer-utils.js b/lib/deserializer-utils.js index 1265fd4..3e73ad4 100644 --- a/lib/deserializer-utils.js +++ b/lib/deserializer-utils.js @@ -36,7 +36,7 @@ module.exports = function (jsonapi, data, opts) { if (included) { // To prevent circular references, check if the record type // has already been processed in this thread - if (ancestry.indexOf(included.type) > -1) { + if (ancestry.indexOf(included.type + included.id) > -1) { return Promise .all([extractAttributes(included)]) .then(function (results) { @@ -47,11 +47,19 @@ module.exports = function (jsonapi, data, opts) { } return Promise - .all([extractAttributes(included), extractRelationships(included, ancestry + ':' + included.type + included.id)]) + .all([extractAttributes(included), extractRelationships(included, ancestry + ':' + included.type + included.id), extractLinks(included)]) .then(function (results) { var attributes = results[0]; var relationships = results[1]; - resolve(_extend(attributes, relationships)); + var links = results[2]; + const record = _extend(attributes, relationships); + + // Links + if (links) { + record.links = links; + } + + resolve(record) }); } else { return resolve(null); @@ -144,17 +152,29 @@ module.exports = function (jsonapi, data, opts) { }); } + function extractLinks(from) { + if (from.links) { + return from.links; + } + if (jsonapi.links) { + return jsonapi.links; + } + return undefined; + } + this.perform = function () { return Promise - .all([extractAttributes(data), extractRelationships(data, data.type + data.id)]) + .all([extractAttributes(data), extractRelationships(data, data.type + data.id), extractLinks(data)]) .then(function (results) { var attributes = results[0]; var relationships = results[1]; + var links = results[2]; + var record = _extend(attributes, relationships); // Links - if (jsonapi.links) { - record.links = jsonapi.links; + if (links) { + record.links = links; } // If option is present, transform record diff --git a/package-lock.json b/package-lock.json index 8b76b04..525e5bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "jsonapi-serializer", - "version": "3.6.3", + "version": "3.6.10", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index d4937d3..8df7fc8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "jsonapi-serializer", - "version": "3.6.7", + "name": "swards-jsonapi-serializer", + "version": "3.6.10", "description": "A Node.js framework agnostic library for serializing your data to JSON API", "main": "index.js", "scripts": { @@ -8,7 +8,7 @@ }, "author": "Sandro Munda ", "license": "MIT", - "repository": "SeyZ/jsonapi-serializer", + "repository": "swards/jsonapi-serializer", "engines": { "node": ">=0.12" }, diff --git a/test/deserializer.js b/test/deserializer.js index bd5ae42..6bf3509 100644 --- a/test/deserializer.js +++ b/test/deserializer.js @@ -616,88 +616,128 @@ describe('JSON API Deserializer', function () { expect(json).to.be.an('object'); expect(json).to.be.be.eql({ - name: 'Twin Pines Mall', - id: '1', - stores: [ - { - name: 'Tasty Food', - id: '1', - deals: [ - { - name: 'Free Drink with Snack Purchase', - id: '1', - stores: [ - { name: 'Tasty Food', id: '1' } - ] - }, { - name: 'Free Samples of New Delicious Treat', - id: '2', - stores: [ - { name: 'Tasty Food', id: '1' } - ] - } - ] - }, { - name: 'Fashionable Clothes', - id: '2', - deals: [ - { - name: 'Buy One Get One Off Shirts', - id: '3', - stores: [ - { name: 'Fashionable Clothes', id: '2' } - ] - } - ] - }, { - name: 'Readable Books', - id: '3' - } - ], - deals: [ - { - name: 'Free Drink with Snack Purchase', - id: '1', - stores: [ - { - name: 'Tasty Food', - id: '1', - deals: [ - { name: 'Free Drink with Snack Purchase', id: '1' }, - { name: 'Free Samples of New Delicious Treat', id: '2' } - ] - } - ] - }, - { - name: 'Free Samples of New Delicious Treat', - id: '2', - stores: [ - { - name: 'Tasty Food', - id: '1', - deals: [ - { name: 'Free Drink with Snack Purchase', id: '1' }, - { name: 'Free Samples of New Delicious Treat', id: '2' } - ] - } - ] - }, - { - name: 'Buy One Get One Off Shirts', - id: '3', - stores: [ - { - name: 'Fashionable Clothes', - id: '2', - deals: [ - { name: 'Buy One Get One Off Shirts', id: '3' } - ] - } - ] - } - ] - }); + "name": "Twin Pines Mall", + "id": "1", + "stores": [ + { + "name": "Tasty Food", + "id": "1", + "deals": [ + { + "name": "Free Drink with Snack Purchase", + "id": "1", + "stores": [ + { + "name": "Tasty Food", + "id": "1" + } + ] + }, + { + "name": "Free Samples of New Delicious Treat", + "id": "2", + "stores": [ + { + "name": "Tasty Food", + "id": "1" + } + ] + } + ] + }, + { + "name": "Fashionable Clothes", + "id": "2", + "deals": [ + { + "name": "Buy One Get One Off Shirts", + "id": "3", + "stores": [ + { + "name": "Fashionable Clothes", + "id": "2" + } + ] + } + ] + }, + { + "name": "Readable Books", + "id": "3" + } + ], + "deals": [ + { + "name": "Free Drink with Snack Purchase", + "id": "1", + "stores": [ + { + "name": "Tasty Food", + "id": "1", + "deals": [ + { + "name": "Free Drink with Snack Purchase", + "id": "1" + }, + { + "name": "Free Samples of New Delicious Treat", + "id": "2", + "stores": [ + { + "name": "Tasty Food", + "id": "1" + } + ] + } + ] + } + ] + }, + { + "name": "Free Samples of New Delicious Treat", + "id": "2", + "stores": [ + { + "name": "Tasty Food", + "id": "1", + "deals": [ + { + "name": "Free Drink with Snack Purchase", + "id": "1", + "stores": [ + { + "name": "Tasty Food", + "id": "1" + } + ] + }, + { + "name": "Free Samples of New Delicious Treat", + "id": "2" + } + ] + } + ] + }, + { + "name": "Buy One Get One Off Shirts", + "id": "3", + "stores": [ + { + "name": "Fashionable Clothes", + "id": "2", + "deals": [ + { + "name": "Buy One Get One Off Shirts", + "id": "3" + } + ] + } + ] + } + ] + } + ); done(null, json); });