215 lines
7.0 KiB
JavaScript

Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
//#region src/constants.ts
let PriorityName = /* @__PURE__ */ function(PriorityName) {
PriorityName["LEFT"] = "left";
PriorityName["RIGHT"] = "right";
return PriorityName;
}({});
//#endregion
//#region src/utils/check.ts
function isObject(item) {
return !!item && typeof item === "object" && !Array.isArray(item);
}
function isSafeKey(key) {
return key !== "__proto__" && key !== "prototype" && key !== "constructor";
}
function isEqual(x, y) {
if (Object.is(x, y)) return true;
if (x instanceof Date && y instanceof Date) return x.getTime() === y.getTime();
if (x instanceof RegExp && y instanceof RegExp) return x.toString() === y.toString();
if (isObject(x) && isObject(y)) {
const keysX = Reflect.ownKeys(x);
const keysY = Reflect.ownKeys(y);
if (keysX.length !== keysY.length) return false;
for (let i = 0; i < keysX.length; i++) {
const key = keysX[i];
if (!Reflect.has(y, key) || !isEqual(x[key], y[key])) return false;
}
return true;
}
if (Array.isArray(x) && Array.isArray(y)) {
if (x.length !== y.length) return false;
for (let i = 0; i < x.length; i++) if (!isEqual(x[i], y[i])) return false;
return true;
}
return false;
}
//#endregion
//#region src/utils/array.ts
function distinctArray(arr) {
for (let i = 0; i < arr.length; i++) for (let j = arr.length - 1; j > i; j--) if (isEqual(arr[i], arr[j])) arr.splice(j, 1);
return arr;
}
//#endregion
//#region src/utils/clone.ts
/* istanbul ignore next */
const gT = (() => {
if (typeof globalThis !== "undefined") return globalThis;
if (typeof self !== "undefined") return self;
if (typeof window !== "undefined") return window;
if (typeof global !== "undefined") return global;
throw new Error("unable to locate global object");
})();
function polyfillClone(input) {
const map = /* @__PURE__ */ new WeakMap();
const fn = (value) => {
if (Array.isArray(value)) {
if (map.has(value)) return map.get(value);
const cloned = [];
map.set(value, cloned);
value.map((el) => cloned.push(fn(el)));
return cloned;
}
if (isObject(value)) {
if (map.has(value)) return map.get(value);
const output = {};
const keys = Object.keys(value);
map.set(value, output);
for (let i = 0; i < keys.length; i++) output[keys[i]] = fn(value[keys[i]]);
return output;
}
return value;
};
return fn(input);
}
/* istanbul ignore next */
function clone(value) {
if (gT.structuredClone) return gT.structuredClone(value);
/* istanbul ignore next */
return polyfillClone(value);
}
//#endregion
//#region src/utils/object.ts
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
//#endregion
//#region src/utils/options.ts
function buildOptions(options = {}) {
options.array = options.array ?? true;
options.arrayDistinct = options.arrayDistinct ?? false;
options.clone = options.clone ?? false;
options.inPlace = options.inPlace ?? false;
options.priority = options.priority || "left";
options.arrayPriority = options.arrayPriority || options.priority;
return options;
}
function togglePriority(priority) {
return priority === "left" ? `right` : `left`;
}
//#endregion
//#region src/module.ts
function baseMerger(context, ...sources) {
let target;
let source;
let { priority } = context.options;
if (sources.length >= 2) {
if (Array.isArray(sources.at(0)) && Array.isArray(sources.at(-1))) priority = context.options.arrayPriority;
}
if (priority === "right") {
target = sources.pop();
source = sources.pop();
} else {
target = sources.shift();
source = sources.shift();
}
if (!source) {
if (Array.isArray(target) && context.options.arrayDistinct) return distinctArray(target);
return target;
}
if (Array.isArray(target) && Array.isArray(source)) {
target.push(...source);
if (context.options.arrayPriority === "right") return baseMerger(context, ...sources, target);
return baseMerger(context, target, ...sources);
}
context.map.set(source, true);
if (isObject(target) && isObject(source)) {
const keys = Object.keys(source);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (!isSafeKey(key)) continue;
if (hasOwnProperty(target, key)) {
if (context.options.strategy) {
if (typeof context.options.strategy(target, key, source[key]) !== "undefined") continue;
}
if (isObject(target[key]) && isObject(source[key])) {
if (context.map.has(source[key])) {
const sourceKeys = Object.keys(source[key]);
for (let j = 0; j < sourceKeys.length; j++) if (isSafeKey(sourceKeys[j]) && !hasOwnProperty(target[key], sourceKeys[j])) target[key][sourceKeys[j]] = source[key][sourceKeys[j]];
continue;
}
if (context.options.priority === "right") target[key] = baseMerger(context, source[key], target[key]);
else target[key] = baseMerger(context, target[key], source[key]);
continue;
}
if (context.options.array && Array.isArray(target[key]) && Array.isArray(source[key])) switch (context.options.priority !== context.options.arrayPriority ? togglePriority(context.options.arrayPriority) : context.options.arrayPriority) {
case "left":
Object.assign(target, { [key]: baseMerger(context, target[key], source[key]) });
break;
case "right":
Object.assign(target, { [key]: baseMerger(context, source[key], target[key]) });
break;
}
} else Object.assign(target, { [key]: source[key] });
}
}
context.map = /* @__PURE__ */ new WeakMap();
if (context.options.priority === "right") return baseMerger(context, ...sources, target);
return baseMerger(context, target, ...sources);
}
function createMerger(input) {
const options = buildOptions(input);
return (...sources) => {
if (!sources.length) throw new SyntaxError("At least one input element is required.");
const ctx = {
options,
map: /* @__PURE__ */ new WeakMap()
};
if (options.clone) return baseMerger(ctx, ...clone(sources));
if (!options.inPlace) {
if (Array.isArray(sources.at(0)) && options.arrayPriority === "left") {
sources.unshift([]);
return baseMerger(ctx, ...sources);
}
if (Array.isArray(sources.at(-1)) && options.arrayPriority === "right") {
sources.push([]);
return baseMerger(ctx, ...sources);
}
if (options.priority === "left") sources.unshift({});
else sources.push({});
}
return baseMerger(ctx, ...sources);
};
}
const merge = createMerger();
//#endregion
//#region src/presets.ts
/**
* Assign source attributes to a target object.
*
* @param target
* @param sources
*/
function assign(target, ...sources) {
return createMerger({
inPlace: true,
priority: "left",
array: false
})(target, ...sources);
}
//#endregion
exports.PriorityName = PriorityName;
exports.assign = assign;
exports.buildOptions = buildOptions;
exports.clone = clone;
exports.createMerger = createMerger;
exports.distinctArray = distinctArray;
exports.hasOwnProperty = hasOwnProperty;
exports.isEqual = isEqual;
exports.isObject = isObject;
exports.isSafeKey = isSafeKey;
exports.merge = merge;
exports.polyfillClone = polyfillClone;
exports.togglePriority = togglePriority;
//# sourceMappingURL=index.cjs.map