UNPKG

@formily/shared

Version:
208 lines 7.22 kB
import { isFn, isPlainObj } from './checkers'; import { isEmpty, isValid } from './isEmpty'; function defaultIsMergeableObject(value) { return isNonNullObject(value) && !isSpecial(value); } function isNonNullObject(value) { // TODO: value !== null && typeof value === 'object' return Boolean(value) && typeof value === 'object'; } function isSpecial(value) { // TODO: use isComplexObject() if ('$$typeof' in value && '_owner' in value) { return true; } if (value._isAMomentObject) { return true; } if (value._isJSONSchemaObject) { return true; } if (isFn(value.toJS)) { return true; } if (isFn(value.toJSON)) { return true; } return !isPlainObj(value); } function emptyTarget(val) { return Array.isArray(val) ? [] : {}; } // @ts-ignore function cloneUnlessOtherwiseSpecified(value, options) { var _a; if (options.clone !== false && ((_a = options.isMergeableObject) === null || _a === void 0 ? void 0 : _a.call(options, value))) { return deepmerge(emptyTarget(value), value, options); } return value; } function defaultArrayMerge(target, source, options) { return target.concat(source).map(function (element) { return cloneUnlessOtherwiseSpecified(element, options); }); } function getMergeFunction(key, options) { if (!options.customMerge) { return deepmerge; } var customMerge = options.customMerge(key); return typeof customMerge === 'function' ? customMerge : deepmerge; } function getEnumerableOwnPropertySymbols(target) { return Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(target).filter(function (symbol) { return target.propertyIsEnumerable(symbol); }) : []; } function getKeys(target) { if (!isValid(target)) return []; return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target)); } function propertyIsOnObject(object, property) { /* istanbul ignore next */ try { return property in object; } catch (_) { return false; } } // Protects from prototype poisoning and unexpected merging up the prototype chain. function propertyIsUnsafe(target, key) { return (propertyIsOnObject(target, key) && // Properties are safe to merge if they don't exist in the target yet, !(Object.hasOwnProperty.call(target, key) && // unsafe if they exist up the prototype chain, Object.propertyIsEnumerable.call(target, key))); // and also unsafe if they're nonenumerable. } function mergeObject(target, source, options) { var destination = options.assign ? target || {} : {}; if (!options.isMergeableObject(target)) return target; if (!options.assign) { getKeys(target).forEach(function (key) { destination[key] = cloneUnlessOtherwiseSpecified(target[key], options); }); } getKeys(source).forEach(function (key) { /* istanbul ignore next */ if (propertyIsUnsafe(target, key)) { return; } if (isEmpty(target[key])) { destination[key] = source[key]; } else if (propertyIsOnObject(target, key) && // @ts-ignore options.isMergeableObject(source[key])) { destination[key] = getMergeFunction(key, options)(target[key], source[key], options); } else { destination[key] = cloneUnlessOtherwiseSpecified(source[key], options); } }); return destination; } // @ts-ignore function deepmerge(target, source, options) { options = options || {}; options.arrayMerge = options.arrayMerge || defaultArrayMerge; options.isMergeableObject = options.isMergeableObject || defaultIsMergeableObject; // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge() // implementations can use it. The caller may not replace it. options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified; var sourceIsArray = Array.isArray(source); var targetIsArray = Array.isArray(target); var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray; if (!sourceAndTargetTypesMatch) { return cloneUnlessOtherwiseSpecified(source, options); } else if (sourceIsArray) { return options.arrayMerge(target, source, options); } else { return mergeObject(target, source, options); } } export var lazyMerge = function (target) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } var _lazyMerge = function (target, source) { if (!isValid(source)) return target; if (!isValid(target)) return source; var isTargetObject = typeof target === 'object'; var isSourceObject = typeof source === 'object'; var isTargetFn = typeof target === 'function'; var isSourceFn = typeof source === 'function'; if (!isTargetObject && !isTargetFn) return source; if (!isSourceObject && !isSourceFn) return target; var getTarget = function () { return (isTargetFn ? target() : target); }; var getSource = function () { return (isSourceFn ? source() : source); }; var set = function (_, key, value) { var source = getSource(); var target = getTarget(); if (key in source) { // @ts-ignore source[key] = value; } else if (key in target) { // @ts-ignore target[key] = value; } else { source[key] = value; } return true; }; var get = function (_, key) { var source = getSource(); // @ts-ignore if (key in source) { return source[key]; } // @ts-ignore return getTarget()[key]; }; var ownKeys = function () { var source = getSource(); var target = getTarget(); var keys = Object.keys(target); for (var key in source) { if (!(key in target)) { keys.push(key); } } return keys; }; var getOwnPropertyDescriptor = function (_, key) { return ({ value: get(_, key), enumerable: true, configurable: true, }); }; var has = function (_, key) { if (key in getSource() || key in getTarget()) return true; return false; }; var getPrototypeOf = function () { return Object.getPrototypeOf({}); }; return new Proxy(Object.create(null), { set: set, get: get, ownKeys: ownKeys, getPrototypeOf: getPrototypeOf, getOwnPropertyDescriptor: getOwnPropertyDescriptor, has: has, }); }; return args.reduce(function (buf, arg) { return _lazyMerge(buf, arg); }, target); }; export var merge = deepmerge; //# sourceMappingURL=merge.js.map