Skip to content

Commit 9ddcd7e

Browse files
authored
refactor(http): clean code - split controllers / middleware (#90)
* chore(http): use http-server folder * chore(http): move root route * test(http): add first test * chore: add updated package.json * chore(http): finish root tests * chore: create context (AsyncLocalStorage) * feat(http): split data endpoint * chore(http): port middleware in split file * chore(http): remove useless spec test * chore(http): fix naming for root import * chore(http): add flags * revert: remove sinon deps * chore: add missing import comment
1 parent bf404c9 commit 9ddcd7e

File tree

9 files changed

+151
-89
lines changed

9 files changed

+151
-89
lines changed

src/commands/http.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import path from "path";
33

44
// Import Internal Dependencies
5-
import { buildServer } from "../httpServer.js";
5+
import { buildServer } from "../http-server/index.js";
66

77
export async function start(json = "nsecure-result.json", options = {}) {
88
const port = Number(options.port);

src/http-server/context.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { AsyncLocalStorage } from "async_hooks";
2+
3+
export const context = new AsyncLocalStorage();

src/http-server/data.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Import Node.js Dependencies
2+
import fs from "fs";
3+
import { pipeline } from "stream";
4+
5+
// Import Internal Dependencies
6+
import { context } from "./context.js";
7+
8+
export async function get(req, res) {
9+
const { dataFilePath } = context.getStore();
10+
11+
res.writeHead(200, { "Content-Type": "application/json" });
12+
13+
pipeline(fs.createReadStream(dataFilePath), res, (err) => {
14+
if (err) {
15+
console.error(err);
16+
}
17+
});
18+
}

src/http-server/flags.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Import Node.Js Dependencies
2+
import { pipeline } from "stream";
3+
4+
// Import Third-party Dependencies
5+
import send from "@polka/send-type";
6+
import { getManifest, lazyFetchFlagFile, getFlags } from "@nodesecure/flags";
7+
8+
// CONSTANTS
9+
const kNodeSecureFlags = getFlags();
10+
11+
export function getAll(req, res) {
12+
send(res, 200, getManifest());
13+
}
14+
15+
export function get(req, res) {
16+
if (req.params.title !== "isDuplicate" && !kNodeSecureFlags.has(req.params.title)) {
17+
return send(res, 404, { error: "Not Found" });
18+
}
19+
20+
res.writeHead(200, { "Content-Type": "text/html" });
21+
22+
return pipeline(lazyFetchFlagFile(req.params.title), res, (err) => {
23+
if (err) {
24+
console.error(err);
25+
}
26+
});
27+
}

src/http-server/index.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/* eslint-disable no-sync */
2+
3+
// Import Node.js Dependencies
4+
import fs from "fs";
5+
6+
// Import Third-party Dependencies
7+
import kleur from "kleur";
8+
import polka from "polka";
9+
import open from "open";
10+
import * as i18n from "@nodesecure/i18n";
11+
12+
// Import Internal Dependencies
13+
import * as root from "./root.js";
14+
import * as data from "./data.js";
15+
import * as flags from "./flags.js";
16+
import * as middleware from "./middleware.js";
17+
18+
export function buildServer(dataFilePath, options = {}) {
19+
const httpConfigPort = typeof options.port === "number" ? options.port : 0;
20+
const openLink = typeof options.openLink === "boolean" ? options.openLink : true;
21+
22+
fs.accessSync(dataFilePath, fs.constants.R_OK | fs.constants.W_OK);
23+
24+
const httpServer = polka();
25+
26+
httpServer.use(middleware.buildContextMiddleware(dataFilePath));
27+
httpServer.use(middleware.addStaticFiles);
28+
httpServer.get("/", root.get);
29+
httpServer.get("/data", data.get);
30+
httpServer.get("/flags", flags.getAll);
31+
httpServer.get("/flags/description/:title", flags.get);
32+
33+
httpServer.listen(httpConfigPort, () => {
34+
const link = `http://localhost:${httpServer.server.address().port}`;
35+
console.log(kleur.magenta().bold(i18n.getToken("cli.http_server_started")), kleur.cyan().bold(link));
36+
37+
if (openLink) {
38+
open(link);
39+
}
40+
});
41+
42+
return httpServer;
43+
}

src/http-server/middleware.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Import Node.js Dependencies
2+
import { join, dirname } from "path";
3+
import { fileURLToPath } from "url";
4+
5+
// Import Third-party Dependencies
6+
import sirv from "sirv";
7+
8+
// Import Internal Dependencies
9+
import { context } from "./context.js";
10+
11+
export function buildContextMiddleware(dataFilePath) {
12+
return function addContext(req, res, next) {
13+
const store = { dataFilePath };
14+
context.run(store, next);
15+
};
16+
}
17+
18+
const __dirname = dirname(fileURLToPath(import.meta.url));
19+
const kProjectRootDir = join(__dirname, "..", "..");
20+
21+
export const addStaticFiles = sirv(join(kProjectRootDir, "dist"), { dev: true });

src/http-server/root.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Import Node.js Dependencies
2+
import { join, dirname } from "path";
3+
import { readFile } from "fs/promises";
4+
import { fileURLToPath } from "url";
5+
6+
// Import Third-party Dependencies
7+
import zup from "zup";
8+
import send from "@polka/send-type";
9+
import * as i18n from "@nodesecure/i18n";
10+
11+
const __dirname = dirname(fileURLToPath(import.meta.url));
12+
const kProjectRootDir = join(__dirname, "..", "..");
13+
14+
export async function buildHtml() {
15+
const HTMLStr = await readFile(join(kProjectRootDir, "views", "index.html"), "utf-8");
16+
const templateStr = zup(HTMLStr)({
17+
lang: i18n.getToken("lang"),
18+
token: (tokenName) => i18n.getToken(`ui.${tokenName}`)
19+
});
20+
21+
return templateStr;
22+
}
23+
24+
export async function get(req, res) {
25+
try {
26+
res.writeHead(200, {
27+
"Content-Type": "text/html"
28+
});
29+
30+
const templateStr = await buildHtml();
31+
32+
res.end(templateStr);
33+
}
34+
catch (err) {
35+
send(res, 500, { error: err.message });
36+
}
37+
}

src/httpServer.js

-87
This file was deleted.

test/httpServer.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import * as i18n from "@nodesecure/i18n";
1111
import * as flags from "@nodesecure/flags";
1212

1313
// Require Internal Dependencies
14-
import { buildServer } from "../src/httpServer.js";
14+
import { buildServer } from "../src/http-server/index.js";
1515

1616
// CONSTANTS
1717
const HTTP_PORT = 1337;

0 commit comments

Comments
 (0)