move sssg to it's own repo at https://git.sad.ovh/sophie/sssg
All checks were successful
/ test (push) Successful in 14s
All checks were successful
/ test (push) Successful in 14s
This commit is contained in:
parent
031625f918
commit
d0084e9f44
11 changed files with 47 additions and 458 deletions
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
42
index.ts
Normal file
42
index.ts
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import SSSG from "sssg";
|
||||||
|
import Variables from "sssg/src/plugins/variables";
|
||||||
|
import Dev from "sssg/src/plugins/dev";
|
||||||
|
import TSCompiler from "sssg/src/plugins/ts-compiler";
|
||||||
|
import MarkdownMetadata from "sssg/src/plugins/markdown-metadata";
|
||||||
|
import MarkdownCompiler from "sssg/src/plugins/markdown-compiler";
|
||||||
|
|
||||||
|
import * as path from "path";
|
||||||
|
import * as fs from "fs";
|
||||||
|
|
||||||
|
const sssg = new SSSG({
|
||||||
|
outputFolder: path.join(__dirname, "dist"),
|
||||||
|
inputFolder: path.join(__dirname, "website"),
|
||||||
|
});
|
||||||
|
|
||||||
|
await sssg.run({
|
||||||
|
plugins: [
|
||||||
|
new Variables(() => {
|
||||||
|
const variables: Record<string, string> = {
|
||||||
|
__BLOG_POSTS__: JSON.stringify(
|
||||||
|
fs.readdirSync("./website/blogs").map((z) => z.replace(".md", ""))
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (fs.existsSync("./website/templates")) {
|
||||||
|
for (const file of fs.readdirSync("./website/templates")) {
|
||||||
|
const id = file.toUpperCase().replace(".HTML", "");
|
||||||
|
variables["__TEMPLATE_" + id + "__"] = fs
|
||||||
|
.readFileSync(path.join("./website/templates", file))
|
||||||
|
.toString("utf8");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return variables;
|
||||||
|
}),
|
||||||
|
new TSCompiler(),
|
||||||
|
new MarkdownMetadata(),
|
||||||
|
new MarkdownCompiler(),
|
||||||
|
new Dev(sssg),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
await sssg.build();
|
13
package.json
13
package.json
|
@ -1,10 +1,10 @@
|
||||||
{
|
{
|
||||||
"name": "website2",
|
"name": "website2",
|
||||||
"module": "src/index.ts",
|
"module": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prod": "bun src/index.ts --prod",
|
"prod": "bun index.ts --prod",
|
||||||
"dev": "bun src/index.ts --dev"
|
"dev": "bun index.ts --dev"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "latest"
|
"@types/bun": "latest"
|
||||||
|
@ -13,11 +13,6 @@
|
||||||
"typescript": "^5.0.0"
|
"typescript": "^5.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/mime-types": "^2.1.4",
|
"sssg": "git+https://git.sad.ovh/sophie/sssg#ef49a06be55dbb5277793d6cfcfa6736b7c1bc96"
|
||||||
"@types/p5": "^1.7.6",
|
|
||||||
"esbuild": "^0.23.0",
|
|
||||||
"marked": "^13.0.2",
|
|
||||||
"mime-types": "^2.1.35",
|
|
||||||
"preact": "^10.23.1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
111
src/index.ts
111
src/index.ts
|
@ -1,111 +0,0 @@
|
||||||
/*
|
|
||||||
⡿⣿⠿⢿⠿⣿⢿⡿⡿⡿⢿⠿⣿⠻⢟⡟⣋⣛⡻⡛⠋⠉⠀⠀⠀⠀⢈⡁⠉⢍⠛⡷⣀⠀⠀⠀⠀⠀⠀⠲⢂⠟⡁⢢⢛⡤⢁⣀⡠⣄
|
|
||||||
⡳⡜⡺⢌⡳⢍⠎⡵⢣⢝⡩⢒⠡⠉⢈⣨⢗⡶⠛⠁⠀⠀⠀⠀⠉⢉⣲⣌⠑⢮⠑⠺⡅⠉⠁⠀⠒⠚⠷⣿⣌⡣⢜⠠⢎⠰⡉⠆⠱⠌
|
|
||||||
⠱⠘⡑⠩⡉⢌⠲⡱⢩⣾⣫⣥⣶⣶⡿⣳⢏⣴⠎⠉⣹⢢⣀⣀⣶⡏⠀⠘⡷⣄⢳⡀⠘⢐⣶⣶⣶⣶⣦⠄⢾⡎⠢⡑⢨⢀⢠⡀⢎⠀
|
|
||||||
⠣⡙⠬⠅⠁⠈⠁⠐⣿⣿⣿⣿⣿⣿⣿⣟⣾⣿⣀⣀⣈⣧⣿⣾⣿⣄⣀⡀⢽⣼⡄⢷⡤⣋⣿⣿⣿⣿⣿⣿⣮⣇⠀⠡⢃⡍⢢⣍⠳⣌
|
|
||||||
⠂⡍⠂⠀⠀⠀⠀⠀⣹⣿⣿⣿⣿⣿⣿⣿⡟⠛⣿⣿⣏⣿⢻⡇⢀⣿⣿⣿⡿⣿⣿⡈⣷⡱⡞⣿⣿⣿⣿⣿⣿⣿⠀⠀⠢⠐⣃⢤⢫⡔
|
|
||||||
⠐⠈⠁⠐⠒⠀⠁⠀⠘⣿⣿⣿⣿⣿⡿⣞⣿⡄⢿⣿⣿⡿⣼⣇⠀⣿⣿⣿⢧⣿⡿⣗⡸⢷⡍⢿⣿⣿⣿⣿⣿⡇⠒⠬⢓⡹⢰⢣⡓⢮
|
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣿⣿⣿⣿⢿⣯⣿⣦⣙⣋⣵⣿⣿⣦⣌⣛⣽⣿⢯⣟⣧⡟⡼⣘⢧⣿⢻⣿⣿⠟⠐⡉⡒⠬⣁⠎⢦⠙⣃
|
|
||||||
⢜⣩⢠⢠⠄⡄⢠⠄⢂⠄⡀⠙⣷⣿⡿⠿⠛⠋⠉⠉⠁⠀⠀⠀⠉⠈⠉⠉⠙⠛⠻⠾⣽⣷⡍⡖⣻⣿⡿⢣⢆⡣⢵⡉⢆⡥⣚⠦⣛⢤
|
|
||||||
⢎⡔⣣⢎⡝⡸⢥⡺⢌⠴⡱⣬⠟⠁⢀⣠⠴⠶⠶⢛⠛⠋⠛⠛⠻⠶⢦⣄⠀⠀⠀⠀⠀⠈⠛⢧⡝⣿⠁⠜⠂⢧⠐⠈⠐⡄⠃⠘⠀⢂
|
|
||||||
⢞⡼⡱⢞⡜⡳⢤⡙⣆⢦⣱⠏⠀⣰⣿⡃⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣻⣷⡀⠀⠀⠀⠀⠀⠈⢻⡅⡟⣈⠅⡆⢂⠈⡐⠀⠄⡀⠀⠀
|
|
||||||
⠊⠼⠹⡄⡙⡜⢧⣽⢞⣮⡏⠀⢰⣿⣿⡿⢦⡌⣁⠒⠐⠂⠐⠀⠀⠐⢉⣩⣽⡇⠀⠀⠀⠀⠀⠀⠈⣷⣰⡌⠭⣰⢀⡱⠌⢢⠱⢠⠌⡘
|
|
||||||
⡀⠤⠡⡼⢩⠛⠘⠜⡊⢹⡃⠀⠈⣿⣿⣿⣁⣎⣑⣪⣑⣣⣜⣰⢶⡾⡟⣤⣿⡿⠀⠀⠀⠀⠀⠀⠀⢸⣟⠾⡕⡁⣊⠱⢫⢄⠢⣅⢺⡰
|
|
||||||
⠜⣰⢉⠲⣁⠚⡄⠈⡠⢐⡂⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⣿⡆⠙⢿⣧⢺⣥⠊⡑⠼⢲⠱
|
|
||||||
⠑⡀⢎⡐⡡⢧⠙⣜⢣⢽⡇⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⢀⡿⡏⠀⠀⠙⣷⡺⣝⢮⡳⢧⣋
|
|
||||||
⠒⠀⠓⡀⠆⢜⠲⢨⡞⡞⣿⣷⣤⣀⠀⠀⢈⣻⣿⣿⣿⣿⣿⣿⡛⠉⠁⠀⠀⠀⠀⠀⠠⠔⠒⣲⡶⢻⡇⠀⠀⠀⠀⠘⢿⡜⢣⢌⡋⡝
|
|
||||||
⣹⡖⢦⡴⢀⠞⣲⢏⡞⡡⢻⡀⠟⣫⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣦⣴⣦⣽⣷⣾⠟⠋⠁⣸⠀⠀⠀⠀⠹⡄⠘⢧⢡⡘⠲⣉
|
|
||||||
⡣⣽⢲⡍⢯⡘⣷⢫⠔⠡⢻⡆⠀⠐⣿⣿⣽⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠋⠀⠀⢀⡇⠀⠀⠀⠀⠀⠠⣉⢚⣤⢂⠱⡶
|
|
||||||
⣣⡙⢶⣘⣧⢼⡳⠃⡌⠐⣉⣇⠀⠀⠘⣿⣲⢻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠋⠀⠀⠀⡼⠀⠀⠀⠀⠀⠀⠀⢐⠎⣀⠉⠀⡈
|
|
||||||
⢳⣏⢿⣹⣚⢧⡏⠡⢀⠃⢄⢻⡀⠀⠀⠘⢧⢋⢎⠻⡽⢿⢿⣿⣿⢿⡿⡟⢿⣹⡿⠁⠀⠀⠀⣸⠃⠀⠀⠀⠀⠀⠀⠀⠨⢆⡕⡘⠐⣃
|
|
||||||
⣳⡾⣯⠷⠏⣿⠨⠁⠀⠈⢀⠊⢷⡀⠀⠀⠀⠁⠈⠁⠳⠌⠖⠌⠆⠃⠢⠽⠖⠉⠀⠀⠀⢀⣼⠃⢀⠀⠀⠀⠀⠀⠀⠀⠨⢇⠰⠉⠂⠀
|
|
||||||
⣏⢷⡱⣎⢣⣏⠧⡀⠀⠀⠀⡜⢠⠿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⠟⠡⠈⠀⠀⠀⠀⠀⠀⠀⠀⢘⡆⠑⡂⠀⠀
|
|
||||||
⡞⣦⢖⡫⣅⡾⢣⠅⡀⠀⡐⠤⢣⣻⢿⣿⣿⣶⣶⣤⣄⣀⣀⣀⣀⣀⣀⣠⣤⣶⡾⣟⡿⣥⢃⠂⠄⠀⠀⠀⠀⠀⠀⠀⡜⠤⢄⠀⠀⠀
|
|
||||||
⣺⡅⢋⡑⣀⡿⣳⠌⡐⠀⠀⠀⠑⠸⢯⣿⣿⣿⢿⣿⢿⣿⢿⡿⣟⡿⣯⣟⣳⢧⣿⡿⣝⠢⣁⠂⠀⠀⠀⠀⠀⠀⠀⢀⠞⠀⠠⠔⠀⠂
|
|
||||||
⡓⣆⢦⠳⡱⣹⢧⡷⣀⡀⠀⠀⠀⣀⠀⡀⣙⣿⣿⡿⣿⢾⣻⣽⣻⣽⣳⣯⣟⣿⣟⡳⠌⠂⠀⠀⠀⠀⠀⠀⠀⠀⠠⣜⠊⠤⠀⠀⠀⠀
|
|
||||||
⣵⡼⣩⢮⣱⢯⣟⡷⣯⡽⣯⣻⡵⣮⣟⣽⣛⣿⣿⡿⣽⣯⣟⣾⣳⢯⣷⣻⣿⣿⣯⣷⡲⣄⡄⣠⣀⡀⣀⣀⡤⣔⠻⡄⢋⠜⠀⢠⡀⠀
|
|
||||||
*/
|
|
||||||
// Five at nit of fredyer
|
|
||||||
// Hor hor
|
|
||||||
export abstract class Plugin {
|
|
||||||
abstract name: string;
|
|
||||||
abstract rewriteTriggers: string[];
|
|
||||||
renameTo?: string;
|
|
||||||
abstract longLasting: boolean;
|
|
||||||
|
|
||||||
abstract rewriteFile(
|
|
||||||
file: string,
|
|
||||||
filePath: string
|
|
||||||
): Promise<string | undefined | null | void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
import * as fs from "fs";
|
|
||||||
import * as path from "path";
|
|
||||||
|
|
||||||
if (!fs.existsSync("dist")) fs.mkdirSync("dist");
|
|
||||||
|
|
||||||
const plugins: Plugin[] = [];
|
|
||||||
|
|
||||||
for await (const file of fs.readdirSync(path.join("src", "plugins"))) {
|
|
||||||
const clas = (await import(path.join(__dirname, "plugins", file))).default;
|
|
||||||
const plug = new clas();
|
|
||||||
|
|
||||||
plugins.push(plug);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function build() {
|
|
||||||
try {
|
|
||||||
fs.rmdirSync("dist");
|
|
||||||
} catch {}
|
|
||||||
|
|
||||||
const sourceFiles = fs.readdirSync(path.join("website"), {
|
|
||||||
recursive: true,
|
|
||||||
withFileTypes: true,
|
|
||||||
});
|
|
||||||
const globalPlugins = plugins.filter((z) => z.rewriteTriggers.includes("*"));
|
|
||||||
|
|
||||||
for await (const file of sourceFiles) {
|
|
||||||
if (!file.isFile()) continue;
|
|
||||||
|
|
||||||
const type = file.name.split(".").at(-1);
|
|
||||||
if (!type) continue;
|
|
||||||
|
|
||||||
const shortname = file.name.slice(0, file.name.length - (type.length + 1));
|
|
||||||
const availablePlugins = plugins.filter((z) =>
|
|
||||||
z.rewriteTriggers.includes(type)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (availablePlugins.length == 0) {
|
|
||||||
const oldPath = path.join(file.parentPath, file.name);
|
|
||||||
fs.cpSync(oldPath, oldPath.replace("website", "dist"));
|
|
||||||
}
|
|
||||||
|
|
||||||
for await (const plugin of availablePlugins) {
|
|
||||||
const oldPath = path.join(file.parentPath, file.name);
|
|
||||||
const newPath = path
|
|
||||||
.join(
|
|
||||||
file.parentPath,
|
|
||||||
shortname +
|
|
||||||
"." +
|
|
||||||
(plugin.rewriteTriggers.includes("*") ? type : plugin.renameTo)
|
|
||||||
)
|
|
||||||
.replace("website", "dist");
|
|
||||||
let data = fs.readFileSync(oldPath).toString("utf8");
|
|
||||||
|
|
||||||
for await (const globalPlugin of globalPlugins) {
|
|
||||||
const rewritten = await globalPlugin.rewriteFile(data, oldPath);
|
|
||||||
if (!rewritten) continue;
|
|
||||||
data = rewritten;
|
|
||||||
}
|
|
||||||
|
|
||||||
let rewrite = await plugin.rewriteFile(data, oldPath);
|
|
||||||
|
|
||||||
if (!rewrite) continue;
|
|
||||||
|
|
||||||
fs.mkdirSync(path.dirname(newPath), { recursive: true });
|
|
||||||
fs.writeFileSync(newPath, rewrite);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await build();
|
|
|
@ -1,96 +0,0 @@
|
||||||
import type { Server, ServerWebSocket } from "bun";
|
|
||||||
import { Plugin, build } from "..";
|
|
||||||
import * as fs from "fs";
|
|
||||||
import mime from "mime-types";
|
|
||||||
|
|
||||||
const script = `let reconnectTimeout;function connect(){console.log("[--dev] connecting to dev server");let ws=new WebSocket("ws://localhost:8080");ws.addEventListener("message",message=>{if(message.data=="refresh"){location.reload()}});ws.addEventListener("open",()=>{console.log("[--dev] connected")});ws.addEventListener("close",()=>{console.log("[--dev] socket closed, restarting in 1s");clearTimeout(reconnectTimeout);reconnectTimeout=setTimeout(()=>{connect()},1e3)})}window.addEventListener("load",()=>connect());`;
|
|
||||||
|
|
||||||
export default class DevPlugin extends Plugin {
|
|
||||||
name = "dev";
|
|
||||||
rewriteTriggers = [];
|
|
||||||
renameTo = undefined;
|
|
||||||
longLasting = true;
|
|
||||||
server!: Server;
|
|
||||||
allConnections: ServerWebSocket<number>[] = [];
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
if (!process.argv.includes("--dev")) return;
|
|
||||||
|
|
||||||
fs.watch(
|
|
||||||
"./website",
|
|
||||||
{
|
|
||||||
recursive: true,
|
|
||||||
},
|
|
||||||
async (e, f) => {
|
|
||||||
console.log("[dev] Noticed update in " + f + ", of type " + e + ".");
|
|
||||||
this.allConnections.forEach((z) => z.send("refresh"));
|
|
||||||
await build();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.server = Bun.serve<number>({
|
|
||||||
fetch(req, server) {
|
|
||||||
const success = server.upgrade(req);
|
|
||||||
if (success) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const url = new URL(req.url);
|
|
||||||
|
|
||||||
let cleanedPath = url.pathname;
|
|
||||||
if (cleanedPath == "/") cleanedPath = "/index.html";
|
|
||||||
if (cleanedPath.endsWith("/")) cleanedPath = cleanedPath.slice(0, -1);
|
|
||||||
|
|
||||||
let fsPath = "./dist" + cleanedPath;
|
|
||||||
|
|
||||||
if (fsPath.match(/\.\.\//g) !== null) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
let rawFile;
|
|
||||||
try {
|
|
||||||
rawFile = fs.readFileSync(fsPath);
|
|
||||||
} catch {
|
|
||||||
return new Response("404 Not Found", {
|
|
||||||
status: 404,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const type = fsPath.split(".").at(-1);
|
|
||||||
if (!type) return;
|
|
||||||
if (type == "html") {
|
|
||||||
|
|
||||||
rawFile = rawFile.toString().replace(
|
|
||||||
"<head>",
|
|
||||||
`<head><script>${script}</script>`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return new Response(rawFile, {
|
|
||||||
headers: {
|
|
||||||
"Cache-Control": "no-cache, no-store, must-revalidate",
|
|
||||||
"Pragma": "no-cache",
|
|
||||||
"Expires": "0",
|
|
||||||
"Content-Type": (mime.lookup(type) || "application/octet-stream") + "; charset=utf-8",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
websocket: {
|
|
||||||
open: (ws) => {
|
|
||||||
ws.data = Math.random();
|
|
||||||
|
|
||||||
this.allConnections.push(ws);
|
|
||||||
},
|
|
||||||
message(ws, message) {},
|
|
||||||
close: (ws) => {
|
|
||||||
this.allConnections = this.allConnections.filter(
|
|
||||||
(z) => z.data != ws.data
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
port: 8080,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async rewriteFile(file: string, filePath: string) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
import { Plugin } from "..";
|
|
||||||
import { marked } from "marked";
|
|
||||||
import { parseMetadata } from "./markdown-metadata";
|
|
||||||
|
|
||||||
export default class MarkdownCompiler extends Plugin {
|
|
||||||
name = "markdown-compiler";
|
|
||||||
rewriteTriggers = ["md"]
|
|
||||||
renameTo = "html"
|
|
||||||
longLasting = false;
|
|
||||||
|
|
||||||
async rewriteFile(file: string, filePath: string) {
|
|
||||||
let text = file;
|
|
||||||
const metadata = parseMetadata(text);
|
|
||||||
if(metadata) {
|
|
||||||
let textSplit = text.split('\n');
|
|
||||||
textSplit.splice(0, Object.keys(metadata).length);
|
|
||||||
textSplit.unshift(metadata.title)
|
|
||||||
text = textSplit.join("\n");
|
|
||||||
}
|
|
||||||
return await marked.parse(text);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
import { Plugin } from "..";
|
|
||||||
|
|
||||||
export function parseMetadata(file: string) {
|
|
||||||
if (!/^=+$/gm.test(file)) return;
|
|
||||||
const splitfile = file.split("\n");
|
|
||||||
let properties: Record<string, string> | undefined;
|
|
||||||
for (let i = 0; i < splitfile.length; i++) {
|
|
||||||
if (!properties) properties = {};
|
|
||||||
const line = splitfile[i];
|
|
||||||
if (/^=+$/gm.test(line)) break;
|
|
||||||
const parts = line.split("=");
|
|
||||||
if (parts.length !== 2) break;
|
|
||||||
properties[parts[0].trim()] = parts[1].trim();
|
|
||||||
}
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class MarkdownMetadataGenerator extends Plugin {
|
|
||||||
name = "markdown-metadata";
|
|
||||||
rewriteTriggers = ["md"];
|
|
||||||
renameTo = "json";
|
|
||||||
longLasting = false;
|
|
||||||
|
|
||||||
async rewriteFile(file: string, filePath: string) {
|
|
||||||
const metadata = parseMetadata(file);
|
|
||||||
if (!metadata) return;
|
|
||||||
return JSON.stringify(metadata);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
import { Plugin } from "..";
|
|
||||||
import * as fs from "fs";
|
|
||||||
import * as esbuild from "esbuild";
|
|
||||||
|
|
||||||
export default class TSCompiler extends Plugin {
|
|
||||||
name = "ts-compiler";
|
|
||||||
rewriteTriggers = ["ts", "tsx", "jsx"];
|
|
||||||
renameTo = "js";
|
|
||||||
longLasting = false;
|
|
||||||
|
|
||||||
minify = false;
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
if (process.argv.includes("--prod")) {
|
|
||||||
this.minify = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async rewriteFile(file: string, filePath: string) {
|
|
||||||
let result;
|
|
||||||
try {
|
|
||||||
result = await esbuild.build({
|
|
||||||
stdin: {
|
|
||||||
contents: file,
|
|
||||||
resolveDir: filePath.split("/")?.slice(0, -1).join("/"),
|
|
||||||
sourcefile: filePath.split("/").at(-1),
|
|
||||||
loader: filePath.split("/").at(-1)?.split(".").at(-1) as
|
|
||||||
| "ts"
|
|
||||||
| "tsx"
|
|
||||||
| "jsx",
|
|
||||||
},
|
|
||||||
jsxFragment: "Fragment",
|
|
||||||
jsxFactory: "h",
|
|
||||||
jsxImportSource: "preact",
|
|
||||||
jsx: "transform",
|
|
||||||
write: false,
|
|
||||||
bundle: true,
|
|
||||||
outdir: "out",
|
|
||||||
minify: this.minify,
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
console.log("Errored!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.errors.length != 0) {
|
|
||||||
console.log("TS compiler errored.");
|
|
||||||
result.errors.forEach((element) => {
|
|
||||||
console.error(element);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const output = result.outputFiles[0].contents;
|
|
||||||
return new TextDecoder().decode(output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
import { Plugin } from "..";
|
|
||||||
import * as fs from "fs";
|
|
||||||
import * as path from "path";
|
|
||||||
|
|
||||||
export default class Variables extends Plugin {
|
|
||||||
name = "variables";
|
|
||||||
rewriteTriggers = ["html", "*"];
|
|
||||||
renameTo = undefined;
|
|
||||||
longLasting = false;
|
|
||||||
|
|
||||||
variables: Record<string, string> = {};
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.variables["__BLOG_POSTS__"] = JSON.stringify(
|
|
||||||
fs.readdirSync("./website/blogs").map((z) => z.replace(".md", ""))
|
|
||||||
);
|
|
||||||
const templatePath = path.resolve(__dirname, "../../website/templates");
|
|
||||||
if (fs.existsSync(templatePath)) {
|
|
||||||
for (const file of fs.readdirSync(templatePath)) {
|
|
||||||
const id = file.toUpperCase().replace(".HTML", "");
|
|
||||||
this.variables["__TEMPLATE_" + id + "__"] = fs
|
|
||||||
.readFileSync(path.join(templatePath, file))
|
|
||||||
.toString("utf8");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async rewriteFile(file: string, filePath: string): Promise<string> {
|
|
||||||
let prevfile = file;
|
|
||||||
for (const a of Object.entries(this.variables)) {
|
|
||||||
prevfile = prevfile.replaceAll(a[0], a[1]);
|
|
||||||
}
|
|
||||||
return prevfile;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
# sad.ovh build system
|
|
||||||
|
|
||||||
design goals:
|
|
||||||
1. rewrite and generate custom HTML/TS/JS/whatever..
|
|
||||||
2. allow for variables and other important features in buildsystem->html
|
|
||||||
3. plugins, this ties together the top two
|
|
||||||
4. HMR and HTML/CSS reloading (in the Dev plugin)
|
|
||||||
5. Rewriteable file renaming
|
|
||||||
6. Every plugin runs on the same set of files, and can rename and reinject multiple times
|
|
||||||
|
|
||||||
Psudeo-code build.ts
|
|
||||||
|
|
||||||
```ts
|
|
||||||
class Plugin {
|
|
||||||
.. whatever's needed to support the plugin system ..
|
|
||||||
}
|
|
||||||
|
|
||||||
if(.. not exist dist ..)
|
|
||||||
.. make dist ..
|
|
||||||
const plugins: Plugin[] = [];
|
|
||||||
.. dynamically load plugins into plugins ..
|
|
||||||
|
|
||||||
const srcFiles: File[] = []
|
|
||||||
.. get files into file ..
|
|
||||||
|
|
||||||
|
|
||||||
export function build () {
|
|
||||||
for(const file of srcFiles) {
|
|
||||||
const plugins = plugins.filter(z=>z.rewriteTriggers(file.type));
|
|
||||||
if(plugins.length == 0) continue;
|
|
||||||
|
|
||||||
for (const plugin of plugins) {
|
|
||||||
let filename = file.name + "." + file.type;
|
|
||||||
let newFilename = path.join("dist", file.name + "." + plugin.renameTo || file.type);
|
|
||||||
|
|
||||||
fs.writeFileSync(newFilename, plugin.rewriteFile(fs.readFileSync(filename), filename))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
build();
|
|
||||||
|
|
||||||
```
|
|
||||||
Psudeo-code plugins
|
|
||||||
```ts
|
|
||||||
class DevPlugin extends Plugin {
|
|
||||||
rewriteTriggers: ["html"]
|
|
||||||
renameTo: undefined
|
|
||||||
longLasting: false;
|
|
||||||
.. websocket server ..
|
|
||||||
constructor(.. options from argv of the main executable..) {
|
|
||||||
.. ran on start of main index.ts executable ..
|
|
||||||
.. this would be long lasting, so leave if not using --dev ..
|
|
||||||
|
|
||||||
.. use a method on the server that rebuilds if required ..
|
|
||||||
.. Would run a web server too ..
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
rewriteFile(file: string, filePath: string) {
|
|
||||||
return file.replace("<head>", `<head><script>${script}</script>`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
class TSCompiler extends Plugin {
|
|
||||||
rewriteTriggers: ["ts"]
|
|
||||||
renameTo: "js"
|
|
||||||
|
|
||||||
rewriteFile(file: string, filePath: string) {
|
|
||||||
// use SWC or TS or esbuild, whatever
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
class MarkdownMetadataGenerator extends Plugin {
|
|
||||||
rewriteTriggers: ["md"]
|
|
||||||
renameTo: "json"
|
|
||||||
|
|
||||||
rewriteFile(file: string, filePath: string) {
|
|
||||||
return marked.parse(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
class MarkdownCompiler extends Plugin {
|
|
||||||
rewriteTriggers: ["md"]
|
|
||||||
renameTo: "html"
|
|
||||||
|
|
||||||
rewriteFile(file: string, filePath: string) {
|
|
||||||
return marked.parse(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -2,7 +2,6 @@ import { useEffect, useState } from "preact/hooks";
|
||||||
import type { Metadata } from "./blog";
|
import type { Metadata } from "./blog";
|
||||||
import { Giscus } from "./giscus";
|
import { Giscus } from "./giscus";
|
||||||
|
|
||||||
|
|
||||||
export function BlogPost({ pageOpen }: { pageOpen: [Metadata | undefined, (z: Metadata | undefined) => void] }) {
|
export function BlogPost({ pageOpen }: { pageOpen: [Metadata | undefined, (z: Metadata | undefined) => void] }) {
|
||||||
if (!pageOpen[0]) return <h1>How did you get to here..?</h1>;
|
if (!pageOpen[0]) return <h1>How did you get to here..?</h1>;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue