summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2024-02-24 15:47:19 -0300
committerEuAndreh <eu@euandre.org>2024-02-24 15:47:19 -0300
commitd064f5ba5cc2fa592c0e7566560b05e9c4ed65dc (patch)
treefdc89ddd55c375e9a4ac7021375bfbaf48d2c0e7
parentsrc/hero.mjs: Add buildServer() (diff)
downloadpapod-d064f5ba5cc2fa592c0e7566560b05e9c4ed65dc.tar.gz
papod-d064f5ba5cc2fa592c0e7566560b05e9c4ed65dc.tar.xz
Normalize how modules import and name each other
Also add a `defaultInterceptors` variable in `src/hero.mjs` to avoid needing to redefine it in every application.
-rw-r--r--Makefile11
-rw-r--r--index.mjs1
-rw-r--r--src/accretion.mjs6
-rw-r--r--src/api.mjs1
-rwxr-xr-xsrc/bin.mjs4
-rw-r--r--src/db.mjs20
-rw-r--r--src/hero.mjs23
-rw-r--r--src/ircd.mjs1
-rw-r--r--src/web.mjs38
-rw-r--r--tests/js/accretion.mjs18
-rw-r--r--tests/js/db.mjs15
-rw-r--r--tests/js/escape.mjs9
-rw-r--r--tests/js/hero.mjs19
-rw-r--r--tests/js/ircd.mjs5
-rw-r--r--tests/js/utils.mjs4
-rw-r--r--tests/js/web.mjs5
-rw-r--r--tests/runner.mjs2
17 files changed, 92 insertions, 90 deletions
diff --git a/Makefile b/Makefile
index e19a81e..d4719ef 100644
--- a/Makefile
+++ b/Makefile
@@ -55,6 +55,8 @@ derived-assets = \
$(manpages) \
side-assets = \
+ tests/hero-0.sock \
+ tests/hero-1.sock \
ircd.sock \
web.sock \
@@ -67,6 +69,11 @@ all: $(derived-assets)
$(manpages): Makefile deps.mk
+rm-sock-files:
+ rm -f tests/hero-0.sock tests/hero-1.sock
+
+tests/js/hero.mjs-check: rm-sock-files
+
.SUFFIXES: .mjs .mjs-check
@@ -130,11 +137,11 @@ uninstall:
run-ircd: all
rm -f ircd.sock
- ./src/papo ircd ircd.sock
+ ./src/bin.mjs ircd ircd.sock
run-web: all
rm -f web.sock
- ./src/papo web web.sock
+ ./src/bin.mjs web web.sock
## Run the web and IRC server locally.
run: all
diff --git a/index.mjs b/index.mjs
deleted file mode 100644
index 898ccb4..0000000
--- a/index.mjs
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./api.mjs";
diff --git a/src/accretion.mjs b/src/accretion.mjs
index 117e291..a9adb97 100644
--- a/src/accretion.mjs
+++ b/src/accretion.mjs
@@ -5,7 +5,7 @@ import url from "node:url";
import sqlite from "./sqlite.cjs";
-import { difference, log } from "./utils.mjs";
+import * as u from "./utils.mjs";
const DIRNAME = path.dirname(url.fileURLToPath(import.meta.url));
@@ -25,12 +25,12 @@ export const runMigrations = async db => {
const done = [...(await db.all("SELECT filename FROM migrations;"))]
.map(row => row.filename);
const allFiles = fs.readdirSync(MIGRATIONS_DIR, "UTF-8");
- const pending = difference(new Set(allFiles), new Set(done));
+ const pending = u.difference(new Set(allFiles), new Set(done));
const sortedPending = [...pending]
.sort((a, b) => a.localeCompare(b, "POSIX"));
for (const filename of sortedPending) {
- log({ log: "exec-migration", filename });
+ u.log({ log: "exec-migration", filename });
const sql = fs.readFileSync(MIGRATIONS_DIR + filename, "UTF-8");
await db.exec("BEGIN TRANSACTION;");
await db.exec(sql);
diff --git a/src/api.mjs b/src/api.mjs
index 27a14b1..2ec7cbf 100644
--- a/src/api.mjs
+++ b/src/api.mjs
@@ -1,4 +1,3 @@
-import { eq } from "./utils.mjs";
import * as ircd from "./ircd.mjs";
import * as web from "./web.mjs";
diff --git a/src/bin.mjs b/src/bin.mjs
index 5dbbb25..e79904f 100755
--- a/src/bin.mjs
+++ b/src/bin.mjs
@@ -1,4 +1,4 @@
#!/usr/bin/env node
-import { main } from "./api.mjs";
+import * as api from "./api.mjs";
-main();
+api.main();
diff --git a/src/db.mjs b/src/db.mjs
index d32df54..6bb2634 100644
--- a/src/db.mjs
+++ b/src/db.mjs
@@ -5,15 +5,15 @@ import url from "node:url";
import sqlite from "./sqlite.cjs";
-import { promisify } from "./utils.mjs";
-import { runMigrations } from "./accretion.mjs";
+import * as u from "./utils.mjs";
+import * as accretion from "./accretion.mjs";
export const promisifyDb = dbHandle => ({
ref: dbHandle,
- all: promisify((...args) => dbHandle.all(...args)),
- exec: promisify((...args) => dbHandle.exec(...args)),
- run: promisify((...args) => dbHandle.run(...args)),
+ all: u.promisify((...args) => dbHandle.all(...args)),
+ exec: u.promisify((...args) => dbHandle.exec(...args)),
+ run: u.promisify((...args) => dbHandle.run(...args)),
each: (...args) =>
new Promise((resolve, reject) => {
const cb = args[args.length - 1];
@@ -27,8 +27,8 @@ export const promisifyDb = dbHandle => ({
new Promise((resolve, reject) => {
const mkStmt = stmtRef => ({
ref: stmtRef,
- run: promisify((...args) => stmtRef.run(...args)),
- finalize: promisify((...args) => stmtRef.finalize(...args)),
+ run: u.promisify((...args) => stmtRef.run(...args)),
+ finalize: u.promisify((...args) => stmtRef.finalize(...args)),
});
const ref = dbHandle.prepare(
...args,
@@ -47,9 +47,9 @@ export const open = (...args) =>
));
});
-export let db = null;
+export let handle = null;
export const init = async (dbName = process.env.PAPO_DB_PATH || ":memory:") => {
- db = await open(dbName);
- await runMigrations(db);
+ handle = await open(dbName);
+ await accretion.runMigrations(handle);
};
diff --git a/src/hero.mjs b/src/hero.mjs
index 38fdde4..aa4a5a4 100644
--- a/src/hero.mjs
+++ b/src/hero.mjs
@@ -2,7 +2,8 @@ import assert from "node:assert/strict";
import crypto from "node:crypto";
import http from "node:http";
-import { assocIn, getIn, first, log, promisify } from "./utils.mjs";
+import * as u from "./utils.mjs";
+
export const normalizeSegments = segments =>
segments.length === 1 && segments[0] === "" ?
@@ -45,13 +46,13 @@ export const addRoute = (table, methods, path, handlerFn) => {
const segments = pathToSegments(path);
const kw = hasPathParams(segments) ? "dynamic" : "static";
return methods.reduce(
- (acc, el) => assocIn(acc, [kw, el].concat(segments), handlerFn),
+ (acc, el) => u.assocIn(acc, [kw, el].concat(segments), handlerFn),
table,
);
};
export const findStaticHandler = (table, method, segments) => {
- const handlerFn = getIn(table, ["static", method].concat(segments));
+ const handlerFn = u.getIn(table, ["static", method].concat(segments));
return !handlerFn ? null : { handlerFn, params: {} };
};
@@ -87,7 +88,7 @@ export const firstParamMatch = (tree, segments, params) => {
const paramOptions = Object.keys(tree)
.filter(s => s.startsWith(":"))
.sort();
- return first(paramOptions, param => firstParamMatch(tree[param], nextSegments, {
+ return u.first(paramOptions, param => firstParamMatch(tree[param], nextSegments, {
...params,
[param.slice(1)]: seg
}));
@@ -148,7 +149,7 @@ export const interceptorsFn = ({
logger,
} = {
uuidFn: crypto.randomUUID,
- logger: log,
+ logger: u.log,
}) => ({
requestId: (req, next) => next({ ...req, id: uuidFn() }),
logged: async (req, next) => {
@@ -204,6 +205,13 @@ export const interceptorsFn = ({
export const interceptors = interceptorsFn();
+export const defaultInterceptors = [
+ interceptors.serverError,
+ interceptors.contentType,
+ interceptors.requestId,
+ interceptors.logged,
+];
+
export const chainInterceptors = arr =>
req => arr.length === 0 ?
req :
@@ -231,8 +239,9 @@ export const buildRoutes = (routes, globalInterceptors = []) =>
export const promisifyServer = serverHandle => ({
ref: serverHandle,
- listen: promisify((...args) => serverHandle.listen(...args)),
- close: promisify((...args) => serverHandle.close(...args)),
+ listen: u.promisify((...args) => serverHandle.listen(...args)),
+ close: u.promisify((...args) => serverHandle.close(...args)),
+ events: serverHandle,
});
export const buildServer = (routes, globalInterceptors = []) => {
diff --git a/src/ircd.mjs b/src/ircd.mjs
index 38903f8..af4d280 100644
--- a/src/ircd.mjs
+++ b/src/ircd.mjs
@@ -1,5 +1,4 @@
import net from "node:net";
-import {} from "./db.mjs";
const server = net.createServer(socket => {
socket.write("olar\r\n");
diff --git a/src/web.mjs b/src/web.mjs
index 8eed5b4..cd875a0 100644
--- a/src/web.mjs
+++ b/src/web.mjs
@@ -1,30 +1,18 @@
-import http from "node:http";
+import * as u from "./utils.mjs";
+import { buildServer, defaultInterceptors } from "./hero.mjs";
-const listProducts = () => {};
-const getProduct = () => {};
-const routes = {
- GET: {
- "/products": listProducts,
- "/products/:id": getProduct,
- },
-};
+const listProducts = req => ({ status: 200 });
+const getProduct = req => ({ status: 200 });
+const getChat = req => ({ status: 200, body: "something\n" });
-const server = http.createServer((req, res) => {
- const { headers ,url, method } = req;
- console.log({
- headers,
- url,
- method,
- });
- res.writeHead(200, {
- "Content-Type": "text/plain",
- });
- res.end("Hello, web!\n");
-});
+const server = buildServer([
+ [ "GET", "/products", listProducts ],
+ [ "GET", "/products/:id", getProduct ],
+ [ "GET", "/chat", getChat ],
+], defaultInterceptors);
-export const app = udsPath => {
- server.listen(udsPath, () => {
- console.log("I'm web.");
- });
+export const app = async udsPath => {
+ await server.listen(udsPath);
+ u.log({ type: "starting-server", udsPath });
};
diff --git a/tests/js/accretion.mjs b/tests/js/accretion.mjs
index 3ea90c3..a0fbb66 100644
--- a/tests/js/accretion.mjs
+++ b/tests/js/accretion.mjs
@@ -2,27 +2,29 @@ import assert from "node:assert/strict";
import sqlite from "../../src/sqlite.cjs";
-import { runTests } from "../runner.mjs";
-import { promisifyDb, open } from "../../src/db.mjs";
-import { runMigrations } from "../../src/accretion.mjs";
+import * as runner from "../runner.mjs";
+import * as db from "../../src/db.mjs";
+import {
+ runMigrations,
+} from "../../src/accretion.mjs";
const test_runMigrations = t => {
t.start("runMigrations()");
t.test("running twice is a noop", async () => {
- const db = await open(":memory:");
- const migrationsFn = () => db.all("SELECT filename FROM migrations;");
+ const handle = await db.open(":memory:");
+ const migrationsFn = () => handle.all("SELECT filename FROM migrations;");
assert.rejects(
migrationsFn,
{ message: "SQLITE_ERROR: no such table: migrations" },
);
- await runMigrations(db);
+ await runMigrations(handle);
const filled = await migrationsFn();
- await runMigrations(db);
+ await runMigrations(handle);
const unchanged = await migrationsFn();
assert.deepEqual(filled, unchanged);
@@ -30,6 +32,6 @@ const test_runMigrations = t => {
};
-await runTests([
+await runner.runTests([
test_runMigrations,
]);
diff --git a/tests/js/db.mjs b/tests/js/db.mjs
index fcea535..c6c5c85 100644
--- a/tests/js/db.mjs
+++ b/tests/js/db.mjs
@@ -2,8 +2,13 @@ import assert from "node:assert/strict";
import sqlite from "../../src/sqlite.cjs";
-import { runTests } from "../runner.mjs";
-import { promisifyDb, open, db, init } from "../../src/db.mjs";
+import * as runner from "../runner.mjs";
+import {
+ promisifyDb,
+ open,
+ handle,
+ init,
+} from "../../src/db.mjs";
const test_promisifyDb = t => {
@@ -88,16 +93,16 @@ const test_init = t => {
t.start("init()");
t.test("we only know how to deal with 1 database", async () => {
await init();
- const ref1 = db;
+ const ref1 = handle;
await init();
- const ref2 = db;
+ const ref2 = handle;
assert.notDeepEqual(ref1, ref2);
});
};
-await runTests([
+await runner.runTests([
test_promisifyDb,
test_open,
test_init,
diff --git a/tests/js/escape.mjs b/tests/js/escape.mjs
index 2cad16a..8291391 100644
--- a/tests/js/escape.mjs
+++ b/tests/js/escape.mjs
@@ -1,6 +1,9 @@
import assert from "node:assert/strict";
-import { runTests } from "../runner.mjs";
-import { escape } from "../../src/escape.mjs";
+
+import * as runner from "../runner.mjs";
+import {
+ escape,
+} from "../../src/escape.mjs";
const test_escape = t => {
t.start("escape()");
@@ -57,6 +60,6 @@ const test_escape = t => {
};
-await runTests([
+await runner.runTests([
test_escape,
]);
diff --git a/tests/js/hero.mjs b/tests/js/hero.mjs
index 7b8a5cc..bc9d3d2 100644
--- a/tests/js/hero.mjs
+++ b/tests/js/hero.mjs
@@ -1,8 +1,8 @@
import assert from "node:assert/strict";
import http from "node:http";
-import { runTests } from "../runner.mjs";
-import { assocIn } from "../../src/utils.mjs";
+import * as runner from "../runner.mjs";
+import * as u from "../../src/utils.mjs";
import {
normalizeSegments,
pathToSegments,
@@ -17,6 +17,7 @@ import {
makeRequestListener,
interceptorsFn,
interceptors,
+ defaultInterceptors,
chainInterceptors,
wrapHandler,
buildRoutes,
@@ -274,7 +275,7 @@ const test_firstParamMatch = t => {
},
};
- const tree2 = assocIn(tree1, [ "path", "param1", ":deeper", "" ], fn1);
+ const tree2 = u.assocIn(tree1, [ "path", "param1", ":deeper", "" ], fn1);
assert.deepEqual(
firstParamMatch(tree1, segments, params),
@@ -298,7 +299,7 @@ const test_firstParamMatch = t => {
},
};
- const tree2 = assocIn(tree1, ["user", ":aaa", ""], fn1);
+ const tree2 = u.assocIn(tree1, ["user", ":aaa", ""], fn1);
assert.deepEqual(
firstParamMatch(tree1, segments, params),
@@ -1163,14 +1164,8 @@ const test_buildServer = t => {
t.test("integrated application server", async () => {
const socketPath = "./tests/hero-1.sock";
const pathHandler = req => ({ status: 200, body: "OK" });
- const globalInterceptors = [
- interceptors.serverError,
- interceptors.contentType,
- interceptors.requestId,
- interceptors.logged,
- ];
const routes = [ [ "GET", "/path", pathHandler ] ];
- const server = buildServer(routes, globalInterceptors);
+ const server = buildServer(routes, defaultInterceptors);
await server.listen(socketPath);
const response = await socketRequest(socketPath, "/path");
@@ -1181,7 +1176,7 @@ const test_buildServer = t => {
};
-await runTests([
+await runner.runTests([
test_normalizeSegments,
test_pathToSegments,
test_hasPathParams,
diff --git a/tests/js/ircd.mjs b/tests/js/ircd.mjs
index e5eda66..d385a72 100644
--- a/tests/js/ircd.mjs
+++ b/tests/js/ircd.mjs
@@ -1,7 +1,6 @@
-import { runTests } from "../runner.mjs";
-import { } from "../../src/ircd.mjs";
+import * as runner from "../runner.mjs";
-await runTests([
+await runner.runTests([
]);
diff --git a/tests/js/utils.mjs b/tests/js/utils.mjs
index e4f21d0..e2475b0 100644
--- a/tests/js/utils.mjs
+++ b/tests/js/utils.mjs
@@ -1,6 +1,6 @@
import assert from "node:assert/strict";
-import { runTests } from "../runner.mjs";
+import * as runner from "../runner.mjs";
import {
eq,
keys,
@@ -291,7 +291,7 @@ const test_promisify = t => {
};
-await runTests([
+await runner.runTests([
test_eq,
test_keys,
test_difference,
diff --git a/tests/js/web.mjs b/tests/js/web.mjs
index 00cce70..d385a72 100644
--- a/tests/js/web.mjs
+++ b/tests/js/web.mjs
@@ -1,7 +1,6 @@
-import { runTests } from "../runner.mjs";
-import { } from "../../src/web.mjs";
+import * as runner from "../runner.mjs";
-await runTests([
+await runner.runTests([
]);
diff --git a/tests/runner.mjs b/tests/runner.mjs
index 79bda8c..0adca10 100644
--- a/tests/runner.mjs
+++ b/tests/runner.mjs
@@ -1,5 +1,3 @@
-import { eq } from "../src/utils.mjs";
-
class AssertionError extends Error {}
const red = s => `\x1b[31m${s}\x1b[0m`;