Socket
Socket
Sign inDemoInstall

resource-schema

Package Overview
Dependencies
Maintainers
3
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

resource-schema - npm Package Compare versions

Comparing version 0.10.3 to 0.10.4

366

lib/index.js

@@ -5,3 +5,4 @@ // Generated by CoffeeScript 1.8.0

__slice = [].slice,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
__hasProp = {}.hasOwnProperty;

@@ -31,8 +32,8 @@ dot = require('dot-component');

this._generateSchemaFromModel = __bind(this._generateSchemaFromModel, this);
this._getResourceAndModelFields = __bind(this._getResourceAndModelFields, this);
this._convertKeysToDotStrings = __bind(this._convertKeysToDotStrings, this);
this._getResourceQuery = __bind(this._getResourceQuery, this);
this._getModelSelectFields = __bind(this._getModelSelectFields, this);
this._getSelectFields = __bind(this._getSelectFields, this);
this._getAddFields = __bind(this._getAddFields, this);
this._getSelectedResourceFields = __bind(this._getSelectedResourceFields, this);
this._getResourceSelectFields = __bind(this._getResourceSelectFields, this);
this._getLimit = __bind(this._getLimit, this);

@@ -47,5 +48,11 @@ this._getGroupQuery = __bind(this._getGroupQuery, this);

this._putMany = __bind(this._putMany, this);
this._getMany = __bind(this._getMany, this);
this._getOne = __bind(this._getOne, this);
this._getMany = __bind(this._getMany, this);
this.schema = schema ? this._normalizeSchema(schema) : this._generateSchemaFromModel(this.Model);
this.resourceFields = Object.keys(this.schema);
this.defaultResourceFields = this.resourceFields.filter((function(_this) {
return function(field) {
return !_this.schema[field].optional;
};
})(this));
}

@@ -66,5 +73,45 @@

ResourceSchema.prototype._getOne = function(paramId) {
return (function(_this) {
return function(req, res, next) {
var err, idValue, modelQuery, query, requestContext, select;
requestContext = {
req: req,
res: res,
next: next
};
if (!_this._enforceValidity(req.query, requestContext)) {
return;
}
select = _this._getModelSelectFields(req.query);
idValue = req.params[paramId];
query = {};
query[paramId] = idValue;
try {
query = _this._convertTypes(query);
} catch (_error) {
err = _error;
return next(Boom.wrap(err));
}
modelQuery = _this.Model.findOne(query);
if (select != null) {
modelQuery.select(select);
}
modelQuery.lean();
return modelQuery.exec(function(err, model) {
if (err) {
return next(Boom.wrap(err));
}
if (model == null) {
return next(Boom.notFound("No resources found with " + paramId + " of " + idValue));
}
return _this._sendResource(model, requestContext);
});
};
})(this);
};
ResourceSchema.prototype._getMany = function(req, res, next) {
var context;
context = {
var requestContext;
requestContext = {
req: req,

@@ -74,6 +121,6 @@ res: res,

};
if (!this._enforceValidity(req.query, context)) {
if (!this._enforceValidity(req.query, requestContext)) {
return;
}
return this._getMongoQuery(req.query, context).then((function(_this) {
return this._getMongoQuery(req.query, requestContext).then((function(_this) {
return function(mongoQuery) {

@@ -101,3 +148,3 @@ var d, limit, modelQuery;

return function(models) {
return _this._sendResources(models, context);
return _this._sendResources(models, requestContext);
};

@@ -111,43 +158,3 @@ })(this))["catch"]((function(_this) {

ResourceSchema.prototype._getOne = function(paramId) {
return (function(_this) {
return function(req, res, next) {
var context, err, idValue, modelQuery, query, select;
context = {
req: req,
res: res,
next: next
};
if (!_this._enforceValidity(req.query, context)) {
return;
}
select = _this._getModelSelectFields(req.query);
idValue = req.params[paramId];
query = {};
query[paramId] = idValue;
try {
query = _this._convertTypes(query);
} catch (_error) {
err = _error;
return next(Boom.wrap(err));
}
modelQuery = _this.Model.findOne(query);
if (select != null) {
modelQuery.select(select);
}
modelQuery.lean();
return modelQuery.exec(function(err, model) {
if (err) {
return next(Boom.wrap(err));
}
if (model == null) {
return next(Boom.notFound("No resources found with " + paramId + " of " + idValue));
}
return _this._sendResource(model, context);
});
};
})(this);
};
/*

@@ -160,3 +167,13 @@ Generate middleware to handle POST requests for resource

return function(req, res, next) {
if (!_this._enforceValidity(req.query, context)) {
var requestContext, resource;
requestContext = {
req: req,
res: res,
next: next
};
resource = req.body;
if (resource == null) {
return next(Boom.badRequest("POST must have a req.body"));
}
if (!_this._enforceValidity(req.query, requestContext)) {
return;

@@ -174,4 +191,4 @@ }

ResourceSchema.prototype._postOne = function(req, res, next) {
var context, model, resource, resourceByModelId;
context = {
var model, requestContext, resource, resourceByModelId;
requestContext = {
req: req,

@@ -182,13 +199,14 @@ res: res,

resource = req.body;
if (!this._enforceValidity(resource, context)) {
if (!this._enforceValidity(resource, requestContext)) {
return;
}
this._extendQueryWithImplicitOptionalFields([resource], requestContext);
model = this._createModelFromResource(resource);
resourceByModelId = {};
resourceByModelId[model._id.toString()] = resource;
return this._buildContext(context, [resource], [model]).then((function(_this) {
return this._buildContext(requestContext, [resource], [model]).then((function(_this) {
return function() {
var d;
d = q.defer();
_this._applySetters(resourceByModelId, [model], context);
_this._applySetters(resourceByModelId, [model], requestContext);
model = new _this.Model(model);

@@ -201,3 +219,3 @@ model.save(d.makeNodeResolver());

res.status(201);
return _this._sendResource(model, context);
return _this._sendResource(model, requestContext);
};

@@ -210,4 +228,4 @@ })(this))["catch"](function(err) {

ResourceSchema.prototype._postMany = function(req, res, next) {
var context, models, resource, resourceByModelId, resources, _i, _len;
context = {
var models, requestContext, resource, resourceByModelId, resources, _i, _len;
requestContext = {
req: req,

@@ -220,6 +238,7 @@ res: res,

resource = resources[_i];
if (!this._enforceValidity(resource, context)) {
if (!this._enforceValidity(resource, requestContext)) {
return;
}
}
this._extendQueryWithImplicitOptionalFields(resources, requestContext);
resourceByModelId = {};

@@ -234,7 +253,7 @@ models = resources.map((function(_this) {

})(this));
return this._buildContext(context, resources, models).then((function(_this) {
return this._buildContext(requestContext, resources, models).then((function(_this) {
return function() {
var d;
d = q.defer();
_this._applySetters(resourceByModelId, models, context);
_this._applySetters(resourceByModelId, models, requestContext);
_this.Model.create(models, function() {

@@ -253,3 +272,3 @@ var err, modelsSaved;

res.status(201);
return _this._sendResources(modelsSaved, context);
return _this._sendResources(modelsSaved, requestContext);
};

@@ -279,4 +298,4 @@ })(this))["catch"]((function(_this) {

return function(req, res, next) {
var context, idValue, model, query, resource, resourceByModelId;
context = {
var idValue, model, query, requestContext, resource, resourceByModelId;
requestContext = {
req: req,

@@ -286,9 +305,13 @@ res: res,

};
if (!_this._enforceValidity(req.query, context)) {
resource = req.body;
if (resource == null) {
return next(Boom.badRequest("PUT must have a req.body"));
}
if (!_this._enforceValidity(req.query, requestContext)) {
return;
}
if (!_this._enforceValidity(req.body, context)) {
if (!_this._enforceValidity(req.body, requestContext)) {
return;
}
resource = req.body;
_this._extendQueryWithImplicitOptionalFields([resource], requestContext);
idValue = req.params[paramId];

@@ -301,6 +324,6 @@ query = {};

resourceByModelId[model._id.toString()] = resource;
return _this._buildContext(context, [resource], [model]).then(function() {
return _this._buildContext(requestContext, [resource], [model]).then(function() {
var d;
d = q.defer();
_this._applySetters(resourceByModelId, [model], context);
_this._applySetters(resourceByModelId, [model], requestContext);
delete model._id;

@@ -316,3 +339,3 @@ _this.Model.findOneAndUpdate(query, model, {

res.status(200);
return _this._sendResource(model, context);
return _this._sendResource(model, requestContext);
})["catch"](function(err) {

@@ -326,4 +349,4 @@ return next(Boom.wrap(err));

ResourceSchema.prototype._putMany = function(req, res, next) {
var context, models, resource, resourceByModelId, resources, _i, _len;
context = {
var models, requestContext, resource, resourceByModelId, resources, _i, _len;
requestContext = {
req: req,

@@ -333,15 +356,19 @@ res: res,

};
if (!this._enforceValidity(req.query, context)) {
resources = req.body;
if (resources == null) {
return next(Boom.badRequest("PUT must have a req.body"));
}
if (!this._enforceValidity(req.query, requestContext)) {
return;
}
if (!this._enforceValidity(req.body, context)) {
if (!this._enforceValidity(req.body, requestContext)) {
return;
}
resources = req.body;
for (_i = 0, _len = resources.length; _i < _len; _i++) {
resource = resources[_i];
if (!this._enforceValidity(resource, context)) {
if (!this._enforceValidity(resource, requestContext)) {
return;
}
}
this._extendQueryWithImplicitOptionalFields(resources, requestContext);
resourceByModelId = {};

@@ -356,6 +383,6 @@ models = resources.map((function(_this) {

})(this));
return this._buildContext(context, resources, models).then((function(_this) {
return this._buildContext(requestContext, resources, models).then((function(_this) {
return function() {
var savePromises;
_this._applySetters(resourceByModelId, models, context);
_this._applySetters(resourceByModelId, models, requestContext);
savePromises = models.map(function(model) {

@@ -378,3 +405,3 @@ var d, modelId;

return function(updatedModels) {
return _this._sendResources(updatedModels, context);
return _this._sendResources(updatedModels, requestContext);
};

@@ -394,4 +421,4 @@ })(this))["catch"](function(err) {

return function(req, res, next) {
var context, idValue, query;
context = {
var idValue, query, requestContext;
requestContext = {
req: req,

@@ -401,3 +428,3 @@ res: res,

};
if (!_this._enforceValidity(req.query, context)) {
if (!_this._enforceValidity(req.query, requestContext)) {
return;

@@ -500,2 +527,5 @@ }

var config, model, resourceField, value, _ref;
if (resource == null) {
return;
}
model = {};

@@ -518,8 +548,7 @@ _ref = this.schema;

ResourceSchema.prototype._createResourceFromModel = function(model, resourceFields) {
var config, fieldIsSelectable, resource, resourceField, value, _ref, _ref1;
ResourceSchema.prototype._createResourceFromModel = function(model, requestContext) {
var config, fieldIsSelected, req, resource, resourceField, resourceSelectFields, value, _ref, _ref1;
req = requestContext.req;
resource = {};
if (typeof resourceFields === 'string') {
resourceFields = resourceFields.split(' ');
}
resourceSelectFields = this._getResourceSelectFields(req.query);
if ((_ref = this.options.groupBy) != null ? _ref.length : void 0) {

@@ -531,3 +560,4 @@ resource._id = model._id;

config = _ref1[resourceField];
if (fieldIsSelectable = (resourceFields == null) || __indexOf.call(resourceFields, resourceField) >= 0) {
fieldIsSelected = __indexOf.call(resourceSelectFields, resourceField) >= 0;
if (fieldIsSelected) {
if (config.field) {

@@ -551,6 +581,6 @@ value = dot.get(model, config.field);

ResourceSchema.prototype._applySetters = function(resourceByModelId, models, context) {
ResourceSchema.prototype._applySetters = function(resourceByModelId, models, requestContext) {
return models.forEach((function(_this) {
return function(model) {
var config, resourceField, _ref, _results;
var config, resourceField, setValue, _ref, _results;
_ref = _this.schema;

@@ -566,3 +596,7 @@ _results = [];

}
_results.push(dot.set(model, _this.schema[resourceField].field, config.set(resourceByModelId[model._id.toString()], context)));
setValue = config.set(resourceByModelId[model._id.toString()], requestContext);
if (setValue === void 0) {
continue;
}
_results.push(dot.set(model, _this.schema[resourceField].field, setValue));
}

@@ -579,5 +613,5 @@ return _results;

ResourceSchema.prototype._applyGetters = function(resourceByModelId, models, context) {
ResourceSchema.prototype._applyGetters = function(resourceByModelId, models, requestContext) {
var config, model, resource, resourceField, selectedResourceFields, _i, _len, _results;
selectedResourceFields = this._getSelectedResourceFields(context.req.query);
selectedResourceFields = this._getResourceSelectFields(requestContext.req.query);
_results = [];

@@ -599,3 +633,3 @@ for (_i = 0, _len = models.length; _i < _len; _i++) {

}
_results1.push(dot.set(resource, resourceField, config.get(model, context)));
_results1.push(dot.set(resource, resourceField, config.get(model, requestContext)));
}

@@ -656,12 +690,7 @@ return _results1;

ResourceSchema.prototype._getSelectedResourceFields = function(query) {
var resourceFields, select;
resourceFields = this._getResourceAndModelFields()[0];
select = query.$select;
resourceFields = select ? (typeof select === 'string' ? select = select.split(' ') : void 0, _(select).intersection(resourceFields)) : _(resourceFields).reject((function(_this) {
return function(resourceField) {
return _this.schema[resourceField].optional;
};
})(this));
return _.union(resourceFields, this._getAddFields(query));
ResourceSchema.prototype._getResourceSelectFields = function(query) {
var $select, fields;
$select = this._getSelectFields(query);
fields = $select.length ? $select : this.defaultResourceFields;
return _(fields).union(this._getAddFields(query));
};

@@ -678,6 +707,5 @@

ResourceSchema.prototype._getAddFields = function(query) {
var addFields, resourceFields;
resourceFields = this._getResourceAndModelFields()[0];
var addFields;
addFields = typeof query.$add === 'string' ? query.$add.split(' ') : Array.isArray(query.$add) ? query.$add : [];
return _(addFields).intersection(resourceFields);
return _(addFields).intersection(this.resourceFields);
};

@@ -687,23 +715,30 @@

/*
Get all valid $select fields from the query. The sekect fields are used to
similar to mongoose select
@param [Object] query - query params from client
@returns [Array] valid keys to add from schema
*/
ResourceSchema.prototype._getSelectFields = function(query) {
var selectFields;
selectFields = typeof query.$select === 'string' ? query.$select.split(' ') : Array.isArray(query.$select) ? query.$select : [];
return _(selectFields).intersection(this.resourceFields);
};
/*
Convert select fields in query, to fields that can be used for
@param [Object] query - query params from client
@returns [String] space separated string of model select fields
*/
ResourceSchema.prototype._getModelSelectFields = function(query) {
var addFields, modelFields, modelSelectFields, resourceFields, select, _ref;
_ref = this._getResourceAndModelFields(), resourceFields = _ref[0], modelFields = _ref[1];
select = query.$select;
addFields = this._getAddFields(query);
modelSelectFields = select ? (typeof select === 'string' ? select = select.split(' ') : void 0, resourceFields = _(select).intersection(resourceFields), resourceFields.map((function(_this) {
var modelSelectFields, resourceSelectFields;
resourceSelectFields = this._getResourceSelectFields(query);
modelSelectFields = resourceSelectFields.map((function(_this) {
return function(resourceSelectField) {
return _this.schema[resourceSelectField].field;
};
})(this))) : resourceFields.map((function(_this) {
return function(resourceField) {
if (_this.schema[resourceField].field && (!_this.schema[resourceField].optional || __indexOf.call(addFields, resourceField) >= 0)) {
return _this.schema[resourceField].field;
}
};
})(this));
return _(modelSelectFields).compact().join(' ');
return _.compact(modelSelectFields).join(' ');
};

@@ -726,9 +761,8 @@

ResourceSchema.prototype._getResourceQuery = function(query) {
var field, modelFields, queryFields, resourceFields, validFields, value, _ref;
var field, queryFields, validFields, value;
query = this._convertKeysToDotStrings(query);
_ref = this._getResourceAndModelFields(), resourceFields = _ref[0], modelFields = _ref[1];
validFields = {};
for (field in query) {
value = query[field];
if (__indexOf.call(resourceFields, field) >= 0) {
if (__indexOf.call(this.resourceFields, field) >= 0) {
dot.set(validFields, field, value);

@@ -777,14 +811,3 @@ }

ResourceSchema.prototype._getResourceAndModelFields = function() {
var modelFields, resourceFields;
resourceFields = Object.keys(this.schema);
modelFields = resourceFields.map((function(_this) {
return function(resourceField) {
return _this.schema[resourceField].field;
};
})(this));
return [_.compact(resourceFields), _.compact(modelFields)];
};
/*

@@ -1048,13 +1071,13 @@ If no schema provided, generate a schema that directly mirrors the mongoose model fields

/*
Apply all resolvers. Data will be added to context, and can be used inside getters and setters.
@returns a promise containing context
Apply all resolvers. Data will be added to requestContext, and can be used inside getters and setters.
@returns a promise containing requestContext
*/
ResourceSchema.prototype._buildContext = function(context, resources, models) {
ResourceSchema.prototype._buildContext = function(requestContext, resources, models) {
var config, next, req, res, resolveMethod, resolvePromises, resolveVar, resourceField, selectedResourceFields, _fn, _fn1, _ref, _ref1, _ref2;
req = context.req, res = context.res, next = context.next;
req = requestContext.req, res = requestContext.res, next = requestContext.next;
resolvePromises = [];
context.resources = resources;
context.models = models;
selectedResourceFields = this._getSelectedResourceFields(req.query);
requestContext.resources = resources;
requestContext.models = models;
selectedResourceFields = this._getResourceSelectFields(req.query);
_ref = this.options.resolve;

@@ -1065,7 +1088,7 @@ _fn = (function(_this) {

d = q.defer();
resolveMethod(context, function(err, result) {
resolveMethod(requestContext, function(err, result) {
if (err) {
return d.reject(Boom.wrap(err));
} else {
context[resolveVar] = result;
requestContext[resolveVar] = result;
return d.resolve();

@@ -1082,3 +1105,3 @@ }

}
if (context[resolveVar]) {
if (requestContext[resolveVar]) {
continue;

@@ -1102,7 +1125,7 @@ }

d = q.defer();
resolveMethod(context, function(err, result) {
resolveMethod(requestContext, function(err, result) {
if (err) {
return d.reject(Boom.wrap(err));
} else {
context[resolveVar] = result;
requestContext[resolveVar] = result;
return d.resolve();

@@ -1119,3 +1142,3 @@ }

}
if (context[resolveVar]) {
if (requestContext[resolveVar]) {
continue;

@@ -1127,16 +1150,16 @@ }

return q.all(resolvePromises).then(function() {
return context;
return requestContext;
});
};
ResourceSchema.prototype._sendResource = function(model, context) {
ResourceSchema.prototype._sendResource = function(model, requestContext) {
var builtContext, next, req, res, resource, resourceByModelId;
req = context.req, res = context.res, next = context.next;
resource = this._createResourceFromModel(model, req.query.$select);
req = requestContext.req, res = requestContext.res, next = requestContext.next;
resource = this._createResourceFromModel(model, requestContext);
resourceByModelId = {};
resourceByModelId[model._id.toString()] = resource;
builtContext = this._buildContext(context, [resource], [model]);
builtContext = this._buildContext(requestContext, [resource], [model]);
builtContext.then((function(_this) {
return function() {
_this._applyGetters(resourceByModelId, [model], context);
_this._applyGetters(resourceByModelId, [model], requestContext);
res.body = resource;

@@ -1151,5 +1174,5 @@ return next();

ResourceSchema.prototype._sendResources = function(models, context) {
ResourceSchema.prototype._sendResources = function(models, requestContext) {
var next, req, res, resourceByModelId, resources;
req = context.req, res = context.res, next = context.next;
req = requestContext.req, res = requestContext.res, next = requestContext.next;
resourceByModelId = {};

@@ -1162,3 +1185,3 @@ resources = models.map((function(_this) {

}
resource = _this._createResourceFromModel(model, req.query.$select);
resource = _this._createResourceFromModel(model, requestContext);
resourceByModelId[model._id.toString()] = resource;

@@ -1168,6 +1191,6 @@ return resource;

})(this));
return this._buildContext(context, resources, models).then((function(_this) {
return this._buildContext(requestContext, resources, models).then((function(_this) {
return function() {
_this._applyGetters(resourceByModelId, models, context);
return _this._applyFilters(resources, context);
_this._applyGetters(resourceByModelId, models, requestContext);
return _this._applyFilters(resources, requestContext);
};

@@ -1184,4 +1207,31 @@ })(this)).then((function(_this) {

/*
When doing PUT or POST requests, if an optional field is on the resource, attach
it to the $add query. The resource should be returned in the same format it was posted.
*/
ResourceSchema.prototype._extendQueryWithImplicitOptionalFields = function(resources, requestContext) {
var config, req, resource, resourceField, _ref, _results;
req = requestContext.req;
req.query.$add = this._getAddFields(req.query);
resource = resources[0];
_ref = this.schema;
_results = [];
for (resourceField in _ref) {
if (!__hasProp.call(_ref, resourceField)) continue;
config = _ref[resourceField];
if (config.optional) {
if (dot.get(resource, resourceField) !== void 0) {
_results.push(req.query.$add.push(resourceField));
} else {
_results.push(void 0);
}
}
}
return _results;
};
return ResourceSchema;
})();
{
"name": "resource-schema",
"version": "0.10.3",
"version": "0.10.4",
"description": "Define schemas for RESTful resources from mongoose models, and generate middleware to GET, POST, PUT, and DELETE to those resources.",

@@ -15,2 +15,9 @@ "author": "Good Eggs <open-source@goodeggs.com>",

},
"keywords": [
"resource",
"api",
"schema",
"express",
"mongoose"
],
"homepage": "https://github.com/goodeggs/resource-schema",

@@ -17,0 +24,0 @@ "bugs": "https://github.com/goodeggs/resource-schema/issues",

Sorry, the diff of this file is not supported yet

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