forked from shadowfacts/shadowfacts.net
130 lines
3.2 KiB
TypeScript
130 lines
3.2 KiB
TypeScript
import { Page } from "./metadata";
|
|
import generators from "./generate";
|
|
|
|
import express, { Router } from "express";
|
|
import morgan from "morgan";
|
|
import bodyParser from "body-parser";
|
|
import activitypub from "./activitypub";
|
|
import validateHttpSig from "./activitypub/middleware/http-signature";
|
|
|
|
import "reflect-metadata";
|
|
import { createConnection} from "typeorm";
|
|
import * as path from "path";
|
|
import chokidar from "chokidar";
|
|
|
|
async function generate(): Promise<Page[]> {
|
|
generators.copy();
|
|
generators.css();
|
|
generators.errors();
|
|
|
|
generators.tutorials().then(generators.rss.tutorials);
|
|
|
|
const posts = await generators.posts();
|
|
generators.homepage(posts);
|
|
generators.years(posts);
|
|
generators.rss.posts(posts)
|
|
generators.tags(posts).then(generators.rss.tags);
|
|
generators.archive(posts);
|
|
|
|
return posts;
|
|
}
|
|
|
|
function watch() {
|
|
const watcher = chokidar.watch("site/", {
|
|
ignoreInitial: true,
|
|
});
|
|
watcher.on("all", (event, path) => {
|
|
console.log(`Regenerating due to ${event} ${path}`);
|
|
// todo: this could be smarter about not regenerating everything
|
|
generate();
|
|
});
|
|
}
|
|
|
|
(async () => {
|
|
if (process.env.NODE_ENV === undefined) {
|
|
process.env.NODE_ENV = "development";
|
|
}
|
|
|
|
const app = express();
|
|
app.use(morgan("dev"));
|
|
app.use(bodyParser.json({ type: "application/activity+json" }));
|
|
app.use(bodyParser.urlencoded());
|
|
|
|
const connection = await createConnection({
|
|
"type": "postgres",
|
|
"host": process.env.DB_HOST || "localhost",
|
|
"port": process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 5432,
|
|
"username": process.env.DB_USERNAME || "blog",
|
|
"password": process.env.DB_PASSWORD || "blog",
|
|
"database": process.env.DB_DATABASE || "blog",
|
|
"synchronize": true,
|
|
"logging": true,
|
|
"entities": [
|
|
path.join(__dirname, "entity/**/*.{ts,js}")
|
|
],
|
|
"migrations": [
|
|
path.join(__dirname, "migration/**/*.{ts,js}")
|
|
],
|
|
"subscribers": [
|
|
path.join(__dirname, "subscriber/**/*.{ts,js}")
|
|
],
|
|
"cli": {
|
|
"entitiesDir": "lib/entity",
|
|
"migrationsDir": "lib/migration",
|
|
"subscribersDir": "lib/subscriber"
|
|
}
|
|
});
|
|
|
|
const posts = await generate();
|
|
|
|
if (process.env.NODE_ENV === "development") {
|
|
watch();
|
|
}
|
|
|
|
await activitypub.articles.setup(posts);
|
|
|
|
await activitypub.interact(app);
|
|
|
|
const apRouter = Router();
|
|
apRouter.use(validateHttpSig);
|
|
await activitypub.actor(apRouter);
|
|
activitypub.comments(apRouter);
|
|
activitypub.followers(apRouter);
|
|
activitypub.inbox(apRouter);
|
|
await activitypub.nodeinfo(apRouter);
|
|
activitypub.webfinger(apRouter);
|
|
activitypub.articles.route(apRouter);
|
|
app.use(apRouter);
|
|
app.use(express.static("out"));
|
|
|
|
// redirect posts with changed permalinks
|
|
for (const post of posts) {
|
|
if (post.metadata.oldPermalink) {
|
|
app.get(post.metadata.oldPermalink, (req, res) => {
|
|
res.status(301).redirect(post.metadata.permalink);
|
|
});
|
|
}
|
|
}
|
|
|
|
app.use((err, req, res, next) => {
|
|
console.error("Unhandled error:", err);
|
|
res.status(500).sendFile("500.html", {
|
|
root: "out"
|
|
});
|
|
});
|
|
app.use((req, res, next) => {
|
|
res.status(404).sendFile("404.html", {
|
|
root: "out"
|
|
});
|
|
});
|
|
|
|
const port = process.env.PORT || 8083;
|
|
app.listen(port, async () => {
|
|
console.log(`Listening on port ${port}`);
|
|
|
|
const toFederate = await activitypub.articles.toFederate();
|
|
activitypub.federate(toFederate);
|
|
});
|
|
})();
|
|
|