diff --git a/README.md b/README.md index 371ec08..0c9c82f 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,9 @@ Serializer.register(type, options); * **topLevelLinks** (optional): Describes the top-level links. It can be: * An _object_ (values can be string or function). * A _function_ with one argument `function(extraData) { ... }` or with two arguments `function(data, extraData) { ... }` +* **meta** (optional): Describes resource-level meta. It can be: + * An _object_ (values can be string or function). + * A _function_ with one argument `function(data) { ... }` or with two arguments `function(data, extraData) { ... }` * **relationships** (optional): An object defining some relationships * relationship: The property in data to use as a relationship * **type**: A _string_ or a _function_ `function(relationshipData, data) { ... }` for the type to use for serializing the relationship (type need to be register). diff --git a/lib/JSONAPISerializer.js b/lib/JSONAPISerializer.js index 9095bab..7f09780 100644 --- a/lib/JSONAPISerializer.js +++ b/lib/JSONAPISerializer.js @@ -55,6 +55,7 @@ module.exports = class JSONAPISerializer { blacklist: joi.array().items(joi.string()).single().default([]), whitelist: joi.array().items(joi.string()).single().default([]), links: joi.alternatives([joi.func(), joi.object()]).default({}), + meta: joi.alternatives([joi.func(), joi.object()]).default({}), relationships: joi.object().pattern(/.+/, joi.object({ type: joi.alternatives([joi.func(), joi.string()]).required(), alternativeKey: joi.string(), @@ -578,6 +579,7 @@ module.exports = class JSONAPISerializer { id: data[options.id] ? data[options.id].toString() : undefined, attributes: this.serializeAttributes(data, options), relationships: this.serializeRelationships(data, options, included, extraData), + meta: this.processOptionsValues(data, extraData, options.meta), links: this.processOptionsValues(data, extraData, options.links), }; } diff --git a/package.json b/package.json index c5b63cc..8821c18 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "json-api-serializer", - "version": "1.15.1", + "version": "1.15.2", "description": "Framework agnostic JSON API serializer.", "main": "index.js", "scripts": { diff --git a/test/unit/JSONAPISerializer.test.js b/test/unit/JSONAPISerializer.test.js index 2245986..4dbfc19 100644 --- a/test/unit/JSONAPISerializer.test.js +++ b/test/unit/JSONAPISerializer.test.js @@ -458,13 +458,15 @@ describe('JSONAPISerializer', function() { id: '1', attributes: { type: 'people', name: 'Roman Nelson' }, relationships: undefined, - links: undefined + links: undefined, + meta: undefined }, { type: 'author', id: '1', attributes: { type: 'author', firstName: 'Kaley', lastName: 'Maggio' }, relationships: undefined, - links: undefined } + links: undefined, + meta: undefined } ]); done(); }); @@ -1586,7 +1588,7 @@ describe('JSONAPISerializer', function() { expect(deserializedData).to.have.property('article_author'); done(); }); - + it('should deserialize with \'unconvertCase\' options with \'alternative_key\' relationship', function(done) { const Serializer = new JSONAPISerializer(); Serializer.register('articles', { @@ -1598,7 +1600,7 @@ describe('JSONAPISerializer', function() { }, } }); - + const data = { data: { type: 'article', @@ -1616,7 +1618,7 @@ describe('JSONAPISerializer', function() { } } }; - + const deserializedData = Serializer.deserialize('articles', data); expect(deserializedData).to.have.property('created_at'); expect(deserializedData).to.have.property('article_author_id'); @@ -1951,7 +1953,7 @@ describe('JSONAPISerializer', function() { expect(serializedError.errors[0]).to.have.property('status').to.eql('500'); expect(serializedError.errors[0]).to.have.property('code').to.eql('ERROR'); expect(serializedError.errors[0]).to.have.property('detail').to.eql('An error occured'); - + done(); }); @@ -1963,7 +1965,7 @@ describe('JSONAPISerializer', function() { expect(serializedErrors).to.have.property('errors').to.be.instanceof(Array).to.have.lengthOf(2); expect(serializedErrors.errors[0]).to.have.property('detail').to.eql('First Error'); expect(serializedErrors.errors[1]).to.have.property('detail').to.eql('Second Error'); - + done(); }); @@ -1976,7 +1978,7 @@ describe('JSONAPISerializer', function() { expect(function() { Serializer.serializeError(jsonapiError); }).to.throw(Error); - + done(); }); @@ -1997,7 +1999,7 @@ describe('JSONAPISerializer', function() { title: 'Error', detail: 'An error occured' }); - + done(); }); @@ -2028,7 +2030,7 @@ describe('JSONAPISerializer', function() { title: 'Second Error', detail: 'Second Error' }]); - + done(); }); })