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];
|
|
}
|