src/router.mjs gelöscht
This commit is contained in:
		
							
								
								
									
										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;
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user