Skip to content

Commit

Permalink
Merge pull request #1 from lysyi3m/feature/multi-relationships
Browse files Browse the repository at this point in the history
Add support for multiple relationships extracting
  • Loading branch information
lysyi3m authored Mar 3, 2020
2 parents c63d0f9 + 3e8546a commit db2cbd8
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 10 deletions.
55 changes: 45 additions & 10 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,47 @@
import { isArray, isEmpty, isNil, find, isPlainObject, camelCase } from 'lodash'

/**
* Extract data relationships using id-type mapping of realtionship object with included entities
* Get single relationship data using id-type mapping of resource relationship object
* @param {object} relationship - resource relationship object
* @param {Array} included - included resources from JSON:API response
* @returns {object} - relationship data
*/
export function getRelationshipData (relationship, included) {
if (isNil(relationship) || isEmpty(relationship)) {
return
}

if (isNil(included) || isEmpty(included)) {
return
}

const resource = find(included, { id: relationship.id, type: relationship.type })

if (isNil(resource) || isEmpty(resource)) {
return
}

const {
attributes,
id,
links,
meta
} = resource

return Object.assign({}, { id, links, meta }, attributes)
}

/**
* Extract data relationships using id-type mapping of resource realtionships object with included entities
* @param {object} relationships - resource relationships object
* @param {Array} included - included resources from JSON:API response
* @returns {object} - extracted relationships data
*/
export function extractRelationships (relationships, included) {
if (isNil(relationships) || isEmpty(relationships)) {
return
}

if (isNil(included) || isEmpty(included)) {
return
}
Expand All @@ -20,13 +55,13 @@ export function extractRelationships (relationships, included) {
return
}

const { attributes } = find(included, { id: data.id, type: data.type }) || {}

if (isNil(attributes) || isEmpty(attributes)) {
return
if (isArray(data)) {
extractedRelationships[key] = data.map(elem => getRelationshipData(elem, included))
}

extractedRelationships[key] = Object.assign({}, { id: data.id }, attributes)
if (isPlainObject(data)) {
extractedRelationships[key] = getRelationshipData(data, included)
}
})

return extractedRelationships
Expand All @@ -42,14 +77,14 @@ export function processData ({ data, included }) {

return dataArray.map(elem => {
const {
attributes = {},
attributes,
id,
links,
meta,
relationships = {}
relationships
} = elem

const extractedRelationships = extractRelationships(relationships, included) || {}
const extractedRelationships = extractRelationships(relationships, included)

return Object.assign({}, { id, links, meta }, attributes, extractedRelationships)
})
Expand All @@ -65,7 +100,7 @@ export function processData ({ data, included }) {
*/
export function camelizeData (data) {
if (isArray(data)) {
return data.map(elem => camelizeData(elem))
return data.map(camelizeData)
}

if (isPlainObject(data)) {
Expand Down
49 changes: 49 additions & 0 deletions tests/exctractRelationships.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,55 @@ describe('extractRelationships()', () => {
})
})

test('correctly map multiple relationships using provided included resources', () => {
const relationships = {
author: {
data: { type: 'authors', id: '9' }
},
tags: {
data: [
{ type: 'tags', id: '1' },
{ type: 'tags', id: '2' }
]
}
}

const included = [
{
id: '9',
type: 'authors',
attributes: {
name: 'Bob'
}
},
{
id: '1',
type: 'tags',
attributes: {
title: 'Book'
}
},
{
id: '2',
type: 'tags',
attributes: {
title: 'Novel'
}
}
]

expect(extractRelationships(relationships, included)).toMatchObject({
author: {
id: '9',
name: 'Bob'
},
tags: [
{ id: '1', title: 'Book' },
{ id: '2', title: 'Novel' }
]
})
})

test('return nothing if included resources are not provided', () => {
const relationships = {
author: {
Expand Down
28 changes: 28 additions & 0 deletions tests/getRelationshipData.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { getRelationshipData } from '../src'

describe('getRelationshipData()', () => {
test('return correct relationship data for provided relationship', () => {
const relationship = { type: 'authors', id: '9' }

const included = [
{
id: '9',
type: 'authors',
attributes: {
name: 'Bob'
}
}
]

expect(getRelationshipData(relationship, included)).toMatchObject({
id: '9',
name: 'Bob'
})
})

test('return nothing if included resources are not provided', () => {
const relationship = { type: 'authors', id: '9' }

expect(getRelationshipData(relationship)).toBeUndefined()
})
})

0 comments on commit db2cbd8

Please sign in to comment.