New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

baucis

Package Overview
Dependencies
Maintainers
1
Versions
202
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

baucis - npm Package Compare versions

Comparing version

to
0.10.0

18

CHANGES.md
Baucis Change Log
=================
v0.10.0
-------
Send `409 Conflict` when there are document version conflicts. This is useful for optimistic locking.
Mongoose only updates `__v` for certain array operations by default. To update for every save (optimistic locking), add this Mongoose middleware to the schema:
schema.pre('save', funciton (next) {
this.increment();
next();
});
By default, document version is only checked for conflict when the versionKey is sent with the PUT request, otherwise no version checking is done. To force version checking for all PUT requests:
var controller = baucis.rest({
singular: 'tea',
'always check version': true
});
v0.9.4

@@ -5,0 +23,0 @@ ------

@@ -59,2 +59,5 @@ // __Dependencies__

var update = extend(request.body);
var versionKey = request.baucis.controller.get('schema').get('versionKey');
var alwaysCheckVersion = request.baucis.controller.get('always check version');
var version = update[versionKey];
var done = function (error, saved) {

@@ -67,2 +70,3 @@ if (error) return next(error);

if (operator && validOperators.indexOf(operator) === -1) return next(new Error('Unsupported update operator: ' + operator));
if (alwaysCheckVersion && (version !== 0) && !version) return response.send(409);

@@ -73,2 +77,13 @@ request.baucis.query.exec(function (error, doc) {

var previousVersion = doc[versionKey];
if (alwaysCheckVersion && !doc.isSelected(versionKey)) {
next(new Error('version key "'+ versionKey + '" was not selected.'));
return;
}
if (previousVersion && (version || version === 0) && version < previousVersion) {
response.send(409);
return;
}
if (!operator) {

@@ -75,0 +90,0 @@ doc.set(update);

2

package.json

@@ -5,3 +5,3 @@ {

"homepage": "https://github.com/wprl/baucis",
"version": "0.9.4",
"version": "0.10.0",
"main": "index.js",

@@ -8,0 +8,0 @@ "scripts": {

@@ -1,3 +0,3 @@

baucis v0.9.4
=============
baucis v0.10.0
==============

@@ -230,2 +230,3 @@ Baucis is Express middleware that creates configurable REST APIs using Mongoose schemata.

| head, get, post, put, del | May be set to false to disable those HTTP verbs completely for the controller |
| always check version | Force all PUTs to send the document version (__v). By default, if a version is not sent with an update no version checking is performed. |

@@ -232,0 +233,0 @@ An example of embedding a controller within another controller

@@ -248,3 +248,3 @@ var expect = require('expect.js');

url: 'http://localhost:8012/api/v1/stores/123/tools/' + id,
json: { name: 'Screwdriver' }
json: { name: 'Screwdriver', __v: body[0].__v + 10 }
};

@@ -342,3 +342,3 @@ request.put(options, function (error, response, body) {

url: 'http://localhost:8012/api/v1/stores/Westlake',
json: { mercoledi: false }
json: { mercoledi: false, __v: 0 }
};

@@ -482,3 +482,3 @@ request.put(options, function (error, response, body) {

json: true,
body: { molds: 'penicillium roqueforti' }
body: { molds: 'penicillium roqueforti', __v: 0 }
};

@@ -532,3 +532,3 @@ request.put(options, function (error, response, body) {

json: true,
body: { molds: 'penicillium roqueforti' }
body: { molds: 'penicillium roqueforti', __v: 0 }
};

@@ -593,3 +593,3 @@ request.put(options, function (error, response, body) {

json: true,
body: { molds: 'penicillium roqueforti' }
body: { molds: 'penicillium roqueforti', __v: 0 }
};

@@ -744,2 +744,95 @@ request.put(options, function (error, response, body) {

it('should send "409 Conflict" if there is a version conflict', function (done) {
var options = {
url: 'http://localhost:8012/api/v1/stores/Westlake',
json: true,
body: { __v: 10 }
};
request.put(options, function (error, response, body) {
if (error) return done(error);
expect(response).to.have.property('statusCode', 200);
var options = {
url: 'http://localhost:8012/api/v1/stores/Westlake',
json: true,
body: { __v: 0 }
};
request.put(options, function (error, response, body) {
if (error) return done(error);
expect(response).to.have.property('statusCode', 409);
done();
});
});
});
it('should not send "409 Conflict" if there is no version conflict (equal)', function (done) {
var options = {
url: 'http://localhost:8012/api/v1/cheeses/Camembert',
json: true
};
request.get(options, function (error, response, body) {
if (error) return done(error);
expect(response).to.have.property('statusCode', 200);
var options = {
url: 'http://localhost:8012/api/v1/cheeses/Camembert',
json: true,
body: { __v: body.__v }
};
request.put(options, function (error, response, body) {
if (error) return done(error);
expect(response).to.have.property('statusCode', 200);
done();
});
});
});
it('should not send "409 Conflict" if there is no version conflict (greater than)', function (done) {
var options = {
url: 'http://localhost:8012/api/v1/cheeses/Camembert',
json: true
};
request.get(options, function (error, response, body) {
if (error) return done(error);
expect(response).to.have.property('statusCode', 200);
var options = {
url: 'http://localhost:8012/api/v1/cheeses/Camembert',
json: true,
body: { __v: body.__v + 10 }
};
request.put(options, function (error, response, body) {
if (error) return done(error);
expect(response).to.have.property('statusCode', 200);
done();
});
});
});
it('should send "409 Conflict" if alwaysCheckVersion is enabled and no version is sent', function (done) {
var options = {
url: 'http://localhost:8012/api/v1/stores/Westlake',
json: true,
body: { }
};
request.put(options, function (error, response, body) {
if (error) return done(error);
expect(response).to.have.property('statusCode', 409);
done();
});
});
it('should cause an error if alwaysCheckVersion is enabled and no version is selected', function (done) {
var options = {
url: 'http://localhost:8012/api/v1/stores/Westlake',
json: true,
qs: { select: '-__v' },
body: { __v: 1000 }
};
request.put(options, function (error, response, body) {
if (error) return done(error);
expect(response).to.have.property('statusCode', 500);
done();
});
});
});

@@ -22,2 +22,7 @@ var mongoose = require('mongoose');

Stores.on('save', function (next) {
this.increment();
next();
});
var Tools = new Schema({

@@ -39,2 +44,7 @@ name: { type: String, required: true },

Cheese.on('save', function (next) {
this.increment();
next();
});
var Beans = new Schema({ koji: Boolean });

@@ -72,3 +82,4 @@ var Deans = new Schema({ room: { type: Number, unique: true } });

findBy: 'name',
select: '-mercoledi'
select: '-mercoledi',
'always check version': true
});

@@ -104,2 +115,3 @@

findBy: 'name',
// 'always check version': true,
'allow $push': 'molds arbitrary arbitrary.$.llama',

@@ -106,0 +118,0 @@ 'allow $set': 'molds arbitrary.$.champagne',