You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							53 lines
						
					
					
						
							1.2 KiB
						
					
					
				
			
		
		
	
	
							53 lines
						
					
					
						
							1.2 KiB
						
					
					
				'use strict';
 | 
						|
 | 
						|
const get = require('../get');
 | 
						|
 | 
						|
/**
 | 
						|
 * Given an update, move all $set on immutable properties to $setOnInsert.
 | 
						|
 * This should only be called for upserts, because $setOnInsert bypasses the
 | 
						|
 * strictness check for immutable properties.
 | 
						|
 */
 | 
						|
 | 
						|
module.exports = function moveImmutableProperties(schema, update, ctx) {
 | 
						|
  if (update == null) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  const keys = Object.keys(update);
 | 
						|
  for (const key of keys) {
 | 
						|
    const isDollarKey = key.startsWith('$');
 | 
						|
 | 
						|
    if (key === '$set') {
 | 
						|
      const updatedPaths = Object.keys(update[key]);
 | 
						|
      for (const path of updatedPaths) {
 | 
						|
        _walkUpdatePath(schema, update[key], path, update, ctx);
 | 
						|
      }
 | 
						|
    } else if (!isDollarKey) {
 | 
						|
      _walkUpdatePath(schema, update, key, update, ctx);
 | 
						|
    }
 | 
						|
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
function _walkUpdatePath(schema, op, path, update, ctx) {
 | 
						|
  const schematype = schema.path(path);
 | 
						|
  if (schematype == null) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  let immutable = get(schematype, 'options.immutable', null);
 | 
						|
  if (immutable == null) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  if (typeof immutable === 'function') {
 | 
						|
    immutable = immutable.call(ctx, ctx);
 | 
						|
  }
 | 
						|
 | 
						|
  if (!immutable) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  update.$setOnInsert = update.$setOnInsert || {};
 | 
						|
  update.$setOnInsert[path] = op[path];
 | 
						|
  delete op[path];
 | 
						|
} |