lib/services/db-operations.js
function getPutOperations(putFn, uri, data, locals) {
  // potentially propagate version throughout object
  const cmptOrLayout = splitCascadingData(uri, replacePropagatingVersions(uri, data));

  // if locals exist and there are more than one component being put,
  // then we should pass a read-only version to each component so they can't affect each other
  // this operation isn't needed in the common case of putting a single object
  if (!!locals && cmptOrLayout.length > 0) {
    locals = control.setReadOnly(_.cloneDeep(locals));
  }

  // run each through the normal put, which may or may not hit custom component logic
  return bluebird.map(cmptOrLayout, ({ key, value }) => putFn(key, value, locals))
    .then(ops => _.filter(_.flattenDeep(ops), _.identity));
}
function getPutOperations(putFn, uri, data, locals) {
  // potentially propagate version throughout object
  const cmptOrLayout = splitCascadingData(uri, replacePropagatingVersions(uri, data));

  // if locals exist and there are more than one component being put,
  // then we should pass a read-only version to each component so they can't affect each other
  // this operation isn't needed in the common case of putting a single object
  if (!!locals && cmptOrLayout.length > 0) {
    locals = control.setReadOnly(_.cloneDeep(locals));
  }

  // run each through the normal put, which may or may not hit custom component logic
  return bluebird.map(cmptOrLayout, ({ key, value }) => putFn(key, value, locals))
    .then(ops => _.filter(_.flattenDeep(ops), _.identity));
}
function getPutOperations ( putFn , uri , data , locals ) { // potentially propagate version throughout object const cmptOrLayout = splitCascadingData ( uri , replacePropagatingVersions ( uri , data ) ) ; // if locals exist and there are more than one component being put, // then we should pass a read-only version to each component so they can't affect each other // this operation isn't needed in the common case of putting a single object if ( ! ! locals && cmptOrLayout . length > 0 ) { locals = control . setReadOnly ( _ . cloneDeep ( locals ) ) ; } // run each through the normal put, which may or may not hit custom component logic return bluebird . map ( cmptOrLayout , ( { key , value } ) => putFn ( key , value , locals ) ) . then ( ops => _ . filter ( _ . flattenDeep ( ops ) , _ . identity ) ) ; }
Get a list of all the put operations needed to complete a cascading PUT

NOTE: this function changes the data object _in-place_ for speed and memory reasons. We are not okay with doing
a deep clone here, because that will significantly slow down this operation.  If someone wants to deep clone the data
before this operation, they can.

@param {Function} putFn
@param {String} uri
@param {Object} data
@param {Object} [locals]
@returns {Promise}
Get a list of all the put operations needed to complete a cascading PUT