RenaiApp/src/main/services/web-crawler.ts

57 lines
1.5 KiB
TypeScript

import { CookieJar } from 'jsdom';
import nodeFetch, { RequestInit, Response } from 'node-fetch';
import { Errors, RenaiError } from '../../types/error';
import { throwError } from './error';
import { load, save, StoreKeys } from './store';
export let cookieJar: CookieJar = new CookieJar();
let initialized = false;
function init(): Promise<void> {
if (!initialized) {
return load(StoreKeys.COOKIES).then((cookies: any) => {
if (cookies !== undefined) {
cookieJar = CookieJar.deserializeSync(cookies);
}
initialized = true;
});
} else {
return Promise.resolve();
}
}
export function fetch(url: string, requestInit: RequestInit = {}): Promise<Response> {
return init().then(() => {
const cookiedInit = {
...requestInit,
...{
headers: {
...requestInit.headers,
...{
Cookie: cookieJar.getCookieStringSync(url),
},
},
},
};
return nodeFetch(url, cookiedInit).then((res: Response) => {
setCookies(res.headers.raw()['set-cookie'], url).catch((reason: any) => {
throwError(new RenaiError(Errors.ECOOKIESAVEFAIL, reason));
});
return res;
});
});
}
function setCookies(header: string[], url: string): Promise<void> {
if (header) {
header.forEach((cookie: string) => {
cookieJar.setCookieSync(cookie, url);
});
return save(StoreKeys.COOKIES, cookieJar.serializeSync()).catch((reason: any) => {
throwError(new RenaiError(Errors.ECOOKIESAVEFAIL, reason));
});
}
return Promise.resolve();
}