Skip to content

Commit 7202f7d

Browse files
committed
fix linting and apply isAttribute in _deattribute
1 parent 617c11b commit 7202f7d

File tree

8 files changed

+104
-48
lines changed

8 files changed

+104
-48
lines changed

packages/kitsu-core/src/components/deattribute.spec.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import test from 'ava'
22

33
import { deattribute } from '../index.js'
4+
import { ResourceObject } from '../resources/resourceObject.js'
45

5-
test('deattribute', t => {
6+
test('deattributes a valid ResourceObject', t => {
67
t.deepEqual(
78
deattribute({
89
id: '1',
@@ -35,7 +36,7 @@ test('deattribute', t => {
3536
)
3637
})
3738

38-
test('deattribute with attributes.attributes', t => {
39+
test('deattributes a ResourceObject when attributes has the key "attributes"', t => {
3940
t.deepEqual(
4041
deattribute({
4142
id: '2',
@@ -60,7 +61,7 @@ test('deattribute with attributes.attributes', t => {
6061
)
6162
})
6263

63-
test('deattribute array', t => {
64+
test('deattributes arrays of ResourceObject', t => {
6465
t.deepEqual(
6566
deattribute([
6667
{
@@ -88,3 +89,20 @@ test('deattribute array', t => {
8889
]
8990
)
9091
})
92+
93+
// subject to change
94+
const fun = () => 'im a function'
95+
test('performs no operation on a ResourceObject with invalid attributes', t => {
96+
t.deepEqual(
97+
deattribute({
98+
id: '1',
99+
type: 'test',
100+
attributes: fun
101+
} as ResourceObject),
102+
{
103+
id: '1',
104+
type: 'test',
105+
attributes: fun
106+
}
107+
)
108+
})
Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,46 @@
1-
import { Attributes, isAttributes } from "../resources/attributes.js";
2-
import { ResourceIdentifier } from "../resources/resource-identifier.js";
3-
import { ResourceObject } from "../resources/resource-object.js";
1+
import { Attributes, isAttributes } from '../resources/attributes.js'
2+
import { ResourceIdentifier } from '../resources/resourceIdentifier.js'
3+
import { ResourceObject } from '../resources/resourceObject.js'
44

5-
export type DeattributedResourceObject = ResourceIdentifier & Attributes;
5+
export type DeattributedResourceObject = ResourceIdentifier & Attributes
66

77
// Write a function that hoists the attributes of a given object to the top level
8-
export function deattribute(data: ResourceObject): DeattributedResourceObject;
9-
export function deattribute(data: ResourceObject[]): DeattributedResourceObject[];
10-
export function deattribute(data: ResourceObject | ResourceObject[]): DeattributedResourceObject | DeattributedResourceObject[] {
11-
return isResourceObjectArray(data) ? data.map(_deattribute) : _deattribute(data);
8+
export function deattribute(data: ResourceObject): DeattributedResourceObject
9+
export function deattribute(
10+
data: ResourceObject[]
11+
): DeattributedResourceObject[]
12+
export function deattribute(
13+
data: ResourceObject | ResourceObject[]
14+
): DeattributedResourceObject | DeattributedResourceObject[] {
15+
return isResourceObjectArray(data)
16+
? data.map(_deattribute)
17+
: _deattribute(data)
1218
}
1319

1420
function _deattribute(data: ResourceObject): DeattributedResourceObject {
21+
// FIXME: what is the best behaviour when given an invalid attributes key?
22+
// 1. (Current) the same invalid object is returned.
23+
// a. This results in deattribute returning potentially invalid DeattributedResourceObjects
24+
// 2. the object is modified, and has the invalid key removed
25+
// a. This would guarantee valid returns, but will also change the current default behaviour.
26+
// 3. the object is not touched, and an error is thrown
27+
// a. this would function closer to how JSON.parse does, throwing errors when unexpected input is given
28+
//
29+
// This should not be an issue for projects using typescript natively, since the compiler will warn when passing
30+
// objects with mismatched types to deattribute
31+
if (!isAttributes(data.attributes)) return data as DeattributedResourceObject
32+
1533
const output = {
1634
...data,
1735
...data.attributes
1836
}
1937

2038
if (output.attributes === data.attributes) delete output.attributes
21-
return output;
39+
return output
2240
}
2341

24-
function isResourceObjectArray(obj: ResourceObject | ResourceObject[]): obj is ResourceObject[] {
25-
return Array.isArray(obj)
42+
function isResourceObjectArray(
43+
object: ResourceObject | ResourceObject[]
44+
): object is ResourceObject[] {
45+
return Array.isArray(object)
2646
}

packages/kitsu-core/src/components/deepEqual.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,25 @@ const people = {
2525
five: {
2626
address: {
2727
street: '123 Main St',
28-
inhabitants: ['Chuck', 'Howard', {name: "Jimmy", age: 35}]
28+
inhabitants: ['Chuck', 'Howard', { name: 'Jimmy', age: 35 }]
2929
}
3030
},
3131
six: {
3232
address: {
3333
street: '123 Main St',
34-
inhabitants: ['Chuck', 'Howard', {name: "Jimmy", age: 35}]
34+
inhabitants: ['Chuck', 'Howard', { name: 'Jimmy', age: 35 }]
3535
}
3636
},
3737
seven: {
3838
address: {
3939
street: '456 Main St',
40-
inhabitants: ['Chuck', 'Howard', {name: "Jimmy", age: 35}]
40+
inhabitants: ['Chuck', 'Howard', { name: 'Jimmy', age: 35 }]
4141
}
4242
},
4343
eight: {
4444
address: {
4545
street: '123 Main St',
46-
inhabitants: ['Howard', {name: "Jimmy", age: 35}, 'Chuck']
46+
inhabitants: ['Howard', { name: 'Jimmy', age: 35 }, 'Chuck']
4747
}
4848
}
4949
}

packages/kitsu-core/src/components/deepEqual.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
export const isDeepEqual = (left: any, right: any) => {
1+
// isDeepEqual is able to compare every possible input, so we allow explicit any
2+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3+
type Comparable = any
4+
5+
export function isDeepEqual(left: Comparable, right: Comparable): boolean {
26
if (!left || !right) return left === right
37

48
const leftKeys = Object.keys(left)
@@ -12,14 +16,17 @@ export const isDeepEqual = (left: any, right: any) => {
1216

1317
const isObjects = isObject(leftValue) && isObject(rightValue)
1418

15-
if ((isObjects && !isDeepEqual(leftValue, rightValue)) || (!isObjects && leftValue !== rightValue)) {
19+
if (
20+
(isObjects && !isDeepEqual(leftValue, rightValue)) ||
21+
(!isObjects && leftValue !== rightValue)
22+
) {
1623
return false
1724
}
1825
}
1926

2027
return true
2128
}
2229

23-
function isObject(obj: any): obj is object {
24-
return obj != undefined && typeof obj === 'object'
30+
function isObject(object: unknown): object is object {
31+
return object != undefined && typeof object === 'object'
2532
}

packages/kitsu-core/src/resources/attributes.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,25 @@
66

77
// Valid JSON values
88
// https://datatracker.ietf.org/doc/html/rfc8259#section-3
9-
export type JsonValues = object | number | string | false | null | true | Array<JsonValues>;
9+
export type JsonValues =
10+
| object
11+
| number
12+
| string
13+
| false
14+
| null
15+
| true
16+
| Array<JsonValues>
1017

1118
// https://datatracker.ietf.org/doc/html/rfc8259#section-4
1219
// "A name is a string"
1320
export interface Attributes {
14-
[name: string]: JsonValues;
21+
[name: string]: JsonValues
1522
}
1623

17-
export function isAttributes(attrs: any): attrs is Attributes {
18-
return typeof attrs.attributes === 'object' &&
19-
attrs.attributes !== null &&
20-
!Array.isArray(attrs.attributes)
24+
export function isAttributes(attributes: unknown): attributes is Attributes {
25+
return (
26+
typeof attributes === 'object' &&
27+
attributes !== null &&
28+
!Array.isArray(attributes)
29+
)
2130
}

packages/kitsu-core/src/resources/resource-object.ts

Lines changed: 0 additions & 15 deletions
This file was deleted.

packages/kitsu-core/src/resources/resource-identifier.ts renamed to packages/kitsu-core/src/resources/resourceIdentifier.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
// > The value of the lid member MUST be identical for every representation of the resource in the document, including resource identifier objects.
77

88
export interface LocalResourceIdentifier {
9-
lid: string;
10-
type: string;
9+
lid: string
10+
type: string
1111
}
1212

1313
export interface RemoteResourceIdentifier {
14-
id: string;
15-
type: string;
14+
id: string
15+
type: string
1616
}
1717

18-
export type ResourceIdentifier = LocalResourceIdentifier | RemoteResourceIdentifier;
18+
export type ResourceIdentifier =
19+
| LocalResourceIdentifier
20+
| RemoteResourceIdentifier
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Attributes } from './attributes.js'
2+
import { ResourceIdentifier } from './resource-identifier.js'
3+
4+
type Relationships = void
5+
type Links = void
6+
type Meta = void
7+
8+
export interface ResourceObjectFields {
9+
attributes?: Attributes
10+
relationships?: Relationships
11+
links?: Links
12+
meta?: Meta
13+
}
14+
15+
export type ResourceObject = ResourceObjectFields & ResourceIdentifier

0 commit comments

Comments
 (0)