@line/bot-sdk
Version:
Node.js SDK for LINE Messaging API
195 lines (179 loc) • 5.14 kB
text/typescript
import { Buffer } from "node:buffer";
import { Readable } from "node:stream";
import { HTTPFetchError } from "./exceptions.js";
import { USER_AGENT } from "./version.js";
export interface FetchRequestConfig {
headers?: Record<string, string>;
}
interface httpFetchClientConfig {
baseURL: string;
defaultHeaders: Record<string, string>;
}
export function convertResponseToReadable(response: Response): Readable {
const reader = response.body.getReader();
return new Readable({
async read() {
const { done, value } = await reader.read();
if (done) {
this.push(null);
} else {
this.push(Buffer.from(value));
}
},
});
}
export default class HTTPFetchClient {
private readonly baseURL: string;
private readonly defaultHeaders: Record<string, string>;
constructor(config: httpFetchClientConfig) {
this.baseURL = config.baseURL;
this.defaultHeaders = {
"User-Agent": USER_AGENT,
...config.defaultHeaders,
};
}
public async get<T>(url: string, params?: any): Promise<Response> {
const requestUrl = new URL(url, this.baseURL);
if (params) {
const searchParams = new URLSearchParams();
for (const key in params) {
if (params.hasOwnProperty(key)) {
searchParams.append(key, params[key]);
}
}
requestUrl.search = searchParams.toString();
}
const response = await fetch(requestUrl, {
headers: this.defaultHeaders,
});
await this.checkResponseStatus(response);
return response;
}
public async post(
url: string,
body?: any,
config?: Partial<FetchRequestConfig>,
): Promise<Response> {
const requestUrl = new URL(url, this.baseURL);
const response = await fetch(requestUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
...this.defaultHeaders,
...(config && config.headers),
},
body: JSON.stringify(body),
});
await this.checkResponseStatus(response);
return response;
}
public async put(
url: string,
body?: any,
config?: Partial<FetchRequestConfig>,
): Promise<Response> {
const requestUrl = new URL(url, this.baseURL);
const response = await fetch(requestUrl, {
method: "PUT",
headers: {
"Content-Type": "application/json",
...this.defaultHeaders,
...(config && config.headers),
},
body: JSON.stringify(body),
});
await this.checkResponseStatus(response);
return response;
}
public async postForm(url: string, body?: any): Promise<Response> {
const requestUrl = new URL(url, this.baseURL);
const params = new URLSearchParams();
for (const key in body) {
if (body.hasOwnProperty(key)) {
params.append(key, body[key]);
}
}
const response = await fetch(requestUrl, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
...this.defaultHeaders,
},
body: params.toString(),
});
await this.checkResponseStatus(response);
return response;
}
public async postFormMultipart(
url: string,
form: FormData,
): Promise<Response> {
const requestUrl = new URL(url, this.baseURL);
const response = await fetch(requestUrl, {
method: "POST",
headers: {
...this.defaultHeaders,
},
body: form,
});
await this.checkResponseStatus(response);
return response;
}
public async putFormMultipart(
url: string,
form: FormData,
config?: Partial<FetchRequestConfig>,
): Promise<Response> {
const requestUrl = new URL(url, this.baseURL);
const response = await fetch(requestUrl, {
method: "PUT",
headers: {
...this.defaultHeaders,
...(config && (config.headers ? config.headers : {})),
},
body: form,
});
await this.checkResponseStatus(response);
return response;
}
public async postBinaryContent(url: string, body: Blob): Promise<Response> {
const requestUrl = new URL(url, this.baseURL);
const response = await fetch(requestUrl, {
method: "POST",
headers: {
"Content-Type": body.type,
...this.defaultHeaders,
},
body: body,
});
await this.checkResponseStatus(response);
return response;
}
public async delete(url: string, params?: any): Promise<Response> {
const requestUrl = new URL(url, this.baseURL);
if (params) {
requestUrl.search = new URLSearchParams(params).toString();
}
const response = await fetch(requestUrl, {
method: "DELETE",
headers: {
...this.defaultHeaders,
},
});
await this.checkResponseStatus(response);
return response;
}
private async checkResponseStatus(response: Response) {
const { ok, status, statusText, headers } = response;
const message = `${status} - ${statusText}`;
if (!ok) {
const body = await response.text();
throw new HTTPFetchError(message, {
status,
statusText,
headers,
body,
});
}
}
}