<commit_before>/*jslint nomen: true */
/*globals define: true */

define([
  'jquery',
  'lib/lodash',
  'backbone',
  'moment',
  'lib/tinypubsub',

  // LocalData
  'settings',
  'api',

  // Models
  'models/responses',

  // Views
  'views/map'
],

function($, _, Backbone, moment, events, settings, api, Responses, MapView) {
  'use strict';

  var ResponseViews = {};

  ResponseViews.ListView = Backbone.View.extend({
    responses: null,
    firstRun: true,
    surveyId: null,
    paginationView: null,
    filters: {},

    events: {
      "change #filter":  "filter",
      "click #subfilter a": "subFilter",
      "click #reset": "reset"
    },

    initialize: function(options) {
      _.bindAll(this, 'render', 'goToPage', 'humanizeDates', 'filter', 'subFilter', 'setupPagination', 'doesQuestionHaveTheRightAnswer');
      this.template = _.template($('#response-view').html());

      this.responses = options.responses;
      this.responses.on('reset', this.render, this);

      this.forms = options.forms;
    },

    render: function() {
      console.log("Rendering response view");

      // The first time we render, we want to save a copy of the original responses
      if (this.firstRun) {
        this.allResponses = new Responses.Collection(this.responses.models);
        this.firstRun = false;
      }

      // TODO: Pagination
      this.setupPagination();
      var thisPage = this.responses.toJSON().slice(this.pageStart, this.pageEnd);

      // Humanize the dates so people who aren't robots can read them
      this.humanizeDates(thisPage);

      // Set up for filtering
      var flattenedForm = this.forms.getFlattenedForm();

      // Actually render the page
      var context = {
        responses: thisPage,
        flattenedForm: flattenedForm
      };
      this.$el.html(this.template(context));

      // Set up the map view _after_ the results have arrived.
      this.mapView = new MapView({
        el: $("#map-view-container"),
        responses: this.responses
      });

      // If the data has been filtered, show that on the page.
      // TODO: This should be done in a view.
      if (_.has(this.filters, "answerValue")) {
        $("#current-filter").html("
Current filter:

" + this.filters.questionValue + ": " + this.filters.answerValue + "
   Clear filter");
      }

    },

    setupPagination: function() {
      this.page = 0;
      this.pageListCount = 20000;
      this.pageStart = 0;
      this.pageEnd = this.pageStart + this.pageListCount;
      this.pageCount = Math.floor(this.responses.length / this.pageListCount);
    },

    goToPage: function(pageStr) {
      var page = parseInt(pageStr, 10);
      this.page = page;
      this.pageStart = (this.page - 1) * this.pageListCount;
      this.pageEnd = this.page * this.pageListCount;

      this.render();
    },

    reset: function(e) {
      this.filters = {};
      this.responses.reset(this.allResponses.models);
      // render should be triggered by an event...
      // this.render();

      $("#current-filter").html("");
    },

    filter: function(e) {
      // _kmq.push(['record', "Question filter selected"]);
      var $question = $(e.target);
      var question = $question.val();

      // Get the list of distinct options
      var answers = this.responses.getUniqueAnswersForQuestion(question);
      $("#subfilter").html(_.template($('#filter-results').html(), { choices: answers }));

      // Distinguish the responses visually on the map
      this.mapView.mapResponses(question, answers);
    },

    subFilter: function(e) {
      // _kmq.push(['record', "Answer filter selected"]);
      var $answer = $(e.target);

      // Notify the user we're working on it.
      events.publish('loading', [true]);

      // Reset the collection
      // this.responses.reset(this.allResponses.models);

      // Filter the responses
      this.filters.answerValue = $answer.text();
      this.filters.questionValue = $("#filter").val();

      var filteredResponses = this.responses.filter(this.doesQuestionHaveTheRightAnswer);

      this.responses.reset(filteredResponses);

      // Let the user know we're done
      events.publish('loading', [false]);
    },

    doesQuestionHaveTheRightAnswer: function(resp) {
      //if (_.has(resp.attributes, 'responses')) {
      return resp.attributes.responses !== undefined && resp.attributes.responses[this.filters.questionValue] === this.filters.answerValue;
      //}
      // return false;
    },

    humanizeDates: function(responses, field) {
      _.each(responses, function(response){
        // 2012-06-26T20:00:52.283Z
        if(_.has(response, "created")) {
          response.createdHumanized = moment(response.created, "YYYY-MM-DDThh:mm:ss.SSSZ").format("MMM Do h:mma");
        }
      });
    }

  });

  return ResponseViews;

});

<commit_msg>remove errant spaces<commit_after>/*jslint nomen: true */
/*globals define: true */

define([
  'jquery',
  'lib/lodash',
  'backbone',
  'moment',
  'lib/tinypubsub',

  // LocalData
  'settings',
  'api',

  // Models
  'models/responses',

  // Views
  'views/map'
],

function($, _, Backbone, moment, events, settings, api, Responses, MapView) {
  'use strict';

  var ResponseViews = {};

  ResponseViews.ListView = Backbone.View.extend({
    responses: null,
    firstRun: true,
    surveyId: null,
    paginationView: null,
    filters: {},

    events: {
      "change #filter":  "filter",
      "click #subfilter a": "subFilter",
      "click #reset": "reset"
    },

    initialize: function(options) {
      _.bindAll(this, 'render', 'goToPage', 'humanizeDates', 'filter', 'subFilter', 'setupPagination', 'doesQuestionHaveTheRightAnswer');
      this.template = _.template($('#response-view').html());

      this.responses = options.responses;
      this.responses.on('reset', this.render, this);

      this.forms = options.forms;
    },

    render: function() {
      console.log("Rendering response view");

      // The first time we render, we want to save a copy of the original responses
      if (this.firstRun) {
        this.allResponses = new Responses.Collection(this.responses.models);
        this.firstRun = false;
      }

      // TODO: Pagination
      this.setupPagination();
      var thisPage = this.responses.toJSON().slice(this.pageStart, this.pageEnd);

      // Humanize the dates so people who aren't robots can read them
      this.humanizeDates(thisPage);

      // Set up for filtering
      var flattenedForm = this.forms.getFlattenedForm();

      // Actually render the page
      var context = {
        responses: thisPage,
        flattenedForm: flattenedForm
      };
      this.$el.html(this.template(context));

      // Set up the map view _after_ the results have arrived.
      this.mapView = new MapView({
        el: $("#map-view-container"),
        responses: this.responses
      });

      // If the data has been filtered, show that on the page.
      // TODO: This should be done in a view.
      if (_.has(this.filters, "answerValue")) {
        $("#current-filter").html("
Current filter:

" + this.filters.questionValue + ": " + this.filters.answerValue + "
   Clear filter");
      }

    },

    setupPagination: function() {
      this.page = 0;
      this.pageListCount = 20000;
      this.pageStart = 0;
      this.pageEnd = this.pageStart + this.pageListCount;
      this.pageCount = Math.floor(this.responses.length / this.pageListCount);
    },

    goToPage: function(pageStr) {
      var page = parseInt(pageStr, 10);
      this.page = page;
      this.pageStart = (this.page - 1) * this.pageListCount;
      this.pageEnd = this.page * this.pageListCount;

      this.render();
    },

    reset: function(e) {
      this.filters = {};
      this.responses.reset(this.allResponses.models);
      // render should be triggered by an event...
      // this.render();

      $("#current-filter").html("");
    },

    filter: function(e) {
      // _kmq.push(['record', "Question filter selected"]);
      var $question = $(e.target);
      var question = $question.val();

      // Get the list of distinct options
      var answers = this.responses.getUniqueAnswersForQuestion(question);
      $("#subfilter").html(_.template($('#filter-results').html(), { choices: answers }));

      // Distinguish the responses visually on the map
      this.mapView.mapResponses(question, answers);
    },

    subFilter: function(e) {
      // _kmq.push(['record', "Answer filter selected"]);
      var $answer = $(e.target);

      // Notify the user we're working on it.
      events.publish('loading', [true]);

      // Reset the collection
      // this.responses.reset(this.allResponses.models);

      // Filter the responses
      this.filters.answerValue = $answer.text();
      this.filters.questionValue = $("#filter").val();

      var filteredResponses = this.responses.filter(this.doesQuestionHaveTheRightAnswer);

      this.responses.reset(filteredResponses);

      // Let the user know we're done
      events.publish('loading', [false]);
    },

    doesQuestionHaveTheRightAnswer: function(resp) {
      //if (_.has(resp.attributes, 'responses')) {
      return resp.attributes.responses !== undefined && resp.attributes.responses[this.filters.questionValue] === this.filters.answerValue;
      //}
      // return false;
    },

    humanizeDates: function(responses, field) {
      _.each(responses, function(response){
        // 2012-06-26T20:00:52.283Z
        if(_.has(response, "created")) {
          response.createdHumanized = moment(response.created, "YYYY-MM-DDThh:mm:ss.SSSZ").format("MMM Do h:mma");
        }
      });
    }

  });

  return ResponseViews;

});

<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var fs = require('fs'),
    path = require('path'),
    utils = exports = module.exports;

/**
 * Does path `p` exist?
 *
 * @param {String} p
 * @return {Boolean}
 */

utils.exists = function exists(p) {
  return fs.existsSync(p);
};

/**
 * Returns `true` if `p` is a directory
 *
 * @param {String} p
 * @return {Boolean}
 */

utils.isDir = function isDir(p) {
  return exists(p) && fs.lstatSync().isDirectory();
};

/**
 * Returns `true` if `p` is a file
 *
 * @param {String} p
 * @return {Boolean}
 */

utils.isFile = function isFile(p) {
  return exists(p) && fs.lstatSync().isFile();
};

/**
 * Chunk `p` into parts
 *
 * @param {String} p
 * @return {Array}
 */

utils.splitPaths = function splitPaths(p) {
  return p.split(path.sep);
};

/**
 * Make all directories leading up to `p`
 * like a unix `mkdir -p p`
 *
 * @param {String} p
 * @return {Boolean}
 */

utils.mkdir = function mkdir(p) {
  var errors;

  splitPaths(p).reduce(function(dirs, dir) {
    dirs += dir + path.sep;
    var s = path.resolve(dirs);

    if(!exists(s)) {
      try {
        fs.mkdirSync(s);
      } catch(e) {
        errors = true;
      }
    }

    return dirs;
  }, '');

  return !errors;
};

/**
 * Read the path `p` and return an object with files and directories
 *
 * @param {String} p
 * @return {Object}
 */

utils.readDir = function readDir(p) {
  if(!isDir(p)) return false;
  var dir = fs.readdirSync(p);

  return {
    files: dir.filter(function(f) {
      return isFile(p);
    }),
    directories: dir.filter(function(f) {
      return isDir(p);
    });
  };
};

/**
 * Read file `p`
 *
 * @param {String} p
 * @return {String|Boolean}
 */

utils.read = function read(p) {
  if(!exists(p)) return false;

  try {
    return fs.readFileSync(p);
  } catch(e) {
    return false;
  }
};

/**
 * Write `data` to path `p`
 *
 * @param {String} p
 * @param {String} data
 * @return {Boolean}
 */

utils.write = function write(p, data) {
  mkdir(path.dirname(p));

  try {
    fs.writeFileSync(p, data);
    return true;
  } catch(e) {
    return false;
  }
};
<commit_msg>fix issues in utils<commit_after>/**
 * Module dependencies
 */

var fs = require('fs'),
    path = require('path'),
    utils = exports = module.exports;

/**
 * Does path `p` exist?
 *
 * @param {String} p
 * @return {Boolean}
 */

var exists = utils.exists = function(p) {
  return fs.existsSync(p);
};

/**
 * Returns `true` if `p` is a directory
 *
 * @param {String} p
 * @return {Boolean}
 */

var isDir = utils.isDir = function(p) {
  return exists(p) && fs.lstatSync(p).isDirectory();
};

/**
 * Returns `true` if `p` is a file
 *
 * @param {String} p
 * @return {Boolean}
 */

var isFile = utils.isFile = function(p) {
  return exists(p) && fs.lstatSync(p).isFile();
};

/**
 * Chunk `p` into parts
 *
 * @param {String} p
 * @return {Array}
 */

var splitPaths = utils.splitPaths = function(p) {
  return p.split(path.sep);
};

/**
 * Make all directories leading up to `p`
 * like a unix `mkdir -p p`
 *
 * @param {String} p
 * @return {Boolean}
 */

var mkdir = utils.mkdir = function(p) {
  var errors;

  splitPaths(p).reduce(function(dirs, dir) {
    dirs += dir + path.sep;
    var s = path.resolve(dirs);

    if(!exists(s)) {
      try {
        fs.mkdirSync(s);
      } catch(e) {
        errors = true;
      }
    }

    return dirs;
  }, '');

  return !errors;
};

/**
 * Read the path `p` and return an object with files and directories
 *
 * @param {String} p
 * @return {Object}
 */

var readDir = utils.readDir = function(p) {
  if(!isDir(p)) return false;
  var dir = fs.readdirSync(p).map(function(f) {
    return path.join(p, f);
  });

  return {
    files: dir.filter(function(f) {
      return isFile(f);
    }),
    directories: dir.filter(function(f) {
      return isDir(f);
    })
  };
};

/**
 * Read file `p`
 *
 * @param {String} p
 * @return {String|Boolean}
 */

var read = utils.read = function(p) {
  if(!exists(p)) return false;

  try {
    return fs.readFileSync(p);
  } catch(e) {
    return false;
  }
};

/**
 * Write `data` to path `p` creating any directories on the way.
 *
 * @param {String} p
 * @param {String} data
 * @return {Boolean}
 */

var write = utils.write = function(p, data) {
  mkdir(path.dirname(p));

  try {
    fs.writeFileSync(p, data);
    return true;
  } catch(e) {
    return false;
  }
};
<|endoftext|>


<commit_before>/* global Promise */

/**
 * @author Christoph Wurst <christoph@winzerhof-wurst.at>
 *
 * Mail
 *
 * This code is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License, version 3,
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

define(function(require) {
	'use strict';

	var _ = require('underscore');
	var Handlebars = require('handlebars');
	var Marionette = require('marionette');
	var Radio = require('radio');
	var AccountController = require('controller/accountcontroller');
	var AccountFormView = require('views/accountformview');
	var ErrorView = require('views/errorview');
	var LoadingView = require('views/loadingview');
	var SetupTemplate = require('text!templates/setup.html');

	/**
	 * @class SetupView
	 */
	return Marionette.View.extend({

		/** @type {string} */
		className: 'container',

		/** @type {Function} */
		template: Handlebars.compile(SetupTemplate),

		/** @type {boolean} */
		_loading: false,

		/** @type {boolean} */
		_error: undefined,

		/** @type {Object} */
		_config: undefined,

		regions: {
			content: '.setup-content'
		},

		initialize: function(options) {
			this._config = options.config;
		},

		/**
		 * @returns {undefined}
		 */
		onRender: function() {
			if (!_.isUndefined(this._error)) {
				this.showChildView('content', new ErrorView({
					text: this._error,
					canRetry: true
				}));
			} else if (this._loading) {
				// Rendering the first time
				this.showChildView('content', new LoadingView({
					text: t('mail', 'Setting up your account')
				}));
			} else {
				// Re-rending because an error occurred
				this.showChildView('content', new AccountFormView({
					config: this._config
				}));
			}
		},

		/**
		 * @private
		 * @param {Object} config
		 * @returns {Promise}
		 */
		onChildviewFormSubmit: function(config) {
			var _this = this;
			this._loading = true;
			this._config = config;
			this.render();

			return Radio.account.request('create', config).then(function() {
				Radio.ui.trigger('navigation:show');
				Radio.ui.trigger('content:loading');
				// reload accounts
				return AccountController.loadAccounts();
			}).then(function(accounts) {
				// Let's assume there's at least one account after a successful
				// setup, so let's show the first one (could be the unified inbox)
				var firstAccount = accounts.first();
				var firstFolder = firstAccount.folders.first();
				Radio.navigation.trigger('folder', firstAccount.get('accountId'), firstFolder.get('id'));
			}).catch(function(error) {
				console.error('could not create account:', error);
				// Show error view for a few seconds
				_this._loading = false;
				_this._error = error;
				_this.render();
			}).catch(console.error.bind(this));
		},

		onChildviewRetry: function() {
			this._loading = false;
			this._error = undefined;
			this.render();
		}

	});
});
<commit_msg>Fix jshint warning<commit_after>/**
 * @author Christoph Wurst <christoph@winzerhof-wurst.at>
 *
 * Mail
 *
 * This code is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License, version 3,
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

define(function(require) {
	'use strict';

	var _ = require('underscore');
	var Handlebars = require('handlebars');
	var Marionette = require('marionette');
	var Radio = require('radio');
	var AccountController = require('controller/accountcontroller');
	var AccountFormView = require('views/accountformview');
	var ErrorView = require('views/errorview');
	var LoadingView = require('views/loadingview');
	var SetupTemplate = require('text!templates/setup.html');

	/**
	 * @class SetupView
	 */
	return Marionette.View.extend({

		/** @type {string} */
		className: 'container',

		/** @type {Function} */
		template: Handlebars.compile(SetupTemplate),

		/** @type {boolean} */
		_loading: false,

		/** @type {boolean} */
		_error: undefined,

		/** @type {Object} */
		_config: undefined,

		regions: {
			content: '.setup-content'
		},

		initialize: function(options) {
			this._config = options.config;
		},

		/**
		 * @returns {undefined}
		 */
		onRender: function() {
			if (!_.isUndefined(this._error)) {
				this.showChildView('content', new ErrorView({
					text: this._error,
					canRetry: true
				}));
			} else if (this._loading) {
				// Rendering the first time
				this.showChildView('content', new LoadingView({
					text: t('mail', 'Setting up your account')
				}));
			} else {
				// Re-rending because an error occurred
				this.showChildView('content', new AccountFormView({
					config: this._config
				}));
			}
		},

		/**
		 * @private
		 * @param {Object} config
		 * @returns {Promise}
		 */
		onChildviewFormSubmit: function(config) {
			var _this = this;
			this._loading = true;
			this._config = config;
			this.render();

			return Radio.account.request('create', config).then(function() {
				Radio.ui.trigger('navigation:show');
				Radio.ui.trigger('content:loading');
				// reload accounts
				return AccountController.loadAccounts();
			}).then(function(accounts) {
				// Let's assume there's at least one account after a successful
				// setup, so let's show the first one (could be the unified inbox)
				var firstAccount = accounts.first();
				var firstFolder = firstAccount.folders.first();
				Radio.navigation.trigger('folder', firstAccount.get('accountId'), firstFolder.get('id'));
			}).catch(function(error) {
				console.error('could not create account:', error);
				// Show error view for a few seconds
				_this._loading = false;
				_this._error = error;
				_this.render();
			}).catch(console.error.bind(this));
		},

		onChildviewRetry: function() {
			this._loading = false;
			this._error = undefined;
			this.render();
		}

	});
});
<|endoftext|>


<commit_before>const fs = require('fs')

module.exports = {
  gitUri,
  projectPath,
  log,
  detectTechno
}

function gitUri (settings) {
  return 'ssh://' + settings.user + '@' + settings.host +
    (settings.port === '22' ? ':' : ':' + settings.port) +
    projectPath(settings)
}

function projectPath (settings) {
  return '/home/' + settings.user + '/git/' + settings.name + '.git'
}

function log (message) {
  console.log(message)
}

/**
 * Detect the techo
 * TODO make it as plugins
 * @returns {string}
 */
function detectTechno () {
  log('Trying to detect the project techno...')
  if (fs.existsSync('./package.json')) {
    log('  looks like a node.js project')
    return 'node'
  }
  throw new Error('Unable to determine the techno of this project')
}
<commit_msg>[IMP] python project automatic detection<commit_after>const fs = require('fs')

module.exports = {
  gitUri,
  projectPath,
  log,
  detectTechno
}

function gitUri (settings) {
  return 'ssh://' + settings.user + '@' + settings.host +
    (settings.port === '22' ? ':' : ':' + settings.port) +
    projectPath(settings)
}

function projectPath (settings) {
  return '/home/' + settings.user + '/git/' + settings.name + '.git'
}

function log (message) {
  console.log(message)
}

/**
 * Detect the techo
 * TODO make it as plugins
 * @returns {string}
 */
function detectTechno () {
  log('Trying to detect the project techno...')

  var detections = [
    {'name': 'node', 'file': 'package.json'},
    {'name': 'python', 'file': 'requirements.txt'},
  ]

  for (detection of detections) {
    if (fs.existsSync('./'+detection.file)) {
      log('  we scanned the '+detection.file+' looks like a '+detection.name+' project.')
      return detection.name
    }
  }

  throw new Error('Unable to determine the techno of this project')
}
<|endoftext|>


<commit_before>var JSActiveModelSync = function(){
};

JSActiveModelSync.prototype = new JSActiveModel();
JSActiveModelSync.prototype.constructor = JSActiveModelSync;
JSActiveModelSync.prototype.parent = JSActiveModel.prototype;

JSActiveModel.inheritKlass(JSActiveModelSync, JSActiveModel);

JSActiveModelSync.parms = {
}

/*DB methods*/
JSActiveModelSync.prototype.init = function(parms){
  JSActiveModelSync.prototype.dbsetup(parms);
}
JSActiveModelSync.prototype.dbsetup = function(parms){
  if(JSActiveModelSync.prototype.dbopen(parms)){
    var DBTABLE = parms['DBTABLE'];
    var DBCOLUMNS = parms['DBCOLUMNS'];
    DBCOLUMNS = DBCOLUMNS + ', jsam_id';
    db.transaction(function (tx) {
      tx.executeSql('CREATE TABLE IF NOT EXISTS ' + DBTABLE + ' (' + DBCOLUMNS + ')');
      tx.executeSql('CREATE TABLE IF NOT EXISTS ' + DBTABLE + '_AUDIT (' + DBCOLUMNS + ', api_url)');
    });
  }else{
    //methods.get_records( url );
  }
}
JSActiveModelSync.prototype.dbopen = function(parms){
  //these vars should have been set on some global var
  if(window.openDatabase){
    var DATABASE = " "+parms['DATABASE']+" ";
    var DBVERSION = parms['DBVERSION'];
    var DBDESCRIPTION = " "+parms['DBDESCRIPTION']+" ";
    var DBSIZE = parms['DBSIZE'];
    db = openDatabase(DATABASE, DBVERSION, DBDESCRIPTION, DBSIZE);
    return true;
  }else{
    return false;
  }
}

/*Housekeeping methods*/
JSActiveModelSync.prototype.if_exist = function(DBTABLE, DBCOLUMNS, data, auto_handle){
  function queryHandle(tx){
    var remote_id = data.id;
    tx.executeSql('SELECT * FROM ' + DBTABLE + ' WHERE jsam_id = ?', [remote_id], querySuccess, errorHandle );
  }
  function querySuccess(tx, results){
    if(results.rows.length == 0){
      JSActiveModelSync.prototype.sync_pull(DBTABLE, DBCOLUMNS, data)//insert this record
      auto_handle('0');
    }else{
      console.log('already here');
      //TODO:: Update method call here
      auto_handle(id);
    }
  }
  function errorHandle(err){
    console.log(err);
  }
  db.transaction(queryHandle, errorHandle);
}//end last_id
JSActiveModelSync.prototype.last_id = function(DBTABLE, auto_handle){
  function queryHandle(tx){
    tx.executeSql('SELECT MAX(id) AS last_id FROM ' + DBTABLE, [], querySuccess, errorHandle );
  }
  function querySuccess(tx, results){
    for (var i=0; i<results.rows.length; i++) {
      var row = results.rows.item(i);
      last_id = row['last_id'] + 1;
    }
    auto_handle(last_id);
  }
  function errorHandle(err){
  }
  db.transaction(queryHandle, errorHandle);
}//end last_id
JSActiveModelSync.prototype.auto_increment = function(DBTABLE, auto_handle){
  function queryHandle(tx){
    tx.executeSql('SELECT MAX(jsam_id) AS last_jsam_id FROM ' + DBTABLE, [], querySuccess, errorHandle );
  }
  function querySuccess(tx, results){
    for (var i=0; i<results.rows.length; i++) {
      var row = results.rows.item(i);
      last_jsam_id = row['last_jsam_id'] + 1;
    }
    auto_handle(last_jsam_id);
  }
  function errorHandle(err){
    handler(err);
  }
  db.transaction(queryHandle, errorHandle);
}//end auto_increment
JSActiveModelSync.prototype.audit_update = function(DBTABLE, id, keyvals){
  function queryHandle(tx){
    tx.executeSql('UPDATE ' + DBTABLE + '_AUDIT SET ' + keyvals + ' WHERE jsam_id = ' + id );
  }
  function querySuccess(tx, results){
    console.log('success');
  }
  function errorHandle(err){
    console.log('fail');
    handler(err);
  }
  db.transaction(queryHandle, errorHandle);
}//end audit_update
JSActiveModelSync.prototype.audit_delete = function(DBTABLE, id){
  function queryHandle(tx){
    tx.executeSql('DELETE FROM ' + DBTABLE + '_AUDIT WHERE jsam_id = ' + id );
  }
  function querySuccess(tx, results){
    console.log('success');
  }
  function errorHandle(err){
    console.log('fail');
    handler(err);
  }
  db.transaction(queryHandle, errorHandle);
}//end audit delete
JSActiveModelSync.prototype.sync_pull = function(DBTABLE, DBCOLUMNS, post_data){
  function insertHandle(tx, results){
    //prep post_data to have right values for right columns
    data = [];
    for(column in DBCOLUMNS){
     if(DBCOLUMNS[column] in post_data){
      data.push('"' + post_data[DBCOLUMNS[column]] + '"');
     }else{
      data.push("null");
     }
    }
    keys = DBCOLUMNS + ', jsam_id';
    values = data + ', ' + post_data.id;
    tx.executeSql('INSERT INTO ' + DBTABLE + '(' + keys + ') VALUES (' + values + ')' );
  }
  function successHandle(){
  }
  function errorHandle(err){
    handler(err);
  }
  db.transaction(insertHandle, errorHandle, successHandle);
}//end insert
JSActiveModelSync.prototype.sync_push = function(DBTABLE){
  function queryHandle(tx){
    tx.executeSql('SELECT * FROM ' + DBTABLE + '_AUDIT ', [], querySuccess, errorHandle );
  }
  function querySuccess(tx, results){
    for(i=0;i<results.rows.length;i++){
      //case for what type of a push
      switch(type){
        case 'create':
          alert('create');
          break;
        case 'update':
          alert('update');
          break;
        case 'delete':
          alert('delete');
          break;
    }
  }
  function errorHandle(err){
    handler(err);
  }
    db.transaction(queryHandle, errorHandle);
  }
}

//klass methods
JSActiveModelSync.klass = {
  all : function(url, handler){
    var DBTABLE = this.parms['DBTABLE'];
    var DBCOLUMNS = this.parms['DBCOLUMNS'];
    JSActiveModelSync.prototype.init(this.parms); //make sure db is available and open
    function queryHandle(tx){
      tx.executeSql('SELECT * FROM ' + DBTABLE, [], querySuccess, errorHandle );
    }
    function querySuccess(tx, results){
      if(typeof(handler) == 'function'){
        rt = []
        for(i=0;i<results.rows.length;i++){
          rows = {};
          rows = results.rows.item(i);
          rt.push(rows);
        }
        handler(rt);
      }
    }
    function errorHandle(err){
      handler(err);
    }
    if(this.parms['isSyncable']){
      db.transaction(queryHandle, errorHandle);
    }else{
      db.transaction(queryHandle, errorHandle);
    }
  },
  find : function(url, id, handler){
    var DBTABLE = this.parms['DBTABLE'];
    function queryHandle(tx){
      tx.executeSql('SELECT * FROM ' + DBTABLE + ' WHERE jsam_id = ' + id, [], querySuccess, errorHandle );
    }
    function querySuccess(tx, results){
      if(typeof(handler) == 'function'){
        handler(results.rows.item(0));
      }
    }
    function errorHandle(err){
      handler(err);
    }
    if(this.parms['isSyncable']){
      db.transaction(queryHandle, errorHandle);
    }else{
      db.transaction(queryHandle, errorHandle);
    }
  },
  /*  Useage for find_by()
  *   [Model Name].find_by([url to api], [db column], [value], [handler])
  *   returns result from "SELECT * FROM [DBTABLE} WHERE [db column] = [value]"
  */
  find_by : function(url, key, value, handler){
    var DBTABLE = this.parms['DBTABLE'];
    function queryHandle(tx){
      tx.executeSql("SELECT * FROM " + DBTABLE + " WHERE " + key + " = ?", [value], querySuccess, errorHandle );
    }
    function querySuccess(tx, results){
      if(typeof(handler) == 'function'){
        rt = []
        for(i=0;i<results.rows.length;i++){
          rows = {};
          rows = results.rows.item(i);
          rt.push(rows);
        }
        handler(rt);
      }
    }
    function errorHandle(err){
      handler(err);
    }
    if(this.parms['isSyncable']){
      db.transaction(queryHandle, errorHandle);
    }else{
      JSActiveModel.find(url, function(j){
        handler(j);
      });
    }
  },
  update : function(url, id, post_data, handler){
    DBTABLE = this.parms['DBTABLE'];
    DBCOLUMNS = this.parms['DBCOLUMNS'];
      JSActiveModelSync.prototype.auto_increment(DBTABLE, function(auto_handle){
        function insertHandle(tx, results){
        //prep post_data to have right values for right columns
        keyvals = '';
        for(column in DBCOLUMNS){
         if(DBCOLUMNS[column] in post_data){
          keyvals += DBCOLUMNS[column] + '="' + post_data[DBCOLUMNS[column]] +'", ';
         }
        }
        keyvals = keyvals.substring(0, keyvals.length-2);
        tx.executeSql('UPDATE ' + DBTABLE + ' SET ' + keyvals + ' WHERE jsam_id = ' + id );
        }
        function successHandle(){
          //trigger sync here?
          handler();
        }
        function errorHandle(err){
          console.log(err);
          handler(err);
        }
        db.transaction(insertHandle, errorHandle, successHandle);
      }); //auto increment before creating the record
  },//end update
  create : function(url, post_data, handler){
    DBTABLE = this.parms['DBTABLE'];
    DBCOLUMNS = this.parms['DBCOLUMNS'];
      JSActiveModelSync.prototype.auto_increment(DBTABLE, function(auto_handle){
        function insertHandle(tx, results){
          //prep post_data to have right values for right columns
          data = [];
          for(column in DBCOLUMNS){
           if(DBCOLUMNS[column] in post_data){
            data.push('"' + post_data[DBCOLUMNS[column]] + '"');
           }else{
            data.push("null");
           }
          }
          keys = DBCOLUMNS + ', jsam_id';
          values = data + ', ' + auto_handle ;
          console.log(keys);
          console.log(values);
          tx.executeSql('INSERT INTO ' + DBTABLE + '(' + keys + ') VALUES (' + values + ')' );
          tx.executeSql('INSERT INTO ' + DBTABLE + '_AUDIT(' + keys + ') VALUES (' + values + ')' );
        }
        function successHandle(){
          //trigger sync here?
          handler();
        }
        function errorHandle(err){
          console.log(err);
          handler(err);
        }
        db.transaction(insertHandle, errorHandle, successHandle);
      }); //auto increment before creating the record
  },//end create
  destroy : function(url, id, handler){
    DBTABLE = this.parms['DBTABLE'];
    DBCOLUMNS = this.parms['DBCOLUMNS'];
      function deleteHandle(tx, results){
        tx.executeSql('DELETE FROM ' + DBTABLE + ' WHERE jsam_id = ' + id );
      }
      function successHandle(){
        //audit table cleanup
        JSActiveModelSync.prototype.audit_delete(DBTABLE, id)
        //trigger sync here?
        handler();
      }
      function errorHandle(err){
        handler(err);
      }
      if(this.parms['isSyncable']){
        db.transaction(deleteHandle, errorHandle, successHandle);
      }else{
        db.transaction(deleteHandle, errorHandle, successHandle);
      }
  },//end destroy
  save : function(){
  },//end save
  sync : function(url){
    //I wanted to make this a prototype method but I couldnt get parms up there. so its here for now
    var DBTABLE = this.parms['DBTABLE'];
    var DBCOLUMNS = this.parms['DBCOLUMNS'];
    JSActiveModelSync.prototype.init(this.parms); //make sure db is available and open

      JSActiveModel.req(url, function(j){
        for(i=0;i<j.length;i++){
          j[i].jsam_id = j[i].id;
          post_data = j[i];
          JSActiveModelSync.prototype.if_exist(DBTABLE, DBCOLUMNS, post_data, function(exist){
            if(exist == 0){
              //it was created
            }else{
              //it was updated
            }
          });
        }
      });

    //clear out the audit table
    JSActiveModelSync.prototype.sync_push(DBTABLE)//clean up audit table for this model

  }//end sync
}

JSActiveModel.hideKlass(JSActiveModelSync);

<commit_msg>added find_by_sql<commit_after>var JSActiveModelSync = function(){
};

JSActiveModelSync.prototype = new JSActiveModel();
JSActiveModelSync.prototype.constructor = JSActiveModelSync;
JSActiveModelSync.prototype.parent = JSActiveModel.prototype;

JSActiveModel.inheritKlass(JSActiveModelSync, JSActiveModel);

JSActiveModelSync.parms = {
}

/*DB methods*/
JSActiveModelSync.prototype.init = function(parms){
  JSActiveModelSync.prototype.dbsetup(parms);
}
JSActiveModelSync.prototype.dbsetup = function(parms){
  if(JSActiveModelSync.prototype.dbopen(parms)){
    var DBTABLE = parms['DBTABLE'];
    var DBCOLUMNS = parms['DBCOLUMNS'];
    DBCOLUMNS = DBCOLUMNS + ', jsam_id';
    db.transaction(function (tx) {
      tx.executeSql('CREATE TABLE IF NOT EXISTS ' + DBTABLE + ' (' + DBCOLUMNS + ')');
      tx.executeSql('CREATE TABLE IF NOT EXISTS ' + DBTABLE + '_AUDIT (' + DBCOLUMNS + ', api_url)');
    });
  }else{
    //methods.get_records( url );
  }
}
JSActiveModelSync.prototype.dbopen = function(parms){
  //these vars should have been set on some global var
  if(window.openDatabase){
    var DATABASE = " "+parms['DATABASE']+" ";
    var DBVERSION = parms['DBVERSION'];
    var DBDESCRIPTION = " "+parms['DBDESCRIPTION']+" ";
    var DBSIZE = parms['DBSIZE'];
    db = openDatabase(DATABASE, DBVERSION, DBDESCRIPTION, DBSIZE);
    return true;
  }else{
    return false;
  }
}

/*Housekeeping methods*/
JSActiveModelSync.prototype.if_exist = function(DBTABLE, DBCOLUMNS, data, auto_handle){
  function queryHandle(tx){
    var remote_id = data.id;
    tx.executeSql('SELECT * FROM ' + DBTABLE + ' WHERE jsam_id = ?', [remote_id], querySuccess, errorHandle );
  }
  function querySuccess(tx, results){
    if(results.rows.length == 0){
      JSActiveModelSync.prototype.sync_pull(DBTABLE, DBCOLUMNS, data)//insert this record
      auto_handle('0');
    }else{
      console.log('already here');
      //TODO:: Update method call here
      auto_handle(id);
    }
  }
  function errorHandle(err){
    console.log(err);
  }
  db.transaction(queryHandle, errorHandle);
}//end last_id
JSActiveModelSync.prototype.last_id = function(DBTABLE, auto_handle){
  function queryHandle(tx){
    tx.executeSql('SELECT MAX(id) AS last_id FROM ' + DBTABLE, [], querySuccess, errorHandle );
  }
  function querySuccess(tx, results){
    for (var i=0; i<results.rows.length; i++) {
      var row = results.rows.item(i);
      last_id = row['last_id'] + 1;
    }
    auto_handle(last_id);
  }
  function errorHandle(err){
  }
  db.transaction(queryHandle, errorHandle);
}//end last_id
JSActiveModelSync.prototype.auto_increment = function(DBTABLE, auto_handle){
  function queryHandle(tx){
    tx.executeSql('SELECT MAX(jsam_id) AS last_jsam_id FROM ' + DBTABLE, [], querySuccess, errorHandle );
  }
  function querySuccess(tx, results){
    for (var i=0; i<results.rows.length; i++) {
      var row = results.rows.item(i);
      last_jsam_id = row['last_jsam_id'] + 1;
    }
    auto_handle(last_jsam_id);
  }
  function errorHandle(err){
    handler(err);
  }
  db.transaction(queryHandle, errorHandle);
}//end auto_increment
JSActiveModelSync.prototype.audit_update = function(DBTABLE, id, keyvals){
  function queryHandle(tx){
    tx.executeSql('UPDATE ' + DBTABLE + '_AUDIT SET ' + keyvals + ' WHERE jsam_id = ' + id );
  }
  function querySuccess(tx, results){
    console.log('success');
  }
  function errorHandle(err){
    console.log('fail');
    handler(err);
  }
  db.transaction(queryHandle, errorHandle);
}//end audit_update
JSActiveModelSync.prototype.audit_delete = function(DBTABLE, id){
  function queryHandle(tx){
    tx.executeSql('DELETE FROM ' + DBTABLE + '_AUDIT WHERE jsam_id = ' + id );
  }
  function querySuccess(tx, results){
    console.log('success');
  }
  function errorHandle(err){
    console.log('fail');
    handler(err);
  }
  db.transaction(queryHandle, errorHandle);
}//end audit delete
JSActiveModelSync.prototype.sync_pull = function(DBTABLE, DBCOLUMNS, post_data){
  function insertHandle(tx, results){
    //prep post_data to have right values for right columns
    data = [];
    for(column in DBCOLUMNS){
     if(DBCOLUMNS[column] in post_data){
      data.push('"' + post_data[DBCOLUMNS[column]] + '"');
     }else{
      data.push("null");
     }
    }
    keys = DBCOLUMNS + ', jsam_id';
    values = data + ', ' + post_data.id;
    tx.executeSql('INSERT INTO ' + DBTABLE + '(' + keys + ') VALUES (' + values + ')' );
  }
  function successHandle(){
  }
  function errorHandle(err){
    handler(err);
  }
  db.transaction(insertHandle, errorHandle, successHandle);
}//end insert
JSActiveModelSync.prototype.sync_push = function(DBTABLE){
  function queryHandle(tx){
    tx.executeSql('SELECT * FROM ' + DBTABLE + '_AUDIT ', [], querySuccess, errorHandle );
  }
  function querySuccess(tx, results){
    for(i=0;i<results.rows.length;i++){
      //case for what type of a push
      switch(type){
        case 'create':
          alert('create');
          break;
        case 'update':
          alert('update');
          break;
        case 'delete':
          alert('delete');
          break;
    }
  }
  function errorHandle(err){
    handler(err);
  }
    db.transaction(queryHandle, errorHandle);
  }
}

//klass methods
JSActiveModelSync.klass = {
  all : function(url, handler){
    var DBTABLE = this.parms['DBTABLE'];
    var DBCOLUMNS = this.parms['DBCOLUMNS'];
    JSActiveModelSync.prototype.init(this.parms); //make sure db is available and open
    function queryHandle(tx){
      tx.executeSql('SELECT * FROM ' + DBTABLE, [], querySuccess, errorHandle );
    }
    function querySuccess(tx, results){
      if(typeof(handler) == 'function'){
        rt = []
        for(i=0;i<results.rows.length;i++){
          rows = {};
          rows = results.rows.item(i);
          rt.push(rows);
        }
        handler(rt);
      }
    }
    function errorHandle(err){
      handler(err);
    }
    if(this.parms['isSyncable']){
      db.transaction(queryHandle, errorHandle);
    }else{
      db.transaction(queryHandle, errorHandle);
    }
  },
  find : function(url, id, handler){
    var DBTABLE = this.parms['DBTABLE'];
    JSActiveModelSync.prototype.init(this.parms); //make sure db is available and open
    function queryHandle(tx){
      tx.executeSql('SELECT * FROM ' + DBTABLE + ' WHERE jsam_id = ' + id, [], querySuccess, errorHandle );
    }
    function querySuccess(tx, results){
      if(typeof(handler) == 'function'){
        handler(results.rows.item(0));
      }
    }
    function errorHandle(err){
      handler(err);
    }
    if(this.parms['isSyncable']){
      db.transaction(queryHandle, errorHandle);
    }else{
      db.transaction(queryHandle, errorHandle);
    }
  },
  /*  Useage for find_by()
  *   [Model Name].find_by([url to api], [db column], [value], [handler])
  *   returns result from "SELECT * FROM [DBTABLE} WHERE [db column] = [value]"
  */
  find_by : function(url, key, value, handler){
    var DBTABLE = this.parms['DBTABLE'];
    JSActiveModelSync.prototype.init(this.parms); //make sure db is available and open
    function queryHandle(tx){
      tx.executeSql("SELECT * FROM " + DBTABLE + " WHERE " + key + " = ?", [value], querySuccess, errorHandle );
    }
    function querySuccess(tx, results){
      if(typeof(handler) == 'function'){
        rt = []
        for(i=0;i<results.rows.length;i++){
          rows = {};
          rows = results.rows.item(i);
          rt.push(rows);
        }
        handler(rt);
      }
    }
    function errorHandle(err){
      console.log("ERROR:");
      console.log(err);
      handler(err);
    }
    if(this.parms['isSyncable']){
      db.transaction(queryHandle, errorHandle);
    }else{
      db.transaction(queryHandle, errorHandle);
    }
  },
  /*  Useage for find_by_sql()
  *   [Model Name].find_by_sql([url to api], [your sql], [handler])
  *   returns result from "SELECT * FROM [DBTABLE} WHERE [db column] = [value]"
  *   It appears that values for your sql need to be in quotes like this:
  *   'SELECT * FROM assignments WHERE task_id = "'+ task +'" AND day = "'+ day +'"'
  */
  find_by_sql : function(url, sql, handler){
    var DBTABLE = this.parms['DBTABLE'];
    //JSActiveModelSync.prototype.init(this.parms); //make sure db is available and open
    function queryHandle(tx){
      tx.executeSql(sql, [], querySuccess, errorHandle );
    }
    function querySuccess(tx, results){
      if(typeof(handler) == 'function'){
        rt = []
        for(i=0;i<results.rows.length;i++){
          rows = {};
          rows = results.rows.item(i);
          rt.push(rows);
        }
        handler(rt);
      }
    }
    function errorHandle(err){
      console.log("ERROR:");
      console.log(err);
      handler(err);
    }
    if(this.parms['isSyncable']){
      db.transaction(queryHandle, errorHandle);
    }else{
      db.transaction(queryHandle, errorHandle);
    }
  },
  update : function(url, id, post_data, handler){
    DBTABLE = this.parms['DBTABLE'];
    DBCOLUMNS = this.parms['DBCOLUMNS'];
      JSActiveModelSync.prototype.auto_increment(DBTABLE, function(auto_handle){
        function insertHandle(tx, results){
        //prep post_data to have right values for right columns
        keyvals = '';
        for(column in DBCOLUMNS){
         if(DBCOLUMNS[column] in post_data){
          keyvals += DBCOLUMNS[column] + '="' + post_data[DBCOLUMNS[column]] +'", ';
         }
        }
        keyvals = keyvals.substring(0, keyvals.length-2);
        tx.executeSql('UPDATE ' + DBTABLE + ' SET ' + keyvals + ' WHERE jsam_id = ' + id );
        }
        function successHandle(){
          //trigger sync here?
          handler();
        }
        function errorHandle(err){
          console.log(err);
          handler(err);
        }
        db.transaction(insertHandle, errorHandle, successHandle);
      }); //auto increment before creating the record
  },//end update
  create : function(url, post_data, handler){
    DBTABLE = this.parms['DBTABLE'];
    DBCOLUMNS = this.parms['DBCOLUMNS'];
      JSActiveModelSync.prototype.auto_increment(DBTABLE, function(auto_handle){
        function insertHandle(tx, results){
          //prep post_data to have right values for right columns
          data = [];
          for(column in DBCOLUMNS){
           if(DBCOLUMNS[column] in post_data){
            data.push('"' + post_data[DBCOLUMNS[column]] + '"');
           }else{
            data.push("null");
           }
          }
          keys = DBCOLUMNS + ', jsam_id';
          values = data + ', ' + auto_handle ;
          tx.executeSql('INSERT INTO ' + DBTABLE + '(' + keys + ') VALUES (' + values + ')' );
          tx.executeSql('INSERT INTO ' + DBTABLE + '_AUDIT(' + keys + ') VALUES (' + values + ')' );
        }
        function successHandle(){
          //trigger sync here?
          handler();
        }
        function errorHandle(err){
          console.log(err);
          handler(err);
        }
        db.transaction(insertHandle, errorHandle, successHandle);
      }); //auto increment before creating the record
  },//end create
  destroy : function(url, id, handler){
    DBTABLE = this.parms['DBTABLE'];
    DBCOLUMNS = this.parms['DBCOLUMNS'];
      function deleteHandle(tx, results){
        tx.executeSql('DELETE FROM ' + DBTABLE + ' WHERE jsam_id = ' + id );
      }
      function successHandle(){
        //audit table cleanup
        JSActiveModelSync.prototype.audit_delete(DBTABLE, id)
        //trigger sync here?
        handler();
      }
      function errorHandle(err){
        handler(err);
      }
      if(this.parms['isSyncable']){
        db.transaction(deleteHandle, errorHandle, successHandle);
      }else{
        db.transaction(deleteHandle, errorHandle, successHandle);
      }
  },//end destroy
  save : function(){
  },//end save
  sync : function(url){
    //I wanted to make this a prototype method but I couldnt get parms up there. so its here for now
    var DBTABLE = this.parms['DBTABLE'];
    var DBCOLUMNS = this.parms['DBCOLUMNS'];
    JSActiveModelSync.prototype.init(this.parms); //make sure db is available and open

      JSActiveModel.req(url, function(j){
        for(i=0;i<j.length;i++){
          j[i].jsam_id = j[i].id;
          post_data = j[i];
          JSActiveModelSync.prototype.if_exist(DBTABLE, DBCOLUMNS, post_data, function(exist){
            if(exist == 0){
              //it was created
            }else{
              //it was updated
            }
          });
        }
      });

    //clear out the audit table
    JSActiveModelSync.prototype.sync_push(DBTABLE)//clean up audit table for this model

  }//end sync
}

JSActiveModel.hideKlass(JSActiveModelSync);

<|endoftext|>


<commit_before>var util       = require("util")
  , DataTypes  = require("./data-types")
  , SqlString  = require("./SqlString")

var Utils = module.exports = {
  _: (function() {
    var _  = require("underscore")
      , _s = require('underscore.string')

    _.mixin(_s.exports())
    _.mixin({
      includes: _s.include,
      camelizeIf: function(string, condition) {
        var result = string

        if (condition) {
          result = _.camelize(string)
        }

        return result
      },
      underscoredIf: function(string, condition) {
        var result = string

        if (condition) {
          result = _.underscored(string)
        }

        return result
      }
    })

    return _
  })(),
  addEventEmitter: function(_class) {
    util.inherits(_class, require('events').EventEmitter)
  },
  TICK_CHAR: '`',
  addTicks: function(s) {
    return Utils.TICK_CHAR + Utils.removeTicks(s) + Utils.TICK_CHAR
  },
  removeTicks: function(s) {
    return s.replace(new RegExp(Utils.TICK_CHAR, 'g'), "")
  },
  escape: function(s) {
    return SqlString.escape(s, true, "local").replace(/\\"/g, '"')
  },
  format: function(arr) {
    return SqlString.format(arr.shift(), arr)
  },
  isHash: function(obj) {
    return Utils._.isObject(obj) && !Array.isArray(obj);
  },
  isEmptyObject: function( obj ) {
		for ( var name in obj ) {
			return false;
		}
		return true;
	},
  pad: function (s) {
    return s < 10 ? '0' + s : s
  },
  toSqlDate: function(date) {
    return date.getUTCFullYear() + '-' +
      this.pad(date.getUTCMonth()+1) + '-' +
      this.pad(date.getUTCDate()) + ' ' +
      this.pad(date.getUTCHours()) + ':' +
      this.pad(date.getUTCMinutes()) + ':' +
      this.pad(date.getUTCSeconds())
  },
  argsArePrimaryKeys: function(args, primaryKeys) {
    var result = (args.length == Object.keys(primaryKeys).length)
    if (result) {
      Utils._.each(args, function(arg) {
        if (result) {
          if (['number', 'string'].indexOf(typeof arg) !== -1) {
            result = true
          } else {
            result = (arg instanceof Date)
          }
        }
      })
    }
    return result
  },
  combineTableNames: function(tableName1, tableName2) {
    return (tableName1.toLowerCase() < tableName2.toLowerCase()) ? (tableName1 + tableName2) : (tableName2 + tableName1)
  },

  singularize: function(s) {
    return Utils.Lingo.en.isSingular(s) ? s : Utils.Lingo.en.singularize(s)
  },

  pluralize: function(s) {
    return Utils.Lingo.en.isPlural(s) ? s : Utils.Lingo.en.pluralize(s)
  },

  removeCommentsFromFunctionString: function(s) {
    s = s.replace(/\s*(\/\/.*)/g, '')
    s = s.replace(/(\/\*[\n\r\s\S]*?\*\/)/mg, '')

    return s
  },

  toDefaultValue: function(value) {
    return (value == DataTypes.NOW) ? new Date() : value
  },

  setAttributes: function(hash, identifier, instance, prefix) {
    prefix = prefix || ''
    if (this.isHash(identifier)) {
      this._.each(identifier, function(elem, key) {
        hash[prefix + key] = Utils._.isString(instance) ? instance : Utils._.isObject(instance) ? instance[elem.key || elem] : null
      })
    } else {
      hash[prefix + identifier] = Utils._.isString(instance) ? instance : Utils._.isObject(instance) ? instance.id : null
    }

    return hash
  },

  removeNullValuesFromHash: function(hash, omitNull) {
    var result = hash

    if (omitNull) {
      var _hash = {}

      Utils._.each(hash, function(val, key) {
        if (key.match(/Id$/) || ((val !== null) && (val !== undefined))) {
          _hash[key] = val;
        }
      })

      result = _hash
    }

    return result
  },

  prependTableNameToHash: function(tableName, hash) {
    if (tableName) {
      var _hash = {}

      for (var key in hash) {
        if (key.indexOf('.') === -1) {
          _hash[tableName + '.' + key] = hash[key]
        } else {
          _hash[key] = hash[key]
        }
      }

      return _hash
    } else {
      return hash
    }
  },

  firstValueOfHash: function(obj) {
    for (var key in obj) {
      if (obj.hasOwnProperty(key))
        return obj[key]
    }
    return null
  },

  inherit: function(subClass, superClass) {
    if (superClass.constructor == Function) {
      // Normal Inheritance
      subClass.prototype = new superClass();
      subClass.prototype.constructor = subClass;
      subClass.prototype.parent = superClass.prototype;
    } else {
      // Pure Virtual Inheritance
      subClass.prototype = superClass;
      subClass.prototype.constructor = subClass;
      subClass.prototype.parent = superClass;
    }

    return subClass;
  }
}

Utils.CustomEventEmitter = require("./emitters/custom-event-emitter")
Utils.QueryChainer = require("./query-chainer")
Utils.Lingo = require("lingo")
<commit_msg>remove isEmptyObject - something weird happened in merge<commit_after>var util       = require("util")
  , DataTypes  = require("./data-types")
  , SqlString  = require("./SqlString")

var Utils = module.exports = {
  _: (function() {
    var _  = require("underscore")
      , _s = require('underscore.string')

    _.mixin(_s.exports())
    _.mixin({
      includes: _s.include,
      camelizeIf: function(string, condition) {
        var result = string

        if (condition) {
          result = _.camelize(string)
        }

        return result
      },
      underscoredIf: function(string, condition) {
        var result = string

        if (condition) {
          result = _.underscored(string)
        }

        return result
      }
    })

    return _
  })(),
  addEventEmitter: function(_class) {
    util.inherits(_class, require('events').EventEmitter)
  },
  TICK_CHAR: '`',
  addTicks: function(s) {
    return Utils.TICK_CHAR + Utils.removeTicks(s) + Utils.TICK_CHAR
  },
  removeTicks: function(s) {
    return s.replace(new RegExp(Utils.TICK_CHAR, 'g'), "")
  },
  escape: function(s) {
    return SqlString.escape(s, true, "local").replace(/\\"/g, '"')
  },
  format: function(arr) {
    return SqlString.format(arr.shift(), arr)
  },
  isHash: function(obj) {
    return Utils._.isObject(obj) && !Array.isArray(obj);
  },
  pad: function (s) {
    return s < 10 ? '0' + s : s
  },
  toSqlDate: function(date) {
    return date.getUTCFullYear() + '-' +
      this.pad(date.getUTCMonth()+1) + '-' +
      this.pad(date.getUTCDate()) + ' ' +
      this.pad(date.getUTCHours()) + ':' +
      this.pad(date.getUTCMinutes()) + ':' +
      this.pad(date.getUTCSeconds())
  },
  argsArePrimaryKeys: function(args, primaryKeys) {
    var result = (args.length == Object.keys(primaryKeys).length)
    if (result) {
      Utils._.each(args, function(arg) {
        if (result) {
          if (['number', 'string'].indexOf(typeof arg) !== -1) {
            result = true
          } else {
            result = (arg instanceof Date)
          }
        }
      })
    }
    return result
  },
  combineTableNames: function(tableName1, tableName2) {
    return (tableName1.toLowerCase() < tableName2.toLowerCase()) ? (tableName1 + tableName2) : (tableName2 + tableName1)
  },

  singularize: function(s) {
    return Utils.Lingo.en.isSingular(s) ? s : Utils.Lingo.en.singularize(s)
  },

  pluralize: function(s) {
    return Utils.Lingo.en.isPlural(s) ? s : Utils.Lingo.en.pluralize(s)
  },

  removeCommentsFromFunctionString: function(s) {
    s = s.replace(/\s*(\/\/.*)/g, '')
    s = s.replace(/(\/\*[\n\r\s\S]*?\*\/)/mg, '')

    return s
  },

  toDefaultValue: function(value) {
    return (value == DataTypes.NOW) ? new Date() : value
  },

  setAttributes: function(hash, identifier, instance, prefix) {
    prefix = prefix || ''
    if (this.isHash(identifier)) {
      this._.each(identifier, function(elem, key) {
        hash[prefix + key] = Utils._.isString(instance) ? instance : Utils._.isObject(instance) ? instance[elem.key || elem] : null
      })
    } else {
      hash[prefix + identifier] = Utils._.isString(instance) ? instance : Utils._.isObject(instance) ? instance.id : null
    }

    return hash
  },

  removeNullValuesFromHash: function(hash, omitNull) {
    var result = hash

    if (omitNull) {
      var _hash = {}

      Utils._.each(hash, function(val, key) {
        if (key.match(/Id$/) || ((val !== null) && (val !== undefined))) {
          _hash[key] = val;
        }
      })

      result = _hash
    }

    return result
  },

  prependTableNameToHash: function(tableName, hash) {
    if (tableName) {
      var _hash = {}

      for (var key in hash) {
        if (key.indexOf('.') === -1) {
          _hash[tableName + '.' + key] = hash[key]
        } else {
          _hash[key] = hash[key]
        }
      }

      return _hash
    } else {
      return hash
    }
  },

  firstValueOfHash: function(obj) {
    for (var key in obj) {
      if (obj.hasOwnProperty(key))
        return obj[key]
    }
    return null
  },

  inherit: function(subClass, superClass) {
    if (superClass.constructor == Function) {
      // Normal Inheritance
      subClass.prototype = new superClass();
      subClass.prototype.constructor = subClass;
      subClass.prototype.parent = superClass.prototype;
    } else {
      // Pure Virtual Inheritance
      subClass.prototype = superClass;
      subClass.prototype.constructor = subClass;
      subClass.prototype.parent = superClass;
    }

    return subClass;
  }
}

Utils.CustomEventEmitter = require("./emitters/custom-event-emitter")
Utils.QueryChainer = require("./query-chainer")
Utils.Lingo = require("lingo")
<|endoftext|>


<commit_before>'use strict';
const path = require('path');

/**
 * Naive filename sanitize function.
 *
 * @link https://github.com/parshap/node-sanitize-filename
 * @param  {String} [name=''] Name to be clean up
 * @return {String}           Sanitized name
 */
function sanitizeName(name='') {
    function toCamelCase(str) {
        // Lower cases the string
        return str.toLowerCase()
            // Replaces any - or _ characters with a space
            .replace( /[-_]+/g, ' ')
            // Removes any non alphanumeric characters
            .replace( /[^\w\s]/g, '')
            // Uppercases the first character in each group immediately following a space
            // (delimited by spaces)
            .replace( / (.)/g, function($1) { return $1.toUpperCase(); })
            // Removes spaces
            .replace( / /g, '' );
    }

    function removeStartingDigits(name=''){
        return name.replace(/^[0-9]+/g, '');
    }

    name = toCamelCase(name);
    name = removeStartingDigits(name);

    return name;
}

/**
 * Return name of module from it's path.
 * @param  {String} [file=''] Path to module.
 * @return {String}           Module name.
 */
function getModuleName(file='') {
    return path.basename(file).replace(path.extname(file), '');
}

/**
 * Get path to main module.
 * @return {String}
 */
function getPathToMain() {
    var sep = path.sep;
    var main = process.argv[1];
    main = main.split(sep);
    main.pop();
    main = main.join(sep);
    return main;
}

function isFunction(fn){
    return typeof fn === 'function';
}

module.exports.isFunction = isFunction;

/**
 * Get number of listeners an event emitter
 * has for a given event type.
 * @param  {Object} emitter
 * @param  {String} type
 * @return {number}
 */
function getListenerCount(emitter, type) {
    if(!emitter) return 0;
    if(typeof emitter.listeners === 'function') return 0;
    let listeners = emitter.listeners(type).length - 1;
    return listeners === -1 ? 0 : listeners;
}

const VError = require('verror');

module.exports.fullStack = VError.fullStack;
/**
 * Utility function to clean up names.
 *
 * @type {Function}
 * @exports sanitizeName
 */
module.exports.sanitizeName = sanitizeName;

/**
 * Utility function to get name from file
 * path.
 *
 * @type {Function}
 * @exports getModuleName
 */
module.exports.getModuleName = getModuleName;

/**
 * Utility function to get path to
 * directory from which we run.
 *
 * @type {Function}
 * @exports getPathToMain
 */
module.exports.getPathToMain = getPathToMain;

/**
 * Get number of listener functions an
 * event has.
 *
 * @type {Function}
 * @exports getListenerCount
 */
module.exports.getListenerCount = getListenerCount;
<commit_msg>Add util function to translate from list of files to an exclude query for in<commit_after>'use strict';
const path = require('path');

/**
 * Transform a list of files we want into
 * a pattern for multimatch that would
 * exclude files NOT matching those names.
 *
 * @param  {Object} options
 * @return {Object}
 */
function makeExcludeFilterFromWantList(options){
    if(options.only) {

        if(!Array.isArray(options.only)) {
            options.only = [options.only];
        }
        /*
         * multimatch pattern to exclude all files
         * except literal matches by name.
         */
        options.only = ['**', `!**/+(${options.only.join('|')}).js`];
    }

    return options;
}

/**
 * Naive filename sanitize function.
 *
 * @link https://github.com/parshap/node-sanitize-filename
 * @param  {String} [name=''] Name to be clean up
 * @return {String}           Sanitized name
 */
function sanitizeName(name='') {
    function toCamelCase(str) {
        // Lower cases the string
        return str.toLowerCase()
            // Replaces any - or _ characters with a space
            .replace( /[-_]+/g, ' ')
            // Removes any non alphanumeric characters
            .replace( /[^\w\s]/g, '')
            // Uppercases the first character in each group immediately following a space
            // (delimited by spaces)
            .replace( / (.)/g, function($1) { return $1.toUpperCase(); })
            // Removes spaces
            .replace( / /g, '' );
    }

    function removeStartingDigits(name=''){
        return name.replace(/^[0-9]+/g, '');
    }

    name = toCamelCase(name);
    name = removeStartingDigits(name);

    return name;
}

/**
 * Return name of module from it's path.
 * @param  {String} [file=''] Path to module.
 * @return {String}           Module name.
 */
function getModuleName(file='') {
    return path.basename(file).replace(path.extname(file), '');
}

/**
 * Get path to main module.
 * @return {String}
 */
function getPathToMain() {
    var sep = path.sep;
    var main = process.argv[1];
    main = main.split(sep);
    main.pop();
    main = main.join(sep);
    return main;
}

function isFunction(fn){
    return typeof fn === 'function';
}

module.exports.isFunction = isFunction;

/**
 * Get number of listeners an event emitter
 * has for a given event type.
 * @param  {Object} emitter
 * @param  {String} type
 * @return {number}
 */
function getListenerCount(emitter, type) {
    if(!emitter) return 0;
    if(typeof emitter.listeners === 'function') return 0;
    let listeners = emitter.listeners(type).length - 1;
    return listeners === -1 ? 0 : listeners;
}

const VError = require('verror');

module.exports.fullStack = VError.fullStack;
/**
 * Utility function to clean up names.
 *
 * @type {Function}
 * @exports sanitizeName
 */
module.exports.sanitizeName = sanitizeName;

/**
 * Utility function to get name from file
 * path.
 *
 * @type {Function}
 * @exports getModuleName
 */
module.exports.getModuleName = getModuleName;

/**
 * Utility function to get path to
 * directory from which we run.
 *
 * @type {Function}
 * @exports getPathToMain
 */
module.exports.getPathToMain = getPathToMain;

/**
 * Get number of listener functions an
 * event has.
 *
 * @type {Function}
 * @exports getListenerCount
 */
module.exports.getListenerCount = getListenerCount;

module.exports.makeExcludeFilterFromWantList = makeExcludeFilterFromWantList;
<|endoftext|>


<commit_before>var controllerDir;
var appName;

function getAppName() {
    var parts = __dirname.replace(/\\/g, '/').split('/');
    return parts[parts.length - 2].split('.')[0];
}

// Get js-controller directory to load libs
function getControllerDir(isInstall) {
    var fs = require('fs');
    // Find the js-controller location
    var controllerDir = __dirname.replace(/\\/g, '/');
    controllerDir = controllerDir.split('/');
    if (controllerDir[controllerDir.length - 3] == 'adapter') {
        controllerDir.splice(controllerDir.length - 3, 3);
        controllerDir = controllerDir.join('/');
    } else if (controllerDir[controllerDir.length - 3] == 'node_modules') {
        controllerDir.splice(controllerDir.length - 3, 3);
        controllerDir = controllerDir.join('/');
        if (fs.existsSync(controllerDir + '/node_modules/' + appName + '.js-controller')) {
            controllerDir += '/node_modules/' + appName + '.js-controller';
        } else if (fs.existsSync(controllerDir + '/node_modules/' + appName.toLowerCase() + '.js-controller')) {
            controllerDir += '/node_modules/' + appName.toLowerCase() + '.js-controller';
        } else if (!fs.existsSync(controllerDir + '/controller.js')) {
            if (!isInstall) {
                console.log('Cannot find js-controller');
                process.exit(10);
            } else {
                process.exit();
            }
        }
    } else {
        if (!isInstall) {
            console.log('Cannot find js-controller');
            process.exit(10);
        } else {
            process.exit();
        }
    }
    return controllerDir;
}

// Read controller configuration file
function getConfig() {
    var fs = require('fs');
    if (fs.existsSync(controllerDir + '/conf/' + appName + '.json')) {
        return JSON.parse(fs.readFileSync(controllerDir + '/conf/' + appName + '.json'));
    } else if (fs.existsSync(controllerDir + '/conf/' + appName.toLowerCase() + '.json')) {
        return JSON.parse(fs.readFileSync(controllerDir + '/conf/' + appName.toLowerCase() + '.json'));
    } else {
        throw new Error('Cannot find ' + controllerDir + '/conf/' + appName + '.json');
    }
}
appName       = getAppName();
controllerDir = getControllerDir(typeof process !== 'undefined' && process.argv && process.argv.indexOf('--install') !== -1);

exports.controllerDir = controllerDir;
exports.getConfig =     getConfig;
exports.adapter =       require(controllerDir + '/lib/adapter.js');
exports.appName =       appName;
<commit_msg>update utils.js<commit_after>var controllerDir;
var appName;

function getAppName() {
    var parts = __dirname.replace(/\\/g, '/').split('/');
    return parts[parts.length - 2].split('.')[0];
}

// Get js-controller directory to load libs
function getControllerDir(isInstall) {
    var fs = require('fs');
    // Find the js-controller location
    var controllerDir = __dirname.replace(/\\/g, '/');
    controllerDir = controllerDir.split('/');
    if (controllerDir[controllerDir.length - 3] === 'adapter') {
        controllerDir.splice(controllerDir.length - 3, 3);
        controllerDir = controllerDir.join('/');
    } else if (controllerDir[controllerDir.length - 3] === 'node_modules') {
        controllerDir.splice(controllerDir.length - 3, 3);
        controllerDir = controllerDir.join('/');
        if (fs.existsSync(controllerDir + '/node_modules/' + appName + '.js-controller')) {
            controllerDir += '/node_modules/' + appName + '.js-controller';
        } else if (fs.existsSync(controllerDir + '/node_modules/' + appName.toLowerCase() + '.js-controller')) {
            controllerDir += '/node_modules/' + appName.toLowerCase() + '.js-controller';
        } else if (!fs.existsSync(controllerDir + '/controller.js')) {
            if (!isInstall) {
                console.log('Cannot find js-controller');
                process.exit(10);
            } else {
                process.exit();
            }
        }
    } else if (fs.existsSync(__dirname + '/../../node_modules/' + appName.toLowerCase() + '.js-controller')) {
        controllerDir.splice(controllerDir.length - 2, 2);
        return controllerDir.join('/') + '/node_modules/' + appName.toLowerCase() + '.js-controller';
    } else {
        if (!isInstall) {
            console.log('Cannot find js-controller');
            process.exit(10);
        } else {
            process.exit();
        }
    }
    return controllerDir;
}

// Read controller configuration file
function getConfig() {
    var fs = require('fs');
    if (fs.existsSync(controllerDir + '/conf/' + appName + '.json')) {
        return JSON.parse(fs.readFileSync(controllerDir + '/conf/' + appName + '.json'));
    } else if (fs.existsSync(controllerDir + '/conf/' + appName.toLowerCase() + '.json')) {
        return JSON.parse(fs.readFileSync(controllerDir + '/conf/' + appName.toLowerCase() + '.json'));
    } else {
        throw new Error('Cannot find ' + controllerDir + '/conf/' + appName + '.json');
    }
}
appName       = getAppName();
controllerDir = getControllerDir(typeof process !== 'undefined' && process.argv && process.argv.indexOf('--install') !== -1);

exports.controllerDir = controllerDir;
exports.getConfig =     getConfig;
exports.Adapter =       require(controllerDir + '/lib/adapter.js');
exports.appName =       appName;
<|endoftext|>


<commit_before>'use strict';

var hexTable = (function () {
    var array = new Array(256);
    for (var i = 0; i < 256; ++i) {
        array[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
    }

    return array;
}());

exports.arrayToObject = function (source, options) {
    var obj = options.plainObjects ? Object.create(null) : {};
    for (var i = 0; i < source.length; ++i) {
        if (typeof source[i] !== 'undefined') {
            obj[i] = source[i];
        }
    }

    return obj;
};

exports.merge = function (target, source, options) {
    if (!source) {
        return target;
    }

    if (typeof source !== 'object') {
        if (Array.isArray(target)) {
            target.push(source);
        } else if (typeof target === 'object') {
            target[source] = true;
        } else {
            return [target, source];
        }

        return target;
    }

    if (typeof target !== 'object') {
        return [target].concat(source);
    }

    var mergeTarget = target;
    if (Array.isArray(target) && !Array.isArray(source)) {
        mergeTarget = exports.arrayToObject(target, options);
    }

	return Object.keys(source).reduce(function (acc, key) {
        var value = source[key];

        if (Object.prototype.hasOwnProperty.call(acc, key)) {
            acc[key] = exports.merge(acc[key], value, options);
        } else {
            acc[key] = value;
        }
		return acc;
    }, mergeTarget);
};

exports.decode = function (str) {
    try {
        return decodeURIComponent(str.replace(/\+/g, ' '));
    } catch (e) {
        return str;
    }
};

exports.encode = function (str) {
    // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
    // It has been adapted here for stricter adherence to RFC 3986
    if (str.length === 0) {
        return str;
    }

    var string = typeof str === 'string' ? str : String(str);

    var out = '';
    for (var i = 0; i < string.length; ++i) {
        var c = string.charCodeAt(i);

        if (
            c === 0x2D || // -
            c === 0x2E || // .
            c === 0x5F || // _
            c === 0x7E || // ~
            (c >= 0x30 && c <= 0x39) || // 0-9
            (c >= 0x41 && c <= 0x5A) || // a-z
            (c >= 0x61 && c <= 0x7A) // A-Z
        ) {
            out += string.charAt(i);
            continue;
        }

        if (c < 0x80) {
            out = out + hexTable[c];
            continue;
        }

        if (c < 0x800) {
            out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]);
            continue;
        }

        if (c < 0xD800 || c >= 0xE000) {
            out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
            continue;
        }

        i += 1;
        c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
        out += (hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
    }

    return out;
};

exports.compact = function (obj, references) {
    if (typeof obj !== 'object' || obj === null) {
        return obj;
    }

    var refs = references || [];
    var lookup = refs.indexOf(obj);
    if (lookup !== -1) {
        return refs[lookup];
    }

    refs.push(obj);

    if (Array.isArray(obj)) {
        var compacted = [];

        for (var i = 0; i < obj.length; ++i) {
            if (Array.isArray(obj[i]) || Object.prototype.toString.call(obj[i]) === '[object Object]') {
                compacted.push(exports.compact(obj[i], refs));
            } else if (typeof obj[i] !== 'undefined') {
                compacted.push(obj[i]);
            }
        }

        return compacted;
    }

    var keys = Object.keys(obj);
    for (var j = 0; j < keys.length; ++j) {
        var key = keys[j];
        obj[key] = exports.compact(obj[key], refs);
    }

    return obj;
};

exports.isRegExp = function (obj) {
    return Object.prototype.toString.call(obj) === '[object RegExp]';
};

exports.isBuffer = function (obj) {
    if (obj === null || typeof obj === 'undefined') {
        return false;
    }

    return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
};
<commit_msg>Simplify check for non-function objects when compacting sparse arrays<commit_after>'use strict';

var hexTable = (function () {
    var array = new Array(256);
    for (var i = 0; i < 256; ++i) {
        array[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
    }

    return array;
}());

exports.arrayToObject = function (source, options) {
    var obj = options.plainObjects ? Object.create(null) : {};
    for (var i = 0; i < source.length; ++i) {
        if (typeof source[i] !== 'undefined') {
            obj[i] = source[i];
        }
    }

    return obj;
};

exports.merge = function (target, source, options) {
    if (!source) {
        return target;
    }

    if (typeof source !== 'object') {
        if (Array.isArray(target)) {
            target.push(source);
        } else if (typeof target === 'object') {
            target[source] = true;
        } else {
            return [target, source];
        }

        return target;
    }

    if (typeof target !== 'object') {
        return [target].concat(source);
    }

    var mergeTarget = target;
    if (Array.isArray(target) && !Array.isArray(source)) {
        mergeTarget = exports.arrayToObject(target, options);
    }

	return Object.keys(source).reduce(function (acc, key) {
        var value = source[key];

        if (Object.prototype.hasOwnProperty.call(acc, key)) {
            acc[key] = exports.merge(acc[key], value, options);
        } else {
            acc[key] = value;
        }
		return acc;
    }, mergeTarget);
};

exports.decode = function (str) {
    try {
        return decodeURIComponent(str.replace(/\+/g, ' '));
    } catch (e) {
        return str;
    }
};

exports.encode = function (str) {
    // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
    // It has been adapted here for stricter adherence to RFC 3986
    if (str.length === 0) {
        return str;
    }

    var string = typeof str === 'string' ? str : String(str);

    var out = '';
    for (var i = 0; i < string.length; ++i) {
        var c = string.charCodeAt(i);

        if (
            c === 0x2D || // -
            c === 0x2E || // .
            c === 0x5F || // _
            c === 0x7E || // ~
            (c >= 0x30 && c <= 0x39) || // 0-9
            (c >= 0x41 && c <= 0x5A) || // a-z
            (c >= 0x61 && c <= 0x7A) // A-Z
        ) {
            out += string.charAt(i);
            continue;
        }

        if (c < 0x80) {
            out = out + hexTable[c];
            continue;
        }

        if (c < 0x800) {
            out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]);
            continue;
        }

        if (c < 0xD800 || c >= 0xE000) {
            out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
            continue;
        }

        i += 1;
        c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
        out += (hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
    }

    return out;
};

exports.compact = function (obj, references) {
    if (typeof obj !== 'object' || obj === null) {
        return obj;
    }

    var refs = references || [];
    var lookup = refs.indexOf(obj);
    if (lookup !== -1) {
        return refs[lookup];
    }

    refs.push(obj);

    if (Array.isArray(obj)) {
        var compacted = [];

        for (var i = 0; i < obj.length; ++i) {
            if (obj[i] && typeof obj[i] === 'object') {
                compacted.push(exports.compact(obj[i], refs));
            } else if (typeof obj[i] !== 'undefined') {
                compacted.push(obj[i]);
            }
        }

        return compacted;
    }

    var keys = Object.keys(obj);
    for (var j = 0; j < keys.length; ++j) {
        var key = keys[j];
        obj[key] = exports.compact(obj[key], refs);
    }

    return obj;
};

exports.isRegExp = function (obj) {
    return Object.prototype.toString.call(obj) === '[object RegExp]';
};

exports.isBuffer = function (obj) {
    if (obj === null || typeof obj === 'undefined') {
        return false;
    }

    return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
};
<|endoftext|>


<commit_before>var utils = {
    extend: function (target) {
        for (var i = 1; i < arguments.length; i += 1) {
            var source = arguments[i];
            Object.keys(source).forEach(function (key) {
                target[key] = source[key];
            });
        }
        return target;
    },

    calculateOutputEntrySize: function (outputEntry) {
        if (outputEntry.size) {
            return outputEntry.size;
        }

        var size;
        switch (outputEntry.style) {
        case 'text':
            size = { width: String(outputEntry.args.content).length, height: 1 };
            break;
        case 'block':
            size = utils.calculateSize(outputEntry.args);
            break;
        case 'raw':
            var arg = outputEntry.args;
            size = { width: arg.width, height: arg.height };
            break;
        default: size = { width: 0, height: 0 };
        }

        outputEntry.size = size;
        return size;
    },

    calculateLineSize: function (line) {
        if (line.size) {
            return line.size;
        }

        var size = { height: 1, width: 0 };
        line.forEach(function (outputEntry) {
            var outputEntrySize = utils.calculateOutputEntrySize(outputEntry);
            size.width += outputEntrySize.width;
            size.height = Math.max(outputEntrySize.height, size.height);
        });
        line.size = size;
        return size;
    },

    calculateSize: function (lines) {
        var size = { height: 0, width: 0 };
        lines.forEach(function (line) {
            var lineSize = utils.calculateLineSize(line);
            size.height += lineSize.height;
            size.width = Math.max(size.width, lineSize.width);
        });
        return size;
    },

    arrayEquals: function (a, b) {
        if (a === b) {
            return true;
        }

        if (!a || a.length !== b.length) {
            return false;
        }

        for (var i = 0; i < a.length; i += 1) {
            if (a[i] !== b[i]) {
                return false;
            }
        }

        return true;

    },

    escapeRegExp: function (text){
        return text.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1");
    },

    findFirst: function (arr, predicate, thisObj) {
        var scope = thisObj || null;
        for (var i = 0 ; i < arr.length ; i += 1) {
            if (predicate.call(scope, arr[i], i, arr)) {
                return arr[i];
            }
        }
        return null;
    },

    getFunctionName: function (f) {
        if (typeof f.name === 'string') {
            return f.name;
        }
        var matchFunctionName = Function.prototype.toString.call(f).match(/function ([^\(]+)/);
        if (matchFunctionName) {
            return matchFunctionName[1];
        }

        if (f === Object) {
            return 'Object';
        }
        if (f === Function) {
            return 'Function';
        }
    }
};

module.exports = utils;
<commit_msg>It is not possible to cache the line size<commit_after>var utils = {
    extend: function (target) {
        for (var i = 1; i < arguments.length; i += 1) {
            var source = arguments[i];
            Object.keys(source).forEach(function (key) {
                target[key] = source[key];
            });
        }
        return target;
    },

    calculateOutputEntrySize: function (outputEntry) {
        if (outputEntry.size) {
            return outputEntry.size;
        }

        var size;
        switch (outputEntry.style) {
        case 'text':
            size = { width: String(outputEntry.args.content).length, height: 1 };
            break;
        case 'block':
            size = utils.calculateSize(outputEntry.args);
            break;
        case 'raw':
            var arg = outputEntry.args;
            size = { width: arg.width, height: arg.height };
            break;
        default: size = { width: 0, height: 0 };
        }

        outputEntry.size = size;
        return size;
    },

    calculateLineSize: function (line) {
        var size = { height: 1, width: 0 };
        line.forEach(function (outputEntry) {
            var outputEntrySize = utils.calculateOutputEntrySize(outputEntry);
            size.width += outputEntrySize.width;
            size.height = Math.max(outputEntrySize.height, size.height);
        });
        line.size = size;
        return size;
    },

    calculateSize: function (lines) {
        var size = { height: 0, width: 0 };
        lines.forEach(function (line) {
            var lineSize = utils.calculateLineSize(line);
            size.height += lineSize.height;
            size.width = Math.max(size.width, lineSize.width);
        });
        return size;
    },

    arrayEquals: function (a, b) {
        if (a === b) {
            return true;
        }

        if (!a || a.length !== b.length) {
            return false;
        }

        for (var i = 0; i < a.length; i += 1) {
            if (a[i] !== b[i]) {
                return false;
            }
        }

        return true;

    },

    escapeRegExp: function (text){
        return text.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1");
    },

    findFirst: function (arr, predicate, thisObj) {
        var scope = thisObj || null;
        for (var i = 0 ; i < arr.length ; i += 1) {
            if (predicate.call(scope, arr[i], i, arr)) {
                return arr[i];
            }
        }
        return null;
    },

    getFunctionName: function (f) {
        if (typeof f.name === 'string') {
            return f.name;
        }
        var matchFunctionName = Function.prototype.toString.call(f).match(/function ([^\(]+)/);
        if (matchFunctionName) {
            return matchFunctionName[1];
        }

        if (f === Object) {
            return 'Object';
        }
        if (f === Function) {
            return 'Function';
        }
    }
};

module.exports = utils;
<|endoftext|>


<commit_before>'use strict'
const {exit} = require('process')
const {getOwnPropertyDescriptor, defineProperty, assign} = Object
const {info, error} = global.console

const success = message => {
  info(message)
  exit(0)
}

const failure = (message, code = 1) => {
  error(message)
  exit(code)
}

const getprop = (object, property) => {
  if (object === undefined || object === null) return undefined
  const descriptor = getOwnPropertyDescriptor(object, property)
  if (!descriptor) return undefined
  return descriptor.value
}

const setprop = (object, property, value) =>
  defineProperty(object, property, {value, enumerable: true})

const getproppath = (object, ...properties) => properties.reduce(getprop, object)

const setproppath = (value, object, first, ...rest) => {
  if (first === undefined) return value
  switch (typeof object) {
    case 'object':
      if (object === null) return null
      object[first] = setproppath(value, object[first], ...rest)
      return object
    case 'string':
      const index = parseInt(first)
      return isFinite(first)
        ? object.slice(0, index) + value + object.slice(index)
        : object
  }
  return object
}

module.exports = {success, failure, getprop, setprop, getproppath, setproppath}
<commit_msg>Variable 'assign' is never used<commit_after>'use strict'
const {exit} = require('process')
const {getOwnPropertyDescriptor, defineProperty} = Object
const {info, error} = global.console

const success = message => {
  info(message)
  exit(0)
}

const failure = (message, code = 1) => {
  error(message)
  exit(code)
}

const getprop = (object, property) => {
  if (object === undefined || object === null) return undefined
  const descriptor = getOwnPropertyDescriptor(object, property)
  if (!descriptor) return undefined
  return descriptor.value
}

const setprop = (object, property, value) =>
  defineProperty(object, property, {value, enumerable: true})

const getproppath = (object, ...properties) => properties.reduce(getprop, object)

const setproppath = (value, object, first, ...rest) => {
  if (first === undefined) return value
  switch (typeof object) {
    case 'object':
      if (object === null) return null
      object[first] = setproppath(value, object[first], ...rest)
      return object
    case 'string':
      const index = parseInt(first)
      return isFinite(first)
        ? object.slice(0, index) + value + object.slice(index)
        : object
  }
  return object
}

module.exports = {success, failure, getprop, setprop, getproppath, setproppath}
<|endoftext|>


<commit_before>const path = require('path');
const fs = require('fs');
const request = require('request');
const isPlainObject = require('lodash/isPlainObject');
const semver = require('semver');
const logger = require('./logger');

const result = (fn, ...args) => (typeof fn === 'function' ? fn(...args) : fn);

const objectToString = (obj) => {
    return Object.keys(obj).reduce((arr, key) => {
        return arr.concat(`${key}: ${obj[key]}`);
    }, []).join(', ');
};

const tmpDir = (str) => {
    return path.join(require('user-home'), '.umeboshi-cli', str.replace(/[/#:]+/g, '-'));
};

const listFolders = (folder) => {
    return fs.readdirSync(folder).filter((f) => (
        fs.statSync(path.join(folder, f)).isDirectory()
    ));
};

const getJSON = (uri) => {
    return new Promise((resolve, reject) => {
        request.get({
            uri,
            headers: {
                'User-Agent': 'request'
            },
            json: true
        }, (err, res, results) => {

            if (err || (res.statusCode < 200 || res.statusCode >= 400)) {

                const errStatus = res ? `(status: ${res.statusCode})` : `(error: ${err.message})`;
                reject(errStatus, err, res);
                return;
            }

            resolve(results, err, res);
        });
    });
};

const getTags = (templateName) => {
    const uri = `https://api.github.com/repos/${templateName}/tags`;

    return getJSON(uri).then(
        (tags) => tags.map(({ name }) => name),
        (errStatus) => { logger.verbose(`Unable retrieve github tags from ${uri}. ${errStatus}`); }
    );
};

const getLatestTag = (templateName) => {

    return getTags(templateName).then(
        (tags) => (tags.length > 0 ? tags[0] : 'master')
    );

};

const deleteFile = (files, filepath) => {
    if (files[filepath]) {
        files[filepath] = null; //eslint-disable-line no-param-reassign
        delete files[filepath]; //eslint-disable-line no-param-reassign
        logger.verbose(`File ${filepath} removed.`);
    }
};

const getFileContents = (files, filepath) => {
    if (files[filepath]) {
        return files[filepath].contents.toString();
    }
    return null;
};

const fileToJSON = (files, filepath) => {
    const contents = getFileContents(files, filepath);
    if (contents) { return JSON.parse(contents); }
    return {};
};

const JSONtoBuffer = (json) => Buffer.from(JSON.stringify(json, null, 2));

const resolveRepoUrl = (templateName, version) => {
    if (typeof version === 'string' && version !== 'latest') {
        //master or develop?
        if (semver.valid(version) === null) {
            return Promise.resolve(`github:${templateName}#${version}`);
        }
        return getTags(templateName).then((tags) => {
            const maxVersion = semver.maxSatisfying(tags, version);
            if (maxVersion) {
                return Promise.resolve(`github:${templateName}#${maxVersion}`);
            }
            return Promise.reject(new Error(`No repository releases matches semver "${version}"`));
        });
    }
    return getLatestTag(templateName).then((v) => `github:${templateName}#${v}`);
};

function Injector(files) {
    this.files = files;
}

Injector.prototype.at = function injectorAt(file, tag, content = '') {
    if (this.files[file]) {
        const template = this.files[file];

        if (isPlainObject(tag)) {
            Object.keys(tag).forEach((t) => {
                this.at(file, t, tag[t]);
            });
            return;
        }

        template.contents = Buffer.from(
            template.contents.toString().replace(`{{!-- ${tag} --}}`, `${content}{{!-- ${tag} --}}`)
        );
    }
};

module.exports = {
    Injector,
    getLatestTag,
    listFolders,
    objectToString,
    tmpDir,
    deleteFile,
    result,
    JSONtoBuffer,
    getFileContents,
    fileToJSON,
    getJSON,
    resolveRepoUrl
};<commit_msg>feat(github tags): filter just valid semver tags<commit_after>const path = require('path');
const fs = require('fs');
const request = require('request');
const isPlainObject = require('lodash/isPlainObject');
const semver = require('semver');
const logger = require('./logger');

const result = (fn, ...args) => (typeof fn === 'function' ? fn(...args) : fn);

const objectToString = (obj) => {
    return Object.keys(obj).reduce((arr, key) => {
        return arr.concat(`${key}: ${obj[key]}`);
    }, []).join(', ');
};

const tmpDir = (str) => {
    return path.join(require('user-home'), '.umeboshi-cli', str.replace(/[/#:]+/g, '-'));
};

const listFolders = (folder) => {
    return fs.readdirSync(folder).filter((f) => (
        fs.statSync(path.join(folder, f)).isDirectory()
    ));
};

const getJSON = (uri) => {
    return new Promise((resolve, reject) => {
        request.get({
            uri,
            headers: {
                'User-Agent': 'request'
            },
            json: true
        }, (err, res, results) => {

            if (err || (res.statusCode < 200 || res.statusCode >= 400)) {

                const errStatus = res ? `(status: ${res.statusCode})` : `(error: ${err.message})`;
                reject(errStatus, err, res);
                return;
            }

            resolve(results, err, res);
        });
    });
};

const getTags = (templateName) => {
    const uri = `https://api.github.com/repos/${templateName}/tags`;

    return getJSON(uri).then(
        (tags) => tags.map(({ name }) => name).filter(semver.valid),
        (errStatus) => { logger.verbose(`Unable retrieve github tags from ${uri}. ${errStatus}`); }
    );
};

const getLatestTag = (templateName) => {

    return getTags(templateName).then(
        (tags) => (tags.length > 0 ? tags[0] : 'master')
    );

};

const deleteFile = (files, filepath) => {
    if (files[filepath]) {
        files[filepath] = null; //eslint-disable-line no-param-reassign
        delete files[filepath]; //eslint-disable-line no-param-reassign
        logger.verbose(`File ${filepath} removed.`);
    }
};

const getFileContents = (files, filepath) => {
    if (files[filepath]) {
        return files[filepath].contents.toString();
    }
    return null;
};

const fileToJSON = (files, filepath) => {
    const contents = getFileContents(files, filepath);
    if (contents) { return JSON.parse(contents); }
    return {};
};

const JSONtoBuffer = (json) => Buffer.from(JSON.stringify(json, null, 2));

const resolveRepoUrl = (templateName, version) => {
    if (typeof version === 'string' && version !== 'latest') {
        if (semver.validRange(version)) {
            return getTags(templateName).then((tags) => {
                const maxVersion = semver.maxSatisfying(tags, version);
                if (maxVersion) {
                    return Promise.resolve(`github:${templateName}#${maxVersion}`);
                }
                return Promise.reject(new Error(`No repository releases matches semver "${version}"`));
            });
        }

        return Promise.resolve(`github:${templateName}#${version}`);

    }
    return getLatestTag(templateName).then((v) => `github:${templateName}#${v}`);
};

function Injector(files) {
    this.files = files;
}

Injector.prototype.at = function injectorAt(file, tag, content = '') {
    if (this.files[file]) {
        const template = this.files[file];

        if (isPlainObject(tag)) {
            Object.keys(tag).forEach((t) => {
                this.at(file, t, tag[t]);
            });
            return;
        }

        template.contents = Buffer.from(
            template.contents.toString().replace(`{{!-- ${tag} --}}`, `${content}{{!-- ${tag} --}}`)
        );
    }
};

module.exports = {
    Injector,
    getLatestTag,
    listFolders,
    objectToString,
    tmpDir,
    deleteFile,
    result,
    JSONtoBuffer,
    getFileContents,
    fileToJSON,
    getJSON,
    resolveRepoUrl
};<|endoftext|>