npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ultimate-extend

v2.0.14

Published

Ultimately configurable extend function can be used as always or in any other way you need. Even in objects deep promise iterations.

Downloads

88

Readme

UltimateExtend

Extends target with other object's properties. Works like 'extend' module, but has several updates:

  1. First argument can be of type Boolean and also UltimateExtend.config ( defines how extend works )
  2. If objects to extend from are Promises or contain promises in properties you can use Extend.promise instead of Extend. Then it will return promise of Extended object.

Installation

# version 2.x ( alpha )
npm install ultimate-extend --save

# version 1.x ( stable )
npm install [email protected] --save

OLD Readme v1.0.1 - for v2.x see tests TODO: Update this ReadMe

Usage:


// UltimateExtend( [{config|Boolean,ExtendConfig}, ]{target|Object,Function}, ...{options|Object,Function} ) => {Object}

// UltimateExtend.outer( [{config|Boolean,ExtendConfig}, ] ...{options|Object,Function} ) => {Object}

// UltimateExtend.promise( [{config|Boolean,ExtendConfig}, ]{target|Object,Function}, ...{options|Object,Function} ) => {Promise{Object}}

// UltimateExtend.config( {config|Object} ) => {ExtendConfig}



/* --------------------------------- Extend --------------------------------- */

var Extend = require( 'ultimate-extend' );

/* ------------ Simple usage ------------- */
var target = {},
    a = { a: { a: [ '1' ] } },
    b = { a: { a: [ 2 ], b: 2 } };

Extend( true, target, a, b ); // working as expected

console.log( target ); // => { a: { a: [ 2 ], b: 2 } }

/* ------------ Advanced usage ------------- */

var config = Extend.config({
    // if true: deeper objects will be extended too
    deep: true,

    // if true: allows to extend object with itself ( careful here )
    extendSelf: false,
    
    // by default returns property from object to extend from by name
    // you can set some special conditions
    // e.g. to extend only from all properties with name beginning with underscore, like '_test':
    // getOption: ( options, name, config, target ) => {
    //      if ( name.match( /^_/ )
    //          || options[ name ] && typeof options[ name ] === 'object'
    //      ) {
    //          return options[ name ];
    //      }
    //      // undefined must be returned to prevent property extension
    // }
    
    // config to extend properties with similar types
    extendSimilar: {
        Array: ( first, second, config, name ) => first.concat( second )
        // Object: ( first, second, config, originMethod ) => ...
        // Function: ( first, second, config, originMethod ) => ...
        // ... any other type beginning with capital letter ( see 'get-explicit-type' module )
        //      - replacement occures only when both first and second are having the same type
        //      - first - target's property
        //      - second - some object's property ( to extend from )
        //      - config - current config object
        //          - config.callOrigin( first, second ) - executes same method from parent config
        //          - config.newConfig() - creates new ExtendConfig using current one as parent
        //          - config.level - current deep extend recursion level ( default - 0 )
        //      - name - current extending property name
    }
    
    // executes when first and second properties have different types
    // Default( first, second, config, name ) { return newTargetProp }

    // returns parent config object ( can not be overwritten )
    // getParentConfig()

    // base handler to extend first with second ( better not override it )
    // use it in extendSimilar if you might receive new value type to extend it as needed by config
    // e.g. extendSimilar: {
    //   // here first and second functions can return any type
    //   Function: ( first, second, config ) => config.extendProp( first(), second(), config )
    // }
    // extendProp: ( first, second, config ) => {}

    // also you can define extend method which will be used on deeper properties
    // so if deep is true then config.extend will handle next deeper extend iterations
    // Experimental ( not tested )
    // extend: Extend || Extend.promise || YourFunc
});

var target = {}; // renew target; a, b are taken from example above

Extend( config, target, a, b ); // now all arrays are concatenated instead of extending

console.log( target ); // => { a: { a: [ '1', 2 ], b: 2 } }


/* --------------------------------- Extend.promise --------------------------------- */

var Extend = require( 'ultimate-extend' );

var target = {},
    a = { a: { a: Promise.resolve( [ '1' ] ) } },
    b = { a: { a: [ 2 ], b: new Promise( resolve => setTimeout( () => resolve( 2 ), 500 ) ) } };

Extend.promise( true, target, a, b )
    .then( () => {
        console.log( target ); // => { a: { a: [ 2 ], b: 2 } }
    });
    

/* --------------------------------- Extend.outer --------------------------------- */

// Extend.outer extends two variables as if they were in extending objects
var Extend = require( 'ultimate-extend' );

var config = Extend.config({
    Array: ( first, second ) => first.concat( second ),

    Default( first, second, config, name ) {
        if ( !first ) return config.callOrigin( first, second, config, name );

        if ( !Array.isArray( first ) ) first = [ first ];
        if ( !Array.isArray( second ) ) second = [ second ];

        return config.extendProp( first, second, config );
    }
});

var a = [ 0, 1 ],
    b = 2;

Extend.outer( config, a, b )                                  => [ 0, 1, 2 ]
( Extend( config, {}, { outer: a }, { outer: b } ) ).outer    => [ 0, 1, 2 ]


/* --------------------------------- Extend.config --------------------------------- */

// Extend.config can be produced from other configs using config.newConfig( configObj )
// to execute method from origin ( parent ) config use config.callOrigin( ...{ same arguments } )
// config.callOrigin() - here 3rd argument will always be replaced with config which called this method

var Extend = require( 'ultimate-extend' );

var config = Extend.config({
    Default: ( first, second, config, name ) => {
        return second + 1;
    }
});

var newConfig = config.newConfig({
    Default: ( first, second, config, name ) => {
        return config.callOrigin( first, second, config, name ) + 2;
    }
});

console.log( Extend( newConfig, {}, { a: 1 } ) );  // { a: 4 }