diff options
| author | Alexis Hovorka <[email protected]> | 2022-02-02 00:06:53 -0700 | 
|---|---|---|
| committer | Alexis Hovorka <[email protected]> | 2022-02-02 00:06:53 -0700 | 
| commit | 8a943500d97598a0b49ef655dc1b5484fe5e83d8 (patch) | |
| tree | 339daf640084d724524c3cfcf92e51f48f7037b0 /lib/router.js | |
Initial commit
Diffstat (limited to 'lib/router.js')
| -rw-r--r-- | lib/router.js | 53 | 
1 files changed, 53 insertions, 0 deletions
| diff --git a/lib/router.js b/lib/router.js new file mode 100644 index 0000000..fd24693 --- /dev/null +++ b/lib/router.js @@ -0,0 +1,53 @@ +"use strict"; // https://github.com/mixu/minimal + +const url = require("url"); +const degroup = path => Object.assign(path, path.groups); + +class Router { +  constructor() { +    this.routes = []; +  } + +  route(req, res) { +    const pathname = url.parse(req.url).pathname; +    return this.routes.some(route => { +      const isMatch = route.method === req.method && route.re.test(pathname); +      if (isMatch) route.cb(req, res, degroup(route.re.exec(pathname))); +      return isMatch; +    }); +  } + +  gather(cb, max) { // Handle POST data +    return (req, res, match) => { +      let data = ""; +      req.on("data", chunk => { +        if ((data += chunk).length > (max||1e6)) // ~1MB +          req.connection.destroy(); +      }).on("end", () => cb(req, res, match, data)); +    }; +  } + +  gpost(re, cb, max) { +    this.post(re, this.gather(cb, max)); +  } + +  jpost(re, cb, max) { +    this.gpost(re, (req, res, match, data) => { +      try { +        data = JSON.parse(data); +      } catch (e) { +        res.writeHead(400, {"Content-Type": "text/plain"}); +        return res.end("400 Bad Request"); +      } + +      cb(req, res, match, data); +    }, max); +  } +} + +["get", "post", "put", "delete"].forEach(method => +  Router.prototype[method] = function(re, cb) { +    this.routes.push({method: method.toUpperCase(), cb, +      re: (re instanceof RegExp)? re : new RegExp(`^${re}$`)})}); + +module.exports = Router; | 
