Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

hapi-sequelize-crud2

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hapi-sequelize-crud2 - npm Package Compare versions

Comparing version 2.5.4 to 2.6.0

build/associations/one_to_many.js

12

build/associations/index.js

@@ -9,11 +9,11 @@ 'use strict';

var _oneToOne = require('./one-to-one');
var _one_to_one = require('./one_to_one');
var _oneToOne2 = _interopRequireDefault(_oneToOne);
var _one_to_one2 = _interopRequireDefault(_one_to_one);
var _oneToMany = require('./one-to-many');
var _one_to_many = require('./one_to_many');
var _oneToMany2 = _interopRequireDefault(_oneToMany);
var _one_to_many2 = _interopRequireDefault(_one_to_many);
exports.oneToOne = _oneToOne2['default'];
exports.oneToMany = _oneToMany2['default'];
exports.oneToOne = _one_to_one2['default'];
exports.oneToMany = _one_to_many2['default'];

@@ -19,5 +19,5 @@ 'use strict';

var _error = require('./error');
var _hoek = require('hoek');
var _error2 = _interopRequireDefault(_error);
var _hoek2 = _interopRequireDefault(_hoek);

@@ -28,2 +28,6 @@ var _joi = require('joi');

var _error = require('./error');
var _error2 = _interopRequireDefault(_error);
var _helpers = require('./helpers');

@@ -36,19 +40,33 @@

var prefix = undefined,
scopePrefix = undefined;
scopePrefix = undefined,
controllerOptions = undefined;
var defaultControllerOptions = {
index: true,
get: true,
count: true,
scope: true,
create: true,
destroy: true,
update: true
};
var methods = {};
exports['default'] = function (server, model, options) {
prefix = options.prefix;
scopePrefix = options.scopePrefix;
prefix = options.prefix, scopePrefix = options.scopePrefix, controllerOptions = _hoek2['default'].applyToDefaults(defaultControllerOptions, options.controllerOptions || {});
index(server, model);
count(server, model);
get(server, model);
scope(server, model);
create(server, model);
destroy(server, model);
update(server, model);
for (var method in methods) {
var methodOpts = controllerOptions[method];
if (!!methodOpts) {
methodOpts = typeof methodOpts === 'object' ? methodOpts : {};
methods[method](server, model, methodOpts);
}
}
};
var index = function index(server, model) {
server.route(_createDecoratedObject([{
var index = methods.index = function (server, model, options) {
var route = _hoek2['default'].applyToDefaults(_createDecoratedObject([{
key: 'method',

@@ -72,3 +90,3 @@ initializer: function initializer() {

case 0:
_queryParams = (0, _helpers.queryParams)(request);
_queryParams = (0, _helpers.queryParams)(server, request);
where = _queryParams.where;

@@ -157,8 +175,10 @@ offset = _queryParams.offset;

}
}]));
}]), options);
server.route(route);
};
exports.index = index;
var get = function get(server, model) {
server.route(_createDecoratedObject([{
var get = methods.get = function (server, model, options) {
var route = _hoek2['default'].applyToDefaults(_createDecoratedObject([{
key: 'method',

@@ -182,3 +202,3 @@ initializer: function initializer() {

case 0:
_queryParams2 = (0, _helpers.queryParams)(request);
_queryParams2 = (0, _helpers.queryParams)(server, request);
include = _queryParams2.include;

@@ -222,10 +242,12 @@ context$2$0.next = 4;

}
}]));
}]), options);
server.route(route);
};
exports.get = get;
var scope = function scope(server, model) {
var scope = methods.scope = function (server, model, options) {
var scopes = Object.keys(model.options.scopes);
server.route(_createDecoratedObject([{
var route = _hoek2['default'].applyToDefaults(_createDecoratedObject([{
key: 'method',

@@ -249,3 +271,3 @@ initializer: function initializer() {

case 0:
_queryParams3 = (0, _helpers.queryParams)(request);
_queryParams3 = (0, _helpers.queryParams)(server, request);
where = _queryParams3.where;

@@ -321,3 +343,3 @@ offset = _queryParams3.offset;

initializer: function initializer() {
var _joi$string;
var _Joi$string;

@@ -327,3 +349,3 @@ return {

params: {
scope: (_joi$string = _joi2['default'].string()).valid.apply(_joi$string, _toConsumableArray(scopes))
scope: (_Joi$string = _joi2['default'].string()).valid.apply(_Joi$string, _toConsumableArray(scopes))
},

@@ -339,8 +361,10 @@ query: {

}
}]));
}]), options);
server.route(route);
};
exports.scope = scope;
var create = function create(server, model) {
server.route(_createDecoratedObject([{
var create = methods.create = function (server, model, options) {
var route = _hoek2['default'].applyToDefaults(_createDecoratedObject([{
key: 'method',

@@ -377,8 +401,10 @@ initializer: function initializer() {

}
}]));
}]), options);
server.route(route);
};
exports.create = create;
var update = function update(server, model) {
server.route(_createDecoratedObject([{
var update = methods.update = function (server, model, options) {
var route = _hoek2['default'].applyToDefaults(_createDecoratedObject([{
key: 'method',

@@ -431,3 +457,3 @@ initializer: function initializer() {

params: {
id: _joi2['default'].number().integer()
id: _helpers.validation.id
}

@@ -437,8 +463,10 @@ }

}
}]));
}]), options);
server.route(route);
};
exports.update = update;
var destroy = function destroy(server, model) {
server.route(_createDecoratedObject([{
var destroy = methods.destroy = function (server, model, options) {
var route = _hoek2['default'].applyToDefaults(_createDecoratedObject([{
key: 'method',

@@ -491,3 +519,3 @@ initializer: function initializer() {

params: {
id: _joi2['default'].number().integer()
id: _helpers.validation.id
}

@@ -497,8 +525,10 @@ }

}
}]));
}]), options);
server.route(route);
};
exports.destroy = destroy;
var count = function count(server, model) {
server.route(_createDecoratedObject([{
var count = methods.count = function (server, model, options) {
var route = _hoek2['default'].applyToDefaults(_createDecoratedObject([{
key: 'method',

@@ -522,3 +552,3 @@ initializer: function initializer() {

case 0:
_queryParams4 = (0, _helpers.queryParams)(request);
_queryParams4 = (0, _helpers.queryParams)(server, request);
where = _queryParams4.where;

@@ -550,3 +580,5 @@ context$2$0.next = 4;

}
}]));
}]), options);
server.route(route);
};

@@ -553,0 +585,0 @@

@@ -6,20 +6,15 @@ 'use strict';

});
var Joi = require('joi');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _joi = require('joi');
var _joi2 = _interopRequireDefault(_joi);
var validation = {
id: _joi2['default'].number().integer().min(1).required(),
limit: _joi2['default'].number().integer().min(0)['default'](0, 'results offset'),
offset: _joi2['default'].number().integer().min(1)['default'](20, 'number of results per set'),
id: Joi.number().integer().min(1).required(),
offset: Joi.number().integer().min(0)['default'](0, 'results offset'),
limit: Joi.number().integer().min(1)['default'](20, 'number of results per set'),
include: function include(model) {
return _joi2['default'].string();
return Joi.string();
},
filter: function filter(model) {
return _joi2['default'].object();
return Joi.object();
}

@@ -29,12 +24,13 @@ };

exports.validation = validation;
var queryParams = function queryParams(request) {
var queryParams = function queryParams(server, request) {
var q = request.query;
var models = server.plugins['hapi-sequelize'].db.sequelize.models;
return {
where: q.filter,
where: q.filter || {},
offset: q.offset,
limit: q.limit,
include: q.include ? [request.models[q.include]] : []
include: q.include ? [models[q.include]] : []
};
};
exports.queryParams = queryParams;
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _crud = require('./crud');
var _controller_manager = require('./controller_manager');
var _crud2 = _interopRequireDefault(_crud);
var _controller_manager2 = _interopRequireDefault(_controller_manager);
var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
var _hoek = require('hoek');
var _hoek2 = _interopRequireDefault(_hoek);
var _url = require('url');
var _url2 = _interopRequireDefault(_url);
var _qs = require('qs');

@@ -17,2 +25,6 @@

var _crud = require('./crud');
var _crud2 = _interopRequireDefault(_crud);
var _snakeCase = require('snake-case');

@@ -22,26 +34,31 @@

var _url = require('url');
var internals = {};
var _url2 = _interopRequireDefault(_url);
internals.onRequest = function (request, reply) {
var uri = request.raw.req.url;
var parsed = _url2['default'].parse(uri, false);
parsed.query = _qs2['default'].parse(parsed.query);
request.setUrl(parsed);
var register = function register(server, options, next) {
return reply['continue']();
};
internals.optionDefaults = {
prefix: '',
scopePrefix: 's',
snakeCase: false,
'private': [],
controllers: 'controllers/**/*.js'
};
exports.register = function (server, options, next) {
if (options === undefined) options = {};
options.prefix = options.prefix || '';
options.scopePrefix = options.scopePrefix || 's';
options.snakeCase = options.snakeCase || false;
options['private'] = options['private'] || [];
options = _hoek2['default'].applyToDefaults(internals.optionDefaults, options);
var db = server.plugins['hapi-sequelize'].db;
var models = db.sequelize.models;
var onRequest = function onRequest(request, reply) {
var uri = request.raw.req.url;
var parsed = _url2['default'].parse(uri, false);
parsed.query = _qs2['default'].parse(parsed.query);
request.setUrl(parsed);
return reply['continue']();
};
var modelNames = Object.keys(models).filter(function (m) {
return options['private'].indexOf(m) === -1;
});
var convertCase = options.snakeCase ? _snakeCase2['default'] : function (str) {

@@ -51,5 +68,7 @@ return str;

_controller_manager2['default'].loadControllers(server, options.controllers);
server.ext({
type: 'onRequest',
method: onRequest
method: internals.onRequest
});

@@ -62,7 +81,9 @@

try {
for (var _iterator = Object.keys(models).filter(function (m) {
return options['private'].indexOf(m) === -1;
})[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
for (var _iterator = modelNames[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var modelName = _step.value;
if (!_controller_manager2['default'].controllersEnabled(modelName)) {
continue;
}
var model = models[modelName];

@@ -77,6 +98,14 @@ var _model$options$name = model.options.name;

// Join tables
if (model.options.name.singular !== model.name) continue;
if (model.options.name.singular !== model.name) {
continue;
}
options.controllerOptions = _controller_manager2['default'].controllerOptions(modelName);
(0, _crud2['default'])(server, model, options);
if (!_controller_manager2['default'].associationsEnabled(modelName)) {
continue;
}
var _iteratorNormalCompletion2 = true;

@@ -90,3 +119,8 @@ var _didIteratorError2 = false;

if (!_controller_manager2['default'].associationEnabled(modelName, key)) {
continue;
}
var association = model.associations[key];
var associationName = association.options.name;
var associationType = association.associationType;

@@ -96,4 +130,2 @@ var source = association.source;

var associationName = association.options.name;
association._plural = convertCase(associationName.plural);

@@ -152,6 +184,4 @@ association._singular = convertCase(associationName.singular);

register.attributes = {
exports.register.attributes = {
pkg: require('../package.json')
};
exports.register = register;
{
"name": "hapi-sequelize-crud2",
"version": "2.5.4",
"version": "2.6.0",
"description": "Hapi plugin that automatically generates a more RESTful API for CRUD, building on hapi-sequelize-crud",

@@ -12,6 +12,7 @@ "main": "build/index.js",

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "lab -r console -o stdout -r html -o test/coverage.html -I core,Reflect,__core-js_shared__,System,_babelPolyfill,regeneratorRuntime",
"clean": "rm -rf build/*"
},
"repository": {
"git": "https://github.com/alexanderreiff/hapi-sequelize-crud"
"git": "https://github.com/alexanderreiff/hapi-sequelize-crud2"
},

@@ -28,2 +29,4 @@ "files": [

"babel": "5.8.3",
"babel-polyfill": "^6.6.1",
"code": "^2.1.0",
"ghooks": "1.0.3",

@@ -33,10 +36,24 @@ "grunt": "0.4.5",

"grunt-contrib-clean": "0.7.0",
"grunt-contrib-watch": "0.6.1"
"grunt-contrib-watch": "0.6.1",
"hapi": "13.x.x",
"hapi-sequelize": "^2.2.4",
"http-status-codes": "^1.0.6",
"lab": "^10.2.0",
"sequelize": "^3.19.3",
"sqlite3": "^3.1.1"
},
"dependencies": {
"boom": "^3.1.2",
"camel-case": "^1.2.2",
"glob": "^7.0.3",
"hoek": "^3.0.4",
"joi": "7.2.1",
"qs": "^6.1.0",
"snake-case": "^1.1.2"
},
"peerDependencies": {
"hapi": "13.x.x",
"sequelize": "^3.x",
"hapi-sequelize": "^2.x"
}
}
hapi-sequelize-crud2
====================
Automatically generate a (more) RESTful API for your models and associations
Automatically generate a RESTful API for your models and associations, with simple route configuration and behavior extensibility.
This plugin depends on [`hapi-sequelize`](https://github.com/danecando/hapi-sequelize).
This plugin depends on [`hapi-sequelize`](https://github.com/danecando/hapi-sequelize), and builds on the work of [`hapi-sequelize-crud`](https://github.com/mdibaiee/hapi-sequelize-crud).

@@ -16,3 +16,3 @@ ```

// First, register hapi-sequelize
await register({
await server.register({
register: require('hapi-sequelize'),

@@ -23,11 +23,15 @@ options: { ... }

// Then, define your associations
let db = server.plugins['hapi-sequelize'].db;
let models = db.sequelize.models;
const db = server.plugins['hapi-sequelize'].db;
const models = db.sequelize.models;
associations(models); // pretend this function defines our associations
// Now, register hapi-sequelize-crud2
await register({
await server.register({
register: require('hapi-sequelize-crud2'),
options: {
prefix: '/v1'
prefix: '', // Global prefix for all routes
scopePrefix: 's', // Prefix for model scope routes (see below)
snakeCase: false, // Create routes with snake_case instead of default camelCase
controllers: 'controllers/**/*.js', // Glob to handler controller override files (can be array) [see below]
private: [] // Array of model names to exclude from route creation
}

@@ -37,3 +41,3 @@ });

Please note that you should register `hapi-sequelize-crud` after defining your
Please note that you should register `hapi-sequelize-crud2` after defining your
associations.

@@ -43,40 +47,118 @@

Let's say you have a `many-to-many` association like this:
Let's say you have associations like this:
```javascript
Team.belongsToMany(Role, { through: 'TeamRoles' });
Role.belongsToMany(Team, { through: 'TeamRoles' });
Team.belongsToMany(Role, { through: 'teamRoles' });
Team.hasOne(Player, { as: 'captain' });
```
You get these:
You get these CRUD routes:
```
# get an array of records
GET /teams/{id}/roles
GET /roles/{id}/teams
# might also append query parameters to search for
GET /roles/{id}/teams?members=5
| Method | Route | Name |
|---|---|---|
| GET | `/teams` | index<sup>1 2 3</sup> |
| GET | `/teams/{id}` | get<sup>3</sup> |
| POST | `/teams` | create |
| PUT | `/teams/{id}` | update |
| DELETE | `/teams/{id}` | destroy |
| GET | `/teams/s/{scope}` | scope<sup>1 2 3</sup> |
| GET | `/teams/count` | count<sup>1</sup> |
# create
POST /teams/{id}/roles
POST /roles/{id}/teams
# add to associations
PUT /teams/{id}/role/{id}
PUT /roles/{id}/team/{id}
And these one-to-one association routes:
# delete
DELETE /teams/{id}
DELETE /roles/{id}
| Method | Route | Name | Description |
|---|---|---|---|
| GET | `/teams/{id}/captain` | index<sup>3</sup> |
| POST | `/teams/{id}/captain` | create | Create a new related model and sets the association |
| PUT | `/teams/{id}/captain/{aid}` | update | Sets the association with an existing related model |
| DELETE | `/teams/{id}/captain` | destroy | Unsets the association |
# un-associate
DELETE /teams/{id}/roles/{id}
DELETE /roles/{id}/teams/{id}
And these one-to-many association routes:
# count
GET /teams/count
GET /roles/{id}/teams/count
| Method | Route | Name | Description |
|---|---|---|---|
| GET | `/teams/{id}/roles` | index<sup>1 2 3</sup> |
| POST | `/teams/{id}/roles` | create | Create a new related model and adds it to the associations |
| PUT | `/teams/{id}/roles/{aid}` | update | Sets the association with an existing related model |
| PUT | `/teams/{id}/roles` | updateMany | Sets the association with a many related models, as provided by id[] querystring parameter |
| DELETE | `/teams/{id}/roles/{aid}` | destroy | Unsets the association |
| DELETE | `/teams/{id}/roles` | destroyMany | Unsets all associations, optionally limited to those given by id[] querystring parameter |
| GET | `/teams/{id}/roles/count` | count<sup>1</sup> | Counts the number of associated models |
# you can specify a prefix to change the URLs like this:
GET /v1/teams/{id}/roles
<sup>1</sup> Accepts a query string parameter object `filter` to limit results by given criteria, e.g. `?filter[status]=active`
<sup>2</sup> Accepts query string parameters `limit` and `offset` to control paginated results
<sup>3</sup> Accepts a querystring parameter `include` to include a related model with the returned parent model
##Custom Route Configuration
Automatic route handling is convenient for getting a basic API in place during development. But
in a production application, authentication, ACL and caching concerns need to be addressed.
Taking advantage of Hapi's convention over configuration approach to route set-up, you can easy
extend and override the plugin's default route options and handler.
Simply create a file named modelName.js (or model_name.js if you prefer) in your controllers path
defined in the plugin options, and your options will be mixed in during route registration. A
controller should export a function that accepts two arguments, a Hapi server instance and the model
object, and returns an object mapping route names to Hapi route configuration object partials or
`false` to disable a route.
For example, a read-only endpoint with limited scope access may look like:
```javascript
// This standard Hapi package make composing
// route configuration options easy
const Hoek = require('hoek');
const Joi = require('joi');
modules.export = function(server, Team) {
const plural = Team.options.name.plural;
const readConfig = {
cache: {
expiresIn: 30 * 1000,
private: 'private'
}
};
return {
index: readConfig,
get: readConfig,
scope: Hoek.applyToDefaults(readConfig, {
config: {
validation: {
params: {
scope: Joi.string().valid('scope1', 'scope2')
}
}
}
}),
count: Hoek.applyToDefaults(readConfig, {
path: `${plural}/total`,
handler: function(request, reply) {
...
const total = ...;
reply({total: total});
}
}),
create: false,
update: false,
destroy: false,
associations: {
captain: {
create: false,
update: false,
destroy: false
},
roles: false
}
};
});
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc