npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

fsbr

v2.0.0

Published

file structure based router for servers

Downloads

95

Readme

npm version types size coverage License

file structure based router for servers

Installation

$ npm i fsbr

Usage

Native

import router from 'fsbr';
import {createServer} from 'http';

const {use, register, route} = router();

// will be invoked on every request, before the route
use((req, res, next) => {
    // do middleware things
    return next();
});

register('./routes');

// will be invoked if no route was found
use((_req, res) => {
    res.statusCode = 404;
    res.end('Not Found');
});

use((req, res, next, error) => {
    // handle error
    return next(error);
});

const server = createServer(route);
server.listen(8080);

Express

import router from 'fsbr';
import express from 'expess';

const app = express();
const {use, register, route} = router();

// will be invoked on every request, before the route
use((req, res, next) => {
    // do middleware things
    return next();
});

use((req, res, next, error) => {
    // handle error
    return next(error);
});

register('./routes');

// will be invoked if no route was found
use((_req, res) => {
    res.statusCode = 404;
    res.end('Not Found');
});

app.use(route);
app.listen(3000);

API

  • fsbr(config)
  • router.on()
  • router.has()
  • router.use()
  • router.chain()
  • router.route()
  • router.register()

Library

fsbr(config: Config)

Config

| | default | description | |:--------|:--------|:-------------------------------------------| | ext | .js | extension of middleware and listener files | | entry | index | name of middleware files e.g. middleware |

Creates a new fsbr instance.

import router from 'fsbr';

const {on, use, chain, register, route} = router();

router.on(method, path, listener)

Registers a route. A Method can be any known HTTP method/verb or a wildcard *. Paths can contain a variable denoted via a semicolon. In this case, listeners receive a third optional argument with the resolved variable. Paths can also have a wildcard. fsbr will match every request after that.

const {on} = router();

// plain route
on('POST', '/post', (req, res) => {
    //
});

// route with id parameter
on('GET', '/user/:id', (req, res, params) => {
    const {id} = params;
});

// route with wildcard method
// any request with any HTTP method/verb on this route executes the listener
on('*', '/foo', (req, res) => {
    //
});

// route with wildcard in pathname
// any request with '/proxy/...' executes the listener
on('GET', '/proxy/*', (req, res) => {
    //
});

router.has(method, path)

Returns true, if the route exists.

const {has} = router();

has('POST', '/post');

router.use(middleware)

Registers a middleware function to the router. Middlewares with 4 parameters are considered as error listeners. Note the order. The error parameter here should be on the fourth place, unlike in other frameworks like express.

const {use} = router();

// normal middleware
use('POST', '/post', (req , res, next) => {
    // do middleware things
    return next();
});

// middleware for errorhandling
// notice the fourth and last argument "error"
use('get', '/photos', (req, res, next, error) => {
    // handle error
    console.error(error);
    return next();
});

router.chain(...middlewares)

Transforms an array of middleware functions into a single middleware function.

const {chain, on} = router();

const middlewares = [
    (req, res, next) => {
        res.data = [];
        return next();
    },
    (req, res, next) => {
        res.data.push('foobar');
        return next();
    },
];

on('GET', '/custom', chain(...middlewares, (req, res) => {
    console.log(res.data); // ['foobar']
}));

router.route(req, res)

Handle the incoming requests.

const {route} = router();

const server = createServer((req, res) => {
    route(req, res);
});
server.listen(8080);

router.register(base, cb)

Recursively register all routes within the base folder and call the optional callback when finished. Each directory represents a part of the URL pathname. Dynamic routes can be created by enclosing the directory name in square brackets e.g. [id]. Listeners are named by HTTP methods/verbs and export a default listening function. Middlewares can be placed alongside the listeners as index files. These files can export a single middleware function or an array of functions.

const {register} = router();

register(__dirname + '/routes', () => {
    console.log('done');
});

Example

Registering the following folder/file structure with default configuration:

routes
|
├───api
|       index.js
|       get.js
|
├───photo
|   |   index.js
│   │   get.js
│   │   post.js
│   │   delete.js
│   │
│   ├───[id]
│   │       get.js
│   │
│   └───vacation
|           index.js
│           get.js
│           post.js
│
└───user
        post.js

Would bind the following routes:

  • GET: example.com/api
  • GET: example.com/photo
  • POST: example.com/photo
  • DELETE: example.com/photo
  • GET: example.com/photo/:id
  • GET: example.com/photo/vacation
  • POST: example.com/photo/vacation
  • POST: example.com/user

A GET call to /photo/vacation would execute the following scripts in order:

  • photo/index.js
  • photo/vacation/index.js
  • photo/vacation/get.js

Licence

MIT License, see LICENSE