Skip to content

Commit fc0b05d

Browse files
lizzypyjeremygriffinLiz Johnson
authored
feat: links deserialization
Co-authored-by: jgriffin <[email protected]> Co-authored-by: Liz Johnson <[email protected]>
1 parent 09be3b6 commit fc0b05d

File tree

8 files changed

+92
-11
lines changed

8 files changed

+92
-11
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"ts-jest": "^27.1.4",
6767
"ts-node": "^10.7.0",
6868
"type-fest": "^2.12.2",
69-
"typedoc": "^0.22.13",
69+
"typedoc": "^0.23.15",
7070
"typedoc-plugin-markdown": "^3.11.14",
7171
"typescript": "^4.6.3"
7272
},

src/deserializer.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ function parseJsonApiSimpleResourceData<TEntity, TExtraOptions>(
5454
...attributes,
5555
}
5656

57+
if (data.links) {
58+
resource['links'] = data.links
59+
}
60+
5761
if (id) {
5862
includedCache[data.type][id] = resource
5963
}
@@ -71,13 +75,19 @@ function parseJsonApiSimpleResourceData<TEntity, TExtraOptions>(
7175
return findJsonApiIncluded(included, includedCache, relationData.type, relationData.id, options)
7276
})
7377
} else if (relationReference && relationReference.data) {
74-
resource[relationName] = findJsonApiIncluded(
78+
const relationResource = findJsonApiIncluded<Record<string, unknown>, TExtraOptions>(
7579
included,
7680
includedCache,
7781
relationReference.data.type,
7882
relationReference.data.id,
7983
options,
8084
)
85+
86+
if (relationReference.links) {
87+
relationResource.links = relationReference.links
88+
}
89+
90+
resource[relationName] = relationResource
8191
}
8292
}
8393
}

src/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export type AttributesObject = JsonObject
1818

1919
export type MetaObject = JsonObject
2020

21+
export type LinkObject = JsonObject
22+
2123
export type ResourceIdentifierObject = {
2224
type: string
2325
id: string
@@ -26,6 +28,7 @@ export type ResourceIdentifierObject = {
2628
export type ExistingResourceObject = ResourceIdentifierObject & {
2729
id: string
2830
attributes: AttributesObject
31+
links?: LinkObject
2932
relationships?: Record<string, RelationshipObject>
3033
}
3134

@@ -35,6 +38,7 @@ export type ResourceObject = ExistingResourceObject | NewResourceObject
3538

3639
export type RelationshipObject = {
3740
data: ResourceIdentifierObject | ResourceIdentifierObject[]
41+
links?: LinkObject
3842
}
3943

4044
export enum CaseType {

tests/deserialize.spec.ts

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ describe('deserialize', () => {
3939
],
4040
}
4141

42-
expect(deserialize(serialized, { changeCase: CaseType.camelCase })).toEqual([
42+
expect(deserialize(serialized, { changeCase: CaseType.camelCase })).toStrictEqual([
4343
{
4444
id: '1',
4545
firstName: 'Joe',
@@ -52,4 +52,71 @@ describe('deserialize', () => {
5252
},
5353
])
5454
})
55+
56+
it('deserialize includes links', () => {
57+
const serialized: DocumentObject = {
58+
data: [
59+
{
60+
type: 'users',
61+
id: '1',
62+
attributes: {
63+
'first-name': 'Joe',
64+
'last-name': 'Doe',
65+
},
66+
links: {
67+
self: 'https://example.org/users/1',
68+
action: 'https://example.org/action',
69+
},
70+
relationships: {
71+
address: {
72+
data: {
73+
type: 'addr',
74+
id: '1',
75+
},
76+
links: {
77+
self: 'https://example.org/address/1/relationships/address',
78+
related: 'https://example.org/address/1',
79+
},
80+
},
81+
images: {
82+
data: [
83+
{ type: 'img', id: '1' },
84+
{ type: 'img', id: '2' },
85+
],
86+
},
87+
},
88+
},
89+
],
90+
included: [
91+
{
92+
type: 'addr',
93+
id: '1',
94+
attributes: {
95+
street: 'Street 1',
96+
},
97+
},
98+
],
99+
}
100+
101+
expect(deserialize(serialized, { changeCase: CaseType.camelCase })).toStrictEqual([
102+
{
103+
id: '1',
104+
firstName: 'Joe',
105+
lastName: 'Doe',
106+
links: {
107+
self: 'https://example.org/users/1',
108+
action: 'https://example.org/action',
109+
},
110+
address: {
111+
id: '1',
112+
street: 'Street 1',
113+
links: {
114+
self: 'https://example.org/address/1/relationships/address',
115+
related: 'https://example.org/address/1',
116+
},
117+
},
118+
images: [{ id: '1' }, { id: '2' }],
119+
},
120+
])
121+
})
55122
})

tests/examples.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ describe('examples', () => {
3434
const script = new vm.Script(scriptText)
3535
script.runInContext(context)
3636

37-
expect(JSON.parse(result)).toEqual(JSON.parse(resultComment))
37+
expect(JSON.parse(result)).toStrictEqual(JSON.parse(resultComment))
3838
})
3939
})

tests/serialize.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ describe('serialize', () => {
2828
it('should do simple transformation', () => {
2929
const serialized = serialize(validEntity, 'users', validOptions)
3030

31-
expect(serialized).toEqual({
31+
expect(serialized).toStrictEqual({
3232
data: {
3333
type: 'users',
3434
attributes: {
@@ -56,7 +56,7 @@ describe('serialize', () => {
5656
it('should accept undefined options', () => {
5757
const serialized = serialize(validEntity, 'users')
5858

59-
expect(serialized).toEqual(
59+
expect(serialized).toStrictEqual(
6060
expect.objectContaining({
6161
data: expect.objectContaining({
6262
attributes: expect.objectContaining({
@@ -70,7 +70,7 @@ describe('serialize', () => {
7070
it('should accept empty entity', () => {
7171
const serialized = serialize(undefined, 'users')
7272

73-
expect(serialized).toEqual({
73+
expect(serialized).toStrictEqual({
7474
// eslint-disable-next-line unicorn/no-null
7575
data: null,
7676
})
@@ -79,7 +79,7 @@ describe('serialize', () => {
7979
it('should accept entity array', () => {
8080
const serialized = serialize([validEntity], 'users')
8181

82-
expect(serialized).toEqual(
82+
expect(serialized).toStrictEqual(
8383
expect.objectContaining({
8484
data: [
8585
expect.objectContaining({
@@ -99,7 +99,7 @@ describe('serialize', () => {
9999
},
100100
})
101101

102-
expect(serialized).toEqual({
102+
expect(serialized).toStrictEqual({
103103
data: {
104104
id: 5,
105105
type: 'users',

tests/transformer.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ describe('transform', () => {
105105
.withOptions({ idKey: '_id' })
106106
.serialize()
107107

108-
expect(entitySerialized).toEqual({
108+
expect(entitySerialized).toStrictEqual({
109109
data: {
110110
type: 'users',
111111
id: 1,

tests/utils.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ describe('changeCase', () => {
2121
})
2222

2323
it('should deep convert keys', () => {
24-
expect(changeCase(input, CaseType.kebabCase, true)).toEqual({
24+
expect(changeCase(input, CaseType.kebabCase, true)).toStrictEqual({
2525
'first-name': 'Joe',
2626
'last-name': 'Doe',
2727
address: {

0 commit comments

Comments
 (0)