deep-merge-arrays.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /**
  2. * @fileoverview Applies default rule options
  3. * @author JoshuaKGoldberg
  4. */
  5. "use strict";
  6. /**
  7. * Check if the variable contains an object strictly rejecting arrays
  8. * @param {unknown} value an object
  9. * @returns {boolean} Whether value is an object
  10. */
  11. function isObjectNotArray(value) {
  12. return typeof value === "object" && value !== null && !Array.isArray(value);
  13. }
  14. /**
  15. * Deeply merges second on top of first, creating a new {} object if needed.
  16. * @param {T} first Base, default value.
  17. * @param {U} second User-specified value.
  18. * @returns {T | U | (T & U)} Merged equivalent of second on top of first.
  19. */
  20. function deepMergeObjects(first, second) {
  21. if (second === void 0) {
  22. return first;
  23. }
  24. if (!isObjectNotArray(first) || !isObjectNotArray(second)) {
  25. return second;
  26. }
  27. const result = { ...first, ...second };
  28. for (const key of Object.keys(second)) {
  29. if (Object.prototype.propertyIsEnumerable.call(first, key)) {
  30. result[key] = deepMergeObjects(first[key], second[key]);
  31. }
  32. }
  33. return result;
  34. }
  35. /**
  36. * Deeply merges second on top of first, creating a new [] array if needed.
  37. * @param {T[]} first Base, default values.
  38. * @param {U[]} second User-specified values.
  39. * @returns {(T | U | (T & U))[]} Merged equivalent of second on top of first.
  40. */
  41. function deepMergeArrays(first, second) {
  42. if (!first || !second) {
  43. return second || first || [];
  44. }
  45. return [
  46. ...first.map((value, i) =>
  47. deepMergeObjects(value, i < second.length ? second[i] : void 0),
  48. ),
  49. ...second.slice(first.length),
  50. ];
  51. }
  52. module.exports = { deepMergeArrays };