Stuff we share across our projects. It's like a toolbox but it smells good!
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Build Status

At Dijiwan, we use JavaScript a lot, especially with node.js. We have common needs across our project, so we decided to package them, and make them available publicly.

A brief word of History While looking a name for this project, we asked to translate the word toolbox in Japanese to our japanese-speaking-guy (Guillaume).

As his answer dôgubako (道具箱) sounded like doggybag, we laughed and decided to call it as is. It's also a way to carry delicious stuff at home, or at work.

Extended forms

This component extends @caolan's forms, providing new features like Twitter Bootstrap templating, new useful validators and fields…

var forms = require('doggybag/forms');

var form = forms.create({
  "username": forms.fields.string({ required:true }),
  "gender":   forms.fields.string({ widget:forms.widgets.multipleCheckbox({}), choices:['M','F','X'], validators:[forms.validators.choices()] }),
  "avatar":   forms.fields.file({ help:"Less than 200K" })

See doc/ for more complete documentation.

Config loader

Based on @flatiron's nconf, this component will allow you to use a two-level file-based configuration: a "common" configuration, and some overrides depending on your environment.

// In your bootstrap
require('doggybag/config').add('myApp'); // loads config/myApp.json and config/myApp.production.json

// Later in your code
var key = require('doggybag/config').myApp.get('key');

See doc/ for more complete documentation.


Based on @flatiron's winston, this component acts as a thin wrapper to simply automatically configure several Logger instances and provide easy access to them.

// In your bootstrap
require('doggybag/logger').add('myApp'); // grab config from 'logging.json', key "myApp"

// Later in your code
var logger = require('doggybag/logger').myApp;

logger.warn('This may not occur');

See doc/ for more complete documentation.

Express CRUD

This component acts as an Express app builder you can use in your back-office. It uses doggybag/forms, and works natively with mongoose but could work with any type of data.

var crud = require('doggybag/crud');

var usersApp = crud.init({
  model: mongoose.model('User'),
  form: function (forms, cb) { cb(null, forms.create(…)) },
  listLocals: crud.helpers.defineLocals({table: "users/list_table"})

app.mount('/users', usersApp);

See doc/ for more complete documentation.

Express Middlewares


This component enables your node.js app to be hosted behind a proxy and avoids Express to become crazy when it comes to res.redirect.

Some other middlewares exists with that stuff but usually, they are not unit-tested.



For now, it will work with the x-forwarded-host HTTP header. Express already deals with the x-forwarded-proto, making the http or https redirect protocol-compliant.

Notice: Express 3.x will cover this feature but though, it's still okay for Express 2.x and below.


Stacking this middleware will ensure your app is always used in an HTTPS context.

app.configure('production', function(){

It's especiall useful when behind a proxy and running an HTTP node server.

Anyway, it can be problematic if you use it after the call of app.router. That's you can load the middleware in every environment, with filtering.


    envs: ['production']



Guessing locale upon browser language can be tricky. Some use case encountered:

  • no Accept-Language (especially true when using PhantomJS)
  • aggressive value (only fr-fr or en_US with Safari)
  • with or without priority

This middleware's goal is autodetection without breaking your app.


  app.use(require('doggybag/middlewares').locale(['fr', 'ja', 'en']));

  //app.locale is then useable, and dynamically configured upon browser request
$ curl -H 'Accept-Language: fr-fr'
--> 'fr' locale will be used

Notice: to avoid greedy lookup, the req.locale will always be lowercase. Think about it when dealing with its value in your apps!