Skip to content

Commit dc654a8

Browse files
committed
Added resource-level meta options for serialization
closes #73 #74
1 parent ad7853c commit dc654a8

File tree

6 files changed

+43
-0
lines changed

6 files changed

+43
-0
lines changed

Diff for: README.md

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ Serializer.register(type, options);
3737
* **topLevelLinks** (optional): Describes the top-level links. It can be:
3838
* An _object_ (values can be string or function).
3939
* A _function_ with one argument `function(extraData) { ... }` or with two arguments `function(data, extraData) { ... }`
40+
* **meta** (optional): Describes resource-level meta. It can be:
41+
* An _object_ (values can be string or function).
42+
* A _function_ with one argument `function(data) { ... }` or with two arguments `function(data, extraData) { ... }`
4043
* **relationships** (optional): An object defining some relationships
4144
* relationship: The property in data to use as a relationship
4245
* **type**: A _string_ or a _function_ `function(relationshipData, data) { ... }` for the type to use for serializing the relationship (type need to be register).

Diff for: lib/JSONAPISerializer.js

+1
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ module.exports = class JSONAPISerializer {
485485
id: data[options.id] ? data[options.id].toString() : undefined,
486486
attributes: this.serializeAttributes(data, options),
487487
relationships: this.serializeRelationships(data, options, included, extraData),
488+
meta: this.processOptionsValues(data, extraData, options.meta),
488489
links: this.processOptionsValues(data, extraData, options.links)
489490
};
490491
}

Diff for: lib/validator.js

+5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ function validateOptions(options) {
1616
relationships: {},
1717
topLevelLinks: {},
1818
topLevelMeta: {},
19+
meta: {},
1920
blacklistOnDeserialize: [],
2021
whitelistOnDeserialize: [],
2122
jsonapiObject: true
@@ -43,6 +44,8 @@ function validateOptions(options) {
4344
typeof options.topLevelMeta !== 'function'
4445
)
4546
throw new Error("option 'topLevelMeta' must be an object or a function");
47+
if (options.meta && typeof options.meta !== 'object' && typeof options.meta !== 'function')
48+
throw new Error("option 'meta' must be an object or a function");
4649
if (typeof options.jsonapiObject !== 'boolean')
4750
throw new Error("option 'jsonapiObject' must a boolean");
4851
if (
@@ -126,6 +129,8 @@ function validateDynamicTypeOptions(options) {
126129
typeof options.topLevelMeta !== 'function'
127130
)
128131
throw new Error("option 'topLevelMeta' must be an object or a function");
132+
if (options.meta && typeof options.meta !== 'object' && typeof options.meta !== 'function')
133+
throw new Error("option 'meta' must be an object or a function");
129134
if (typeof options.jsonapiObject !== 'boolean')
130135
throw new Error("option 'jsonapiObject' must a boolean");
131136

Diff for: test/integration/examples.js

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ describe('Examples', function() {
1616
self: '/articles/' + data.id
1717
}
1818
},
19+
meta: function(data) {
20+
return {
21+
meta: 'metadata'
22+
}
23+
},
1924
relationships: {
2025
author: {
2126
type: 'people',
@@ -109,6 +114,7 @@ describe('Examples', function() {
109114
expect(serializedData.data[0].relationships.comments.data[0]).to.have.property('id').to.be.a('string');
110115
expect(serializedData.data[0]).to.have.property('links');
111116
expect(serializedData.data[0].links).to.have.property('self').to.eql('/articles/1');
117+
expect(serializedData.data[0].meta).to.have.property('meta').to.eql('metadata');
112118
expect(serializedData).to.have.property('included');
113119
expect(serializedData.included).to.be.instanceof(Array).to.have.lengthOf(10);
114120
var includedAuhor1 = _.find(serializedData.included, {

Diff for: test/unit/JSONAPISerializer.test.js

+10
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ describe('JSONAPISerializer', function() {
8484
expect(serializedData).to.have.property('attributes').to.have.property('body').to.eql('test body');
8585
expect(serializedData.relationships).to.be.undefined;
8686
expect(serializedData.links).to.be.undefined;
87+
expect(serializedData.meta).to.be.undefined;
8788

8889
done();
8990
});
@@ -99,6 +100,7 @@ describe('JSONAPISerializer', function() {
99100
expect(serializedData.attributes).to.be.undefined;
100101
expect(serializedData.relationships).to.be.undefined;
101102
expect(serializedData.links).to.be.undefined;
103+
expect(serializedData.meta).to.be.undefined;
102104

103105
done();
104106
});
@@ -118,11 +120,13 @@ describe('JSONAPISerializer', function() {
118120
expect(serializedData[0]).to.have.property('attributes').to.have.property('body').to.eql('test body 1');
119121
expect(serializedData[0].relationships).to.be.undefined;
120122
expect(serializedData[0].links).to.be.undefined;
123+
expect(serializedData[0].meta).to.be.undefined;
121124
expect(serializedData[1]).to.have.property('type').to.eql('articles');
122125
expect(serializedData[1]).to.have.property('id').to.eql('2');
123126
expect(serializedData[1]).to.have.property('attributes').to.have.property('body').to.eql('test body 2');
124127
expect(serializedData[1].relationships).to.be.undefined;
125128
expect(serializedData[1].links).to.be.undefined;
129+
expect(serializedData[1].meta).to.be.undefined;
126130
done();
127131
});
128132

@@ -137,6 +141,7 @@ describe('JSONAPISerializer', function() {
137141
expect(serializedData).to.have.property('id').to.eql('1');
138142
expect(serializedData.relationships).to.be.undefined;
139143
expect(serializedData.links).to.be.undefined;
144+
expect(serializedData.meta).to.be.undefined;
140145

141146
done();
142147
});
@@ -221,6 +226,7 @@ describe('JSONAPISerializer', function() {
221226
expect(serializedData).to.have.property('attributes').to.have.property('body').to.eql('test body');
222227
expect(serializedData.relationships).to.be.undefined;
223228
expect(serializedData.links).to.be.undefined;
229+
expect(serializedData.meta).to.be.undefined;
224230

225231
done();
226232
});
@@ -242,11 +248,13 @@ describe('JSONAPISerializer', function() {
242248
expect(serializedData[0]).to.have.property('attributes').to.have.property('body').to.eql('article body');
243249
expect(serializedData[0].relationships).to.be.undefined;
244250
expect(serializedData[0].links).to.be.undefined;
251+
expect(serializedData[0].meta).to.be.undefined;
245252
expect(serializedData[1]).to.have.property('type').to.eql('people');
246253
expect(serializedData[1]).to.have.property('id').to.eql('1');
247254
expect(serializedData[1]).to.have.property('attributes').to.have.property('body').to.eql('people body');
248255
expect(serializedData[1].relationships).to.be.undefined;
249256
expect(serializedData[1].links).to.be.undefined;
257+
expect(serializedData[1].meta).to.be.undefined;
250258
done();
251259
});
252260

@@ -455,12 +463,14 @@ describe('JSONAPISerializer', function() {
455463
id: '1',
456464
attributes: { type: 'people', name: 'Roman Nelson' },
457465
relationships: undefined,
466+
meta: undefined,
458467
links: undefined
459468
}, {
460469
type: 'author',
461470
id: '1',
462471
attributes: { type: 'author', firstName: 'Kaley', lastName: 'Maggio' },
463472
relationships: undefined,
473+
meta: undefined,
464474
links: undefined }
465475
]);
466476
done();

Diff for: test/unit/validator.test.js

+18
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ describe('validator', function() {
4444

4545
done();
4646
});
47+
48+
it('incorrect meta', done => {
49+
expect(function() {
50+
validator.validateDynamicTypeOptions({ type: 'test', meta: 'test' });
51+
}).to.throw(Error, "option 'meta' must be an object or a function");
52+
53+
done();
54+
});
4755
});
4856

4957
describe('validateOptions', function() {
@@ -77,6 +85,16 @@ describe('validator', function() {
7785
done();
7886
});
7987

88+
it('incorrect meta', done => {
89+
expect(function() {
90+
validator.validateOptions({
91+
meta: 'test'
92+
});
93+
}).to.throw(Error, "option 'meta' must be an object or a function");
94+
95+
done();
96+
});
97+
8098
it('incorrect blacklistOnDeserialize', done => {
8199
expect(function() {
82100
validator.validateOptions({

0 commit comments

Comments
 (0)