Skip to content

Commit 1e819db

Browse files
committed
feat: update version to 1.1.0 and refactor HTTP client response handling
1 parent 349f140 commit 1e819db

File tree

3 files changed

+76
-53
lines changed

3 files changed

+76
-53
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "blink-http",
3-
"version": "1.0.1",
3+
"version": "1.1.0",
44
"description": "A tiny and standalone HTTP client based on XMLHttpRequest",
55
"exports": {
66
".": {

source/core/client.ts

Lines changed: 12 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
// @ts-expect-error: xhr2 has no types
22
import { XMLHttpRequest } from "xhr2";
3+
34
import { Interceptor, ResponseInterceptor, BlinkResponse } from "../interfaces";
45
import {
56
BLINK_USER_AGENT,
67
DEFAULT_TIMEOUT,
78
DEFAULT_OPTIONS,
8-
DEFAULT_HEADERS,
99
} from "../constants.js";
10+
import { buildFinalUrl, applyInterceptors, createResponse } from "./utils.js";
1011

1112
class Client {
1213
baseURL: string;
@@ -48,22 +49,10 @@ class Client {
4849
queryParams: Record<string, string> = {},
4950
onProgress?: (event: ProgressEvent) => void,
5051
): Promise<Response> {
51-
let finalUrl = this.baseURL ? new URL(url, this.baseURL).toString() : url;
52+
let finalUrl = buildFinalUrl(this.baseURL, url, queryParams);
5253
let finalOptions: RequestInit = { ...this.defaultOptions, ...options };
5354

54-
const urlObj = new URL(finalUrl);
55-
Object.keys(queryParams).forEach((key) =>
56-
urlObj.searchParams.append(key, queryParams[key]),
57-
);
58-
finalUrl = urlObj.toString();
59-
60-
for (const interceptor of this.interceptors.request) {
61-
const modified = interceptor(finalUrl, finalOptions);
62-
if (modified) {
63-
finalUrl = modified.url || finalUrl;
64-
finalOptions = modified.options || finalOptions;
65-
}
66-
}
55+
applyInterceptors(this.interceptors.request, finalUrl, finalOptions);
6756

6857
return new Promise((resolve, reject) => {
6958
const xhr = new XMLHttpRequest();
@@ -83,40 +72,11 @@ class Client {
8372
}
8473

8574
xhr.onload = async () => {
86-
let response: BlinkResponse = {
87-
status: xhr.status,
88-
ok: xhr.status >= 200 && xhr.status < 300,
89-
json: async () => JSON.parse(xhr.responseText),
90-
text: async () => xhr.responseText,
91-
clone: () => response,
92-
headers: new Headers(
93-
xhr
94-
.getAllResponseHeaders()
95-
.split("\r\n")
96-
.reduce(
97-
(
98-
acc: { [x: string]: any },
99-
current: { split: (arg0: string) => [any, any] },
100-
) => {
101-
const [key, value] = current.split(": ");
102-
if (key) acc[key] = value;
103-
return acc;
104-
},
105-
{} as Record<string, string>,
106-
),
107-
),
108-
redirected: false,
109-
statusText: xhr.statusText,
110-
type: "basic",
111-
url: finalUrl,
112-
body: null,
113-
bodyUsed: false,
114-
arrayBuffer: async () => new ArrayBuffer(0),
115-
blob: async () => new Blob(),
116-
formData: async () => new FormData(),
117-
bytes: async () => new Uint8Array(),
118-
userAgent: this.userAgent,
119-
};
75+
let response: BlinkResponse = createResponse(
76+
xhr,
77+
finalUrl,
78+
this.userAgent,
79+
);
12080

12181
for (const interceptor of this.interceptors.response) {
12282
const modifiedResponse = await interceptor(response);
@@ -161,7 +121,7 @@ class Client {
161121
...options,
162122
method: "POST",
163123
body: JSON.stringify(body),
164-
headers: { ...DEFAULT_HEADERS, ...options.headers },
124+
headers: { "Content-Type": "application/json", ...options.headers },
165125
},
166126
queryParams,
167127
onProgress,
@@ -181,7 +141,7 @@ class Client {
181141
...options,
182142
method: "PUT",
183143
body: JSON.stringify(body),
184-
headers: { ...DEFAULT_HEADERS, ...options.headers },
144+
headers: { "Content-Type": "application/json", ...options.headers },
185145
},
186146
queryParams,
187147
onProgress,
@@ -215,7 +175,7 @@ class Client {
215175
...options,
216176
method: "PATCH",
217177
body: JSON.stringify(body),
218-
headers: { ...DEFAULT_HEADERS, ...options.headers },
178+
headers: { "Content-Type": "application/json", ...options.headers },
219179
},
220180
queryParams,
221181
onProgress,

source/core/utils.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { BlinkResponse } from "../interfaces";
2+
3+
export function buildFinalUrl(
4+
baseURL: string,
5+
url: string,
6+
queryParams: Record<string, string>,
7+
): string {
8+
let finalUrl = baseURL ? new URL(url, baseURL).toString() : url;
9+
const urlObj = new URL(finalUrl);
10+
Object.keys(queryParams).forEach((key) =>
11+
urlObj.searchParams.append(key, queryParams[key]),
12+
);
13+
return urlObj.toString();
14+
}
15+
16+
export function applyInterceptors(
17+
interceptors: any[],
18+
finalUrl: string,
19+
finalOptions: RequestInit,
20+
): void {
21+
for (const interceptor of interceptors) {
22+
const modified = interceptor(finalUrl, finalOptions);
23+
if (modified) {
24+
finalUrl = modified.url || finalUrl;
25+
finalOptions = modified.options || finalOptions;
26+
}
27+
}
28+
}
29+
30+
export function createResponse(
31+
xhr: XMLHttpRequest,
32+
finalUrl: string,
33+
userAgent: string,
34+
): BlinkResponse {
35+
const headers = new Headers();
36+
xhr
37+
.getAllResponseHeaders()
38+
.split("\r\n")
39+
.forEach((header) => {
40+
const [key, value] = header.split(": ");
41+
if (key) headers.append(key, value);
42+
});
43+
44+
return {
45+
status: xhr.status,
46+
ok: xhr.status >= 200 && xhr.status < 300,
47+
json: async () => JSON.parse(xhr.responseText),
48+
text: async () => xhr.responseText,
49+
clone: () => createResponse(xhr, finalUrl, userAgent),
50+
headers: headers,
51+
redirected: false,
52+
statusText: xhr.statusText,
53+
type: "basic",
54+
url: finalUrl,
55+
body: null,
56+
bodyUsed: false,
57+
arrayBuffer: async () => new ArrayBuffer(0),
58+
blob: async () => new Blob(),
59+
formData: async () => new FormData(),
60+
bytes: async () => new Uint8Array(),
61+
userAgent: userAgent,
62+
};
63+
}

0 commit comments

Comments
 (0)