From 3e670427a087e467de2a90a66685968fc7cfdb5c Mon Sep 17 00:00:00 2001 From: Rob Capellini Date: Sun, 21 Aug 2016 23:27:10 +0200 Subject: [PATCH] fix: store('scope').update() ignores scope Ensures that when calling `store('scope').update(...)`, that only items in scope are updated. Items out of scope are ignored. This code assumes the following: * `storedObjects` is an array with the exact same size as `objectsOrIds` * `objectsOrIds` is either a string, an object, a list of strings, or a list of objects * if `objectsOrIds` is not an array then it is a single string representing an id or a single object and, as a result, `storedObjects` will either be null or a single object * when attempting to find a single objectOrId, a single object is returned (rather than an array with one object) * every item returned by find() will have an id associated with it. --- lib/scoped/update.js | 50 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/lib/scoped/update.js b/lib/scoped/update.js index 0b6fd75..a33ad82 100644 --- a/lib/scoped/update.js +++ b/lib/scoped/update.js @@ -1,11 +1,59 @@ module.exports = update var find = require('./find') +var merge = require('lodash/merge') function update (type, api, objectsOrIds, change) { return find(type, api, objectsOrIds) .then(function (storedObjects) { - return api.update(objectsOrIds, change) + // objectsOrIds may contain updated information for the respective storedObject + // (e.g. _deleted = true), so incorporate all information in the objectOrId into + // the storedObject + var updatedObjects = updateObjectsAndFilterErrors(objectsOrIds, storedObjects) + + return api.update(updatedObjects, change) + + .then(function (apiUpdates) { + if (!Array.isArray(apiUpdates)) { + return apiUpdates + } + + return restoreOriginalFindErrors(storedObjects, apiUpdates) + }) + }) +} + +function updateObjectsAndFilterErrors (objectsOrIds, storedObjects) { + if (!Array.isArray(objectsOrIds)) { + return updateObject(objectsOrIds, storedObjects) + } + + return storedObjects.map(function (storedObject, index) { + if (storedObject instanceof Error) { + return storedObject + } + + return updateObject(objectsOrIds[index], storedObject) + }).filter(function (storedObject) { + return !(storedObject instanceof Error) + }) +} + +function updateObject (objectOrId, storedObject) { + if (typeof objectOrId !== 'object') { + return storedObject + } + + return merge(storedObject, objectOrId) +} + +function restoreOriginalFindErrors (foundObjects, apiUpdates) { + return foundObjects.map(function (foundObject) { + if (foundObject instanceof Error) { + return foundObject + } + + return apiUpdates.shift() }) }