sarala-json-api-data-formatter
Advanced tools
Comparing version
{ | ||
"extends": "standard", | ||
"rules": { | ||
"indent": [2, 4], | ||
"semi": ["error", "always"] | ||
"indent": [2, 4] | ||
} | ||
} | ||
} |
module.exports = { | ||
testURL: "http://localhost", | ||
collectCoverageFrom: [ | ||
@@ -6,2 +7,2 @@ "src/*.js", | ||
] | ||
}; | ||
} |
{ | ||
"name": "sarala-json-api-data-formatter", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"description": "Simple and fluent framework agnostic javascript library to transform standard JSON API responses to simple JSON objects and vice versa.", | ||
@@ -43,11 +43,11 @@ "main": "build/index.js", | ||
"babel-preset-latest": "^6.24.1", | ||
"codecov": "^3.0.1", | ||
"codecov": "^3.1.0", | ||
"eslint": "^4.19.1", | ||
"eslint-config-standard": "^11.0.0", | ||
"eslint-plugin-import": "^2.11.0", | ||
"eslint-plugin-import": "^2.14.0", | ||
"eslint-plugin-node": "^6.0.1", | ||
"eslint-plugin-promise": "^3.7.0", | ||
"eslint-plugin-promise": "^3.8.0", | ||
"eslint-plugin-standard": "^3.1.0", | ||
"jest": "^22.4.3" | ||
"jest": "^22.4.4" | ||
} | ||
} |
@@ -1,21 +0,21 @@ | ||
import _ from 'lodash'; | ||
import _ from 'lodash' | ||
export default class Formatter { | ||
constructor () { | ||
this.data = {}; | ||
this.includes = null; | ||
this.fields = null; | ||
this.includedData = []; | ||
this.data = {} | ||
this.includes = null | ||
this.fields = null | ||
this.includedData = [] | ||
} | ||
includeOnly (includes = []) { | ||
this.includes = includes; | ||
this.includes = includes | ||
return this; | ||
return this | ||
} | ||
filterFields (fields = {}) { | ||
this.fields = fields; | ||
this.fields = fields | ||
return this; | ||
return this | ||
} | ||
@@ -25,6 +25,6 @@ | ||
if (this.includes === null) { | ||
return true; | ||
return true | ||
} | ||
return _.indexOf(this.includes, relation) > 0; | ||
return _.indexOf(this.includes, relation) > 0 | ||
} | ||
@@ -34,37 +34,37 @@ | ||
if (this.fields === null) { | ||
return true; | ||
return true | ||
} | ||
if (!this.fields.hasOwnProperty(relation)) { | ||
return true; | ||
return true | ||
} | ||
if (_.indexOf(this.fields[relation], field) !== -1) { | ||
return true; | ||
return true | ||
} | ||
return false; | ||
return false | ||
} | ||
deserialize (data) { | ||
this.data = data; | ||
this.data = data | ||
if (_.isArray(data.data)) { | ||
return this.deserializeCollection(data); | ||
return this.deserializeCollection(data) | ||
} | ||
return this.deserializeOne(data.data); | ||
return this.deserializeOne(data.data) | ||
} | ||
deserializeOne (data) { | ||
let formatted = {}; | ||
formatted.id = data.id; | ||
formatted.type = data.type; | ||
let formatted = {} | ||
formatted.id = data.id | ||
formatted.type = data.type | ||
if (data.links) { | ||
formatted.links = data.links; | ||
formatted.links = data.links | ||
} | ||
if (data.meta) { | ||
formatted.meta = data.meta; | ||
formatted.meta = data.meta | ||
} | ||
@@ -74,22 +74,22 @@ | ||
if (this.shouldIncludeField(data.type, key)) { | ||
formatted[key] = value; | ||
formatted[key] = value | ||
} | ||
}); | ||
}) | ||
if (data.relationships) { | ||
formatted.relationships = []; | ||
formatted.relationships = [] | ||
for (var key in data.relationships) { | ||
if (this.shouldIncludeRelation(key)) { | ||
formatted.relationships.push(key); | ||
let relationship = this.mapAndKillProps(data.relationships[key], {}, ['links', 'meta']).to; | ||
formatted.relationships.push(key) | ||
let relationship = this.mapAndKillProps(data.relationships[key], {}, ['links', 'meta']).to | ||
if (_.isArray(data.relationships[key].data)) { | ||
relationship.data_collection = true; | ||
relationship.data = this.resolveRelationCollection(data.relationships[key].data); | ||
relationship.data_collection = true | ||
relationship.data = this.resolveRelationCollection(data.relationships[key].data) | ||
} else if (data.relationships[key].data) { | ||
relationship.data = this.resolveRelation(data.relationships[key].data); | ||
relationship.data = this.resolveRelation(data.relationships[key].data) | ||
} | ||
formatted[key] = relationship; | ||
formatted[key] = relationship | ||
} | ||
@@ -99,17 +99,17 @@ } | ||
return formatted; | ||
return formatted | ||
} | ||
deserializeCollection (data) { | ||
data.data_collection = true; | ||
data.data_collection = true | ||
data.data = _.map(data.data, item => { | ||
return this.deserializeOne(item); | ||
}); | ||
return this.deserializeOne(item) | ||
}) | ||
return data; | ||
return data | ||
} | ||
resolveRelation (data) { | ||
return this.deserializeOne(_.find(this.data.included, data)); | ||
return this.deserializeOne(_.find(this.data.included, data)) | ||
} | ||
@@ -119,4 +119,4 @@ | ||
return _.map(relations, relation => { | ||
return this.resolveRelation(relation); | ||
}); | ||
return this.resolveRelation(relation) | ||
}) | ||
} | ||
@@ -127,29 +127,29 @@ | ||
if (from.hasOwnProperty(prop)) { | ||
to[prop] = from[prop]; | ||
delete from[prop]; | ||
to[prop] = from[prop] | ||
delete from[prop] | ||
} | ||
}); | ||
}) | ||
return { from, to }; | ||
return { from, to } | ||
} | ||
isSerializeableCollection (data) { | ||
return data.hasOwnProperty('data_collection') && data.data_collection === true && _.isArray(data.data); | ||
return data.hasOwnProperty('data_collection') && data.data_collection === true && _.isArray(data.data) | ||
} | ||
serialize (data) { | ||
this.includedData = []; | ||
let serialized = {}; | ||
this.includedData = [] | ||
let serialized = {} | ||
if (this.isSerializeableCollection(data)) { | ||
serialized = this.serializeCollection(data); | ||
serialized = this.serializeCollection(data) | ||
} else { | ||
serialized.data = this.serializeOne(data); | ||
serialized.data = this.serializeOne(data) | ||
} | ||
if (this.includedData.length) { | ||
serialized.included = this.includedData; | ||
serialized.included = this.includedData | ||
} | ||
return serialized; | ||
return serialized | ||
} | ||
@@ -161,8 +161,8 @@ | ||
relationships: {} | ||
}; | ||
} | ||
const mapAndKilled = this.mapAndKillProps(data, serialized, ['id', 'type', 'links', 'meta']); | ||
const mapAndKilled = this.mapAndKillProps(data, serialized, ['id', 'type', 'links', 'meta']) | ||
data = mapAndKilled.from; | ||
serialized = mapAndKilled.to; | ||
data = mapAndKilled.from | ||
serialized = mapAndKilled.to | ||
@@ -172,17 +172,17 @@ if (data.hasOwnProperty('relationships')) { | ||
if (this.shouldIncludeRelation(relationship)) { | ||
let relationshipData = this.mapAndKillProps(data[relationship], {}, ['links', 'meta']).to; | ||
let relationshipData = this.mapAndKillProps(data[relationship], {}, ['links', 'meta']).to | ||
if (this.isSerializeableCollection(data[relationship])) { | ||
relationshipData.data = this.serializeRelationshipCollection(data[relationship].data); | ||
relationshipData.data = this.serializeRelationshipCollection(data[relationship].data) | ||
} else { | ||
relationshipData.data = this.serializeRelationship(data[relationship].data); | ||
relationshipData.data = this.serializeRelationship(data[relationship].data) | ||
} | ||
serialized.relationships[relationship] = relationshipData; | ||
serialized.relationships[relationship] = relationshipData | ||
} | ||
delete data[relationship]; | ||
}); | ||
delete data[relationship] | ||
}) | ||
delete data.relationships; | ||
delete data.relationships | ||
} | ||
@@ -192,31 +192,31 @@ | ||
if (this.shouldIncludeField(serialized.type, key)) { | ||
serialized.attributes[key] = value; | ||
serialized.attributes[key] = value | ||
} | ||
}); | ||
}) | ||
if (_.isEmpty(serialized.relationships)) { | ||
delete serialized.relationships; | ||
delete serialized.relationships | ||
} | ||
return serialized; | ||
return serialized | ||
} | ||
serializeCollection (data) { | ||
const mapAndKilled = this.mapAndKillProps(data, {}, ['links', 'meta']); | ||
const mapAndKilled = this.mapAndKillProps(data, {}, ['links', 'meta']) | ||
data = mapAndKilled.from; | ||
let serialized = mapAndKilled.to; | ||
data = mapAndKilled.from | ||
let serialized = mapAndKilled.to | ||
serialized.data = _.map(data.data, item => { | ||
return this.serializeOne(item); | ||
}); | ||
return this.serializeOne(item) | ||
}) | ||
return serialized; | ||
return serialized | ||
} | ||
serializeRelationship (data) { | ||
const serialized = this.serializeOne(data); | ||
this.addToIncludes(serialized); | ||
const serialized = this.serializeOne(data) | ||
this.addToIncludes(serialized) | ||
return { type: serialized.type, id: serialized.id }; | ||
return { type: serialized.type, id: serialized.id } | ||
} | ||
@@ -226,4 +226,4 @@ | ||
return _.map(data, item => { | ||
return this.serializeRelationship(item); | ||
}); | ||
return this.serializeRelationship(item) | ||
}) | ||
} | ||
@@ -233,5 +233,5 @@ | ||
if (_.isUndefined(_.find(this.includedData, { id: data.id, type: data.type }))) { | ||
this.includedData.push(data); | ||
this.includedData.push(data) | ||
} | ||
} | ||
} |
@@ -1,5 +0,5 @@ | ||
import Formatter from './Formatter'; | ||
import Formatter from './Formatter' | ||
export { | ||
Formatter | ||
}; | ||
} |
@@ -1,22 +0,22 @@ | ||
import Formatter from './../src/Formatter'; | ||
import Formatter from './../src/Formatter' | ||
let formatter = null; | ||
let formatter = null | ||
beforeEach(() => { | ||
formatter = new Formatter(); | ||
}); | ||
formatter = new Formatter() | ||
}) | ||
test('it initialize with clean properties', () => { | ||
expect(formatter.data).toEqual({}); | ||
expect(formatter.includes).toBeNull(); | ||
expect(formatter.fields).toBeNull(); | ||
}); | ||
expect(formatter.data).toEqual({}) | ||
expect(formatter.includes).toBeNull() | ||
expect(formatter.fields).toBeNull() | ||
}) | ||
test('includeOnly will set includes to be processed and returns chainable formatter object', () => { | ||
const includes = ['author', 'tags', 'comments']; | ||
const chainable = formatter.includeOnly(includes); | ||
const includes = ['author', 'tags', 'comments'] | ||
const chainable = formatter.includeOnly(includes) | ||
expect(chainable.includes).toEqual(includes); | ||
expect(chainable).toBeInstanceOf(Formatter); | ||
}); | ||
expect(chainable.includes).toEqual(includes) | ||
expect(chainable).toBeInstanceOf(Formatter) | ||
}) | ||
@@ -27,16 +27,16 @@ test('filterFields will set fields to be processed and returns chainable formatter object', () => { | ||
tags: ['name'] | ||
}; | ||
} | ||
const chainable = formatter.filterFields(fields); | ||
const chainable = formatter.filterFields(fields) | ||
expect(chainable.fields).toEqual(fields); | ||
expect(chainable).toBeInstanceOf(Formatter); | ||
}); | ||
expect(chainable.fields).toEqual(fields) | ||
expect(chainable).toBeInstanceOf(Formatter) | ||
}) | ||
test('shouldIncludeRelation verifies whether given relationship is in the includes list', () => { | ||
const includes = ['author', 'tags', 'comments']; | ||
formatter.includeOnly(includes); | ||
const includes = ['author', 'tags', 'comments'] | ||
formatter.includeOnly(includes) | ||
expect(formatter.shouldIncludeRelation('tags')).toBeTruthy(); | ||
expect(formatter.shouldIncludeRelation('unicorn')).toBeFalsy(); | ||
}); | ||
expect(formatter.shouldIncludeRelation('tags')).toBeTruthy() | ||
expect(formatter.shouldIncludeRelation('unicorn')).toBeFalsy() | ||
}) |
@@ -19,3 +19,3 @@ export const Post = { | ||
} | ||
}; | ||
} | ||
@@ -51,3 +51,3 @@ export const PostWithRelationalLinks = { | ||
} | ||
}; | ||
} | ||
@@ -214,3 +214,3 @@ export const PostWithAllNesterRelations = { | ||
] | ||
}; | ||
} | ||
@@ -291,3 +291,3 @@ export const PaginatedPostsList = { | ||
} | ||
}; | ||
} | ||
@@ -1102,2 +1102,2 @@ export const PaginatedPostsListWithAllNesterRelations = { | ||
} | ||
}; | ||
} |
@@ -13,3 +13,3 @@ export const Post = { | ||
} | ||
}; | ||
} | ||
@@ -90,2 +90,2 @@ export const PaginatedPostsList = { | ||
} | ||
}; | ||
} |
@@ -15,3 +15,3 @@ export const Post = { | ||
} | ||
}; | ||
} | ||
@@ -85,3 +85,3 @@ export const PaginatedPostsList = { | ||
} | ||
}; | ||
} | ||
@@ -207,3 +207,3 @@ export const PostWithAllNesterRelations = { | ||
} | ||
}; | ||
} | ||
@@ -237,2 +237,2 @@ export const PostWithRelationalLinks = { | ||
} | ||
}; | ||
} |
@@ -1,2 +0,2 @@ | ||
import Formatter from './../src/Formatter'; | ||
import Formatter from './../src/Formatter' | ||
@@ -8,3 +8,3 @@ import { | ||
PaginatedPostsList as ApiPaginatedPostsList | ||
} from './data/json-api-responce'; | ||
} from './data/json-api-responce' | ||
@@ -16,28 +16,28 @@ import { | ||
PaginatedPostsList as SimplePaginatedPostsList | ||
} from './data/simple-object'; | ||
} from './data/simple-object' | ||
let formatter = null; | ||
let formatter = null | ||
beforeEach(() => { | ||
formatter = new Formatter(); | ||
}); | ||
formatter = new Formatter() | ||
}) | ||
test('it deserialize single object', () => { | ||
const result = formatter.deserialize(ApiPost); | ||
expect(result).toEqual(SimplePost); | ||
}); | ||
const result = formatter.deserialize(ApiPost) | ||
expect(result).toEqual(SimplePost) | ||
}) | ||
test('it deserialize related resource object when the data is not present', () => { | ||
const result = formatter.deserialize(ApiPostWithRelationalLinks); | ||
expect(result).toEqual(SimplePostWithRelationalLinks); | ||
}); | ||
const result = formatter.deserialize(ApiPostWithRelationalLinks) | ||
expect(result).toEqual(SimplePostWithRelationalLinks) | ||
}) | ||
test('it deserialize single object with relationships', () => { | ||
const result = formatter.deserialize(ApiPostWithAllNesterRelations); | ||
expect(result).toEqual(SimplePostWithAllNesterRelations); | ||
}); | ||
const result = formatter.deserialize(ApiPostWithAllNesterRelations) | ||
expect(result).toEqual(SimplePostWithAllNesterRelations) | ||
}) | ||
test('it deserialize collection of objects', () => { | ||
const result = formatter.deserialize(ApiPaginatedPostsList); | ||
expect(result).toEqual(SimplePaginatedPostsList); | ||
}); | ||
const result = formatter.deserialize(ApiPaginatedPostsList) | ||
expect(result).toEqual(SimplePaginatedPostsList) | ||
}) |
@@ -1,2 +0,2 @@ | ||
import Formatter from './../src/Formatter'; | ||
import Formatter from './../src/Formatter' | ||
@@ -7,3 +7,3 @@ import { | ||
PaginatedPostsList as ApiPaginatedPostsList | ||
} from './data/json-api-responce'; | ||
} from './data/json-api-responce' | ||
@@ -14,24 +14,24 @@ import { | ||
PaginatedPostsList as SimplePaginatedPostsList | ||
} from './data/simple-object'; | ||
} from './data/simple-object' | ||
let formatter = null; | ||
let formatter = null | ||
beforeEach(() => { | ||
formatter = new Formatter(); | ||
}); | ||
formatter = new Formatter() | ||
}) | ||
test('it serialize single object', () => { | ||
const result = formatter.serialize(SimplePost); | ||
expect(result).toEqual(ApiPost); | ||
}); | ||
const result = formatter.serialize(SimplePost) | ||
expect(result).toEqual(ApiPost) | ||
}) | ||
test('it serialize single object with relationships', () => { | ||
const result = formatter.serialize(SimplePostWithAllNesterRelations); | ||
expect(result.data).toEqual(ApiPostWithAllNesterRelations.data); | ||
expect(result.included.length).toEqual(ApiPostWithAllNesterRelations.included.length); | ||
}); | ||
const result = formatter.serialize(SimplePostWithAllNesterRelations) | ||
expect(result.data).toEqual(ApiPostWithAllNesterRelations.data) | ||
expect(result.included.length).toEqual(ApiPostWithAllNesterRelations.included.length) | ||
}) | ||
test('it serialize collection of objects', () => { | ||
const result = formatter.serialize(SimplePaginatedPostsList); | ||
expect(result).toEqual(ApiPaginatedPostsList); | ||
}); | ||
const result = formatter.serialize(SimplePaginatedPostsList) | ||
expect(result).toEqual(ApiPaginatedPostsList) | ||
}) |
77933
-11.37%13
-13.33%1717
-11.68%