-
Notifications
You must be signed in to change notification settings - Fork 3
/
jsonApi.interface.ts
158 lines (133 loc) · 4.19 KB
/
jsonApi.interface.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import { ContentType } from '@coolio/http';
export interface Attributes {
[x: string]: any;
}
export type RelationshipData<Type extends string = string> = {
id: string;
type: Type;
};
export type RelationshipType<Type extends string = string> = RelationshipData<Type> | RelationshipData<Type>[];
type RawRelationship<T> = {
data: T;
links?: {
self?: string;
related: string;
};
related?: string;
};
export type Relationship = RawRelationship<RelationshipData>;
export type RelationshipArray = RawRelationship<RelationshipData[]>;
export type ResolvedRelationship<D extends AnyData = AnyData> = RawRelationship<D>;
export type ResolvedRelationshipArray<D extends AnyData = AnyData> = RawRelationship<D[]>;
export type Relationships = Record<string, RawRelationship<RelationshipType> | undefined>;
export type UnresolvedRelationships = Record<string, Relationship | RelationshipArray>;
export type ResolvedRelationships = Record<string, ResolvedRelationship | ResolvedRelationshipArray | undefined>;
export type OptionalRels = Relationships | undefined;
export type IncludedRelationships<D extends AnyData = AnyData> = D[];
export interface Data<Attrs extends Attributes, Rels extends OptionalRels = {}> {
id: string;
type: string;
attributes: Attrs;
relationships: Rels;
links: {
self: string;
};
}
export type AnyData = Data<any, any>;
type EmptyRecord = { [key: string]: never };
export type AttributesOf<D> = D extends { attributes: Attributes } ? D['attributes'] : EmptyRecord;
export type RelationshipsOf<D> = D extends { relationships: Relationships } ? D['relationships'] : EmptyRecord;
/**
* MergeData type
* --------------
* This sophisticated type allows to correctly infer nicely formatted data from JSON API format.
* `id`, `type`, `attributes` and `relationships` suddenly become a single, combined object with easy access to it.
* Same is applied to arrays.
*/
export type MergedData<D> =
D extends AnyData ? (
& AttributesOf<D>
& (
RelationshipsOf<D> extends Relationships
? { [k in keyof RelationshipsOf<D>]: MergedData<RelationshipsOf<D>[k]['data']> }
: RelationshipsOf<D>
)
& ({
id: string;
type: string;
self: string;
})
) : D extends AnyData[] ? (
& AttributesOf<D[0]>
& (
RelationshipsOf<D[0]> extends Relationships
? { [k in keyof RelationshipsOf<D[0]>]: MergedData<RelationshipsOf<D[0]>[k]['data']> }
: RelationshipsOf<D[0]>
)
& ({
id: string;
type: string;
self: string;
})
)[] : (
D extends RelationshipData ? D['id'] : D extends RelationshipData[] ? D[0]['id'][] : never
);
export interface ListMetaData {
totalResourceCount: number;
}
/**
* Included groups
* ---------------
* Included groups allow you to extract stuff from 'included' JSON API field
* basing on specified name-type pairs, and add proper types to it.
*
*/
export interface IncludedGroup<D extends AnyData = AnyData> {
type: string;
__d: D;
}
export type IncludedGroupsSchema = Record<string, IncludedGroup>;
export type IncludedGroups<Groups extends IncludedGroupsSchema = IncludedGroupsSchema>
= { [k in keyof Groups]: Groups[k]['__d'][] };
export type MergedIncludedGroups<G extends IncludedGroups<any>> = { [k in keyof G]: MergedData<G[k]> };
/*
* RawResponse & RawListResponse
* ------------
* These are types covering JSON API responses for single element and multiple elements.
*/
export interface RawResponse<D extends AnyData, M extends {} = {}> {
data: D;
meta?: M;
included?: IncludedRelationships;
}
export interface RawListResponse<D extends AnyData, M extends ListMetaData = ListMetaData> {
data: D[];
links: {
first: string;
next?: string;
prev?: string;
last: string;
};
included?: IncludedRelationships;
meta: M;
}
export const Headers = {
'Content-Type': ContentType.VND_JSON,
'Accept': ContentType.VND_JSON,
};
/**
* @deprecated It is not part of JSON API and is not supported in when array of keys is passed
*/
export enum FilterOperator {
EQUALS = 'EQ',
NOT_EQUALS = 'NEQ',
LIKE = 'LIKE',
GREATER = 'GT',
LOWER = 'LT',
GREATER_OR_EQUAL = 'GE',
LOWER_OR_EQUAL = 'LE',
}
export enum SortOrder {
ASCENDING = '',
DESCENDING = '-',
}