Security News
tea.xyz Spam Plagues npm and RubyGems Package Registries
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
beeline
Advanced tools
Readme
A laughably simplistic router for node.js
Currently works with node.js v0.3.1 and above
var bee = require("beeline");
var router = bee.route({ // Create a new router
"/cheggit": function(req, res) {
// Called when req.url === "/cheggit" or req.url === "/cheggit?woo=poo"
},
"/names/`last-name`/`first-name`": function(req, res, tokens, values) {
// Called when req.url contains three parts, the first of is "name".
// The parameter tokens is an object that maps token names to values.
// For example if req.url === "/names/smith/will"
// then tokens === { "first-name": "will", "last-name": "smith" }
// and values === [ "will", "smith" ]
// also req.params === tokens
},
"/static/`path...`": function(req, res, tokens, values) {
// Called when req.url starts with "/static/"
// The parameter tokens is an object that maps token name to a value
// The parameter values is a list of
// For example if req.url === "/static/pictures/actors/smith/will.jpg"
// then tokens === { "path": "pictures/actors/smith/will.jpg" }
// and values === [ "pictures/actors/smith/will.jpg" ]
// also req.params === tokens
},
"/`user`/static/`path...`": function(req, res, tokens, values) {
// Called when req.url contains at least three parts, the second of which
// is "static".
// The parameter tokens is an object that maps token names and value
// For example if req.url === "/da-oozer/static/pictures/venkman.jpg"
// then tokens === { "user": "da-oozer", "path": "pictures/venkman.jpg" }
// and values === [ "da-oozer", "pictures/venkman.jpg" ]
// also req.params === tokens
},
"/blogs/`user-id: [a-z]{2}-\\d{5}`/`post-id: \\d+`": function(
req, res, tokens, values
) {
// Called when req.url starts with "/blogs/" and when the second and third
// parts match /[a-z]{2}-\d{5}/ and /\d+/ respectiviely.
// The parameter tokens is an object that maps token names and value
// For example if req.url === "/blog/ab-12345/1783"
// then tokens === { "user-id": "ab-12345", "post-id": "1783" }
// and values === [ "ab-12345", "1783" ]
// also req.params === tokens
},
"r`^/actors/([\\w]+)/([\\w]+)$`": function(req, res, matches) {
// Called when req.url matches this regex: "^/actors/([\\w]+)/([\\w]+)$"
// An array of captured groups is passed as the third parameter
// For example if req.url === "/actors/smith/will"
// then matches === [ "smith", "will" ]
},
"`404`": function(req, res) {
// Called when no other route rule are matched
//
// This handler can later be called explicitly with router.missing
},
"`500`": function(req, res, err) {
// Called when an exception is thrown by another router function
// The error that caused the exception is passed as the third parameter
// This _not_ guaranteed to catch all exceptions
//
// This handler can later be called explicitly with router.error
}
});
router.add({ // Use `.add` to append new rules to a router
"/ /home r`^/index(.php|.html|.xhtml)?$`": function(req, res) {
// Called when req.url === "/" or req.url === "/home"
// or req.url matches this regex: ^/index(.php|.html|.xhtml)?$
// (i.e. req.url === "/index.php" or req.url === "/index.html")
// Note that any number of rules can be combined using a space.
// All rules will call the same request handler when matched.
},
"/my-method": { // Method (aka verb) specific dispatch. Note case matters.
"GET": function(req, res) {
// Called when req.url === "/my-method" and req.method === "GET"
},
"POST PUT": function(req, res) {
// Called when req.url === "/my-method" and
// req.method === "POST" or req.method === "PUT"
// Methods can be combined with a space like URL rules.
},
"any": function(req, res) {
// Called when req.url === "/my-method" and req.method is not
// "GET" or "POST"
}
},
"`405`": function(req, res) {
// Called when when a URL is specified but no corresponding method (aka verb)
// matches. For example, this handler would be executed if the "any" catch
// all wasn't specified in the handler above and req.method === "HEAD"
//
// This handler can later be called explicitly with router.missingVerb
},
"/explicit-calls": function(req, res) { // If necessary you can reroute requests
if(url.parse(req.url).query["item-name"] === "unknown") {
// Calls the 404 (aka missing) handler:
return router.missing(req, res, this);
// The last parameter is optional. It sets the this pointer in the
// 404 handler.
}
if(url.parse(req.url).query["item-name"] === "an-error") {
// Calls the 500 (aka error) handler:
return router.error(req, res, err, this);
// The last parameter is optional. It sets the this pointer in the
// 500 handler.
}
// Do normal request handling
}
});
// Starts serve with routes defined above:
require("http").createServer(router).listen(8001);
See test/test.js
for a working example.
To start, simply store the beeline
library in a local variable:
var bee = require("beeline");
The beeline
library contains the following three methods:
bee.route(routes)
: Used to create a new router. It returns a function called rtn_fn
that takes ServerRequest and ServerResponse objects as parameters. The routes
parameter is an objects that maps rules to handlers. See examples section for more details.
bee.staticFile(path, mimeType[, maxage=31536000])
: This is a utility method that is used to quickly expose static files. It returns a function called rtn_fn
that takes ServerRequest and ServerResponse objects as parameters. When rtn_fn
is called, the file contents located at path
are served (via the ServerResponse) with the Content-Type
set to the mimeType
parameter. If the file at path
does not exist a 404
is served. The optional maxage
parameter is used to in the response's Cache-Control
header. Also note that all Set-Cookie
headers are removed. Here's an example of how you might use bee.staticFile
:
bee.route({
"/robots.txt": bee.staticFile("./content/robots.txt", "text/plain")
});
bee.staticDir(path, mimeTypes[, maxage=31536000])
: This is utility method is used to expose directories of files. It returns a function called rtn_fn
that takes a ServerRequest object, a ServerResponse object, an optional third parameter, and an array of strings called matches
as parameters. Whenever rtn_fn
is called, the items of matches
are joined together and then concatenated to path
. The resulting string is assumed to be a path to a specific file. If this file exists, its contents are served (via the ServerResponse) with the Content-Type
set to the value that corresponds to the file's extension in the mimeTypes
object. If the resulting string doesn't point to an existing file or if the file's extension is not found in mimeTypes
, then a 404
is served. Also, file extensions require a leading period (.
) and are assumed to be lowercase. The optional maxage
parameter is used to in the response's Cache-Control
header. Also note that all Set-Cookie
headers are removed. Here's an example of how you might use bee.staticDir
:
bee.route({
// /pics/mofo.png serves ./content/pics/mofo.png
// /pics/la-ghetto/oh-gee.gif serves ./content/pics/la-ghetto/oh-gee.gif
// /pics/woo-fee.tiff serves a 404 since there's no corresponding
// mimeType specified.
// This helps prevent accidental exposure.
"r`^/pics/(.*)$`": bee.staticDir(
"./content/pics/",
{
".gif": "image/gif", ".png": "image/png",
".jpg": "image/jpeg", ".jpeg": "image/jpeg"
}
),
// Also works with URLs with tokens
// /static/help/faq.html serves ./static/help/faq.html
// /static/properties.json serves a 404 since there's no corresponding
// mimeType specified.
"/static/`path...`": bee.staticDir(
"./static/",
{
".txt": "text/plain", ".html": "text/html",
".css": "text/css", ".xml": "text/xml"
}
),
// More complicated path constructs also works
// /will-smith/img-library/headshots/sexy42.jpg
// serves ./user-images/will-smith/headshots/sexy42.jpg
"/`user`/img-library/`path...`": bee.staticDir(
"./user-images/", { ".jpg": "image/jpeg", ".jpeg": "image/jpeg" }
)
});
Beeline is also at least somewhat compatibile with expressjs. Here's an example:
app.use(beeline.route({
"/": function(req, res, next) {
fs.readFile("./templates/index.html", function(err, data) {
if(err) { throw err; }
res.html(data);
});
},
"/`user`/static/`path...`": function(req, res, tokens, values, next) {
/* ... code ... */
}
}));
Note the next
callback is always passed as the last parameter.
In the event that a request matches two rules, the following precedence rules are considered:
"/index"
has a higher precedences then "r`^/index$`"
even though semantically both rules are exactly the same.404
404
and 405
have the lowest precedences500
rules is outside the precedence rules. It can potentially be triggered at any time.If the exact same rule is defined twice, then it's unspecified which request handler will be triggered.
The easiest way to get beeline is with npm:
npm install beeline
Alternatively you can clone this git repository:
git clone git://github.com/xavi-/beeline.git
Execute the following commands to run the beeline's unit tests:
$ cd <beeline-directory>
$ cd test
$ node test.js
The last line printed to the console should be, "All done. Everything passed.", if all the tests passed successfully.
This project is released under The MIT License.
FAQs
A laughably simplistic router for node.js
The npm package beeline receives a total of 99 weekly downloads. As such, beeline popularity was classified as not popular.
We found that beeline demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
Security News
As cyber threats become more autonomous, AI-powered defenses are crucial for businesses to stay ahead of attackers who can exploit software vulnerabilities at scale.
Security News
UnitedHealth Group disclosed that the ransomware attack on Change Healthcare compromised protected health information for millions in the U.S., with estimated costs to the company expected to reach $1 billion.