Merge branch 'main' into non-html
This commit is contained in:
commit
d873be0226
55
package-lock.json
generated
55
package-lock.json
generated
@ -10,6 +10,8 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/static": "^6.10.2",
|
"@fastify/static": "^6.10.2",
|
||||||
|
"@fastify/swagger": "^8.8.0",
|
||||||
|
"@fastify/swagger-ui": "^1.9.3",
|
||||||
"@fastify/view": "^8.0.0",
|
"@fastify/view": "^8.0.0",
|
||||||
"@mozilla/readability": "^0.4.4",
|
"@mozilla/readability": "^0.4.4",
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
@ -211,6 +213,30 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@fastify/swagger": {
|
||||||
|
"version": "8.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fastify/swagger/-/swagger-8.8.0.tgz",
|
||||||
|
"integrity": "sha512-tYI2lbItb4yg9FhQj+leK6DdIBICLbXkSR2vZjo117ygHyYQLxw2v0ere/d2PtDmYAx7SOJzxvg3w6y0Sxc3iw==",
|
||||||
|
"dependencies": {
|
||||||
|
"fastify-plugin": "^4.0.0",
|
||||||
|
"json-schema-resolver": "^2.0.0",
|
||||||
|
"openapi-types": "^12.0.0",
|
||||||
|
"rfdc": "^1.3.0",
|
||||||
|
"yaml": "^2.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@fastify/swagger-ui": {
|
||||||
|
"version": "1.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fastify/swagger-ui/-/swagger-ui-1.9.3.tgz",
|
||||||
|
"integrity": "sha512-YYqce4CydjDIEry6Zo4JLjVPe5rjS8iGnk3fHiIQnth9sFSLeyG0U1DCH+IyYmLddNDg1uWJOuErlVqnu/jI3w==",
|
||||||
|
"dependencies": {
|
||||||
|
"@fastify/static": "^6.0.0",
|
||||||
|
"fastify-plugin": "^4.0.0",
|
||||||
|
"openapi-types": "^12.0.2",
|
||||||
|
"rfdc": "^1.3.0",
|
||||||
|
"yaml": "^2.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@fastify/view": {
|
"node_modules/@fastify/view": {
|
||||||
"version": "8.0.0",
|
"version": "8.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@fastify/view/-/view-8.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@fastify/view/-/view-8.0.0.tgz",
|
||||||
@ -2091,6 +2117,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/json-schema-resolver": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-schema-resolver/-/json-schema-resolver-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-pJ4XLQP4Q9HTxl6RVDLJ8Cyh1uitSs0CzDBAz1uoJ4sRD/Bk7cFSXL1FUXDW3zJ7YnfliJx6eu8Jn283bpZ4Yg==",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.1.1",
|
||||||
|
"rfdc": "^1.1.4",
|
||||||
|
"uri-js": "^4.2.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/Eomm/json-schema-resolver?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/json-schema-traverse": {
|
"node_modules/json-schema-traverse": {
|
||||||
"version": "0.4.1",
|
"version": "0.4.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@ -2304,6 +2346,11 @@
|
|||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/openapi-types": {
|
||||||
|
"version": "12.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz",
|
||||||
|
"integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="
|
||||||
|
},
|
||||||
"node_modules/optionator": {
|
"node_modules/optionator": {
|
||||||
"version": "0.9.3",
|
"version": "0.9.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@ -3285,6 +3332,14 @@
|
|||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/yaml": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/yocto-queue": {
|
"node_modules/yocto-queue": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
"main": "dist/app.js",
|
"main": "dist/app.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/static": "^6.10.2",
|
"@fastify/static": "^6.10.2",
|
||||||
|
"@fastify/swagger": "^8.8.0",
|
||||||
|
"@fastify/swagger-ui": "^1.9.3",
|
||||||
"@fastify/view": "^8.0.0",
|
"@fastify/view": "^8.0.0",
|
||||||
"@mozilla/readability": "^0.4.4",
|
"@mozilla/readability": "^0.4.4",
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
|
15
src/app.ts
15
src/app.ts
@ -6,6 +6,8 @@ import path from "path";
|
|||||||
import Fastify from "fastify";
|
import Fastify from "fastify";
|
||||||
import fastifyStatic from "@fastify/static";
|
import fastifyStatic from "@fastify/static";
|
||||||
import fastifyView from "@fastify/view";
|
import fastifyView from "@fastify/view";
|
||||||
|
import fastifySwagger from "@fastify/swagger";
|
||||||
|
import fastifySwaggerUi from "@fastify/swagger-ui";
|
||||||
import ejs from "ejs";
|
import ejs from "ejs";
|
||||||
|
|
||||||
import getRoute from "./routes/get";
|
import getRoute from "./routes/get";
|
||||||
@ -13,6 +15,8 @@ import parseRoute from "./routes/parse";
|
|||||||
import indexRoute from "./routes/index";
|
import indexRoute from "./routes/index";
|
||||||
import rawHtml from "./routes/raw-html";
|
import rawHtml from "./routes/raw-html";
|
||||||
|
|
||||||
|
import publicConfig from "./publicConfig";
|
||||||
|
|
||||||
class App {
|
class App {
|
||||||
config: IConfigService;
|
config: IConfigService;
|
||||||
|
|
||||||
@ -36,6 +40,17 @@ class App {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await fastify.register(fastifySwagger, {
|
||||||
|
swagger: {
|
||||||
|
info: {
|
||||||
|
title: "TXTDot API",
|
||||||
|
description: publicConfig.description,
|
||||||
|
version: publicConfig.version,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await fastify.register(fastifySwaggerUi, { routePrefix: "/doc" });
|
||||||
|
|
||||||
fastify.register(indexRoute);
|
fastify.register(indexRoute);
|
||||||
fastify.register(getRoute);
|
fastify.register(getRoute);
|
||||||
fastify.register(parseRoute);
|
fastify.register(parseRoute);
|
||||||
|
@ -4,3 +4,21 @@ export interface IHandlerOutput {
|
|||||||
title: string;
|
title: string;
|
||||||
lang: string;
|
lang: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const handlerSchema = {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
content: {
|
||||||
|
type: "string",
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
type: "string",
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: "string",
|
||||||
|
},
|
||||||
|
lang: {
|
||||||
|
type: "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
5
src/publicConfig.ts
Normal file
5
src/publicConfig.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export default {
|
||||||
|
version: "1.0.0",
|
||||||
|
description:
|
||||||
|
"HTTP proxy that parses only text, links and pictures from pages reducing internet traffic, removing ads and heavy scripts",
|
||||||
|
};
|
@ -1,43 +1,45 @@
|
|||||||
import { FastifyInstance } from "fastify";
|
import { FastifyInstance } from "fastify";
|
||||||
|
|
||||||
import { GetRequest } from "../types/requests";
|
import { GetSchema, IGetSchema } from "../types/requests";
|
||||||
import handlePage from "../handlers/main";
|
import handlePage from "../handlers/main";
|
||||||
import { generateRequestUrl } from "../utils";
|
import { generateRequestUrl } from "../utils";
|
||||||
|
|
||||||
import { NotHtmlMimetypeError } from "../errors";
|
import { NotHtmlMimetypeError } from "../errors";
|
||||||
|
|
||||||
export default async function getRoute(fastify: FastifyInstance) {
|
export default async function getRoute(fastify: FastifyInstance) {
|
||||||
fastify.get("/get", async (request: GetRequest, reply) => {
|
fastify.get<IGetSchema>(
|
||||||
const remoteUrl = request.query.url;
|
"/get",
|
||||||
const engine = request.query.engine;
|
{ schema: GetSchema },
|
||||||
|
async (request, reply) => {
|
||||||
|
const remoteUrl = request.query.url;
|
||||||
|
const engine = request.query.engine;
|
||||||
|
|
||||||
let parsed;
|
let parsed;
|
||||||
try {
|
try {
|
||||||
parsed = await handlePage(
|
parsed = await handlePage(
|
||||||
remoteUrl,
|
remoteUrl,
|
||||||
generateRequestUrl(
|
generateRequestUrl(
|
||||||
request.protocol,
|
request.protocol,
|
||||||
request.hostname,
|
request.hostname,
|
||||||
request.originalUrl
|
request.originalUrl
|
||||||
),
|
),
|
||||||
engine
|
engine
|
||||||
);
|
);
|
||||||
}
|
} catch (err) {
|
||||||
catch (err) {
|
if (err instanceof NotHtmlMimetypeError) {
|
||||||
if (err instanceof NotHtmlMimetypeError) {
|
return reply.redirect(301, remoteUrl);
|
||||||
return reply.redirect(301, remoteUrl);
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
throw err;
|
if (request.query.format === "text") {
|
||||||
|
reply.type("text/plain; charset=utf-8");
|
||||||
|
return parsed.textContent;
|
||||||
|
} else {
|
||||||
|
reply.type("text/html; charset=utf-8");
|
||||||
|
return reply.view("/templates/get.ejs", { parsed: parsed });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
);
|
||||||
if (request.query.format === "text") {
|
|
||||||
reply.type("text/plain; charset=utf-8");
|
|
||||||
return parsed.textContent;
|
|
||||||
} else {
|
|
||||||
reply.type("text/html; charset=utf-8");
|
|
||||||
return reply.view("/templates/get.ejs", { parsed: parsed });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { FastifyInstance } from "fastify";
|
import { FastifyInstance } from "fastify";
|
||||||
import { engineList } from "../handlers/main";
|
import { engineList } from "../handlers/main";
|
||||||
|
import { indexSchema } from "../types/requests";
|
||||||
|
|
||||||
export default async function indexRoute(fastify: FastifyInstance) {
|
export default async function indexRoute(fastify: FastifyInstance) {
|
||||||
fastify.get("/", async (_, reply) => {
|
fastify.get("/", { schema: indexSchema }, async (_, reply) => {
|
||||||
return reply.view("/templates/index.ejs", { engineList });
|
return reply.view("/templates/index.ejs", { engineList });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,22 @@
|
|||||||
import { EngineRequest } from "../types/requests";
|
import { EngineRequest, IParseSchema, parseSchema } from "../types/requests";
|
||||||
import { FastifyInstance } from "fastify";
|
import { FastifyInstance } from "fastify";
|
||||||
import handlePage from "../handlers/main";
|
import handlePage from "../handlers/main";
|
||||||
import { generateRequestUrl } from "../utils";
|
import { generateRequestUrl } from "../utils";
|
||||||
|
|
||||||
export default async function parseRoute(fastify: FastifyInstance) {
|
export default async function parseRoute(fastify: FastifyInstance) {
|
||||||
fastify.get("/parse", async (request: EngineRequest) => {
|
fastify.get<IParseSchema>(
|
||||||
const parsed = await handlePage(
|
"/parse",
|
||||||
request.query.url,
|
{ schema: parseSchema },
|
||||||
generateRequestUrl(
|
async (request: EngineRequest) => {
|
||||||
request.protocol,
|
return await handlePage(
|
||||||
request.hostname,
|
request.query.url,
|
||||||
request.originalUrl
|
generateRequestUrl(
|
||||||
),
|
request.protocol,
|
||||||
request.query.engine
|
request.hostname,
|
||||||
);
|
request.originalUrl
|
||||||
|
),
|
||||||
return parsed;
|
request.query.engine
|
||||||
});
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,24 @@
|
|||||||
import { FastifyInstance } from "fastify";
|
import { FastifyInstance } from "fastify";
|
||||||
|
|
||||||
import { GetRequest } from "../types/requests";
|
import { GetRequest, IParseSchema, rawHtmlSchema } from "../types/requests";
|
||||||
import handlePage from "../handlers/main";
|
import handlePage from "../handlers/main";
|
||||||
import { generateRequestUrl } from "../utils";
|
import { generateRequestUrl } from "../utils";
|
||||||
|
|
||||||
export default async function rawHtml(fastify: FastifyInstance) {
|
export default async function rawHtml(fastify: FastifyInstance) {
|
||||||
fastify.get("/raw-html", async (request: GetRequest) => {
|
fastify.get<IParseSchema>(
|
||||||
return (
|
"/raw-html",
|
||||||
await handlePage(
|
{ schema: rawHtmlSchema },
|
||||||
request.query.url,
|
async (request: GetRequest) => {
|
||||||
generateRequestUrl(
|
return (
|
||||||
request.protocol,
|
await handlePage(
|
||||||
request.hostname,
|
request.query.url,
|
||||||
request.originalUrl
|
generateRequestUrl(
|
||||||
|
request.protocol,
|
||||||
|
request.hostname,
|
||||||
|
request.originalUrl
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
).content;
|
||||||
).content;
|
}
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { FastifyRequest } from "fastify";
|
import { FastifyRequest, FastifySchema } from "fastify";
|
||||||
|
import { handlerSchema } from "../handlers/handler.interface";
|
||||||
|
import { engineList } from "../handlers/main";
|
||||||
|
|
||||||
export type GetRequest = FastifyRequest<{
|
export type GetRequest = FastifyRequest<{
|
||||||
Querystring: {
|
Querystring: {
|
||||||
@ -8,6 +10,85 @@ export type GetRequest = FastifyRequest<{
|
|||||||
};
|
};
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
export interface IGetQuery {
|
||||||
|
url: string;
|
||||||
|
format?: string;
|
||||||
|
engine?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IParseQuery {
|
||||||
|
url: string;
|
||||||
|
engine?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IGetSchema {
|
||||||
|
Querystring: IGetQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IParseSchema {
|
||||||
|
Querystring: IParseQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const indexSchema = {
|
||||||
|
produces: ["text/html"],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getQuerySchema = {
|
||||||
|
type: "object",
|
||||||
|
required: ["url"],
|
||||||
|
properties: {
|
||||||
|
url: {
|
||||||
|
type: "string",
|
||||||
|
description: "URL",
|
||||||
|
},
|
||||||
|
format: {
|
||||||
|
type: "string",
|
||||||
|
enum: ["text", "html", ""],
|
||||||
|
default: "html",
|
||||||
|
},
|
||||||
|
engine: {
|
||||||
|
type: "string",
|
||||||
|
enum: [...engineList, ""],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const parseQuerySchema = {
|
||||||
|
type: "object",
|
||||||
|
required: ["url"],
|
||||||
|
properties: {
|
||||||
|
url: {
|
||||||
|
type: "string",
|
||||||
|
description: "URL",
|
||||||
|
},
|
||||||
|
engine: {
|
||||||
|
type: "string",
|
||||||
|
enum: [...engineList, ""],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GetSchema: FastifySchema = {
|
||||||
|
description: "Get page",
|
||||||
|
querystring: getQuerySchema,
|
||||||
|
produces: ["text/html", "text/plain"],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const parseSchema: FastifySchema = {
|
||||||
|
description: "Parse page",
|
||||||
|
querystring: parseQuerySchema,
|
||||||
|
response: {
|
||||||
|
"2xx": handlerSchema,
|
||||||
|
},
|
||||||
|
produces: ["text/json"],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const rawHtmlSchema: FastifySchema = {
|
||||||
|
description: "Get raw HTML",
|
||||||
|
querystring: parseQuerySchema,
|
||||||
|
produces: ["text/html"],
|
||||||
|
};
|
||||||
|
|
||||||
export type EngineRequest = FastifyRequest<{
|
export type EngineRequest = FastifyRequest<{
|
||||||
Querystring: {
|
Querystring: {
|
||||||
url: string;
|
url: string;
|
||||||
|
@ -30,9 +30,9 @@
|
|||||||
<option value="" selected>Default</option>
|
<option value="" selected>Default</option>
|
||||||
<% engineList.forEach((engine)=> {
|
<% engineList.forEach((engine)=> {
|
||||||
%>
|
%>
|
||||||
<option value="<%= engine %>">
|
<option value="<%= engine %>">
|
||||||
<%= engine %>
|
<%= engine %>
|
||||||
</option>
|
</option>
|
||||||
<%
|
<%
|
||||||
})
|
})
|
||||||
%>
|
%>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user