lib/tumblr.js
function addMethod(client, methodName, apiPath, paramNames, requestType) {
    const apiPathSplit = apiPath.split('/');
    const apiPathParamsCount = apiPath.split(/\/:[^\/]+/).length - 1;

    const buildApiPath = function(args) {
        let pathParamIndex = 0;
        return reduce(apiPathSplit, function(apiPath, apiPathChunk, i) {
            // Parse arguments in the path
            if (apiPathChunk === ':blogIdentifier') {
                // Blog URLs are special
                apiPathChunk = forceFullBlogUrl(args[pathParamIndex++]);
            } else if (apiPathChunk[0] === ':') {
                apiPathChunk = args[pathParamIndex++];
            }

            if (apiPathChunk) {
                return apiPath + '/' + apiPathChunk;
            } else {
                return apiPath;
            }
        }, '');
    };

    const namedParams = (apiPath.match(/\/:[^\/]+/g) || []).map(function(param) {
        return param.substr(2);
    }).concat(paramNames, 'params', 'callback');

    const methodBody = function() {
        const argsLength = arguments.length;
        const args = new Array(argsLength);
        for (let i = 0; i < argsLength; i++) {
            args[i] = arguments[i];
        }

        const requiredParamsStart = apiPathParamsCount;
        const requiredParamsEnd = requiredParamsStart + paramNames.length;
        const requiredParamArgs = args.slice(requiredParamsStart, requiredParamsEnd);

        // Callback is at the end
        const callback = isFunction(args[args.length - 1]) ? args.pop() : null;

        // Required Parmas
        const params = zipObject(paramNames, requiredParamArgs);
        extend(params, isPlainObject(args[args.length - 1]) ? args.pop() : {});

        // Path arguments are determined after required parameters
        const apiPathArgs = args.slice(0, apiPathParamsCount);

        let request = requestType;
        if (isString(requestType)) {
            request = requestType.toUpperCase() === 'POST' ? client.postRequest : client.getRequest;
        } else if (!isFunction(requestType)) {
            request = client.getRequest;
        }

        return request.call(client, buildApiPath(apiPathArgs), params, callback);
    };

    set(client, methodName, createFunction(methodName, namedParams, methodBody));
}
function addMethod(client, methodName, apiPath, paramNames, requestType) {
    const apiPathSplit = apiPath.split('/');
    const apiPathParamsCount = apiPath.split(/\/:[^\/]+/).length - 1;

    const buildApiPath = function(args) {
        let pathParamIndex = 0;
        return reduce(apiPathSplit, function(apiPath, apiPathChunk, i) {
            // Parse arguments in the path
            if (apiPathChunk === ':blogIdentifier') {
                // Blog URLs are special
                apiPathChunk = forceFullBlogUrl(args[pathParamIndex++]);
            } else if (apiPathChunk[0] === ':') {
                apiPathChunk = args[pathParamIndex++];
            }

            if (apiPathChunk) {
                return apiPath + '/' + apiPathChunk;
            } else {
                return apiPath;
            }
        }, '');
    };

    const namedParams = (apiPath.match(/\/:[^\/]+/g) || []).map(function(param) {
        return param.substr(2);
    }).concat(paramNames, 'params', 'callback');

    const methodBody = function() {
        const argsLength = arguments.length;
        const args = new Array(argsLength);
        for (let i = 0; i < argsLength; i++) {
            args[i] = arguments[i];
        }

        const requiredParamsStart = apiPathParamsCount;
        const requiredParamsEnd = requiredParamsStart + paramNames.length;
        const requiredParamArgs = args.slice(requiredParamsStart, requiredParamsEnd);

        // Callback is at the end
        const callback = isFunction(args[args.length - 1]) ? args.pop() : null;

        // Required Parmas
        const params = zipObject(paramNames, requiredParamArgs);
        extend(params, isPlainObject(args[args.length - 1]) ? args.pop() : {});

        // Path arguments are determined after required parameters
        const apiPathArgs = args.slice(0, apiPathParamsCount);

        let request = requestType;
        if (isString(requestType)) {
            request = requestType.toUpperCase() === 'POST' ? client.postRequest : client.getRequest;
        } else if (!isFunction(requestType)) {
            request = client.getRequest;
        }

        return request.call(client, buildApiPath(apiPathArgs), params, callback);
    };

    set(client, methodName, createFunction(methodName, namedParams, methodBody));
}
function addMethod ( client , methodName , apiPath , paramNames , requestType ) { const apiPathSplit = apiPath . split ( '/' ) ; const apiPathParamsCount = apiPath . split ( / \/:[^\/]+ / ) . length - 1 ; const buildApiPath = function ( args ) { let pathParamIndex = 0 ; return reduce ( apiPathSplit , function ( apiPath , apiPathChunk , i ) { // Parse arguments in the path if ( apiPathChunk === ':blogIdentifier' ) { // Blog URLs are special apiPathChunk = forceFullBlogUrl ( args [ pathParamIndex ++ ] ) ; } else if ( apiPathChunk [ 0 ] === ':' ) { apiPathChunk = args [ pathParamIndex ++ ] ; } if ( apiPathChunk ) { return apiPath + '/' + apiPathChunk ; } else { return apiPath ; } } , '' ) ; } ; const namedParams = ( apiPath . match ( / \/:[^\/]+ / g ) || [ ] ) . map ( function ( param ) { return param . substr ( 2 ) ; } ) . concat ( paramNames , 'params' , 'callback' ) ; const methodBody = function ( ) { const argsLength = arguments . length ; const args = new Array ( argsLength ) ; for ( let i = 0 ; i < argsLength ; i ++ ) { args [ i ] = arguments [ i ] ; } const requiredParamsStart = apiPathParamsCount ; const requiredParamsEnd = requiredParamsStart + paramNames . length ; const requiredParamArgs = args . slice ( requiredParamsStart , requiredParamsEnd ) ; // Callback is at the end const callback = isFunction ( args [ args . length - 1 ] ) ? args . pop ( ) : null ; // Required Parmas const params = zipObject ( paramNames , requiredParamArgs ) ; extend ( params , isPlainObject ( args [ args . length - 1 ] ) ? args . pop ( ) : { } ) ; // Path arguments are determined after required parameters const apiPathArgs = args . slice ( 0 , apiPathParamsCount ) ; let request = requestType ; if ( isString ( requestType ) ) { request = requestType . toUpperCase ( ) === 'POST' ? client . postRequest : client . getRequest ; } else if ( ! isFunction ( requestType ) ) { request = client . getRequest ; } return request . call ( client , buildApiPath ( apiPathArgs ) , params , callback ) ; } ; set ( client , methodName , createFunction ( methodName , namedParams , methodBody ) ) ; }
Adds a request method to the client

@param  {Object} client - add the method to this object
@param  {string} methodName - the name of the method
@param  {string} apiPath - the API route, which uses any colon-prefixed segments as arguments
@param  {Array} paramNames - ordered list of required request parameters used as arguments
@param  {String|Function} requestType - the request type or a function that makes the request

@private
Adds a request method to the client