Last active
September 19, 2018 18:55
-
-
Save friendlyanon/2dbaacb858bab49e0e6b1ac2ce8d1f51 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Server } from "_http_server"; | |
const Aya = class Aya { | |
constructor() { | |
this.routes = { | |
GET: [], | |
HEAD: [], | |
POST: [], | |
PUT: [], | |
DELETE: [], | |
CONNECT: [], | |
OPTIONS: [], | |
TRACE: [], | |
PATCH: [], | |
}; | |
this.middleware = []; | |
} | |
use(func) { | |
return this.middleware.push(func), this; | |
} | |
route(method, route, ...func) { | |
const upper = method.toUpperCase(); | |
if ( | |
!this.routes.hasOwnProperty(upper) || | |
typeof route !== "string" | |
) throw new Error("Invalid route setup"); | |
this.routes[upper].push([ | |
route.split("/").slice(1).filter(this._validateRoute), | |
func | |
]); | |
return this; | |
} | |
start(port) { | |
this.server = new this._Server(this._serverHandler).listen({ port }); | |
this.server.__ayaInstance = this; | |
console.log("Listening on port %i", port); | |
} | |
_serverHandler(req, res) { | |
const self = this.__ayaInstance; | |
self._handler(req, res, self.routes, self.middleware); | |
} | |
_validateRoute(str) { | |
return str.length > 0; | |
} | |
async _handler(req, res, routes, middleware) { | |
try { for (const f of middleware) await f(req, res); } | |
catch (err) { return res.end(err.message); } | |
const path = req.url.split("/").filter(this._validateRoute); | |
const pathLen = path.length; | |
let fns; | |
for (const { 0: info, 1: funcs } of routes[req.method]) { | |
if (pathLen !== info.length) continue; | |
const params = {}; | |
let j = 0; | |
for (let len = info.length; j < len; ++j) { | |
const part = info[j]; | |
if (part.charCodeAt() === 58) params[part.substring(1)] = path[j]; | |
else if (path[j] !== part) break; | |
} | |
if (j !== info.length) continue; | |
req.params = params; | |
fns = funcs; | |
break; | |
} | |
if (fns == null) return res.end("Invalid route"); | |
try { | |
const { hasOwnProperty: has } = arguments; | |
for (const f of fns) { | |
if (typeof f === "function") await f(req, res); | |
else for (const k in f) if (has.call(f, k)) req[k] = f[k]; | |
} | |
} | |
catch (err) { res.end(err.message); } | |
} | |
}; // class Aya | |
// enumerable properties in the prototype chain are verboten | |
Object.defineProperties(Aya.prototype, { | |
_Server: { | |
value: Server, | |
writable: true, | |
configurable: true, | |
}, | |
}); | |
Object.defineProperties(Aya, { | |
Aya: { | |
value: Aya, | |
writable: true, | |
configurable: true, | |
}, | |
}); | |
export default Aya; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment