Skip to content

Commit cbf50df

Browse files
committed
feat(kitsu-core): preserve links in relationships during deserialisation
BREAKING CHANGE for deserialise and linkRelationships
1 parent 6a73433 commit cbf50df

10 files changed

Lines changed: 766 additions & 400 deletions

File tree

packages/kitsu-core/src/deserialise/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { linkRelationships } from '../linkRelationships'
1111
function deserialiseArray (obj) {
1212
for (let value of obj.data) {
1313
if (obj.included) value = linkRelationships(value, obj.included)
14+
if (value.relationships) value = linkRelationships(value)
1415
if (value.attributes) value = deattribute(value)
1516
obj.data[obj.data.indexOf(value)] = value
1617
}
@@ -62,6 +63,7 @@ export function deserialise (obj) {
6263
if (obj.data && obj.data.constructor === Array) obj = deserialiseArray(obj)
6364
// Single resource with included relationships
6465
else if (obj.included) obj.data = linkRelationships(obj.data, obj.included)
66+
else if (obj.data && obj.data.constructor === Object) obj.data = linkRelationships(obj.data)
6567

6668
delete obj.included
6769

packages/kitsu-core/src/deserialise/index.spec.js

Lines changed: 342 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,11 @@ describe('kitsu-core', () => {
8282
{
8383
name: 'Josh',
8484
waifu: {
85-
name: 'Genkai',
86-
id: '1',
87-
type: 'characters'
85+
data: {
86+
name: 'Genkai',
87+
id: '1',
88+
type: 'characters'
89+
}
8890
},
8991
id: '1',
9092
type: 'users'
@@ -124,9 +126,11 @@ describe('kitsu-core', () => {
124126
data: {
125127
name: 'Josh',
126128
waifu: {
127-
name: 'Genkai',
128-
id: '1',
129-
type: 'characters'
129+
data: {
130+
name: 'Genkai',
131+
id: '1',
132+
type: 'characters'
133+
}
130134
},
131135
id: '1',
132136
type: 'users'
@@ -152,5 +156,337 @@ describe('kitsu-core', () => {
152156
}
153157
})
154158
})
159+
160+
it('deserialises relationships with links', () => {
161+
expect.assertions(1)
162+
expect(deserialise({
163+
data: {
164+
id: '1',
165+
type: 'users',
166+
relationships: {
167+
followers: {
168+
links: {
169+
self: 'https://kitsu.example/users/1/relationships/followers',
170+
related: 'https://kitsu.example/users/1/followers'
171+
}
172+
}
173+
}
174+
}
175+
})).toEqual({
176+
data: {
177+
id: '1',
178+
type: 'users',
179+
followers: {
180+
links: {
181+
self: 'https://kitsu.example/users/1/relationships/followers',
182+
related: 'https://kitsu.example/users/1/followers'
183+
}
184+
}
185+
}
186+
})
187+
})
188+
189+
it('deserialises relationships with links and data (array)', () => {
190+
expect.assertions(1)
191+
192+
const input = deserialise({
193+
data: {
194+
id: '1',
195+
type: 'users',
196+
relationships: {
197+
followers: {
198+
links: {
199+
self: 'https://kitsu.example/users/1/relationships/followers',
200+
related: 'https://kitsu.example/users/1/followers'
201+
},
202+
data: [ {
203+
type: 'follows',
204+
id: '1'
205+
},
206+
{
207+
type: 'follows',
208+
id: '2'
209+
} ]
210+
}
211+
}
212+
},
213+
included: [
214+
{
215+
id: '1',
216+
type: 'follows',
217+
links: {
218+
self: 'https://kitsu.example/follows/1'
219+
},
220+
relationships: {
221+
follower: {
222+
links: {
223+
self: 'https://kitsu.io/follows/1/relationships/follower',
224+
related: 'https://kitsu.io/follows/1/follower'
225+
}
226+
},
227+
followed: {
228+
links: {
229+
self: 'https://kitsu.io/follows/1/relationships/followed',
230+
related: 'https://kitsu.io/follows/1/followed'
231+
}
232+
}
233+
}
234+
},
235+
{
236+
id: '2',
237+
type: 'follows',
238+
links: {
239+
self: 'https://kitsu.example/follows/2'
240+
},
241+
relationships: {
242+
follower: {
243+
links: {
244+
self: 'https://kitsu.io/follows/2/relationships/follower',
245+
related: 'https://kitsu.io/follows/2/follower'
246+
}
247+
},
248+
followed: {
249+
links: {
250+
self: 'https://kitsu.io/follows/2/relationships/followed',
251+
related: 'https://kitsu.io/follows/2/followed'
252+
}
253+
}
254+
}
255+
}
256+
]
257+
})
258+
259+
const output = {
260+
data: {
261+
id: '1',
262+
type: 'users',
263+
followers: {
264+
links: {
265+
self: 'https://kitsu.example/users/1/relationships/followers',
266+
related: 'https://kitsu.example/users/1/followers'
267+
},
268+
data: [
269+
{
270+
id: '1',
271+
type: 'follows',
272+
links: {
273+
self: 'https://kitsu.example/follows/1'
274+
},
275+
follower: {
276+
links: {
277+
self: 'https://kitsu.io/follows/1/relationships/follower',
278+
related: 'https://kitsu.io/follows/1/follower'
279+
}
280+
},
281+
followed: {
282+
links: {
283+
self: 'https://kitsu.io/follows/1/relationships/followed',
284+
related: 'https://kitsu.io/follows/1/followed'
285+
}
286+
}
287+
},
288+
{
289+
id: '2',
290+
type: 'follows',
291+
links: {
292+
self: 'https://kitsu.example/follows/2'
293+
},
294+
follower: {
295+
links: {
296+
self: 'https://kitsu.io/follows/2/relationships/follower',
297+
related: 'https://kitsu.io/follows/2/follower'
298+
}
299+
},
300+
followed: {
301+
links: {
302+
self: 'https://kitsu.io/follows/2/relationships/followed',
303+
related: 'https://kitsu.io/follows/2/followed'
304+
}
305+
}
306+
}
307+
]
308+
}
309+
}
310+
}
311+
312+
expect(input).toEqual(output)
313+
})
314+
315+
it('deserialises relationships with links and data (object)', () => {
316+
expect.assertions(1)
317+
318+
const input = deserialise({
319+
data: {
320+
id: '1',
321+
type: 'users',
322+
relationships: {
323+
waifu: {
324+
links: {
325+
self: 'https://kitsu.example/users/1/relationships/waifu',
326+
related: 'https://kitsu.example/users/1/waifu'
327+
},
328+
data: {
329+
type: 'characters',
330+
id: '1'
331+
}
332+
}
333+
}
334+
},
335+
included: [
336+
{
337+
id: '1',
338+
type: 'characters',
339+
links: {
340+
self: 'https://kitsu.example/characters/1'
341+
},
342+
relationships: {
343+
primaryMedia: {
344+
links: {
345+
self: 'https://kitsu.io/characters/1/relationships/primary-media',
346+
related: 'https://kitsu.io/characters/1/primary-media'
347+
}
348+
}
349+
}
350+
}
351+
]
352+
})
353+
354+
const output = {
355+
data: {
356+
id: '1',
357+
type: 'users',
358+
waifu: {
359+
links: {
360+
self: 'https://kitsu.example/users/1/relationships/waifu',
361+
related: 'https://kitsu.example/users/1/waifu'
362+
},
363+
data: {
364+
id: '1',
365+
type: 'characters',
366+
links: {
367+
self: 'https://kitsu.example/characters/1'
368+
},
369+
primaryMedia: {
370+
links: {
371+
self: 'https://kitsu.io/characters/1/relationships/primary-media',
372+
related: 'https://kitsu.io/characters/1/primary-media'
373+
}
374+
}
375+
}
376+
}
377+
}
378+
}
379+
380+
expect(input).toEqual(output)
381+
})
382+
383+
it('deserialises a relationship used twice or more', () => {
384+
expect.assertions(1)
385+
386+
const input = deserialise({
387+
data: [
388+
{
389+
id: '1',
390+
type: 'anime',
391+
relationships: {
392+
categories: {
393+
links: {
394+
self: 'https://kitsu.example/anime/1/relationships/categories',
395+
related: 'https://kitsu.example/anime/1/categories'
396+
},
397+
data: [
398+
{
399+
type: 'categories',
400+
id: '10'
401+
}
402+
]
403+
}
404+
}
405+
},
406+
{
407+
id: '2',
408+
type: 'anime',
409+
relationships: {
410+
categories: {
411+
links: {
412+
self: 'https://kitsu.example/anime/2/relationships/categories',
413+
related: 'https://kitsu.example/anime/2/categories'
414+
},
415+
data: [
416+
{
417+
type: 'categories',
418+
id: '10'
419+
}
420+
]
421+
}
422+
}
423+
}
424+
],
425+
included: [
426+
{
427+
id: '10',
428+
type: 'categories',
429+
links: {
430+
self: 'https://kitsu.example/categories/10'
431+
}
432+
}
433+
]
434+
})
435+
436+
const output = {
437+
data: [
438+
{
439+
id: '1',
440+
type: 'anime',
441+
categories: {
442+
links: {
443+
self: 'https://kitsu.example/anime/1/relationships/categories',
444+
related: 'https://kitsu.example/anime/1/categories'
445+
},
446+
data: [
447+
{
448+
id: '10',
449+
type: 'categories',
450+
links: {
451+
self: 'https://kitsu.example/categories/10'
452+
}
453+
}
454+
]
455+
}
456+
},
457+
{
458+
id: '2',
459+
type: 'anime',
460+
categories: {
461+
links: {
462+
self: 'https://kitsu.example/anime/2/relationships/categories',
463+
related: 'https://kitsu.example/anime/2/categories'
464+
},
465+
data: [
466+
{
467+
id: '10',
468+
type: 'categories',
469+
links: {
470+
self: 'https://kitsu.example/categories/10'
471+
}
472+
}
473+
]
474+
}
475+
}
476+
]
477+
}
478+
479+
expect(input).toEqual(output)
480+
})
481+
482+
it('deserialises an empty object', () => {
483+
expect.assertions(1)
484+
expect(deserialise({})).toEqual({})
485+
})
486+
487+
it('deserialises an empty array', () => {
488+
expect.assertions(1)
489+
expect(deserialise([])).toEqual([])
490+
})
155491
})
156492
})

0 commit comments

Comments
 (0)