Skip to content

Commit

Permalink
fix: Correct behaviour of _.cloneDeep when working with buffers
Browse files Browse the repository at this point in the history
  • Loading branch information
notheotherben committed Nov 17, 2015
1 parent e182b97 commit 6419b2a
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 10 deletions.
16 changes: 8 additions & 8 deletions lib/Instance.ts
Expand Up @@ -43,7 +43,7 @@ export class Instance<TDocument extends { _id?: any }, TInstance> {
this._isNew = !!isNew;
this._isPartial = isPartial;
this._original = document;
this._modified = _.cloneDeep<TDocument>(document);
this._modified = model.helpers.cloneDocument(document);

_.each(model.core.plugins,(plugin: Plugin) => {
if (plugin.newInstance) plugin.newInstance(this, model);
Expand Down Expand Up @@ -162,15 +162,15 @@ export class Instance<TDocument extends { _id?: any }, TInstance> {
});

return Bluebird.resolve().then(() => {
conditions = _.cloneDeep(conditions);
conditions = this._model.helpers.cloneConditions(conditions);
_.merge(conditions, { _id: this._modified._id });

if (!changes) {
var validation = this._model.helpers.validate(this._modified);
if (validation.failed) return Bluebird.reject(validation.error).bind(this).nodeify(callback);

var original = _.cloneDeep(this._original);
var modified = _.cloneDeep(this._modified);
var original = this._model.helpers.cloneDocument(this._original);
var modified = this._model.helpers.cloneDocument(this._modified);

changes = this._model.helpers.diff(original, modified);
}
Expand Down Expand Up @@ -221,15 +221,15 @@ export class Instance<TDocument extends { _id?: any }, TInstance> {
}).then((latest: TDocument) => {
if(!latest) {
this._isNew = true;
this._original = _.cloneDeep(this._modified);
this._original = this._model.helpers.cloneDocument(this._modified);
return Bluebird.resolve(<TInstance><any>this);
}

return this._model.handlers.documentReceived(conditions, latest, (value) => {
this._isPartial = false;
this._isNew = false;
this._modified = value;
this._original = _.cloneDeep(value);
this._original = this._model.helpers.cloneDocument(value);
return <TInstance><any>this;
});
}).nodeify(callback);
Expand Down Expand Up @@ -263,15 +263,15 @@ export class Instance<TDocument extends { _id?: any }, TInstance> {
if (!newDocument) {
this._isPartial = true;
this._isNew = true;
this._original = _.cloneDeep<TDocument>(this._modified);
this._original = this._model.helpers.cloneDocument(this._modified);
return <Bluebird<TInstance>><any>this;
}

return this._model.handlers.documentReceived(conditions, newDocument, (doc) => {
this._isNew = false;
this._isPartial = false;
this._original = doc;
this._modified = _.cloneDeep<TDocument>(doc);
this._modified = this._model.helpers.cloneDocument(doc);

return <TInstance><any>this;
});
Expand Down
30 changes: 28 additions & 2 deletions lib/ModelHelpers.ts
Expand Up @@ -47,8 +47,9 @@ export class ModelHelpers<TDocument extends { _id?: any }, TInstance> {
*/
transformToDB<T>(document: T): T {
for (var property in this.model.transforms)
if(document.hasOwnProperty(property))
if(document.hasOwnProperty(property)) {
document[property] = this.model.transforms[property].toDB(document[property]);
}
return document;
}

Expand All @@ -59,7 +60,7 @@ export class ModelHelpers<TDocument extends { _id?: any }, TInstance> {
* @returns {any} A new document cloned from the original and transformed
*/
convertToDB<T>(document: T): T {
var doc: T = _.cloneDeep(document);
var doc: T = this.cloneDocument(document);
return this.transformToDB(doc);
}

Expand All @@ -73,4 +74,29 @@ export class ModelHelpers<TDocument extends { _id?: any }, TInstance> {
omnom.diff(original, modified);
return omnom.changes;
}

/**
* Clones the given document recursively, taking into account complex types like
* Buffers correctly.
*
* @param {any} The document you wish to clone deeply.
*/
cloneDocument<T>(original: T): T {
return _.cloneDeep(original, (value) => {
if(Buffer.isBuffer(value)) {
return (<Buffer>value).slice();
}
});
}

/**
* Clones the given document recursively, taking into account complex types like
* Buffers correctly. Optimized for working with query documents instead of true
* documents.
*
* @param {any} The document you wish to clone deeply.
*/
cloneConditions<T>(original: T): T {
return this.cloneDocument(original);
}
}

0 comments on commit 6419b2a

Please sign in to comment.