Skip to content

Commit

Permalink
Merge 5b313a6 into b016d08
Browse files Browse the repository at this point in the history
  • Loading branch information
danivek committed Oct 12, 2020
2 parents b016d08 + 5b313a6 commit 65163c7
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Serializer.register(type, options);
* **type**: A _string_ or a _function_ `function(relationshipData, data) { ... }` for the type to use for serializing the relationship (type need to be register).
* **alternativeKey** (optional): An alternative key (string or path) to use if relationship key not exist (example: 'author_id' as an alternative key for 'author' relationship). See [issue #12](https://github.com/danivek/json-api-serializer/issues/12).
* **schema** (optional): A custom schema for serializing the relationship. If no schema define, it use the default one.
* **data** (optional): A _function_ `function(data) { ... }` that returns the data to serialize for the relationship.
* **links** (optional): Describes the links for the relationship. 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) { ... }`
Expand Down
7 changes: 6 additions & 1 deletion lib/JSONAPISerializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -716,13 +716,17 @@ module.exports = class JSONAPISerializer {
relationshipKey = relationshipOptions.alternativeKey;
}

const dataFn = relationshipOptions.data
? relationshipOptions.data
: (relationshipData) => relationshipData;

const serializeRelationship = {
links: this.processOptionsValues(data, extraData, relationshipOptions.links),
meta: this.processOptionsValues(data, extraData, relationshipOptions.meta),
data: this.serializeRelationship(
relationshipOptions.type,
relationshipOptions.schema,
get(data, relationshipKey),
dataFn(get(data, relationshipKey)),
included,
data,
extraData,
Expand Down Expand Up @@ -996,6 +1000,7 @@ module.exports = class JSONAPISerializer {
* @property {string|Function} type a string or a function for the type to use for serializing the relationship (type need to be register)
* @property {string} [alternativeKey] an alternative key (string or path) to use if relationship key not exist (example: 'author_id' as an alternative key for 'author' relationship)
* @property {string} [schema] a custom schema for serializing the relationship. If no schema define, it use the default one.
* @property {Function} [data] a function that returns the data to serialize for the relationship
* @property {Function|object} [links] describes the links for the relationship
* @property {Function|object} [meta] describes meta that contains non-standard meta-information about the relationship
* @property {Function} [deserialize] describes the function which should be used to deserialize a related property which is not included in the JSON:API document
Expand Down
3 changes: 3 additions & 0 deletions lib/validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ function validateOptions(options) {

if (relationships[key].deserialize && typeof relationships[key].deserialize !== 'function')
throw new Error(`option 'deserialize' for relationship '${key}' must be a function`);

if (relationships[key].data && typeof relationships[key].data !== 'function')
throw new Error(`option 'data' for relationship '${key}' must be a function`);
});

return options;
Expand Down
31 changes: 31 additions & 0 deletions test/unit/JSONAPISerializer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,37 @@ describe('JSONAPISerializer', function() {
expect(serializedRelationships.author).to.have.property('links').to.be.undefined;
done();
});

it('should return relationships with data option', function(done) {
const Serializer = new JSONAPISerializer();

Serializer.register('article', {
relationships: {
comments: {
type: 'comment',
data: (data) => data.data
}
}
});
Serializer.register('comment');

const serializedRelationships = Serializer.serializeRelationships({
id: '1',
comments: {
total: 2,
data: [{id: '1', title: 'comment 1'}, {id: '2', title: 'comment 2'}]
}
}, Serializer.schemas.article.default);
console.log(JSON.stringify(serializedRelationships, null, 2));
expect(serializedRelationships).to.have.property('comments');
expect(serializedRelationships.comments).to.have.property('data');
expect(serializedRelationships.comments.data).to.be.instanceof(Array).to.have.length(2);
expect(serializedRelationships.comments.data[0]).to.have.property('type').to.eql('comment');
expect(serializedRelationships.comments.data[0]).to.have.property('id').to.be.a('string').to.eql('1');
expect(serializedRelationships.comments.data[1]).to.have.property('id').to.be.a('string').to.eql('2');
expect(serializedRelationships.comments).to.have.property('links').to.be.undefined;
done();
});
});

describe('serializeAttributes', function() {
Expand Down
15 changes: 15 additions & 0 deletions test/unit/validator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,5 +291,20 @@ describe('validator', function () {

done();
});

it('incorrect data on relationship', (done) => {
expect(function () {
validator.validateOptions({
relationships: {
test: {
type: 'test',
data: 'test',
},
},
});
}).to.throw(Error, "option 'data' for relationship 'test' must be a function");

done();
});
});
});

0 comments on commit 65163c7

Please sign in to comment.