Last active
November 15, 2019 12:36
-
-
Save Saul-Mirone/00a9ac8082d1caa74f64bbb96aa09939 to your computer and use it in GitHub Desktop.
Just An Express Style Framework
This file contains 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
const http = require('http') | |
const url = require('url') | |
const path = require('path') | |
const fs = require('fs') | |
const mime = { | |
"html": "text/html", | |
"css": "text/css", | |
"js": "text/javascript", | |
"json": "application/json", | |
"gif": "image/gif", | |
"ico": "image/x-icon", | |
"jpeg": "image/jpeg", | |
"jpg": "image/jpeg", | |
"png": "image/png" | |
} | |
function handleStatic(res, pathname, ext) { | |
fs.exists(pathname, (exists) => { | |
if(!exists) { | |
res.writeHead(404, {'Content-Type': 'text/plain'}) | |
res.write('The request url' + pathname + 'was not found on this server') | |
res.end() | |
} else { | |
fs.readFile(pathname, (err, file) => { | |
if(err) { | |
res.writeHead(500, {'Content-Type': 'text/plain'}) | |
res.end(err) | |
} else { | |
const contentType = mime[ext] || 'text/plain' | |
res.writeHead(200, {'Content-Type': contentType}) | |
res.write(file) | |
res.end() | |
} | |
}) | |
} | |
}) | |
} | |
const lazy = function* (arr) { | |
yield* arr; | |
} | |
const passRouter = (routes, method, path) => (req, res) => { | |
const replaceParams = (path) => new RegExp(`\^${path.replace(/:\w[^\/]+/g, '\\w[^\/]+')}\$`); | |
const lazyRoutes = lazy(routes); | |
(function next () { | |
const it = lazyRoutes.next().value; | |
if (!it) { | |
res.end(`Cannot ${method} ${path}`) | |
return; | |
} else if (it.method === 'use' | |
&& (it.path === '/' | |
|| it.path === path | |
|| path.startsWith(it.path.concat('/')))) { | |
it.fn(req, res, next); | |
} else if ((it.method === method | |
|| it.method === 'all') | |
&& (it.path === path | |
|| it.path === '*')) { | |
it.fn(req, res); | |
} else if ( it.path.includes(':') | |
&& (it.method === method | |
|| it.method === 'all') | |
&& (replaceParams(it.path).test(path))) { | |
let index = 0; | |
const param2Array = it.path.split('/'); | |
const path2Array = path.split('/'); | |
const params = {}; | |
param2Array.forEach((path) => { | |
if(/\:/.test(path)) { | |
params[path.slice(1)] = path2Array[index] | |
} | |
index++ | |
}) | |
req.params = params | |
it.fn(req, res); | |
} else { | |
next(); | |
} | |
}()); | |
}; | |
function core() { | |
let _static = 'static' | |
let app = (req, res) => { | |
const method = req.method.toLowerCase() | |
const urlObj = url.parse(req.url, true) | |
const pathname = urlObj.pathname | |
const ext = path.extname(pathname).slice(1) | |
if(ext) { | |
handleStatic(res, _static + pathname, ext) | |
} else { | |
passRouter(app.routes, method, pathname)(req, res) | |
} | |
} | |
app.setStatic = (path) => { | |
_static = path | |
} | |
app.routes = [] | |
const methods = ['get', 'post', 'put', 'options', 'delete', 'all', 'use'] | |
methods.forEach((method) => { | |
app[method] = (path, fn) => { | |
app.routes.push({ | |
method: method, | |
path: path, | |
fn: fn | |
}) | |
} | |
}) | |
app.use = (path, fn) => { | |
app.routes.push({ | |
method: 'use', | |
path: path, | |
fn: fn | |
}) | |
} | |
app.listen = (port=3000, host='localhost') => { | |
http.createServer(app).listen(port, host, () => { | |
console.log(`Server running at ${host}\:${port}.`) | |
process.setMaxListeners(0) | |
process.on('uncaughtException', function(err) { | |
console.log(err.stack) | |
}) | |
process.stdin.resume() | |
process.on('SIGINT', function() { | |
console.log('\n') | |
console.log('Good Day!') | |
process.exit(2) | |
}) | |
}) | |
} | |
return app | |
} | |
module.exports = core |
Author
Saul-Mirone
commented
Dec 19, 2016
•
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment