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

bookshelf-scopes

Package Overview
Dependencies
Maintainers
2
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bookshelf-scopes - npm Package Compare versions

Comparing version 1.4.0 to 1.5.0

test/scopes_collection.js

18

package.json
{
"name": "bookshelf-scopes",
"version": "1.4.0",
"version": "1.5.0",
"description": "Giving you Rails like scopes in Bookshelf.js.",
"main": "src/scopes.js",
"dependencies": {
"lodash": "^3.9.3"
"lodash": "^3.10.1"
},
"devDependencies": {
"bluebird": "^2.9.27",
"bookshelf": "^0.8.1",
"bluebird": "^2.11.0",
"bookshelf": "^0.8.2",
"chai": "^2.3.0",
"knex": "^0.8.6",
"mocha": "^2.2.5",
"sqlite3": "^3.0.8"
"mocha": "^2.5.3",
"sqlite3": "^3.1.8"
},

@@ -22,3 +22,3 @@ "scripts": {

"type": "git",
"url": "https://github.com/pk4media/bookshelf-scopes.git"
"url": "https://github.com/jtwebman/bookshelf-scopes.git"
},

@@ -36,5 +36,5 @@ "keywords": [

"bugs": {
"url": "https://github.com/pk4media/bookshelf-scopes/issues"
"url": "https://github.com/jtwebman/bookshelf-scopes/issues"
},
"homepage": "https://github.com/pk4media/bookshelf-scopes"
"homepage": "https://github.com/jtwebman/bookshelf-scopes"
}
# Bookshelf-Scopes
[![Circle CI](https://circleci.com/gh/pk4media/bookshelf-scopes/tree/master.svg?style=svg&circle-token=4f67b03079c057b9ae20ef5485459f97215eebe7)](https://circleci.com/gh/pk4media/bookshelf-scopes/tree/master)
[![CircleCI](https://circleci.com/gh/jtwebman/bookshelf-scopes.svg?style=svg)](https://circleci.com/gh/jtwebman/bookshelf-scopes)
Giving you Rails like scopes in Bookshelf.js.
Giving you Rails like scopes in Bookshelf.js. This was originally a [PK4Media](https://github.com/pk4media/bookshelf-scopes) project but I moved it over to my account as they do not use it anymore.

@@ -32,3 +32,3 @@ If you add in the plugin like so:

},
nameContains: function(gb, text) {
nameContains: function(qb, name) {
qb.where(knex.raw('name LIKE ?', '%' + name + '%'));

@@ -35,0 +35,0 @@ }

@@ -5,98 +5,63 @@ 'use strict';

var applyScope = function (_this, applier) {
return function (qb) {
var tempStatements = qb._statements.slice();
// Apply scope
applier.call(_this, qb);
// Find added statements
_.difference(qb._statements, tempStatements)
// Memorize scoped statements
.forEach(function (statement) {
_this.unscoped.scopeStatements.push(statement);
});
};
}
module.exports = function(bookshelf) {
var base = bookshelf.Model;
var baseExtend = bookshelf.Model.extend;
var ModelCtor = bookshelf.Model;
var CollectionCtor = bookshelf.Collection;
// `bookshelf.knex()` was deprecated in knex v0.8.0, use `knex.queryBuilder()` instead if available
var QueryBuilder = (bookshelf.knex.queryBuilder) ? bookshelf.knex.queryBuilder().constructor : bookshelf.knex().constructor;
bookshelf.Model.extend = function(protoProps, constructorProps) {
var model = baseExtend.apply(this, arguments);
var extended = function(Target) {
// Model/Collection abstraction
var isModel = !this.prototype.model;
model.prototype.scopes = model.prototype.scopes || {};
var Ctor = isModel ? ModelCtor: CollectionCtor;
_.defaults(model.prototype.scopes, this.prototype.scopes || {});
if (_.isFunction(Ctor.extended) && this.extended != Ctor.extended) {
Ctor.extended(Target);
}
Object.keys(model.prototype.scopes).forEach(function(property) {
model.prototype[property] = function() {
// Parent model
var Model = isModel ? this : Target.prototype.model;
// Inherit scopes from parent
Target.prototype.scopes = _.defaults({}, Target.prototype.scopes || {}, Model.prototype.scopes || {});
// Scopes as prototype methods
Object.keys(Target.prototype.scopes).forEach(function(property) {
Target.prototype[property] = function() {
var _this = this;
var passedInArguments = _.toArray(arguments);
if (passedInArguments.length > 0 && passedInArguments[0] instanceof QueryBuilder) {
this.scopes[property].apply(this, passedInArguments);
return this;
} else {
return this.query(function(qb) {
return this.query(applyScope(this, function(qb) {
if (passedInArguments.length == 0 || !(passedInArguments[0] instanceof QueryBuilder)) {
passedInArguments.unshift(qb);
_this.scopes[property].apply(_this, passedInArguments);
});
}
}
_this.scopes[property].apply(_this, passedInArguments);
}));
};
model[property] = function() {
var instance = model.forge();
Target[property] = function() {
var instance = Target.forge();
return instance[property].apply(instance, arguments);
};
});
_.each(['hasMany', 'hasOne', 'belongsToMany', 'morphOne', 'morphMany',
'belongsTo', 'through'], function(method) {
var original = model.prototype[method];
model.prototype[method] = function() {
var relationship = original.apply(this, arguments);
var target = relationship.model || relationship.relatedData.target;
var originalSelectConstraints = relationship.relatedData.selectConstraints;
if (target.prototype.scopes) {
relationship.relatedData.selectConstraints = function(knex, options) {
originalSelectConstraints.apply(this, arguments);
if (target.prototype.scopes.default) {
if (!knex.appliedDefault) {
knex.appliedDefault = true;
target.prototype.scopes.default.apply(this, [knex, options]);
}
}
};
Object.keys(target.prototype.scopes).forEach(function(key) {
relationship[key] = function() {
var passedInArguments = _.toArray(arguments);
var currentSelectConstraints = relationship.relatedData.selectConstraints;
relationship.relatedData.selectConstraints = function(knex, options) {
currentSelectConstraints.apply(this, arguments);
passedInArguments.unshift(knex);
target.prototype.scopes[key].apply(target.prototype, passedInArguments);
};
return relationship;
};
});
relationship.unscoped = function() {
relationship.relatedData.selectConstraints = function(knex, options) {
var originalDefaultScope;
if(target.prototype.scopes && target.prototype.scopes.default) {
originalDefaultScope = target.prototype.scopes.default;
delete target.prototype.scopes.default;
}
originalSelectConstraints.apply(this, arguments);
if (originalDefaultScope) {
target.prototype.scopes.default = originalDefaultScope;
}
};
return relationship;
};
}
return relationship;
};
});
return model;
};
var Model = bookshelf.Model.extend({
var abstractProperties = [{

@@ -106,2 +71,7 @@ scopes: null,

initialize: function() {
var superInitialize = (this instanceof ModelCtor
? ModelCtor
: CollectionCtor).prototype.initialize;
this.unscoped.scopeStatements = [];
superInitialize.apply(this, arguments);
this.addScope();

@@ -113,8 +83,7 @@ },

if (self.scopes && self.scopes.default) {
self.query(function(qb) {
self.query(applyScope(this, function(qb) {
if (!qb.appliedDefault) {
qb.appliedDefault = true;
self.scopes.default.call(self, qb);
}
});
}));
}

@@ -124,11 +93,34 @@ },

unscoped: function() {
return this.resetQuery();
var unscoped = this.unscoped;
return this.query(function function_name(qb) {
// Remove scoped statements
_.remove(qb._statements, function (statement) {
return unscoped.scopeStatements.some(_.matches(statement));
});
// Clear scoped statements registry
unscoped.scopeStatements = [];
// and default applied state
qb.appliedDefault = false;
});
}
}, {
extended: extended,
collection: function () {
var Collection = bookshelf.Collection.extend({model: this});
return new (Function.prototype.bind.apply(Collection, [null].concat(Array.prototype.slice.call(arguments))))();
},
unscoped: function() {
return this.forge().unscoped();
}
});
}];
var Model = ModelCtor.extend.apply(ModelCtor, abstractProperties);
delete abstractProperties[1].collection;
var Collection = CollectionCtor.extend.apply(CollectionCtor, abstractProperties);
bookshelf.Model = Model;
bookshelf.Collection = Collection;
};

@@ -231,2 +231,20 @@ 'use strict';

it('plugin initialize calls super initialize (#10)', function() {
var superInitializeCalled = 0;
var bookshelf = require('bookshelf')(knex);
bookshelf.Model = bookshelf.Model.extend({
initialize: function() {
superInitializeCalled++;
}
});
bookshelf.plugin(require('../src/scopes'));
var TestModel1 = bookshelf.Model.extend({
tableName: 'testmodel'
});
TestModel1.forge();
expect(superInitializeCalled).to.equal(1);
});
});

@@ -203,3 +203,3 @@ 'use strict';

active: function(qb) {
if (this !== TestModel1.prototype) {
if (!(this instanceof bookshelf.Collection) || this.model !== TestModel1) {
throw new Error('this not set to target prototype');

@@ -206,0 +206,0 @@ }

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