src/router.mjs gelöscht

This commit is contained in:
Flummi 2025-03-15 13:24:55 +00:00
parent 930f232a93
commit ad1536ff2e

@ -1,200 +0,0 @@
import fs from "fs";
import path from "path";
import Tpl from "./template.mjs";
export default class Router {
#mimes;
constructor() {
this.routes = new Map();
return this;
};
async importRoutesFromPath(p, tpl = false) {
for(let tmp of await fs.promises.readdir(path.resolve() + '/' + p, { withFileTypes: true }))
if(tmp.isFile() && tmp.name.endsWith('.mjs'))
this.use((await import(`${path.resolve()}/${p}/${tmp.name}`)).default(this, tpl));
else if(tmp.isDirectory())
await this.importRoutesFromPath(p + '/' + tmp.name);
return this;
};
group(path, cb) {
const methods = {
get: this.get.bind(this),
post: this.post.bind(this),
head: this.head.bind(this),
put: this.put.bind(this),
delete: this.delete.bind(this),
patch: this.patch.bind(this),
};
const target = {
path: new RegExp(path),
};
const handler = {
get: (opt, method) => (p, ...args) => methods[method](
new RegExp([ opt.path, new RegExp(p === "/" ? "$": p) ]
.map(regex => regex.source)
.join("")
.replace(/(\\\/){1,}/g, "/")),
...args,
)
};
cb(new Proxy(target, handler));
return this;
};
use(obj) {
if(obj instanceof Router) {
this.routes = new Map([ ...this.routes, ...obj.routes ]);
this.sortRoutes();
}
if(obj instanceof Tpl) {
this.tpl = obj;
}
}
get(path, ...args) {
if(args.length === 1)
this.registerRoute(path, args[0], "get");
else
this.registerRoute(path, args[1], "get", args[0]);
return this;
};
post(path, ...args) {
if(args.length === 1)
this.registerRoute(path, args[0], "post");
else
this.registerRoute(path, args[1], "post", args[0]);
return this;
};
head(path, ...args) {
if(args.length === 1)
this.registerRoute(path, args[0], "head");
else
this.registerRoute(path, args[1], "head", args[0]);
return this;
};
put(path, ...args) {
if(args.length === 1)
this.registerRoute(path, args[0], "put");
else
this.registerRoute(path, args[1], "put", args[0]);
return this;
};
delete(path, ...args) {
if(args.length === 1)
this.registerRoute(path, args[0], "delete");
else
this.registerRoute(path, args[1], "delete", args[0]);
return this;
};
patch(path, ...args) {
if(args.length === 1)
this.registerRoute(path, args[0], "patch");
else
this.registerRoute(path, args[1], "patch", args[0]);
return this;
};
registerRoute(path, cb, method, middleware) {
if(!this.routes.has(path))
this.routes.set(path, {});
this.routes.set(path, {
...this.routes.get(path),
[method]: cb,
[method + "mw"]: middleware,
});
console.log("route set:", method.toUpperCase(), path);
this.sortRoutes();
return this;
};
getRoute(path, method) {
method = method.toLowerCase();
return [...this.routes.entries()].filter(r => {
return (r[0] === path || r[0].exec?.(path)) && r[1].hasOwnProperty(method);
})[0];
};
sortRoutes() {
this.routes = new Map([...this.routes.entries()].sort().reverse());
return this;
};
readMimes(file = "/etc/mime.types") {
this.#mimes = new Map();
(fs.readFileSync(file, "utf-8"))
.split("\n")
.filter(e => !e.startsWith("#") && e)
.map(e => e.split(/\s{2,}/))
.filter(e => e.length > 1)
.forEach(m => m[1].split(" ").forEach(ext => this.#mimes.set(ext, m[0])));
};
static({ dir = path.resolve() + "/public", route = /^\/public/ }) {
if(!this.#mimes)
this.readMimes();
this.get(route, (req, res) => {
try {
const filename = req.url.pathname.replace(route, "") || "index.html";
const mime = this.#mimes.get(filename.split(".").pop());
const file = path.join(dir, filename);
let stat;
try {
stat = fs.statSync(file);
} catch(err) {
console.log(err);
res.reply({
code: 404,
body: "404 - file not found."
});
return this;
}
if(!mime.startsWith("video") && !mime.startsWith("audio")) {
res.writeHead(200, {
"Content-Length": stat.size,
"Content-Type": this.#mimes.get(filename.split(".").pop()).toLowerCase()
}).end(fs.readFileSync(path.join(dir, filename)));
return this;
}
if(req.headers.range) {
const parts = req.headers.range.replace(/bytes=/, "").split("-");
const start = parseInt(parts[0], 10);
const end = parts[1] ? parseInt(parts[1], 10) : stat.size - 1;
res.writeHead(206, {
"Content-Range": `bytes ${start}-${end}/${stat.size}`,
"Accept-Ranges": "bytes",
"Content-Length": (end - start) + 1,
"Content-Type": mime,
});
const stream = fs.createReadStream(file, { start: start, end: end })
.on("open", () => stream.pipe(res))
.on("error", err => res.end(err));
}
else {
res.writeHead(200, {
"Content-Length": stat.size,
"Content-Type": mime,
});
fs.createReadStream(file).pipe(res);
}
} catch(err) {
console.error(err);
res.reply({
code: 500,
body: "500 - internal server error"
});
}
});
return this;
};
};