src/router.mjs gelöscht
This commit is contained in:
parent
930f232a93
commit
ad1536ff2e
200
src/router.mjs
200
src/router.mjs
@ -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;
|
||||
};
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user