Code Monkey home page Code Monkey logo

jhildenbiddle / mergician Goto Github PK

View Code? Open in Web Editor NEW
65.0 2.0 3.0 934 KB

Uniquely flexible and light-weight utility for cloning and deep (recursive) merging of JavaScript objects. Supports descriptor values, accessor functions, and custom prototypes. Provides advanced options for customizing the clone/merge process.

Home Page: https://jhildenbiddle.github.io/mergician/

License: MIT License

JavaScript 99.62% TypeScript 0.38%
array clone deep extend filter immutable merge object recursive accessor

mergician's Issues

TypeScript support

Cool work.

Please add support for TypeScript.
I'm using the following as a work-around:

declare module 'mergician' {

    type ObjectLiteral = Record<any, any>

    export interface MergicianOptions {

        // ----
        // Keys
        // ----

        /**
         * Exclusive array of keys to be merged (others are skipped).
         */
        onlyKeys?: string[];

        /**
         * Array of keys to skip (others are merged).
         */
        skipKeys?: string[];

        /**
         * Merge only keys found in multiple objects (ignore single occurrence keys).
         */
        onlyCommonKeys?: boolean;

        /**
         * Merge only keys found in all objects
         */
        onlyUniversalKeys?: boolean;

        /**
         * Skip keys found in multiple objects (merge only single
         *     occurrence keys)
         */
        skipCommonKeys?: boolean;

        /**
         * Skip keys found in all objects (merge only common keys)
         */
        skipUniversalKeys?: boolean;

        // ------
        // Arrays
        // ------

        /**
         * Merge array values at the end of existing arrays
         */
        appendArrays?: boolean;

        /**
         * Merge array values at the beginning of existing arrays
         */
        prependArrays?: boolean;

        /**
         * Remove duplicate array values in new merged object
         */
        dedupArrays?: boolean;

        /**
         * Sort array values in new merged object
         */
        sortArrays?: boolean;

        // ---------
        // Callbacks
        // ---------

        /**
         * Callback used for inspecting/modifying properties before merge.
         * Return value is used as value to merge.
         */
        beforeEach?(options: { depth: number, key: string, srcObj: ObjectLiteral, srcVal: any, targetObj: ObjectLiteral, targetVal: any }): any | undefined;

        /**
         * Callback used to conditionally merge or skip a property.
         * Return "true" to merge or "false" to skip.
         * Return no value to proceed according to other option values.
         */
        filter?(options: { depth: number, key: string, srcObj: ObjectLiteral, srcVal: any, targetObj: ObjectLiteral, targetVal: any }): boolean;

        /**
         * Callback used for inspecting/modifying properties after merge.
         * Return value is used as merged value.
         */
        afterEach?<M>(options: { depth: number, key: string, mergeVal: M, srcObj: ObjectLiteral, targetObj: ObjectLiteral }): any | undefined;
    }

    /**
     * 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
     * const obj1 = { a: 1 };
     * const obj2 = { b: [2, 2], c: { d: 2 } };
     * const obj3 = { b: [3, 3], c: { e: 3 } };
     *
     * const mergedObj = mergician({
     *     appendArrays: true,
     *     dedupArrays: true
     * })(obj1, obj2, obj3);
     *
     * console.log(mergedObj); // { a: 1, b: [2, 3], c: { d: 2, e: 3 } }
     *
     * @param options
     */
    export default function mergician<T extends ObjectLiteral>(options: MergicianOptions): (...objects: ObjectLiteral[]) => T;

    /**
     * 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
     * const obj1 = { a: 1 };
     * const obj2 = { b: [2, 2], c: { d: 2 } };
     * const obj3 = { b: [3, 3], c: { e: 3 } };
     *
     * const customMerge = mergician({
     *     appendArrays: true,
     *     dedupArrays: true
     * });
     * const clonedObj = customMerge({}, obj2);
     * const mergedObj = customMerge(obj1, obj2, obj3);
     *
     * console.log(clonedObj);  // { b: [2], c: { d: 2 } }
     * console.log(mergedObj);  // { a: 1, b: [2, 3], c: { d: 2, e: 3 } }
     * @param options
     */
    export default function mergician<T extends ObjectLiteral>(options: MergicianOptions): (options: MergicianOptions) => (...objects: ObjectLiteral[]) => T;

    /**
     * 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
     * const obj1 = { a: 1 };
     * const obj2 = { b: [2, 2], c: { d: 2 } };
     * const obj3 = { b: [3, 3], c: { e: 3 } };
     *
     * const clonedObj = mergician({}, obj1);
     * const mergedObj = mergician(obj1, obj2, obj3);
     *
     * console.log(clonedObj);              // { a: 1 }
     * console.log(clonedObj === obj1);     // false
     * console.log(mergedObj);              // { a: 1, b: [3, 3], c: { d: 2, e: 3 } }
     *
     * @param {...object} [objects] - Objects to merge
     * @returns {object} New merged object
     */
    export default function mergician<T extends ObjectLiteral>(...objects: ObjectLiteral[]): T;
}

merge Date object

const obj1 = { date1: new Date() };
const obj2 = merge(obj1, { date2: new Date() });

console.log(obj1.date1.toISOString());
console.log(obj2.date1.toISOString()); // not working
console.log(obj2.date2.toISOString()); // not working

Mergician Does Not Maintain All Properties

When merging two objects, the original data is not always included in the resultant object.

Consider the following example:

import mergician from 'mergician';

// See attached files for const values
import { input, translation } from './data.js';

const main = () => {
  // See attached file for what this looks like
  const result = mergician(input, translation);
  // This always exists
  console.log(input.events[0].decisions);
  // This SHOULD exist, but doesn't
  console.log(result.events[0].decisions);
};

main();

data.js.input.json
data.js.translation.json
data.js.result.json

Basically, input + translation = result, but result is missing events[0].decisions that is found in input. This is also true for lands.shire.population, lands.shire.isFrodoHome, lands.rivendell.isSafeHaven, lands.rivendell.architecture.age, villians.saruman.powerLevel, and villians.sauron.powerLevel – essentially every case where the original value has an object with a property that doesn't have the merged value with the corresponding object doesn't have that property.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.