txtdot/src/handlers/main.ts
2023-08-21 18:35:25 +04:00

73 lines
1.7 KiB
TypeScript

import { IHandlerOutput } from "./handler.interface";
import axios from "../types/axios";
import { JSDOM } from "jsdom";
import { DOMWindow } from "jsdom";
import readability from "./readability";
import google from "./google";
import stackoverflow from "./stackoverflow/main";
import { generateProxyUrl } from "../utils/generate";
import isLocalResource from "../utils/islocal";
import {
LocalResourceError,
NotHtmlMimetypeError,
} from "../errors/main";
export default async function handlePage(
url: string, // remote URL
requestUrl: URL, // proxy URL
engine?: string
): Promise<IHandlerOutput> {
const urlObj = new URL(url);
if (await isLocalResource(urlObj)) {
throw new LocalResourceError();
}
const response = await axios.get(url);
const mime: string | undefined = response.headers["content-type"]?.toString();
if (mime && mime.indexOf("text/html") === -1) {
throw new NotHtmlMimetypeError(url);
}
const window = new JSDOM(response.data, { url }).window;
[...window.document.getElementsByTagName("a")].forEach((link) => {
try {
link.href = generateProxyUrl(requestUrl, link.href, engine);
} catch (_err) {
// ignore TypeError: Invalid URL
}
});
if (engine) {
return engines[engine](window);
}
return fallback[urlObj.host]?.(window) || fallback["*"](window);
}
interface Engines {
[key: string]: EngineFunction;
}
type EngineFunction = (window: DOMWindow) => Promise<IHandlerOutput>;
export const engines: Engines = {
readability,
google,
stackoverflow,
};
export const engineList: string[] = Object.keys(engines);
const fallback: Engines = {
"stackoverflow.com": engines.stackoverflow,
"www.google.com": engines.google,
"*": engines.readability,
};