Skip to content

Commit

Permalink
Refactor and improve web application
Browse files Browse the repository at this point in the history
  • Loading branch information
pklaschka committed Sep 8, 2024
1 parent b41bf43 commit c63b515
Show file tree
Hide file tree
Showing 12 changed files with 245 additions and 177 deletions.
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
".": "./main.ts",
"./cli": "./lib/cli/mod.ts",
"./common": "./lib/common/mod.ts",
"./http": "./lib/http/mod.tsx"
"./http": "./lib/http/mod.ts"
},
"tasks": {
"dev": "deno run --watch --env --unstable-kv -A main.ts",
Expand Down
2 changes: 1 addition & 1 deletion lib/cli/server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { z } from "@collinhacks/zod";
import { CONFIG, logPaths } from "$common/mod.ts";
import { httpApp } from "$http/mod.tsx";
import { httpApp } from "../http/mod.ts";
import metadata from "$/deno.json" with { type: "json" };

const serverArgs = z.object({
Expand Down
15 changes: 15 additions & 0 deletions lib/http/asn-metadata-from-context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Context } from "@hono/hono";
import denojson from "$/deno.json" with { type: "json" };

/**
* Builds the metadata for an ASN from the context of an HTTP request.
* @param c the context of the HTTP request
* @returns ASN metadata for ASNs generated by an HTTP request
*/
export function createMetadata(c: Context): Record<string, unknown> {
return {
client: "web",
path: c.req.path,
denojson,
};
}
48 changes: 48 additions & 0 deletions lib/http/mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* @module
* Various APIs surrounding the HTTP server / Web Application.
*
* {@link httpApp} is the main HTTP server of the web application.
*/
import { Hono } from "@hono/hono";
import { logger } from "@hono/hono/logger";
import { serveStatic } from "@hono/hono/deno";

import { getFormatDescription } from "$common/mod.ts";
import denojson from "$/deno.json" with { type: "json" };

import { svgRoutes } from "$http/routes/svg.ts";
import { uiRoutes } from "$http/routes/ui.tsx";
import { apiRoutes } from "$http/routes/api.ts";
import { lookupRoutes } from "$http/routes/lookup.ts";

export * from "$http/lookup-url.ts";
export * from "$http/barcode-svg.ts";
export * from "$http/asn-metadata-from-context.ts";

/**
* The main HTTP server of the web application.
* This server is responsible for serving the web application and the API.
*
* @see <https://hono.dev/>
*
* @example
* ```ts
* Deno.serve(httpApp.fetch);
* ```
*/
export const httpApp: Hono = new Hono();

httpApp.use(logger());
httpApp.get(
"/about",
(c) => c.text(`${denojson.name} v${denojson.version} is running!`),
);
httpApp.get("/format", (c) => c.text(getFormatDescription()));

httpApp.get("/static/*", serveStatic({ root: "." }));

httpApp.route("/api", apiRoutes);
httpApp.route("/svg", svgRoutes);
httpApp.route("/", lookupRoutes);
httpApp.route("/", uiRoutes);
174 changes: 0 additions & 174 deletions lib/http/mod.tsx

This file was deleted.

25 changes: 25 additions & 0 deletions lib/http/routes/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Hono } from "@hono/hono";

import { generateASN } from "$common/mod.ts";

import { createMetadata } from "$http/mod.ts";
import { optionalQueryNamespaceValidator } from "$http/validators/query/optional-namespace.ts";

export const apiRoutes = new Hono();

apiRoutes.get(
"/asn",
optionalQueryNamespaceValidator,
async (c) =>
c.json(
await generateASN(
createMetadata(c),
c.req.valid("query").namespace,
),
),
);

apiRoutes.get(
"/asn/:asn",
(c) => c.text("Not implemented yet", 501), // TODO: Implement this route
);
47 changes: 47 additions & 0 deletions lib/http/routes/lookup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Hono } from "@hono/hono";
import { validator } from "@hono/hono/validator";
import { z } from "@collinhacks/zod";

import { CONFIG, isValidASN } from "$common/mod.ts";

import { getLookupURL } from "$http/mod.ts";

export const lookupRoutes = new Hono();

lookupRoutes.post(
"/lookup",
validator("form", (value, c) => {
const parsed = z.object({
asn: z.string({ coerce: true }).min(1).regex(/^\d+$/),
}).safeParse(value);

if (!parsed.success) {
return c.text("Invalid ASN. " + parsed.error.message, 400);
}

return parsed.data;
}),
(c) => {
const asn = CONFIG.ASN_PREFIX + c.req.valid("form").asn;
return c.redirect("/go/" + asn);
},
);

lookupRoutes.get(
"/go/:asn",
validator("param", (value, c) => {
if (!value || !isValidASN(value.asn)) {
return c.text("Invalid ASN", 400);
}
return value;
}),
(c) => {
const asn = c.req.valid("param").asn;

if (!CONFIG.ASN_LOOKUP_URL) {
return c.text("ASN Lookup is disabled", 400);
}

return c.redirect(getLookupURL(asn));
},
);
30 changes: 30 additions & 0 deletions lib/http/routes/svg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Hono } from "@hono/hono";
import { generateASN } from "$common/mod.ts";
import { createBarcodeSVG } from "$http/barcode-svg.ts";
import { createMetadata } from "../mod.ts";
import { paramASNValidator } from "$http/validators/param/asn.ts";
import { optionalQueryNamespaceValidator } from "$http/validators/query/optional-namespace.ts";

export const svgRoutes = new Hono();

svgRoutes.get("/", optionalQueryNamespaceValidator, async (c) => {
const barcode = createBarcodeSVG(
(await generateASN(createMetadata(c), c.req.valid("query").namespace)).asn,
!!c.req.query("embed"),
);
return c.body(barcode ?? "", 200, {
"Cache-Control": "no-cache",
"Content-Type": "image/svg+xml",
});
});

svgRoutes.get("/:asn", paramASNValidator, (c) => {
const { asn } = c.req.valid("param");

const barcode = createBarcodeSVG(asn, !!c.req.query("embed"));

return c.body(barcode ?? "", 200, {
"Cache-Control": "no-cache",
"Content-Type": "image/svg+xml",
});
});
Loading

0 comments on commit c63b515

Please sign in to comment.