<commit_before>import {defineOption} from "../edit"
import {eventMixin} from "../util/event"
import {AssertionError} from "../util/error"

import {rebaseSteps} from "./rebase"
export {rebaseSteps}

defineOption("collab", false, (pm, value) => {
  if (pm.mod.collab) {
    pm.mod.collab.detach()
    pm.mod.collab = null
  }

  if (value) {
    pm.mod.collab = new Collab(pm, value)
  }
})

class Collab {
  constructor(pm, options) {
    this.pm = pm
    this.options = options

    this.version = options.version || 0
    this.versionDoc = pm.doc

    this.unconfirmedSteps = []
    this.unconfirmedMaps = []

    pm.on("transform", this.onTransform = transform => {
      for (let i = 0; i < transform.steps.length; i++) {
        this.unconfirmedSteps.push(transform.steps[i])
        this.unconfirmedMaps.push(transform.maps[i])
      }
      this.signal("mustSend")
    })
    pm.on("beforeSetDoc", this.onSetDoc = () => {
      AssertionError.raise("setDoc is not supported on a collaborative editor")
    })
    pm.history.allowCollapsing = false
  }

  detach() {
    this.pm.off("transform", this.onTransform)
    this.pm.off("beforeSetDoc", this.onSetDoc)
    this.pm.history.allowCollapsing = true
  }

  hasSendableSteps() {
    return this.unconfirmedSteps.length > 0
  }

  sendableSteps() {
    return {
      version: this.version,
      doc: this.pm.doc,
      steps: this.unconfirmedSteps.slice()
    }
  }

  confirmSteps(sendable) {
    this.unconfirmedSteps.splice(0, sendable.steps.length)
    this.unconfirmedMaps.splice(0, sendable.steps.length)
    this.version += sendable.steps.length
    this.versionDoc = sendable.doc
  }

  receive(steps) {
    let doc = this.versionDoc
    let maps = steps.map(step => {
      let result = step.apply(doc)
      doc = result.doc
      return result.map
    })
    this.version += steps.length
    this.versionDoc = doc

    let rebased = rebaseSteps(doc, maps, this.unconfirmedSteps, this.unconfirmedMaps)
    this.unconfirmedSteps = rebased.transform.steps.slice()
    this.unconfirmedMaps = rebased.transform.maps.slice()

    this.pm.updateDoc(rebased.doc, rebased.mapping)
    this.pm.history.rebased(maps, rebased.transform, rebased.positions)
    return maps
  }
}

eventMixin(Collab)
<commit_msg>docs(collab): Add doc comments to the collab module<commit_after>import {defineOption} from "../edit"
import {eventMixin} from "../util/event"
import {AssertionError} from "../util/error"

import {rebaseSteps} from "./rebase"
export {rebaseSteps}

// :: ?Object #path=collab #kind=option
//
// When given, enables the collaborative editing framework for the
// editor. Will register itself of the `Collab` class as
// `.mod.collab`.
//
// If the object given has a `version` property, that will determine
// the starting version number of the collaborative editing.

defineOption("collab", false, (pm, value) => {
  if (pm.mod.collab) {
    pm.mod.collab.detach()
    pm.mod.collab = null
  }

  if (value) {
    pm.mod.collab = new Collab(pm, value)
  }
})

// ;; This class accumulates changes that have to be sent to the
// central authority in the collaborating group, signals an event when
// it has something to send, and makes it possible to integrate
// changes made by peers into our local document. It is created and
// attached to the editor (under `.mod.collab`) by setting the
// `collab` option.
//
// Includes the [event mixin](#EventMixin).
class Collab {
  constructor(pm, options) {
    this.pm = pm
    this.options = options

    // :: number
    // The version number of the last update received from the central
    // authority. Starts at 0 or the value of the `version` property
    // in the option object, for the editor's value when the option
    // was enabled.
    this.version = options.version || 0
    this.versionDoc = pm.doc

    this.unconfirmedSteps = []
    this.unconfirmedMaps = []

    pm.on("transform", this.onTransform = transform => {
      for (let i = 0; i < transform.steps.length; i++) {
        this.unconfirmedSteps.push(transform.steps[i])
        this.unconfirmedMaps.push(transform.maps[i])
      }
      // :: () #path=Collab#events#mustSend
      // Fired when there are new steps to send to the central
      // authority. Consumers should respond by calling
      // `sendableSteps` and pushing those to the authority.
      this.signal("mustSend")
    })
    pm.on("beforeSetDoc", this.onSetDoc = () => {
      AssertionError.raise("setDoc is not supported on a collaborative editor")
    })
    pm.history.allowCollapsing = false
  }

  detach() {
    this.pm.off("transform", this.onTransform)
    this.pm.off("beforeSetDoc", this.onSetDoc)
    this.pm.history.allowCollapsing = true
  }

  // :: () -> bool
  // Reports whether the editor has any unsent steps.
  hasSendableSteps() {
    return this.unconfirmedSteps.length > 0
  }

  // :: () → {version: number, doc: Node, steps: [Step]}
  // Provides the data describing the editor's unconfirmed steps. This
  // is the thing you'd send to the central authority.
  sendableSteps() {
    return {
      version: this.version,
      doc: this.pm.doc,
      steps: this.unconfirmedSteps.slice()
    }
  }

  // :: ({version: number, doc: Node, steps: [Step]})
  // Tells the module that a set of unconfirmed steps have been
  // accepted by the central authority, and can now be considered
  // confirmed.
  confirmSteps(sendable) {
    this.unconfirmedSteps.splice(0, sendable.steps.length)
    this.unconfirmedMaps.splice(0, sendable.steps.length)
    this.version += sendable.steps.length
    this.versionDoc = sendable.doc
  }

  // :: ([Step]) → [PosMap]
  // Pushes a set of steps (made by peers and received from the
  // central authority) into the editor. This will rebase any
  // unconfirmed steps over these steps.
  //
  // Returns the [position maps](#PosMap) produced by applying the
  // steps.
  receive(steps) {
    let doc = this.versionDoc
    let maps = steps.map(step => {
      let result = step.apply(doc)
      doc = result.doc
      return result.map
    })
    this.version += steps.length
    this.versionDoc = doc

    let rebased = rebaseSteps(doc, maps, this.unconfirmedSteps, this.unconfirmedMaps)
    this.unconfirmedSteps = rebased.transform.steps.slice()
    this.unconfirmedMaps = rebased.transform.maps.slice()

    this.pm.updateDoc(rebased.doc, rebased.mapping)
    this.pm.history.rebased(maps, rebased.transform, rebased.positions)
    return maps
  }
}

eventMixin(Collab)
<|endoftext|>


<commit_before>var Client = require('ssh2').Client;
var MODES = require('ssh2').SFTP_OPEN_MODE;
// var Promise = require('bluebird');

var statToAttrs = function (stats) {
  var attrs = {};
  for (var attr in stats) {
    if (stats.hasOwnProperty(attr)) {
      attrs[attr] = stats[attr];
    }
  }
  return attrs;
}

module.exports = function (config) {

  var sftpClient = {

    config: config,

    ls: function ls(location) {
      var self = this;
      return new Promise(function (resolve, reject) {
        var conn = new Client();
        conn.on('ready', function () {
          //console.log('reading %s', location);
          conn.sftp(function (err, sftp) {
            sftp.stat(location, function (err, stat) {
              if (err) {
                reject(err);
                conn.end()
                return false;
              };
              var attrs = statToAttrs(stat);
              if (stat.isDirectory()) {
                sftp.readdir(location, function (err, list) {
                  if (err) { reject(err) };
                  resolve({ path: location, type: 'directory', attrs: attrs, entries: list });
                  conn.end();
                });
              } else if (stat.isFile()) {
                resolve({ path: location, type: 'file', attrs: attrs });
                conn.end();
              } else {
                reject('not a file or directory');
                conn.end();
              }
            });
          });
        }).connect(self.config);
        conn.on('error', function (err) {
          conn.end();
          reject(err);
        })
      })

    },

    getBuffer: function getBuffer(location) {
      var self = this;
      return new Promise(function (resolve, reject) {
        var conn = new Client();
        conn.on('ready', function () {
          conn.sftp(function (err, sftp) {
            sftp.open(location, 'r', function (err, handle) {
              if (err) {
                reject(err);
                conn.end();
                return;
              }
              sftp.fstat(handle, function (err, stat) {
                if (err) { reject(err); conn.end(); return false }
                var bytes = stat.size;
                var buffer = Buffer(bytes);
                buffer.fill(0);
                var cb = function(err, readBytes, offsetBuffer, position) {
                  if(err) {
                    reject(err);
                    sftp.close();
                    conn.end();
                    return false;
                  }
                  position = position + readBytes;
                  bytes = bytes - readBytes;
                  if (bytes < 1) {
                    sftp.close(handle, function (err) {
                      conn.end();
                      if (err) {
                        reject(err);
                        return false;
                      } else {
                        resolve(buffer);
                        return;
                      }
                    })
                  } else {
                    sftp.read(handle, buffer, position, bytes, position, cb)
                  }
                }
                sftp.read(handle, buffer, 0, bytes, 0, cb)
              })
            })
          })
        }).connect(self.config);
        conn.on('error', function (err) {
          conn.end();
          reject(err);
        });
      });
    },

    putBuffer: function putBuffer(buffer, location) {
      var self = this;
      return new Promise(function (resolve, reject) {
        var conn = new Client();
        conn.on('ready', function () {
          conn.sftp(function (err, sftp) {
            sftp.open(location, 'w', function (err, handle) {
              if (err) {
                reject(err);
                conn.end();
                return;
              }
              sftp.write(handle, buffer, 0, buffer.length, 0, function (err) {
                if (err) {
                  reject(err);
                  conn.end();
                  return false;
                } else {
                  resolve(true)
                  sftp.close(handle, function (err) {
                    conn.end();
                    if (err) {
                      reject(err);
                      return false;
                    } else {
                      resolve(true);
                      return true;
                    }
                  })
                }
              })
            })
          })
        }).connect(self.config);
        conn.on('error', function (err) {
          conn.end();
          reject(err);
        });
      });
    },

    get: function get(remote, local) {
      var self = this;
      return new Promise(function (resolve, reject) {
        var conn = new Client();
        conn.on('ready', function () {
          conn.sftp(function (err, sftp) {
            sftp.fastGet(remote, local, function (err) {
              if (err) {
                reject(err)
              } else {
                resolve(true)
              }
              conn.end();
            });
          });
        }).connect(self.config);
        conn.on('error', function (err) {
          conn.end();
          reject(err);
        })
      });
    },

    put: function put(local, remote) {
      var self = this;
      return new Promise(function (resolve, reject) {
        var conn = new Client();
        conn.on('ready', function () {
          conn.sftp(function (err, sftp) {
            sftp.fastPut(local, remote, function (err) {
              if (err) {
                reject(err)
              } else {
                resolve(true)
              }
              conn.end();
            });
          });
        }).connect(self.config);
        conn.on('error', function (err) {
          conn.end();
          reject(err);
        })
      });
    },

    rm: function rm(location) {
      var self = this;
      return new Promise(function (resolve, reject) {
        var conn = new Client();
        conn.on('ready', function () {
          conn.sftp(function (err, sftp) {
            sftp.unlink(location, function (err) {
              if (err) {
                reject(err)
              } else {
                resolve(true)
              }
              conn.end();
            });
          });
        }).connect(self.config);
        conn.on('error', function (err) {
          conn.end();
          reject(err);
        })
      })
    },

    mv: function rm(src, dest) {
      var self = this;
      return new Promise(function (resolve, reject) {
        var conn = new Client();
        conn.on('ready', function () {
          conn.sftp(function (err, sftp) {
            sftp.rename(src, dest, function (err) {
              if (err) {
                reject(err)
              } else {
                resolve(true)
              }
              conn.end();
            });
          });
        }).connect(self.config);
        conn.on('error', function (err) {
          conn.end();
          reject(err);
        })
      })
    }

  };

  return sftpClient;
};
<commit_msg>create general connection function, removed redundant promise and connection code from each function<commit_after>var Client = require('ssh2').Client;
var MODES = require('ssh2').SFTP_OPEN_MODE;
// var Promise = require('bluebird');

var statToAttrs = function (stats) {
  var attrs = {};
  for (var attr in stats) {
    if (stats.hasOwnProperty(attr)) {
      attrs[attr] = stats[attr];
    }
  }
  return attrs;
}

module.exports = function (config) {

  var sftpClient = {

    config: config,

    sftpCmd: function sftpCmd(cmd) {
      var self = this;
      var p = new Promise(function (resolve, reject) {
        var conn = new Client();
        conn.on('ready', function () {
          conn.sftp(cmd(conn, resolve, reject))
        }).connect(self.config);
        conn.on('error', function (err) {
          reject(err);
          conn.end();
        })
      })
      return p;
    },

    ls: function ls(location) {
      return this.sftpCmd(function (conn, resolve, reject) {
        var cmd = function (err, sftp) {
          sftp.stat(location, function (err, stat) {
            if (err) {
              reject(err);
              conn.end()
              return false;
            };
            var attrs = statToAttrs(stat);
            if (stat.isDirectory()) {
              sftp.readdir(location, function (err, list) {
                if (err) { reject(err) };
                resolve({ path: location, type: 'directory', attrs: attrs, entries: list });
                conn.end();
              });
            } else if (stat.isFile()) {
              resolve({ path: location, type: 'file', attrs: attrs });
              conn.end();
            } else {
              reject('not a file or directory');
              conn.end();
            }
          });
        }
        return cmd;
      })
    },

    getBuffer: function getBuffer(location) {
      return this.sftpCmd(function (conn, resolve, reject) {
        var cmd = function (err, sftp) {
          sftp.open(location, 'r', function (err, handle) {
            if (err) {
              reject(err);
              conn.end();
              return;
            }
            sftp.fstat(handle, function (err, stat) {
              if (err) { reject(err); conn.end(); return false }
              var bytes = stat.size;
              var buffer = Buffer(bytes);
              buffer.fill(0);
              var cb = function (err, readBytes, offsetBuffer, position) {
                if (err) {
                  reject(err);
                  sftp.close();
                  conn.end();
                  return false;
                }
                position = position + readBytes;
                bytes = bytes - readBytes;
                if (bytes < 1) {
                  sftp.close(handle, function (err) {
                    conn.end();
                    if (err) {
                      reject(err);
                      return false;
                    } else {
                      resolve(buffer);
                      return;
                    }
                  })
                } else {
                  sftp.read(handle, buffer, position, bytes, position, cb)
                }
              }
              sftp.read(handle, buffer, 0, bytes, 0, cb)
            })
          })
        }
        return cmd
      })
    },

    putBuffer: function putBuffer(buffer, location) {
      return this.sftpCmd(function (conn, resolve, reject) {
        var cmd = function (err, sftp) {
          sftp.open(location, 'w', function (err, handle) {
            if (err) {
              reject(err);
              conn.end();
              return;
            }
            sftp.write(handle, buffer, 0, buffer.length, 0, function (err) {
              if (err) {
                reject(err);
                conn.end();
                return false;
              } else {
                resolve(true)
                sftp.close(handle, function (err) {
                  conn.end();
                  if (err) {
                    reject(err);
                    return false;
                  } else {
                    resolve(true);
                    return true;
                  }
                })
              }
            })
          })
        }
        return cmd;
      })
    },

    get: function get(remote, local) {
      return this.sftpCmd(function (conn, resolve, reject) {
        var cmd = function (err, sftp) {
          sftp.fastGet(remote, local, function (err) {
            if (err) {
              reject(err)
            } else {
              resolve(true)
            }
            conn.end();
          });
        }
        return cmd;
      })
    },

    put: function put(local, remote) {
      return this.sftpCmd(function (conn, resolve, reject) {
        var cmd = function (err, sftp) {
          conn.sftp(function (err, sftp) {
            sftp.fastPut(local, remote, function (err) {
              if (err) {
                reject(err)
              } else {
                resolve(true)
              }
              conn.end();
            });
          });
        }
        return cmd;
      })
    },

    rm: function rm(location) {
      return this.sftpCmd(function (conn, resolve, reject) {
        var cmd = function (err, sftp) {
          sftp.unlink(location, function (err) {
            if (err) {
              reject(err)
            } else {
              resolve(true)
            }
            conn.end();
          });
        }
        return cmd
      })
    },

    mv: function rm(src, dest) {
      return this.sftpCmd(function (conn, resolve, reject) {
        var cmd = function (err, sftp) {
          sftp.rename(src, dest, function (err) {
            if (err) {
              reject(err)
            } else {
              resolve(true)
            }
            conn.end();
          });
        }
        return cmd;
      })
    }

  };

  return sftpClient;
};
<|endoftext|>


<commit_before>"use strict";

var __slice = [].slice, EventEmitter = require('events').EventEmitter;

function extend (object) {
  __slice.call(arguments, 1).forEach(function (append) {
    for (var key in append) if (append.hasOwnProperty(key)) {
      object[key] = append[key];
    }
  });
  return object;
}

function factory () {
  var options = { context: {} };
  __slice.call(arguments, 0).forEach(function (opts) {
    var context = extend({}, options.context, opts.context || {});
    extend(options, opts).context = context;
  });

  return cadence;

  function cadence () {
    var vargs = __slice.call(arguments, 0)
      , steps = []
      , firstSteps = []
      , timer
      , callback
      , called
      , count
      , exitCode = 0
      , cadences = []
      , methods = { async: async }
      , abended
      , key
      , arg
      , context = {}
      ;

    firstSteps = flatten(vargs);

    if (firstSteps.every(function (object) { return typeof object == "object" })) {
      return factory.apply(this, [ options ].concat(firstSteps));
    }

    firstSteps = firstSteps.map(function (step) { return parameterize(step, context) });

    return execute;

    function execute () {
      var vargs = __slice.call(arguments, 0), callbacks = [], callback = exceptional;
      if (vargs.length) {
        callback = vargs.pop();
        callbacks = [{ names: [], vargs: vargs }];
      }
      steps = firstSteps.slice(0);
      cadences.length = 0;
      abended = false;
      invoke(steps, 0, Object.create(options.context), callbacks, callback);
    }

    function exceptional (error) { if (error) throw error }

    function flatten (array) {
      var flattened = [];
      while (array.length) {
        arg = array.shift();
        if (Array.isArray(arg)) {
          while (arg.length) array.unshift(arg.pop());
        } else {
          flattened.push(arg);
        }
      }
      return flattened;
    }

    // Creating a problem for myself here. I'm using the named arguments, which
    // I was going to get rid of. Maybe I need to create a sub-cadence?
    function EventInterceptor (emitter) {
      var bindings = {}, gatherers = [], count = 0, completed = 0;
      this.on = function (type) {
        var callback = async(type);
        bindings[type] = { type: 'on', values: [] }
        emitter.on(type, function () {
          bindings[type].values.push(__slice.call(arguments, 0));
        });
        gatherers.push(function () {
          var values = bindings[type].values;
          if (values.every(function (value) { return value.length == 1 })) {
            values = values.map(function (value) { return value[0]  });
          }
          callback(null, values);
        });
        return this;
      }
      this.once = function (type) {
        var callback = async(type);
        bindings[type] = { type: 'once' }
        emitter.once(type, function () {
          callback.apply(this, [ null ].concat(arguments));
          if (++completed == count) {
            gatherers.forEach(function (gatherer) { gatherer() });
          }
        });
        count++;
        return this;
      }
      this.emitter = emitter;
    }

    // Set and reset a thirty second timeout between assertions.
    function timeout () {
      if (timer) clearTimeout(timer);
      if (options.timeout) timer = setTimeout(function () { callback(new Error("Timeout")) }, options.timeout);
    }

    var invocation;

    // We give this function to the caller to build control flow.

    //
    function async () {
      var vargs = __slice.call(arguments, 0), i = -1, step, original;

      // If we're called with an empty array, we're going to assume that the
      // caller created a cadence programatically, but the conditions were such
      // that no steps were added to the cadence. If we don't skip the empty
      // array, then the next step will flatten the array and we'll end up
      // treating it as a call with no arguments, which generates a callback.

      //
      if (vargs.length == 1 && Array.isArray(vargs[0]) && !vargs[0].length)
        return;

      // If the first argument is null, we're going to assume this is an
      // explicit early return, otherwise we flatten the arguments.

      //
      if (vargs[0] != null)
        vargs = flatten(vargs);

      // Wrap event emitters with out interceptor.
      if (vargs[0] instanceof EventEmitter)
        return new EventInterceptor(vargs[0]);

      // The caller as invoked the async function directly as an explicit early
      // return to exit the entire cadence.
      if (vargs.length && (vargs[0] == null || vargs[0] instanceof Error)) {
        invocation.count = Number.MAX_VALUE;
        invocation.callback.apply(this, vargs);
        return;
      }

      // If we're called with a single object argument, we merge the given
      // object into the cadence context.
      if (vargs.length == 1 && typeof vargs[0] == "object" && vargs[0]) {
        extend(invocation.context, vargs[0]);
        return;
      }

      // If our first argument is a function, we check to see if it is a jump
      // instruction. If the function is a member of the current cadence, we
      // will inovke that function with the results of this step.

      // Search for the function in the current cadence.
      if (vargs.length == 1 && typeof vargs[0] == "function") {
        original = vargs[0].original || vargs[0];
        for (i = invocation.arguments[0].length - 1; step = invocation.arguments[0][i]; i--) {
          if (original === step || original === step.original) break;
        }
      }

      // If we find the function in the current cadence, we set the index of
      // next step function to execute; then remove the function argument and
      // procede.
      if (~i) {
        invocation.arguments[1] = i;
        vargs.shift();
      }

      // If we have no arguments, or else if every argument is a string, then
      // we've been asked to build a callback, otherwise, this is a sub-cadence.

      //
      if (!vargs.length || vargs.every(function (arg) { return typeof vargs[0] == "string" })) {
        invocation.count++;
        return createCallback(invocation, vargs);
      } else {
        cadences.push(vargs);
      }
    }

    function createCallback (invocation, names) {
      return function (error) {
        var vargs = __slice.call(arguments, 1);
        if (error) {
          thrown(invocation, error);
        } else {
          invocation.callbacks.push({ names: names, vargs: vargs });
          // Indicates that the function has completed, so we need create
          // the callbacks for parallel cadences now, the next increment of
          // the called counter, which may be the last.
          if (vargs[0] == invoke) {
            cadences.slice(0).forEach(function (steps) {
              var subtext = Object.create(invocation.context);
              steps = steps.map(function (step) { return parameterize(step, subtext) });
              invoke(steps, 0, subtext, [], async());
            });
          }
        }
        if (++invocation.called == invocation.count) {
          invoke.apply(this, invocation.arguments);
        }
      }
    }

    function parameterize (step, context) {
      var $ = /^function\s*[^(]*\(([^)]*)\)/.exec(step.toString());
      if (!$) throw new Error("bad function");
      if (step.name) {
        context[step.name] = function () { async(step).apply(this, [ null ].concat(__slice.call(arguments, 0))) }
        context[step.name].original = step;
      }
      step.parameters = $[1].split(/\s*,\s/);
      if (!step.parameters[0].trim()) step.parameters.shift();
      return step;
    }

    // Test if a program name matches one of our special names. We support
    // Streamline.js by also accepting a function whose name has been mangled in a
    // Streamline.js fashion.

    //
    function named (proc, name) {
      return proc.name == name || (proc.name && !proc.name.indexOf(name + '__'));
    }

    // TODO And what if there are many, many errors?

    //
    function thrown (invocation, error) {
      var steps = invocation.arguments[0]
        , next = steps[invocation.index + 1]
        ;
      if (next && /^errors?$/.test(next.parameters[0])) {
        invocation.context.errors.push(error);
      } else {
        if (timer) clearTimeout(timer);
        abended = true;
        invocation.callback(error);
      }
    }

    // Parallel arrays make the most sense, really. If the paralleled function
    // is better off returning a map, it can be shimmed.
    function contextualize (step, callbacks, context, ephemeral) {
      var inferred = [], explicit = []
        , i, $ , vargs, names;
      callbacks.forEach(function (callback) {
        if (callback.names.length) explicit.push(callback);
        else inferred.push(callback);
      });

      names = step.parameters.slice(0);
      if (~(i = names.indexOf('async')) || ~(i = names.indexOf(options.alias))) {
        names.length = i;
      }
      if (step.name == '_') {
        names.length = 0;
      }

      if (inferred.length == 1) {
        vargs = inferred[0].vargs;
        for (i = names.length; i--;) {
          if (!names[i].indexOf('$vargs') && ($ = /^\$vargs(?:\$(\d+))?$/.exec(names[i]))) {
            ephemeral[names[i]] = vargs.splice(i, vargs.length - (i + +($[1] || 0)));
            names.splice(i, 1);
            break;
          }
        }
        names.length = callbacks[0].vargs.length;
        names.forEach(function (name, i) { (name[0] == '$' ? ephemeral : context)[name] = vargs[i] });
      } else if (inferred.length && names.length) {
        parallelize(names, inferred, context, ephemeral);
      }

      var map = {};
      explicit.forEach(function (callback) {
        var key = callback.names.join('!');
        (map[key] || (map[key] = [])).push(callback);
      });

      Object.keys(map).forEach(function (key) {
        parallelize(map[key][0].names, map[key], context, ephemeral);
      });
    }

    // Attempt to organize many callbacks into parallel arrays of values.

    //
    function parallelize (names, callbacks, context, ephemeral) {
      if (callbacks.length == 1) {
        callbacks[0].names.forEach(function (name, i) {
          (names[i][0] == '$' ? ephemeral : context)[name] = callbacks[0].vargs[i];
        });
      } else {
        // Is the result well organized? We have a specific size for names.
        var arrayed = callbacks.every(function (result) {
          return (
            result.vargs.length == names.length
            && (!result.names.length || names.every(function (name, i) { return name == result.names[i] }))
          )
        });
        if (arrayed) {
          names.length = callbacks[0].vargs.length;
          names.forEach(function (name, i) { (name[0] == '$' ? ephemeral : context)[name] = [] });
          callbacks.forEach(function (result) {
            result.vargs.forEach(function (arg, i) {
              (names[i][0] == '$' ? ephemeral : context)[names[i]].push(arg);
            });
          });
        } else {
          throw new Error("Can't infer array assignment.");
        }
      }
    }

    function invoke (steps, index, context, callbacks, callback) {
      var arg
        , args = []
        , match
        , parameter, parameters
        , i, I
        , calledback
        , step, key, next
        , leaked
        , result
        , value
        , names
        , result
        , hold
        , ephemeral = {}
        ;

      if (abended) return;

      timeout();

      if (steps[index] && /^errors?$/.test(steps[index].parameters[0]) && !context.errors.length) {
        invoke(steps, index + 1, context, callbacks, callback);
      } else {
        // No callbacks means that we use the function return value, if any.
        if (callbacks.length == 1) {
          if (callbacks[0].vargs[0] == invoke) { callbacks[0].vargs.shift() }
        } else {
          callbacks = callbacks.filter(function (result) { return result.vargs[0] !== invoke });
        }

        if (steps.length == index) {
          callback.apply(this, [ null ].concat(callbacks.length == 1 ? callbacks[0].vargs : []));
          return;
        }

        // Get the next step.
        step = steps[index];

        // Filter out the return value, if there are callbacks left, then
        // `contextualize` will process them.
        if (callbacks.length) {
          contextualize(step, callbacks, context, ephemeral);
        }

        // Give our creator a chance to inspect the step, possibly wrap it.
        Object.keys(options.wrap || {})
          .filter(function (name) { return named(step, name) && name })
          .map(function (name) { return options.wrap[name] })
          .forEach(function (wrapper) {
            var parameters = step.parameters, original = step.original || step;
            step = wrapper(step)
            step.parameters = parameters;
            step.original = original;
          });

        invocation = { callbacks: [], count: 0 , called: 0, context: context, index: index, callback: callback };
        invocation.arguments = [ steps, index + 1, context, invocation.callbacks, callback ]

        step.parameters.forEach(function (parameter) {
          if (parameter == options.alias) {
            parameter = 'async';
          }
          if (parameter == "error") {
            arg = context.errors[0];
          // Did not know that `/^_|callback$/` means `^_` or `done$`.
          } else if (/^(_|callback)$/.test(parameter)) {
            arg = async();
          } else if ((arg  = context[parameter]) == void(0)) {
            if ((arg = ephemeral[parameter]) == void(0)) arg = methods[parameter];
          }
          args.push(arg);
        });

        cadences.length = 0;
        context.errors = [];

        try {
          hold = async();
          result = step.apply(this, args);
          hold.apply(this, [ null, invoke ].concat(result == void(0) ? [] : [ result ]));
        } catch (error) {
          thrown(invocation, error);
          invoke.apply(this, invocation.arguments);
        }
      }
    }
  }
}

module.exports = factory();
<commit_msg>Step over to stop out of `async`.<commit_after>"use strict";

var __slice = [].slice, EventEmitter = require('events').EventEmitter;

function extend (object) {
  __slice.call(arguments, 1).forEach(function (append) {
    for (var key in append) if (append.hasOwnProperty(key)) {
      object[key] = append[key];
    }
  });
  return object;
}

function factory () {
  var options = { context: {} };
  __slice.call(arguments, 0).forEach(function (opts) {
    var context = extend({}, options.context, opts.context || {});
    extend(options, opts).context = context;
  });

  return cadence;

  function cadence () {
    var vargs = __slice.call(arguments, 0)
      , steps = []
      , firstSteps = []
      , timer
      , callback
      , called
      , count
      , exitCode = 0
      , cadences = []
      , methods = { async: async }
      , abended
      , key
      , arg
      , context = {}
      ;

    firstSteps = flatten(vargs);

    if (firstSteps.every(function (object) { return typeof object == "object" })) {
      return factory.apply(this, [ options ].concat(firstSteps));
    }

    firstSteps = firstSteps.map(function (step) { return parameterize(step, context) });

    return execute;

    function execute () {
      var vargs = __slice.call(arguments, 0), callbacks = [], callback = exceptional;
      if (vargs.length) {
        callback = vargs.pop();
        callbacks = [{ names: [], vargs: vargs }];
      }
      steps = firstSteps.slice(0);
      cadences.length = 0;
      abended = false;
      invoke(steps, 0, Object.create(options.context), callbacks, callback);
    }

    function exceptional (error) { if (error) throw error }

    function flatten (array) {
      var flattened = [];
      while (array.length) {
        arg = array.shift();
        if (Array.isArray(arg)) {
          while (arg.length) array.unshift(arg.pop());
        } else {
          flattened.push(arg);
        }
      }
      return flattened;
    }

    // Creating a problem for myself here. I'm using the named arguments, which
    // I was going to get rid of. Maybe I need to create a sub-cadence?
    function EventInterceptor (emitter) {
      var bindings = {}, gatherers = [], count = 0, completed = 0;
      this.on = function (type) {
        var callback = async(type);
        bindings[type] = { type: 'on', values: [] }
        emitter.on(type, function () {
          bindings[type].values.push(__slice.call(arguments, 0));
        });
        gatherers.push(function () {
          var values = bindings[type].values;
          if (values.every(function (value) { return value.length == 1 })) {
            values = values.map(function (value) { return value[0]  });
          }
          callback(null, values);
        });
        return this;
      }
      this.once = function (type) {
        var callback = async(type);
        bindings[type] = { type: 'once' }
        emitter.once(type, function () {
          callback.apply(this, [ null ].concat(arguments));
          if (++completed == count) {
            gatherers.forEach(function (gatherer) { gatherer() });
          }
        });
        count++;
        return this;
      }
      this.emitter = emitter;
    }

    // Set and reset a thirty second timeout between assertions.
    function timeout () {
      if (timer) clearTimeout(timer);
      if (options.timeout) timer = setTimeout(function () { callback(new Error("Timeout")) }, options.timeout);
    }

    var invocation;

    // We give this function to the caller to build control flow. In the
    // debugger, I often want to step into a function that takes a step
    // callback, so I'm often stepping into this function, only to step right
    // back out again. Step out is a two finger chord in the Chrome debugger,
    // but step over is a single function key, so I want to have the option to
    // step over the body of this function, instead of having to find the
    // control key when I'm in it. That is the only reason for the separate
    // async function.

    //
    function async () { _async.apply(null, arguments) }

    function _async() {
      var vargs = __slice.call(arguments, 0), i = -1, step, original;

      // If we're called with an empty array, we're going to assume that the
      // caller created a cadence programatically, but the conditions were such
      // that no steps were added to the cadence. If we don't skip the empty
      // array, then the next step will flatten the array and we'll end up
      // treating it as a call with no arguments, which generates a callback.

      //
      if (vargs.length == 1 && Array.isArray(vargs[0]) && !vargs[0].length)
        return;

      // If the first argument is null, we're going to assume this is an
      // explicit early return, otherwise we flatten the arguments.

      //
      if (vargs[0] != null)
        vargs = flatten(vargs);

      // Wrap event emitters with out interceptor.
      if (vargs[0] instanceof EventEmitter)
        return new EventInterceptor(vargs[0]);

      // The caller as invoked the async function directly as an explicit early
      // return to exit the entire cadence.
      if (vargs.length && (vargs[0] == null || vargs[0] instanceof Error)) {
        invocation.count = Number.MAX_VALUE;
        invocation.callback.apply(this, vargs);
        return;
      }

      // If we're called with a single object argument, we merge the given
      // object into the cadence context.
      if (vargs.length == 1 && typeof vargs[0] == "object" && vargs[0]) {
        extend(invocation.context, vargs[0]);
        return;
      }

      // If our first argument is a function, we check to see if it is a jump
      // instruction. If the function is a member of the current cadence, we
      // will inovke that function with the results of this step.

      // Search for the function in the current cadence.
      if (vargs.length == 1 && typeof vargs[0] == "function") {
        original = vargs[0].original || vargs[0];
        for (i = invocation.arguments[0].length - 1; step = invocation.arguments[0][i]; i--) {
          if (original === step || original === step.original) break;
        }
      }

      // If we find the function in the current cadence, we set the index of
      // next step function to execute; then remove the function argument and
      // procede.
      if (~i) {
        invocation.arguments[1] = i;
        vargs.shift();
      }

      // If we have no arguments, or else if every argument is a string, then
      // we've been asked to build a callback, otherwise, this is a sub-cadence.

      //
      if (!vargs.length || vargs.every(function (arg) { return typeof vargs[0] == "string" })) {
        invocation.count++;
        return createCallback(invocation, vargs);
      } else {
        cadences.push(vargs);
      }
    }

    function createCallback (invocation, names) {
      return function (error) {
        var vargs = __slice.call(arguments, 1);
        if (error) {
          thrown(invocation, error);
        } else {
          invocation.callbacks.push({ names: names, vargs: vargs });
          // Indicates that the function has completed, so we need create
          // the callbacks for parallel cadences now, the next increment of
          // the called counter, which may be the last.
          if (vargs[0] == invoke) {
            cadences.slice(0).forEach(function (steps) {
              var subtext = Object.create(invocation.context);
              steps = steps.map(function (step) { return parameterize(step, subtext) });
              invoke(steps, 0, subtext, [], async());
            });
          }
        }
        if (++invocation.called == invocation.count) {
          invoke.apply(this, invocation.arguments);
        }
      }
    }

    function parameterize (step, context) {
      var $ = /^function\s*[^(]*\(([^)]*)\)/.exec(step.toString());
      if (!$) throw new Error("bad function");
      if (step.name) {
        context[step.name] = function () { async(step).apply(this, [ null ].concat(__slice.call(arguments, 0))) }
        context[step.name].original = step;
      }
      step.parameters = $[1].split(/\s*,\s/);
      if (!step.parameters[0].trim()) step.parameters.shift();
      return step;
    }

    // Test if a program name matches one of our special names. We support
    // Streamline.js by also accepting a function whose name has been mangled in a
    // Streamline.js fashion.

    //
    function named (proc, name) {
      return proc.name == name || (proc.name && !proc.name.indexOf(name + '__'));
    }

    // TODO And what if there are many, many errors?

    //
    function thrown (invocation, error) {
      var steps = invocation.arguments[0]
        , next = steps[invocation.index + 1]
        ;
      if (next && /^errors?$/.test(next.parameters[0])) {
        invocation.context.errors.push(error);
      } else {
        if (timer) clearTimeout(timer);
        abended = true;
        invocation.callback(error);
      }
    }

    // Parallel arrays make the most sense, really. If the paralleled function
    // is better off returning a map, it can be shimmed.
    function contextualize (step, callbacks, context, ephemeral) {
      var inferred = [], explicit = []
        , i, $ , vargs, names;
      callbacks.forEach(function (callback) {
        if (callback.names.length) explicit.push(callback);
        else inferred.push(callback);
      });

      names = step.parameters.slice(0);
      if (~(i = names.indexOf('async')) || ~(i = names.indexOf(options.alias))) {
        names.length = i;
      }
      if (step.name == '_') {
        names.length = 0;
      }

      if (inferred.length == 1) {
        vargs = inferred[0].vargs;
        for (i = names.length; i--;) {
          if (!names[i].indexOf('$vargs') && ($ = /^\$vargs(?:\$(\d+))?$/.exec(names[i]))) {
            ephemeral[names[i]] = vargs.splice(i, vargs.length - (i + +($[1] || 0)));
            names.splice(i, 1);
            break;
          }
        }
        names.length = callbacks[0].vargs.length;
        names.forEach(function (name, i) { (name[0] == '$' ? ephemeral : context)[name] = vargs[i] });
      } else if (inferred.length && names.length) {
        parallelize(names, inferred, context, ephemeral);
      }

      var map = {};
      explicit.forEach(function (callback) {
        var key = callback.names.join('!');
        (map[key] || (map[key] = [])).push(callback);
      });

      Object.keys(map).forEach(function (key) {
        parallelize(map[key][0].names, map[key], context, ephemeral);
      });
    }

    // Attempt to organize many callbacks into parallel arrays of values.

    //
    function parallelize (names, callbacks, context, ephemeral) {
      if (callbacks.length == 1) {
        callbacks[0].names.forEach(function (name, i) {
          (names[i][0] == '$' ? ephemeral : context)[name] = callbacks[0].vargs[i];
        });
      } else {
        // Is the result well organized? We have a specific size for names.
        var arrayed = callbacks.every(function (result) {
          return (
            result.vargs.length == names.length
            && (!result.names.length || names.every(function (name, i) { return name == result.names[i] }))
          )
        });
        if (arrayed) {
          names.length = callbacks[0].vargs.length;
          names.forEach(function (name, i) { (name[0] == '$' ? ephemeral : context)[name] = [] });
          callbacks.forEach(function (result) {
            result.vargs.forEach(function (arg, i) {
              (names[i][0] == '$' ? ephemeral : context)[names[i]].push(arg);
            });
          });
        } else {
          throw new Error("Can't infer array assignment.");
        }
      }
    }

    function invoke (steps, index, context, callbacks, callback) {
      var arg
        , args = []
        , match
        , parameter, parameters
        , i, I
        , calledback
        , step, key, next
        , leaked
        , result
        , value
        , names
        , result
        , hold
        , ephemeral = {}
        ;

      if (abended) return;

      timeout();

      if (steps[index] && /^errors?$/.test(steps[index].parameters[0]) && !context.errors.length) {
        invoke(steps, index + 1, context, callbacks, callback);
      } else {
        // No callbacks means that we use the function return value, if any.
        if (callbacks.length == 1) {
          if (callbacks[0].vargs[0] == invoke) { callbacks[0].vargs.shift() }
        } else {
          callbacks = callbacks.filter(function (result) { return result.vargs[0] !== invoke });
        }

        if (steps.length == index) {
          callback.apply(this, [ null ].concat(callbacks.length == 1 ? callbacks[0].vargs : []));
          return;
        }

        // Get the next step.
        step = steps[index];

        // Filter out the return value, if there are callbacks left, then
        // `contextualize` will process them.
        if (callbacks.length) {
          contextualize(step, callbacks, context, ephemeral);
        }

        // Give our creator a chance to inspect the step, possibly wrap it.
        Object.keys(options.wrap || {})
          .filter(function (name) { return named(step, name) && name })
          .map(function (name) { return options.wrap[name] })
          .forEach(function (wrapper) {
            var parameters = step.parameters, original = step.original || step;
            step = wrapper(step)
            step.parameters = parameters;
            step.original = original;
          });

        invocation = { callbacks: [], count: 0 , called: 0, context: context, index: index, callback: callback };
        invocation.arguments = [ steps, index + 1, context, invocation.callbacks, callback ]

        step.parameters.forEach(function (parameter) {
          if (parameter == options.alias) {
            parameter = 'async';
          }
          if (parameter == "error") {
            arg = context.errors[0];
          // Did not know that `/^_|callback$/` means `^_` or `done$`.
          } else if (/^(_|callback)$/.test(parameter)) {
            arg = async();
          } else if ((arg  = context[parameter]) == void(0)) {
            if ((arg = ephemeral[parameter]) == void(0)) arg = methods[parameter];
          }
          args.push(arg);
        });

        cadences.length = 0;
        context.errors = [];

        try {
          hold = async();
          result = step.apply(this, args);
          hold.apply(this, [ null, invoke ].concat(result == void(0) ? [] : [ result ]));
        } catch (error) {
          thrown(invocation, error);
          invoke.apply(this, invocation.arguments);
        }
      }
    }
  }
}

module.exports = factory();
<|endoftext|>


<commit_before>//   Copyright 2014-2015 François de Campredon
//
//   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';

module.exports = {
  Component: require('./lib/component'),
  LifecycleMixin: require('./lib/lifecycleMixin'),
  StateStreamMixin: require('./lib/stateStreamMixin').StateStreamMixin,
  PropsMixin: require('./lib/propsMixin'),
  FuncSubject: require('./lib/funcSubject')
};
<commit_msg>expose cleanAllSubscripttions<commit_after>//   Copyright 2014-2015 François de Campredon
//
//   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';

var stateStream = require('./lib/stateStreamMixin');

module.exports = {
  Component: require('./lib/component'),
  LifecycleMixin: require('./lib/lifecycleMixin'),
  StateStreamMixin: stateStream.StateStreamMixin,
  PropsMixin: require('./lib/propsMixin'),
  FuncSubject: require('./lib/funcSubject'),
  cleanAllSubscriptions: stateStream.cleanAllSubscriptions
};
<|endoftext|>


<commit_before>'use strict';

const Path = require('path'),
    isOSX = (process.platform === 'darwin'),
    isWindows = (process.platform === 'win32');

let options = {
    dmg: /darwin/,
    dmgFormat: 'UDZO',
    isSilent: false,
    isSync: true
};

let setParam = (param, value) => {
    if (!options.hasOwnProperty(param)) {
        return false;
    }

    return options[param] = value
};

let asDMG = (path) => {
    if (!isOSX || !options.dmg) {
        // Impossible to pack as DMG, or disabled
        return false;
    }
    if (options.dmg instanceof RegExp) {
        return options.dmg.test(path);
    }

    return !!options.dmg;
};

let exec = () => {
    return options.isSync
        ? require('child_process').execSync
        : require('child_process').exec;
};

let get7zPath = () => {
    return Path.normalize(__dirname + '/7z/7za.exe');
};

let log = (message) => {
    if (options.isSilent) {
        return;
    }

    console.log(message + "\n");
};

let packDMG = (path) => {
    exec()(`hdiutil create -format ${options.dmgFormat} -srcfolder ${path} ${path}.dmg`);
    log(`DMG file created: "${path}.dmg"`);
};

let packZIP = (path) => {
    let pathInfo = Path.parse(path),
        cmd = isWindows
            ? `${get7zPath()} a ${pathInfo.base} ${pathInfo.base}.zip`
            : `zip -r ${pathInfo.base}.zip ${pathInfo.base}`;

    exec()(cmd, { cwd: pathInfo.dir });
    log(`ZIP archive created: "${path}.zip"`);
};

let pack = (path) => {
    if (Array.isArray(path)) {
        // Recursive packing for Array of paths
        path.forEach(path => pack(path));

        return true;
    }

    try {
        if (asDMG(path)) {
            packDMG(path);
        } else {
            packZIP(path);
        }
    }
    catch (e) {
        console.error(`Error while packaging "${path}":`, e.message);
    }
};

module.exports = {
    path: pack,
    param: setParam
};
<commit_msg>ZIP/7z pack update<commit_after>'use strict';

const Path = require('path'),
    isOSX = (process.platform === 'darwin'),
    isWindows = (process.platform === 'win32');

let options = {
    dmg: /darwin/,
    dmgFormat: 'UDZO',
    isSilent: false,
    isSync: true
};

let setParam = (param, value) => {
    if (!options.hasOwnProperty(param)) {
        return false;
    }

    return options[param] = value
};

let asDMG = (path) => {
    if (!isOSX || !options.dmg) {
        // Impossible to pack as DMG, or disabled
        return false;
    }
    if (options.dmg instanceof RegExp) {
        return options.dmg.test(path);
    }

    return !!options.dmg;
};

let exec = () => {
    return options.isSync
        ? require('child_process').execSync
        : require('child_process').exec;
};

let get7zPath = () => {
    return Path.normalize(__dirname + '/7z/7za.exe');
};

let log = (message) => {
    if (options.isSilent) {
        return;
    }

    console.log(message + "\n");
};

let packDMG = (path) => {
    exec()(`hdiutil create -format ${options.dmgFormat} -srcfolder ${path} ${path}.dmg`);
    log(`DMG file created: "${path}.dmg"`);
};

let packZIP = (path) => {
    let pathInfo = Path.parse(path),
        cmd = (isWindows
            ? `${get7zPath()} a`
            : 'zip -r')
            + ` ${pathInfo.base}.zip ${pathInfo.base}`,
        params = { };

    if (pathInfo.dir) {
        params.cwd = pathInfo.dir;
    }

    exec()(cmd, params);
    log(`ZIP archive created: "${path}.zip"`);
};

let pack = (path) => {
    if (Array.isArray(path)) {
        // Recursive packing for Array of paths
        path.forEach(path => pack(path));

        return true;
    }

    try {
        if (asDMG(path)) {
            packDMG(path);
        } else {
            packZIP(path);
        }
    }
    catch (e) {
        console.error(`Error while packaging "${path}":`, e.message);
    }
};

module.exports = {
    path: pack,
    param: setParam
};
<|endoftext|>


<commit_before>var moduleFactory = require('./lib/shared/ModuleFactory.js');
var request = require('./lib/shared/Request.js');
var reply = require('./lib/shared/Reply.js');
var errorHandler = require('./lib/shared/ErrorHandler.js');
var user = require('./lib/shared/User.js');
var fs = require('fs');

// sign with default (HMAC SHA256)
var jwt = require('jsonwebtoken');

// sign with RSA SHA256
var cert = fs.readFileSync('rsa.pub');  // get private key

exports.handler = function(event, context){
    var callingFunction = context.functionName;
    var token = event.sessionToken;

    var req = request(token,event,context);
    var rep = reply(req);
    var err = errorHandler(req);
    //NEED TO LOOKUP IN USERDB FIRST, FIX
    var decoded = {};
    if(typeof token != 'undefined'){
      try {
  		  decoded = jwt.verify(token, cert, { algorithms: ['RS256'] });
	    }
      catch(err) {
		    //err
        console.log(err);
		    console.log('token invalid');
	    }
    }
    else {
      decoded.RIN = parseInt(event.RIN);
    }

    console.log('Loading user');
    var usr = user(decoded.RIN,token);

    var module = moduleFactory(callingFunction, usr, req, rep);
    console.log('Running module: ', module);
    module.run();
    console.log('Module completed execution');
};

var serve = function(){
  // Encapsulate expressJS dependency
  var express = require('express');
  var app = express();

  // Enable CORS
  app.use(function(request, result, next) {
    result.header('Access-Control-Allow-Origin', '*');
    result.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
    next();
  });

  // Enable POST parsing
  var bodyParser = require('body-parser');
  app.use(bodyParser.json()); // Parses application/json
  app.use(bodyParser.urlencoded({extended: true})); // Parses form encoded

  // Generate event and context for Lambda handler
  var genEventContext = function(request, response){
    console.log('Received request');
    // Make a context object
    var context = {};
    // Set up callbacks
    context.succeed = context.fail = function(payload){
      console.log('Sending payload: ', payload);
      console.log('Using response: ', response);
      response.send(payload);
    };
    // Get root URL
    context.functionName = request.path.split('/')[1];

    // Make a fake evt
    var evt = {};

    var extend = function(target, source) {
      for(var index in source){
        target[index] = source[index];
      }
    }
    // Concatenate with query string
    extend(evt, request.query);
    // Concatenate with body
    extend(evt, request.body);

    //TODO: REMOVE
    evt.RIN = '123456'; // Hard-coded

    return { evt: evt, context: context };
  }

  var callLambda = function(eventContext){
    console.log('Calling exports handler');
    try {
      exports.handler(eventContext.evt, eventContext.context);
    } catch(error) {
      console.error('Failed to run module ', eventContext.context.functionName, ' for reason: ', error);
    }
  }

  // Create GET handler
  app.get('*', function(request, response) {
    var eventContext = genEventContext(request, response);
    eventContext.context.httpMethod = 'GET';
    callLambda(eventContext);
  });

  // Create POST handler
  app.post('*', function(request, response) {
    var eventContext = genEventContext(request, response);
    eventContext.context.httpMethod = 'POST';
    callLambda(eventContext);
  });

  // Start server
  var listener = app.listen(8080, function(){
    console.log('Server started');
  });
};

serve();
<commit_msg>Formatting<commit_after>var moduleFactory = require('./lib/shared/ModuleFactory.js');
var request = require('./lib/shared/Request.js');
var reply = require('./lib/shared/Reply.js');
var errorHandler = require('./lib/shared/ErrorHandler.js');
var user = require('./lib/shared/User.js');
var fs = require('fs');

// sign with default (HMAC SHA256)
var jwt = require('jsonwebtoken');

// sign with RSA SHA256
var cert = fs.readFileSync('rsa.pub');  // get private key

exports.handler = function(event, context){
    var callingFunction = context.functionName;
    var token = event.sessionToken;

    var req = request(token,event,context);
    var rep = reply(req);
    var err = errorHandler(req);
    //NEED TO LOOKUP IN USERDB FIRST, FIX
    var decoded = {};
    if(typeof token != 'undefined'){
      try {
  		  decoded = jwt.verify(token, cert, { algorithms: ['RS256'] });
	    } catch(err) {
        console.log(err);
		    console.log('token invalid');
	    }
    }
    else {
      decoded.RIN = parseInt(event.RIN);
    }

    console.log('Loading user');
    var usr = user(decoded.RIN,token);

    var module = moduleFactory(callingFunction, usr, req, rep);
    console.log('Running module: ', module);
    module.run();
    console.log('Module completed execution');
};

var serve = function(){
  // Encapsulate expressJS dependency
  var express = require('express');
  var app = express();

  // Enable CORS
  app.use(function(request, result, next) {
    result.header('Access-Control-Allow-Origin', '*');
    result.header('Access-Control-Allow-Headers',
                  'Origin, X-Requested-With, Content-Type, Accept');
    next();
  });

  // Enable POST parsing
  var bodyParser = require('body-parser');
  app.use(bodyParser.json()); // Parses application/json
  app.use(bodyParser.urlencoded({extended: true})); // Parses form encoded

  // Generate event and context for Lambda handler
  var genEventContext = function(request, response){
    console.log('Received request');
    // Make a context object
    var context = {};
    // Set up callbacks
    context.succeed = context.fail = function(payload){
      console.log('Sending payload: ', payload);
      console.log('Using response: ', response);
      response.send(payload);
    };
    // Get root URL
    context.functionName = request.path.split('/')[1];

    // Make a fake evt
    var evt = {};

    var extend = function(target, source) {
      for(var index in source){
        target[index] = source[index];
      }
    }
    // Concatenate with query string
    extend(evt, request.query);
    // Concatenate with body
    extend(evt, request.body);

    //TODO: REMOVE
    evt.RIN = '123456'; // Hard-coded

    return { evt: evt, context: context };
  }

  var callLambda = function(eventContext){
    console.log('Calling exports handler');
    try {
      exports.handler(eventContext.evt, eventContext.context);
    } catch(error) {
      console.error('Failed to run module ',
                    eventContext.context.functionName,
                    'for reason:', error);
    }
  }

  // Create GET handler
  app.get('*', function(request, response) {
    var eventContext = genEventContext(request, response);
    eventContext.context.httpMethod = 'GET';
    callLambda(eventContext);
  });

  // Create POST handler
  app.post('*', function(request, response) {
    var eventContext = genEventContext(request, response);
    eventContext.context.httpMethod = 'POST';
    callLambda(eventContext);
  });

  // Start server
  var listener = app.listen(8080, function(){
    console.log('Server started');
  });
};

serve();
<|endoftext|>


<commit_before>'use strict';

var es = require('event-stream');
var TopoSort = require('topo-sort');
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;
//var fs = require('fs');

var PLUGIN_NAME = 'gulp-extify';

/**
 * this file just make sure that the test will work
 */
module.exports = function extify () {
    var files = {};
    var referencesFilesMap = {};
    var classAnalytics = [];
    var tsort = new TopoSort();

    var dependencies = {};
    var addedClasses = new Array();

    return es.through(function collectFilesToSort (file) {
        var defineRegexp = /Ext[ |\n|\r]*\.define[ |\n|\r]*\(/;

        if(!file.contents) {
            return this.emit('error', new PluginError(PLUGIN_NAME, 'File: "' + file.relative + '" is empty. You have to read it with gulp.src(..)'));
        }

        var fileContent = removeComments(file.contents.toString());

        var startIndex = regexIndexOf(fileContent, defineRegexp);
        var stopIndex = regexIndexOf(fileContent, defineRegexp, startIndex+1);

        while(startIndex !== -1) {
            if (stopIndex !== -1) {
                var defineContent = fileContent.substr(startIndex, stopIndex-startIndex);
                var contentUntilStopIndex = fileContent.substr(0, stopIndex);
            } else {
                var defineContent = fileContent.substr(startIndex);
                var contentUntilStopIndex = fileContent;
            }
            var braceDiffUntilStopIndex = Math.abs(countChars(contentUntilStopIndex, '{') - countChars(contentUntilStopIndex, '}'));
            var openBraces = countChars(defineContent, '{');
            var closedBraces = countChars(defineContent, '}');

            if (openBraces === closedBraces) {

                var currentClassWithApostrophes = defineContent.match(/Ext[ |\n|\r]*\.[ |\n|\r]*define[ |\n|\r|\(]*?[\'|\"][a-zA-Z0-9\.]*?[\'|\"]/);

                var requirements = defineContent.match(/requires[.|\n|\r| ]*:[ |\n|\r|]*[\[]*[a-zA-Z0-9|\n|\r|\'|\"| |\.|,|\/]*[\]]*/);
                var mixins = defineContent.match(/mixins[.|\n|\r| ]*:[ |\n|\r][\{|\[]+(.|\n|\r)*?(\}|\])+/);
                var extend = defineContent.match(/extend[ |\n|\r]*:[ |\n|\r]*[\'|\"][a-zA-Z\. ]*[\'|\"]/);
                var model = defineContent.match(/model[ |\n|\r]*:[ |\n|\r]*[\'|\"][a-zA-Z\. ]*[\'|\"]/);

                //parse classnames
                var currentClass = getClassNames(currentClassWithApostrophes)[0];
                var reqClasses = getClassNames(requirements);
                var extendClasses = getClassNames(extend);
                var mixinClasses = getClassNames(mixins);
                var modelClass = getClassNames(model);

                var dependencyClasses = mixinClasses.concat(extendClasses).concat(reqClasses).concat(modelClass);

                if(braceDiffUntilStopIndex === 0) {
                    dependencies[currentClass] = dependencyClasses;
                    files[currentClass] = file;

                    //put all file paths in a map, and update all concat all dependencies
                    if(!referencesFilesMap[file.path]) {
                        referencesFilesMap[file.path] = [currentClass];
                    } else {
                        referencesFilesMap[file.path].forEach(function(refClassName) {
                            dependencies[refClassName] = concatUnique(dependencies[refClassName], dependencies[currentClass]);
                            dependencies[currentClass] = concatUnique(dependencies[currentClass], dependencies[currentClass]);
                        });
                    }
                }

                if(stopIndex !== -1) {
                    startIndex = regexIndexOf(fileContent, defineRegexp, stopIndex + 1);
                } else {
                    startIndex = regexIndexOf(fileContent, defineRegexp, startIndex + 1);
                }

                stopIndex = regexIndexOf(fileContent, defineRegexp, startIndex + 1);
            } else {
                if(stopIndex !== -1) {
                    stopIndex = regexIndexOf(fileContent, defineRegexp, stopIndex + 1);
                } else {
                    startIndex = regexIndexOf(fileContent, defineRegexp, startIndex + 1);
                }
            }
        }
    }, function afterFileCollection () {

        dependencies = sortObjectByKey(dependencies);
        for( var className in dependencies) {
            if(className != "undefined") {
                tsort.add(className, dependencies[className]);
            }
        }

        //fs.writeFile('tsort.map.txt', JSON.stringify(tsort.map));

        try {
            var result = tsort.sort().reverse();
        } catch(e) {
            return this.emit('error', new PluginError(PLUGIN_NAME, e.message));
        }

        //fs.writeFile('tsort.result.txt', JSON.stringify(result));

        result.forEach(function (className) {
            if(files[className] && addedClasses.indexOf(files[className]) === -1) {
                addedClasses.push(files[className]);
                this.emit('data', files[className]);
            }
        }.bind(this));

        this.emit('end');
    });

    function countChars(str, char) {
        var hist = {};
        for (var si in str) {
            hist[str[si]] = hist[str[si]] ? 1 + hist[str[si]] : 1;
        };
        return hist[char];
    }

    function getClassNames(stringWithClassNames) {
        var allClassNames = [];

        if(stringWithClassNames) {
            var i = 0;
            stringWithClassNames.forEach(function (req) {
                var classNames = req.match(/[\'|\"][a-zA-Z0-9\.]+[\'|\"]/g);
                if(classNames) {
                    classNames.forEach(function (c, index) {
                        if (typeof index === "number") {
                            allClassNames[i++] = c.substr(1, c.length - 2);
                        }
                    });
                }
            });
        }

        return allClassNames;
    }

    function concatUnique(arr1, arr2) {
        arr2.forEach(function(element) {
            if(arr1.indexOf(element) === -1) {
                arr1.push(element);
            }
        });
        return arr1;
    }

    //noinspection Eslint
    function removeComments(content) {
        return content.replace(/(?:\/\*(?:[\s\S]*?)\*\/)|(?:([\s;])+\/\/(?:.*)$)/gm, '');
    }

    function regexIndexOf (str, regex, startpos) {
        var indexOf = str.substring(startpos || 0).search(regex);
        return (indexOf >= 0) ? (indexOf + (startpos || 0)) : indexOf;
    }

    function sortObjectByKey (obj){
        var keys = [];
        var sorted_obj = {};

        for(var key in obj){
            if(obj.hasOwnProperty(key)){
                keys.push(key);
            }
        }

        // sort keys
        keys.sort();

        // create new array based on Sorted Keys
        keys.forEach(function(key) {
            sorted_obj[key] = obj[key];
        });

        return sorted_obj;
    };
};<commit_msg>allow  tab intention### fixes #5<commit_after>'use strict';

var es = require('event-stream');
var TopoSort = require('topo-sort');
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;
//var fs = require('fs');

var PLUGIN_NAME = 'gulp-extify';

/**
 * this file just make sure that the test will work
 */
module.exports = function extify () {
    var files = {};
    var referencesFilesMap = {};
    var tsort = new TopoSort();

    var dependencies = {};
    var addedClasses = [];

    return es.through(function collectFilesToSort (file) {
        var defineRegexp = /Ext[\s|\n|\r]*\.define[\s|\n|\r]*\(/;

        if(!file.contents) {
            return this.emit('error', new PluginError(PLUGIN_NAME, 'File: "' + file.relative + '" is empty. You have to read it with gulp.src(..)'));
        }

        var fileContent = removeComments(file.contents.toString());

        var startIndex = regexIndexOf(fileContent, defineRegexp);
        var stopIndex = regexIndexOf(fileContent, defineRegexp, startIndex+1);

        while(startIndex !== -1) {
            var defineContent, contentUntilStopIndex;
            if (stopIndex !== -1) {
                defineContent = fileContent.substr(startIndex, stopIndex-startIndex);
                contentUntilStopIndex = fileContent.substr(0, stopIndex);
            } else {
                defineContent = fileContent.substr(startIndex);
                contentUntilStopIndex = fileContent;
            }
            var braceDiffUntilStopIndex = Math.abs(countChars(contentUntilStopIndex, '{') - countChars(contentUntilStopIndex, '}'));
            var openBraces = countChars(defineContent, '{');
            var closedBraces = countChars(defineContent, '}');

            if (openBraces === closedBraces) {

                var currentClassWithApostrophes = defineContent.match(/Ext[\s|\n|\r]*\.[\s|\n|\r]*define[\s|\n|\r|\(]*?[\'|\"][a-zA-Z0-9\.]*?[\'|\"]/);

                var requirements = defineContent.match(/requires[.|\n|\r|\s]*:[\s|\n|\r|]*[\[]*[a-zA-Z0-9|\n|\r|\'|\"|\s|\.|,|\/]*[\]]*/);
                var mixins = defineContent.match(/mixins[.|\n|\r| ]*:[\s|\n|\r][\{|\[]+(.|\n|\r)*?(\}|\])+/);
                var extend = defineContent.match(/extend[\s|\n|\r]*:[\s|\n|\r]*[\'|\"][a-zA-Z\.\s]*[\'|\"]/);
                var model = defineContent.match(/model[\s|\n|\r]*:[\s|\n|\r]*[\'|\"][a-zA-Z\.\s]*[\'|\"]/);

                //parse classnames
                var currentClass = getClassNames(currentClassWithApostrophes)[0];
                var reqClasses = getClassNames(requirements);
                var extendClasses = getClassNames(extend);
                var mixinClasses = getClassNames(mixins);
                var modelClass = getClassNames(model);

                var dependencyClasses = mixinClasses.concat(extendClasses).concat(reqClasses).concat(modelClass);

                if(braceDiffUntilStopIndex === 0) {
                    dependencies[currentClass] = dependencyClasses;
                    files[currentClass] = file;

                    //put all file paths in a map, and update all concat all dependencies
                    if(!referencesFilesMap[file.path]) {
                        referencesFilesMap[file.path] = [currentClass];
                    } else {
                        referencesFilesMap[file.path].forEach(function(refClassName) {
                            dependencies[refClassName] = concatUnique(dependencies[refClassName], dependencies[currentClass]);
                            dependencies[currentClass] = concatUnique(dependencies[currentClass], dependencies[currentClass]);
                        });
                    }
                }

                if(stopIndex !== -1) {
                    startIndex = regexIndexOf(fileContent, defineRegexp, stopIndex + 1);
                } else {
                    startIndex = regexIndexOf(fileContent, defineRegexp, startIndex + 1);
                }

                stopIndex = regexIndexOf(fileContent, defineRegexp, startIndex + 1);
            } else {
                if(stopIndex !== -1) {
                    stopIndex = regexIndexOf(fileContent, defineRegexp, stopIndex + 1);
                } else {
                    startIndex = regexIndexOf(fileContent, defineRegexp, startIndex + 1);
                }
            }
        }
    }, function afterFileCollection () {

        dependencies = sortObjectByKey(dependencies);
        for( var className in dependencies) {
            if(className != "undefined") {
                tsort.add(className, dependencies[className]);
            }
        }

        //fs.writeFile('tsort.map.txt', JSON.stringify(tsort.map));

        try {
            var result = tsort.sort().reverse();
        } catch(e) {
            return this.emit('error', new PluginError(PLUGIN_NAME, e.message));
        }

        //fs.writeFile('tsort.result.txt', JSON.stringify(result));

        result.forEach(function (className) {
            if(files[className] && addedClasses.indexOf(files[className]) === -1) {
                addedClasses.push(files[className]);
                this.emit('data', files[className]);
            }
        }.bind(this));

        this.emit('end');
    });

    function countChars(str, char) {
        var hist = {};
        for (var si in str) {
            hist[str[si]] = hist[str[si]] ? 1 + hist[str[si]] : 1;
        }
        return hist[char];
    }

    function getClassNames(stringWithClassNames) {
        var allClassNames = [];

        if(stringWithClassNames) {
            var i = 0;
            stringWithClassNames.forEach(function (req) {
                var classNames = req.match(/[\'|\"][a-zA-Z0-9\.]+[\'|\"]/g);
                if(classNames) {
                    classNames.forEach(function (c, index) {
                        if (typeof index === "number") {
                            allClassNames[i++] = c.substr(1, c.length - 2);
                        }
                    });
                }
            });
        }

        return allClassNames;
    }

    function concatUnique(arr1, arr2) {
        arr2.forEach(function(element) {
            if(arr1.indexOf(element) === -1) {
                arr1.push(element);
            }
        });
        return arr1;
    }

    //noinspection Eslint
    function removeComments(content) {
        return content.replace(/(?:\/\*(?:[\s\S]*?)\*\/)|(?:([\s;])+\/\/(?:.*)$)/gm, '');
    }

    function regexIndexOf (str, regex, startpos) {
        var indexOf = str.substring(startpos || 0).search(regex);
        return (indexOf >= 0) ? (indexOf + (startpos || 0)) : indexOf;
    }

    function sortObjectByKey (obj){
        var keys = [];
        var sorted_obj = {};

        for(var key in obj){
            if(obj.hasOwnProperty(key)){
                keys.push(key);
            }
        }

        // sort keys
        keys.sort();

        // create new array based on Sorted Keys
        keys.forEach(function(key) {
            sorted_obj[key] = obj[key];
        });

        return sorted_obj;
    }
};<|endoftext|>


<commit_before>var fs = require('fs');
var async = require('async');
var crypto = require('crypto');
var moment = require('moment');

var config = require('./configs/config.json');

// Load integration for BuildTools and Spigot
var buildtools = require('./buildtools-integration/buildtools.js');
var MinecraftServer = require('./minecraftserver-integration/server.js');

// Allow for color coded output
var colors = require('colors');

// Set color theme
colors.setTheme(config.colors);

// This line make nodejs not verify ssl certs. I have experienced issues with some jenkins servers which use Lets Encrypt certs which aren't supported by NodeJS
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

// Set encoding type of inputs
process.stdin.setEncoding('utf8');

function startServer(cb) {
    if (MinecraftServer.proc == null) {
        console.log();
        console.log("Starting server".notification);
        console.log('---------------------------------'.notification);

        MinecraftServer.start();

        MinecraftServer.onLog(function (data) {
            var log = data.toString().replace("\n", "");
            if (log.indexOf("WARN") > -1)
                log = log.warn;
            if (log.indexOf("ERROR") > -1)
                log = log.error;
            console.log(log);
        });
        MinecraftServer.onErr(function (data) {
            console.log(data.toString().replace("\n", "").error);
        });

        if (cb !== undefined)
            cb();
    }
    else {
        console.log("Server already running".error);
        cb();
    }
}

function setupMinecraftServer(callback) {

    console.log("Setting up server wrapper".notification);

    // Setup minecraft server
    MinecraftServer.path = config.minecraftserv.path;
    MinecraftServer.FileName = config.minecraftserv.FileName;
    MinecraftServer.pluginsDir = config.minecraftserv.pluginsDir;
    MinecraftServer.worldsDir = config.minecraftserv.worldsDir;
    MinecraftServer.configDirectory = config.minecraftserv.configDirectory;
    MinecraftServer.maxRam = config.minecraftserv.maxRam;
    MinecraftServer.minRam = config.minecraftserv.minRam;

    MinecraftServer.on('start', function () {
        console.log("Server has been started successfully".notification)
    });

    MinecraftServer.on("stop", function () {

        // Print to console that the server has been stopped
        console.log("Server has been stopped successfully".notification);

        // If auto restart is enabled, restart the server
        if (config.minecraftserv.AutoRestart) {
            startServer(function () {
                console.log("Server started automatically".notification)
            });
        }
    });

    callback();
}

function UpdatePlugins(cb) {
    var plugins = require("./configs/plugins.json");
    async.eachSeries(plugins, function iteratee(plugin, callback) {
        if (plugin.source == "jenkins") {
            var JenkinsPluginManager = require('./plugin-manager/jenkins');
            JenkinsPluginManager.download(plugin.repo, plugin.job, null, config.minecraftserv.path + config.minecraftserv.pluginsDir,callback);
        }
        if (plugin.source == "spigot") {
            var SpigotPluginManager = require('./plugin-manager/spigot');
            SpigotPluginManager.download(plugin.id,config.minecraftserv.path+config.minecraftserv.pluginsDir,callback);
        }
    },function() {
        cb();
    });
}

// Start the server startup sequence

async.series([
    function (callback) {
        console.log("Setting up server".notification);
        console.log('---------------------------------'.notification);

        // Download and run buildtools
        if (config.buildtools.run) {
            buildtools.run(callback)
        } else {
            console.log("Skipping buildtools as it is turned off in config".notification);
            callback();
        }
    },
    setupMinecraftServer,
    function (callback) {
        console.log('---------------------------------'.notification);
        console.log("Server preflight finished".notification);
        callback()
    },
    function (callback) {
        if (config.minecraftserv.AutoStart) {
            startServer(callback)
        } else {
            callback();
        }
    }
]);

// Define commands available for use
var wrapperCommands = {
    "stopwrapper": function (args) {
        config.minecraftserv.AutoRestart = false;
        MinecraftServer.stop(function () {
                console.log("Killing wrapper now".notification);
                process.kill(process.pid);
            }
        );
    },
    "set": function(args) {
        if (args[2] == "True") {
            args[2] = true;
        } else if (args[2] == "False") {
            args[2] = false;
        }
        config.minecraftserv[args[1]] = args[2];
    },
    "stop": function (args) {
        MinecraftServer.stop();
    },
    "start": function (args) {
        startServer();
    },
    "restart": function (args) {
        MinecraftServer.stop(function() {
            if (config.minecraftserv.AutoRestart == false) {
                startServer(function () {
                    console.log("Server has been restarted".notification)
                });
            }
        });
    },
    "recompile": function(args) {
        buildtools.run(function() {
            console.log("Sever has been updated".notification);
        });
    },
    "install": function(args) {
        var source = args[1];
        if (source == "jenkins") {
            var JenkinsPluginManager = require('./plugin-manager/jenkins');
            JenkinsPluginManager.install(args[2],args[3],null,config.minecraftserv.path+config.minecraftserv.pluginsDir, function(err) {
                if (err) {
                    console.log("Plugin installation failed".error)
                }
                console.log("Plugin installed!".notification)
            });
        } else if (source == "spigot") {
            var SpigotPluginManager = require('./plugin-manager/spigot');
            SpigotPluginManager.install(args[2],config.minecraftserv.path+config.minecraftserv.pluginsDir, function(err,test) {
                if (err) {
                    return console.log("Plugin installation failed".error)
                }
                console.log("Plugin installed!".notification)
            });
        }
    },
    "plugins": function(args) {
        if (args[1] == "list") {
            var plugins = require("./configs/plugins.json");
            for (var i in plugins) {
                var plugin = plugins[i];
                if (plugin.source == "jenkins") {
                    var formatted = moment( plugin.timestamp ).format("Y/M/D hh:MM:ss");
                    console.log(plugin.job.blue + " from ".blue +plugin.repo.red + " Build time: ".blue + formatted);
                } else {
                    console.log(plugin.name.blue + " from ".blue +plugin.source.red + " Version: ".blue + plugin.version);
                }
            }
        } else if (args[1] == "update") {
            UpdatePlugins(function() {
                console.log("Plugin update finished".notification);
            })
        }
    },
    "backup": function(args) {
        var backup = require('./backup-manager/index');
        backup.setConfig(config);
        args.shift(); // Remove first items from array as this is the command.
        backup.backup(args);
    }

};

// Listen for input on stdin
process.stdin.on('readable', function () {
    var chunk = process.stdin.read();
    if (chunk !== null) {
        if (chunk.substring(0, 1) == "!") {
            // Remove newline char and ! from input
            var length = chunk.length - 1;
            var command = chunk.substring(1, length).split(' ');

            // Execute command
            if (wrapperCommands[command[0]])
                wrapperCommands[command[0]](command);
        } else {
            // If command does not include a ! as the first character, consider it as a minecraft server command
            MinecraftServer.exec(chunk);
        }
    }
});

function runScriptSeries(script) {
    var AutoRestart = config.minecraftserv.AutoRestart;
    async.eachSeries(script, function iteratee(action, callback) {
        var ActionType = action.action;

        if (ActionType == "start") {
            config.minecraftserv.AutoRestart = AutoRestart;
            startServer(callback);
        }
        else if (ActionType == "stop") {
            config.minecraftserv.AutoRestart = false;
            MinecraftServer.stop(callback);
        }
        else if (ActionType == "updatePlugins") {
            UpdatePlugins(callback);
        }
        else if (ActionType == "command") {
            MinecraftServer.exec(action.command);
            setTimeout(function () {
                callback()
            }, action.wait * 1000);
        }
        else if (ActionType == "backup") {
            var backup = require('./backup-manager/index');
            backup.setConfig(config);
            backup.backup(action.items,callback);
        }
        else {
            setTimeout(function () {
                callback()
            }, 1000);
        }
    },function() {

    });
}

function startScheduler(id) {
    console.log("Starting scheduler ".notification+id.notification);
    var item = config.schedule[id];
    setInterval(function() {
        var actions = item.actions;
        runScriptSeries(actions)

    },item.every*1000);
}

// Setup scheduler
for (var i in config.schedule) {
    startScheduler(i);
}<commit_msg>Add callback to run script<commit_after>var fs = require('fs');
var async = require('async');
var crypto = require('crypto');
var moment = require('moment');

var config = require('./configs/config.json');

// Load integration for BuildTools and Spigot
var buildtools = require('./buildtools-integration/buildtools.js');
var MinecraftServer = require('./minecraftserver-integration/server.js');

// Allow for color coded output
var colors = require('colors');

// Set color theme
colors.setTheme(config.colors);

// This line make nodejs not verify ssl certs. I have experienced issues with some jenkins servers which use Lets Encrypt certs which aren't supported by NodeJS
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

// Set encoding type of inputs
process.stdin.setEncoding('utf8');

function startServer(cb) {
    if (MinecraftServer.proc == null) {
        console.log();
        console.log("Starting server".notification);
        console.log('---------------------------------'.notification);

        MinecraftServer.start();

        MinecraftServer.onLog(function (data) {
            var log = data.toString().replace("\n", "");
            if (log.indexOf("WARN") > -1)
                log = log.warn;
            if (log.indexOf("ERROR") > -1)
                log = log.error;
            console.log(log);
        });
        MinecraftServer.onErr(function (data) {
            console.log(data.toString().replace("\n", "").error);
        });

        if (cb !== undefined)
            cb();
    }
    else {
        console.log("Server already running".error);
        cb();
    }
}

function setupMinecraftServer(callback) {

    console.log("Setting up server wrapper".notification);

    // Setup minecraft server
    MinecraftServer.path = config.minecraftserv.path;
    MinecraftServer.FileName = config.minecraftserv.FileName;
    MinecraftServer.pluginsDir = config.minecraftserv.pluginsDir;
    MinecraftServer.worldsDir = config.minecraftserv.worldsDir;
    MinecraftServer.configDirectory = config.minecraftserv.configDirectory;
    MinecraftServer.maxRam = config.minecraftserv.maxRam;
    MinecraftServer.minRam = config.minecraftserv.minRam;

    MinecraftServer.on('start', function () {
        console.log("Server has been started successfully".notification)
    });

    MinecraftServer.on("stop", function () {

        // Print to console that the server has been stopped
        console.log("Server has been stopped successfully".notification);

        // If auto restart is enabled, restart the server
        if (config.minecraftserv.AutoRestart) {
            startServer(function () {
                console.log("Server started automatically".notification)
            });
        }
    });

    callback();
}

function UpdatePlugins(cb) {
    var plugins = require("./configs/plugins.json");
    async.eachSeries(plugins, function iteratee(plugin, callback) {
        if (plugin.source == "jenkins") {
            var JenkinsPluginManager = require('./plugin-manager/jenkins');
            JenkinsPluginManager.download(plugin.repo, plugin.job, null, config.minecraftserv.path + config.minecraftserv.pluginsDir,callback);
        }
        if (plugin.source == "spigot") {
            var SpigotPluginManager = require('./plugin-manager/spigot');
            SpigotPluginManager.download(plugin.id,config.minecraftserv.path+config.minecraftserv.pluginsDir,callback);
        }
    },function() {
        cb();
    });
}

// Start the server startup sequence

async.series([
    function (callback) {
        console.log("Setting up server".notification);
        console.log('---------------------------------'.notification);

        // Download and run buildtools
        if (config.buildtools.run) {
            buildtools.run(callback)
        } else {
            console.log("Skipping buildtools as it is turned off in config".notification);
            callback();
        }
    },
    setupMinecraftServer,
    function (callback) {
        console.log('---------------------------------'.notification);
        console.log("Server preflight finished".notification);
        callback()
    },
    function (callback) {
        if (config.minecraftserv.AutoStart) {
            startServer(callback)
        } else {
            callback();
        }
    }
]);

// Define commands available for use
var wrapperCommands = {
    "stopwrapper": function (args) {
        config.minecraftserv.AutoRestart = false;
        MinecraftServer.stop(function () {
                console.log("Killing wrapper now".notification);
                process.kill(process.pid);
            }
        );
    },
    "set": function(args) {
        if (args[2] == "True") {
            args[2] = true;
        } else if (args[2] == "False") {
            args[2] = false;
        }
        config.minecraftserv[args[1]] = args[2];
    },
    "stop": function (args) {
        MinecraftServer.stop();
    },
    "start": function (args) {
        startServer();
    },
    "restart": function (args) {
        MinecraftServer.stop(function() {
            if (config.minecraftserv.AutoRestart == false) {
                startServer(function () {
                    console.log("Server has been restarted".notification)
                });
            }
        });
    },
    "recompile": function(args) {
        buildtools.run(function() {
            console.log("Sever has been updated".notification);
        });
    },
    "install": function(args) {
        var source = args[1];
        if (source == "jenkins") {
            var JenkinsPluginManager = require('./plugin-manager/jenkins');
            JenkinsPluginManager.install(args[2],args[3],null,config.minecraftserv.path+config.minecraftserv.pluginsDir, function(err) {
                if (err) {
                    console.log("Plugin installation failed".error)
                }
                console.log("Plugin installed!".notification)
            });
        } else if (source == "spigot") {
            var SpigotPluginManager = require('./plugin-manager/spigot');
            SpigotPluginManager.install(args[2],config.minecraftserv.path+config.minecraftserv.pluginsDir, function(err,test) {
                if (err) {
                    return console.log("Plugin installation failed".error)
                }
                console.log("Plugin installed!".notification)
            });
        }
    },
    "plugins": function(args) {
        if (args[1] == "list") {
            var plugins = require("./configs/plugins.json");
            for (var i in plugins) {
                var plugin = plugins[i];
                if (plugin.source == "jenkins") {
                    var formatted = moment( plugin.timestamp ).format("Y/M/D hh:MM:ss");
                    console.log(plugin.job.blue + " from ".blue +plugin.repo.red + " Build time: ".blue + formatted);
                } else {
                    console.log(plugin.name.blue + " from ".blue +plugin.source.red + " Version: ".blue + plugin.version);
                }
            }
        } else if (args[1] == "update") {
            UpdatePlugins(function() {
                console.log("Plugin update finished".notification);
            })
        }
    },
    "backup": function(args) {
        var backup = require('./backup-manager/index');
        backup.setConfig(config);
        args.shift(); // Remove first items from array as this is the command.
        backup.backup(args);
    }

};

// Listen for input on stdin
process.stdin.on('readable', function () {
    var chunk = process.stdin.read();
    if (chunk !== null) {
        if (chunk.substring(0, 1) == "!") {
            // Remove newline char and ! from input
            var length = chunk.length - 1;
            var command = chunk.substring(1, length).split(' ');

            // Execute command
            if (wrapperCommands[command[0]])
                wrapperCommands[command[0]](command);
        } else {
            // If command does not include a ! as the first character, consider it as a minecraft server command
            MinecraftServer.exec(chunk);
        }
    }
});

function runScriptSeries(script,cb) {
    var AutoRestart = config.minecraftserv.AutoRestart;
    async.eachSeries(script, function iteratee(action, callback) {
        var ActionType = action.action;

        if (ActionType == "start") {
            config.minecraftserv.AutoRestart = AutoRestart;
            startServer(callback);
        }
        else if (ActionType == "stop") {
            config.minecraftserv.AutoRestart = false;
            MinecraftServer.stop(callback);
        }
        else if (ActionType == "updatePlugins") {
            UpdatePlugins(callback);
        }
        else if (ActionType == "command") {
            MinecraftServer.exec(action.command);
            setTimeout(function () {
                callback()
            }, action.wait * 1000);
        }
        else if (ActionType == "backup") {
            var backup = require('./backup-manager/index');
            backup.setConfig(config);
            backup.backup(action.items,callback);
        }
        else {
            setTimeout(function () {
                callback()
            }, 1000);
        }
    },function() {
        if (cb)
            cb();
    });
}

function startScheduler(id) {
    console.log("Starting scheduler ".notification+id.notification);
    var item = config.schedule[id];
    setInterval(function() {
        var actions = item.actions;
        runScriptSeries(actions)

    },item.every*1000);
}

// Setup scheduler
for (var i in config.schedule) {
    startScheduler(i);
}<|endoftext|>