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 🙏

© 2026 – Pkg Stats / Ryan Hefner

november-cli

v0.2.1

Published

Generate a Node.js API for your Ember.js app

Readme

November logo

November helps you generate a simple Node.js API tailored for Ember.js apps, with the help of Express and Sequelize.

Installation

$ npm install -g november-cli

Get started

$ november new my-app

This will create a new project with the following structure:

├── app
│   ├── actions
│   ├── controllers
│   ├── middleware
│   ├── models
│   ├── router.js
│
├── config
│   ├── config.json
│
├── lib
├── migrations
├── node_modules
├── public
├── server.js
├── test

By default, MySQL is used as a database, but you can use any relational database supported by Sequelize by changing the values in config/config.json.

To run the app, run npm start (or just nodemon if you have it installed) in your app’s directory and visit localhost:9000.

In your Ember.js app

Make sure you change the host in your Ember.js adapter file so that it can communicate with November:

# In your ember project folder
$ ember generate adapter
// app/adapters/application.js
import DS from "ember-data";

export default DS.RESTAdapter.reopen({ 
  host: 'http://localhost:9000'
});

Models

$ november generate model user

This generates:

  • A model file (app/models/user.js) for the user, which will determine the structure of the database table
  • Routes in app/router.js for creating, reading, updating and deleting users (based on the conventions of Ember Data). Feel free to remove the actions you don't need.
  • Controller files, which hook up the routes to database actions:
    • app/controllers/user/add.js
    • app/controllers/user/list.js
    • app/controllers/user/load.js
    • app/controllers/user/update.js
    • app/controllers/user/remove.js

With the app and your local database running in the background, visit localhost:9000/users, and you should see:

{
  "users": []
}

The table users has automatically been created in your database.

Actions

Actions are for API endpoints which are not specifically tied to any model.

$ november generate action login

This generates:

  • An action file (app/actions/login.js)
  • A route in app/router.js (POST by default)

Render()

The render()-method in your controllers is used for rendering both your models and your error messages. It takes a single argument.

Rendering models

If you pass a valid sequelize model to render(), it will generate that model according to the JSON API conventions used by Ember Data.

The most basic usage:

render(<your-sequelize-model>);

...which can also be typed like this:

render({
  model: <your-sequelize-model> 
});

returns:

{
  "user": {
    <...>
  }
}

If your sequelize model includes associated models, they are sideloaded by default:

{
  "user": {
    <...>
    "tweets": [1, 5]
  },
  "tweets": [
    <...>
  ]
}

However, you can also specify if you want some (or all) associations to be embedded instead.

Here we specify that we want the tweets-association to be embedded. If we wanted all associations to be embedded, we would set embedded: true

render({
  model: <your-sequelize-model>,
  embedded: ['tweets']
});

... which returns:

{
  "user": {
    <...>
    "tweets": [
      {
        id: 1,
        <...>
      },
      {
        id: 5,
        <...>
      }
    ]
  }
}

Rendering errors

Controllers generated by November rely heavily on promises. If they catch an error, they call render(error).

Let's say we accidentally search for a field (name) which doesn't exist in our database table:

// app/controllers/user/list.js
req.models.user
.findAll({
  where: {
    name: "Bob"
  }
})
.then(function(users) {
  // Not gonna happen
})
.catch(function(err) {
  render(err);
});

An error will be catched and render(err) will return this JSON to the client:

{
  "error": {
    "code": 500,
    "message": "Could not load users"
  }
}

... while still showing a more descriptive error to the developer in the console so that you can locate the problem:

A console error

You can also render your own exceptions to the user, by throwing a string with the error message or an array where the first element is the error code and the second is the error message:

// app/controllers/user/update.js
req.models.user.find({
  where: {
    username: req.params.username
  }
})
.then(function(user) {
  if (user.id !== req.user) {
    throw [403, "You are not allowed to edit this user!"]
  }
  return user.save();
})
.then(function(user) {
  // Not gonna happen
})
.catch(function(err) {
  render(err);
});

...what the client will see:

{
  "error": {
    "code": 403,
    "message": "You are not allowed to edit this user!"
  }
}

Todos

TDD is not really my thing, but it would be nice to get some automatic Mocha tests when you generate new models. :)

Contact

If you have any questions, feel free to ping me on Twitter or just open an issue!