<commit_before>'use strict';

var PLUGIN_NAME = 'gulp-rollup';

var util         = require('util');
var gutil        = require('gulp-util');
var PluginError  = gutil.PluginError;
var File         = gutil.File;
var Transform    = require('readable-stream').Transform;
var hypothetical = require('rollup-plugin-hypothetical');
var path         = require('path');

function GulpRollup(options) {
  var self = this;

  Transform.call(self, { objectMode: true });

  options = options || {};

  var wonderland = {};
  var entries = [], haveSourcemaps;

  var entryFiles = Promise.resolve(options.entry).then(function(entryFiles) {
    if (typeof entryFiles === 'string') {
      return [entryFiles];
    } else if (Array.isArray(entryFiles)) {
      if (entryFiles.some(function(entryFile) {
        return typeof entryFile !== 'string';
      })) {
        throw new Error('options.entry must include only strings!');
      }
      return entryFiles;
    } else {
      throw new Error('options.entry must be a string or array of strings!');
    }
  });

  self._transform = function(file, enc, cb) {
    if (!file.isBuffer()) {
      self.emit('error', new PluginError(PLUGIN_NAME, 'Input files must be buffered!'));
      return cb();
    }

    if (haveSourcemaps === undefined) {
      haveSourcemaps = file.sourceMap !== undefined;
    } else if (haveSourcemaps !== (file.sourceMap !== undefined)) {
      self.emit('error', new PluginError(PLUGIN_NAME, 'Mixing of sourcemapped and non-sourcemapped files!'));
      return cb();
    }

    if (haveSourcemaps) {
      wonderland[file.path] = {
        code: file.contents.toString(),
        map:  file.sourceMap
      };
    } else {
      wonderland[file.path] = file.contents.toString();
    }

    // taking advantage of hypothetical's state-of-the-art resolving capabilities.
    var onederland = {}; // ohoho, funny pun. I laugh.
    onederland[file.path] = '';
    var finder = hypothetical({ files: onederland, allowRealFiles: true });
    // now let's see if this is an entry file.
    entryFiles = entryFiles.then(function(entryFiles) {
      entryFiles.forEach(function(entryFile, i) {
        if (!entries[i] && finder.resolveId(entryFile)) {
          entries[i] = file;
        }
      });
      return entryFiles;
    });

    cb();
  };

  self._flush = function(cb) {
    entryFiles.then(function(entryFiles) {
      var rollup = options.rollup || require('rollup');

      return Promise.all(entryFiles.map(function(entryFile, i) {
        // don't tamper with the original options. copy them over instead.
        var adjustedOptions = {};
        for (var key in options) {
          if (key !== 'rollup' && key !== 'allowRealFiles') {
            adjustedOptions[key] = options[key];
          }
        }

        if (!adjustedOptions.plugins) {
          adjustedOptions.plugins = [];
        } else if (!Array.isArray(adjustedOptions.plugins)) {
          adjustedOptions.plugins = [adjustedOptions.plugins];
        }
        adjustedOptions.plugins = adjustedOptions.plugins.concat(hypothetical({
          files: wonderland,
          allowRealFiles: options.allowRealFiles
        }));

        adjustedOptions.entry = entryFile;

        adjustedOptions.sourceMap = haveSourcemaps;

        return rollup.rollup(adjustedOptions).then(function(bundle) {
          var result = bundle.generate(adjustedOptions);

          // get the corresponding entry Vinyl file to output with.
          // this makes file.history work. maybe expando properties too if you use them.
          var file = entries[i];
          if (file === undefined) { // possible if options.allowRealFiles is true
            file = new File({
              path: entryFile,
              contents: new Buffer(result.code)
            });
          } else {
            file.contents = new Buffer(result.code);
          }

          var map = result.map;
          if (map) {
            // This makes sure the paths in the generated source map (file and
            // sources) are relative to file.base:
            map.file = unixStylePath(file.relative);
            map.sources = map.sources.map(function(fileName) {
              return unixStylePath(path.relative(file.base, fileName));
            });
            file.sourceMap = map;
          }

          self.push(file);
        });
      }));
    }).then(function() {
      cb(); // it's over!
    }).catch(function(err) {
      setImmediate(function() {
        self.emit('error', new PluginError(PLUGIN_NAME, err));
        cb();
      });
    });
  };
}
util.inherits(GulpRollup, Transform);

function unixStylePath(filePath) {
  return filePath.split(path.sep).join('/');
}

module.exports = function(options) {
  return new GulpRollup(options);
};
<commit_msg>Select the last matching entry file rather than the first<commit_after>'use strict';

var PLUGIN_NAME = 'gulp-rollup';

var util         = require('util');
var gutil        = require('gulp-util');
var PluginError  = gutil.PluginError;
var File         = gutil.File;
var Transform    = require('readable-stream').Transform;
var hypothetical = require('rollup-plugin-hypothetical');
var path         = require('path');

function GulpRollup(options) {
  var self = this;

  Transform.call(self, { objectMode: true });

  options = options || {};

  var wonderland = {};
  var entries = [], haveSourcemaps;

  var entryFiles = Promise.resolve(options.entry).then(function(entryFiles) {
    if (typeof entryFiles === 'string') {
      return [entryFiles];
    } else if (Array.isArray(entryFiles)) {
      if (entryFiles.some(function(entryFile) {
        return typeof entryFile !== 'string';
      })) {
        throw new Error('options.entry must include only strings!');
      }
      return entryFiles;
    } else {
      throw new Error('options.entry must be a string or array of strings!');
    }
  });

  self._transform = function(file, enc, cb) {
    if (!file.isBuffer()) {
      self.emit('error', new PluginError(PLUGIN_NAME, 'Input files must be buffered!'));
      return cb();
    }

    if (haveSourcemaps === undefined) {
      haveSourcemaps = file.sourceMap !== undefined;
    } else if (haveSourcemaps !== (file.sourceMap !== undefined)) {
      self.emit('error', new PluginError(PLUGIN_NAME, 'Mixing of sourcemapped and non-sourcemapped files!'));
      return cb();
    }

    if (haveSourcemaps) {
      wonderland[file.path] = {
        code: file.contents.toString(),
        map:  file.sourceMap
      };
    } else {
      wonderland[file.path] = file.contents.toString();
    }

    // taking advantage of hypothetical's state-of-the-art resolving capabilities.
    var onederland = {}; // ohoho, funny pun. I laugh.
    onederland[file.path] = '';
    var finder = hypothetical({ files: onederland, allowRealFiles: true });
    // now let's see if this is an entry file.
    entryFiles = entryFiles.then(function(entryFiles) {
      entryFiles.forEach(function(entryFile, i) {
        if (finder.resolveId(entryFile)) {
          entries[i] = file;
        }
      });
      return entryFiles;
    });

    cb();
  };

  self._flush = function(cb) {
    entryFiles.then(function(entryFiles) {
      var rollup = options.rollup || require('rollup');

      return Promise.all(entryFiles.map(function(entryFile, i) {
        // don't tamper with the original options. copy them over instead.
        var adjustedOptions = {};
        for (var key in options) {
          if (key !== 'rollup' && key !== 'allowRealFiles') {
            adjustedOptions[key] = options[key];
          }
        }

        if (!adjustedOptions.plugins) {
          adjustedOptions.plugins = [];
        } else if (!Array.isArray(adjustedOptions.plugins)) {
          adjustedOptions.plugins = [adjustedOptions.plugins];
        }
        adjustedOptions.plugins = adjustedOptions.plugins.concat(hypothetical({
          files: wonderland,
          allowRealFiles: options.allowRealFiles
        }));

        adjustedOptions.entry = entryFile;

        adjustedOptions.sourceMap = haveSourcemaps;

        return rollup.rollup(adjustedOptions).then(function(bundle) {
          var result = bundle.generate(adjustedOptions);

          // get the corresponding entry Vinyl file to output with.
          // this makes file.history work. maybe expando properties too if you use them.
          var file = entries[i];
          if (file === undefined) { // possible if options.allowRealFiles is true
            file = new File({
              path: entryFile,
              contents: new Buffer(result.code)
            });
          } else {
            file.contents = new Buffer(result.code);
          }

          var map = result.map;
          if (map) {
            // This makes sure the paths in the generated source map (file and
            // sources) are relative to file.base:
            map.file = unixStylePath(file.relative);
            map.sources = map.sources.map(function(fileName) {
              return unixStylePath(path.relative(file.base, fileName));
            });
            file.sourceMap = map;
          }

          self.push(file);
        });
      }));
    }).then(function() {
      cb(); // it's over!
    }).catch(function(err) {
      setImmediate(function() {
        self.emit('error', new PluginError(PLUGIN_NAME, err));
        cb();
      });
    });
  };
}
util.inherits(GulpRollup, Transform);

function unixStylePath(filePath) {
  return filePath.split(path.sep).join('/');
}

module.exports = function(options) {
  return new GulpRollup(options);
};
<|endoftext|>


<commit_before>var util = require('util');
var pg = require('pg');
var semver = require('semver');
var Base = require('db-migrate-base');
var type;
var log;
var Promise = require('bluebird');

var internals = {};

var PgDriver = Base.extend({
    init: function(connection, schema, intern) {
        this._escapeString = '\'';
        this._super(intern);
        this.internals = intern;
        this.connection = connection;
        this.schema = schema || "public";
        this.connection.connect();
    },

    startMigration: function(cb){

      if(!this.internals.notransactions) {

        return this.runSql('BEGIN;').nodeify(cb);
      }
      else
        return Promise.resolve().nodeify(cb);
    },

    endMigration: function(cb){

      if(!this.internals.notransactions) {

        return this.runSql('COMMIT;').nodeify(cb);
      }
      else
        return Promise.resolve(null).nodeify(cb);
    },

    createColumnDef: function(name, spec, options, tableName) {
        var type = spec.autoIncrement ? '' : this.mapDataType(spec.type);
        var len = spec.length ? util.format('(%s)', spec.length) : '';
        var constraint = this.createColumnConstraint(spec, options, tableName, name);
        if (name.charAt(0) != '"') {
            name = '"' + name + '"';
        }

        return { foreignKey: constraint.foreignKey,
                 constraints: [name, type, len, constraint.constraints].join(' ') };
    },

    mapDataType: function(str) {
        switch(str) {
          case type.STRING:
            return 'VARCHAR';
          case type.DATE_TIME:
            return 'TIMESTAMP';
          case type.BLOB:
            return 'BYTEA';
        }
        return this._super(str);
    },

    createDatabase: function(dbName, options, callback) {

      var spec = '';

      if(typeof(options) === 'function')
        callback = options;

      this.runSql(util.format('CREATE DATABASE %s %s', this.escapeDDL(dbName),
        spec), callback);
    },

    dropDatabase: function(dbName, options, callback) {

      var ifExists = '';

      if(typeof(options) === 'function')
        callback = options;
      else
      {
        ifExists = (options.ifExists === true) ? 'IF EXISTS' : '';
      }

      this.runSql(util.format('DROP DATABASE %s %s', ifExists, this.escapeDDL(dbName)), callback);
    },

    createSequence: function(sqName, options, callback) {

      var spec = '',
          temp = '';

      if(typeof(options) === 'function')
        callback = options;
      else
      {
        temp = (options.temp === true) ? 'TEMP' : '';
      }

      this.runSql(util.format('CREATE %s SEQUENCE `%s` %s', temp, sqName, spec), callback);
    },

    switchDatabase: function(options, callback) {

      if(typeof(options) === 'object')
      {
        if(typeof(options.database) === 'string')
        {
          log.info('Ignore database option, not available with postgres. Use schema instead!');
          this.runSql(util.format('SET search_path TO `%s`', options.database), callback);
        }
      }
      else if(typeof(options) === 'string')
      {
        this.runSql(util.format('SET search_path TO `%s`', options), callback);
      }
      else
        callback(null);
    },

    dropSequence: function(dbName, options, callback) {

      var ifExists = '',
          rule = '';

      if(typeof(options) === 'function')
        callback = options;
      else
      {
        ifExists = (options.ifExists === true) ? 'IF EXISTS' : '';

        if(options.cascade === true)
          rule = 'CASCADE';
        else if(options.restrict === true)
          rule = 'RESTRICT';
      }

      this.runSql(util.format('DROP SEQUENCE %s `%s` %s', ifExists, dbName, rule), callback);
    },

    createMigrationsTable: function(callback) {
      var options = {
        columns: {
          'id': { type: type.INTEGER, notNull: true, primaryKey: true, autoIncrement: true },
          'name': { type: type.STRING, length: 255, notNull: true},
          'run_on': { type: type.DATE_TIME, notNull: true}
        },
        ifNotExists: false
      };

      return this.all('select version() as version')
      .then(function(result) {

        if (result && result && result.length > 0 && result[0].version) {
          var version = result[0].version;
          var match = version.match(/\d+\.\d+\.\d+/);
          if (match && match[0] && semver.gte(match[0], '9.1.0')) {
            options.ifNotExists = true;
          }
        }

        // Get the current search path so we can change the current schema
        // if necessary
        return this.all("SHOW search_path");
      }.bind(this))
      .then(function(result) {

          var searchPath,
              search_pathes = result[0].search_path.split(',');

          for (var i = 0; i < search_pathes.length; ++i) {
            if (search_pathes[i].indexOf('"') !== 0) {
              search_pathes[i] = '"' + search_pathes[i].trim() + '"';
            }
          }

          result[0].search_path = search_pathes.join(',');

          // if the user specified a different schema, prepend it to the
          // search path. This will make all DDL/DML/SQL operate on the specified
          // schema.
          if (this.schema === 'public') {
              searchPath = result[0].search_path;
          } else {
              searchPath = '"' + this.schema + '",' + result[0].search_path;
          }

          return this.all('SET search_path TO ' + searchPath);
        }.bind(this))
        .then(function() {

          return this.all("SELECT table_name FROM information_schema.tables WHERE table_name = '" +
            this.internals.migrationTable + "'" +
            ((this.schema) ?
              " AND table_schema = '" + this.schema + "'" :
              ''));
        }.bind(this))
        .then(function(result) {

          if (result && result && result.length < 1) {
            return this.createTable(this.internals.migrationTable, options);
          } else {
            return Promise.resolve();
          }
        }.bind(this)).nodeify(callback);
    },

    createSeedsTable: function(callback) {
      var options = {
        columns: {
          'id': { type: type.INTEGER, notNull: true, primaryKey: true, autoIncrement: true },
          'name': { type: type.STRING, length: 255, notNull: true},
          'run_on': { type: type.DATE_TIME, notNull: true}
        },
        ifNotExists: false
      };

      return this.all('select version() as version')
      .then(function(result) {

        if (result && result && result.length > 0 && result[0].version) {
          var version = result[0].version;
          var match = version.match(/\d+\.\d+\.\d+/);
          if (match && match[0] && semver.gte(match[0], '9.1.0')) {
            options.ifNotExists = true;
          }
        }

        // Get the current search path so we can change the current schema
        // if necessary
        return this.all("SHOW search_path");
      }.bind(this))
      .then(function(result) {

          var searchPath;

            // if the user specified a different schema, prepend it to the
            // search path. This will make all DDL/DML/SQL operate on the specified
            // schema.
            if (this.schema === 'public') {
                searchPath = result[0].search_path;
            } else {
                searchPath = '"' + this.schema + '",' + result[0].search_path;
            }

          return this.all('SET search_path TO ' + searchPath);
        }.bind(this))
        .then(function() {

            return this.all("SELECT table_name FROM information_schema.tables WHERE table_name = '" +
              this.internals.seedTable + "'" +
              ((this.schema) ?
                " AND table_schema = '" + this.schema + "'" :
                ''));
        }.bind(this))
        .then(function(result) {

          if (result && result && result.length < 1) {
            return this.createTable(this.internals.seedTable, options);
          } else {
            return Promise.resolve();
          }
        }.bind(this)).nodeify(callback);
    },

    createColumnConstraint: function(spec, options, tableName, columnName) {
        var constraint = [],
            cb;

        if (spec.primaryKey && options.emitPrimaryKey) {
            if (spec.autoIncrement) {
                constraint.push('SERIAL');
            }
            constraint.push('PRIMARY KEY');
        }

        if (spec.notNull === true) {
            constraint.push('NOT NULL');
        }

        if (spec.unique) {
            constraint.push('UNIQUE');
        }

        if (typeof spec.defaultValue != 'undefined') {
            constraint.push('DEFAULT');
            if (typeof spec.defaultValue == 'string'){
                constraint.push("'" + spec.defaultValue + "'");
            } else {
              constraint.push(spec.defaultValue);
            }
        }

        if (spec.foreignKey) {

          cb = this.bindForeignKey(tableName, columnName, spec.foreignKey);
        }

        return { foreignKey: cb, constraints: constraint.join(' ') };
    },

    renameTable: function(tableName, newTableName, callback) {
        var sql = util.format('ALTER TABLE "%s" RENAME TO "%s"', tableName, newTableName);
        return this.runSql(sql).nodeify(callback);
    },

    removeColumn: function(tableName, columnName, callback) {
        var sql = util.format('ALTER TABLE "%s" DROP COLUMN "%s"', tableName, columnName);

        return this.runSql(sql).nodeify(callback);
    },

    renameColumn: function(tableName, oldColumnName, newColumnName, callback) {
        var sql = util.format('ALTER TABLE "%s" RENAME COLUMN "%s" TO "%s"', tableName, oldColumnName, newColumnName);
        return this.runSql(sql).nodeify(callback);
    },

    changeColumn: function(tableName, columnName, columnSpec, callback) {
      return setNotNull.call(this);

      function setNotNull() {
        var setOrDrop = columnSpec.notNull === true ? 'SET' : 'DROP';
        var sql = util.format('ALTER TABLE "%s" ALTER COLUMN "%s" %s NOT NULL', tableName, columnName, setOrDrop);

        return this.runSql(sql).nodeify(setUnique.bind(this));
      }

      function setUnique(err) {
        if (err) {
          return Promise.reject(err);
        }

        var sql;
        var constraintName = tableName + '_' + columnName + '_key';

        if (columnSpec.unique === true) {
          sql = util.format('ALTER TABLE "%s" ADD CONSTRAINT "%s" UNIQUE ("%s")', tableName, constraintName, columnName);
          return this.runSql(sql).nodeify(setDefaultValue.bind(this));
        } else if (columnSpec.unique === false) {
          sql = util.format('ALTER TABLE "%s" DROP CONSTRAINT "%s"', tableName, constraintName);
          return this.runSql(sql).nodeify(setDefaultValue.bind(this));
        } else {
          return setDefaultValue.call(this);
        }
      }

      function setDefaultValue(err) {
        if (err) {
          return Promise.reject(err).nodeify(callback);
        }

        var sql;

        if (columnSpec.defaultValue !== undefined) {
          var defaultValue = null;
          if (typeof columnSpec.defaultValue == 'string'){
            defaultValue = "'" + columnSpec.defaultValue + "'";
          } else {
            defaultValue = columnSpec.defaultValue;
          }
          sql = util.format('ALTER TABLE "%s" ALTER COLUMN "%s" SET DEFAULT %s', tableName, columnName, defaultValue);
        } else {
          sql = util.format('ALTER TABLE "%s" ALTER COLUMN "%s" DROP DEFAULT', tableName, columnName);
        }
        return this.runSql(sql).then(
          setType.bind(this)
        ).nodeify(callback);
      }

      function setType() {
        if (columnSpec.type !== undefined){
          var using = columnSpec.using !== undefined ?
            columnSpec.using : util.format('USING "%s"::%s', columnName, this.mapDataType(columnSpec.type))
          var sql = util.format('ALTER TABLE "%s" ALTER COLUMN "%s" TYPE %s %s', tableName, columnName, this.mapDataType(columnSpec.type), using);
          return this.runSql(sql);
        }
      }
    },

    addForeignKey: function(tableName, referencedTableName, keyName, fieldMapping, rules, callback) {
      if(arguments.length === 5 && typeof(rules) === 'function') {
        callback = rules;
        rules = {};
      }
      var columns = Object.keys(fieldMapping);
      var referencedColumns = columns.map(function (key) { return '"' + fieldMapping[key] + '"'; });
      var sql = util.format('ALTER TABLE "%s" ADD CONSTRAINT "%s" FOREIGN KEY (%s) REFERENCES "%s" (%s) ON DELETE %s ON UPDATE %s',
        tableName, keyName, this.quoteDDLArr(columns), referencedTableName, referencedColumns, rules.onDelete || 'NO ACTION', rules.onUpdate || 'NO ACTION');
      return this.runSql(sql).nodeify(callback);
    },

    removeForeignKey: function(tableName, keyName, callback) {
      var sql = util.format('ALTER TABLE "%s" DROP CONSTRAINT "%s"', tableName, keyName);
      return this.runSql(sql).nodeify(callback);
    },

    insert: function() {

      var index = 1;

      if( arguments.length > 3 ) {

        index = 2;
      }

      arguments[index] = arguments[index].map(function(value) {
        return 'string' === typeof value ? value : JSON.stringify(value);
      });

      return this._super.apply(this, arguments);
    },

    runSql: function() {
        var callback,
            minLength = 1;

        if(typeof(arguments[arguments.length - 1]) === 'function')
        {
          minLength = 2;
          callback = arguments[arguments.length - 1];
        }

        params = arguments;
        if (params.length > minLength){
            // We have parameters, but db-migrate uses "?" for param substitutions.
            // PG uses "$1", "$2", etc so fix up the "?" into "$1", etc
            var param = params[0].split('?'),
                new_param = [];
            for (var i = 0; i < param.length-1; i++){
                new_param.push(param[i], "$" + (i+1));
            }
            new_param.push(param[param.length-1]);
            params[0] = new_param.join('');
        }

        log.sql.apply(null, params);
        if(this.internals.dryRun) {
          return Promise.resolve().nodeify(callback);
        }

        return new Promise(function(resolve, reject) {
          var prCB = function(err, data) {
            return (err ? reject(err) : resolve(data));
          };

          if( minLength === 2 )
            params[params.length - 1] = prCB;
          else
            params[params.length++] = prCB;

          this.connection.query.apply(this.connection, params);
        }.bind(this)).nodeify(callback);
    },

    all: function() {
        params = arguments;

        log.sql.apply(null, params);

        return new Promise(function(resolve, reject) {
          var prCB = function(err, data) {
            return (err ? reject(err) : resolve(data));
          };

          this.connection.query.apply(this.connection, [params[0], function(err, result){
            prCB(err, (result) ? result.rows : result);
          }]);

        }.bind(this)).nodeify(params[1]);
    },

    close: function(callback) {
        this.connection.end();
        if( typeof(callback) === 'function' )
          return Promise.resolve().nodeify(callback);
        else
          return Promise.resolve();
    }

});

Promise.promisifyAll(PgDriver);

exports.connect = function(config, intern, callback) {

    internals = intern;

    log = intern.mod.log;
    type = intern.mod.type;

    if (config.native) { pg = pg.native; }
    var db = config.db || new pg.Client(config);
    callback(null, new PgDriver(db, config.schema, intern));
};
<commit_msg>fix(spec): defaultValue should be checked for undefined only<commit_after>var util = require('util');
var pg = require('pg');
var semver = require('semver');
var Base = require('db-migrate-base');
var type;
var log;
var Promise = require('bluebird');

var internals = {};

var PgDriver = Base.extend({
    init: function(connection, schema, intern) {
        this._escapeString = '\'';
        this._super(intern);
        this.internals = intern;
        this.connection = connection;
        this.schema = schema || "public";
        this.connection.connect();
    },

    startMigration: function(cb){

      if(!this.internals.notransactions) {

        return this.runSql('BEGIN;').nodeify(cb);
      }
      else
        return Promise.resolve().nodeify(cb);
    },

    endMigration: function(cb){

      if(!this.internals.notransactions) {

        return this.runSql('COMMIT;').nodeify(cb);
      }
      else
        return Promise.resolve(null).nodeify(cb);
    },

    createColumnDef: function(name, spec, options, tableName) {
        var type = spec.autoIncrement ? '' : this.mapDataType(spec.type);
        var len = spec.length ? util.format('(%s)', spec.length) : '';
        var constraint = this.createColumnConstraint(spec, options, tableName, name);
        if (name.charAt(0) != '"') {
            name = '"' + name + '"';
        }

        return { foreignKey: constraint.foreignKey,
                 constraints: [name, type, len, constraint.constraints].join(' ') };
    },

    mapDataType: function(str) {
        switch(str) {
          case type.STRING:
            return 'VARCHAR';
          case type.DATE_TIME:
            return 'TIMESTAMP';
          case type.BLOB:
            return 'BYTEA';
        }
        return this._super(str);
    },

    createDatabase: function(dbName, options, callback) {

      var spec = '';

      if(typeof(options) === 'function')
        callback = options;

      this.runSql(util.format('CREATE DATABASE %s %s', this.escapeDDL(dbName),
        spec), callback);
    },

    dropDatabase: function(dbName, options, callback) {

      var ifExists = '';

      if(typeof(options) === 'function')
        callback = options;
      else
      {
        ifExists = (options.ifExists === true) ? 'IF EXISTS' : '';
      }

      this.runSql(util.format('DROP DATABASE %s %s', ifExists, this.escapeDDL(dbName)), callback);
    },

    createSequence: function(sqName, options, callback) {

      var spec = '',
          temp = '';

      if(typeof(options) === 'function')
        callback = options;
      else
      {
        temp = (options.temp === true) ? 'TEMP' : '';
      }

      this.runSql(util.format('CREATE %s SEQUENCE `%s` %s', temp, sqName, spec), callback);
    },

    switchDatabase: function(options, callback) {

      if(typeof(options) === 'object')
      {
        if(typeof(options.database) === 'string')
        {
          log.info('Ignore database option, not available with postgres. Use schema instead!');
          this.runSql(util.format('SET search_path TO `%s`', options.database), callback);
        }
      }
      else if(typeof(options) === 'string')
      {
        this.runSql(util.format('SET search_path TO `%s`', options), callback);
      }
      else
        callback(null);
    },

    dropSequence: function(dbName, options, callback) {

      var ifExists = '',
          rule = '';

      if(typeof(options) === 'function')
        callback = options;
      else
      {
        ifExists = (options.ifExists === true) ? 'IF EXISTS' : '';

        if(options.cascade === true)
          rule = 'CASCADE';
        else if(options.restrict === true)
          rule = 'RESTRICT';
      }

      this.runSql(util.format('DROP SEQUENCE %s `%s` %s', ifExists, dbName, rule), callback);
    },

    createMigrationsTable: function(callback) {
      var options = {
        columns: {
          'id': { type: type.INTEGER, notNull: true, primaryKey: true, autoIncrement: true },
          'name': { type: type.STRING, length: 255, notNull: true},
          'run_on': { type: type.DATE_TIME, notNull: true}
        },
        ifNotExists: false
      };

      return this.all('select version() as version')
      .then(function(result) {

        if (result && result && result.length > 0 && result[0].version) {
          var version = result[0].version;
          var match = version.match(/\d+\.\d+\.\d+/);
          if (match && match[0] && semver.gte(match[0], '9.1.0')) {
            options.ifNotExists = true;
          }
        }

        // Get the current search path so we can change the current schema
        // if necessary
        return this.all("SHOW search_path");
      }.bind(this))
      .then(function(result) {

          var searchPath,
              search_pathes = result[0].search_path.split(',');

          for (var i = 0; i < search_pathes.length; ++i) {
            if (search_pathes[i].indexOf('"') !== 0) {
              search_pathes[i] = '"' + search_pathes[i].trim() + '"';
            }
          }

          result[0].search_path = search_pathes.join(',');

          // if the user specified a different schema, prepend it to the
          // search path. This will make all DDL/DML/SQL operate on the specified
          // schema.
          if (this.schema === 'public') {
              searchPath = result[0].search_path;
          } else {
              searchPath = '"' + this.schema + '",' + result[0].search_path;
          }

          return this.all('SET search_path TO ' + searchPath);
        }.bind(this))
        .then(function() {

          return this.all("SELECT table_name FROM information_schema.tables WHERE table_name = '" +
            this.internals.migrationTable + "'" +
            ((this.schema) ?
              " AND table_schema = '" + this.schema + "'" :
              ''));
        }.bind(this))
        .then(function(result) {

          if (result && result && result.length < 1) {
            return this.createTable(this.internals.migrationTable, options);
          } else {
            return Promise.resolve();
          }
        }.bind(this)).nodeify(callback);
    },

    createSeedsTable: function(callback) {
      var options = {
        columns: {
          'id': { type: type.INTEGER, notNull: true, primaryKey: true, autoIncrement: true },
          'name': { type: type.STRING, length: 255, notNull: true},
          'run_on': { type: type.DATE_TIME, notNull: true}
        },
        ifNotExists: false
      };

      return this.all('select version() as version')
      .then(function(result) {

        if (result && result && result.length > 0 && result[0].version) {
          var version = result[0].version;
          var match = version.match(/\d+\.\d+\.\d+/);
          if (match && match[0] && semver.gte(match[0], '9.1.0')) {
            options.ifNotExists = true;
          }
        }

        // Get the current search path so we can change the current schema
        // if necessary
        return this.all("SHOW search_path");
      }.bind(this))
      .then(function(result) {

          var searchPath;

            // if the user specified a different schema, prepend it to the
            // search path. This will make all DDL/DML/SQL operate on the specified
            // schema.
            if (this.schema === 'public') {
                searchPath = result[0].search_path;
            } else {
                searchPath = '"' + this.schema + '",' + result[0].search_path;
            }

          return this.all('SET search_path TO ' + searchPath);
        }.bind(this))
        .then(function() {

            return this.all("SELECT table_name FROM information_schema.tables WHERE table_name = '" +
              this.internals.seedTable + "'" +
              ((this.schema) ?
                " AND table_schema = '" + this.schema + "'" :
                ''));
        }.bind(this))
        .then(function(result) {

          if (result && result && result.length < 1) {
            return this.createTable(this.internals.seedTable, options);
          } else {
            return Promise.resolve();
          }
        }.bind(this)).nodeify(callback);
    },

    createColumnConstraint: function(spec, options, tableName, columnName) {
        var constraint = [],
            cb;

        if (spec.primaryKey && options.emitPrimaryKey) {
            if (spec.autoIncrement) {
                constraint.push('SERIAL');
            }
            constraint.push('PRIMARY KEY');
        }

        if (spec.notNull === true) {
            constraint.push('NOT NULL');
        }

        if (spec.unique) {
            constraint.push('UNIQUE');
        }

        if (spec.defaultValue !== undefined) {
            constraint.push('DEFAULT');
            if (typeof spec.defaultValue == 'string'){
                constraint.push("'" + spec.defaultValue + "'");
            } else {
              constraint.push(spec.defaultValue);
            }
        }

        if (spec.foreignKey) {

          cb = this.bindForeignKey(tableName, columnName, spec.foreignKey);
        }

        return { foreignKey: cb, constraints: constraint.join(' ') };
    },

    renameTable: function(tableName, newTableName, callback) {
        var sql = util.format('ALTER TABLE "%s" RENAME TO "%s"', tableName, newTableName);
        return this.runSql(sql).nodeify(callback);
    },

    removeColumn: function(tableName, columnName, callback) {
        var sql = util.format('ALTER TABLE "%s" DROP COLUMN "%s"', tableName, columnName);

        return this.runSql(sql).nodeify(callback);
    },

    renameColumn: function(tableName, oldColumnName, newColumnName, callback) {
        var sql = util.format('ALTER TABLE "%s" RENAME COLUMN "%s" TO "%s"', tableName, oldColumnName, newColumnName);
        return this.runSql(sql).nodeify(callback);
    },

    changeColumn: function(tableName, columnName, columnSpec, callback) {
      return setNotNull.call(this);

      function setNotNull() {
        var setOrDrop = columnSpec.notNull === true ? 'SET' : 'DROP';
        var sql = util.format('ALTER TABLE "%s" ALTER COLUMN "%s" %s NOT NULL', tableName, columnName, setOrDrop);

        return this.runSql(sql).nodeify(setUnique.bind(this));
      }

      function setUnique(err) {
        if (err) {
          return Promise.reject(err);
        }

        var sql;
        var constraintName = tableName + '_' + columnName + '_key';

        if (columnSpec.unique === true) {
          sql = util.format('ALTER TABLE "%s" ADD CONSTRAINT "%s" UNIQUE ("%s")', tableName, constraintName, columnName);
          return this.runSql(sql).nodeify(setDefaultValue.bind(this));
        } else if (columnSpec.unique === false) {
          sql = util.format('ALTER TABLE "%s" DROP CONSTRAINT "%s"', tableName, constraintName);
          return this.runSql(sql).nodeify(setDefaultValue.bind(this));
        } else {
          return setDefaultValue.call(this);
        }
      }

      function setDefaultValue(err) {
        if (err) {
          return Promise.reject(err).nodeify(callback);
        }

        var sql;

        if (columnSpec.defaultValue !== undefined) {
          var defaultValue = null;
          if (typeof columnSpec.defaultValue == 'string'){
            defaultValue = "'" + columnSpec.defaultValue + "'";
          } else {
            defaultValue = columnSpec.defaultValue;
          }
          sql = util.format('ALTER TABLE "%s" ALTER COLUMN "%s" SET DEFAULT %s', tableName, columnName, defaultValue);
        } else {
          sql = util.format('ALTER TABLE "%s" ALTER COLUMN "%s" DROP DEFAULT', tableName, columnName);
        }
        return this.runSql(sql).then(
          setType.bind(this)
        ).nodeify(callback);
      }

      function setType() {
        if (columnSpec.type !== undefined){
          var using = columnSpec.using !== undefined ?
            columnSpec.using : util.format('USING "%s"::%s', columnName, this.mapDataType(columnSpec.type))
          var sql = util.format('ALTER TABLE "%s" ALTER COLUMN "%s" TYPE %s %s', tableName, columnName, this.mapDataType(columnSpec.type), using);
          return this.runSql(sql);
        }
      }
    },

    addForeignKey: function(tableName, referencedTableName, keyName, fieldMapping, rules, callback) {
      if(arguments.length === 5 && typeof(rules) === 'function') {
        callback = rules;
        rules = {};
      }
      var columns = Object.keys(fieldMapping);
      var referencedColumns = columns.map(function (key) { return '"' + fieldMapping[key] + '"'; });
      var sql = util.format('ALTER TABLE "%s" ADD CONSTRAINT "%s" FOREIGN KEY (%s) REFERENCES "%s" (%s) ON DELETE %s ON UPDATE %s',
        tableName, keyName, this.quoteDDLArr(columns), referencedTableName, referencedColumns, rules.onDelete || 'NO ACTION', rules.onUpdate || 'NO ACTION');
      return this.runSql(sql).nodeify(callback);
    },

    removeForeignKey: function(tableName, keyName, callback) {
      var sql = util.format('ALTER TABLE "%s" DROP CONSTRAINT "%s"', tableName, keyName);
      return this.runSql(sql).nodeify(callback);
    },

    insert: function() {

      var index = 1;

      if( arguments.length > 3 ) {

        index = 2;
      }

      arguments[index] = arguments[index].map(function(value) {
        return 'string' === typeof value ? value : JSON.stringify(value);
      });

      return this._super.apply(this, arguments);
    },

    runSql: function() {
        var callback,
            minLength = 1;

        if(typeof(arguments[arguments.length - 1]) === 'function')
        {
          minLength = 2;
          callback = arguments[arguments.length - 1];
        }

        params = arguments;
        if (params.length > minLength){
            // We have parameters, but db-migrate uses "?" for param substitutions.
            // PG uses "$1", "$2", etc so fix up the "?" into "$1", etc
            var param = params[0].split('?'),
                new_param = [];
            for (var i = 0; i < param.length-1; i++){
                new_param.push(param[i], "$" + (i+1));
            }
            new_param.push(param[param.length-1]);
            params[0] = new_param.join('');
        }

        log.sql.apply(null, params);
        if(this.internals.dryRun) {
          return Promise.resolve().nodeify(callback);
        }

        return new Promise(function(resolve, reject) {
          var prCB = function(err, data) {
            return (err ? reject(err) : resolve(data));
          };

          if( minLength === 2 )
            params[params.length - 1] = prCB;
          else
            params[params.length++] = prCB;

          this.connection.query.apply(this.connection, params);
        }.bind(this)).nodeify(callback);
    },

    all: function() {
        params = arguments;

        log.sql.apply(null, params);

        return new Promise(function(resolve, reject) {
          var prCB = function(err, data) {
            return (err ? reject(err) : resolve(data));
          };

          this.connection.query.apply(this.connection, [params[0], function(err, result){
            prCB(err, (result) ? result.rows : result);
          }]);

        }.bind(this)).nodeify(params[1]);
    },

    close: function(callback) {
        this.connection.end();
        if( typeof(callback) === 'function' )
          return Promise.resolve().nodeify(callback);
        else
          return Promise.resolve();
    }

});

Promise.promisifyAll(PgDriver);

exports.connect = function(config, intern, callback) {

    internals = intern;

    log = intern.mod.log;
    type = intern.mod.type;

    if (config.native) { pg = pg.native; }
    var db = config.db || new pg.Client(config);
    callback(null, new PgDriver(db, config.schema, intern));
};
<|endoftext|>


<commit_before>'use strict'

const requiredGrpc = require('grpc')
const express = require('express')

const supportedMethods = ['get', 'put', 'post', 'delete', 'patch'] // supported HTTP methods
const paramRegex = /{(\w+)}/g // regex to find gRPC params in url

/**
 * generate middleware to proxy to gRPC defined by proto files
 * @param  {string[]} protoFiles Filenames of protobuf-file
 * @param  {string} grpcLocation HOST:PORT of gRPC server
 * @param  {ChannelCredentials}  gRPC credential context (default: grpc.credentials.createInsecure())
 * @param  {string} include      Path to find all includes
 * @return {Function}            Middleware
 */
const middleware = (protoFiles, grpcLocation, credentials, debug, include, grpc) => {
  grpc = grpc || requiredGrpc
  credentials = credentials || grpc.credentials.createInsecure()
  const clients = {}
  const router = express.Router()
  protoFiles.forEach(p => {
    const proto = include ? grpc.load({file: p, root: include}) : grpc.load(p)
    Object.keys(proto).forEach(pkg => {
      clients[pkg] = clients[pkg] || {}
      Object.keys(proto[pkg]).forEach(svc => {
        if (proto[pkg][svc].service && proto[pkg][svc].service.children.length) {
          clients[pkg][svc] = new proto[pkg][svc](grpcLocation, credentials)
          proto[pkg][svc].service.children
            .filter(child => child.className === 'Service.RPCMethod' && child.options)
            .forEach(child => {
              // TODO: PRIORITY:LOW - handle child.options.additional_bindings
              supportedMethods.forEach(httpMethod => {
                if (typeof child.options[`(google.api.http).${httpMethod}`] !== 'undefined') {
                  if (debug) {
                    console.log(httpMethod.toUpperCase(), child.options[`(google.api.http).${httpMethod}`], ':', `${pkg}.${svc}.${child.name}(${child.requestName})`, '→', child.responseName)
                  }
                  router[httpMethod](convertUrl(child.options[`(google.api.http).${httpMethod}`]), (req, res) => {
                    const params = convertParams(req, child.options[`(google.api.http).${httpMethod}`])
                    const meta = convertHeaders(req.headers, grpc)
                    if (debug) {
                      console.log(`${pkg}.${svc}.${child.name}(${JSON.stringify(params)})`)
                    }
                    clients[pkg][svc][child.name](params, meta, (err, ans) => {
                      // TODO: PRIORITY:MEDIUM - improve error-handling
                      // TODO: PRIORITY:HIGH - double-check JSON mapping is identical to grpc-gateway
                      if (err) {
                        console.error(err.message)
                        return res.status(500).json({code: err.code, message: err.message})
                      }
                      res.json(convertBody(ans, child.options['(google.api.http).body'], child.options[`(google.api.http).${httpMethod}`]))
                    })
                  })
                }
              })
            })
        }
      })
    })
  })
  return router
}

/**
 * Parse express request into params for grpc client
 * @param  {Request} req Express request object
 * @param  {string} url  gRPC url field (ie "/v1/hi/{name}")
 * @return {Object}      params for gRPC client
 */
const convertParams = (req, url) => {
  const gparams = getParamsList(url)
  const out = req.body
  gparams.forEach(p => { out[p] = req.params[p] })
  return out
}

/**
 * Convert gRPC URL expression into express
 * @param  {string} url gRPC URL expression
 * @return {string}     express URL expression
 */
const convertUrl = (url) => (
  // TODO: PRIORITY:LOW - use types to generate regex for numbers & strings in params
  url.replace(paramRegex, ':$1?')
)

/**
 * Convert gRPC response to output, based on gRPC body field
 * @param  {Object} value   gRPC response object
 * @param  {string} bodyMap gRPC body field
 * @return {mixed}          mapped output for `res.send()`
 */
const convertBody = (value, bodyMap) => {
  bodyMap = bodyMap || '*'
  if (bodyMap === '*') {
    return value
  } else {
    return value[bodyMap]
  }
}

/**
 * Get a list of params from a gRPC URL
 * @param  {string} url gRPC URL
 * @return {string[]}   Array of params
 */
const getParamsList = (url) => {
  const out = []
  let m
  while ((m = paramRegex.exec(url)) !== null) {
    if (m.index === paramRegex.lastIndex) {
      paramRegex.lastIndex++
    }
    out.push(m[1])
  }
  return out
}

/**
 * Convert headers into gRPC meta
 * @param  {object} headers Headers: {name: value}
 * @return {meta}           grpc meta object
 */
const convertHeaders = (headers, grpc) => {
  grpc = grpc || requiredGrpc
  headers = headers || {}
  const metadata = new grpc.Metadata()
  Object.keys(headers).forEach(h => { metadata.set(h, headers[h]) })
  return metadata
}

// interface
module.exports = middleware
module.exports.convertParams = convertParams
module.exports.convertUrl = convertUrl
module.exports.convertBody = convertBody
module.exports.getParamsList = getParamsList
module.exports.convertHeaders = convertHeaders
<commit_msg>add support for query<commit_after>'use strict'

const requiredGrpc = require('grpc')
const express = require('express')

const supportedMethods = ['get', 'put', 'post', 'delete', 'patch'] // supported HTTP methods
const paramRegex = /{(\w+)}/g // regex to find gRPC params in url

/**
 * generate middleware to proxy to gRPC defined by proto files
 * @param  {string[]} protoFiles Filenames of protobuf-file
 * @param  {string} grpcLocation HOST:PORT of gRPC server
 * @param  {ChannelCredentials}  gRPC credential context (default: grpc.credentials.createInsecure())
 * @param  {string} include      Path to find all includes
 * @return {Function}            Middleware
 */
const middleware = (protoFiles, grpcLocation, credentials, debug, include, grpc) => {
  grpc = grpc || requiredGrpc
  credentials = credentials || grpc.credentials.createInsecure()
  const clients = {}
  const router = express.Router()
  protoFiles.forEach(p => {
    const proto = include ? grpc.load({file: p, root: include}) : grpc.load(p)
    Object.keys(proto).forEach(pkg => {
      clients[pkg] = clients[pkg] || {}
      Object.keys(proto[pkg]).forEach(svc => {
        if (proto[pkg][svc].service && proto[pkg][svc].service.children.length) {
          clients[pkg][svc] = new proto[pkg][svc](grpcLocation, credentials)
          proto[pkg][svc].service.children
            .filter(child => child.className === 'Service.RPCMethod' && child.options)
            .forEach(child => {
              // TODO: PRIORITY:LOW - handle child.options.additional_bindings
              supportedMethods.forEach(httpMethod => {
                if (typeof child.options[`(google.api.http).${httpMethod}`] !== 'undefined') {
                  if (debug) {
                    console.log(httpMethod.toUpperCase(), child.options[`(google.api.http).${httpMethod}`], ':', `${pkg}.${svc}.${child.name}(${child.requestName})`, '→', child.responseName)
                  }
                  router[httpMethod](convertUrl(child.options[`(google.api.http).${httpMethod}`]), (req, res) => {
                    const params = convertParams(req, child.options[`(google.api.http).${httpMethod}`])
                    const meta = convertHeaders(req.headers, grpc)
                    if (debug) {
                      console.log(`${pkg}.${svc}.${child.name}(${JSON.stringify(params)})`)
                    }
                    clients[pkg][svc][child.name](params, meta, (err, ans) => {
                      // TODO: PRIORITY:MEDIUM - improve error-handling
                      // TODO: PRIORITY:HIGH - double-check JSON mapping is identical to grpc-gateway
                      if (err) {
                        console.error(err.message)
                        return res.status(500).json({code: err.code, message: err.message})
                      }
                      res.json(convertBody(ans, child.options['(google.api.http).body'], child.options[`(google.api.http).${httpMethod}`]))
                    })
                  })
                }
              })
            })
        }
      })
    })
  })
  return router
}

/**
 * Parse express request params & query into params for grpc client
 * @param  {Request} req Express request object
 * @param  {string} url  gRPC url field (ie "/v1/hi/{name}")
 * @return {Object}      params for gRPC client
 */
const convertParams = (req, url) => {
  const gparams = getParamsList(url)
  const out = req.body
  gparams.forEach(p => {
    if (req.query && req.query[p]) {
      out[p] = req.query[p]
    }
    if (req.params && req.params[p]) {
      out[p] = req.params[p]
    }
  })
  return out
}

/**
 * Convert gRPC URL expression into express
 * @param  {string} url gRPC URL expression
 * @return {string}     express URL expression
 */
const convertUrl = (url) => (
  // TODO: PRIORITY:LOW - use types to generate regex for numbers & strings in params
  url.replace(paramRegex, ':$1?')
)

/**
 * Convert gRPC response to output, based on gRPC body field
 * @param  {Object} value   gRPC response object
 * @param  {string} bodyMap gRPC body field
 * @return {mixed}          mapped output for `res.send()`
 */
const convertBody = (value, bodyMap) => {
  bodyMap = bodyMap || '*'
  if (bodyMap === '*') {
    return value
  } else {
    return value[bodyMap]
  }
}

/**
 * Get a list of params from a gRPC URL
 * @param  {string} url gRPC URL
 * @return {string[]}   Array of params
 */
const getParamsList = (url) => {
  const out = []
  let m
  while ((m = paramRegex.exec(url)) !== null) {
    if (m.index === paramRegex.lastIndex) {
      paramRegex.lastIndex++
    }
    out.push(m[1])
  }
  return out
}

/**
 * Convert headers into gRPC meta
 * @param  {object} headers Headers: {name: value}
 * @return {meta}           grpc meta object
 */
const convertHeaders = (headers, grpc) => {
  grpc = grpc || requiredGrpc
  headers = headers || {}
  const metadata = new grpc.Metadata()
  Object.keys(headers).forEach(h => { metadata.set(h, headers[h]) })
  return metadata
}

// interface
module.exports = middleware
module.exports.convertParams = convertParams
module.exports.convertUrl = convertUrl
module.exports.convertBody = convertBody
module.exports.getParamsList = getParamsList
module.exports.convertHeaders = convertHeaders
<|endoftext|>


<commit_before>var crypto = require('crypto'),
bignum = require('bignum');

/**
 * This module provides native bindings to ecdsa [secp256k1](https://github.com/bitcoin/secp256k1) functions
 * @module secp256k1
 */

var secpNode = require('bindings')('secp256k1');

/**
 * Verify an ECDSA secret key.
 * @method verifySecetKey
 * @param {Buffer} sercetKey the sercet Key to verify
 * @return {Boolean}  `true` if sercet key is valid, `false` sercet key is invalid
 */
exports.verifySecretKey = function(sercetKey){
  return Boolean(secpNode.secKeyVerify(sercetKey));
};

/**
 * Verify an ECDSA public key.
 * @method verifyPublicKey
 * @param {Buffer} publicKey the public Key to verify
 * @return {Boolean} `true` if public key is valid, `false` sercet key is invalid
 */
exports.verifyPublicKey = function(publicKey){
  return Boolean(secpNode.pubKeyVerify(publicKey));
};

/**
 * Create an ECDSA signature.
 * @method sign
 * @param  {Buffer} secretkey a 32-byte secret key (assumed to be valid)
 * @param {Buffer} msg he message being signed
 * @param {Function} cb the callback given. The callback is given the signature
 * @returns {Buffer} if no callback is given a 72-byte signature is returned
 */
exports.sign = function(secretKey, msg, cb){
  if(cb){
    secpNode.signAsync(secretKey, msg, cb);
  }else{
    return secpNode.sign(secretKey, msg);
  }
};

/**
 * Create a compact ECDSA signature (64 byte + recovery id). Runs asyncously
 * if given a callback
 * @method signCompact
 * @param {Buffer} sercetKey a 32-byte secret key (assumed to be valid)
 * @param {Buffer} msg the message being signed
 * @param {Function} [cb] the callback which is give `err`, `sig` the
 *    - param {Buffer} sig  a 64-byte buffer repersenting the signature
 *    - param {Number} recid an int which is the recovery id.
 * @return {Object} result only if no callback is given will the result be returned
 *    - result.sigature
 *    - result.r
 *    - result.s
 *    - result.recoveryID
 */
exports.signCompact = function(secretKey, msg, cb){

  if(cb){
    secpNode.signCompactAsync(secretKey, msg, cb);
  }else{
    var array = secpNode.signCompact(secretKey, msg);
    return {
      recoveryId: array[1],
      signature: array[2],
      r: array[2].slice(0, 32),
      s: array[2].slice(32, 64)
    };
  }
};

/**
 * Verify an ECDSA signature.
 * @method verify
 * @param {Buffer} pubKey the public key
 * @param {Buffer} mgs the message
 * @param {Buffer} sig the signature
 * @return {Integer}
 *
 *    - 1: correct signature
 *    - 0: incorrect signature
 *    - -1: invalid public key
 *    - -2: invalid signature
 */
exports.verify = function(pubKey, msg, sig, cb){
  if(cb){
    secpNode.verifyAsync(pubKey, msg, sig, cb);
  }else{
    return secpNode.verify(pubKey, msg, sig);
  }
};

/**
 * Recover an ECDSA public key from a compact signature. In the process also verifing it.
 * @method recoverCompact
 * @param {Buffer} msg the message assumed to be signed
 * @param {Buffer} sig the signature as 64 byte buffer
 * @param {Integer} recid the recovery id (as returned by ecdsa_sign_compact)
 * @param {Boolean} compressed whether to recover a compressed or uncompressed pubkey
 * @param {Function} [cb]
 * @return {Buffer} the pubkey, a 33 or 65 byte buffer
 */
exports.recoverCompact = function(msg, sig, recid, compressed, cb){

  compressed = compressed ? 1 : 0;

  if(!cb){
    return secpNode.recoverCompact(msg, sig, compressed, recid);
  }else{
    secpNode.recoverCompactAsync(msg, sig, compressed, recid, cb);
  }
};

/**
 * Compute the public key for a secret key.
 * @method createPubKey
 * @param {Buffer} secKey a 32-byte private key.
 * @param {Boolean} [compressed=0] whether the computed public key should be compressed
 * @return {Buffer} a 33-byte (if compressed) or 65-byte (if uncompressed) area to store the public key.
 */
exports.createPublicKey = function(secKey, compressed){
  compressed = compressed ? 1 : 0;
  return secpNode.pubKeyCreate(secKey, compressed);
};

/**
 * @method exportPrivateKey
 * @param {Buffer} secertKey
 * @param {Boolean} compressed
 * @return {Buffer} privateKey
 */
exports.exportPrivateKey = secpNode.privKeyExport;

/**
 * @method importPrivateKey
 * @param {Buffer} privateKey
 * @return {Buffer} secertKey
 */
exports.importPrivateKey = secpNode.privKeyImport;

/**
 * @method decompressPublickey
 * @param {Buffer} secretKey
 * @return {Buffer}
 */
exports.decompressPublicKey = secpNode.pubKeyDecompress;

/**
 * deteministic Generation of k
 * @method detereministicGenerateK
 * @param {Buffer} h1 the hash of the message
 * @param {Buffer} x the private key
 */
exports.deterministicGenerateK  = function(h1, x){

  var k = new Buffer(32);
  var v = new Buffer(32);
  //step b
  v.fill(1);
  //step c
  k.fill(0);

  //step d
  var hash = crypto.createHmac('sha256', k);
  hash.update(Buffer.concat([v, new Buffer([0]), x, h1]));
  k = hash.digest();

  //step e
  hash = crypto.createHmac('sha256', k);
  hash.update(v);
  v = hash.digest();

  //step f
  hash = crypto.createHmac('sha256', k);
  hash.update(Buffer.concat([v, new Buffer([1]), x, h1]));
  k = hash.digest();

  //step g
  hash = crypto.createHmac('sha256', k);
  hash.update(v);
  v = hash.digest();

  //step h
  hash = crypto.createHmac('sha256', k);
  hash.update(v);
  v = hash.digest();

  return v;
};
<commit_msg>fix CI: bignum not needed (yet)<commit_after>var crypto = require('crypto');

/**
 * This module provides native bindings to ecdsa [secp256k1](https://github.com/bitcoin/secp256k1) functions
 * @module secp256k1
 */

var secpNode = require('bindings')('secp256k1');

/**
 * Verify an ECDSA secret key.
 * @method verifySecetKey
 * @param {Buffer} sercetKey the sercet Key to verify
 * @return {Boolean}  `true` if sercet key is valid, `false` sercet key is invalid
 */
exports.verifySecretKey = function(sercetKey){
  return Boolean(secpNode.secKeyVerify(sercetKey));
};

/**
 * Verify an ECDSA public key.
 * @method verifyPublicKey
 * @param {Buffer} publicKey the public Key to verify
 * @return {Boolean} `true` if public key is valid, `false` sercet key is invalid
 */
exports.verifyPublicKey = function(publicKey){
  return Boolean(secpNode.pubKeyVerify(publicKey));
};

/**
 * Create an ECDSA signature.
 * @method sign
 * @param  {Buffer} secretkey a 32-byte secret key (assumed to be valid)
 * @param {Buffer} msg he message being signed
 * @param {Function} cb the callback given. The callback is given the signature
 * @returns {Buffer} if no callback is given a 72-byte signature is returned
 */
exports.sign = function(secretKey, msg, cb){
  if(cb){
    secpNode.signAsync(secretKey, msg, cb);
  }else{
    return secpNode.sign(secretKey, msg);
  }
};

/**
 * Create a compact ECDSA signature (64 byte + recovery id). Runs asyncously
 * if given a callback
 * @method signCompact
 * @param {Buffer} sercetKey a 32-byte secret key (assumed to be valid)
 * @param {Buffer} msg the message being signed
 * @param {Function} [cb] the callback which is give `err`, `sig` the
 *    - param {Buffer} sig  a 64-byte buffer repersenting the signature
 *    - param {Number} recid an int which is the recovery id.
 * @return {Object} result only if no callback is given will the result be returned
 *    - result.sigature
 *    - result.r
 *    - result.s
 *    - result.recoveryID
 */
exports.signCompact = function(secretKey, msg, cb){

  if(cb){
    secpNode.signCompactAsync(secretKey, msg, cb);
  }else{
    var array = secpNode.signCompact(secretKey, msg);
    return {
      recoveryId: array[1],
      signature: array[2],
      r: array[2].slice(0, 32),
      s: array[2].slice(32, 64)
    };
  }
};

/**
 * Verify an ECDSA signature.
 * @method verify
 * @param {Buffer} pubKey the public key
 * @param {Buffer} mgs the message
 * @param {Buffer} sig the signature
 * @return {Integer}
 *
 *    - 1: correct signature
 *    - 0: incorrect signature
 *    - -1: invalid public key
 *    - -2: invalid signature
 */
exports.verify = function(pubKey, msg, sig, cb){
  if(cb){
    secpNode.verifyAsync(pubKey, msg, sig, cb);
  }else{
    return secpNode.verify(pubKey, msg, sig);
  }
};

/**
 * Recover an ECDSA public key from a compact signature. In the process also verifing it.
 * @method recoverCompact
 * @param {Buffer} msg the message assumed to be signed
 * @param {Buffer} sig the signature as 64 byte buffer
 * @param {Integer} recid the recovery id (as returned by ecdsa_sign_compact)
 * @param {Boolean} compressed whether to recover a compressed or uncompressed pubkey
 * @param {Function} [cb]
 * @return {Buffer} the pubkey, a 33 or 65 byte buffer
 */
exports.recoverCompact = function(msg, sig, recid, compressed, cb){

  compressed = compressed ? 1 : 0;

  if(!cb){
    return secpNode.recoverCompact(msg, sig, compressed, recid);
  }else{
    secpNode.recoverCompactAsync(msg, sig, compressed, recid, cb);
  }
};

/**
 * Compute the public key for a secret key.
 * @method createPubKey
 * @param {Buffer} secKey a 32-byte private key.
 * @param {Boolean} [compressed=0] whether the computed public key should be compressed
 * @return {Buffer} a 33-byte (if compressed) or 65-byte (if uncompressed) area to store the public key.
 */
exports.createPublicKey = function(secKey, compressed){
  compressed = compressed ? 1 : 0;
  return secpNode.pubKeyCreate(secKey, compressed);
};

/**
 * @method exportPrivateKey
 * @param {Buffer} secertKey
 * @param {Boolean} compressed
 * @return {Buffer} privateKey
 */
exports.exportPrivateKey = secpNode.privKeyExport;

/**
 * @method importPrivateKey
 * @param {Buffer} privateKey
 * @return {Buffer} secertKey
 */
exports.importPrivateKey = secpNode.privKeyImport;

/**
 * @method decompressPublickey
 * @param {Buffer} secretKey
 * @return {Buffer}
 */
exports.decompressPublicKey = secpNode.pubKeyDecompress;

/**
 * deteministic Generation of k
 * @method detereministicGenerateK
 * @param {Buffer} h1 the hash of the message
 * @param {Buffer} x the private key
 */
exports.deterministicGenerateK  = function(h1, x){

  var k = new Buffer(32);
  var v = new Buffer(32);
  //step b
  v.fill(1);
  //step c
  k.fill(0);

  //step d
  var hash = crypto.createHmac('sha256', k);
  hash.update(Buffer.concat([v, new Buffer([0]), x, h1]));
  k = hash.digest();

  //step e
  hash = crypto.createHmac('sha256', k);
  hash.update(v);
  v = hash.digest();

  //step f
  hash = crypto.createHmac('sha256', k);
  hash.update(Buffer.concat([v, new Buffer([1]), x, h1]));
  k = hash.digest();

  //step g
  hash = crypto.createHmac('sha256', k);
  hash.update(v);
  v = hash.digest();

  //step h
  hash = crypto.createHmac('sha256', k);
  hash.update(v);
  v = hash.digest();

  return v;
};
<|endoftext|>


<commit_before>module.exports = {
  baseKonnector: require('./base_konnector'),
  cozyClient: require('./cozyclient'),
  fetcher: require('./fetcher'),
  filterExisting: require('./filter_existing'),
  log: require('./logger')
  manifest: require('./manifest'),
  naming: require('./naming'),
  saveDataAndFile: require('./save_data_and_file'),
  updateOrCreate: require('./update_or_create'),
  linkBankOperation: require('./link_bank_operation'),
  models: {
    baseModel: require('./models/base_model'),
    bill: require('./models/bill'),
    file: require('./models/file'),
    folder: require('./models/folder')
  }
}
<commit_msg>fix: bad format in index.js<commit_after>module.exports = {
  baseKonnector: require('./base_konnector'),
  cozyClient: require('./cozyclient'),
  fetcher: require('./fetcher'),
  filterExisting: require('./filter_existing'),
  log: require('./logger'),
  manifest: require('./manifest'),
  naming: require('./naming'),
  saveDataAndFile: require('./save_data_and_file'),
  updateOrCreate: require('./update_or_create'),
  linkBankOperation: require('./link_bank_operation'),
  models: {
    baseModel: require('./models/base_model'),
    bill: require('./models/bill'),
    file: require('./models/file'),
    folder: require('./models/folder')
  }
}
<|endoftext|>


<commit_before>const version = 2.0
console.log('talkback version ' + version)

const loudness = require('loudness')
const talkback = require('./modules/talkback')
const fs = require('fs')
const say = require('say')
const tts = require('./modules/tts')
const erds = require('./modules/erds')
const enums = require('./modules/enumerations')
const messages = require('./modules/messages')
talkback.start()

// Only works on Raspberry Pi
fs.readFile('/proc/cpuinfo', function(err, data) {
  if (data.toString().indexOf('BCM2709') !== -1 || data.toString().indexOf('BCM2708') !== -1) {
    const GPIO_PATH = '/sys/class/gpio'
    setInterval(function() {
      talkback.appliances.map(function(appliance) {
        fs.readFile(GPIO_PATH + '/gpio' + appliance.pinNo + '/value', function(err, data) {
          if (err) throw err
          if (data == 0) {
            if (!appliance.buttonPressed) {
              if (appliance.name === 'dryer') {
                tts.speak(messages[talkback.lang][erds.DRY_TEMP].replace('%1', appliance.dryTemp)+ ',' + messages[talkback.lang]['timeLeft'].replace('%1', appliance.timeInMins).replace('%2', appliance.name), talkback.lang)
              } else if (appliance.name === 'washer') {
                let spinLevelMessage = messages[talkback.lang][erds.SPIN_LEVEL].replace('%1', appliance.spinLevel)
                let soilLevelMessage = messages[talkback.lang][erds.SOIL_LEVEL].replace('%1', appliance.soilLevel)
                let waterTempMessage = messages[talkback.lang][erds.WATER_TEMP].replace('%1', appliance.waterTemp)
                tts.speak(spinLevelMessage + ',' + soilLevelMessage + ',' + waterTempMessage + ',' + messages[talkback.lang]["timeLeft"].replace('%1', appliance.timeInMins).replace('%2', appliance.name), talkback.lang)
              }
            }
            appliance.buttonPressed = true
          } else {
            appliance.buttonPressed = false
          }
        })
      })
    })

    // Volume encoder wheel map
    var encodings = {
      "0101": 1,
      "0100": 2,
      "0000": 3,
      "0001": 4,
      "0011": 5,
      "0010": 6,
      "0110": 7,
      "0111": 8,
      "1111": 9,
      "1110": 10,
      "1010": 11,
      "1011": 12,
      "1001": 13,
      "1000": 14,
      "1100": 15,
      "1101": 16
    }

    // Read Volume Encoder
    setInterval(function() {
      var regex = /\n$/
      var pin1 = fs.readFileSync(GPIO_PATH + '/gpio26/value').toString().replace(regex, '')
      var pin2 = fs.readFileSync(GPIO_PATH + '/gpio13/value').toString().replace(regex, '')
      var pin3 = fs.readFileSync(GPIO_PATH + '/gpio6/value').toString().replace(regex, '')
      var pin4 = fs.readFileSync(GPIO_PATH + '/gpio27/value').toString().replace(regex, '')
      var num = pin1.concat(pin2).concat(pin3).concat(pin4)
      loudness.setVolume(90 - encodings[num], function(err) {
        if (err) throw err
      })
    }, 100)
    setInterval(function() {
      var pin = fs.readFileSync(GPIO_PATH + '/gpio22/value').toString().replace(/\n$/, '')
      var langs = ['en', 'es']
      //talkback.lang = langs[(langs.indexOf(talkback.lang) + 1) % langs.length]
    }, 100)
  }

})
<commit_msg>Slowed down speaking for all settings<commit_after>const version = 2.0
console.log('talkback version ' + version)

const loudness = require('loudness')
const talkback = require('./modules/talkback')
const fs = require('fs')
const say = require('say')
const tts = require('./modules/tts')
const erds = require('./modules/erds')
const enums = require('./modules/enumerations')
const messages = require('./modules/messages')
talkback.start()

// Only works on Raspberry Pi
fs.readFile('/proc/cpuinfo', function(err, data) {
  if (data.toString().indexOf('BCM2709') !== -1 || data.toString().indexOf('BCM2708') !== -1) {
    const GPIO_PATH = '/sys/class/gpio'
    setInterval(function() {
      talkback.appliances.map(function(appliance) {
        fs.readFile(GPIO_PATH + '/gpio' + appliance.pinNo + '/value', function(err, data) {
          if (err) throw err
          if (data == 0) {
            if (!appliance.buttonPressed) {
              if (appliance.name === 'dryer') {
                tts.speak(messages[talkback.lang][erds.DRY_TEMP].replace('%1', appliance.dryTemp)+ ' , ' + messages[talkback.lang]['timeLeft'].replace('%1', appliance.timeInMins).replace('%2', appliance.name), talkback.lang)
              } else if (appliance.name === 'washer') {
                let spinLevelMessage = messages[talkback.lang][erds.SPIN_LEVEL].replace('%1', appliance.spinLevel)
                let soilLevelMessage = messages[talkback.lang][erds.SOIL_LEVEL].replace('%1', appliance.soilLevel)
                let waterTempMessage = messages[talkback.lang][erds.WATER_TEMP].replace('%1', appliance.waterTemp)
                tts.speak(spinLevelMessage + ' , ' + soilLevelMessage + ' , ' + waterTempMessage + ' , ' + messages[talkback.lang]["timeLeft"].replace('%1', appliance.timeInMins).replace('%2', appliance.name), talkback.lang)
              }
            }
            appliance.buttonPressed = true
          } else {
            appliance.buttonPressed = false
          }
        })
      })
    })

    // Volume encoder wheel map
    var encodings = {
      "0101": 1,
      "0100": 2,
      "0000": 3,
      "0001": 4,
      "0011": 5,
      "0010": 6,
      "0110": 7,
      "0111": 8,
      "1111": 9,
      "1110": 10,
      "1010": 11,
      "1011": 12,
      "1001": 13,
      "1000": 14,
      "1100": 15,
      "1101": 16
    }

    // Read Volume Encoder
    setInterval(function() {
      var regex = /\n$/
      var pin1 = fs.readFileSync(GPIO_PATH + '/gpio26/value').toString().replace(regex, '')
      var pin2 = fs.readFileSync(GPIO_PATH + '/gpio13/value').toString().replace(regex, '')
      var pin3 = fs.readFileSync(GPIO_PATH + '/gpio6/value').toString().replace(regex, '')
      var pin4 = fs.readFileSync(GPIO_PATH + '/gpio27/value').toString().replace(regex, '')
      var num = pin1.concat(pin2).concat(pin3).concat(pin4)
      loudness.setVolume(90 - encodings[num], function(err) {
        if (err) throw err
      })
    }, 100)
    setInterval(function() {
      var pin = fs.readFileSync(GPIO_PATH + '/gpio22/value').toString().replace(/\n$/, '')
      var langs = ['en', 'es']
      //talkback.lang = langs[(langs.indexOf(talkback.lang) + 1) % langs.length]
    }, 100)
  }

})
<|endoftext|>


<commit_before>$(function(){

	var touchStartX = 0;
	var touchStartY = 0;

	var animationEndVendors = "webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend";
	var viewport = getViewport();

	$("html, body").css("min-width", viewport.width * 3);

	$(".page").css("width", viewport.width);
	$(".page").css("height", viewport.height);
	// $(".page").css("overflow-y", "auto");

	$(".page").each(function(){

		if($(this).height() > viewport.height) {
			$(this).addClass("scrollable");
		}

	});

	$(".hollow.secondary").on("click", function(e){

		e.preventDefault();

		$("#testInput").css("-webkit-animation-duration", "0.5s");
		$("#testInput").css("-webkit-animation-delay", "0s");
		$("#testInput").addClass("animated fadeInUp").one(animationEndVendors, function() {
			$(this).removeClass("animated fadeInUp");
		});

	});

	$(document).on('touchstart', function(e){
		if($(e.target).parents("#projectDetails")[0]) {
			touchStartX = e.originalEvent.touches[0].pageX;
			touchStartY = e.originalEvent.touches[0].pageY;
		}
	});

	$(document).on('touchmove', function(e) {
		// e.preventDefault();
	    if ($(e.target).parents('#projectDetails')[0] ) {

	    	if(Math.abs(touchStartX - e.originalEvent.touches[0].pageX)
	    		> Math.abs(touchStartY - e.originalEvent.touches[0].pageY)) {
	    		e.preventDefault();
	    	}

	   //  	if(e.originalEvent.touches[0].pageY - lastY > 0) {
	   //  		$("#projectDetails").scrollTop($("#projectDetails").scrollTop() - 15);
	   //  	} else {
	   //  		$("#projectDetails").scrollTop($("#projectDetails").scrollTop() + 15);
	   //  	}

	   //  	// if(e.originalEvent.touches[0].pageY - lastY > 0) {
	   //  	// 	$("#projectDetails").scrollTop($("#projectDetails").scrollTop() - (e.originalEvent.touches[0].pageY + lastY));
	   //  	// } else {
	   //  	// 	$("#projectDetails").scrollTop($("#projectDetails").scrollTop() + (e.originalEvent.touches[0].pageY - lastY));
	   //  	// }
	   // //  	if(Math.abs(e.timeStamp - lastY_timestamp) < 200) {
    // // 		 	$("#projectDetails").scrollTop($("#projectDetails").scrollTop() - (e.originalEvent.touches[0].pageY - lastY));
	   // //  	}
	   // //  	else if(Math.abs(e.timeStamp - lastY_timestamp) < 1000) {
				// // if(e.originalEvent.touches[0].pageY - lastY > 0) {
		  // //   		$("#projectDetails").scrollTop($("#projectDetails").scrollTop() - 25);
		  // //   	}
		  // //   	else if(e.originalEvent.touches[0].pageY - lastY < 0) {
		  // //   		$("#projectDetails").scrollTop($("#projectDetails").scrollTop() + 25);
		  // //   	}
	   // //  	}

	   //  	lastY = e.originalEvent.touches[0].pageY;
	   //  	// lastY_timestamp = e.timeStamp;
	    } else {
	    	e.preventDefault();
	    }
	});

	$(".nextPage").on("click", function(e) {

		e.preventDefault();

		$("html, body").animate({
			scrollLeft: $($(this).attr("href")).offset().left
		}, 1000);

	});

	$(".previousPage").on("click", function(e){

		e.preventDefault();

		$("html, body").animate({
			scrollLeft: $($(this).attr("href")).offset().left
		}, 1000);

	});

	$(".seeMore").on("click", function(e){

		e.preventDefault();

		$("html, body").animate({
			scrollTop: $($(this).attr("href")).offset().top
		}, 1000);

	});

	$(".seeLess").on("click", function(e){

		e.preventDefault();

		$("html, body").animate({
			scrollTop: $($(this).attr("href")).offset().top
		}, 1000);

	});

});

function getViewport() {
    var container = window, property = "inner";
    if (!("innerWidth" in window )) {
       property = "client";
       container = document.documentElement || document.body;
    }
    return { width : container[property + "Width"], height : container[property + "Height"]};
}<commit_msg>jkljlk<commit_after>$(function(){

	var touchStartX = 0;
	var touchStartY = 0;

	var animationEndVendors = "webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend";
	var viewport = getViewport();

	$("html, body").css("min-width", viewport.width * 3);

	$(".page").css("width", viewport.width);
	$(".page").css("height", viewport.height);
	// $(".page").css("overflow-y", "auto");

	$(".page").each(function(){

		if($(this).height() > viewport.height) {
			$(this).addClass("scrollable");
		}

	});

	$(".hollow.secondary").on("click", function(e){

		e.preventDefault();

		$("#testInput").css("-webkit-animation-duration", "0.5s");
		$("#testInput").css("-webkit-animation-delay", "0s");
		$("#testInput").addClass("animated fadeInUp").one(animationEndVendors, function() {
			$(this).removeClass("animated fadeInUp");
		});

	});

	$(document).on('touchstart', function(e){
		if($(e.target).parents("#projectDetails")[0]) {
			touchStartX = e.originalEvent.touches[0].pageX;
			touchStartY = e.originalEvent.touches[0].pageY;

			var $this = $(this);
		    var scroller = $("#projectDetails").get(0);

		    if ($this.scrollTop() === 0) $this.scrollTop(1);
		    var scrollTop = scroller.scrollTop;
		    var scrollHeight = scroller.scrollHeight;
		    var offsetHeight = scroller.offsetHeight;
		    var contentHeight = scrollHeight - offsetHeight;
		    if (contentHeight == scrollTop) $this.scrollTop(scrollTop-1);
		}
	});

	$(document).on('touchmove', function(e) {
		// e.preventDefault();
	    if ($(e.target).parents('#projectDetails')[0] ) {

	    	if(Math.abs(touchStartX - e.originalEvent.touches[0].pageX)
	    		> Math.abs(touchStartY - e.originalEvent.touches[0].pageY)) {
	    		e.preventDefault();
	    	}
	    } else {
	    	e.preventDefault();
	    }
	});

	$(".nextPage").on("click", function(e) {

		e.preventDefault();

		$("html, body").animate({
			scrollLeft: $($(this).attr("href")).offset().left
		}, 1000);

	});

	$(".previousPage").on("click", function(e){

		e.preventDefault();

		$("html, body").animate({
			scrollLeft: $($(this).attr("href")).offset().left
		}, 1000);

	});

	$(".seeMore").on("click", function(e){

		e.preventDefault();

		$("html, body").animate({
			scrollTop: $($(this).attr("href")).offset().top
		}, 1000);

	});

	$(".seeLess").on("click", function(e){

		e.preventDefault();

		$("html, body").animate({
			scrollTop: $($(this).attr("href")).offset().top
		}, 1000);

	});

});

function getViewport() {
    var container = window, property = "inner";
    if (!("innerWidth" in window )) {
       property = "client";
       container = document.documentElement || document.body;
    }
    return { width : container[property + "Width"], height : container[property + "Height"]};
}<|endoftext|>


<commit_before>
var Slack = require('node-slack');
var express = require('express');
var bufferEq = require('buffer-equal-constant-time');
var crypto = require('crypto');

function initSlack() {
    if (process.env.HOOK_URL) {
        hookURL = process.env.HOOK_URL;
    } else {
        console.log("Must configure HOOK_URL!");
        process.exit(1);
    }
    return new Slack(hookURL);
}

function main()  {
    var slack = initSlack();
    var app = newServer(slack);

    app.set('port', (process.env.PORT || 5000));
    app.listen(app.get('port'), function() {
        console.log('Node app is running on port', app.get('port'));
    });
}

function hasValidSignature(sig, body) {
    var secret = process.env.GITHUB_SECRET;
    if (!secret) {
        console.error("GITHUB_SECRET is not configured");
        return true;
    }
    if (!sig) {
        console.error("Request is unsigned");
        return false;
    }

    var computedSig = 'sha1=' + crypto.createHmac('sha1', secret).update(body).digest('hex');
    return bufferEq(new Buffer(sig), new Buffer(computedSig));
}

function newServer(slack) {
    var app = express();

    // concatenate raw body
    app.use(function(req, res, next) {
        var data = '';
        req.setEncoding('utf8');
        req.on('data', function(chunk) {
            data += chunk;
        });
        req.on('end', function() {
            req.rawBody = data;
            next();
        });
    });

    var handlers = {};

    var newHandler = function(handler) {
        return handler(slack);
    };

    handlers['ping'] = newHandler(pingHandler);
    handlers['commit_comment'] = newHandler(commitCommentHandler);
    handlers['pull_request'] = newHandler(pullRequestHandler);
    handlers['pull_request_review_comment'] = newHandler(pullRequestCommentHandler);
    handlers['issue_comment'] = newHandler(issueCommentHandler);
    handlers['status'] = newHandler(statusHandler);

    app.post('/', function (req, res) {
        var rawBody = req.rawBody;
        var sig = req.headers['x-hub-signature'];
        if (!hasValidSignature(sig, rawBody)) {
            console.error("Invalid signature");
            res.sendStatus(403);
            res.end();
            return;
        }

        var event = req.headers['x-github-event'];
        if (!handlers[event]) {
            res.send('Unhandled event: ' + handlers[event]);
            res.end();
            return;
        }

        var json = JSON.parse(rawBody)

        res.sendStatus(handlers[event](json));
        res.end();
    });
    return app;
}

function pingHandler(slack) {
    return function(data) {
        slack.send({
            text: 'Howdy ping!',
            channel: '@matt.hauck',
        });
        return 200;
    }
}

function commitCommentHandler(slack) {
    return function(data) {
        return 200;
    }
}

function slackUser(login) {
    // our slack convention is to use '.' but github replaces dots with dashes.
    return '@' + login.replace('-', '.');
}

function assignees(pullRequest) {
    if (!pullRequest || !pullRequest.assignees) {
        return [];
    }
    return pullRequest.assignees.map(function(a) {
        return slackUser(a.login);
    });
}

function assigneesStr(pullRequest) {
    return assignees(pullRequest).join(', ');
}

function pullRequestHandler(slack) {
    return function(data) {
        var verb;
        var extra = '';
        if (data.action == 'opened') {
            verb = 'opened';
        } else if (data.action == 'closed') {
            if (data.pull_request.merged) {
                verb = 'merged';
            } else {
                verb = 'closed';
            }
        } else if (data.action == 'reopened') {
            verb = 'reopened';
        } else if (data.action == 'assigned') {
            verb = 'assigned';
            extra = ' to ' + assigneesStr(data.pull_request);
        } else if (data.action == 'unassigned') {
            verb = 'unassigned';
        }

        if (verb) {
            var msg = 'Pull Request ' + verb + extra;
            var attachments = [{
                title: 'Pull Request #' + data.pull_request.number + ': "' + data.pull_request.title + '"',
                title_link: data.pull_request.html_url,
            }];

            slack.send({
                text: msg,
                attachments: attachments,
            });
            assignees(data.pull_request).forEach(function(name) {
                console.log("Sending private message to assignee " + name);
                slack.send({
                    text: msg,
                    attachments: attachments,
                    channel: name,
                });
            });
            var owner = slackUser(data.pull_request.user.login);
            console.log("Sending private message to owner " + owner);
            slack.send({
                text: msg,
                attachments: attachments,
                channel: owner,
            });
        }

        return 200;
    }
}

function pullRequestCommentHandler(slack) {
    return function(data) {
        return 200;
    }
}

function issueCommentHandler(slack) {
    return function(data) {
        // only notify on new/edited comments
        if (data.action == "created" || data.action == "edited") {
            var msg = 'Comment on "' + data.issue.title;
            var attachments = [{
                title: slackUser(data.comment.user.login) + ' said:',
                title_link: data.comment.html_url,
                text: data.comment.body,
            }];

            console.log("Sending message to main channel");
            slack.send({
                text: msg,
                attachments: attachments,
            });
            assignees(data.issue).forEach(function(name) {
                console.log("Sending private message to assignee " + name);
                slack.send({
                    text: msg,
                    attachments: attachments,
                    channel: name,
                });
            });
            var owner = slackUser(data.issue.user.login);
            console.log("Sending private message to issue owner " + owner);
            slack.send({
                text: msg,
                attachments: attachments,
                channel: owner,
            });
        }

        return 200;
    }
}

function statusHandler(slack) {
    return function(data) {
        return 200;
    }
}

if (require.main === module) {
    main();
}
<commit_msg>Add pull request comment diff slack message<commit_after>
var Slack = require('node-slack');
var express = require('express');
var bufferEq = require('buffer-equal-constant-time');
var crypto = require('crypto');

function initSlack() {
    if (process.env.HOOK_URL) {
        hookURL = process.env.HOOK_URL;
    } else {
        console.log("Must configure HOOK_URL!");
        process.exit(1);
    }
    return new Slack(hookURL);
}

function main()  {
    var slack = initSlack();
    var app = newServer(slack);

    app.set('port', (process.env.PORT || 5000));
    app.listen(app.get('port'), function() {
        console.log('Node app is running on port', app.get('port'));
    });
}

function hasValidSignature(sig, body) {
    var secret = process.env.GITHUB_SECRET;
    if (!secret) {
        console.error("GITHUB_SECRET is not configured");
        return true;
    }
    if (!sig) {
        console.error("Request is unsigned");
        return false;
    }

    var computedSig = 'sha1=' + crypto.createHmac('sha1', secret).update(body).digest('hex');
    return bufferEq(new Buffer(sig), new Buffer(computedSig));
}

function newServer(slack) {
    var app = express();

    // concatenate raw body
    app.use(function(req, res, next) {
        var data = '';
        req.setEncoding('utf8');
        req.on('data', function(chunk) {
            data += chunk;
        });
        req.on('end', function() {
            req.rawBody = data;
            next();
        });
    });

    var handlers = {};

    var newHandler = function(handler) {
        return handler(slack);
    };

    handlers['ping'] = newHandler(pingHandler);
    handlers['commit_comment'] = newHandler(commitCommentHandler);
    handlers['pull_request'] = newHandler(pullRequestHandler);
    handlers['pull_request_review_comment'] = newHandler(pullRequestCommentHandler);
    handlers['issue_comment'] = newHandler(issueCommentHandler);
    handlers['status'] = newHandler(statusHandler);

    app.post('/', function (req, res) {
        var rawBody = req.rawBody;
        var sig = req.headers['x-hub-signature'];
        if (!hasValidSignature(sig, rawBody)) {
            console.error("Invalid signature");
            res.sendStatus(403);
            res.end();
            return;
        }

        var event = req.headers['x-github-event'];
        if (!handlers[event]) {
            res.send('Unhandled event: ' + handlers[event]);
            res.end();
            return;
        }

        var json = JSON.parse(rawBody)

        res.sendStatus(handlers[event](json));
        res.end();
    });
    return app;
}

function pingHandler(slack) {
    return function(data) {
        slack.send({
            text: 'Howdy ping!',
            channel: '@matt.hauck',
        });
        return 200;
    }
}

function commitCommentHandler(slack) {
    return function(data) {
        return 200;
    }
}

function slackUser(login) {
    // our slack convention is to use '.' but github replaces dots with dashes.
    return '@' + login.replace('-', '.');
}

function assignees(pullRequest) {
    if (!pullRequest || !pullRequest.assignees) {
        return [];
    }
    return pullRequest.assignees.map(function(a) {
        return slackUser(a.login);
    });
}

function assigneesStr(pullRequest) {
    return assignees(pullRequest).join(', ');
}

function pullRequestHandler(slack) {
    return function(data) {
        var verb;
        var extra = '';
        if (data.action == 'opened') {
            verb = 'opened';
        } else if (data.action == 'closed') {
            if (data.pull_request.merged) {
                verb = 'merged';
            } else {
                verb = 'closed';
            }
        } else if (data.action == 'reopened') {
            verb = 'reopened';
        } else if (data.action == 'assigned') {
            verb = 'assigned';
            extra = ' to ' + assigneesStr(data.pull_request);
        } else if (data.action == 'unassigned') {
            verb = 'unassigned';
        }

        if (verb) {
            var msg = 'Pull Request ' + verb + extra;
            var attachments = [{
                title: 'Pull Request #' + data.pull_request.number + ': "' + data.pull_request.title + '"',
                title_link: data.pull_request.html_url,
            }];

            slack.send({
                text: msg,
                attachments: attachments,
            });
            assignees(data.pull_request).forEach(function(name) {
                console.log("Sending private message to assignee " + name);
                slack.send({
                    text: msg,
                    attachments: attachments,
                    channel: name,
                });
            });
            var owner = slackUser(data.pull_request.user.login);
            console.log("Sending private message to owner " + owner);
            slack.send({
                text: msg,
                attachments: attachments,
                channel: owner,
            });
        }

        return 200;
    }
}

function pullRequestCommentHandler(slack) {
    return function(data) {
        if (data.action == "created" || data.action == "edited") {
            var msg = 'Comment on "' + data.pull_request.title + '"';
            var attachments = [{
                title: slackUser(data.comment.user.login) + ' said:',
                title_link: data.comment.html_url,
                text: data.comment.body,
            }];

            console.log("Sending message to main channel");
            slack.send({
                text: msg,
                attachments: attachments,
            });
            assignees(data.pull_request).forEach(function(name) {
                console.log("Sending private message to assignee " + name);
                slack.send({
                    text: msg,
                    attachments: attachments,
                    channel: name,
                });
            });
            var owner = slackUser(data.pull_request.user.login);
            console.log("Sending private message to issue owner " + owner);
            slack.send({
                text: msg,
                attachments: attachments,
                channel: owner,
            });
        }
        return 200;
    }
}

function issueCommentHandler(slack) {
    return function(data) {
        // only notify on new/edited comments
        if (data.action == "created" || data.action == "edited") {
            var msg = 'Comment on "' + data.issue.title + '"';
            var attachments = [{
                title: slackUser(data.comment.user.login) + ' said:',
                title_link: data.comment.html_url,
                text: data.comment.body,
            }];

            console.log("Sending message to main channel");
            slack.send({
                text: msg,
                attachments: attachments,
            });
            assignees(data.issue).forEach(function(name) {
                console.log("Sending private message to assignee " + name);
                slack.send({
                    text: msg,
                    attachments: attachments,
                    channel: name,
                });
            });
            var owner = slackUser(data.issue.user.login);
            console.log("Sending private message to issue owner " + owner);
            slack.send({
                text: msg,
                attachments: attachments,
                channel: owner,
            });
        }

        return 200;
    }
}

function statusHandler(slack) {
    return function(data) {
        return 200;
    }
}

if (require.main === module) {
    main();
}
<|endoftext|>


<commit_before>/* eslint-env node */
'use strict';

module.exports = {
  name: require('./package').name,

  included() {
    this._super.included.apply(this, arguments);

    const dependencies = Object.keys(this.project.dependencies());
    const hasFastboot = dependencies.includes('ember-cli-fastboot');

    const importOptions = {};
    if (hasFastboot) {
      importOptions.using = [{ transformation: 'fastbootShim' }];
    }

    this.import('node_modules/pikaday/pikaday.js', importOptions);
    this.import('node_modules/pikaday/css/pikaday.css');
  }
};
<commit_msg>Fix `excludePikadayAssets` support<commit_after>/* eslint-env node */
'use strict';

module.exports = {
  name: require('./package').name,

  included() {
    this._super.included.apply(this, arguments);

    const addonOptions =
      (this.app.options && this.app.options.emberPikaday) || {};

    const dependencies = Object.keys(this.project.dependencies());
    const hasFastboot = dependencies.includes('ember-cli-fastboot');

    const importOptions = {};
    if (hasFastboot) {
      importOptions.using = [{ transformation: 'fastbootShim' }];
    }

    this.import('node_modules/pikaday/pikaday.js', importOptions);
    if (!addonOptions.excludePikadayAssets) {
      this.import('node_modules/pikaday/css/pikaday.css');
    }
  }
};
<|endoftext|>


<commit_before>'use strict';

const domainPing = require('./index');

domainPing('github.com')
    .then((res) => {
        console.log(res);
    })
    .catch((error) => {
        console.error(error);
    });
<commit_msg>Updated path to module<commit_after>'use strict';

const domainPing = require('./domain-ping');

domainPing('github.com')
    .then((res) => {
        console.log(res);
    })
    .catch((error) => {
        console.error(error);
    });
<|endoftext|>


<commit_before>'use strict';

const replace = require('broccoli-replace');

module.exports = {
  name: require('./package').name,

  included() {
    this._super.included.apply(this, arguments);
    this.app.options.replace = this.app.options.replace || {};

    const defaultOptions = {
      files: [],
      patterns: [],
      enabled: true,
    };

    for (let option in defaultOptions) {
      if (!this.app.options.replace.hasOwnProperty(option)) {
        this.app.options.replace[option] = defaultOptions[option];
      }
    }
  },

  postprocessTree: function (type, tree) {
    if (
      type === 'all' &&
      this.app.options.replace &&
      this.app.options.replace.enabled
    ) {
      tree = replace(tree, this.app.options.replace);
    }

    return tree;
  },
};
<commit_msg>refactor option setting<commit_after>'use strict';

const replace = require('broccoli-replace');

module.exports = {
  name: require('./package').name,

  included() {
    this._super.included.apply(this, arguments);

    const options = this.app.options.replace || {};
    const defaultOptions = {
      files: [],
      patterns: [],
      enabled: true,
    };

    this.app.options.replace = {
      ...defaultOptions,
      ...options,
    };
  },

  postprocessTree: function (type, tree) {
    if (
      type === 'all' &&
      this.app.options.replace &&
      this.app.options.replace.enabled
    ) {
      tree = replace(tree, this.app.options.replace);
    }

    return tree;
  },
};
<|endoftext|>


<commit_before>process.on('uncaughtException', function (err) {
  console.log(err)
  process.exit()
})

var electron = require('electron')
var openWindow = require('./lib/window')

var Path = require('path')
var defaultMenu = require('electron-default-menu')
var Menu = electron.Menu
var extend = require('xtend')
var ssbKeys = require('ssb-keys')

var windows = {
  dialogs: new Set()
}

var ssbConfig = null

electron.app.on('ready', () => {
  setupContext('ssb', {
    server: !(process.argv.includes('-g') || process.argv.includes('--use-global-ssb'))
  }, () => {
    var menu = defaultMenu(electron.app, electron.shell)
    var view = menu.find(x => x.label === 'View')
    view.submenu.push({
      label: 'Zoom In',
      accelerator: 'CmdOrCtrl+=',
      role: 'zoomin'
    }, {
      label: 'Zoom Out',
      accelerator: 'CmdOrCtrl+-',
      role: 'zoomout'
    })
    Menu.setApplicationMenu(Menu.buildFromTemplate(menu))
    openMainWindow()
  })

  electron.app.on('activate', function (e) {
    openMainWindow()
  })

  electron.ipcMain.on('open-background-devtools', function (ev, config) {
    if (windows.background) {
      windows.background.webContents.openDevTools({detach: true})
    }
  })
})

function openMainWindow () {
  if (!windows.main) {
    windows.main = openWindow(ssbConfig, Path.join(__dirname, 'main-window.js'), {
      minWidth: 800,
      width: 1024,
      height: 768,
      titleBarStyle: 'hidden-inset',
      title: 'Patchwork',
      show: true,
      backgroundColor: '#EEE',
      webPreferences: {
        experimentalFeatures: true
      },
      icon: './assets/icon.png'
    })
    windows.main.setSheetOffset(40)
    windows.main.on('closed', function () {
      windows.main = null
      if (process.platform !== 'darwin') electron.app.quit()
    })
  }
}

function setupContext (appName, opts, cb) {
  ssbConfig = require('ssb-config/inject')(appName, extend({
    port: 8008,
    blobsPort: 7777
  }, opts))

  ssbConfig.keys = ssbKeys.loadOrCreateSync(Path.join(ssbConfig.path, 'secret'))

  if (opts.server === false) {
    cb && cb()
  } else {
    electron.ipcMain.once('server-started', function (ev, config) {
      ssbConfig = config
      cb && cb()
    })
    windows.background = openWindow(ssbConfig, Path.join(__dirname, 'server-process.js'), {
      connect: false,
      center: true,
      fullscreen: false,
      fullscreenable: false,
      height: 150,
      maximizable: false,
      minimizable: false,
      resizable: false,
      show: false,
      skipTaskbar: true,
      title: 'patchwork-server',
      useContentSize: true,
      width: 150
    })
    // windows.background.on('close', (ev) => {
    //   ev.preventDefault()
    //   windows.background.hide()
    // })
  }
}
<commit_msg>use view roles instead of hardcoded<commit_after>process.on('uncaughtException', function (err) {
  console.log(err)
  process.exit()
})

var electron = require('electron')
var openWindow = require('./lib/window')

var Path = require('path')
var defaultMenu = require('electron-default-menu')
var Menu = electron.Menu
var extend = require('xtend')
var ssbKeys = require('ssb-keys')

var windows = {
  dialogs: new Set()
}

var ssbConfig = null

electron.app.on('ready', () => {
  setupContext('ssb', {
    server: !(process.argv.includes('-g') || process.argv.includes('--use-global-ssb'))
  }, () => {
    var menu = defaultMenu(electron.app, electron.shell)
    var view = menu.find(x => x.label === 'View')
    view.submenu = [
      { role: 'reload' },
      { role: 'toggledevtools' },
      { type: 'separator' },
      { role: 'resetzoom' },
      { role: 'zoomin' },
      { role: 'zoomout' },
      { type: 'separator' },
      { role: 'togglefullscreen' }
    ]
    Menu.setApplicationMenu(Menu.buildFromTemplate(menu))
    openMainWindow()
  })

  electron.app.on('activate', function (e) {
    openMainWindow()
  })

  electron.ipcMain.on('open-background-devtools', function (ev, config) {
    if (windows.background) {
      windows.background.webContents.openDevTools({detach: true})
    }
  })
})

function openMainWindow () {
  if (!windows.main) {
    windows.main = openWindow(ssbConfig, Path.join(__dirname, 'main-window.js'), {
      minWidth: 800,
      width: 1024,
      height: 768,
      titleBarStyle: 'hidden-inset',
      title: 'Patchwork',
      show: true,
      backgroundColor: '#EEE',
      webPreferences: {
        experimentalFeatures: true
      },
      icon: './assets/icon.png'
    })
    windows.main.setSheetOffset(40)
    windows.main.on('closed', function () {
      windows.main = null
      if (process.platform !== 'darwin') electron.app.quit()
    })
  }
}

function setupContext (appName, opts, cb) {
  ssbConfig = require('ssb-config/inject')(appName, extend({
    port: 8008,
    blobsPort: 7777
  }, opts))

  ssbConfig.keys = ssbKeys.loadOrCreateSync(Path.join(ssbConfig.path, 'secret'))

  if (opts.server === false) {
    cb && cb()
  } else {
    electron.ipcMain.once('server-started', function (ev, config) {
      ssbConfig = config
      cb && cb()
    })
    windows.background = openWindow(ssbConfig, Path.join(__dirname, 'server-process.js'), {
      connect: false,
      center: true,
      fullscreen: false,
      fullscreenable: false,
      height: 150,
      maximizable: false,
      minimizable: false,
      resizable: false,
      show: false,
      skipTaskbar: true,
      title: 'patchwork-server',
      useContentSize: true,
      width: 150
    })
    // windows.background.on('close', (ev) => {
    //   ev.preventDefault()
    //   windows.background.hide()
    // })
  }
}
<|endoftext|>