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

railroad

v0.3.2

Published

Build Node REST API's with the annoying stuff already done for you.

Downloads

14

Readme

Railroad

npm version Build Status Coverage Status Dependency Status devDependency Status Shitty logo, help me!

Basic framework for rest api's based on koa and uses Waterline models.

Features:

  • Automatic REST controllers with support for authentication and authorization.
  • Authentication middleware (Json Web Tokens or custom implementation).
  • Configure ACL for controllers and actions.
  • ACL based on the current user (e.g. a user can only edit itself).
  • Pagination
  • Etag and Conditional GET

Usage

let koa = require('koa');

let Railroad = require('railroad');
let config = require('./config');

let app = koa();

Railroad(app, config, {
    acl: require('./acl'),
    auth: require('./auth')
}).then(() => {
    app.listen(3000);
}).catch((err) => {
    console.log(err.stack);
});

Configuration

// config.js

let path = require('path');
let connections = require('./connections');
let routes = require('./routes');

module.exports = {
    // Path to the controllers directory
    controllers: path.join(__dirname, 'controllers'),

    // Path to the models directory
    models: path.join(__dirname, 'models'),

    connections: connections,
    routes: routes,

    // Options for resource controllers/actions.
    resource: {
        pagination: true, // turn on pagination
        pageLimit: 50 // If pagination is turned on, set the limit per page
    }

    // Options for Json Web Tokens (if you want to use it)
    jwt: {
        expiresIn: 180 * 60,
        secret: 'secret'
    }
};

Database connections

The database connection configuration is a configuration object for the Waterline ORM.

// connections.js

let diskAdapter = require('sails-disk');

/**
 * Waterline ORM config.
 */
module.exports = {
    adapters: {
        default: diskAdapter,
        disk: diskAdapter
    },

    connections: {
        myLocalDisk: {
            adapter: 'disk'
        }
    },

    defaults: {
        connection: 'myLocalDisk',
        migrate: 'safe'
    }
};

Resource Controllers

A resource controller will provide all the CRUD operations for a model. It taps into the authentication and authorization functionality. It will use the global pagination configuration, or you can pass an optional options object. A Resource will return an object. Example:

let Resource = require('railroad/lib/utils/Resource');

// model name and optional "resource" options
module.exports = Resource('User', { pagination: false });

A resource has the following methods:

  • find: GET method, returns an array with resources.
  • findOne: GET method, returns a single resource
  • create: POST method, create a resource and return it.
  • update: PATCH method, update a resource and return it.
  • destroy: DELETE method, delete a resource.

If you do not need all methods, you could make your own controller and use the action helpers individually (located in railroad/lib/utils/ResourceAction).

Pagination

By default a Resource has pagination on the find method. Query parameters page and limit are used to control the pagination. A response will include Link Headers for navigation to other pages.

To turn off pagination pass the following option into the resource function:

Resource('User', { pagination: false });

Routes

The routes configuration maps paths to controllers or actions. For a resource controller, just use the path. For a custom controller action, add the method as a prefix. Example route configuration:

// routes.js

module.exports = {
    '/product': 'ProductController', // Resource route
    'get /product/custom': 'ProductController.custom', // Custom route
    'get /product/custom/:title': { // Custom route alternate syntax
        controller: 'ProductController',
        action: 'customOne'
    },
    '/pet': 'animals/PetController' // Nested file
};

Authentication

A middleware is used to authenticate a user. An example:

// auth.js

module.exports = function* (next) {
    if (!this.state.route.requiresAuth) {
        return yield next;
    }

    this.state.user = {
        id: 2,
        name: 'Test User',
        isAdmin: false
    };

    return yield next;
};

Railroad includes an auth middleware and controller that uses Json Web Tokens. See the example.

Authorization

The ACL file must export a function with the user as it's argument. An object explaining the rights of the user must be returned from this function.

Properties names of this object can be controller names, (action names nested within a controller) or * for defining the default ACL.

Values can be a boolean, function or an object.

  • boolean: When set to true, authentication is required.
  • object: Authentication is required, but authorization depends on the accessed resourced. The object will describe criteria that applies to the Waterline model. It is basically a where clause.
  • function: Authentication is required, but the outcome of the function will decide if a user has access. A function can either return a boolean or an object. Depennding on the type, one of the previous rules will apply.
module.exports = function (user) {
    return {
        '*': true, // All routes protected by default
        'animals/PetController': false, // Allow PetController
        ProductController: {
            find: {
                userId: user.id
            },
            custom: true, // Require auth
            customOne: () => user.isAdmin, // Conditional Acl with a function
            create: false,
            findOne: {
                userId: user.id // Conditions for the Waterline model
            },
            update: {
                userId: user.id
            },
            destroy: {
                userId: user.id
            }
        }
    }
};

Context added by Railroad

  • ctx.config: The railroad configuration object.
  • ctx.state.route.controllerName: Name of the current controller.
  • ctx.state.route.actionName: Name of the current action.
  • ctx.state.route.path: Path as defined in the route configuration.
  • ctx.state.route.method: Method of the current route.
  • ctx.state.route.requiresAuth: Check if the current route requires authentication.
  • ctx.state.user: The current user.
  • ctx.state.route.acl.authenticated: If the current user is authenticated.
  • ctx.state.route.acl.authorized: If the current user is authorized to access the current route.
  • ctx.state.route.acl.criteria: Criteria for the current route as defined in the acl middleware.