applyToDefaults.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. 'use strict';
  2. const Assert = require('./assert');
  3. const Clone = require('./clone');
  4. const Merge = require('./merge');
  5. const Utils = require('./utils');
  6. const internals = {};
  7. module.exports = function (defaults, source, options = {}) {
  8. Assert(defaults && typeof defaults === 'object', 'Invalid defaults value: must be an object');
  9. Assert(!source || source === true || typeof source === 'object', 'Invalid source value: must be true, falsy or an object');
  10. Assert(typeof options === 'object', 'Invalid options: must be an object');
  11. if (!source) { // If no source, return null
  12. return null;
  13. }
  14. if (options.shallow) {
  15. return internals.applyToDefaultsWithShallow(defaults, source, options);
  16. }
  17. const copy = Clone(defaults);
  18. if (source === true) { // If source is set to true, use defaults
  19. return copy;
  20. }
  21. const nullOverride = options.nullOverride !== undefined ? options.nullOverride : false;
  22. return Merge(copy, source, { nullOverride, mergeArrays: false });
  23. };
  24. internals.applyToDefaultsWithShallow = function (defaults, source, options) {
  25. const keys = options.shallow;
  26. Assert(Array.isArray(keys), 'Invalid keys');
  27. options = Object.assign({}, options);
  28. options.shallow = false;
  29. const copy = Clone(defaults, { shallow: keys });
  30. if (source === true) { // If source is set to true, use defaults
  31. return copy;
  32. }
  33. const storage = Utils.store(source, keys); // Move shallow copy items to storage
  34. Merge(copy, source, { mergeArrays: false, nullOverride: false }); // Deep copy the rest
  35. Utils.restore(copy, source, storage); // Shallow copy the stored items and restore
  36. return copy;
  37. };