-
Notifications
You must be signed in to change notification settings - Fork 20
/
verbs.ts
50 lines (45 loc) · 1.56 KB
/
verbs.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
import { StringMap } from "./types";
import { KeratinError } from "./types";
import formData from "./formData";
export function get<T>(url: string, data: StringMap): Promise<T> {
return jhr((xhr: XMLHttpRequest) => {
xhr.open("GET", `${url}?${formData(data)}`.replace(/\?$/, ""));
xhr.send();
});
}
export function del<T>(url: string): Promise<T> {
return jhr((xhr: XMLHttpRequest) => {
xhr.open("DELETE", url);
xhr.send();
});
}
export function post<T>(url: string, data: StringMap): Promise<T> {
return jhr((xhr: XMLHttpRequest) => {
xhr.open("POST", url);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(formData(data));
});
}
function jhr<T>(sender: (xhr: XMLHttpRequest) => void): Promise<T> {
return new Promise(
(fulfill: (data: T) => any, reject: (errors: KeratinError[]) => any) => {
const xhr = new XMLHttpRequest();
xhr.withCredentials = true; // enable authentication server cookies
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.DONE) {
const data: { result: T } | { errors: KeratinError[] } =
xhr.responseText.length > 1 ? JSON.parse(xhr.responseText) : {};
if ("errors" in data) {
reject(data.errors);
} else if (xhr.status > 400) {
// statusText may be missing in HTTP/2. only the status number is reliable.
reject([{ message: xhr.status.toString() }]);
} else {
fulfill(data.result);
}
}
};
sender(xhr);
}
);
}