<commit_before>'use strict';
var debug = require('debug')('loopback:connector:flexirest');
var RestConnector = require('loopback-connector-rest');
var requiredir = require('require-dir');
var path = require('path');
var fs = require('fs');
var walk = require('./lib/walk');
var transformerLib = require('./lib/transformer');

/**
 * Export the initialize method to loopback-datasource-juggler
 * @param {DataSource} dataSource The loopback data source instance
 * @param {function} [callback] The callback function
 */
exports.initialize = function initializeDataSource(dataSource, callback) {
    var settings = dataSource.settings || {};
    var endpointPath = settings.path || 'endpoints';
    var baseURL = settings.baseURL || settings.restPath || 'http://localhost:3000/';

    // load endpoints folder and add to operations for loopback-connector-rest
    if (endpointPath) {
       var endpointTemplates = walk(path.resolve(endpointPath),'json');

       settings.operations = [];
       endpointTemplates.forEach(function(templateFile){

           debug('Found JSON file', templateFile);
           var defintion = require(templateFile);
           defintion.file = templateFile;

           if(defintion && defintion.template && defintion.functions) {
               // file is a template json file
               debug('Adding template to settings.operations');

               if (baseURL) {
                   defintion.template.url = baseURL + defintion.template.url;
               }

               settings.operations.push(defintion);
           }
       });
   }

   RestConnector.initialize(dataSource, callback);
   applyTransformerPatch(dataSource);
   autoloadFunctions(dataSource);
};

var applyTransformerPatch = function(dataSource) {

    var dao = dataSource.connector.DataAccessObject;
    var connector = dataSource.connector;

    Object.keys(dao).filter(function(key){
        return key !== 'invoke';
    }).forEach(function(key){
        var originalfn = dao[key];
        debug('patched function', key);

        var argsList = originalfn.accepts.map(function(param){
            return param.arg;
        });

        var newfn = function(){

            var self = this;
            var context = {'name':key};
            var cb = null;
            if (arguments.length > 0
                    && 'function' === typeof arguments[arguments.length - 1]) {
                cb = arguments[arguments.length - 1];
            }

            context.parameters = {};
            var argsLength = arguments.length;

            Array.prototype.slice.call(arguments)
            .filter(function(arg,index){
                // to avoid callback being added to
                // parameters
                return index < (argsLength -1);
            })
            .forEach(function(arg,index){
                context.parameters[argsList[index]] = arg;
            })

            function outgoingTransform(context, done) {

                if(self[key].outgoingTransform) {
                    debug('outgoingTransform called');
                    var transformedOutput = null;
                    try {
                        transformedOutput = self[key].outgoingTransform(context.parameters);

                        if(typeof transformedOutput !== 'object')
                            done(new Error('transformedOutput is not an object'));

                        Object.keys(context.parameters).filter(function(property){
                            return !transformedOutput.hasOwnProperty(property);
                        }).forEach(function(property){
                            transformedOutput[property] = context.parameters[property];
                        });

                        context.parameters = transformedOutput;
                        done();
                    } catch (e) {
                        done(e);
                    }
                } else {
                    done();
                }
            }

            function errorHandler(err, body, response,done) {

                if(self[key].errorHandler) {
                    debug('errorHandler called');
                    self[key].errorHandler(err, body, response, done);
                } else {
                    done(err, body, response);
                }
            }

            function incomingTransform(context, done) {

                if(self[key].incomingTransform) {
                    debug('incomingTransform called');
                    try {
                        context.body = self[key].incomingTransform(context.body);
                    } catch (e) {
                        done(e);
                    }
                }
                done(null, context.body, context.response);
            }

            connector.notifyObserversAround('outgoingTransform', context, outgoingTransform, function(err) {

                //TODO: fix it properly
                if(err)
                    return cb(err);

                context.parameters = Object.keys(context.parameters).map(function(property){
                    return context.parameters[property];
                });

                var callback = function(err, body, response) {
                    errorHandler(err,body,response,function(err,body,response){
                        if(err) {
                            cb(err, body, response);
                        } else {
                            delete context.parameters;
                            context.body = body;
                            connector.notifyObserversAround('incomingTransform', context, incomingTransform, function(err, body, response){
                                cb(err, body, response);
                            });<commit_msg>Corrected argument sequence<commit_after>'use strict';
var debug = require('debug')('loopback:connector:flexirest');
var RestConnector = require('loopback-connector-rest');
var path = require('path');
var walk = require('./lib/walk');
var transformerLib = require('./lib/transformer');

/**
 * Export the initialize method to loopback-datasource-juggler
 * @param {DataSource} dataSource The loopback data source instance
 * @param {function} [callback] The callback function
 */
exports.initialize = function initializeDataSource(dataSource, callback) {
    var settings = dataSource.settings || {};
    var endpointPath = settings.path || 'endpoints';
    var baseURL = settings.baseURL || settings.restPath || 'http://localhost:3000/';

    // load endpoints folder and add to operations for loopback-connector-rest
    if (endpointPath) {
       var endpointTemplates = walk(path.resolve(endpointPath),'json');

       settings.operations = [];
       endpointTemplates.forEach(function(templateFile){

           debug('Found JSON file', templateFile);
           var defintion = require(templateFile);
           defintion.file = templateFile;

           if(defintion && defintion.template && defintion.functions) {
               // file is a template json file
               debug('Adding template to settings.operations');

               if (baseURL) {
                   defintion.template.url = baseURL + defintion.template.url;
               }

               settings.operations.push(defintion);
           }
       });
   }

   RestConnector.initialize(dataSource, callback);
   applyTransformerPatch(dataSource);
   autoloadFunctions(dataSource);
};

var applyTransformerPatch = function(dataSource) {

    var dao = dataSource.connector.DataAccessObject;
    var connector = dataSource.connector;

    Object.keys(dao).filter(function(key){
        return key !== 'invoke';
    }).forEach(function(key){
        var originalfn = dao[key];
        debug('patched function', key);

        var argsList = originalfn.accepts.map(function(param){
            return param.arg;
        });

        var newfn = function(){

            var self = this;
            var context = {'name':key};
            var cb = null;
            if (arguments.length > 0
                    && 'function' === typeof arguments[arguments.length - 1]) {
                cb = arguments[arguments.length - 1];
            }

            context.parameters = {};
            var argsLength = arguments.length;

            Array.prototype.slice.call(arguments)
            .filter(function(arg,index){
                // to avoid callback being added to
                // parameters
                return index < (argsLength -1);
            })
            .forEach(function(arg,index){
                context.parameters[argsList[index]] = arg;
            })

            function outgoingTransform(context, done) {

                if(self[key].outgoingTransform) {
                    debug('outgoingTransform called');
                    var transformedOutput = null;
                    try {
                        transformedOutput = self[key].outgoingTransform(context.parameters);

                        if(typeof transformedOutput !== 'object')
                            done(new Error('transformedOutput is not an object'));

                        Object.keys(context.parameters).filter(function(property){
                            return !transformedOutput.hasOwnProperty(property);
                        }).forEach(function(property){
                            transformedOutput[property] = context.parameters[property];
                        });

                        context.parameters = transformedOutput;
                        done();
                    } catch (e) {
                        done(e);
                    }
                } else {
                    done();
                }
            }

            function errorHandler(err, body, response,done) {

                if(self[key].errorHandler) {
                    debug('errorHandler called');
                    self[key].errorHandler(err, body, response, done);
                } else {
                    done(err, body, response);
                }
            }

            function incomingTransform(context, done) {

                if(self[key].incomingTransform) {
                    debug('incomingTransform called');
                    try {
                        context.body = self[key].incomingTransform(context.body);
                    } catch (e) {
                        done(e);
                    }
                }
                done(null, context.body, context.response);
            }

            connector.notifyObserversAround('outgoingTransform', context, outgoingTransform, function(err) {

                //TODO: fix it properly
                if(err)
                    return cb(err);

                context.parameters = argsList.map(function(property){
                    return context.parameters[property];
                });

                var callback = function(err, body, response) {
                    errorHandler(err,body,response,function(err,body,response){
                        if(err) {
                            cb(err, body, response);
                        } else {
                            delete context.parameters;
                            context.body = body;
                            connector.notifyObserversAround('incomingTransform', context, incomingTransform, function(err, body, response){
                                cb(err, body, response);
                            });
{'fraction_non_alphanumeric': 0.10316212438853949, 'fraction_numerical': 0.001397624039133473, 'mean_word_length': 1.5844243792325057, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3642129', 'n_tokens_mistral': 2703, 'n_tokens_neox': 2519, 'n_words': 552}