@utiliread/http 1.10.2 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +2 -2
- package/dist/cjs/events.js +19 -85
- package/dist/cjs/events.js.map +1 -1
- package/dist/cjs/http-builder.js.map +1 -1
- package/dist/cjs/http.js +2 -1
- package/dist/cjs/http.js.map +1 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/msgpack.js +17 -0
- package/dist/cjs/msgpack.js.map +1 -1
- package/dist/esm/events.d.ts +4 -22
- package/dist/esm/events.js +17 -84
- package/dist/esm/events.js.map +1 -1
- package/dist/esm/http-builder.d.ts +3 -0
- package/dist/esm/http-builder.js.map +1 -1
- package/dist/esm/http.js +2 -1
- package/dist/esm/http.js.map +1 -1
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/msgpack.d.ts +1 -0
- package/dist/esm/msgpack.js +18 -1
- package/dist/esm/msgpack.js.map +1 -1
- package/karma.config.js +30 -30
- package/package.json +1 -1
- package/src/event-aggregator.ts +31 -31
- package/src/events.ts +35 -0
- package/src/helpers.ts +13 -13
- package/src/http-builder.ts +254 -253
- package/src/http-error.ts +25 -25
- package/src/http-response.ts +55 -55
- package/src/http.spec.ts +104 -104
- package/src/http.ts +121 -120
- package/src/index.ts +17 -16
- package/src/json.ts +138 -138
- package/src/mapping.ts +42 -42
- package/src/msgpack.ts +63 -48
- package/src/pagination.ts +25 -25
- package/src/problem-details.ts +7 -7
- package/src/query-string.spec.ts +62 -62
- package/src/query-string.ts +69 -69
- package/src/timeout-error.ts +10 -10
- package/tsconfig.cjs.json +8 -8
- package/tsconfig.json +13 -13
- package/dist/cjs/settings.js +0 -3
- package/dist/cjs/settings.js.map +0 -1
- package/dist/cjs/utils.js +0 -8
- package/dist/cjs/utils.js.map +0 -1
- package/dist/esm/settings.d.ts +0 -6
- package/dist/esm/settings.js +0 -2
- package/dist/esm/settings.js.map +0 -1
- package/dist/esm/utils.d.ts +0 -3
- package/dist/esm/utils.js +0 -4
- package/dist/esm/utils.js.map +0 -1
package/src/http-error.ts
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import { HttpResponse } from './http-response';
|
|
2
|
-
import { ProblemDetails } from './problem-details';
|
|
3
|
-
|
|
4
|
-
export class HttpError extends Error {
|
|
5
|
-
constructor(public statusCode: number, private response: HttpResponse | undefined = undefined) {
|
|
6
|
-
super(`The response was not successful: ${statusCode}`);
|
|
7
|
-
this.name = 'HttpError';
|
|
8
|
-
|
|
9
|
-
// Set the prototype explicitly to allow for "... instanceof HttpError",
|
|
10
|
-
// see https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
|
11
|
-
Object.setPrototypeOf(this, HttpError.prototype);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
details<TDetails = ProblemDetails>() {
|
|
15
|
-
const rawResponse = this.response?.rawResponse;
|
|
16
|
-
|
|
17
|
-
if (rawResponse) {
|
|
18
|
-
const contentType = rawResponse.headers.get("Content-Type");
|
|
19
|
-
if (contentType && contentType.includes("application/problem+json")) {
|
|
20
|
-
return rawResponse.json().then(details => <TDetails>details);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return Promise.reject(new Error("There are no problem details in the response"));
|
|
25
|
-
}
|
|
1
|
+
import { HttpResponse } from './http-response';
|
|
2
|
+
import { ProblemDetails } from './problem-details';
|
|
3
|
+
|
|
4
|
+
export class HttpError extends Error {
|
|
5
|
+
constructor(public statusCode: number, private response: HttpResponse | undefined = undefined) {
|
|
6
|
+
super(`The response was not successful: ${statusCode}`);
|
|
7
|
+
this.name = 'HttpError';
|
|
8
|
+
|
|
9
|
+
// Set the prototype explicitly to allow for "... instanceof HttpError",
|
|
10
|
+
// see https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
|
11
|
+
Object.setPrototypeOf(this, HttpError.prototype);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
details<TDetails = ProblemDetails>() {
|
|
15
|
+
const rawResponse = this.response?.rawResponse;
|
|
16
|
+
|
|
17
|
+
if (rawResponse) {
|
|
18
|
+
const contentType = rawResponse.headers.get("Content-Type");
|
|
19
|
+
if (contentType && contentType.includes("application/problem+json")) {
|
|
20
|
+
return rawResponse.json().then(details => <TDetails>details);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return Promise.reject(new Error("There are no problem details in the response"));
|
|
25
|
+
}
|
|
26
26
|
}
|
package/src/http-response.ts
CHANGED
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
import { HttpError } from "./http-error";
|
|
2
|
-
|
|
3
|
-
export class HttpResponse {
|
|
4
|
-
get url() {
|
|
5
|
-
return this.rawResponse.url;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
get statusCode() {
|
|
9
|
-
return this.rawResponse.status;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
get headers() {
|
|
13
|
-
return this.rawResponse.headers;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
get isInformational() {
|
|
17
|
-
return this.statusCode >= 100 && this.statusCode < 200;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
get isSuccessful() {
|
|
21
|
-
return this.statusCode >= 200 && this.statusCode < 300;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
get isRedirection() {
|
|
25
|
-
return this.statusCode >= 300 && this.statusCode < 400;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
get isClientError() {
|
|
29
|
-
return this.statusCode >= 400 && this.statusCode < 500;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
get isServerError() {
|
|
33
|
-
return this.statusCode >= 500 && this.statusCode < 600;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
constructor(public rawResponse: Response) {
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
ensureSuccessfulStatusCode() {
|
|
40
|
-
if (!this.isSuccessful) {
|
|
41
|
-
throw new HttpError(this.statusCode, this);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return this;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export class HttpResponseOfT<T> extends HttpResponse {
|
|
49
|
-
constructor(rawResponse: Response, private handler: (response: Response) => Promise<T>) {
|
|
50
|
-
super(rawResponse);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
receive() {
|
|
54
|
-
return this.handler(this.rawResponse);
|
|
55
|
-
}
|
|
1
|
+
import { HttpError } from "./http-error";
|
|
2
|
+
|
|
3
|
+
export class HttpResponse {
|
|
4
|
+
get url() {
|
|
5
|
+
return this.rawResponse.url;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
get statusCode() {
|
|
9
|
+
return this.rawResponse.status;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
get headers() {
|
|
13
|
+
return this.rawResponse.headers;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
get isInformational() {
|
|
17
|
+
return this.statusCode >= 100 && this.statusCode < 200;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get isSuccessful() {
|
|
21
|
+
return this.statusCode >= 200 && this.statusCode < 300;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
get isRedirection() {
|
|
25
|
+
return this.statusCode >= 300 && this.statusCode < 400;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
get isClientError() {
|
|
29
|
+
return this.statusCode >= 400 && this.statusCode < 500;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get isServerError() {
|
|
33
|
+
return this.statusCode >= 500 && this.statusCode < 600;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
constructor(public rawResponse: Response) {
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
ensureSuccessfulStatusCode() {
|
|
40
|
+
if (!this.isSuccessful) {
|
|
41
|
+
throw new HttpError(this.statusCode, this);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export class HttpResponseOfT<T> extends HttpResponse {
|
|
49
|
+
constructor(rawResponse: Response, private handler: (response: Response) => Promise<T>) {
|
|
50
|
+
super(rawResponse);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
receive() {
|
|
54
|
+
return this.handler(this.rawResponse);
|
|
55
|
+
}
|
|
56
56
|
}
|
package/src/http.spec.ts
CHANGED
|
@@ -1,104 +1,104 @@
|
|
|
1
|
-
import { expect } from "chai";
|
|
2
|
-
import { Http } from "./http";
|
|
3
|
-
import "./json";
|
|
4
|
-
|
|
5
|
-
describe("static http", () => {
|
|
6
|
-
it("can get", () => {
|
|
7
|
-
const builder = Http.get("hello");
|
|
8
|
-
expect(builder.getUrl()).to.equal("hello");
|
|
9
|
-
expect(builder.options.fetch).to.equal(Http.defaults.fetch);
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
it("can get with leading /", () => {
|
|
13
|
-
const builder = Http.get("/hello");
|
|
14
|
-
expect(builder.getUrl()).to.equal("/hello");
|
|
15
|
-
expect(builder.options.fetch).to.equal(Http.defaults.fetch);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it("can get with changed default fetch", () => {
|
|
19
|
-
Http.get("/hello"); // Creates internal singleton
|
|
20
|
-
// Change static default after request is created
|
|
21
|
-
const fetch = Http.defaults.fetch;
|
|
22
|
-
Http.defaults.fetch = fakeFetch;
|
|
23
|
-
const builder = Http.get("/hello");
|
|
24
|
-
expect(builder.options.fetch).to.equal(fakeFetch);
|
|
25
|
-
Http.defaults.fetch = fetch;
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
describe("instance http", () => {
|
|
30
|
-
it("can get with different timeout", () => {
|
|
31
|
-
const http = new Http();
|
|
32
|
-
const builder = http.get("/hello");
|
|
33
|
-
expect(builder.options.fetch).to.equal(Http.defaults.fetch);
|
|
34
|
-
expect(builder.options.timeout).to.equal(undefined);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it("can get with different timeout", () => {
|
|
38
|
-
const http = new Http({ timeout: 123 });
|
|
39
|
-
const builder = http.get("/hello");
|
|
40
|
-
expect(builder.options.fetch).to.equal(Http.defaults.fetch);
|
|
41
|
-
expect(builder.options.timeout).to.equal(123);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it("can get with different fetch", () => {
|
|
45
|
-
const http = new Http({ fetch: fakeFetch });
|
|
46
|
-
const builder = http.get("/hello");
|
|
47
|
-
expect(builder.options.fetch).to.equal(fakeFetch);
|
|
48
|
-
expect(builder.options.timeout).to.equal(undefined);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it("can get hello with base url", () => {
|
|
52
|
-
const http = new Http({ baseUrl: "base" });
|
|
53
|
-
const builder = http.get("hello");
|
|
54
|
-
expect(builder.getUrl()).to.equal("base/hello");
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("can get hello with base/", () => {
|
|
58
|
-
const http = new Http({ baseUrl: "base/" });
|
|
59
|
-
const builder = http.get("hello");
|
|
60
|
-
expect(builder.getUrl()).to.equal("base/hello");
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it("can get /hello with base url", () => {
|
|
64
|
-
const http = new Http({ baseUrl: "base" });
|
|
65
|
-
const builder = http.get("/hello");
|
|
66
|
-
expect(builder.getUrl()).to.equal("base/hello");
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it("can get /hello with base/", () => {
|
|
70
|
-
const http = new Http({ baseUrl: "base/" });
|
|
71
|
-
const builder = http.get("/hello");
|
|
72
|
-
expect(builder.getUrl()).to.equal("base/hello");
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it("can post json, with then expect", async () => {
|
|
76
|
-
const user = await new Http()
|
|
77
|
-
.post("https://reqres.in/api/users")
|
|
78
|
-
.withJson({
|
|
79
|
-
name: "morpheus",
|
|
80
|
-
job: "leader",
|
|
81
|
-
})
|
|
82
|
-
.expectJson<{ name: string; job: string }>()
|
|
83
|
-
.transfer();
|
|
84
|
-
|
|
85
|
-
expect(user.name).to.equal("morpheus");
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it("can post json, expect then with", async () => {
|
|
89
|
-
const user = await new Http()
|
|
90
|
-
.post("https://reqres.in/api/users")
|
|
91
|
-
.expectJson<{ name: string; job: string }>()
|
|
92
|
-
.withJson({
|
|
93
|
-
name: "morpheus",
|
|
94
|
-
job: "leader",
|
|
95
|
-
})
|
|
96
|
-
.transfer();
|
|
97
|
-
|
|
98
|
-
expect(user.name).to.equal("morpheus");
|
|
99
|
-
}).timeout(5000);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
function fakeFetch(input: RequestInfo, init?: RequestInit): Promise<Response> {
|
|
103
|
-
return Promise.resolve(new Response());
|
|
104
|
-
}
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import { Http } from "./http";
|
|
3
|
+
import "./json";
|
|
4
|
+
|
|
5
|
+
describe("static http", () => {
|
|
6
|
+
it("can get", () => {
|
|
7
|
+
const builder = Http.get("hello");
|
|
8
|
+
expect(builder.getUrl()).to.equal("hello");
|
|
9
|
+
expect(builder.options.fetch).to.equal(Http.defaults.fetch);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("can get with leading /", () => {
|
|
13
|
+
const builder = Http.get("/hello");
|
|
14
|
+
expect(builder.getUrl()).to.equal("/hello");
|
|
15
|
+
expect(builder.options.fetch).to.equal(Http.defaults.fetch);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("can get with changed default fetch", () => {
|
|
19
|
+
Http.get("/hello"); // Creates internal singleton
|
|
20
|
+
// Change static default after request is created
|
|
21
|
+
const fetch = Http.defaults.fetch;
|
|
22
|
+
Http.defaults.fetch = fakeFetch;
|
|
23
|
+
const builder = Http.get("/hello");
|
|
24
|
+
expect(builder.options.fetch).to.equal(fakeFetch);
|
|
25
|
+
Http.defaults.fetch = fetch;
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
describe("instance http", () => {
|
|
30
|
+
it("can get with different timeout", () => {
|
|
31
|
+
const http = new Http();
|
|
32
|
+
const builder = http.get("/hello");
|
|
33
|
+
expect(builder.options.fetch).to.equal(Http.defaults.fetch);
|
|
34
|
+
expect(builder.options.timeout).to.equal(undefined);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("can get with different timeout", () => {
|
|
38
|
+
const http = new Http({ timeout: 123 });
|
|
39
|
+
const builder = http.get("/hello");
|
|
40
|
+
expect(builder.options.fetch).to.equal(Http.defaults.fetch);
|
|
41
|
+
expect(builder.options.timeout).to.equal(123);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("can get with different fetch", () => {
|
|
45
|
+
const http = new Http({ fetch: fakeFetch });
|
|
46
|
+
const builder = http.get("/hello");
|
|
47
|
+
expect(builder.options.fetch).to.equal(fakeFetch);
|
|
48
|
+
expect(builder.options.timeout).to.equal(undefined);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("can get hello with base url", () => {
|
|
52
|
+
const http = new Http({ baseUrl: "base" });
|
|
53
|
+
const builder = http.get("hello");
|
|
54
|
+
expect(builder.getUrl()).to.equal("base/hello");
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("can get hello with base/", () => {
|
|
58
|
+
const http = new Http({ baseUrl: "base/" });
|
|
59
|
+
const builder = http.get("hello");
|
|
60
|
+
expect(builder.getUrl()).to.equal("base/hello");
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("can get /hello with base url", () => {
|
|
64
|
+
const http = new Http({ baseUrl: "base" });
|
|
65
|
+
const builder = http.get("/hello");
|
|
66
|
+
expect(builder.getUrl()).to.equal("base/hello");
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("can get /hello with base/", () => {
|
|
70
|
+
const http = new Http({ baseUrl: "base/" });
|
|
71
|
+
const builder = http.get("/hello");
|
|
72
|
+
expect(builder.getUrl()).to.equal("base/hello");
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("can post json, with then expect", async () => {
|
|
76
|
+
const user = await new Http()
|
|
77
|
+
.post("https://reqres.in/api/users")
|
|
78
|
+
.withJson({
|
|
79
|
+
name: "morpheus",
|
|
80
|
+
job: "leader",
|
|
81
|
+
})
|
|
82
|
+
.expectJson<{ name: string; job: string }>()
|
|
83
|
+
.transfer();
|
|
84
|
+
|
|
85
|
+
expect(user.name).to.equal("morpheus");
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("can post json, expect then with", async () => {
|
|
89
|
+
const user = await new Http()
|
|
90
|
+
.post("https://reqres.in/api/users")
|
|
91
|
+
.expectJson<{ name: string; job: string }>()
|
|
92
|
+
.withJson({
|
|
93
|
+
name: "morpheus",
|
|
94
|
+
job: "leader",
|
|
95
|
+
})
|
|
96
|
+
.transfer();
|
|
97
|
+
|
|
98
|
+
expect(user.name).to.equal("morpheus");
|
|
99
|
+
}).timeout(5000);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
function fakeFetch(input: RequestInfo, init?: RequestInit): Promise<Response> {
|
|
103
|
+
return Promise.resolve(new Response());
|
|
104
|
+
}
|
package/src/http.ts
CHANGED
|
@@ -1,121 +1,122 @@
|
|
|
1
|
-
import { EventAggregator } from './event-aggregator';
|
|
2
|
-
import { HttpBuilder, HttpMethod, Message } from './http-builder';
|
|
3
|
-
import { HttpResponse, HttpResponseOfT } from './http-response';
|
|
4
|
-
import { QueryString } from './query-string';
|
|
5
|
-
|
|
6
|
-
export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise<Response>;
|
|
7
|
-
|
|
8
|
-
export class Http {
|
|
9
|
-
static defaults: HttpOptions = {
|
|
10
|
-
fetch: window.fetch ? window.fetch.bind(window) : undefined,
|
|
11
|
-
}
|
|
12
|
-
private static instance?: Http;
|
|
13
|
-
options: HttpOptions;
|
|
14
|
-
/** @internal */
|
|
15
|
-
_onSend = new EventAggregator<[Message]>();
|
|
16
|
-
/** @internal */
|
|
17
|
-
_onSent = new EventAggregator<[HttpResponse, Message]>();
|
|
18
|
-
/** @internal */
|
|
19
|
-
_onReceived = new EventAggregator<[HttpResponseOfT<any>, Message, any]>();
|
|
20
|
-
|
|
21
|
-
constructor(options?: Partial<HttpOptions>) {
|
|
22
|
-
this.options = Object.assign({}, Http.defaults, options); // Later sources' properties overwrite earlier ones.
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
static request(method: HttpMethod, url: string, params?: any) {
|
|
26
|
-
return this.getInstance().request(method, url, params);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
static head(url: string, params?: any) {
|
|
30
|
-
return this.getInstance().head(url, params);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
static post(url: string, params?: any) {
|
|
34
|
-
return this.getInstance().post(url, params);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
static get(url: string, params?: any) {
|
|
38
|
-
return this.getInstance().get(url, params);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
static put(url: string, params?: any) {
|
|
42
|
-
return this.getInstance().put(url, params);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
static patch(url: string, params?: any) {
|
|
46
|
-
return this.getInstance().patch(url, params);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
static delete(url: string, params?: any) {
|
|
50
|
-
return this.getInstance().delete(url, params);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
private static getInstance() {
|
|
54
|
-
if (!this.instance) {
|
|
55
|
-
this.instance = new Http();
|
|
56
|
-
// The singleton instance should always use the static options
|
|
57
|
-
this.instance.options = Http.defaults;
|
|
58
|
-
}
|
|
59
|
-
return this.instance;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
request(method: HttpMethod, url: string, params?: any) {
|
|
63
|
-
const message = {
|
|
64
|
-
method,
|
|
65
|
-
url: url + QueryString.serialize(params),
|
|
66
|
-
headers: new Headers()
|
|
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
|
-
|
|
1
|
+
import { EventAggregator } from './event-aggregator';
|
|
2
|
+
import { HttpBuilder, HttpMethod, Message } from './http-builder';
|
|
3
|
+
import { HttpResponse, HttpResponseOfT } from './http-response';
|
|
4
|
+
import { QueryString } from './query-string';
|
|
5
|
+
|
|
6
|
+
export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise<Response>;
|
|
7
|
+
|
|
8
|
+
export class Http {
|
|
9
|
+
static defaults: HttpOptions = {
|
|
10
|
+
fetch: window.fetch ? window.fetch.bind(window) : undefined,
|
|
11
|
+
}
|
|
12
|
+
private static instance?: Http;
|
|
13
|
+
options: HttpOptions;
|
|
14
|
+
/** @internal */
|
|
15
|
+
_onSend = new EventAggregator<[Message]>();
|
|
16
|
+
/** @internal */
|
|
17
|
+
_onSent = new EventAggregator<[HttpResponse, Message]>();
|
|
18
|
+
/** @internal */
|
|
19
|
+
_onReceived = new EventAggregator<[HttpResponseOfT<any>, Message, any]>();
|
|
20
|
+
|
|
21
|
+
constructor(options?: Partial<HttpOptions>) {
|
|
22
|
+
this.options = Object.assign({}, Http.defaults, options); // Later sources' properties overwrite earlier ones.
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static request(method: HttpMethod, url: string, params?: any) {
|
|
26
|
+
return this.getInstance().request(method, url, params);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static head(url: string, params?: any) {
|
|
30
|
+
return this.getInstance().head(url, params);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static post(url: string, params?: any) {
|
|
34
|
+
return this.getInstance().post(url, params);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static get(url: string, params?: any) {
|
|
38
|
+
return this.getInstance().get(url, params);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static put(url: string, params?: any) {
|
|
42
|
+
return this.getInstance().put(url, params);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static patch(url: string, params?: any) {
|
|
46
|
+
return this.getInstance().patch(url, params);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static delete(url: string, params?: any) {
|
|
50
|
+
return this.getInstance().delete(url, params);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private static getInstance() {
|
|
54
|
+
if (!this.instance) {
|
|
55
|
+
this.instance = new Http();
|
|
56
|
+
// The singleton instance should always use the static options
|
|
57
|
+
this.instance.options = Http.defaults;
|
|
58
|
+
}
|
|
59
|
+
return this.instance;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
request(method: HttpMethod, url: string, params?: any) {
|
|
63
|
+
const message = {
|
|
64
|
+
method,
|
|
65
|
+
url: url + QueryString.serialize(params),
|
|
66
|
+
headers: new Headers(),
|
|
67
|
+
properties: {},
|
|
68
|
+
};
|
|
69
|
+
const fetch = this.options.fetch;
|
|
70
|
+
if (!fetch) {
|
|
71
|
+
throw Error('fetch() is not properly configured');
|
|
72
|
+
}
|
|
73
|
+
const builder = new HttpBuilder(message, {
|
|
74
|
+
fetch,
|
|
75
|
+
timeout: this.options.timeout,
|
|
76
|
+
baseUrl: this.options.baseUrl,
|
|
77
|
+
}, this);
|
|
78
|
+
return builder;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
head(url: string, params?: any) {
|
|
82
|
+
return this.request('HEAD', url, params);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
post(url: string, params?: any) {
|
|
86
|
+
return this.request('POST', url, params);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
get(url: string, params?: any) {
|
|
90
|
+
return this.request('GET', url, params);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
put(url: string, params?: any) {
|
|
94
|
+
return this.request('PUT', url, params);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
patch(url: string, params?: any) {
|
|
98
|
+
return this.request('PATCH', url, params);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
delete(url: string, params?: any) {
|
|
102
|
+
return this.request('DELETE', url, params);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
onSend(callback: (request: Message) => void | Promise<void>) {
|
|
106
|
+
return this._onSend.subscribe(callback);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
onSent(callback: (response: HttpResponse, request: Message) => void | Promise<void>) {
|
|
110
|
+
return this._onSent.subscribe(callback);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
onReceived(callback: (response: HttpResponseOfT<any>, request: Message, value: any) => void | Promise<void>) {
|
|
114
|
+
return this._onReceived.subscribe(callback);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface HttpOptions {
|
|
119
|
+
fetch?: Fetch,
|
|
120
|
+
timeout?: number,
|
|
121
|
+
baseUrl?: string,
|
|
121
122
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
export { Http } from "./http";
|
|
2
|
-
export {
|
|
3
|
-
Page,
|
|
4
|
-
PaginationResult,
|
|
5
|
-
InfinitePage,
|
|
6
|
-
InfinitePaginationResult,
|
|
7
|
-
} from "./pagination";
|
|
8
|
-
export { ProblemDetails } from "./problem-details";
|
|
9
|
-
export { QueryString } from "./query-string";
|
|
10
|
-
export { HttpResponse, HttpResponseOfT } from "./http-response";
|
|
11
|
-
export { HttpBuilder, HttpBuilderOfT } from "./http-builder";
|
|
12
|
-
export { HttpError } from "./http-error";
|
|
13
|
-
export { TimeoutError } from "./timeout-error";
|
|
14
|
-
export
|
|
15
|
-
export
|
|
16
|
-
export {
|
|
1
|
+
export { Http } from "./http";
|
|
2
|
+
export {
|
|
3
|
+
Page,
|
|
4
|
+
PaginationResult,
|
|
5
|
+
InfinitePage,
|
|
6
|
+
InfinitePaginationResult,
|
|
7
|
+
} from "./pagination";
|
|
8
|
+
export { ProblemDetails } from "./problem-details";
|
|
9
|
+
export { QueryString } from "./query-string";
|
|
10
|
+
export { HttpResponse, HttpResponseOfT } from "./http-response";
|
|
11
|
+
export { HttpBuilder, HttpBuilderOfT, Message } from "./http-builder";
|
|
12
|
+
export { HttpError } from "./http-error";
|
|
13
|
+
export { TimeoutError } from "./timeout-error";
|
|
14
|
+
export { events } from "./events";
|
|
15
|
+
export * from "./helpers";
|
|
16
|
+
export { Fetch } from "./http";
|
|
17
|
+
export { Subscription } from "./event-aggregator";
|