Socket
Socket
Sign inDemoInstall

bookshelf

Package Overview
Dependencies
Maintainers
7
Versions
87
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bookshelf - npm Package Compare versions

Comparing version 0.12.1 to 0.13.0

lib/plugins/case-converter.js

44

CHANGELOG.md
## Change Log
**0.13.0** <small>_Mar 18, 2018_</small> - [Diff](https://github.com/bookshelf/bookshelf/compare/0.12.1...0.13.0)
#### Breaking changes
- Make `require: true` the default when deleting models: [#1779](https://github.com/bookshelf/bookshelf/pull/1779)
- Remove the second argument to the model's destroyed event handler: [#1777](https://github.com/bookshelf/bookshelf/pull/1777)
- Events are now triggered sequentially even when the handlers execute asynchronous code: [#1768](https://github.com/bookshelf/bookshelf/pull/1768)
- Drop support for Node versions older than 4: [#1696](https://github.com/bookshelf/bookshelf/pull/1696)
- Reorder `saving` and `creating` events to reflect the documentation: [#1142](https://github.com/bookshelf/bookshelf/pull/1142)
#### Enhancements
- Only request `returning` attribute if client supports `returning`: [#1770](https://github.com/bookshelf/bookshelf/pull/1770)
- Throw error if user doesn't pass a valid Knex instance on initialize: [#1756](https://github.com/bookshelf/bookshelf/pull/1756)
- Add parameterized virtual properties to virtuals plugin: [#1755](https://github.com/bookshelf/bookshelf/pull/1755)
- Add individual attribute processor plugin to core: [#1741](https://github.com/bookshelf/bookshelf/pull/1741)
- Format `idAttribute` on save and delete: [#1680](https://github.com/bookshelf/bookshelf/pull/1680)
- Add `withSchema` option to all database operations: [#1638](https://github.com/bookshelf/bookshelf/pull/1638)
- Add a case converter plugin to core: [#1093](https://github.com/bookshelf/bookshelf/pull/1093)
#### Bug fixes
- Fix inconsistent timestamp values between save and fetch: [#1784](https://github.com/bookshelf/bookshelf/pull/1784)
- Set `model.id` if attributes being `.set()` contain a parsed version of `idAttribute`: [#1760](https://github.com/bookshelf/bookshelf/pull/1760)
- Fix pagination plugin's `fetchPage()` ignoring or hanging with transactions: [#1625](https://github.com/bookshelf/bookshelf/pull/1625)
- Fix `fetchPage()` from pagination plugin not working for relation collections: [#1561](https://github.com/bookshelf/bookshelf/pull/1561)
- Don't try to update `idAttribute` if it hasn't changed: [#1260](https://github.com/bookshelf/bookshelf/pull/1260)
#### Test suite
- Increase timeout of the large arrays test: [#1778](https://github.com/bookshelf/bookshelf/pull/1778)
- Add test to verify that `parentId` is not undefined when using `fetchAll` with relations: [#1769](https://github.com/bookshelf/bookshelf/pull/1769)
- Fixes and general improvements to the test suite: [#1753](https://github.com/bookshelf/bookshelf/pull/1753)
- Remove OracleDB tests: [#1744](https://github.com/bookshelf/bookshelf/pull/1744)
- Fix invalid test related to dirty attributes: [#1312](https://github.com/bookshelf/bookshelf/pull/1312)
#### Documentation
- Improve docs about running tests: [#1761](https://github.com/bookshelf/bookshelf/pull/1761)
- Fix typo on parse-and-format tutorial: [#1748](https://github.com/bookshelf/bookshelf/pull/1748)
- Add Bookshelf Manager to list of community plugins: [#1747](https://github.com/bookshelf/bookshelf/pull/1747)
#### Dependencies
- Update some dependencies: [#1787](https://github.com/bookshelf/bookshelf/pull/1787), [#1782](https://github.com/bookshelf/bookshelf/pull/1782), [#1780](https://github.com/bookshelf/bookshelf/pull/1780), [#1767](https://github.com/bookshelf/bookshelf/pull/1767) [#1746](https://github.com/bookshelf/bookshelf/pull/1746), [#1730](https://github.com/bookshelf/bookshelf/pull/1730)
**0.12.1** <small>_Jan 8, 2018_</small> - [Diff](https://github.com/bookshelf/bookshelf/compare/0.12.0...0.12.1)

@@ -4,0 +48,0 @@

7

lib/base/collection.js

@@ -613,3 +613,8 @@ 'use strict';

CollectionBase.prototype.clone = function () {
return new this.constructor(this.models, _lodash2.default.pick(this, collectionProps));
// Iterate over the selected list of collection properties and invoke `clone` for
// each property that has a method for that porpose.
var clonedProps = (0, _lodash2.default)(this).pick(collectionProps).mapValues(function (val) {
return val && typeof val.clone === 'function' ? val.clone() : val;
}).value();
return new this.constructor(this.models, clonedProps);
};

@@ -616,0 +621,0 @@

2

lib/base/events.js

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

});
return _promise2.default.map(listeners, function (listener) {
return _promise2.default.mapSeries(listeners, function (listener) {
return listener.apply(_this5, args);

@@ -178,0 +178,0 @@ });

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

var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _lodash = require('lodash');

@@ -28,10 +32,9 @@

var _constants = require('../constants');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var PIVOT_PREFIX = '_pivot_'; // Base Model
// List of attributes attached directly from the `options` passed to the constructor.
// Base Model
// ---------------
var DEFAULT_TIMESTAMP_KEYS = ['created_at', 'updated_at'];
// List of attributes attached directly from the `options` passed to the constructor.
var modelProps = ['tableName', 'hasTimestamps'];

@@ -141,12 +144,16 @@

* for each database row (typically an auto-incrementing primary key named
* `"id"`). Note that if you are using {@link Model#parse parse} and {@link
* `'id'`). Note that if you are using {@link Model#parse parse} and {@link
* Model#format format} (to have your model's attributes in `camelCase`,
* but your database's columns in `snake_case`, for example) this refers to
* the name returned by parse (`myId`), not the database column (`my_id`).
* the name returned by parse (`myId`), not the actual database column
* (`my_id`).
*
* If the table you're working with does not have an Primary-Key in the form
* of a single column - you'll have to override it with a getter that returns
* null. (overriding with undefined does not cascade the default behavior of
* the value `'id'`.
* Such a getter in ES6 would look like `get idAttribute() { return null }`
* You can also get the parsed id attribute value by using the model's
* {@link Model#parsedIdAttribute parsedIdAttribute} method.
*
* If the table you're working with does not have a Primary-Key in the form
* of a single column you'll have to override it with a getter that returns
* `null`. Overriding with `undefined` does not cascade the default behavior of
* the value `'id'`. Such a getter in ES6 would look like
* `get idAttribute() { return null }`.
*/

@@ -176,2 +183,29 @@ ModelBase.prototype.idAttribute = 'id';

* @method
* @private
* @description
*
* Converts the timestamp keys to actual Date objects. This will not run if the
* model doesn't have {@link Model#hasTimestamps hasTimestamps} set to either
* `true` or an array of key names.
* This method is run internally when reading data from the database to ensure
* data consistency between the several database implementations.
* It returns the model instance that called it, so it allows chaining of other
* model methods.
*
* @returns {Model} The model that called this.
*/
ModelBase.prototype.formatTimestamps = function formatTimestamps() {
var _this = this;
if (!this.hasTimestamps) return this;
this.getTimestampKeys().forEach(function (key) {
_this.set(key, new Date(_this.get(key)));
});
return this;
};
/**
* @method
* @description Get the current value of an attribute from the model.

@@ -189,2 +223,31 @@ * @example note.get("title");

* @method
* @private
* @description
*
* Returns the model's {@link Model#idAttribute idAttribute} after applying the
* model's {@link Model#parse parse} method to it. Doesn't mutate the original
* value of {@link Model#idAttribute idAttribute} in any way.
*
* @example
*
* var Customer = bookshelf.Model.extend({
* idAttribute: 'id',
* parse: function(attrs) {
* return _.mapKeys(attrs, function(value, key) {
* return 'parsed_' + key;
* });
* }
* });
*
* customer.parsedIdAttribute() // 'parsed_id'
*
* @returns {mixed} Whatever value the parse method returns.
*/
ModelBase.prototype.parsedIdAttribute = function () {
var parsedAttributes = this.parse((0, _defineProperty3.default)({}, this.idAttribute, null));
return parsedAttributes && Object.keys(parsedAttributes)[0];
};
/**
* @method
* @description Set a hash of attributes (one or many) on the model.

@@ -221,3 +284,3 @@ * @example

// Check for changes of `id`.
if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];else if (this.parsedIdAttribute() in attrs) this.id = attrs[this.parsedIdAttribute()];

@@ -315,3 +378,3 @@ // For each `set` attribute, update or delete the current value.

var pivotAttributes = (0, _lodash.mapKeys)(pivot, function (value, key) {
return '' + PIVOT_PREFIX + key;
return '' + _constants.PIVOT_PREFIX + key;
});

@@ -390,12 +453,12 @@

* @example
*
* // Example of a "parse" to convert snake_case to camelCase, using `underscore.string`
* // Example of a parser to convert snake_case to camelCase, using lodash
* // This is just an example. You can use the built-in case-converter plugin
* // to achieve the same functionality.
* model.parse = function(attrs) {
* return _.reduce(attrs, function(memo, val, key) {
* memo[_.camelCase(key)] = val;
* return memo;
* }, {});
* return _.mapKeys(attrs, function(value, key) {
* return _.camelCase(key);
* });
* };
*
* @param {Object} response Hash of attributes to parse.
* @param {Object} attributes Hash of attributes to parse.
* @returns {Object} Parsed attributes.

@@ -537,3 +600,19 @@ */

* @method
* @private
* @description
*
* Returns the automatic timestamp key names set on this model. Note that this
* will always return a value even if the model has {@link Model#hasTimestamps
* hasTimestamps} set to `false`. In this case and when set to `true` the
* return value will be the default names of `created_at` and `updated_at`.
*
* @returns {Array<string>} The two timestamp key names.
*/
ModelBase.prototype.getTimestampKeys = function () {
return Array.isArray(this.hasTimestamps) ? this.hasTimestamps : _constants.DEFAULT_TIMESTAMP_KEYS;
};
/**
* @method
* @description
* Sets the timestamp attributes on the model, if {@link Model#hasTimestamps

@@ -563,10 +642,9 @@ * hasTimestamps} is set to `true` or an array. Check if the model {@link

var method = this.saveMethod(options);
var keys = _lodash2.default.isArray(this.hasTimestamps) ? this.hasTimestamps : DEFAULT_TIMESTAMP_KEYS;
var canEditUpdatedAtKey = (options || {}).editUpdatedAt != undefined ? options.editUpdatedAt : true;
var canEditCreatedAtKey = (options || {}).editCreatedAt != undefined ? options.editCreatedAt : true;
var _keys = (0, _slicedToArray3.default)(keys, 2),
createdAtKey = _keys[0],
updatedAtKey = _keys[1];
var _getTimestampKeys = this.getTimestampKeys(),
_getTimestampKeys2 = (0, _slicedToArray3.default)(_getTimestampKeys, 2),
createdAtKey = _getTimestampKeys2[0],
updatedAtKey = _getTimestampKeys2[1];

@@ -573,0 +651,0 @@ if (updatedAtKey && canEditUpdatedAtKey) {

@@ -62,2 +62,10 @@ 'use strict';

// Clones a relation. Required by Pagination plugin.
}, {
key: 'clone',
value: function clone() {
return new this.constructor(null, null, this);
}
// Eager pair the models.

@@ -64,0 +72,0 @@

@@ -50,2 +50,5 @@ 'use strict';

function Bookshelf(knex) {
if (!knex || knex.name !== 'knex') {
throw new Error('Invalid knex instance');
}
var bookshelf = {

@@ -56,3 +59,2 @@ VERSION: require('../package.json').version

var Model = bookshelf.Model = _model2.default.extend({
_builder: builderFn,

@@ -266,5 +268,52 @@

// Provides a nice, tested, standardized way of adding plugins to a
// `Bookshelf` instance, injecting the current instance into the plugin,
// which should be a module.exports.
/**
* @method Bookshelf#plugin
* @memberOf Bookshelf
* @description
*
* This method provides a nice, tested, standardized way of adding plugins
* to a `Bookshelf` instance, injecting the current instance into the
* plugin, which should be a `module.exports`.
*
* You can add a plugin by specifying a string with the name of the plugin
* to load. In this case it will try to find a module. It will first check
* for a match within the `bookshelf/plugins` directory. If nothing is
* found it will pass the string to `require()`, so you can either require
* an npm dependency by name or one of your own modules by relative path:
*
* bookshelf.plugin('./bookshelf-plugins/my-favourite-plugin');
* bookshelf.plugin('plugin-from-npm');
*
* There are a few built-in plugins already, along with many independently
* developed ones. See [the list of available plugins](#plugins).
*
* You can also provide an array of strings or functions, which is the same
* as calling `bookshelf.plugin()` multiple times. In this case the same
* options object will be reused:
*
* bookshelf.plugin(['registry', './my-plugins/special-parse-format']);
*
* Example plugin:
*
* // Converts all string values to lower case when setting attributes on a model
* module.exports = function(bookshelf) {
* bookshelf.Model = bookshelf.Model.extend({
* set: function(key, value, options) {
* if (!key) return this;
* if (typeof value === 'string') value = value.toLowerCase();
* return bookshelf.Model.prototype.set.call(this, key, value, options);
* }
* });
* }
*
* @param {string|array|Function} plugin
* The plugin or plugins to add. If you provide a string it can
* represent a built-in plugin, an npm package or a file somewhere on
* your project. You can also pass a function as argument to add it as a
* plugin. Finally, it's also possible to pass an array of strings or
* functions to add them all at once.
* @param {mixed} options
* This can be anything you want and it will be passed directly to the
* plugin as the second argument when loading it.
*/
plugin: function plugin(_plugin, options) {

@@ -271,0 +320,0 @@ var _this = this;

@@ -446,3 +446,6 @@ 'use strict';

this.set(response, { silent: true, parse: true }).invokeMap('_reset');
this.set(response, { silent: true, parse: true }).invokeMap('formatTimestamps');
this.invokeMap('_reset');
if (relatedData && relatedData.isJoined()) {

@@ -449,0 +452,0 @@ relatedData.parsePivot(this.models);

@@ -6,2 +6,3 @@ 'use strict';

});
var PIVOT_PREFIX = exports.PIVOT_PREFIX = '_pivot_';
var PIVOT_PREFIX = exports.PIVOT_PREFIX = '_pivot_';
var DEFAULT_TIMESTAMP_KEYS = exports.DEFAULT_TIMESTAMP_KEYS = ['created_at', 'updated_at'];

@@ -49,4 +49,2 @@ 'use strict';

var DEFAULT_TIMESTAMP_KEYS = ['created_at', 'updated_at'];
/**

@@ -1019,9 +1017,7 @@ * @class Model

// Obtain the keys for the timestamp columns
var keys = _lodash2.default.isArray(this.hasTimestamps) ? this.hasTimestamps : DEFAULT_TIMESTAMP_KEYS;
var _getTimestampKeys = this.getTimestampKeys(),
_getTimestampKeys2 = (0, _slicedToArray3.default)(_getTimestampKeys, 2),
createdAtKey = _getTimestampKeys2[0],
updatedAtKey = _getTimestampKeys2[1];
var _keys = (0, _slicedToArray3.default)(keys, 2),
createdAtKey = _keys[0],
updatedAtKey = _keys[1];
// Now set timestamps if appropriate. Extend `attrs` so that the

@@ -1119,3 +1115,3 @@ // timestamps will be provided for a patch operation.

*/
return this.triggerThen(method === 'insert' ? 'creating saving' : 'updating saving', this, attrs, options).bind(this).then(function () {
return this.triggerThen(method === 'insert' ? 'saving creating' : 'saving updating', this, attrs, options).bind(this).then(function () {
return sync[options.method](method === 'update' && options.patch ? attrs : this.attributes);

@@ -1201,3 +1197,4 @@ }).then(function (resp) {

* @param {bool} [options.require=true]
* Throw a {@link Model.NoRowsDeletedError} if no records are affected by destroy.
* Throw a {@link Model.NoRowsDeletedError} if no records are affected by destroy. This is
* the default behavior as of version 0.13.0.
*

@@ -1242,3 +1239,3 @@ * @example

}).then(function (affectedRows) {
if (options.require && affectedRows === 0) {
if (options.require !== false && affectedRows === 0) {
throw new this.constructor.NoRowsDeletedError('No Rows Deleted');

@@ -1256,7 +1253,6 @@ }

* @param {Model} model The model firing the event.
* @param {Object} affectedRows Number of affected rows.
* @param {Object} options Options object passed to {@link Model#destroy destroy}.
* @returns {Promise}
*/
return this.triggerThen('destroyed', this, affectedRows, options);
return this.triggerThen('destroyed', this, options);
}).then(this._reset);

@@ -1452,3 +1448,5 @@ }),

var relatedData = this.relatedData;
this.set(this.parse(response[0]), { silent: true })._reset();
this.set(this.parse(response[0]), { silent: true }).formatTimestamps()._reset();
if (relatedData && relatedData.isJoined()) {

@@ -1455,0 +1453,0 @@ relatedData.parsePivot([this]);

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

module.exports = function paginationPlugin(bookshelf) {
var Model = bookshelf.Model;
/**

@@ -125,2 +125,3 @@ * @method Model#fetchPage

fetchOptions = (0, _objectWithoutProperties3.default)(options, ['page', 'pageSize', 'limit', 'offset']);
var transacting = fetchOptions.transacting;

@@ -161,8 +162,19 @@

var tableName = this.constructor.prototype.tableName;
var idAttribute = this.constructor.prototype.idAttribute ? this.constructor.prototype.idAttribute : 'id';
var isModel = this instanceof Model;
var _ref = isModel ? ['fetchAll', this.constructor] : ['fetch', this.target || this.model],
_ref2 = (0, _slicedToArray3.default)(_ref, 2),
fetchMethodName = _ref2[0],
targetModel = _ref2[1];
var _targetModel$prototyp = targetModel.prototype,
tableName = _targetModel$prototyp.tableName,
_targetModel$prototyp2 = _targetModel$prototyp.idAttribute,
idAttribute = _targetModel$prototyp2 === undefined ? 'id' : _targetModel$prototyp2;
var targetIdColumn = tableName + '.' + idAttribute;
var paginate = function paginate() {
// const pageQuery = clone(this.query());
var pager = _this.constructor.forge();
var pager = _this.clone();

@@ -174,3 +186,3 @@ return pager.query(function (qb) {

return null;
}).fetchAll(fetchOptions);
})[fetchMethodName](fetchOptions);
};

@@ -180,3 +192,3 @@

var notNeededQueries = ['orderByBasic', 'orderByRaw', 'groupByBasic', 'groupByRaw'];
var counter = _this.constructor.forge();
var counter = _this.clone();

@@ -192,4 +204,9 @@ return counter.query(function (qb) {

});
qb.countDistinct.apply(qb, [tableName + '.' + idAttribute]);
}).fetchAll().then(function (result) {
if (!isModel && counter.relatedData) {
// Remove joining columns that break COUNT operation.
// eg. pivotal coulmns for belongsToMany relation.
counter.relatedData.joinColumns = _lodash.noop;
}
qb.countDistinct.apply(qb, [targetIdColumn]);
})[fetchMethodName]({ transacting: transacting }).then(function (result) {

@@ -214,6 +231,6 @@ var metadata = usingPageSize ? { page: _page, pageSize: _limit } : { offset: _offset, limit: _limit };

return _bluebird2.default.join(paginate(), count()).then(function (_ref) {
var _ref2 = (0, _slicedToArray3.default)(_ref, 2),
rows = _ref2[0],
metadata = _ref2[1];
return _bluebird2.default.join(paginate(), count()).then(function (_ref3) {
var _ref4 = (0, _slicedToArray3.default)(_ref3, 2),
rows = _ref4[0],
metadata = _ref4[1];

@@ -234,9 +251,3 @@ var pageCount = Math.ceil(metadata.rowCount / _limit);

bookshelf.Collection.prototype.fetchPage = function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return fetchPage.apply(this.model.forge(), args);
};
bookshelf.Collection.prototype.fetchPage = fetchPage;
};

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

if (options && options.virtuals === true || this.outputVirtuals) {
attrs = _lodash2.default.extend(attrs, getVirtuals(this));
attrs = _lodash2.default.extend(attrs, getVirtuals(this, options && options.virtualParams));
}

@@ -70,6 +70,10 @@ }

get: function get(attr) {
for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
params[_key - 1] = arguments[_key];
}
var virtuals = this.virtuals;
if (_lodash2.default.isObject(virtuals) && virtuals[attr]) {
return getVirtual(this, attr);
return getVirtual.apply(undefined, [this, attr].concat(params));
}

@@ -81,3 +85,2 @@ return proto.get.apply(this, arguments);

set: function set(key, value, options) {
if (key == null) {

@@ -168,3 +171,3 @@ return this;

// Underscore methods that we want to implement on the Model.
// Lodash methods that we want to implement on the Model.
var modelMethods = ['keys', 'values', 'toPairs', 'invert', 'pick', 'omit'];

@@ -183,7 +186,13 @@

if (_lodash2.default.isObject(virtuals) && virtuals[virtualName]) {
return virtuals[virtualName].get ? virtuals[virtualName].get.call(model) : virtuals[virtualName].call(model);
var _virtuals$virtualName, _virtuals$virtualName2;
for (var _len2 = arguments.length, params = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
params[_key2 - 2] = arguments[_key2];
}
return virtuals[virtualName].get ? (_virtuals$virtualName = virtuals[virtualName].get).call.apply(_virtuals$virtualName, [model].concat(params)) : (_virtuals$virtualName2 = virtuals[virtualName]).call.apply(_virtuals$virtualName2, [model].concat(params));
}
}
function getVirtuals(model) {
function getVirtuals(model, params) {
var virtuals = model.virtuals;

@@ -194,3 +203,4 @@

for (var virtualName in virtuals) {
attrs[virtualName] = getVirtual(model, virtualName);
var paramsForVirtual = (typeof params === 'undefined' ? 'undefined' : (0, _typeof3.default)(params)) === 'object' && params !== null ? params[virtualName] : undefined;
attrs[virtualName] = getVirtual(model, virtualName, paramsForVirtual);
}

@@ -197,0 +207,0 @@ }

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

model.attributes = model.parse(model.attributes);
model._reset();
model.formatTimestamps()._reset();
});

@@ -434,0 +434,0 @@

'use strict';
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _lodash = require('lodash');

@@ -13,2 +17,8 @@

// Sync
// ---------------
var supportsReturning = function supportsReturning(client) {
return _lodash2.default.includes(['postgresql', 'postgres', 'pg', 'oracle', 'mssql'], client);
};
// Sync is the dispatcher for any database queries,

@@ -19,4 +29,2 @@ // taking the "syncing" `model` or `collection` being queried, along with

// part of a transaction, and this information is passed along to `Knex`.
// Sync
// ---------------
var Sync = function Sync(syncing, options) {

@@ -29,2 +37,3 @@ options = options || {};

if (options.transacting) this.query.transacting(options.transacting);
if (options.withSchema) this.query.withSchema(options.withSchema);
};

@@ -202,3 +211,3 @@

var syncing = this.syncing;
return this.query.insert(syncing.format(_lodash2.default.extend(Object.create(null), syncing.attributes)), syncing.idAttribute);
return this.query.insert(syncing.format(_lodash2.default.extend(Object.create(null), syncing.attributes)), supportsReturning(this.query.client.config.client) ? syncing.idAttribute : null);
}),

@@ -210,7 +219,11 @@

query = this.query;
if (syncing.id != null) query.where(syncing.idAttribute, syncing.id);
if (syncing.id != null) query.where(syncing.format((0, _defineProperty3.default)({}, syncing.idAttribute, syncing.id)));
if (_lodash2.default.filter(query._statements, { grouping: 'where' }).length === 0) {
throw new Error('A model cannot be updated without a "where" clause or an idAttribute.');
}
return query.update(syncing.format(_lodash2.default.extend(Object.create(null), attrs)));
var updating = syncing.format(_lodash2.default.extend(Object.create(null), attrs));
if (syncing.id === updating[syncing.idAttribute]) {
delete updating[syncing.idAttribute];
}
return query.update(updating);
}),

@@ -222,3 +235,3 @@

syncing = this.syncing;
if (syncing.id != null) query.where(syncing.idAttribute, syncing.id);
if (syncing.id != null) query.where(syncing.format((0, _defineProperty3.default)({}, syncing.idAttribute, syncing.id)));
if (_lodash2.default.filter(query._statements, { grouping: 'where' }).length === 0) {

@@ -225,0 +238,0 @@ throw new Error('A model cannot be destroyed without a "where" clause or an idAttribute.');

{
"name": "bookshelf",
"version": "0.12.1",
"version": "0.13.0",
"description": "A lightweight ORM for PostgreSQL, MySQL, and SQLite3",

@@ -46,4 +46,4 @@ "main": "bookshelf.js",

"bookshelf-jsdoc-theme": "^0.2.0",
"chai": "^3.5.0",
"eslint": "4.15.0",
"chai": "4.0.2",
"eslint": "^4.17.0",
"istanbul": "^0.4.5",

@@ -53,9 +53,9 @@ "jsdoc": "^3.4.0",

"minimist": "^1.1.0",
"mocha": "^3.0.2",
"mocha": "^5.0.0",
"mysql": "^2.5.2",
"pg": "^6.1.0",
"pg": "^7.4.1",
"semver": "^5.0.3",
"sinon": "^4.1.3",
"sinon-chai": "^2.6.0",
"sqlite3": "^3.0.5",
"sinon-chai": "^3.0.0",
"sqlite3": "^4.0.0",
"uuid": "^3.1.0"

@@ -79,3 +79,6 @@ },

"license": "MIT",
"readmeFilename": "README.md"
"readmeFilename": "README.md",
"engines": {
"node": ">=4"
}
}

@@ -116,2 +116,4 @@ # [bookshelf.js](http://bookshelfjs.org)

* [Pagination](https://github.com/bookshelf/bookshelf/wiki/Plugin:-Pagination): Adds `fetchPage` methods to use for pagination in place of `fetch` and `fetchAll`.
* [Case Converter](https://github.com/bookshelf/bookshelf/wiki/Plugin:-Case-Converter): Handles the conversion between the database's snake_cased and a model's camelCased properties automatically.
* [Processor](https://github.com/bookshelf/bookshelf/wiki/Plugin:-Processor): Allows defining custom processor functions that handle transformation of values whenever they are `.set()` on a model.

@@ -133,2 +135,3 @@ ## Community plugins

* [bookshelf-ez-fetch](https://github.com/DJAndries/bookshelf-ez-fetch) - Convenient fetching methods which allow for compact filtering, relation selection and error handling.
* [bookshelf-manager](https://github.com/ericclemmons/bookshelf-manager) - Model & Collection manager to make it easy to create & save deep, nested JSON structures from API requests.

@@ -169,6 +172,5 @@ ## Support

The test suite looks for an environment variable called `BOOKSHELF_TEST` for the path to the database configuration. If you run the following command: `$ export BOOKSHELF_TEST='/path/to/your/bookshelf_config.js'`, replacing with the path to your config file, and the config file is valid, the test suite should run with npm test.
See the [CONTRIBUTING](https://github.com/bookshelf/bookshelf/blob/master/.github/CONTRIBUTING.md#running-the-tests)
document on GitHub.
Also note that you will have to create the appropriate database(s) for the test suite to run. For example, with MySQL, you'll need to run the command `create database bookshelf_test;` in addition to exporting the correct test settings prior to running the test suite.
### Can I use Bookshelf outside of Node.js?

@@ -175,0 +177,0 @@

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