{"id":22418876,"url":"https://github.com/t4t5/november-cli","last_synced_at":"2025-08-01T04:31:23.781Z","repository":{"id":32394409,"uuid":"35970959","full_name":"t4t5/november-cli","owner":"t4t5","description":"❄️ Generate a Node.js API for your Ember.js app","archived":false,"fork":false,"pushed_at":"2017-01-14T10:31:49.000Z","size":1133,"stargazers_count":51,"open_issues_count":2,"forks_count":10,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-12-01T22:40:47.588Z","etag":null,"topics":["database","ember","ember-data","nodejs","sequelize"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/t4t5.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-05-20T19:56:33.000Z","updated_at":"2024-05-30T02:25:29.000Z","dependencies_parsed_at":"2022-09-23T07:11:37.992Z","dependency_job_id":null,"html_url":"https://github.com/t4t5/november-cli","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t4t5%2Fnovember-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t4t5%2Fnovember-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t4t5%2Fnovember-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t4t5%2Fnovember-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/t4t5","download_url":"https://codeload.github.com/t4t5/november-cli/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228330163,"owners_count":17903019,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","ember","ember-data","nodejs","sequelize"],"created_at":"2024-12-05T16:13:05.771Z","updated_at":"2024-12-05T16:13:06.788Z","avatar_url":"https://github.com/t4t5.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![November logo](https://raw.githubusercontent.com/t4t5/november-cli/master/november-logo.png)\n\nNovember helps you generate a simple Node.js API tailored for [Ember.js](http://emberjs.com) apps, with the help of [Express](http://expressjs.com) and [Sequelize](http://docs.sequelizejs.com/en/latest).\n\n\nInstallation\n------------\n```bash\n$ npm install -g november-cli\n```\n\n\nGet started\n-----------\n```bash\n$ november new my-app\n```\nThis will create a new project with the following structure:\n```\n├── app\n│   ├── actions\n│   ├── controllers\n│   ├── middleware\n│   ├── models\n│   ├── router.js\n│\n├── config\n│   ├── config.json\n│\n├── lib\n├── migrations\n├── node_modules\n├── public\n├── server.js\n├── test\n```\n\nBy default, MySQL is used as a database, but you can use any relational database [supported by Sequelize](http://docs.sequelizejs.com/en/latest) by changing the values in `config/config.json`.\n\nTo run the app, run `npm start` (or just `nodemon` if you have it installed) in your app’s directory and visit `localhost:9000`.\n\n\nIn your Ember.js app\n--------------------\n\nMake sure you change the host in your Ember.js adapter file so that it can communicate with November:\n```bash\n# In your ember project folder\n$ ember generate adapter\n```\n```javascript\n// app/adapters/application.js\nimport DS from \"ember-data\";\n\nexport default DS.RESTAdapter.reopen({ \n  host: 'http://localhost:9000'\n});\n```\n\n\nModels\n------\n```bash\n$ november generate model user\n```\n\nThis generates:\n- A **model file** (`app/models/user.js`) for the user, which will determine the structure of the database table\n- **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.\n- **Controller files**, which hook up the routes to database actions:\n  - `app/controllers/user/add.js`\n  - `app/controllers/user/list.js`\n  - `app/controllers/user/load.js`\n  - `app/controllers/user/update.js`\n  - `app/controllers/user/remove.js`\n\nWith the app and your local database running in the background, visit `localhost:9000/users`, and you should see:\n```json\n{\n  \"users\": []\n}\n```\nThe table `users` has automatically been created in your database.\n\n\nActions\n-------\nActions are for API endpoints which are not specifically tied to any model.\n```bash\n$ november generate action login\n```\n\nThis generates:\n- An **action file** (`app/actions/login.js`)\n- A **route** in `app/router.js` (`POST` by default)\n\n\nRender()\n-------\nThe `render()`-method in your controllers is used for rendering both your *models* and your *error messages*. It takes a single argument.\n\n\nRendering models\n-------------\nIf you pass a valid sequelize model to `render()`, it will generate that model according to the [JSON API](http://jsonapi.org) conventions used by Ember Data.\n\nThe most basic usage:\n```\nrender(\u003cyour-sequelize-model\u003e);\n```\n...which can also be typed like this:\n```\nrender({\n  model: \u003cyour-sequelize-model\u003e \n});\n```\nreturns:\n```javascript\n{\n  \"user\": {\n    \u003c...\u003e\n  }\n}\n```\n\nIf your sequelize model includes [associated models](http://docs.sequelizejs.com/en/latest/api/associations), they are sideloaded by default:\n```javascript\n{\n  \"user\": {\n    \u003c...\u003e\n    \"tweets\": [1, 5]\n  },\n  \"tweets\": [\n    \u003c...\u003e\n  ]\n}\n```\n\nHowever, you can also specify if you want some (or all) associations to be embedded instead.\n\nHere we specify that we want the tweets-association to be embedded. If we wanted *all* associations to be embedded, we would set `embedded: true`\n```javascript\nrender({\n  model: \u003cyour-sequelize-model\u003e,\n  embedded: ['tweets']\n});\n```\n... which returns:\n```javascript\n{\n  \"user\": {\n    \u003c...\u003e\n    \"tweets\": [\n      {\n        id: 1,\n        \u003c...\u003e\n      },\n      {\n        id: 5,\n        \u003c...\u003e\n      }\n    ]\n  }\n}\n```\n\nRendering errors\n---------------\n\nControllers generated by November rely heavily on promises. If they catch an error, they call `render(error)`.\n\nLet's say we accidentally search for a field (`name`) which doesn't exist in our database table:\n\n```javascript\n// app/controllers/user/list.js\nreq.models.user\n.findAll({\n  where: {\n    name: \"Bob\"\n  }\n})\n.then(function(users) {\n  // Not gonna happen\n})\n.catch(function(err) {\n  render(err);\n});\n```\n\nAn error will be catched and `render(err)` will return this JSON to the client:\n```json\n{\n  \"error\": {\n    \"code\": 500,\n    \"message\": \"Could not load users\"\n  }\n}\n```\n... while still showing a more descriptive error to the developer in the console so that you can locate the problem:\n\n![A console error](http://tristanedwards.me/u/november/console-error.png)\n\nYou 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:\n\n```javascript\n// app/controllers/user/update.js\nreq.models.user.find({\n  where: {\n    username: req.params.username\n  }\n})\n.then(function(user) {\n  if (user.id !== req.user) {\n    throw [403, \"You are not allowed to edit this user!\"]\n  }\n  return user.save();\n})\n.then(function(user) {\n  // Not gonna happen\n})\n.catch(function(err) {\n  render(err);\n});\n```\n\n...what the client will see:\n```json\n{\n  \"error\": {\n    \"code\": 403,\n    \"message\": \"You are not allowed to edit this user!\"\n  }\n}\n```\n\nTodos\n-----\nTDD is not really my thing, but it would be nice to get some automatic Mocha tests when you generate new models. :)\n\nContact\n-------\n\nIf you have any questions, feel free to [ping me on Twitter](https://twitter.com/t4t5) or just open an issue!\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ft4t5%2Fnovember-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ft4t5%2Fnovember-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ft4t5%2Fnovember-cli/lists"}