This repository has been archived by the owner on Oct 7, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 13
/
hal-resource.ts
160 lines (141 loc) · 4.8 KB
/
hal-resource.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
159
160
import { DefaultSerializer, IJSONSerializer } from "./hal-json-serializer";
import { IHalResource, IHalResourceConstructor } from "./hal-resource-interface";
import { HalRestClient } from "./hal-rest-client";
import { URI } from "./uri";
export class HalResource implements IHalResource {
public readonly links = {};
public readonly props = {};
public isLoaded = false;
protected restClient: HalRestClient;
private readonly settedProps = [];
private readonly settedLinks = [];
private initEnded = false;
constructor(restClient: HalRestClient|HalResource, protected _uri ?: URI) {
if (restClient instanceof HalRestClient) {
this.restClient = restClient;
} else {
this.restClient = restClient.restClient;
this.links = restClient.links;
this.props = restClient.props;
this.settedLinks = restClient.settedLinks;
this.settedProps = restClient.settedProps;
this._uri = restClient._uri;
}
}
public fetch(forceOrParams ?: boolean|object): Promise<this> {
if ((this.isLoaded && !forceOrParams) || this.uri === undefined) {
return new Promise((resolve) => resolve(this));
} else {
return this.restClient.fetch(
this.uri.fill(forceOrParams as object),
this.constructor as IHalResourceConstructor<this>,
this,
) as Promise<this>;
}
}
/**
* to clear value use null not undefined
*/
public prop(name: string, value ?: any): any {
if (value !== void 0) {
if (this.links[name]) {
this.link(name, value);
} else {
this.props[name] = value;
if (this.initEnded) {
this.settedProps.push(name);
}
}
return this;
} else {
if (this.props[name] !== undefined) {
return this.props[name];
} else if (this.links[name]) {
return this.link(name);
}
}
}
set uri(uri: URI) {
this._uri = uri;
}
get uri(): URI {
return this._uri;
}
/**
* to clear value use null not undefined
*/
public link(name: string, value ?: any): any {
if (value !== void 0) {
this.links[name] = value;
if (this.initEnded) {
this.settedLinks.push(name);
}
return this;
} else {
return this.links[name];
}
}
/**
* delete the resource
* according server, return can be :
* - the request
* - an halResource returned by server
* - a json object return by server
*/
public delete(): Promise<any> {
return this.restClient.delete(this);
}
public onInitEnded() {
this.initEnded = true;
}
/**
* update the resource
*
* @param serializer : object used to serialize the prop and link value
*/
public update(serializer ?: IJSONSerializer): Promise<any> {
const json = this.serialize(this.settedProps, this.settedLinks, serializer);
return this.restClient.update(this.uri.resourceURI, json, false, this.constructor as IHalResourceConstructor<this>);
}
/**
* save the resource
*/
public create(serializer ?: IJSONSerializer): Promise<any> {
const json = this.serialize(Object.keys(this.props), Object.keys(this.links), serializer);
return this.restClient.create(this.uri.fetchedURI, json, this.constructor as IHalResourceConstructor<this>);
}
public reset() {
Object.keys(this.props).forEach((prop) => {
delete this.props[prop];
});
Object.keys(this.links).forEach((prop) => {
delete this.props[prop];
});
}
/**
* get the service prop name corresponding to ts attribute name
*/
protected tsProptoHalProd(prop: string) {
const tsToHal = Reflect.getMetadata("halClient:tsToHal", this.constructor.prototype) || {};
return tsToHal[prop] || prop;
}
/**
* serialize this object to json
*/
private serialize(props: string[], links: string[], serializer: IJSONSerializer = new DefaultSerializer()): object {
const json = {};
for (const prop of props) {
const jsonKey = this.tsProptoHalProd(prop) ;
if (this.props[prop] !== undefined && this.props[prop] !== null && this.props[prop].onInitEnded !== undefined) {
json[jsonKey] = serializer.parseResource(this.props[prop]);
} else {
json[jsonKey] = serializer.parseProp(this.props[prop]);
}
}
for (const link of links) {
const jsonKey = this.tsProptoHalProd(link);
json[jsonKey] = serializer.parseResource(this.links[link]);
}
return json;
}
}