commit 110c3ddb0e750008dd7ae3b3d9ec8da87c1acae5 Author: Flummi Date: Sun Mar 22 01:58:00 2020 +0100 first commit diff --git a/package.json b/package.json new file mode 100644 index 0000000..45c206e --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "flumm-express", + "version": "1.0.0", + "description": "Express für arme", + "main": "src/index.mjs", + "repository": { + "type": "git", + "url": "git@github.com:kein-Bot/flummpress.git" + }, + "scripts": {}, + "author": "Flummi", + "license": "MIT", + "bugs": { + "url": "https://github.com/kein-Bot/flummpress/issues" + }, + "homepage": "https://github.com/kein-Bot/flummpress#readme" +} diff --git a/src/index.mjs b/src/index.mjs new file mode 100644 index 0000000..7bde947 --- /dev/null +++ b/src/index.mjs @@ -0,0 +1,37 @@ +import http from "http"; +import path from "path"; +import url from "url"; +import querystring from "querystring"; + +import router from "./router.mjs"; +import views from "./views.mjs"; + +export default class flummpress { + constructor(opts) { + this.Router = router; + this.views = views; + this.opts = { ...{ + views: path.resolve() + "/src/views", + routes: path.resolve() + "/src/routes" + }, ...opts }; + return (async () => { + await router.loadRoutes(this.opts.routes); + await views.loadViews(this.opts.views); + return this; + })(); + } + listen(...args) { + return http.createServer((req, res, r) => { + req.url = url.parse(req.url.replace(/(?!^.)(\/+)?%/, '')); + req.url.qs = querystring.parse(req.url.query); + + req.post = new Promise((resolve, _, data = "") => req + .on("data", d => void (data += d)) + .on("end", () => void resolve(Object.fromEntries(Object.entries(querystring.parse(data)).map(([k, v]) => [k, decodeURIComponent(v)]))))); + + console.log(`[${(new Date()).toLocaleTimeString()}] ${req.method} ${req.url.pathname}`); + + !(r = router.routes.getRegex(req.url.pathname, req.method)) ? res.writeHead(404).end(`404 - ${req.url.pathname}`) : r(req, res); + }).listen(...args); + } +}; diff --git a/src/router.mjs b/src/router.mjs new file mode 100644 index 0000000..9a401c3 --- /dev/null +++ b/src/router.mjs @@ -0,0 +1,28 @@ +import { promises as fs } from "fs"; + +export default new class { + constructor() { + this.routes = new Map(); + } + async loadRoutes(path) { + await Promise.all( + (await fs.readdir(path)) + .filter(f => f.endsWith(".mjs")) + .map(async route => await import(`${path}/${route}`)) + ); + } + route(method, args) { + this.routes.set(args[0], { method: method, f: args[1] }); + console.log("route set", method, args[0]); + } + get() { + this.route("GET", arguments); + } + post() { + this.route("POST", arguments); + } +}; + +Map.prototype.getRegex = function(path, method) { + return [...this.entries()].filter(r => r[0].exec(path) && r[1].method.includes(method))[0]?.[1].f; +}; diff --git a/src/views.mjs b/src/views.mjs new file mode 100644 index 0000000..724120a --- /dev/null +++ b/src/views.mjs @@ -0,0 +1,15 @@ +import { promises as fs } from "fs"; + +export default new class { + constructor() { + this.views = new Map(); + } + get(view) { + return this.views.get(view) || false; + } + async loadViews(path) { + (await fs.readdir(path)) + .filter(view => view.endsWith(".html")) + .forEach(async view => this.views.set(view.slice(0, -5), await fs.readFile(`${path}/${view}`))); + } +};