defu.mjs 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. function isObject(val) {
  2. return val !== null && typeof val === "object";
  3. }
  4. function _defu(baseObj, defaults, namespace = ".", merger) {
  5. if (!isObject(defaults)) {
  6. return _defu(baseObj, {}, namespace, merger);
  7. }
  8. const obj = Object.assign({}, defaults);
  9. for (const key in baseObj) {
  10. if (key === "__proto__" || key === "constructor") {
  11. continue;
  12. }
  13. const val = baseObj[key];
  14. if (val === null) {
  15. continue;
  16. }
  17. if (merger && merger(obj, key, val, namespace)) {
  18. continue;
  19. }
  20. if (Array.isArray(val) && Array.isArray(obj[key])) {
  21. obj[key] = obj[key].concat(val);
  22. } else if (isObject(val) && isObject(obj[key])) {
  23. obj[key] = _defu(val, obj[key], (namespace ? `${namespace}.` : "") + key.toString(), merger);
  24. } else {
  25. obj[key] = val;
  26. }
  27. }
  28. return obj;
  29. }
  30. function extend(merger) {
  31. return (...args) => args.reduce((p, c) => _defu(p, c, "", merger), {});
  32. }
  33. const defu = extend();
  34. defu.fn = extend((obj, key, currentValue, _namespace) => {
  35. if (typeof obj[key] !== "undefined" && typeof currentValue === "function") {
  36. obj[key] = currentValue(obj[key]);
  37. return true;
  38. }
  39. });
  40. defu.arrayFn = extend((obj, key, currentValue, _namespace) => {
  41. if (Array.isArray(obj[key]) && typeof currentValue === "function") {
  42. obj[key] = currentValue(obj[key]);
  43. return true;
  44. }
  45. });
  46. defu.extend = extend;
  47. export default defu;