<commit_before>var _       = require("lodash");
var pg      = require("p" + "g"); //silly hack to keep browserify out of here.
try{
  pg = pg.native;
}catch(e){}
var Query   = require("../../sql/Query").Query;
var shared  = require("./_shared");
var DDL     = require("../DDL/SQL");

exports.Driver = Driver;

var switchableFunctions = {
  pool: {
    connect: function (cb) {
      this.db.connect(this.config, function (err, client, done) {
        if (!err) {
          done();
        }
        cb(err);
      });
    },
    execSimpleQuery: function (query, cb) {
      if (this.opts.debug) {
        require("../../Debug").sql('postgres', query);
      }
      this.db.connect(this.config, function (err, client, done) {
        if (err) {
          return cb(err);
        }

        client.query(query, function (err, result) {
          done();

          if (err) {
            cb(err);
          } else {
            cb(null, result.rows);
          }
        });
      });
      return this;
    },
    on: function(ev, cb) {
      // Because `pg` is the same for all instances of this driver
      // we can't keep adding listeners since they are never removed.
      return this;
    }
  },
  client: {
    connect: function (cb) {
      this.db.connect(cb);
    },
    execSimpleQuery: function (query, cb) {
      if (this.opts.debug) {
        require("../../Debug").sql('postgres', query);
      }
      var start, end, profiler;
      if(this.opts.profiler){
        start = new Date();
        profiler = this.opts.profiler;
      }
      this.db.query(query, function (err, result) {
        if(profiler){
          end = new Date();
          var duration = end - start;
          profiler(duration, query);
        }
        if (err) {
          cb(err);
        } else {
          cb(null, result.rows);
        }
      });
      return this;
    },
    on: function(ev, cb) {
      if (ev == "error") {
        this.db.on("error", cb);
      }
      return this;
    }
  }
};

function Driver(config, connection, opts) {
  var functions = switchableFunctions.client;

  this.dialect = 'postgresql';
  this.config = config || {};
  this.opts   = opts || {};
  if (!this.config.timezone) {
    this.config.timezone = "local";
  }
  if ((typeof window !== "undefined" && window !== null ? window.pg : void 0) != null) {
    pg = window.pg; //HACK: to sideload pg
  }

  this.query  = new Query({ dialect: this.dialect, timezone: this.config.timezone });
  this.customTypes = {};

  if (connection) {
    this.db = connection;
  } else {
    if (this.config.query && this.config.query.ssl) {
      config.ssl = true;
      this.config = _.extend(this.config, config);
    // } else {
    //   this.config = _.extend(this.config, config);
    //   this.config = config.href || config;
    }

    pg.types.setTypeParser(20, Number);

    if (opts.pool) {
      functions = switchableFunctions.pool;
      this.db = pg;
    } else {
      this.db = new pg.Client(this.config);
    }
  }

  _.extend(this.constructor.prototype, functions);

  this.aggregate_functions = [
    "ABS", "CEIL", "FLOOR", "ROUND",
    "AVG", "MIN", "MAX",
    "LOG", "EXP", "POWER",
    "ACOS", "ASIN", "ATAN", "COS", "SIN", "TAN",
    "RANDOM", "RADIANS", "DEGREES",
    "SUM", "COUNT",
    "DISTINCT"
  ];
}

_.extend(Driver.prototype, shared, DDL);

Driver.prototype.ping = function (cb) {
  this.execSimpleQuery("SELECT * FROM pg_stat_activity LIMIT 1", function () {
    return cb();
  });
  return this;
};

Driver.prototype.begin = function (cb) {
  this.execSimpleQuery("begin", function () {
    return cb();
  });
  return this;
};

Driver.prototype.commit = function (cb) {
  this.execSimpleQuery("commit", function () {
    return cb();
  });
  return this;
};

Driver.prototype.rollback = function (cb) {
  this.execSimpleQuery("rollback", function () {
    return cb();
  });
  return this;
};

Driver.prototype.close = function (cb) {
  this.db.end();

  if (typeof cb == "function") cb();

  return;
};

Driver.prototype.getQuery = function () {
  return this.query;
};

Driver.prototype.find = function (fields, table, conditions, opts, cb) {
  var i, q = this.query.select().from(table).select(fields);
  if(opts.joins){
    for(i = 0; i != opts.joins.length; i++){
      var join = opts.joins[i];
      q.from(join.toTable, join.toFields, join.fromTable, join.fromFields);

      if(join.toAlias == null) {
        join.toAlias = 'j' + (i + 1);
      }

      q.alias(join.toAlias);

      if(join.conditions){
        q.where(join.toAlias, join.conditions);
      }
    }
  }

  if (opts.offset) {
    q.offset(opts.offset);
  }
  if (typeof opts.limit == "number") {
    q.limit(opts.limit);
  }
  if (opts.order) {
    for (i = 0; i < opts.order.length; i++) {
      q.order(opts.order[i][0], opts.order[i][1], opts.order[i][2]);
    }
  }

  if(opts.distinct_on){
    q.distinct_on(opts.distinct_on);
  }

  if (opts.merge) {
    q.from(opts.merge.from.table, opts.merge.from.field, opts.merge.to.field).select(opts.merge.select);
    if (opts.merge.where && Object.keys(opts.merge.where[1]).length) {
      q = q.where(opts.merge.where[0], opts.merge.where[1], opts.merge.table || null, conditions);
    } else {
      q = q.where(opts.merge.table || null, conditions);
    }
  } else if(opts.joins){
    q = q.where(table, conditions);
  } else {
    q = q.where(conditions);
  }

  if (opts.exists) {
    for (var k in opts.exists) {
      q.whereExists(opts.exists[k].table, table, opts.exists[k].link, opts.exists[k].conditions);
    }
  }
  if(opts.format){
    q.format(opts.format);
  }
  if(opts.transform){
    q.transform(opts.transform.functionName, opts.transform.functionArgs);
  }

  q = q.build();

  this.execSimpleQuery(q, cb);
};

Driver.prototype.count = function (table, conditions, opts, cb) {
  var q = this.query.select().from(table).count(null, 'c');
  if(opts.joins){
    for(i = 0; i != opts.joins.length; i++){
      var join = opts.joins[i];
      q.from(join.toTable, join.toFields, join.fromTable, join.fromFields);
      if(join.conditions){
        q.where(join.toTable, join.conditions);
      }
    }
  }

  if (opts.merge) {
    q.from(opts.merge.from.table, opts.merge.from.field, opts.merge.to.field);
    if (opts.merge.where && Object.keys(opts.merge.where[1]).length) {
      q = q.where(opts.merge.where[0], opts.merge.where[1], conditions);
    } else {
      q = q.where(conditions);
    }
  } else if(opts.joins){
    q = q.where(table, conditions);
  } else {
    q = q.where(conditions);
  }

  if (opts.exists) {
    for (var k in opts.exists) {
      q.whereExists(opts.exists[k].table, table, opts.exists[k].link, opts.exists[k].conditions);
    }
  }

  q = q.build();

  this.execSimpleQuery(q, cb);
};

Driver.prototype.insert = function (table, data, keyProperties, cb) {
  var q = this.query.insert().into(table).set(data).build();

  this.execSimpleQuery(q + " RETURNING *", function (err, results) {
    if (err) {
      return cb(err);
    }

    var i, ids = {}, prop;

    if (keyProperties) {
      for (i = 0; i < keyProperties.length; i++) {
        prop = keyProperties[i];

        if(results[0]){
          ids[prop.name] = results[0][prop.mapsTo] || null;
        }else{ //TODO: if ignore returns
          ids[prop.name] = data[prop.name] || null;
        }
      }
    }

    return cb(null, ids);
  });
};

Driver.prototype.update = function (table, changes, conditions, cb) {
  var q = this.query.update().into(table).set(changes).where(conditions).build();

  this.execSimpleQuery(q, cb);
};

Driver.prototype.remove = function (table, conditions, cb) {
  var q = this.query.remove().from(table).where(conditions).build();

  this.execSimpleQuery(q, cb);
};

Driver.prototype.clear = function (table, cb) {
  var q = "TRUNCATE TABLE " + this.query.escapeId(table);

  this.execSimpleQuery(q, cb);
};

Driver.prototype.valueToProperty = function (value, property) {
  var customType, v;

  switch (property.type) {
    case "object":
      if (typeof value == "object" && !Buffer.isBuffer(value)) {
        break;
      }
      try {
        value = JSON.parse(value);
      } catch (e) {
        value = null;
      }
      break;
    case "json":
      //no-op, value is already an object
      break;
    case "point":
      if (typeof value == "string") {
        var m = value.match(/\((\-?[\d\.]+)[\s,]+(\-?[\d\.]+)\)/);

        if (m) {
          value = { x : parseFloat(m[1], 10) , y : parseFloat(m[2], 10) };
        }
      }
      break;
    case "array":
      // The driver converts this type for us.
      break;
    case "date":
      if (this.config.timezone && this.config.timezone != 'local') {
        var tz = convertTimezone(this.config.timezone);

        if(value !==null && value.getTime !== undefined){
          // shift local to UTC
          value.setTime(value.getTime() - (value.getTimezoneOffset() * 60000));
          if (tz !== false) {
            // shift UTC to timezone
            value.setTime(value.getTime() - (tz * 60000));
          }
        }
      }
      break;
    case "number":
      if (typeof value != 'number' && value !== null) {
        v = Number(value);
        if (!isNaN(v)) {
          value = v;
        }
      }
      break;
    default:
      customType = this.customTypes[property.type];

      if (customType && 'valueToProperty' in customType) {
        value = customType.valueToProperty(value);
      }
  }
  return value;
};

Driver.prototype.propertyToValue = function (value, property) {
  var customType;

  switch (property.type) {
    case "object":
      if (value !== null && !Buffer.isBuffer(value)) {
        value = new Buffer(JSON.stringify(value));
      }
      break;
    case "json":
      if (value !== null) {
        value = JSON.stringify(value);
      }
      break;
    case "date":
      if (this.config.timezone && this.config.timezone != 'local') {
        var tz = convertTimezone(this.config.timezone);

        if(value !== null && value.getTime !== undefined){
          // shift local to UTC
          value.setTime(value.getTime() + (value.getTimezoneOffset() * 60000));
          if (tz !== false) {
            // shift UTC to timezone
            value.setTime(value.getTime() + (tz * 60000));
          }
        }
      }
      break;
    case "point":
      return function () {
        return "POINT(" + value.x + ', ' + value.y + ")";
      };
    case "array":
      if(value){
        value = "{" + value.map(function(item) {
          if(_.isString(item)) {
            return '"' + item + '"';
          }
          return item;
        }) + "}";
      }
      break;
    default:
      customType = this.customTypes[property.type];

      if (customType && 'propertyToValue' in customType) {
        value = customType.propertyToValue(value);
      }
  }
  return value;
};

Object.defineProperty(Driver.prototype, "isSql", {
    value: true
});

function convertTimezone(tz) {
  if (tz == "Z") {
    return 0;
  }

  var m = tz.match(/([\+\-\s])(\d\d):?(\d\d)?/);

  if (m) {
    return (m[1] == '-' ? -1 : 1) * (parseInt(m[2], 10) + ((m[3] ? parseInt(m[3], 10) : 0) / 60)) * 60;
  }
  return false;
}
<commit_msg>work with newer versions of pg<commit_after>var _       = require("lodash");
var pg      = require("pg");
// try{
//   pg = pg.native;
// }catch(e){}
var Query   = require("../../sql/Query").Query;
var shared  = require("./_shared");
var DDL     = require("../DDL/SQL");

exports.Driver = Driver;

var pools = {};

var switchableFunctions = {
  pool: {
    connect: function (cb) {
      this.db.connect(function (err, client, done) {
        if (!err) {
          done();
        }else{
          console.log("-->", err);
        }
        cb(err);
      });
    },
    execSimpleQuery: function (query, cb) {
      if (this.opts.debug) {
        require("../../Debug").sql('postgres', query);
      }
      this.db.connect(function (err, client, done) {
        if (err) {
          return cb(err);
        }

        client.query(query, function (err, result) {
          done();

          if (err) {
            cb(err);
          } else {
            cb(null, result.rows);
          }
        });
      });
      return this;
    },
    on: function(ev, cb) {
      // Because `pg` is the same for all instances of this driver
      // we can't keep adding listeners since they are never removed.
      return this;
    }
  },
  client: {
    connect: function (cb) {
      this.db.connect(cb);
    },
    execSimpleQuery: function (query, cb) {
      if (this.opts.debug) {
        require("../../Debug").sql('postgres', query);
      }
      var start, end, profiler;
      if(this.opts.profiler){
        start = new Date();
        profiler = this.opts.profiler;
      }
      this.db.query(query, function (err, result) {
        if(profiler){
          end = new Date();
          var duration = end - start;
          profiler(duration, query);
        }
        if (err) {
          cb(err);
        } else {
          cb(null, result.rows);
        }
      });
      return this;
    },
    on: function(ev, cb) {
      if (ev == "error") {
        this.db.on("error", cb);
      }
      return this;
    }
  }
};

function Driver(config, connection, opts) {
  var functions = switchableFunctions.client;

  this.dialect = 'postgresql';
  this.config = config || {};
  this.opts   = opts || {};
  if (!this.config.timezone) {
    this.config.timezone = "local";
  }

  this.query  = new Query({ dialect: this.dialect, timezone: this.config.timezone });
  this.customTypes = {};

  if (connection) {
    this.db = connection;
  } else {
    if (this.config.query && this.config.query.ssl) {
      config.ssl = true;
      this.config = _.extend(this.config, config);
    // } else {
    //   this.config = _.extend(this.config, config);
    //   this.config = config.href || config;
    }

    pg.types.setTypeParser(20, Number);

    if (opts.pool) {
      functions = switchableFunctions.pool;

      var key = JSON.stringify(this.config);
      if(!pools[key]){
        pools[key] = new pg.Pool(this.config);
      }
      this.db = pools[key];
      this.isPooled = true;
    } else {
      this.db = new pg.Client(this.config);
      this.isPooled = false;
    }
  }

  _.extend(this.constructor.prototype, functions);

  this.aggregate_functions = [
    "ABS", "CEIL", "FLOOR", "ROUND",
    "AVG", "MIN", "MAX",
    "LOG", "EXP", "POWER",
    "ACOS", "ASIN", "ATAN", "COS", "SIN", "TAN",
    "RANDOM", "RADIANS", "DEGREES",
    "SUM", "COUNT",
    "DISTINCT"
  ];
}

_.extend(Driver.prototype, shared, DDL);

Driver.prototype.ping = function (cb) {
  this.execSimpleQuery("SELECT * FROM pg_stat_activity LIMIT 1", function () {
    return cb();
  });
  return this;
};

Driver.prototype.begin = function (cb) {
  this.execSimpleQuery("begin", function () {
    return cb();
  });
  return this;
};

Driver.prototype.commit = function (cb) {
  this.execSimpleQuery("commit", function () {
    return cb();
  });
  return this;
};

Driver.prototype.rollback = function (cb) {
  this.execSimpleQuery("rollback", function () {
    return cb();
  });
  return this;
};

Driver.prototype.close = function (cb) {
  if(!this.isPooled){
    this.db.end();
  }

  if (typeof cb == "function") cb();

  return;
};

Driver.prototype.getQuery = function () {
  return this.query;
};

Driver.prototype.find = function (fields, table, conditions, opts, cb) {
  var i, q = this.query.select().from(table).select(fields);
  if(opts.joins){
    for(i = 0; i != opts.joins.length; i++){
      var join = opts.joins[i];
      q.from(join.toTable, join.toFields, join.fromTable, join.fromFields);

      if(join.toAlias == null) {
        join.toAlias = 'j' + (i + 1);
      }

      q.alias(join.toAlias);

      if(join.conditions){
        q.where(join.toAlias, join.conditions);
      }
    }
  }

  if (opts.offset) {
    q.offset(opts.offset);
  }
  if (typeof opts.limit == "number") {
    q.limit(opts.limit);
  }
  if (opts.order) {
    for (i = 0; i < opts.order.length; i++) {
      q.order(opts.order[i][0], opts.order[i][1], opts.order[i][2]);
    }
  }

  if(opts.distinct_on){
    q.distinct_on(opts.distinct_on);
  }

  if (opts.merge) {
    q.from(opts.merge.from.table, opts.merge.from.field, opts.merge.to.field).select(opts.merge.select);
    if (opts.merge.where && Object.keys(opts.merge.where[1]).length) {
      q = q.where(opts.merge.where[0], opts.merge.where[1], opts.merge.table || null, conditions);
    } else {
      q = q.where(opts.merge.table || null, conditions);
    }
  } else if(opts.joins){
    q = q.where(table, conditions);
  } else {
    q = q.where(conditions);
  }

  if (opts.exists) {
    for (var k in opts.exists) {
      q.whereExists(opts.exists[k].table, table, opts.exists[k].link, opts.exists[k].conditions);
    }
  }
  if(opts.format){
    q.format(opts.format);
  }
  if(opts.transform){
    q.transform(opts.transform.functionName, opts.transform.functionArgs);
  }

  q = q.build();

  this.execSimpleQuery(q, cb);
};

Driver.prototype.count = function (table, conditions, opts, cb) {
  var q = this.query.select().from(table).count(null, 'c');
  if(opts.joins){
    for(i = 0; i != opts.joins.length; i++){
      var join = opts.joins[i];
      q.from(join.toTable, join.toFields, join.fromTable, join.fromFields);
      if(join.conditions){
        q.where(join.toTable, join.conditions);
      }
    }
  }

  if (opts.merge) {
    q.from(opts.merge.from.table, opts.merge.from.field, opts.merge.to.field);
    if (opts.merge.where && Object.keys(opts.merge.where[1]).length) {
      q = q.where(opts.merge.where[0], opts.merge.where[1], conditions);
    } else {
      q = q.where(conditions);
    }
  } else if(opts.joins){
    q = q.where(table, conditions);
  } else {
    q = q.where(conditions);
  }

  if (opts.exists) {
    for (var k in opts.exists) {
      q.whereExists(opts.exists[k].table, table, opts.exists[k].link, opts.exists[k].conditions);
    }
  }

  q = q.build();

  this.execSimpleQuery(q, cb);
};

Driver.prototype.insert = function (table, data, keyProperties, cb) {
  var q = this.query.insert().into(table).set(data).build();

  this.execSimpleQuery(q + " RETURNING *", function (err, results) {
    if (err) {
      return cb(err);
    }

    var i, ids = {}, prop;

    if (keyProperties) {
      for (i = 0; i < keyProperties.length; i++) {
        prop = keyProperties[i];

        if(results[0]){
          ids[prop.name] = results[0][prop.mapsTo] || null;
        }else{ //TODO: if ignore returns
          ids[prop.name] = data[prop.name] || null;
        }
      }
    }

    return cb(null, ids);
  });
};

Driver.prototype.update = function (table, changes, conditions, cb) {
  var q = this.query.update().into(table).set(changes).where(conditions).build();

  this.execSimpleQuery(q, cb);
};

Driver.prototype.remove = function (table, conditions, cb) {
  var q = this.query.remove().from(table).where(conditions).build();

  this.execSimpleQuery(q, cb);
};

Driver.prototype.clear = function (table, cb) {
  var q = "TRUNCATE TABLE " + this.query.escapeId(table);

  this.execSimpleQuery(q, cb);
};

Driver.prototype.valueToProperty = function (value, property) {
  var customType, v;

  switch (property.type) {
    case "object":
      if (typeof value == "object" && !Buffer.isBuffer(value)) {
        break;
      }
      try {
        value = JSON.parse(value);
      } catch (e) {
        value = null;
      }
      break;
    case "json":
      //no-op, value is already an object
      break;
    case "point":
      if (typeof value == "string") {
        var m = value.match(/\((\-?[\d\.]+)[\s,]+(\-?[\d\.]+)\)/);

        if (m) {
          value = { x : parseFloat(m[1], 10) , y : parseFloat(m[2], 10) };
        }
      }
      break;
    case "array":
      // The driver converts this type for us.
      break;
    case "date":
      if (this.config.timezone && this.config.timezone != 'local') {
        var tz = convertTimezone(this.config.timezone);

        if(value !==null && value.getTime !== undefined){
          // shift local to UTC
          value.setTime(value.getTime() - (value.getTimezoneOffset() * 60000));
          if (tz !== false) {
            // shift UTC to timezone
            value.setTime(value.getTime() - (tz * 60000));
          }
        }
      }
      break;
    case "number":
      if (typeof value != 'number' && value !== null) {
        v = Number(value);
        if (!isNaN(v)) {
          value = v;
        }
      }
      break;
    default:
      customType = this.customTypes[property.type];

      if (customType && 'valueToProperty' in customType) {
        value = customType.valueToProperty(value);
      }
  }
  return value;
};

Driver.prototype.propertyToValue = function (value, property) {
  var customType;

  switch (property.type) {
    case "object":
      if (value !== null && !Buffer.isBuffer(value)) {
        value = new Buffer(JSON.stringify(value));
      }
      break;
    case "json":
      if (value !== null) {
        value = JSON.stringify(value);
      }
      break;
    case "date":
      if (this.config.timezone && this.config.timezone != 'local') {
        var tz = convertTimezone(this.config.timezone);

        if(value !== null && value.getTime !== undefined){
          // shift local to UTC
          value.setTime(value.getTime() + (value.getTimezoneOffset() * 60000));
          if (tz !== false) {
            // shift UTC to timezone
            value.setTime(value.getTime() + (tz * 60000));
          }
        }
      }
      break;
    case "point":
      return function () {
        return "POINT(" + value.x + ', ' + value.y + ")";
      };
    case "array":
      if(value){
        value = "{" + value.map(function(item) {
          if(_.isString(item)) {
            return '"' + item + '"';
          }
          return item;
        }) + "}";
      }
      break;
    default:
      customType = this.customTypes[property.type];

      if (customType && 'propertyToValue' in customType) {
        value = customType.propertyToValue(value);
      }
  }
  return value;
};

Object.defineProperty(Driver.prototype, "isSql", {
    value: true
});

function convertTimezone(tz) {
  if (tz == "Z") {
    return 0;
  }

  var m = tz.match(/([\+\-\s])(\d\d):?(\d\d)?/);

  if (m) {
    return (m[1] == '-' ? -1 : 1) * (parseInt(m[2], 10) + ((m[3] ? parseInt(m[3], 10) : 0) / 60)) * 60;
  }
  return false;
}
<|endoftext|>


<commit_before>;(function(global) {       // IIFE for legacy non-module usage
'use strict'

var utils = require('./lib/utils')

// Validate the arguments passed in to an action creator against the schema
// that is declared in faction.create()
function _validate(paramsHash, spec) {
    var specKeys = Object.keys(spec)
    specKeys.forEach(function(k) {
        var validator = spec[k]
        // TODO: assign validated values to a cloned object?
        paramsHash[k] = validator(paramsHash[k])    // may throw ActionParamError
    })
}

// Return an action creator function
//
// If a service function is given, the action's payload will be a Promise, which
// is returned from the service function.
//
// Otherwise the action creator is fully synchronous, and the Object literal
// passed in to it will be the action payload.
function _makeActionCreator(type, spec, service) {
    return function actionCreator(paramsHash) {
        var action = { type: type, meta: {} }    // payload is set below

        // If action argument is an error object, follow the FSA conventions:
        if (paramsHash instanceof Error) {
            action.error = true
            action.payload = paramsHash
            return action
        }

        paramsHash = paramsHash || {}
        if (spec) _validate(paramsHash, spec)     // Will throw if validation fails

        if (service) {
            // The service function *must* return a Promise, or else we throw:
            var result = service(paramsHash)
            if (!utils.isPromise(result)) {
                throw new Error('Service for ' + type + ' did not return a Promise')
            }
            action.payload = result
        } else {
            action.payload = paramsHash
        }

        return action
    }
}

function createFaction(actionSpecs, options) {
    var types = {}
    var creators = {}

    for (var key in actionSpecs) {
        types[key] = key

        var spec = actionSpecs[key]
        if (!spec) break
        else if (spec._service) {
            creators[key] = _makeActionCreator(key, spec._spec, spec._service)
        } else creators[key] = _makeActionCreator(key, spec)
    }

    return {
        types: Object.freeze(types),
        creators: Object.freeze(creators)
    }
}

// Register a service function for handling asynchronous actions.
// Returns an object that createFaction() will use to make the appropriate
// Promise-returning action creator
function useService(service, argSpecs) {
    if (typeof service !== 'function') {
        throw new Error('First arg to useService must be a function, got: ' +
                        JSON.stringify(service))
    }

    return {
        _service: service,
        _spec: argSpecs
    }
}

var exports = {
    create: createFaction,
    useService: useService,
    v: require('./lib/validators'),
    middleware: require('./lib/middleware'),
    ActionParamError: utils.ActionParamError
}

// Export for CommonJS, or else add a global faction variable:
if (typeof(module) !== 'undefined') module.exports = exports
else global.faction = exports

}(this))
<commit_msg>Refactoring to support onSuccess and onError for async action chaining.<commit_after>;(function(global) {       // IIFE for legacy non-module usage
'use strict'

var utils = require('./lib/utils')

// Validate the arguments passed in to an action creator against the schema
// that is declared in faction.create()
function _validate(paramsHash, spec) {
    var specKeys = Object.keys(spec)
    specKeys.forEach(function(k) {
        var validator = spec[k]
        // TODO: assign validated values to a cloned object?
        paramsHash[k] = validator(paramsHash[k])    // may throw ActionParamError
    })
}

// Return an action creator function
//
// If a service function is given, the action's payload will be a Promise, which
// is returned from the service function.
//
// Otherwise the action creator is fully synchronous, and the Object literal
// passed in to it will be the action payload.
function _makeActionCreator(type, options) {
    return function actionCreator(paramsHash) {
        var action = { type: type, meta: {} }    // payload is set below

        // If action argument is an error object, follow the FSA conventions:
        if (paramsHash instanceof Error) {
            action.error = true
            action.payload = paramsHash
            return action
        }

        paramsHash = paramsHash || {}

        // This will throw if validation fails:
        if (options.validators) _validate(paramsHash, options.validators)

        if (typeof options.service === 'function') {
            // The service function *must* return a Promise, or else we throw:
            var result = options.service(paramsHash)
            if (!utils.isPromise(result)) {
                throw new Error('Service for ' + type + ' did not return a Promise')
            }
            action.payload = result
        } else {
            action.payload = paramsHash
        }

        return action
    }
}

function createFaction(actionSpecs, options) {
    var types = {}
    var creators = {}

    for (var key in actionSpecs) {
        types[key] = key

        var spec = actionSpecs[key]
        if (!spec) break
        else if (spec.service) {
            creators[key] = _makeActionCreator(key, spec)
        } else creators[key] = _makeActionCreator(key, { validators: spec })
    }

    return {
        types: Object.freeze(types),
        creators: Object.freeze(creators)
    }
}

// Register a service function for handling asynchronous actions.
// Returns an object that createFaction() will use to make the appropriate
// Promise-returning action creator
function useService(service, argSpecs) {
    if (typeof service !== 'function') {
        throw new Error('First arg to useService must be a function, got: ' +
                        JSON.stringify(service))
    }

    return {
        service: service,
        validators: argSpecs,
    }
}

var exports = {
    create: createFaction,
    useService: useService,
    v: require('./lib/validators'),
    middleware: require('./lib/middleware'),
    ActionParamError: utils.ActionParamError
}

// Export for CommonJS, or else add a global faction variable:
if (typeof(module) !== 'undefined') module.exports = exports
else global.faction = exports

}(this))
<|endoftext|>


<commit_before>var util     = require("util");
var postgres = require("./postgres");

exports.Driver = Driver;

function Driver(config, connection, opts) {
	postgres.Driver.call(this, config, connection, opts);
}

util.inherits(Driver, postgres.Driver);

Driver.prototype.insert = function (table, data, id_prop, cb) {
	var q = this.query.insert()
	                  .into(table)
	                  .set(data)
	                  .build();

	if (this.opts.debug) {
		require("../../Debug").sql('postgres', q);
	}
	this.db.query(q, function (err, result) {
		if (err) {
			return cb(err);
		}

		this.db.query("SELECT LASTVAL() AS id", function (err, result) {
			return cb(null, {
				id: !err && result.rows[0].id || null
			});
		});
	}.bind(this));
};
<commit_msg>Update redshift driver to use new postgres driver<commit_after>var util     = require("util");
var postgres = require("./postgres");

exports.Driver = Driver;

function Driver(config, connection, opts) {
	postgres.Driver.call(this, config, connection, opts);
}

util.inherits(Driver, postgres.Driver);

Driver.prototype.insert = function (table, data, id_prop, cb) {
	var q = this.query.insert()
	                  .into(table)
	                  .set(data)
	                  .build();

	if (this.opts.debug) {
		require("../../Debug").sql('postgres', q);
	}
	this.execQuery(q, function (err, result) {
		if (err) {
			return cb(err);
		}

		this.execQuery("SELECT LASTVAL() AS id", function (err, results) {
			return cb(null, {
				id: !err && results[0].id || null
			});
		});
	}.bind(this));
};
<|endoftext|>


<commit_before>'use strict';

var express = require('express');
var parser = require('body-parser');
var http = require('http');

var app = express();

app.use(parser.urlencoded({
    extended: true
}));
app.use(parser.json());

var port = process.env.PORT || 3000;

var router = express.Router();

router.use(function (req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, OPTIONS, DELETE');

    console.log(req.method + ' ' + req.url);

    next();
});

var hiscoresUrl = 'http://services.runescape.com/m=hiscore_oldschool/index_lite.ws?player=';

router.route('/stats/:username').get(function (req, res) {
    getStats(req.params.username, function (data) {
        if (data.length === 0) {
            return res.status(404).json({
                message: 'Player not found.'
            });
        }

        var skills = ['overall', 'attack', 'defence', 'strength', 'constitution', 'ranged', 'prayer', 'magic', 'cooking', 'woodcutting', 'fletching', 'fishing', 'firemaking', 'crafting', 'smithing', 'mining', 'herblore', 'agility', 'thieving', 'slayer', 'farming', 'runecrafting', 'hunter', 'construction'];

        var raw = data.join().split('\n');
        var stats = {};

        for (var i in skills) {
            var row = raw[i].split(',');

            stats[skills[i]] = {
                rank: row[0],
                level: row[1],
                xp: row[2]
            };
        }

        return res.status(200).json(stats);
    });

    function getStats(username, callback) {
        http.get(hiscoresUrl + username, function (res) {
            var data = [];

            res.on('data', function (chunk) {
                data.push(chunk);
            });

            res.on('end', function () {
                if (res.statusCode === 404) {
                    data = [];
                }

                callback(data);
            });
        }).end();
    }
});

function extractStats(raw) {
    var stats = {};

    var skills = ['overall', 'attack', 'defence', 'strength', 'constitution', 'ranged', 'prayer', 'magic', 'cooking', 'woodcutting', 'fletching', 'fishing', 'firemaking', 'crafting', 'smithing', 'mining', 'herblore', 'agility', 'thieving', 'slayer', 'farming', 'runecrafting', 'hunter', 'construction'];

    for (var i in skills) {
        var row = raw[i].split(',');

        stats[skills[i]] = {
            rank: row[0],
            level: row[1],
            xp: row[2]
        };
    }

    return stats;
}

app.use('/', router);

app.listen(port);
console.log('Running on localhost:' + port);<commit_msg>Remove duplicated parsing code<commit_after>'use strict';

var express = require('express');
var parser = require('body-parser');
var http = require('http');

var app = express();

app.use(parser.urlencoded({
    extended: true
}));
app.use(parser.json());

var port = process.env.PORT || 3000;

var router = express.Router();

router.use(function (req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, OPTIONS, DELETE');

    console.log(req.method + ' ' + req.url);

    next();
});

var hiscoresUrl = 'http://services.runescape.com/m=hiscore_oldschool/index_lite.ws?player=';

router.route('/stats/:username').get(function (req, res) {
    getStats(req.params.username, function (data) {
        if (data.length === 0) {
            return res.status(404).json({
                message: 'Player not found.'
            });
        }

        var skills = ['overall', 'attack', 'defence', 'strength', 'constitution', 'ranged', 'prayer', 'magic', 'cooking', 'woodcutting', 'fletching', 'fishing', 'firemaking', 'crafting', 'smithing', 'mining', 'herblore', 'agility', 'thieving', 'slayer', 'farming', 'runecrafting', 'hunter', 'construction'];

        var raw = data.join().split('\n');
        var stats = {};

        for (var i in skills) {
            var row = raw[i].split(',');

            stats[skills[i]] = {
                rank: row[0],
                level: row[1],
                xp: row[2]
            };
        }

        return res.status(200).json(stats);
    });

    function getStats(username, callback) {
        http.get(hiscoresUrl + username, function (res) {
            var data = [];

            res.on('data', function (chunk) {
                data.push(chunk);
            });

            res.on('end', function () {
                if (res.statusCode === 404) {
                    data = [];
                }

                callback(data);
            });
        }).end();
    }
});

app.use('/', router);

app.listen(port);
console.log('Running on localhost:' + port);<|endoftext|>


<commit_before>var money = 10;
var tickSpeedCost = 1000;
var tickspeed = 1000;
var firstCost = 10;
var secondCost = 100;
var thirdCost = 10000;
var fourthCost = 1000000;
var firstAmount = 0;
var secondAmount = 0;
var thirdAmount = 0;
var fourthAmount = 0;
var interval;
function updateMoney() {
	var element = document.getElementById("coinAmount");
  element.innerHTML = 'You have ' + shorten(Math.round(money * 10) /10) + ' antimatter.'
}

function updateCoinPerSec() {
	var element = document.getElementById("coinsPerSec")
  element.innerHTML = 'You are getting ' + shorten(Math.round(firstAmount*(1000/tickspeed)*10)/10) + ' antimatter per second.'
}

function updateDimensions() {
	document.getElementById("firstAmount").innerHTML = shorten(firstAmount);
  document.getElementById("secondAmount").innerHTML = shorten(secondAmount);
  document.getElementById("thirdAmount").innerHTML = shorten(thirdAmount);
  document.getElementById("fourthAmount").innerHTML = shorten(fourthAmount);
}

function updateInterval() {
clearInterval(interval)
interval = setInterval(function() {
	firstAmount += secondAmount;
  secondAmount += thirdAmount;
  thirdAmount += fourthAmount;
  updateDimensions();
}, tickspeed*10);
}

function updateCosts() {
document.getElementById("third").innerHTML = 'Cost ' + shorten(thirdCost)
document.getElementById("fourth").innerHTML = 'Cost ' + shorten(fourthCost)
}

function shorten(x) {
if (x < 1000) return x;
else if (x < 1000000) return Math.round(x/1000 * 100)/100 + ' K';
else if (x < 1000000000) return Math.round(x/1000000 * 100)/100 + ' M';
else if (x < 1000000000000) return Math.round(x/1000000000 * 100)/100 + ' B';
}

document.getElementById("tickSpeed").onclick = function() {
	if (money >= tickSpeedCost) {
  money -= tickSpeedCost;
  tickspeed = tickspeed * .9;
  tickSpeedCost = tickSpeedCost*5;
  document.getElementById("tickSpeedAmount").innerHTML = 'Tickspeed: ' + tickspeed;
  document.getElementById("tickSpeed").innerHTML = 'Cost: ' + shorten(tickSpeedCost);
  updateMoney();
  updateInterval();
  }
}

document.getElementById("first").onclick = function() {
	if (money >= firstCost) {
	firstAmount++;
  money -= firstCost;
  firstCost = Math.round(firstCost*1.15 * 10) / 10;
  updateCoinPerSec();
  var element = document.getElementById("first");
  element.innerHTML = 'Cost: ' + shorten(firstCost);
  updateMoney();
  document.getElementById("firstAmount").innerHTML = firstAmount;
  }
}

document.getElementById("second").onclick = function() {
	if (money >= secondCost) {
	secondAmount++;
  money -= secondCost;
  secondCost = Math.round(secondCost*1.15 * 10) / 10;
  updateCoinPerSec();
  var element = document.getElementById("second");
  element.innerHTML = 'Cost: ' + shorten(secondCost);
  updateMoney();
  document.getElementById("secondAmount").innerHTML = secondAmount;
  }
}

document.getElementById("third").onclick = function() {
  if (money >= thirdCost) {
    thirdAmount++;
    money -= thirdCost;
    thirdCost = Math.round(thirdCost * 1.15 * 10) / 10;
    updateCoinPerSec();
    var element = document.getElementById("third");
    element.innerHTML = 'Cost: ' + shorten(thirdCost);
    updateMoney();
    document.getElementById("thirdAmount").innerHTML = thirdAmount;
  }
}

document.getElementById("fourth").onclick = function() {
  if (money >= fourthCost) {
    fourthAmount++;
    money -= fourthCost;
    fourthCost = Math.round(fourthCost * 1.15 * 10) / 10;
    updateCoinPerSec();
    var element = document.getElementById("fourth");
    element.innerHTML = 'Fourth Dimension: ' + shorten(fourthCost);
    updateMoney();
    document.getElementById("fourthAmount").innerHTML = fourthAmount;
  }
}

setInterval(function() {
	money += firstAmount/(tickspeed/100);
  updateMoney();
  updateCoinPerSec();;
}, 100);

updateCosts();
updateInterval();
<commit_msg>Update game.js<commit_after>var money = 10;
var tickSpeedCost = 1000;
var tickspeed = 1000;
var firstCost = 10;
var secondCost = 100;
var thirdCost = 10000;
var fourthCost = 1000000;
var firstAmount = 0;
var secondAmount = 0;
var thirdAmount = 0;
var fourthAmount = 0;
var interval;
var firstButton = document.getElementById("first")
var secondButton = document.getElementById("second")
var thirdButton = document.getElementById("third")
var fourthButton = document.getElementById("fourth")
function updateMoney() {
	var element = document.getElementById("coinAmount");
  element.innerHTML = 'You have ' + shorten(Math.round(money * 10) /10) + ' antimatter.'
}

function updateCoinPerSec() {
	var element = document.getElementById("coinsPerSec")
  element.innerHTML = 'You are getting ' + shorten(Math.round(firstAmount*(1000/tickspeed)*10)/10) + ' antimatter per second.'
}

function updateDimensions() {
	document.getElementById("firstAmount").innerHTML = shorten(firstAmount);
  document.getElementById("secondAmount").innerHTML = shorten(secondAmount);
  document.getElementById("thirdAmount").innerHTML = shorten(thirdAmount);
  document.getElementById("fourthAmount").innerHTML = shorten(fourthAmount);
}

function updateInterval() {
clearInterval(interval)
interval = setInterval(function() {
	firstAmount += secondAmount;
  secondAmount += thirdAmount;
  thirdAmount += fourthAmount;
  updateDimensions();
}, tickspeed*10);
}

function updateCosts() {
document.getElementById("third").innerHTML = 'Cost ' + shorten(thirdCost)
document.getElementById("fourth").innerHTML = 'Cost ' + shorten(fourthCost)
}

function shorten(x) {
if (x < 1000) return x;
else if (x < 1000000) return Math.round(x/1000 * 100)/100 + ' K';
else if (x < 1000000000) return Math.round(x/1000000 * 100)/100 + ' M';
else if (x < 1000000000000) return Math.round(x/1000000000 * 100)/100 + ' B';
}

document.getElementById("tickSpeed").onclick = function() {
	if (money >= tickSpeedCost) {
  money -= tickSpeedCost;
  tickspeed = tickspeed * .9;
  tickSpeedCost = tickSpeedCost*5;
  document.getElementById("tickSpeedAmount").innerHTML = 'Tickspeed: ' + tickspeed;
  document.getElementById("tickSpeed").innerHTML = 'Cost: ' + shorten(tickSpeedCost);
  updateMoney();
  updateInterval();
  }
}

document.getElementById("first").onclick = function() {
	if (money >= firstCost) {
	firstAmount++;
  money -= firstCost;
  firstCost = Math.round(firstCost*1.15 * 10) / 10;
  updateCoinPerSec();
  var element = document.getElementById("first");
  element.innerHTML = 'Cost: ' + shorten(firstCost);
  updateMoney();
  document.getElementById("firstAmount").innerHTML = firstAmount;
  }
}

document.getElementById("second").onclick = function() {
	if (money >= secondCost) {
	secondAmount++;
  money -= secondCost;
  secondCost = Math.round(secondCost*1.15 * 10) / 10;
  updateCoinPerSec();
  var element = document.getElementById("second");
  element.innerHTML = 'Cost: ' + shorten(secondCost);
  updateMoney();
  document.getElementById("secondAmount").innerHTML = secondAmount;
  }
}

document.getElementById("third").onclick = function() {
  if (money >= thirdCost) {
    thirdAmount++;
    money -= thirdCost;
    thirdCost = Math.round(thirdCost * 1.15 * 10) / 10;
    updateCoinPerSec();
    var element = document.getElementById("third");
    element.innerHTML = 'Cost: ' + shorten(thirdCost);
    updateMoney();
    document.getElementById("thirdAmount").innerHTML = thirdAmount;
  }
}

document.getElementById("fourth").onclick = function() {
  if (money >= fourthCost) {
    fourthAmount++;
    money -= fourthCost;
    fourthCost = Math.round(fourthCost * 1.15 * 10) / 10;
    updateCoinPerSec();
    var element = document.getElementById("fourth");
    element.innerHTML = 'Fourth Dimension: ' + shorten(fourthCost);
    updateMoney();
    document.getElementById("fourthAmount").innerHTML = fourthAmount;
  }
}

setInterval(function() {
	money += firstAmount/(tickspeed/100);
  updateMoney();
  updateCoinPerSec();
}, 100);

updateCosts();
updateInterval();
<|endoftext|>


<commit_before>// Copyright 2016 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

// [START functions_slack_setup]
const {google} = require('googleapis');
const {verifyRequestSignature} = require('@slack/events-api');

// Get a reference to the Knowledge Graph Search component
const kgsearch = google.kgsearch('v1');
// [END functions_slack_setup]

// [START functions_slack_format]
/**
 * Format the Knowledge Graph API response into a richly formatted Slack message.
 *
 * @param {string} query The user's search query.
 * @param {object} response The response from the Knowledge Graph API.
 * @returns {object} The formatted message.
 */
const formatSlackMessage = (query, response) => {
  let entity;

  // Extract the first entity from the result list, if any
  if (
    response &&
    response.data &&
    response.data.itemListElement &&
    response.data.itemListElement.length > 0
  ) {
    entity = response.data.itemListElement[0].result;
  }

  // Prepare a rich Slack message
  // See https://api.slack.com/docs/message-formatting
  const slackMessage = {
    response_type: 'in_channel',
    text: `Query: ${query}`,
    attachments: [],
  };

  if (entity) {
    const attachment = {
      color: '#3367d6',
    };
    if (entity.name) {
      attachment.title = entity.name;
      if (entity.description) {
        attachment.title = `${attachment.title}: ${entity.description}`;
      }
    }
    if (entity.detailedDescription) {
      if (entity.detailedDescription.url) {
        attachment.title_link = entity.detailedDescription.url;
      }
      if (entity.detailedDescription.articleBody) {
        attachment.text = entity.detailedDescription.articleBody;
      }
    }
    if (entity.image && entity.image.contentUrl) {
      attachment.image_url = entity.image.contentUrl;
    }
    slackMessage.attachments.push(attachment);
  } else {
    slackMessage.attachments.push({
      text: 'No results match your query...',
    });
  }

  return slackMessage;
};
// [END functions_slack_format]

// [START functions_verify_webhook]
/**
 * Verify that the webhook request came from Slack.
 *
 * @param {object} req Cloud Function request object.
 * @param {string} req.headers Headers Slack SDK uses to authenticate request.
 * @param {string} req.rawBody Raw body of webhook request to check signature against.
 */
const verifyWebhook = (req) => {
  const signature = {
    signingSecret: process.env.SLACK_SECRET,
    requestSignature: req.headers['x-slack-signature'],
    requestTimestamp: req.headers['x-slack-request-timestamp'],
    body: req.rawBody,
  };

  if (!verifyRequestSignature(signature)) {
    const error = new Error('Invalid credentials');
    error.code = 401;
    throw error;
  }
};
// [END functions_verify_webhook]

// [START functions_slack_request]
/**
 * Send the user's search query to the Knowledge Graph API.
 *
 * @param {string} query The user's search query.
 */
const makeSearchRequest = (query) => {
  return new Promise((resolve, reject) => {
    kgsearch.entities.search(
      {
        auth: process.env.KG_API_KEY,
        query: query,
        limit: 1,
      },
      (err, response) => {
        console.log(err);
        if (err) {
          reject(err);
          return;
        }

        // Return a formatted message
        resolve(formatSlackMessage(query, response));
      }
    );
  });
};
// [END functions_slack_request]

// [START functions_slack_search]
/**
 * Receive a Slash Command request from Slack.
 *
 * Trigger this function by creating a Slack slash command with this URL:
 * https://[YOUR_REGION].[YOUR_PROJECT_ID].cloudfunctions.net/kgsearch
 *
 * @param {object} req Cloud Function request object.
 * @param {object} req.body The request payload.
 * @param {string} req.rawBody Raw request payload used to validate Slack's message signature.
 * @param {string} req.body.text The user's search query.
 * @param {object} res Cloud Function response object.
 */
exports.kgSearch = async (req, res) => {
  try {
    if (req.method !== 'POST') {
      const error = new Error('Only POST requests are accepted');
      error.code = 405;
      throw error;
    }

    // Verify that this request came from Slack
    verifyWebhook(req);

    // Make the request to the Knowledge Graph Search API
    const response = await makeSearchRequest(req.body.text);

    // Send the formatted message back to Slack
    res.json(response);

    return Promise.resolve();
  } catch (err) {
    console.error(err);
    res.status(err.code || 500).send(err);
    return Promise.reject(err);
  }
};
// [END functions_slack_search]
<commit_msg>Use correct GCF URL in Slack sample (#1756)<commit_after>// Copyright 2016 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

// [START functions_slack_setup]
const {google} = require('googleapis');
const {verifyRequestSignature} = require('@slack/events-api');

// Get a reference to the Knowledge Graph Search component
const kgsearch = google.kgsearch('v1');
// [END functions_slack_setup]

// [START functions_slack_format]
/**
 * Format the Knowledge Graph API response into a richly formatted Slack message.
 *
 * @param {string} query The user's search query.
 * @param {object} response The response from the Knowledge Graph API.
 * @returns {object} The formatted message.
 */
const formatSlackMessage = (query, response) => {
  let entity;

  // Extract the first entity from the result list, if any
  if (
    response &&
    response.data &&
    response.data.itemListElement &&
    response.data.itemListElement.length > 0
  ) {
    entity = response.data.itemListElement[0].result;
  }

  // Prepare a rich Slack message
  // See https://api.slack.com/docs/message-formatting
  const slackMessage = {
    response_type: 'in_channel',
    text: `Query: ${query}`,
    attachments: [],
  };

  if (entity) {
    const attachment = {
      color: '#3367d6',
    };
    if (entity.name) {
      attachment.title = entity.name;
      if (entity.description) {
        attachment.title = `${attachment.title}: ${entity.description}`;
      }
    }
    if (entity.detailedDescription) {
      if (entity.detailedDescription.url) {
        attachment.title_link = entity.detailedDescription.url;
      }
      if (entity.detailedDescription.articleBody) {
        attachment.text = entity.detailedDescription.articleBody;
      }
    }
    if (entity.image && entity.image.contentUrl) {
      attachment.image_url = entity.image.contentUrl;
    }
    slackMessage.attachments.push(attachment);
  } else {
    slackMessage.attachments.push({
      text: 'No results match your query...',
    });
  }

  return slackMessage;
};
// [END functions_slack_format]

// [START functions_verify_webhook]
/**
 * Verify that the webhook request came from Slack.
 *
 * @param {object} req Cloud Function request object.
 * @param {string} req.headers Headers Slack SDK uses to authenticate request.
 * @param {string} req.rawBody Raw body of webhook request to check signature against.
 */
const verifyWebhook = (req) => {
  const signature = {
    signingSecret: process.env.SLACK_SECRET,
    requestSignature: req.headers['x-slack-signature'],
    requestTimestamp: req.headers['x-slack-request-timestamp'],
    body: req.rawBody,
  };

  if (!verifyRequestSignature(signature)) {
    const error = new Error('Invalid credentials');
    error.code = 401;
    throw error;
  }
};
// [END functions_verify_webhook]

// [START functions_slack_request]
/**
 * Send the user's search query to the Knowledge Graph API.
 *
 * @param {string} query The user's search query.
 */
const makeSearchRequest = (query) => {
  return new Promise((resolve, reject) => {
    kgsearch.entities.search(
      {
        auth: process.env.KG_API_KEY,
        query: query,
        limit: 1,
      },
      (err, response) => {
        console.log(err);
        if (err) {
          reject(err);
          return;
        }

        // Return a formatted message
        resolve(formatSlackMessage(query, response));
      }
    );
  });
};
// [END functions_slack_request]

// [START functions_slack_search]
/**
 * Receive a Slash Command request from Slack.
 *
 * Trigger this function by creating a Slack slash command with this URL:
 * https://[YOUR_REGION]-[YOUR_PROJECT_ID].cloudfunctions.net/kgSearch
 *
 * @param {object} req Cloud Function request object.
 * @param {object} req.body The request payload.
 * @param {string} req.rawBody Raw request payload used to validate Slack's message signature.
 * @param {string} req.body.text The user's search query.
 * @param {object} res Cloud Function response object.
 */
exports.kgSearch = async (req, res) => {
  try {
    if (req.method !== 'POST') {
      const error = new Error('Only POST requests are accepted');
      error.code = 405;
      throw error;
    }

    // Verify that this request came from Slack
    verifyWebhook(req);

    // Make the request to the Knowledge Graph Search API
    const response = await makeSearchRequest(req.body.text);

    // Send the formatted message back to Slack
    res.json(response);

    return Promise.resolve();
  } catch (err) {
    console.error(err);
    res.status(err.code || 500).send(err);
    return Promise.reject(err);
  }
};
// [END functions_slack_search]
<|endoftext|>


<commit_before>import React from 'react';

import { Khadaj, niseko, Yajinni, Zerotorescue, blazyb } from 'CONTRIBUTORS';
import SpellLink from 'common/SpellLink';
import SPELLS from 'common/SPELLS';
import { change, date } from 'common/changelog';

export default [
  change(date(2019, 8, 6), 'Added essence Lucid Dreams.', [blazyb]),
  change(date(2019, 4, 9), <>Adding Holy Nova card and updating spreadsheet</>, [Khadaj]),
  change(date(2019, 3, 12), <>Fixed an error in the <SpellLink id={SPELLS.PRAYERFUL_LITANY.id} /> analyzer.</>, [Zerotorescue]),
  change(date(2018, 12, 18), <>Adding <SpellLink id={SPELLS.PROMISE_OF_DELIVERANCE.id} /> and <SpellLink id={SPELLS.DEATH_DENIED.id} />.</>, [Khadaj]),
  change(date(2018, 11, 5), 'Adding Renew suggestion.', [Khadaj]),
  change(date(2018, 10, 22), 'Adding mana efficiency tab.', [Khadaj]),
  change(date(2018, 9, 13), 'Adding Holy Priest Azerite traits.', [Khadaj]),
  change(date(2018, 9, 7), 'Creating Holy Priest spreadsheet export.', [Khadaj]),
  change(date(2018, 9, 6), 'Updating base Holy Priest checklist.', [Khadaj]),
  change(date(2018, 7, 28), <>Added suggestion for maintaining <SpellLink id={SPELLS.PERSEVERANCE_TALENT.id} /> and <SpellLink id={SPELLS.POWER_WORD_FORTITUDE.id} /> buffs.</>, [Yajinni]),
  change(date(2018, 7, 28), <>Added Stat box for <SpellLink id={SPELLS.COSMIC_RIPPLE_TALENT.id} />.</>, [Yajinni]),
  change(date(2018, 7, 26), <>Added Stat box for <SpellLink id={SPELLS.TRAIL_OF_LIGHT_TALENT.id} />.</>, [Yajinni]),
  change(date(2018, 7, 5), 'Updated Holy Priest spells for BFA and accounted for Holy Words cooldown reductions.', [niseko]),
];
<commit_msg>Update CHANGELOG.js<commit_after>import React from 'react';

import { Khadaj, niseko, Yajinni, Zerotorescue, blazyb } from 'CONTRIBUTORS';
import SpellLink from 'common/SpellLink';
import SPELLS from 'common/SPELLS';
import { change, date } from 'common/changelog';

export default [
  change(date(2019, 8, 12), 'Added essence Lucid Dreams.', [blazyb]),
  change(date(2019, 4, 9), <>Adding Holy Nova card and updating spreadsheet</>, [Khadaj]),
  change(date(2019, 3, 12), <>Fixed an error in the <SpellLink id={SPELLS.PRAYERFUL_LITANY.id} /> analyzer.</>, [Zerotorescue]),
  change(date(2018, 12, 18), <>Adding <SpellLink id={SPELLS.PROMISE_OF_DELIVERANCE.id} /> and <SpellLink id={SPELLS.DEATH_DENIED.id} />.</>, [Khadaj]),
  change(date(2018, 11, 5), 'Adding Renew suggestion.', [Khadaj]),
  change(date(2018, 10, 22), 'Adding mana efficiency tab.', [Khadaj]),
  change(date(2018, 9, 13), 'Adding Holy Priest Azerite traits.', [Khadaj]),
  change(date(2018, 9, 7), 'Creating Holy Priest spreadsheet export.', [Khadaj]),
  change(date(2018, 9, 6), 'Updating base Holy Priest checklist.', [Khadaj]),
  change(date(2018, 7, 28), <>Added suggestion for maintaining <SpellLink id={SPELLS.PERSEVERANCE_TALENT.id} /> and <SpellLink id={SPELLS.POWER_WORD_FORTITUDE.id} /> buffs.</>, [Yajinni]),
  change(date(2018, 7, 28), <>Added Stat box for <SpellLink id={SPELLS.COSMIC_RIPPLE_TALENT.id} />.</>, [Yajinni]),
  change(date(2018, 7, 26), <>Added Stat box for <SpellLink id={SPELLS.TRAIL_OF_LIGHT_TALENT.id} />.</>, [Yajinni]),
  change(date(2018, 7, 5), 'Updated Holy Priest spells for BFA and accounted for Holy Words cooldown reductions.', [niseko]),
];
<|endoftext|>


<commit_before>import _ from 'lodash';
import React from 'react';
import styles from './App.css';
import GenreSelector from './containers/genre_selector'
import MusicPlayerGroup from './containers/music_player_group';

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {test: 'foo'};
  }

  check(answer) {
    // if user guesses a song correctly make corresponding music player stop playing
    // and calculate points
    console.log(answer);
  }

  render() {
    // Not sure want to throttle answer checking -- will effect scoring
    const answerCheck = _.debounce((answer) => { this.check(answer) }, 300);

    return (

        <GenreSelector />
        <MusicPlayerGroup />

    );
  }
}
<commit_msg>import header component into App<commit_after>import _ from 'lodash';
import React from 'react';
import styles from './App.css';
import GenreSelector from './containers/genre_selector'
import MusicPlayerGroup from './containers/music_player_group';
import Header from './containers/header';

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {test: 'foo'};
  }

  check(answer) {
    // if user guesses a song correctly make corresponding music player stop playing
    // and calculate points
    console.log(answer);
  }

  render() {
    // Not sure want to throttle answer checking -- will effect scoring
    const answerCheck = _.debounce((answer) => { this.check(answer) }, 300);

    return (

        <GenreSelector />
        <MusicPlayerGroup />

    );
  }
}
<|endoftext|>


<commit_before>// ==UserScript==
// @name        Reddit - Browse comments by parent
// @namespace   localhost
// @description Browse comments by parent (root) comments
// @include     https://*.reddit.com/r/*/comments/*
// @version     1
// @grant       none
// ==/UserScript==

function getPosition(element)
{
    return element.getBoundingClientRect().top + window.scrollY;
}

function goTo(next)
{
    var children = $("div[id^='siteTable_t3']").children();
    var current = $("html").scrollTop();

    if(next)
    {
        for(var i = 0; i < children.length; i += 2)
        {
            var top = getPosition(children[i]);

            if(top > current + 10)
            {
                $("html").scrollTop(top);
                return;
            }
        }
    }
    else
    {
        for(var i = 0; i < children.length; i += 2)
        {
            var top = getPosition(children[i]);

            if(top > current - 10)
            {
                if(i < 2)
                    return;

                var previousTop = getPosition(children[i - 2]);
                $("html").scrollTop(previousTop);
                return;
            }
        }
    }
}

var interval = window.setInterval(function() {
    if($("#NREFloat ul li").length == 0)
    {
        return;
    }

    window.clearInterval(interval);

    var previous = document.createElement("a");
    previous.style.cursor = "pointer";
    previous.style.fontSize = "20px";
    previous.appendChild(document.createTextNode("\u2190"));

    var next = document.createElement("a");
    next.style.cursor = "pointer";
    next.style.fontSize = "20px";
    next.appendChild(document.createTextNode("\u2192"));

    $(next).click(function() { goTo(true) } );

    var nrefloat = $("#NREFloat ul li")[0]
    nrefloat.appendChild(document.createElement("br"));
    nrefloat.appendChild(previous);
    nrefloat.appendChild(document.createElement("br"));
    nrefloat.appendChild(next);

    $(previous).click(function() { goTo(false) } );
}, 10000);<commit_msg>Reddit comments: support for threads<commit_after>// ==UserScript==
// @name        Reddit - Browse comments by parent
// @namespace   localhost
// @description Browse comments by parent (root) comments
// @include     https://*.reddit.com/r/*/comments/*
// @version     1
// @grant       none
// ==/UserScript==

function getPosition(element)
{
    return element.getBoundingClientRect().top + window.scrollY;
}

function goTo(next)
{
    var children = $("div[id^='siteTable_t3']").children();

    // If there's only two children, we're in a comment thread
    if(children.length == 2)
        var children = $("div[id^='siteTable_t1_']").eq(0).children();

    var current = $("html").scrollTop();

    if(next)
    {
        for(var i = 0; i < children.length; i += 2)
        {
            var top = getPosition(children[i]);

            if(top > current + 10)
            {
                $("html").scrollTop(top);
                return;
            }
        }
    }
    else
    {
        for(var i = 0; i < children.length; i += 2)
        {
            var top = getPosition(children[i]);

            if(top > current - 10)
            {
                if(i < 2)
                    return;

                var previousTop = getPosition(children[i - 2]);
                $("html").scrollTop(previousTop);
                return;
            }
        }
    }
}

var interval = window.setInterval(function() {
    if($("#NREFloat ul li").length == 0)
    {
        return;
    }

    window.clearInterval(interval);

    var previous = document.createElement("a");
    previous.style.cursor = "pointer";
    previous.style.fontSize = "20px";
    previous.appendChild(document.createTextNode("\u2190"));

    var next = document.createElement("a");
    next.style.cursor = "pointer";
    next.style.fontSize = "20px";
    next.appendChild(document.createTextNode("\u2192"));

    $(next).click(function() { goTo(true) } );

    var nrefloat = $("#NREFloat ul li")[0]
    nrefloat.appendChild(document.createElement("br"));
    nrefloat.appendChild(previous);
    nrefloat.appendChild(document.createElement("br"));
    nrefloat.appendChild(next);

    $(previous).click(function() { goTo(false) } );
}, 10000);<|endoftext|>


<commit_before>import { AUTHENTICATION } from '../constants/action_types'
import {
  loginToken,
  logout as logoutEndpoint,
  forgotPassword,
  refreshAuthToken,
} from '../networking/api'

export function cancelAuthRefresh() {
  return {
    type: AUTHENTICATION.CANCEL_REFRESH,
  }
}

export function clearAuthStore() {
  return {
    type: AUTHENTICATION.CLEAR_STORE,
  }
}

export function signIn(email, password) {
  return {
    type: AUTHENTICATION.SIGN_IN,
    payload: {
      email,
      password,
    },
  }
}

export function getUserCredentials(email, password, meta) {
  return {
    type: AUTHENTICATION.USER,
    payload: {
      endpoint: loginToken(email, password),
      method: 'POST',
      body: {
        email,
        password,
      },
    },
    meta,
  }
}

export function logout() {
  return {
    type: AUTHENTICATION.LOGOUT,
    payload: {
      endpoint: logoutEndpoint(),
      method: 'DELETE',
    },
    meta: {
      successAction: () => {
        localStorage.clear()
        requestAnimationFrame(() => {
          window.location.href = '/enter'
        })
      },
    },
  }
}

export function refreshAuthenticationToken(refreshToken) {
  return {
    type: AUTHENTICATION.REFRESH,
    payload: {
      endpoint: refreshAuthToken(refreshToken),
      method: 'POST',
      body: {
        refresh_token: refreshToken,
      },
    },
  }
}

export function scheduleAuthRefresh(refreshToken, timeout) {
  return {
    type: AUTHENTICATION.SCHEDULE_REFRESH,
    payload: {
      refreshToken,
      timeout,
    },
  }
}

export function sendForgotPasswordRequest(email) {
  return {
    type: AUTHENTICATION.FORGOT_PASSWORD,
    payload: {
      endpoint: forgotPassword(),
      method: 'POST',
      body: {
        email,
      },
    },
  }
}

<commit_msg>Be specific around the post options<commit_after>import { AUTHENTICATION } from '../constants/action_types'
import {
  loginToken,
  logout as logoutEndpoint,
  forgotPassword,
  refreshAuthToken,
} from '../networking/api'

export function cancelAuthRefresh() {
  return {
    type: AUTHENTICATION.CANCEL_REFRESH,
  }
}

export function clearAuthStore() {
  return {
    type: AUTHENTICATION.CLEAR_STORE,
  }
}

export function signIn(email, password) {
  return {
    type: AUTHENTICATION.SIGN_IN,
    payload: {
      method: 'POST',
      email,
      password,
    },
  }
}

export function getUserCredentials(email, password, meta) {
  return {
    type: AUTHENTICATION.USER,
    payload: {
      endpoint: loginToken(email, password),
      method: 'POST',
      body: {
        email,
        password,
      },
    },
    meta,
  }
}

export function logout() {
  return {
    type: AUTHENTICATION.LOGOUT,
    payload: {
      endpoint: logoutEndpoint(),
      method: 'DELETE',
    },
    meta: {
      successAction: () => {
        localStorage.clear()
        requestAnimationFrame(() => {
          window.location.href = '/enter'
        })
      },
    },
  }
}

export function refreshAuthenticationToken(refreshToken) {
  return {
    type: AUTHENTICATION.REFRESH,
    payload: {
      endpoint: refreshAuthToken(refreshToken),
      method: 'POST',
      body: {
        refresh_token: refreshToken,
      },
    },
  }
}

export function scheduleAuthRefresh(refreshToken, timeout) {
  return {
    type: AUTHENTICATION.SCHEDULE_REFRESH,
    payload: {
      refreshToken,
      timeout,
    },
  }
}

export function sendForgotPasswordRequest(email) {
  return {
    type: AUTHENTICATION.FORGOT_PASSWORD,
    payload: {
      endpoint: forgotPassword(),
      method: 'POST',
      body: {
        email,
      },
    },
  }
}

<|endoftext|>


<commit_before>import React from 'react';
import { connect } from 'react-redux';
import { Navbar, Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';

const mapStateToProps = ({ user }) => {
  return {
    user
  };
}

const WimfNavbar = ({ user }) => (
  <Navbar inverse>
    <Navbar.Header>
      <Navbar.Brand>
        What's in my Freezer?
      </Navbar.Brand>
      <Navbar.Toggle />
    </Navbar.Header>
    <Navbar.Collapse>

        <NavItem eventKey={1} href="#">Link</NavItem>
        <NavItem eventKey={2} href="#">Link</NavItem>

        <NavItem eventKey={1} href="#">Link Right</NavItem>
        <NavDropdown eventKey={3} title={user.name} id="basic-nav-dropdown">
          <MenuItem eventKey={3.1}>Action</MenuItem>
          <MenuItem eventKey={3.2}>Another action</MenuItem>
          <MenuItem eventKey={3.3}>Something else here</MenuItem>
          <MenuItem divider />
          <MenuItem eventKey={3.3}>Separated link</MenuItem>
        </NavDropdown>

    </Navbar.Collapse>
  </Navbar>
);

export default connect(mapStateToProps)(WimfNavbar);<commit_msg>add navbar component<commit_after>import React from 'react';
import { connect } from 'react-redux';
import { Navbar, Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';

const mapStateToProps = ({ user }) => {
  return {
    user
  };
}

const WimfNavbar = ({ user }) => (
  <Navbar inverse>
    <Navbar.Header>
      <Navbar.Brand>
        What's in my Freezer?
      </Navbar.Brand>
      <Navbar.Toggle />
    </Navbar.Header>
    <Navbar.Collapse>

        <NavItem eventKey={1} href="#">Link</NavItem>
        <NavItem eventKey={2} href="#">Link</NavItem>

        <NavItem eventKey={1} href="#">Link Right</NavItem>
        <NavDropdown eventKey={3} title={user.name} id="basic-nav-dropdown">
          <MenuItem eventKey={3.1}>Logout</MenuItem>
          <MenuItem eventKey={3.2}>Another action</MenuItem>
          <MenuItem eventKey={3.3}>Something else here</MenuItem>
          <MenuItem divider />
          <MenuItem eventKey={3.3}>Separated link</MenuItem>
        </NavDropdown>

    </Navbar.Collapse>
  </Navbar>
);

export default connect(mapStateToProps)(WimfNavbar);<|endoftext|>


<commit_before>const constants = require('./constants');
const parseSignature = require('./signature');

// TODO: use xmlbuilder

var xmlHeader =
  '<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"\n' +
  '    "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">';
var stdIfaces;

module.exports = function(msg, bus) {
  if (
    msg['interface'] === 'org.freedesktop.DBus.Introspectable' &&
    msg.member === 'Introspect'
  ) {
    if (msg.path === '/') msg.path = '';

    var resultXml = [xmlHeader];
    var nodes = {};
    var obj;
    // TODO: this is not very efficiant for large number of exported objects
    // need to build objects tree as they are exported and walk this tree on introspect request
    for (var path in bus.exportedObjects) {
      if (path.indexOf(msg.path) === 0) {
        // objects path starts with requested
        obj = bus.exportedObjects[msg.path];
        if (obj) {
          nodes[msg.path] = obj;
        } else {
          if (path[msg.path.length] !== '/') continue;
          var localPath = path.substr(msg.path.length);
          var pathParts = localPath.split('/');
          var localName = pathParts[1];
          nodes[localName] = null;
        }
      }
    }

    var length = Object.keys(nodes).length;
    if (length === 0) {
      resultXml.push('<node/>');
    } else if (length === 1) {
      obj = nodes[Object.keys(nodes)[0]];
      if (obj) {
        resultXml.push('<node>');
        for (var ifaceNode in obj) {
          resultXml.push(interfaceToXML(obj[ifaceNode][0]));
        }
        resultXml.push(stdIfaces);
        resultXml.push('</node>');
      } else {
        resultXml.push(
          '<node>\n  <node name="' + Object.keys(nodes)[0] + '"/>\n  </node>'
        );
      }
    } else {
      resultXml.push('<node>');
      for (var name in nodes) {
        if (nodes[name] === null) {
          resultXml.push('  <node name="' + name + '" />');
        } else {
          obj = nodes[name];
          resultXml.push('  <node name="' + name + '" >');
          for (var ifaceName in obj) {
            resultXml.push(interfaceToXML(obj[ifaceName][0]));
          }
          resultXml.push(stdIfaces);
          resultXml.push('  </node>');
        }
      }
      resultXml.push('</node>');
    }

    const introspectableReply = {
      type: constants.messageType.methodReturn,
      replySerial: msg.serial,
      destination: msg.sender,
      signature: 's',
      body: [resultXml.join('\n')]
    };
    bus.connection.message(introspectableReply);
    return 1;
  } else if (msg['interface'] === 'org.freedesktop.DBus.Properties') {
    var interfaceName = msg.body[0];
    const obj = bus.exportedObjects[msg.path];
    // TODO: !obj -> UnknownObject  http://www.freedesktop.org/wiki/Software/DBusBindingErrors
    if (!obj || !obj[interfaceName]) {
      // TODO:
      bus.sendError(
        msg,
        'org.freedesktop.DBus.Error.UnknownMethod',
        'Uh oh oh'
      );
      return 1;
    }
    var impl = obj[interfaceName][1];

    const propertiesReply = {
      type: constants.messageType.methodReturn,
      replySerial: msg.serial,
      destination: msg.sender
    };
    if (msg.member === 'Get' || msg.member === 'Set') {
      var propertyName = msg.body[1];
      var propType = obj[interfaceName][0].properties[propertyName];
      if (msg.member === 'Get') {
        var propValue = impl[propertyName];
        propertiesReply.signature = 'v';
        propertiesReply.body = [[propType, propValue]];
      } else {
        impl[propertyName] = 1234; // TODO: read variant and set property value
      }
    } else if (msg.member === 'GetAll') {
      propertiesReply.signature = 'a{sv}';
      var props = [];
      for (var p in obj[interfaceName][0].properties) {
        var propertySignature = obj[interfaceName][0].properties[p];
        props.push([p, [propertySignature, impl[p]]]);
      }
      propertiesReply.body = [props];
    }
    bus.connection.message(propertiesReply);
    return 1;
  } else if (msg['interface'] === 'org.freedesktop.DBus.Peer') {
    // TODO: implement bus.replyTo(srcMsg, signature, body) method
    const peerReply = {
      type: constants.messageType.methodReturn,
      replySerial: msg.serial,
      destination: msg.sender
    };
    if (msg.member === 'Ping') {
      // empty body
    } else if (msg.member === 'GetMachineId') {
      peerReply.signature = 's';
      peerReply.body = ['This is a machine id. TODO: implement'];
    }
    bus.connection.message(peerReply);
    return 1;
  }
  return 0;
};

// TODO: move to introspect.js
function interfaceToXML(iface) {
  var result = [];
  var dumpArgs = function(argsSignature, argsNames, direction) {
    if (!argsSignature) return;
    var args = parseSignature(argsSignature);
    args.forEach(function(arg, num) {
      var argName = argsNames ? argsNames[num] : direction + num;
      var dirStr = direction === 'signal' ? '' : '" direction="' + direction;
      result.push(
        '      <arg type="' +
          dumpSignature([arg]) +
          '" name="' +
          argName +
          dirStr +
          '" />'
      );
    });
  };
  result.push('  <interface name="' + iface.name + '">');
  if (iface.methods) {
    for (var methodName in iface.methods) {
      var method = iface.methods[methodName];
      result.push('    <method name="' + methodName + '">');
      dumpArgs(method[0], method[2], 'in');
      dumpArgs(method[1], method[3], 'out');
      result.push('    </method>');
    }
  }
  if (iface.signals) {
    for (var signalName in iface.signals) {
      var signal = iface.signals[signalName];
      result.push('    <signal name="' + signalName + '">');
      dumpArgs(signal[0], signal.slice(1), 'signal');
      result.push('    </signal>');
    }
  }
  if (iface.properties) {
    for (const propertyName in iface.properties) {
      // TODO: decide how to encode access
      result.push(
        '    <property name="' +
          propertyName +
          '" type="' +
          iface.properties[propertyName] +
          '" access="readwrite"/>'
      );
    }
  }
  result.push('  </interface>');
  return result.join('\n');
}

function dumpSignature(s) {
  var result = [];
  s.forEach(function(sig) {
    result.push(sig.type + dumpSignature(sig.child));
    if (sig.type === '{') result.push('}');
    if (sig.type === '(') result.push(')');
  });
  return result.join('');
}
module.exports.interfaceToXML = interfaceToXML;
stdIfaces =
  '  <interface name="org.freedesktop.DBus.Properties">\n    <method name="Get">\n      <arg type="s" name="interface_name" direction="in"/>\n      <arg type="s" name="property_name" direction="in"/>\n      <arg type="v" name="value" direction="out"/>\n    </method>\n    <method name="GetAll">\n      <arg type="s" name="interface_name" direction="in"/>\n      <arg type="a{sv}" name="properties" direction="out"/>\n    </method>\n    <method name="Set">\n      <arg type="s" name="interface_name" direction="in"/>\n      <arg type="s" name="property_name" direction="in"/>\n      <arg type="v" name="value" direction="in"/>\n    </method>\n    <signal name="PropertiesChanged">\n      <arg type="s" name="interface_name"/>\n      <arg type="a{sv}" name="changed_properties"/>\n      <arg type="as" name="invalidated_properties"/>\n    </signal>\n  </interface>\n  <interface name="org.freedesktop.DBus.Introspectable">\n    <method name="Introspect">\n      <arg type="s" name="xml_data" direction="out"/>\n    </method>\n  </interface>\n  <interface name="org.freedesktop.DBus.Peer">\n    <method name="Ping"/>\n    <method name="GetMachineId">\n      <arg type="s" name="machine_uuid" direction="out"/>\n    </method>\n  </interface>';
<commit_msg>Don't export interfaceToXML in stdifaces.js<commit_after>const constants = require('./constants');
const parseSignature = require('./signature');

// TODO: use xmlbuilder

var xmlHeader =
  '<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"\n' +
  '    "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">';
var stdIfaces;

module.exports = function(msg, bus) {
  if (
    msg['interface'] === 'org.freedesktop.DBus.Introspectable' &&
    msg.member === 'Introspect'
  ) {
    if (msg.path === '/') msg.path = '';

    var resultXml = [xmlHeader];
    var nodes = {};
    var obj;
    // TODO: this is not very efficiant for large number of exported objects
    // need to build objects tree as they are exported and walk this tree on introspect request
    for (var path in bus.exportedObjects) {
      if (path.indexOf(msg.path) === 0) {
        // objects path starts with requested
        obj = bus.exportedObjects[msg.path];
        if (obj) {
          nodes[msg.path] = obj;
        } else {
          if (path[msg.path.length] !== '/') continue;
          var localPath = path.substr(msg.path.length);
          var pathParts = localPath.split('/');
          var localName = pathParts[1];
          nodes[localName] = null;
        }
      }
    }

    var length = Object.keys(nodes).length;
    if (length === 0) {
      resultXml.push('<node/>');
    } else if (length === 1) {
      obj = nodes[Object.keys(nodes)[0]];
      if (obj) {
        resultXml.push('<node>');
        for (var ifaceNode in obj) {
          resultXml.push(interfaceToXML(obj[ifaceNode][0]));
        }
        resultXml.push(stdIfaces);
        resultXml.push('</node>');
      } else {
        resultXml.push(
          '<node>\n  <node name="' + Object.keys(nodes)[0] + '"/>\n  </node>'
        );
      }
    } else {
      resultXml.push('<node>');
      for (var name in nodes) {
        if (nodes[name] === null) {
          resultXml.push('  <node name="' + name + '" />');
        } else {
          obj = nodes[name];
          resultXml.push('  <node name="' + name + '" >');
          for (var ifaceName in obj) {
            resultXml.push(interfaceToXML(obj[ifaceName][0]));
          }
          resultXml.push(stdIfaces);
          resultXml.push('  </node>');
        }
      }
      resultXml.push('</node>');
    }

    const introspectableReply = {
      type: constants.messageType.methodReturn,
      replySerial: msg.serial,
      destination: msg.sender,
      signature: 's',
      body: [resultXml.join('\n')]
    };
    bus.connection.message(introspectableReply);
    return 1;
  } else if (msg['interface'] === 'org.freedesktop.DBus.Properties') {
    var interfaceName = msg.body[0];
    const obj = bus.exportedObjects[msg.path];
    // TODO: !obj -> UnknownObject  http://www.freedesktop.org/wiki/Software/DBusBindingErrors
    if (!obj || !obj[interfaceName]) {
      // TODO:
      bus.sendError(
        msg,
        'org.freedesktop.DBus.Error.UnknownMethod',
        'Uh oh oh'
      );
      return 1;
    }
    var impl = obj[interfaceName][1];

    const propertiesReply = {
      type: constants.messageType.methodReturn,
      replySerial: msg.serial,
      destination: msg.sender
    };
    if (msg.member === 'Get' || msg.member === 'Set') {
      var propertyName = msg.body[1];
      var propType = obj[interfaceName][0].properties[propertyName];
      if (msg.member === 'Get') {
        var propValue = impl[propertyName];
        propertiesReply.signature = 'v';
        propertiesReply.body = [[propType, propValue]];
      } else {
        impl[propertyName] = 1234; // TODO: read variant and set property value
      }
    } else if (msg.member === 'GetAll') {
      propertiesReply.signature = 'a{sv}';
      var props = [];
      for (var p in obj[interfaceName][0].properties) {
        var propertySignature = obj[interfaceName][0].properties[p];
        props.push([p, [propertySignature, impl[p]]]);
      }
      propertiesReply.body = [props];
    }
    bus.connection.message(propertiesReply);
    return 1;
  } else if (msg['interface'] === 'org.freedesktop.DBus.Peer') {
    // TODO: implement bus.replyTo(srcMsg, signature, body) method
    const peerReply = {
      type: constants.messageType.methodReturn,
      replySerial: msg.serial,
      destination: msg.sender
    };
    if (msg.member === 'Ping') {
      // empty body
    } else if (msg.member === 'GetMachineId') {
      peerReply.signature = 's';
      peerReply.body = ['This is a machine id. TODO: implement'];
    }
    bus.connection.message(peerReply);
    return 1;
  }
  return 0;
};

// TODO: move to introspect.js
function interfaceToXML(iface) {
  var result = [];
  var dumpArgs = function(argsSignature, argsNames, direction) {
    if (!argsSignature) return;
    var args = parseSignature(argsSignature);
    args.forEach(function(arg, num) {
      var argName = argsNames ? argsNames[num] : direction + num;
      var dirStr = direction === 'signal' ? '' : '" direction="' + direction;
      result.push(
        '      <arg type="' +
          dumpSignature([arg]) +
          '" name="' +
          argName +
          dirStr +
          '" />'
      );
    });
  };
  result.push('  <interface name="' + iface.name + '">');
  if (iface.methods) {
    for (var methodName in iface.methods) {
      var method = iface.methods[methodName];
      result.push('    <method name="' + methodName + '">');
      dumpArgs(method[0], method[2], 'in');
      dumpArgs(method[1], method[3], 'out');
      result.push('    </method>');
    }
  }
  if (iface.signals) {
    for (var signalName in iface.signals) {
      var signal = iface.signals[signalName];
      result.push('    <signal name="' + signalName + '">');
      dumpArgs(signal[0], signal.slice(1), 'signal');
      result.push('    </signal>');
    }
  }
  if (iface.properties) {
    for (const propertyName in iface.properties) {
      // TODO: decide how to encode access
      result.push(
        '    <property name="' +
          propertyName +
          '" type="' +
          iface.properties[propertyName] +
          '" access="readwrite"/>'
      );
    }
  }
  result.push('  </interface>');
  return result.join('\n');
}

function dumpSignature(s) {
  var result = [];
  s.forEach(function(sig) {
    result.push(sig.type + dumpSignature(sig.child));
    if (sig.type === '{') result.push('}');
    if (sig.type === '(') result.push(')');
  });
  return result.join('');
}
stdIfaces =
  '  <interface name="org.freedesktop.DBus.Properties">\n    <method name="Get">\n      <arg type="s" name="interface_name" direction="in"/>\n      <arg type="s" name="property_name" direction="in"/>\n      <arg type="v" name="value" direction="out"/>\n    </method>\n    <method name="GetAll">\n      <arg type="s" name="interface_name" direction="in"/>\n      <arg type="a{sv}" name="properties" direction="out"/>\n    </method>\n    <method name="Set">\n      <arg type="s" name="interface_name" direction="in"/>\n      <arg type="s" name="property_name" direction="in"/>\n      <arg type="v" name="value" direction="in"/>\n    </method>\n    <signal name="PropertiesChanged">\n      <arg type="s" name="interface_name"/>\n      <arg type="a{sv}" name="changed_properties"/>\n      <arg type="as" name="invalidated_properties"/>\n    </signal>\n  </interface>\n  <interface name="org.freedesktop.DBus.Introspectable">\n    <method name="Introspect">\n      <arg type="s" name="xml_data" direction="out"/>\n    </method>\n  </interface>\n  <interface name="org.freedesktop.DBus.Peer">\n    <method name="Ping"/>\n    <method name="GetMachineId">\n      <arg type="s" name="machine_uuid" direction="out"/>\n    </method>\n  </interface>';
<|endoftext|>


<commit_before>var ghPages = require('gulp-gh-pages')
var gulp    = require('gulp')
var open    = require('open')
var os      = require('os')
var path    = require('path')

var deployTask = function() {
  var pkg = require(path.resolve(process.env.PWD, 'package.json'))

  var settings = {
    url: pkg.homepage,
    src: path.resolve(process.env.PWD, PATH_CONFIG.dest, '**/*'),
    ghPages: {
      cacheDir: path.join(os.tmpdir(), pkg.name)
    }
  }

  return gulp.src(settings.src)
    .pipe(ghPages(settings.ghPages))
    .on('end', function(){
      open(settings.url)
    })
}

gulp.task('deploy', ['production'], deployTask)
module.exports = deployTask
<commit_msg>Remove open from deploy task<commit_after>var ghPages = require('gulp-gh-pages')
var gulp    = require('gulp')
var os      = require('os')
var path    = require('path')

var deployTask = function() {
  var pkg = require(path.resolve(process.env.PWD, 'package.json'))

  var settings = {
    url: pkg.homepage,
    src: path.resolve(process.env.PWD, PATH_CONFIG.finalDest, '**/*'),
    ghPages: {
      cacheDir: path.join(os.tmpdir(), pkg.name)
    }
  }

  return gulp.src(settings.src)
    .pipe(ghPages(settings.ghPages))
}

gulp.task('deploy', ['production'], deployTask)
module.exports = deployTask
<|endoftext|>


<commit_before>var config    = require("./config/config")
  , Sequelize = require("../index")

describe('Sequelize', function() {
  it('should pass the global options correctly', function() {
    var sequelize = new Sequelize(config.database, config.username, config.password, {
      logging: false,
      define: { underscored:true }
    })
    var Model = sequelize.define('model', {name: Sequelize.STRING})
    expect(Model.options.underscored).toBeTruthy()
  })
})
<commit_msg>test for correct port and host passing<commit_after>var config    = require("./config/config")
  , Sequelize = require("../index")

describe('Sequelize', function() {
  it('should pass the global options correctly', function() {
    var sequelize = new Sequelize(config.database, config.username, config.password, {
      logging: false,
      define: { underscored:true }
    })
    var Model = sequelize.define('model', {name: Sequelize.STRING})
    expect(Model.options.underscored).toBeTruthy()
  })

  it('should correctly set the host and the port', function() {
    var options   = { host: '127.0.0.1', port: 1234 }
      , sequelize = new Sequelize(config.database, config.username, config.password, options)

    expect(sequelize.config.host).toEqual(options.host)
    expect(sequelize.config.port).toEqual(options.port)
  })
})
<|endoftext|>