UNPKG

wickr-bedrock-bot

Version:

AWS Wickr's own Bedrock Bot

420 lines (417 loc) 15.5 kB
/*! * mergician * v1.1.0 * https://jhildenbiddle.github.io/mergician/ * (c) 2022-2023 John Hildenbiddle * MIT license */ var __getOwnPropNames = Object.getOwnPropertyNames; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; // src/util.cjs var require_util = __commonJS({ "src/util.cjs"(exports, module) { function countOccurrences(...arrays) { const countObj = {}; arrays.forEach((array) => { array.forEach((v) => { countObj[v] = v in countObj ? ++countObj[v] : 1; }); }); return countObj; } function getInMultiple(...arrays) { const countObj = countOccurrences(...arrays); return Object.keys(countObj).filter((v) => countObj[v] > 1); } function getInAll(...arrays) { return arrays.reduce( (acc, curr) => acc.filter(Set.prototype.has, new Set(curr)) ); } function getNotInMultiple(...arrays) { const countObj = countOccurrences(...arrays); return Object.keys(countObj).filter((v) => countObj[v] === 1); } function getNotInAll(...arrays) { const countObj = countOccurrences(...arrays); return Object.keys(countObj).filter((v) => countObj[v] < arrays.length); } function getObjectKeys(obj, includeProto = false) { if (includeProto) { const keys = []; for (const key in obj) { keys.push(key); } return keys; } else { return Object.keys(obj); } } function isObject(value) { return typeof value === "object" && value !== null && !Array.isArray(value); } function isPropDescriptor(obj) { if (!isObject(obj)) { return false; } const hasFlagKey = ["writable", "enumerable", "configurable"].some((key) => key in obj); const hasMethod = ["get", "set"].some((key) => typeof obj[key] === "function"); const hasMethodKeys = ["get", "set"].every((key) => key in obj); let isDescriptor = "value" in obj && hasFlagKey || hasMethod && (hasMethodKeys || hasFlagKey); if (isDescriptor) { const validKeys = [ "configurable", "get", "set", "enumerable", "value", "writable" ]; isDescriptor = Object.keys(obj).some((key) => !(key in validKeys)); } return isDescriptor; } module.exports = { countOccurrences, getInMultiple, getInAll, getNotInMultiple, getNotInAll, getObjectKeys, isObject, isPropDescriptor }; } }); // src/index.cjs var require_src = __commonJS({ "src/index.cjs"(exports, module) { var { getInMultiple, getInAll, getNotInMultiple, getNotInAll, getObjectKeys, isObject, isPropDescriptor } = require_util(); var defaults = { // Keys onlyKeys: [], skipKeys: [], onlyCommonKeys: false, onlyUniversalKeys: false, skipCommonKeys: false, skipUniversalKeys: false, // Values invokeGetters: false, skipSetters: false, // Arrays appendArrays: false, prependArrays: false, dedupArrays: false, sortArrays: false, // Prototype hoistProto: false, // Callbacks filter: Function.prototype, beforeEach: Function.prototype, afterEach: Function.prototype, onCircular: Function.prototype }; /** * Deep recursive object merging with options to inspect, modify, and filter * keys/values, merge arrays (append/prepend), and remove duplicate values from * merged arrays. Returns new object without modifying sources (immutable). * * @preserve * * @example * // Without options (use default option values) * mergician(obj1, obj2, obj3, ...); * * @example * // With options (defaults shown) * mergician({ * // Keys * onlyKeys: [], * skipKeys: [], * onlyCommonKeys: false, * onlyUniversalKeys: false, * skipCommonKeys: false, * skipUniversalKeys: false, * // Values * invokeGetters: false, * skipSetters: false, * // Arrays * appendArrays: false, * prependArrays: false, * dedupArrays: false, * sortArrays: false, * // Prototype * hoistProto: false, * // Callbacks * filter({ depth, key, srcObj, srcVal, targetObj, targetVal }) {}, * beforeEach({ depth, key, srcObj, srcVal, targetObj, targetVal }) {}, * afterEach({ depth, key, mergeVal, srcObj, targetObj }) {}, * onCircular({ depth, key, srcObj, srcVal, targetObj, targetVal }) {} * })(obj1, obj2, obj3, ...) * * @param {...object} optionsOrObjects - Options or objects to merge * @param {array} [options.onlyKeys] - Exclusive array of keys to be merged * (others are skipped) * @param {array} [options.skipKeys] - Array of keys to skip (others are merged) * @param {boolean} [options.onlyCommonKeys = false] - Merge only keys found in * multiple objects (ignore single occurrence keys) * @param {boolean} [options.onlyUniversalKeys = false] - Merge only keys found * in all objects * @param {boolean} [options.skipCommonKeys = false] - Skip keys found in * multiple objects (merge only single occurrence keys) * @param {boolean} [options.skipUniversalKeys = false] - Skip keys found in all * objects (merge only common keys) * @param {boolean} [options.invokeGetters = false] - Invoke "getter" methods * and merge returned values * @param {boolean} [options.skipSetters = false] - Skip "setter" methods during * merge * @param {boolean} [options.appendArrays = false] - Merge array values at the * end of existing arrays * @param {boolean} [options.prependArrays = false] - Merge array values at the * beginning of existing arrays * @param {boolean} [options.dedupArrays = false] - Remove duplicate array * values in new merged object * @param {boolean|function} [options.sortArrays = false] - Sort array values in * new merged object * @param {boolean} [options.hoistProto = false] - Clone prototype properties as * direct properties of merged/cloned object * @param {function} [options.filter] - Callback used to conditionally merge or * skip a property. Return a "truthy" value to merge or a "falsy" value to skip. * Return no value to proceed according to other option values. * @param {function} [options.beforeEach] - Callback used for * inspecting/modifying properties before merge. Return value is used as value * to merge. * @param {function} [options.afterEach] - Callback used for * inspecting/modifying properties after merge. Return value is used as merged * value. * @param {function} [options.onCircular] - Callback used for handling circular * object references during merge * @returns {function|object} Merge function with options applied or new merged * object * @param {...object} [objects] - Objects to merge * @returns {object} New merged object */ function mergician(...optionsOrObjects) { const options = arguments.length === 1 ? arguments[0] : {}; const settings = { ...defaults, ...options }; const dedupArrayMap = /* @__PURE__ */ new Map(); const sortArrayMap = /* @__PURE__ */ new Map(); const sortArrayFn = typeof settings.sortArrays === "function" ? settings.sortArrays : void 0; const circularRefs = /* @__PURE__ */ new WeakMap(); let mergeDepth = 0; function _getObjectKeys(obj) { return getObjectKeys(obj, settings.hoistProto); } function _mergician(...objects) { let mergeKeyList; if (objects.length > 1) { if (settings.onlyCommonKeys) { mergeKeyList = getInMultiple(...objects.map((obj) => _getObjectKeys(obj))); } else if (settings.onlyUniversalKeys) { mergeKeyList = getInAll(...objects.map((obj) => _getObjectKeys(obj))); } else if (settings.skipCommonKeys) { mergeKeyList = getNotInMultiple(...objects.map((obj) => _getObjectKeys(obj))); } else if (settings.skipUniversalKeys) { mergeKeyList = getNotInAll(...objects.map((obj) => _getObjectKeys(obj))); } } if (!mergeKeyList && settings.onlyKeys.length) { mergeKeyList = settings.onlyKeys; } if (mergeKeyList && mergeKeyList !== settings.onlyKeys && settings.onlyKeys.length) { mergeKeyList = mergeKeyList.filter((key) => settings.onlyKeys.includes(key)); } const newObj = objects.reduce((targetObj, srcObj) => { circularRefs.set(srcObj, targetObj); let keys = mergeKeyList || _getObjectKeys(srcObj); if (settings.skipKeys.length) { keys = keys.filter((key) => settings.skipKeys.indexOf(key) === -1); } for (let i = 0; i < keys.length; i++) { const key = keys[i]; const targetVal = targetObj[key]; let isReturnVal = false; let mergeVal; if (key in srcObj === false) { continue; } try { mergeVal = srcObj[key]; } catch (err) { console.error(err); continue; } const srcDescriptor = Object.getOwnPropertyDescriptor(srcObj, key); const isSetterOnly = srcDescriptor && typeof srcDescriptor.set === "function" && typeof srcDescriptor.get !== "function"; if (isSetterOnly) { if (!settings.skipSetters) { srcDescriptor.configurable = true; Object.defineProperty(targetObj, key, srcDescriptor); } continue; } if (settings.filter !== defaults.filter) { const returnVal = settings.filter({ depth: mergeDepth, key, srcObj, srcVal: mergeVal, targetObj, targetVal }); if (returnVal !== void 0 && !returnVal) { continue; } } if (settings.beforeEach !== defaults.beforeEach) { const returnVal = settings.beforeEach({ depth: mergeDepth, key, srcObj, srcVal: mergeVal, targetObj, targetVal }); if (returnVal !== void 0) { isReturnVal = true; mergeVal = returnVal; } } if (typeof mergeVal === "object" && mergeVal !== null) { if (circularRefs.has(srcObj[key])) { const returnVal = settings.onCircular({ depth: mergeDepth, key, srcObj, srcVal: srcObj[key], targetObj, targetVal }); if (returnVal === void 0) { mergeVal = circularRefs.get(srcObj[key]); targetObj[key] = mergeVal; continue; } isReturnVal = true; mergeVal = returnVal; } } if (Array.isArray(mergeVal)) { mergeVal = [...mergeVal]; if (Array.isArray(targetVal)) { if (settings.appendArrays) { mergeVal = [...targetVal, ...mergeVal]; } else if (settings.prependArrays) { mergeVal = [...mergeVal, ...targetVal]; } } if (settings.dedupArrays) { if (settings.afterEach !== defaults.afterEach) { mergeVal = [...new Set(mergeVal)]; } else { const keyArray = dedupArrayMap.get(targetObj); if (keyArray && !keyArray.includes(key)) { keyArray.push(key); } else { dedupArrayMap.set(targetObj, [key]); } } } if (settings.sortArrays) { if (settings.afterEach !== defaults.afterEach) { mergeVal = mergeVal.sort(sortArrayFn); } else { const keyArray = sortArrayMap.get(targetObj); if (keyArray && !keyArray.includes(key)) { keyArray.push(key); } else { sortArrayMap.set(targetObj, [key]); } } } } else if (isObject(mergeVal) && (!isReturnVal || !isPropDescriptor(mergeVal))) { mergeDepth++; if (isObject(targetVal)) { mergeVal = _mergician(targetVal, mergeVal); } else { mergeVal = _mergician(mergeVal); } mergeDepth--; } if (settings.afterEach !== defaults.afterEach) { const returnVal = settings.afterEach({ depth: mergeDepth, key, mergeVal, srcObj, targetObj }); if (returnVal !== void 0) { isReturnVal = true; mergeVal = returnVal; } } if (isReturnVal) { if (isPropDescriptor(mergeVal)) { mergeVal.configurable = true; mergeVal.enumerable = !("enumerable" in mergeVal) ? true : mergeVal.enumerable; if ("value" in mergeVal && !("writable" in mergeVal)) { mergeVal.writable = true; } Object.defineProperty(targetObj, key, mergeVal); } else { targetObj[key] = mergeVal; } } else { const mergeDescriptor = Object.getOwnPropertyDescriptor(srcObj, key); if (mergeDescriptor && typeof mergeDescriptor.get === "function" && !settings.invokeGetters) { if (settings.skipSetters) { mergeDescriptor.set = void 0; } mergeDescriptor.configurable = true; Object.defineProperty(targetObj, key, mergeDescriptor); } else { targetObj[key] = mergeVal; } } } return targetObj; }, {}); for (const [obj, keyArray] of dedupArrayMap.entries()) { for (const key of keyArray) { obj[key] = [...new Set(obj[key])]; } } for (const [obj, keyArray] of sortArrayMap.entries()) { for (const key of keyArray) { obj[key].sort(sortArrayFn); } } return newObj; } if (arguments.length === 1) { return function(...objects) { if (arguments.length === 1) { return mergician({ ...settings, ...objects[0] }); } else { return _mergician(...objects); } }; } else { return _mergician(...arguments); } } module.exports = mergician; } }); export default require_src();