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

columbo

v3.0.1

Published

Framework agnostic, automagical RESTful resource discoverer

Downloads

34

Readme

Columbo

Dependency Status devDependency Status Build Status Coverage Status

RIMMER: You can scoff, Lister. That's nothing new. They laughed at Galileo. They laughed at Edison. They laughed at Columbo.
LISTER: Who's Columbo?
RIMMER: The man with the dirty mac who discovered America.

Red Dwarf Season 1, Episode 4

Discovers REST resources in js files named by convention. Is it a good idea? I don't know. Either way, it makes setting up a REST interface pretty easy.

Usage

URLs

Put your resource classes in a folder (the default is name is resources). Follow the convention:

Library.js
LibraryBook.js

or

LibraryResource.js
LibraryBookResource.js

This will generate resources for the following URLs:

/libraries
/libraries/{libraryId}/books
/libraries/{libraryId}/books/{bookId}

### Methods

HTTP Methods are determined by the methods exposed on your resource classes. An OPTIONS resource is generated dynamically.

Your methods should accept whatever arguments your web framework requires.

LibraryBook = function() {

};

LibraryBook.prototype.retrieve = function() {
  // generates GET with a URL parameter named 'id'
};

LibraryBook.prototype.retrieveAll = function() {
  // generates GET with no URL parameter
};

LibraryBook.prototype.retrieveOne = function() {
  // generates GET with no URL parameter (intended for singletons, do no use with retrieve and retrieveAll)
};

LibraryBook.prototype.create = function() {
  // generates POST
};

LibraryBook.prototype.update = function() {
  // generates PUT
};

LibraryBook.prototype.patch = function() {
  // generates PATCH
};

LibraryBook.prototype.remove = function() {
  // generates DELETE
};

API

var Columbo = require("columbo");

// all options are, well, optional
var columbo = new Columbo({
  // The path to the resources directory
  resourceDirectory: "./resources",

  // All files in `resourceDirectory` will be `require`d - pass a function here
  // to override how the resources are created.  `resource` will be whatever is
  // returned from `require` and `name` is the camelised name of the file
  resourceCreator: function(resource, name) {
    return new resource()
  },

  // This will be called for every resource found - if you need to edit the resource
  // definition, do it here then pass it to the callback
  preProcessor: function(resource, callback) {
    callback(undefined, resource)
  },

  // In order to support :id or {id} form url arguments, pass a function here
  // that will return arguments in the format you desire.
  idFormatter: function(id) {
    return "{" + id + "}";
  },

  // Responder for OPTIONS requests - the first argument will be an array of
  // strings corresponding to HTTP verbs, subsequent arguments are supplied by
  // your web framework of choice.
  optionsSender: function(opts, request) {
    request.reply(opts);
  },

  // Optionally pass in a logger (e.g. Winston) - defaults to console.
  logger: {}
});

// Discover resources
var resources = columbo.discover();

Above resources will be an array:

[
  {
    method: String,		// e.g. GET
    path: String,		// e.g. /foo
    handler: Function	// a bound function - the method on the resource class
  }, ...
]

You can then use it with Hapi

var columbo = new Columbo();

var server = new Hapi.Server();
server.addConnection({port: 3000});

columbo.discover(function(error, routes) {
  server.route(routes);
  server.start();
})

Or with Express:

var app = express();
...
var columbo = new Columbo({
  idFormatter: function(id) {
    return ":" + id;
  },
  optionsSender: function(options, request, response) {
    response.json(options);
  }
});
columbo.discover(function(error, routes) {
  routes.forEach(function(resource) {
    app[resource.method.toLowerCase()](resource.path, resource.handler);
  });
})

Etc, etc.

Todo

  • Framework agnostic argument validation
  • OPTIONS is a little half baked