<commit_before>;(function(root, factory) {
  if (typeof root.define === 'function' && root.define.amd)
    root.define(factory);
  else if (typeof exports === 'object')
    module.exports = factory(require, exports, module);
  else
    root.flume = factory();
})(this, function() {
  // api

  var nil = message(NilMsgType, null);

  function input() {
    return new InputDef();
  }

  function create(defs) {
    var self = {};
    self.dispatch = dispatch;
    self.inputs = buildGraph(self, defs);

    return self;

    function dispatch(def, msgs, done) {
      var nodes = inputsOf(self.inputs, def);
      var n = nodes.length;
      var i = -1;

      done = callOnNth(n, done || noop);
      while (++i < n) nodes[i].handle(msgs, done);

      return self;
    }
  }

  function message(type, v) {
    return new Msg(type, v);
  }

  function batch(values) {
    return new Batch(values.map(castMessage));
  }

  function except(obj) {
    return trap(ErrorMsgType, obj);
  }

  function trap(type, obj) {
    return conj(castProcessorShape(obj), {type: type});
  }

  // types

  function ValueMsgType() {}
  function ErrorMsgType() {}
  function NilMsgType() {}

  function Msg(type, value) {
    this.type = type;
    this.value = value;
  }

  function Batch(messages) {
    this.messages = messages;
  }

  function InputDef() {
  }

  function ProcessorDef(opts) {
    opts = castProcessorShape(opts);
    this.type = ensure(opts.type, ValueMsgType);
    this.init = ensure(opts.init, noop);
    this.process = opts.process;
  }

  function Node(graph, def, child, index) {
    this.graph = graph;
    this.def = def;
    this.child = child;
    this.index = index;
    this.handle = createHandler(this);
  }

  // graph building

  function buildGraph(graph, defs, child, index) {
    var i = defs.length - 1;
    if (i < 0) return [];

    // tail
    if (i) child = new Node(graph, new ProcessorDef(defs[i]), child, index);
    while (--i > 0) child = new Node(graph, new ProcessorDef(defs[i]), child, 0);

    return buildGraphHead(graph, defs[0], child);
  }

  function buildGraphHead(graph, defs, child) {
    defs = castArray(defs);

    var inputs = [];
    var i = -1;
    var def;
    var n = defs.length;

    while (++i < n) {
      def = defs[i];

      if (Array.isArray(def)) {
        inputs.push.apply(inputs, buildGraph(graph, def, child, i));
      } else if (def instanceof InputDef) {
        inputs.push(new Node(graph, def, child, i));
      } else {
        throw new Error("Expected input or array but got " + typeOf(def));
      }
    }

    return inputs;
  }

  function createHandler(node) {
    return {
      InputDef: createInputHandler,
      ProcessorDef: createProcessorHandler
    }[node.def.constructor.name](node);
  }

  function createInputHandler(node) {
    return function handle(msgs, end) {
      node.child.handle(msgs, node, end);
    };
  }

  function createProcessorHandler(node) {
    var queue = [];
    var isBusy = false;
    var task = null;
    var state = node.def.init();
    var processAsync = maybeAsync(process);

    return function handle(msgs, parent, end) {
      msgs = castBatch(msgs).messages;

      var i = -1;
      var n = msgs.length - 1;

      while (++i < n) schedule({
        msg: msgs[i],
        parent: parent,
        end: noop
      });

      if (n > -1) schedule({
        msg: msgs[n],
        parent: parent,
        end: end
      });
    };

    function schedule(task) {
      queue.push(task);
      if (!isBusy) next();
    }

    function next() {
      task = queue.shift();
      if (task) run();
    }

    function run() {
      isBusy = true;

      return processAsync()
        .then(resolveSeq)
        .then(success, failure)
        .then(done)
        .then(null, throwUnhandled);
    }

    function process() {
      return node.def.type === task.msg.type
        ? node.def.process(state, task.msg.value, task.parent.index, node.graph)
        : [state, task.msg];
    }

    function done(msgs) {
      var end = task.end;

      isBusy = false;
      task = null;

      if (node.child) node.child.handle(msgs, node, end);
      else end();

      next();
    }

    function success(res) {
      if (Array.isArray(res)) {
        state = res[0];
        return res[1];
      }
      else {
        return nil;
      }
    }

    function failure(e) {
      if (!node.child) throw e;
      return message(ErrorMsgType, e);
    }
  }

  // utils

  function inputsOf(inputs, def) {
    var res = [];
    var n = inputs.length;
    var i = -1;
    var input;

    while (++i < n) {
      input = inputs[i];
      if (input.def === def) res.push(input);
    }

    return res;
  }

  function conj() {
    var res = {};
    var objects = Array.prototype.slice.call(arguments);

    var i = -1;
    var n = objects.length;
    var obj;

    while (++i < n) {
      obj = objects[i];
      for (var k in obj) if (obj.hasOwnProperty(k)) res[k] = obj[k]
    }

    return res;
  }

  function noop() {
    return null;
  }

  function ensure(v, defaultVal) {
    return typeof v === 'undefined'
      ? defaultVal
      : v;
  }

  function identity(v) {
    return v;
  }

  function throwError(e) {
    throw e;
  }

  function castBatch(v) {
    return !(v instanceof Batch)
      ? batch([v])
      : v;
  }

  function castMessage(v) {
    return !(v instanceof Msg)
      ? message(ValueMsgType, v)
      : v;
  }

  function castArray(v) {
    return !Array.isArray(v)
      ? [v]
      : v;
  }

  function castProcessorShape(v) {
    if (typeof v != 'function' && (typeof (v || 0).process != 'function')) throw new Error(
      "Expected function or object with 'process' function property but got " + typeOf(v));

    return typeof v === 'function'
      ? {process: v}
      : v;
  }

  function typeOf(v) {
    return v !== null
      ? typeof v
      : 'null';
  }

  function callOnNth(n, fn) {
    var i = 0;

    return function onNthFn() {
      if (++i >= n) fn.apply(null, arguments);
    };
  }

  function maybeAsync(fn) {
    return function maybeAsyncFn() {
      try {
        var v = fn.apply(this, arguments);
        return castThenable(v);
      } catch (e) {
        if (e instanceof UnhandledError) throw e.error;
        return thenableError(e);
      }
    }
  }

  function castThenable(v) {
    return !isThenable(v)
      ? thenableValue(v)
      : v;
  }

  function thenableValue(v) {
    return new Thenable(v, false);
  }

  function thenableError(e) {
    return new Thenable(e, true);
  }

  function resolveSeq(values) {
    return Array.isArray(values) && values.filter(isThenable).length > 0
      ? resolveThenablesSeq(values)
      : castThenable(values);
  }

  function resolveThenablesSeq(values) {
    var res = [];
    var n = values.length;
    var i = -1;
    var j = -1;
    var p = thenableValue(null);

    while (++i < n) p = p.then(call);
    return p.then(done);

    function call() {
      return castThenable(values[++j]).then(push);
    }

    function push(v) {
      res.push(v);
    }

    function done() {
      return res;
    }
  }

  function isThenable(v) {
    return !!(v || 0).then;
  }

  function throwUnhandled(e) {
    if (this instanceof Thenable) throw new UnhandledError(e);
    else throw e;
  }

  function UnhandledError(error) {
    this.error = error;
  }

  function Thenable(value, isFailure) {
    this.value = value;
    this.isFailure = isFailure;
  }

  Thenable.prototype.then = maybeAsync(function then(successFn, failureFn) {
    if (this.isFailure) return (failureFn || throwError).call(this, this.value);
    else return (successFn || identity).call(this, this.value);
  });

  return {
    create: create,
    input: input,
    message: message,
    batch: batch,
    except: except,
    trap: trap,
    nil: nil
  };
});
<commit_msg>export utils likely to be used elsewhere<commit_after>;(function(root, factory) {
  if (typeof root.define === 'function' && root.define.amd)
    root.define(factory);
  else if (typeof exports === 'object')
    module.exports = factory(require, exports, module);
  else
    root.flume = factory();
})(this, function() {
  // api

  var nil = message(NilMsgType, null);

  function input() {
    return new InputDef();
  }

  function create(defs) {
    var self = {};
    self.dispatch = dispatch;
    self.inputs = buildGraph(self, defs);

    return self;

    function dispatch(def, msgs, done) {
      var nodes = inputsOf(self.inputs, def);
      var n = nodes.length;
      var i = -1;

      done = callOnNth(n, done || noop);
      while (++i < n) nodes[i].handle(msgs, done);

      return self;
    }
  }

  function message(type, v) {
    return new Msg(type, v);
  }

  function batch(values) {
    return new Batch(values.map(castMessage));
  }

  function except(obj) {
    return trap(ErrorMsgType, obj);
  }

  function trap(type, obj) {
    return conj(castProcessorShape(obj), {type: type});
  }

  // types

  function ValueMsgType() {}
  function ErrorMsgType() {}
  function NilMsgType() {}

  function Msg(type, value) {
    this.type = type;
    this.value = value;
  }

  function Batch(messages) {
    this.messages = messages;
  }

  function InputDef() {
  }

  function ProcessorDef(opts) {
    opts = castProcessorShape(opts);
    this.type = ensure(opts.type, ValueMsgType);
    this.init = ensure(opts.init, noop);
    this.process = opts.process;
  }

  function Node(graph, def, child, index) {
    this.graph = graph;
    this.def = def;
    this.child = child;
    this.index = index;
    this.handle = createHandler(this);
  }

  // graph building

  function buildGraph(graph, defs, child, index) {
    var i = defs.length - 1;
    if (i < 0) return [];

    // tail
    if (i) child = new Node(graph, new ProcessorDef(defs[i]), child, index);
    while (--i > 0) child = new Node(graph, new ProcessorDef(defs[i]), child, 0);

    return buildGraphHead(graph, defs[0], child);
  }

  function buildGraphHead(graph, defs, child) {
    defs = castArray(defs);

    var inputs = [];
    var i = -1;
    var def;
    var n = defs.length;

    while (++i < n) {
      def = defs[i];

      if (Array.isArray(def)) {
        inputs.push.apply(inputs, buildGraph(graph, def, child, i));
      } else if (def instanceof InputDef) {
        inputs.push(new Node(graph, def, child, i));
      } else {
        throw new Error("Expected input or array but got " + typeOf(def));
      }
    }

    return inputs;
  }

  function createHandler(node) {
    return {
      InputDef: createInputHandler,
      ProcessorDef: createProcessorHandler
    }[node.def.constructor.name](node);
  }

  function createInputHandler(node) {
    return function handle(msgs, end) {
      node.child.handle(msgs, node, end);
    };
  }

  function createProcessorHandler(node) {
    var queue = [];
    var isBusy = false;
    var task = null;
    var state = node.def.init();
    var processAsync = maybeAsync(process);

    return function handle(msgs, parent, end) {
      msgs = castBatch(msgs).messages;

      var i = -1;
      var n = msgs.length - 1;

      while (++i < n) schedule({
        msg: msgs[i],
        parent: parent,
        end: noop
      });

      if (n > -1) schedule({
        msg: msgs[n],
        parent: parent,
        end: end
      });
    };

    function schedule(task) {
      queue.push(task);
      if (!isBusy) next();
    }

    function next() {
      task = queue.shift();
      if (task) run();
    }

    function run() {
      isBusy = true;

      return processAsync()
        .then(resolveSeq)
        .then(success, failure)
        .then(done)
        .then(null, throwUnhandled);
    }

    function process() {
      return node.def.type === task.msg.type
        ? node.def.process(state, task.msg.value, task.parent.index, node.graph)
        : [state, task.msg];
    }

    function done(msgs) {
      var end = task.end;

      isBusy = false;
      task = null;

      if (node.child) node.child.handle(msgs, node, end);
      else end();

      next();
    }

    function success(res) {
      if (Array.isArray(res)) {
        state = res[0];
        return res[1];
      }
      else {
        return nil;
      }
    }

    function failure(e) {
      if (!node.child) throw e;
      return message(ErrorMsgType, e);
    }
  }

  // utils

  function inputsOf(inputs, def) {
    var res = [];
    var n = inputs.length;
    var i = -1;
    var input;

    while (++i < n) {
      input = inputs[i];
      if (input.def === def) res.push(input);
    }

    return res;
  }

  function conj() {
    var res = {};
    var objects = Array.prototype.slice.call(arguments);

    var i = -1;
    var n = objects.length;
    var obj;

    while (++i < n) {
      obj = objects[i];
      for (var k in obj) if (obj.hasOwnProperty(k)) res[k] = obj[k]
    }

    return res;
  }

  function noop() {
    return null;
  }

  function ensure(v, defaultVal) {
    return typeof v === 'undefined'
      ? defaultVal
      : v;
  }

  function identity(v) {
    return v;
  }

  function throwError(e) {
    throw e;
  }

  function castBatch(v) {
    return !(v instanceof Batch)
      ? batch([v])
      : v;
  }

  function castMessage(v) {
    return !(v instanceof Msg)
      ? message(ValueMsgType, v)
      : v;
  }

  function castArray(v) {
    return !Array.isArray(v)
      ? [v]
      : v;
  }

  function castProcessorShape(v) {
    if (typeof v != 'function' && (typeof (v || 0).process != 'function')) throw new Error(
      "Expected function or object with 'process' function property but got " + typeOf(v));

    return typeof v === 'function'
      ? {process: v}
      : v;
  }

  function typeOf(v) {
    return v !== null
      ? typeof v
      : 'null';
  }

  function callOnNth(n, fn) {
    var i = 0;

    return function onNthFn() {
      if (++i >= n) fn.apply(null, arguments);
    };
  }

  function maybeAsync(fn) {
    return function maybeAsyncFn() {
      try {
        var v = fn.apply(this, arguments);
        return castThenable(v);
      } catch (e) {
        if (e instanceof UnhandledError) throw e.error;
        return thenableError(e);
      }
    }
  }

  function castThenable(v) {
    return !isThenable(v)
      ? thenableValue(v)
      : v;
  }

  function thenableValue(v) {
    return new Thenable(v, false);
  }

  function thenableError(e) {
    return new Thenable(e, true);
  }

  function resolveSeq(values) {
    return Array.isArray(values) && values.filter(isThenable).length > 0
      ? resolveThenablesSeq(values)
      : castThenable(values);
  }

  function resolveThenablesSeq(values) {
    var res = [];
    var n = values.length;
    var i = -1;
    var j = -1;
    var p = thenableValue(null);

    while (++i < n) p = p.then(call);
    return p.then(done);

    function call() {
      return castThenable(values[++j]).then(push);
    }

    function push(v) {
      res.push(v);
    }

    function done() {
      return res;
    }
  }

  function isThenable(v) {
    return !!(v || 0).then;
  }

  function throwUnhandled(e) {
    if (this instanceof Thenable) throw new UnhandledError(e);
    else throw e;
  }

  function UnhandledError(error) {
    this.error = error;
  }

  function Thenable(value, isFailure) {
    this.value = value;
    this.isFailure = isFailure;
  }

  Thenable.prototype.then = maybeAsync(function then(successFn, failureFn) {
    if (this.isFailure) return (failureFn || throwError).call(this, this.value);
    else return (successFn || identity).call(this, this.value);
  });

  return {
    create: create,
    input: input,
    message: message,
    batch: batch,
    except: except,
    trap: trap,
    nil: nil,
    conj: conj,
    maybeAsync: maybeAsync,
    resolveSeq: resolveSeq
  };
});
<|endoftext|>


<commit_before>/*
 * gult-stubby
 * https://github.com/felixzapata/gulp-pug-i18n
 *
 * Copyright (c) 2016 Félix Zapata
 * Licensed under the MIT license.
 */

'use strict';

var R = require('ramda');
var pug = require('pug');
var glob = require('glob');
var fs = require('fs');
var gutil = require('gulp-util');
var ext = require('gulp-util').replaceExtension;
var PluginError = require('gulp-util').PluginError;
var path = require('path');
var YAML = require('js-yaml');
var through = require('through2');
var PLUGIN_NAME = 'gulp-pug-i18n';

function getExtension(filepath) {
    return path.extname(filepath);
}

function setExtension(ext) {
    if (ext.charAt(0) !== '.') {
        ext = '.' + ext;
    }
    return ext;
}

function readYAML(filepath, options) {
    var src = fs.readFileSync(filepath, options);
    var result;
    try {
        result = YAML.load(src);
        return result;
    } catch (e) {
        throw new gutil.PluginError(PLUGIN_NAME, 'Unable to parse "' + filepath + '" file (' + e.problem + ').', e);
    }
}

function readJSON(filepath, options) {
    var src = fs.readFileSync(filepath, options);
    var result;
    try {
        result = JSON.parse(src);
        return result;
    } catch (e) {
        throw new gutil.PluginError(PLUGIN_NAME, 'Unable to parse "' + filepath + '" file (' + e.message + ').', e);
    }
}

function addLocaleExtensionDest(obj, locale, outputExt) {

    var files = glob.sync(path.join(obj.cwd, obj.src));
    return _.map(files, function (file) {

        var dest, ext;

        locale = locale.toLowerCase();
        ext = getExtension(file);

        function getBaseName() {
            return path.basename(file).split('.')[0];
        }

        if (ext) {
            dest = path.join(obj.dest, path.basename(file, ext) + '.' + locale);
        } else {
            dest = path.join(obj.dest, getBaseName() + '.' + locale);
        }

        if (obj.ext) {
            dest += setExtension(obj.ext);
        } else {
            dest += setExtension(outputExt);
        }

        return dest;
    });
}

function addLocaleDirnameDest(file, locale, outputExt) {
    var base, dest, ext = getExtension(file);
    if (ext) {
        dest = path.join(path.dirname(file), locale, path.basename(file, ext) + setExtension(ext));
    } else {
        if (/(\/|\*+)$/i.test(file)) {
            base = file.split('/');
            dest = path.join(path.join.apply(null, base.slice(0, -1)), locale, base.slice(-1)[0]);
        } else {
            dest = path.join(file, locale);
        }
    }
    dest = dest.replace(/\.pug$/i, setExtension(outputExt));
    return dest;
}

function readFile(filepath) {
    var data;
    try {
        if (/(\.yaml|\.yml)$/i.test(filepath)) {
            data = readYAML(filepath);
        } else if (/\.js$/i.test(filepath)) {
            data = require(path.resolve(filepath));
        } else {
            data = readJSON(filepath);
        }
    } catch (_error) {
        throw new gutil.PluginError("Cannot parse file '" + filepath + "': " + _error.message, _error);
    }
    return data;
}

function plugI18nPlugin(options) {

    var baseName;
    var compiledFile;
    var defaultExt;
    var dest;
    var localeExtension;
    var localePath;
    var namespace;
    var fileExt;
    var locale;

    if (!options.i18n) {
        options.i18n = {};
    } else {
        locales = options.i18n.locales;
        namespace = options.i18n.namespace;
        localeExtension = options.i18n.localeExtension;
        defaultExt = options.i18n.defaultExt;
    }

    if (!namespace) {
        namespace = '$i18n';
    }

    if (!localeExtension) {
        localeExtension = false;
    }

    if (!defaultExt) {
        defaultExt = '.html';
    }

    var locales = glob.sync(options.i18n.locales);

    var bufferContents = function (file, enc, cb) {

        if (file.isNull()) {
            cb(null, file);
            return;
        }

        if (file.isStream()) {
            driver.quit();
            cb(new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
            return;
        }

        if (locales && locales.length) {

            for(var i = 0, len = locales.length; i < len; i++) {
                localePath = locales[i];
                fileExt = localePath.split('.').slice(-1)[0];
                locale = path.basename(localePath, '.' + fileExt);
                baseName = path.basename(file.path);
                gutil.log('Loading locale ' + locale);
                gutil.log('Reading translation data: ' + localePath);
                if (!options.data) {
                    options.data = {};
                }
                options.data[namespace] = readFile(localePath);

                if (localeExtension) {
                    dest = addLocaleExtensionDest(baseName, locale, defaultExt);
                } else {
                    dest = addLocaleDirnameDest(baseName, locale, defaultExt);
                }

                compiledFile = new gutil.File({
                    base: path.join(__dirname, locale),
                    cwd: __dirname,
                    contents: new Buffer(pug.compileFile(file.path, options)(options.data)),
                    path: path.join(options.i18n.dest, dest)
                });

            }

        } else {
            gutil.log('Locales files not found. Nothing to translate');
        }

        cb();
    }

    var endStream = function (cb) {
        if (!compiledFile) {
            cb();
            return;
        }
        this.push(compiledFile);
        cb();
    }

    return through.obj(bufferContents, endStream);
}

module.exports = plugI18nPlugin;
<commit_msg>feat(index.js): iterate over multiple locales files<commit_after>/*
 * gult-stubby
 * https://github.com/felixzapata/gulp-pug-i18n
 *
 * Copyright (c) 2016 Félix Zapata
 * Licensed under the MIT license.
 */

'use strict';

var R = require('ramda');
var pug = require('pug');
var glob = require('glob');
var fs = require('fs');
var gutil = require('gulp-util');
var ext = require('gulp-util').replaceExtension;
var PluginError = require('gulp-util').PluginError;
var path = require('path');
var YAML = require('js-yaml');
var through = require('through2');
var PLUGIN_NAME = 'gulp-pug-i18n';

function getExtension(filepath) {
    return path.extname(filepath);
}

function setExtension(ext) {
    if (ext.charAt(0) !== '.') {
        ext = '.' + ext;
    }
    return ext;
}

function readYAML(filepath, options) {
    var src = fs.readFileSync(filepath, options);
    var result;
    try {
        result = YAML.load(src);
        return result;
    } catch (e) {
        throw new gutil.PluginError(PLUGIN_NAME, 'Unable to parse "' + filepath + '" file (' + e.problem + ').', e);
    }
}

function readJSON(filepath, options) {
    var src = fs.readFileSync(filepath, options);
    var result;
    try {
        result = JSON.parse(src);
        return result;
    } catch (e) {
        throw new gutil.PluginError(PLUGIN_NAME, 'Unable to parse "' + filepath + '" file (' + e.message + ').', e);
    }
}

function addLocaleExtensionDest(obj, locale, outputExt) {

    var files = glob.sync(path.join(obj.cwd, obj.src));
    return _.map(files, function (file) {

        var dest, ext;

        locale = locale.toLowerCase();
        ext = getExtension(file);

        function getBaseName() {
            return path.basename(file).split('.')[0];
        }

        if (ext) {
            dest = path.join(obj.dest, path.basename(file, ext) + '.' + locale);
        } else {
            dest = path.join(obj.dest, getBaseName() + '.' + locale);
        }

        if (obj.ext) {
            dest += setExtension(obj.ext);
        } else {
            dest += setExtension(outputExt);
        }

        return dest;
    });
}

function addLocaleDirnameDest(file, locale, outputExt) {
    var base, dest, ext = getExtension(file);
    if (ext) {
        dest = path.join(path.dirname(file), locale, path.basename(file, ext) + setExtension(ext));
    } else {
        if (/(\/|\*+)$/i.test(file)) {
            base = file.split('/');
            dest = path.join(path.join.apply(null, base.slice(0, -1)), locale, base.slice(-1)[0]);
        } else {
            dest = path.join(file, locale);
        }
    }
    dest = dest.replace(/\.pug$/i, setExtension(outputExt));
    return dest;
}

function readFile(filepath) {
    var data;
    try {
        if (/(\.yaml|\.yml)$/i.test(filepath)) {
            data = readYAML(filepath);
        } else if (/\.js$/i.test(filepath)) {
            data = require(path.resolve(filepath));
        } else {
            data = readJSON(filepath);
        }
    } catch (_error) {
        throw new gutil.PluginError("Cannot parse file '" + filepath + "': " + _error.message, _error);
    }
    return data;
}

function plugI18nPlugin(options) {

    var baseName;
    var compiledFiles = [];
    var defaultExt;
    var dest;
    var localeExtension;
    var localePath;
    var namespace;
    var fileExt;
    var locale;

    if (!options.i18n) {
        options.i18n = {};
    } else {
        locales = options.i18n.locales;
        namespace = options.i18n.namespace;
        localeExtension = options.i18n.localeExtension;
        defaultExt = options.i18n.defaultExt;
    }

    if (!namespace) {
        namespace = '$i18n';
    }

    if (!localeExtension) {
        localeExtension = false;
    }

    if (!defaultExt) {
        defaultExt = '.html';
    }

    var locales = glob.sync(options.i18n.locales);

    var bufferContents = function (file, enc, cb) {

        if (file.isNull()) {
            cb(null, file);
            return;
        }

        if (file.isStream()) {
            driver.quit();
            cb(new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
            return;
        }

        if (locales && locales.length) {

            for (var i = 0, len = locales.length; i < len; i++) {
                localePath = locales[i];
                fileExt = localePath.split('.').slice(-1)[0];
                locale = path.basename(localePath, '.' + fileExt);
                baseName = path.basename(file.path);
                gutil.log('Loading locale ' + locale);
                gutil.log('Reading translation data: ' + localePath);
                if (!options.data) {
                    options.data = {};
                }
                options.data[namespace] = readFile(localePath);

                if (localeExtension) {
                    dest = addLocaleExtensionDest(baseName, locale, defaultExt);
                } else {
                    dest = addLocaleDirnameDest(baseName, locale, defaultExt);
                }

                compiledFiles.push(new gutil.File({
                    base: path.join(__dirname, locale),
                    cwd: __dirname,
                    contents: new Buffer(pug.compileFile(file.path, options)(options.data)),
                    path: path.join(options.i18n.dest, dest)
                }));

            }

        } else {
            gutil.log('Locales files not found. Nothing to translate');
        }
        cb();
    }

    var endStream = function (cb) {
        if (!compiledFiles || compiledFiles.length === 0) {
            cb();
            return;
        }
        for (var i = 0, len = compiledFiles.length; i < len; i++) {
            this.push(compiledFiles[i]);
        }
        cb();
    }

    return through.obj(bufferContents, endStream);
}

module.exports = plugI18nPlugin;
<|endoftext|>


<commit_before>"use strict"

const express = require('express')
const app = express()
const bodyParser = require("body-parser")
const twitterParse = require('twitter-url-parser')
const twitterAPI = require('node-twitter-api')
const twitter = new twitterAPI({
	consumerKey: process.env.TWITTER_CONSUMER_KEY,
	consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
	callback: process.env.TWITTER_OAUTH_CALLBACK || 'http://localhost:8080/oauth'
})
let sessionRequestToken
let sessionRequestTokenSecret
let sessionAccessToken
let sessionAccessTokenSecret

twitter.getRequestToken(function(error, requestToken, requestTokenSecret, results){
    if (error) {
        console.log("Error getting OAuth request token : " + error)
    } else {
        sessionRequestToken = requestToken
        sessionRequestTokenSecret = requestTokenSecret

        console.log(twitter.getAuthUrl(sessionRequestToken))
    }
});

app.use(bodyParser.json());

app.post('/', (req, res) => {
  twitter.search(
      { q: '"' + req.body.text + '"' },
      sessionRequestToken,
      sessionRequestTokenSecret,
      (err, data, response) => {
        console.log('error: ' + err)
        console.log('data: ' + data)
      })

  res.end()
})

app.get('/oauth', (req, res) => {
  sessionAccessToken = req.query.oauth_token
  sessionAccessTokenSecret = req.query.oauth_verifier

  twitter.verifyCredentials(sessionAccessToken, sessionAccessTokenSecret, {}, (error, data, response) => {
      if (error) {
          //something was wrong with either accessToken or accessTokenSecret
          //start over with Step 1
      } else {
          //accessToken and accessTokenSecret can now be used to make api-calls (not yet implemented)
          //data contains the user-data described in the official Twitter-API-docs
          //you could e.g. display his screen_name
          console.log(data["screen_name"]);
      }
  })

  res.end()
})

app.listen(process.env.PORT || 8080, () => console.log('listening ' + (process.env.PORT || 8080)))<commit_msg>Log errors<commit_after>"use strict"

const express = require('express')
const app = express()
const bodyParser = require("body-parser")
const twitterParse = require('twitter-url-parser')
const twitterAPI = require('node-twitter-api')
const twitter = new twitterAPI({
	consumerKey: process.env.TWITTER_CONSUMER_KEY,
	consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
	callback: process.env.TWITTER_OAUTH_CALLBACK || 'http://localhost:8080/oauth'
})
let sessionRequestToken
let sessionRequestTokenSecret
let sessionAccessToken
let sessionAccessTokenSecret

twitter.getRequestToken(function(error, requestToken, requestTokenSecret, results){
    if (error) {
        console.log("Error getting OAuth request token : " + error)
    } else {
        sessionRequestToken = requestToken
        sessionRequestTokenSecret = requestTokenSecret

        console.log(twitter.getAuthUrl(sessionRequestToken))
    }
});

app.use(bodyParser.json());

app.post('/', (req, res) => {
  twitter.search(
      { q: '"' + req.body.text + '"' },
      sessionRequestToken,
      sessionRequestTokenSecret,
      (err, data, response) => {
        console.log('error: ' + err)
        console.log('data: ' + data)
      })

  res.end()
})

app.get('/oauth', (req, res) => {
  sessionAccessToken = req.query.oauth_token
  sessionAccessTokenSecret = req.query.oauth_verifier

  twitter.verifyCredentials(
    sessionAccessToken,
    sessionAccessTokenSecret,
    {},
    (error, data, response) => {
        if (error) {
            console.log(error)
        } else {
            //accessToken and accessTokenSecret can now be used to make api-calls (not yet implemented)
            //data contains the user-data described in the official Twitter-API-docs
            //you could e.g. display his screen_name
            console.log(data["screen_name"]);
        }
    })

  res.end()
})

app.listen(process.env.PORT || 8080, () => console.log('listening ' + (process.env.PORT || 8080)))<|endoftext|>


<commit_before>// Require browserify and watchify from the parent so that their versions are
// not tied to gulp-watchify
try {
  var browserify = module.parent.require('browserify'),
      watchify = module.parent.require('watchify');
} catch(e) {
  var parentFile = module.parent.id
  throw new Error([
    gutil.colors.red('Local browserify or watchify not found in ' + parentFile),
    gutil.colors.red('Try running: ' + 'npm install browserify watchify')
  ].join("\n"))
}

function log() {
  var gutil = require('gulp-util');
  var args = Array.prototype.slice.call(arguments)
  var prefix = [gutil.colors.magenta('[gulp-watchify]')]
  args[0] = prefix + ' ' + args[0]
  return gutil.log.apply(this,args);
}

function rebundle(opts) {
  var _  = require('underscore'),
  source = require('vinyl-source-stream');

  var stream = opts.stream,
  bundler    = opts.bundler;

  bundler.compiles = bundler.compiles || 0
  bundler.compiles++

  if (typeof bundler.start_time !== "undefined" && bundler.start_time !== null) {
    log('time since last execution: ' + gutil.colors.cyan(Date.now() - bundler.start_time + 'ms'))
  }
  bundler.start_time = Date.now()

  // Form bundle
  bundle = bundler.bundle()

  // Catch errors
  bundle.on('error', (function(_this) {
    return function(err) {
      gutil.log(gutil.colors.red("" + (err.annotated || err.message)))
      return stream.emit('end')
    }
  })(this))

  var browserifyStream = bundle.pipe(source(opts.filename))
  browserifyStream.on('data', (function(_this) {
    return function(data) {
      // Forward data returned to opts.stream
      stream.emit('data', data)

      // Log compilation time
      var start_time = bundler.start_time
      var end_time = Date.now()

      if (end_time - start_time > 0) {
        log('compiled in ' + gutil.colors.cyan((end_time - start_time) + 'ms'))
      }

      if (bundler.compiles >= 1 && opts.watch === false) {
        // Close stream if not in watch mode
        stream.emit('end')
        return bundler.close()
      }
    }
  })(this))
  return bundle;
}

module.exports = function(opts) {
  var _       = require('underscore'),
  eventStream = require('event-stream');

  var ctx = {rebundle: rebundle}

  stream = eventStream.writeArray(function(err, files) {
    var entries = _.pluck(files, 'path')

    var browserifyOpts = _.omit(_.extend(opts, {
      cache: {},
      packageCache: {},
      entries: entries,
    }), 'watch', 'filename')

    bundler = watchify(browserify(opts))
    stream.emit('prebundle', bundler)

		// Compile files once, as well as whenever the bundle changes
    var rebundle = this.rebundle.bind(null, _.extend(
      opts, {
        stream: stream,
        bundler: bundler
      }
    ))
    bundler.on('update', rebundle)
    return rebundle();
  }.bind(ctx))

  return stream;
};
<commit_msg>make util lib global<commit_after>var gutil = require('gulp-util')

// Require browserify and watchify from the parent so that their versions are
// not tied to gulp-watchify
try {
  var browserify = module.parent.require('browserify'),
      watchify = module.parent.require('watchify');
} catch(e) {
  var parentFile = module.parent.id
  throw new Error([
    gutil.colors.red('Local browserify or watchify not found in ' + parentFile),
    gutil.colors.red('Try running: ' + 'npm install browserify watchify')
  ].join("\n"))
}

function log() {
  var args = Array.prototype.slice.call(arguments)
  var prefix = [gutil.colors.magenta('[gulp-watchify]')]
  args[0] = prefix + ' ' + args[0]
  return gutil.log.apply(this,args);
}

function rebundle(opts) {
  var _  = require('underscore'),
  source = require('vinyl-source-stream');

  var stream = opts.stream,
  bundler    = opts.bundler;

  bundler.compiles = bundler.compiles || 0
  bundler.compiles++

  if (typeof bundler.start_time !== "undefined" && bundler.start_time !== null) {
    log('time since last execution: ' + gutil.colors.cyan(Date.now() - bundler.start_time + 'ms'))
  }
  bundler.start_time = Date.now()

  // Form bundle
  bundle = bundler.bundle()

  // Catch errors
  bundle.on('error', (function(_this) {
    return function(err) {
      gutil.log(gutil.colors.red("" + (err.annotated || err.message)))
      return stream.emit('end')
    }
  })(this))

  var browserifyStream = bundle.pipe(source(opts.filename))
  browserifyStream.on('data', (function(_this) {
    return function(data) {
      // Forward data returned to opts.stream
      stream.emit('data', data)

      // Log compilation time
      var start_time = bundler.start_time
      var end_time = Date.now()

      if (end_time - start_time > 0) {
        log('compiled in ' + gutil.colors.cyan((end_time - start_time) + 'ms'))
      }

      if (bundler.compiles >= 1 && opts.watch === false) {
        // Close stream if not in watch mode
        stream.emit('end')
        return bundler.close()
      }
    }
  })(this))
  return bundle;
}

module.exports = function(opts) {
  var _       = require('underscore'),
  eventStream = require('event-stream');

  var ctx = {rebundle: rebundle}

  opts = _.defaults(opts, {watch: false, filename: 'app.js'})

  stream = eventStream.writeArray(function(err, files) {
    var entries = _.pluck(files, 'path')

    var browserifyOpts = _.omit(_.extend(opts, {
      cache: {},
      packageCache: {},
      entries: entries,
    }), 'watch', 'filename')

    bundler = watchify(browserify(opts))
    stream.emit('prebundle', bundler)

		// Compile files once, as well as whenever the bundle changes
    var rebundle = this.rebundle.bind(null, _.extend(
      opts, {
        stream: stream,
        bundler: bundler
      }
    ))
    bundler.on('update', rebundle)
    return rebundle();
  }.bind(ctx))

  return stream;
};
<|endoftext|>


<commit_before>'use strict';

var gutil = require('gulp-util');
var File = require('vinyl');
var MemoryFileSystem = require('memory-fs');
var through = require('through');
var ProgressPlugin = require('webpack/lib/ProgressPlugin');
var MultiCompiler = require('webpack/lib/MultiCompiler');
var clone = require('lodash.clone');
var some = require('lodash.some');

var defaultStatsOptions = {
  colors: gutil.colors.supportsColor,
  hash: false,
  timings: false,
  chunks: false,
  chunkModules: false,
  modules: false,
  children: true,
  version: true,
  cached: false,
  cachedAssets: false,
  reasons: false,
  source: false,
  errorDetails: false
};

module.exports = function (options, wp, done) {
  options = clone(options) || {};
  var config = options.config || options;
  if (typeof done !== 'function') {
    var callingDone = false;
    done = function (err, stats) {
      if (err) {
        // The err is here just to match the API but isnt used
        return;
      }
      stats = stats || {};
      if (options.quiet || callingDone) {
        return;
      }

      // Debounce output a little for when in watch mode
      if (options.watch) {
        callingDone = true;
        setTimeout(function () {
          callingDone = false;
        }, 500);
      }

      if (options.verbose) {
        gutil.log(stats.toString({
          colors: gutil.colors.supportsColor
        }));
      } else {
        var statsOptions = options && options.stats || {};

        Object.keys(defaultStatsOptions).forEach(function (key) {
          if (typeof statsOptions[key] === 'undefined') {
            statsOptions[key] = defaultStatsOptions[key];
          }
        });

        gutil.log(stats.toString(statsOptions));
      }
    };
  }

  var webpack = wp || require('webpack');
  var entry = [];
  var entries = Object.create(null);

  var stream = through(function (file) {
    if (file.isNull()) {
      return;
    }
    if ('named' in file) {
      if (!Array.isArray(entries[file.named])) {
        entries[file.named] = [];
      }
      entries[file.named].push(file.path);
    } else {
      entry = entry || [];
      entry.push(file.path);
    }
  }, function () {
    var self = this;
    var handleConfig = function (config) {
      config.output = config.output || {};
      config.watch = !!options.watch;

      // Determine pipe'd in entry
      if (Object.keys(entries).length > 0) {
        entry = entries;
        if (!config.output.filename) {
          // Better output default for multiple chunks
          config.output.filename = '[name].js';
        }
      } else if (entry.length < 2) {
        entry = entry[0] || entry;
      }

      config.entry = config.entry || entry;
      config.output.path = config.output.path || process.cwd();
      config.output.filename = config.output.filename || '[hash].js';
      entry = [];

      if (!config.entry || config.entry.length < 1) {
        gutil.log('webpack-stream - No files given; aborting compilation');
        self.emit('end');
        return false;
      }
      return true;
    };

    var succeeded;
    if (Array.isArray(config)) {
      for (var i = 0; i < config.length; i++) {
        succeeded = handleConfig(config[i]);
        if (!succeeded) {
          return false;
        }
      }
    } else {
      succeeded = handleConfig(config);
      if (!succeeded) {
        return false;
      }
    }

    var compiler = webpack(config, function (err, stats) {
      if (err) {
        self.emit('error', new gutil.PluginError('webpack-stream', err));
      }
      var jsonStats = stats.toJson() || {};
      var errors = jsonStats.errors || [];
      if (errors.length) {
        var errorMessage = errors.reduce(function (resultMessage, nextError) {
          resultMessage += nextError.toString();
          return resultMessage;
        }, '');
        self.emit('error', new gutil.PluginError('webpack-stream', errorMessage));
      }
      if (!options.watch) {
        self.queue(null);
      }
      done(err, stats);
      if (options.watch && !options.quiet) {
        gutil.log('webpack is watching for changes');
      }
    });

    // In watch mode webpack returns a wrapper object so we need to get
    // the underlying compiler
    if (options.watch) {
      compiler = compiler.compiler;
    }

    if (options.progress) {
      compiler.apply(new ProgressPlugin(function (percentage, msg) {
        percentage = Math.floor(percentage * 100);
        msg = percentage + '% ' + msg;
        if (percentage < 10) msg = ' ' + msg;
        gutil.log('webpack', msg);
      }));
    }

    var fs = compiler.outputFileSystem = new MemoryFileSystem();

    compiler.plugin('done', function (result) {
      var queueAssets = function (assets) {
        Object.keys(assets).forEach(function (outname) {
          if (assets[outname].emitted) {
            var file = prepareFile(fs, compiler, outname);
            self.queue(file);
          }
        });
      };

      if (compiler instanceof MultiCompiler) {
        result.stats.forEach(function (stats) {
          queueAssets(stats.compilation.assets);
        });
      } else {
        queueAssets(result.compilation.assets);
      }
    });
  });

  // If entry point manually specified, trigger that
  var hasEntry = Array.isArray(config)
    ? some(config, function (c) { return c.entry; })
    : config.entry;
  if (hasEntry) {
    stream.end();
  }

  return stream;
};

function prepareFile (fs, compiler, outname) {
  var path = fs.join(compiler.outputPath, outname);
  if (path.indexOf('?') !== -1) {
    path = path.split('?')[0];
  }
  var contents = fs.readFileSync(path);
  var file = new File({
    base: compiler.outputPath,
    path: path,
    contents: contents
  });
  return file;
}

// Expose webpack if asked
Object.defineProperty(module.exports, 'webpack', {
  get: function () {
    return require('webpack');
  }
});
<commit_msg>Handle compiler events properly<commit_after>'use strict';

var gutil = require('gulp-util');
var File = require('vinyl');
var MemoryFileSystem = require('memory-fs');
var through = require('through');
var ProgressPlugin = require('webpack/lib/ProgressPlugin');
var MultiCompiler = require('webpack/lib/MultiCompiler');
var clone = require('lodash.clone');
var some = require('lodash.some');

var defaultStatsOptions = {
  colors: gutil.colors.supportsColor,
  hash: false,
  timings: false,
  chunks: false,
  chunkModules: false,
  modules: false,
  children: true,
  version: true,
  cached: false,
  cachedAssets: false,
  reasons: false,
  source: false,
  errorDetails: false
};

module.exports = function (options, wp, done) {
  options = clone(options) || {};
  var config = options.config || options;
  if (typeof done !== 'function') {
    var callingDone = false;
    done = function (err, stats) {
      if (err) {
        // The err is here just to match the API but isnt used
        return;
      }
      stats = stats || {};
      if (options.quiet || callingDone) {
        return;
      }

      // Debounce output a little for when in watch mode
      if (options.watch) {
        callingDone = true;
        setTimeout(function () {
          callingDone = false;
        }, 500);
      }

      if (options.verbose) {
        gutil.log(stats.toString({
          colors: gutil.colors.supportsColor
        }));
      } else {
        var statsOptions = options && options.stats || {};

        Object.keys(defaultStatsOptions).forEach(function (key) {
          if (typeof statsOptions[key] === 'undefined') {
            statsOptions[key] = defaultStatsOptions[key];
          }
        });

        gutil.log(stats.toString(statsOptions));
      }
    };
  }

  var webpack = wp || require('webpack');
  var entry = [];
  var entries = Object.create(null);

  var stream = through(function (file) {
    if (file.isNull()) {
      return;
    }
    if ('named' in file) {
      if (!Array.isArray(entries[file.named])) {
        entries[file.named] = [];
      }
      entries[file.named].push(file.path);
    } else {
      entry = entry || [];
      entry.push(file.path);
    }
  }, function () {
    var self = this;
    var handleConfig = function (config) {
      config.output = config.output || {};
      config.watch = !!options.watch;

      // Determine pipe'd in entry
      if (Object.keys(entries).length > 0) {
        entry = entries;
        if (!config.output.filename) {
          // Better output default for multiple chunks
          config.output.filename = '[name].js';
        }
      } else if (entry.length < 2) {
        entry = entry[0] || entry;
      }

      config.entry = config.entry || entry;
      config.output.path = config.output.path || process.cwd();
      config.output.filename = config.output.filename || '[hash].js';
      entry = [];

      if (!config.entry || config.entry.length < 1) {
        gutil.log('webpack-stream - No files given; aborting compilation');
        self.emit('end');
        return false;
      }
      return true;
    };

    var succeeded;
    if (Array.isArray(config)) {
      for (var i = 0; i < config.length; i++) {
        succeeded = handleConfig(config[i]);
        if (!succeeded) {
          return false;
        }
      }
    } else {
      succeeded = handleConfig(config);
      if (!succeeded) {
        return false;
      }
    }

    var compiler = webpack(config, function (err, stats) {
      if (err) {
        self.emit('error', new gutil.PluginError('webpack-stream', err));
      }
      var jsonStats = stats.toJson() || {};
      var errors = jsonStats.errors || [];
      if (errors.length) {
        var errorMessage = errors.reduce(function (resultMessage, nextError) {
          resultMessage += nextError.toString();
          return resultMessage;
        }, '');
        self.emit('error', new gutil.PluginError('webpack-stream', errorMessage));
      }
      if (!options.watch) {
        self.queue(null);
      }
      done(err, stats);
      if (options.watch && !options.quiet) {
        gutil.log('webpack is watching for changes');
      }
    });

    // In watch mode webpack returns a wrapper object so we need to get
    // the underlying compiler
    if (options.watch) {
      compiler = compiler.compiler;
    }

    if (options.progress) {
      compiler.apply(new ProgressPlugin(function (percentage, msg) {
        percentage = Math.floor(percentage * 100);
        msg = percentage + '% ' + msg;
        if (percentage < 10) msg = ' ' + msg;
        gutil.log('webpack', msg);
      }));
    }

    var fs = compiler.outputFileSystem = new MemoryFileSystem();

    var handleCompilerEvent = function (compiler) {
      compiler.plugin('after-emit', function (compilation, callback) {
        Object.keys(compilation.assets).forEach(function (outname) {
          if (compilation.assets[outname].emitted) {
            var file = prepareFile(fs, compiler, outname);
            self.queue(file);
          }
        });
        callback();
      });
    };

    if (compiler instanceof MultiCompiler) {
      compiler.compilers.forEach(function (compiler) {
        handleCompilerEvent(compiler);
      });
    } else {
      handleCompilerEvent(compiler);
    }
  });

  // If entry point manually specified, trigger that
  var hasEntry = Array.isArray(config)
    ? some(config, function (c) { return c.entry; })
    : config.entry;
  if (hasEntry) {
    stream.end();
  }

  return stream;
};

function prepareFile (fs, compiler, outname) {
  var path = fs.join(compiler.outputPath, outname);
  if (path.indexOf('?') !== -1) {
    path = path.split('?')[0];
  }

  console.log(fs.existsSync(path));
  var contents = fs.readFileSync(path);

  var file = new File({
    base: compiler.outputPath,
    path: path,
    contents: contents
  });
  return file;
}

// Expose webpack if asked
Object.defineProperty(module.exports, 'webpack', {
  get: function () {
    return require('webpack');
  }
});
<|endoftext|>


<commit_before>/**
 * Created by Omry_Nachman on 2/2/15.
 */
"use strict";

exports.isLoaded = true;<commit_msg>Update index.js<commit_after>/**
 * Created by Omry_Nachman on 2/2/15.
 */
"use strict";
//
exports.isLoaded = true;
<|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) {
        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('/')[2];

    // 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('/api/*', function(request, response) {
    var eventContext = genEventContext(request, response);
    eventContext.context.httpMethod = 'GET';
    callLambda(eventContext);
  });

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

  var staticWebLocation = require('process').env.STATIC_WEB_DIR || './StaticWeb/dist';

  // Serve static content
  app.use('/', express.static(staticWebLocation));

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

serve();
<commit_msg>Formatting again<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('/')[2];

    // 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('/api/*', function(request, response) {
    var eventContext = genEventContext(request, response);
    eventContext.context.httpMethod = 'GET';
    callLambda(eventContext);
  });

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

  var staticWebLocation = require('process').env.STATIC_WEB_DIR || './StaticWeb/dist';

  // Serve static content
  app.use('/', express.static(staticWebLocation));

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

serve();
<|endoftext|>


<commit_before>'use strict'

// IMPORT
// =============================================================================
const Koa = require('koa')
const session = require('koa-session')
const router = require('koa-router')()
const app = new Koa()
require('koa-qs')(app)
const koaBody = require('koa-body')
const TrafficControl = require('./api/TrafficControl')
const render = require('koa-ejs')
const path = require('path')
const http = require('http')
const ws = require('ws')
const { URL } = require('url')
const logger = require('./api/logger')

const fs = require('fs')
const Permission = require('./api/permission')
const uid = require('uid-safe')
const npid = require('npid')

// Import config
const config = require('./config')

const Error = require('./api/errors')

// Import controllers
const Authentication = require('./api/controllers/auth')
const client = require('./api/controllers/client')
const decal = require('./api/controllers/decal')
const irc = require('./api/controllers/irc').HTTP
const leaderboard = require('./api/controllers/leaderboard')
const login = require('./api/controllers/login')
const ssologin = require('./api/controllers/ssologin')
const logout = require('./api/controllers/logout')
const news = require('./api/controllers/news')
const nicknames = require('./api/controllers/nicknames')
const oauth2 = require('./api/controllers/oauth2')
const profile = require('./api/controllers/profile')
const rat = require('./api/controllers/rat')
const register = require('./api/controllers/register')
const reset = require('./api/controllers/reset')
const rescue = require('./api/controllers/rescue')
const ship = require('./api/controllers/ship')
const statistics = require('./api/controllers/statistics')
const user = require('./api/controllers/user')
const version = require('./api/controllers/version')
const WebSocketManager = require('./api/websocket')
const jiraDrill = require('./api/controllers/jira/drill')
const { AnopeWebhook } = require('./api/controllers/anope-webhook')

try {
  npid.remove('api.pid')
  let pid = npid.create('api.pid')
  pid.removeOnExit()
} catch (err) {
  process.exit(1)
}

app.keys = [config.cookie.secret]

let sessionConfiguration = {
  key: 'fuelrats:session',
  overwrite: true,
  signed: true
}

app.use(session(sessionConfiguration, app))
app.use(require('koa-static')('static', {
  hidden: false,
  gzip: true
}))
app.use(koaBody())

let port = config.port || process.env.PORT

app.use(async function (ctx, next) {
  ctx.data = ctx.request.body
  ctx.meta = WebSocketManager.meta
  ctx.requireFields = WebSocketManager.requireFields
  ctx.client = {}

  let query = ctx.query
  ctx.query = parseQuery(query)

  ctx.inet = ctx.request.req.headers['x-forwarded-for'] || ctx.request.ip
  await next()
})

app.use(async function (ctx, next) {
  if (Array.isArray(ctx.data) || typeof ctx.data === 'object') {
    ['id', 'createdAt', 'updatedAt', 'deletedAt'].map((cleanField) => {
      delete ctx.data[cleanField]
    })
  }
  await next()
})

const traffic = new TrafficControl()

app.use(async (ctx, next) => {
  try {
    await Authentication.authenticate(ctx)

    let rateLimit = traffic.validateRateLimit(ctx)

    ctx.set('X-API-Version', '2.0')
    ctx.set('X-Rate-Limit-Limit', rateLimit.total)
    ctx.set('X-Rate-Limit-Remaining', rateLimit.remaining)
    ctx.set('X-Rate-Limit-Reset', traffic.nextResetDate)

    logger.info({ tags: ['request'] }, `Request by ${ctx.inet} to ${ctx.request.path}`, {
      'ip': ctx.inet,
      'path': ctx.request.path,
      'rate-limit-limit': rateLimit.total,
      'rate-limit-remaining': rateLimit.remaining,
      'query': ctx.query,
      'body': censor(ctx.data),
      'method': ctx.request.req.method
    })

    if (rateLimit.exceeded) {
      return next(Error.template('rate_limit_exceeded'))
    }

    let result = await next()
    if (result === true) {
      ctx.status = 204
    } else if (result) {
      ctx.body = result
    }
  } catch (ex) {
    let error = ex
    if (!error.code) {
      error = Error.template('server_error', error)
    }
    ctx.body = {
      errors: [error]
    }

    ctx.status = error.code
    if (error.code === 500) {
      logger.error(error)
      ctx.app.emit('error', ex, ctx)
    }
  }
})

render(app, {
  root: path.join(__dirname, 'views'),
  layout: false,
  viewExt: 'html',
  cache: false,
  debug: true
})

// ROUTES
// =============================================================================
router.get('/rescues', Authentication.isAuthenticated, Permission.required(['rescue.read']), rescue.search)
router.get('/rescues/:id', Authentication.isAuthenticated, Permission.required(['rescue.read']), rescue.findById)
router.post('/rescues', Authentication.isAuthenticated, Permission.required(['rescue.write']), rescue.create)
router.put('/rescues/:id', Authentication.isAuthenticated, rescue.update)
router.put('/rescues/assign/:id', Authentication.isAuthenticated, rescue.assign)
router.put('/rescues/addquote/:id', Authentication.isAuthenticated, rescue.assign)
router.put('/rescues/unassign/:id', Authentication.isAuthenticated, rescue.unassign)
router.delete('/rescues/:id', Authentication.isAuthenticated, Permission.required(['rescue.delete']), rescue.delete)

router.get('/clients', Authentication.isAuthenticated, Permission.required(['client.read']), client.search)
router.get('/clients/:id', Authentication.isAuthenticated, client.findById)
router.post('/clients', Authentication.isAuthenticated, client.create)
router.put('/clients/:id', Authentication.isAuthenticated, client.update)
router.delete('/clients/:id', Authentication.isAuthenticated, Permission.required(['client.delete']), client.delete)

router.get('/users', Authentication.isAuthenticated, Permission.required(['user.read']), user.search)
router.get('/users/:id', Authentication.isAuthenticated, user.findById)
router.get('/users/image/:id', user.image)
router.post('/users', Authentication.isAuthenticated, user.create)
router.put('/users/setpassword', Authentication.isAuthenticated, user.setpassword)
router.post('/users/image/:id', Authentication.isAuthenticated, user.setimage)
router.put('/users/:id/updatevirtualhost', Authentication.isAuthenticated,
  Permission.required(['user.write']), user.updatevirtualhost)
router.put('/users/:id', clean('image', 'password'), Authentication.isAuthenticated, user.update)
router.delete('/users/:id', Authentication.isAuthenticated, Permission.required(['user.delete']), user.delete)

router.get('/nicknames/info/:nickname', Authentication.isAuthenticated, nicknames.info)
router.get('/nicknames/:nickname', Authentication.isAuthenticated, nicknames.search)
router.post('/nicknames', Authentication.isAuthenticated, nicknames.register)
router.put('/nicknames', Authentication.isAuthenticated, nicknames.connect)
router.delete('/nicknames/:nickname', Authentication.isAuthenticated, nicknames.delete)

router.get('/rats', rat.search)
router.get('/rats/:id', rat.findById)
router.post('/rats', rat.create)
router.put('/rats/:id', rat.update)
router.delete('/rats/:id', Permission.required(['rat.delete']), rat.delete)

router.get('/ships', ship.search)
router.get('/ships/:id', ship.findById)
router.post('/ships', fields('name', 'shipType', 'ratId'), clean('shipId'), ship.create)
router.put('/ships/:id', clean('shipId'), ship.update)
router.delete('/ships/:id', rat.delete)

router.get('/welcome', (ctx) => {
  ctx.redirect('https://fuelrats.com/profile')
  ctx.status = 301
})

router.post('/login', fields('email', 'password'), login.login)
router.post('/register', fields('email', 'password', 'name', 'platform', 'nickname'),
  register.create)
router.get('/profile', Authentication.isAuthenticated, Permission.required(['user.read.me']), profile.read)

router.post('/anope', Authentication.isWhitelisted, AnopeWebhook.update)

router.get('/oauth2/authorize',
  Authentication.isAuthenticated,
  oauth2.authorizationValidateFields,
  oauth2.authorizationValidateRedirect,
  oauth2.authorizationRender
)

router.post('/oauth2/authorize', Authentication.isAuthenticated, ...oauth2.server.decision())

// Create endpoint handlers for oauth2 token
router.post('/oauth2/token',
  Authentication.isClientAuthenticated,
  oauth2.server.token(),
  oauth2.server.errorHandler())

router.post('/oauth2/revoke', Authentication.isClientAuthenticated, oauth2.revoke)
router.post('/oauth2/revokeall', Authentication.isClientAuthenticated, oauth2.revokeAll)

router.get('/statistics/rescues', statistics.rescues)
router.get('/statistics/systems', statistics.systems)
router.get('/statistics/rats', statistics.rats)

router.get('/version', version.read)
router.post('/reset', fields('email'), reset.requestReset)
router.get('/reset/:token', reset.validateReset)
router.post('/reset/:token', fields('password'), reset.resetPassword)

router.get('/decals/check', Authentication.isAuthenticated, decal.check)
router.get('/decals/redeem', Authentication.isAuthenticated, decal.redeem)
router.post('/jira/drill', Authentication.isAuthenticated, Permission.required(['user.update']), jiraDrill.update)

/*

router.get('/news', API.route(news.list))

router.get('/logout', logout.post)
router.post('/logout', logout.post)

router.post('/jira/drill', auth.isJiraAuthenticated(), Permission.required('user.update', false), jiraDrill.post)
router.post('/irc/message', auth.isAuthenticated(false), Permission.required('irc.oper', false), irc.message)
router.post('/irc/action', auth.isAuthenticated(false), Permission.required('irc.oper', false), irc.action)

 */

app.use(router.routes())
app.use(router.allowedMethods())

function parseQuery (query) {
  let queryObj = {}

  // Iterate over each individual query item
  for (let key of Object.keys(query)) {
    // Split them into period delimited arrays
    let keys = key.split('.')
    let target = queryObj

    // Iterate over the period delimited arrays to construct a nested hierarchy
    for (let keyPair of keys.entries()) {
      let subkey = keyPair[1]
      if (keyPair[0] === keys.length - 1) {
        // We have reached the end of the delimited array which means we can insert the value

        target[subkey] = query[key]
      } else if (!target[subkey]) {
        /* We have not reached the end of the delimited array so we need to create a nested object unless
        it already exists */
        target[subkey] = {}
        target = target[subkey]
      }
    }
  }
  return queryObj
}

let server = http.createServer(app.callback())
const wss = new ws.Server({ server })

const websocketManager = new WebSocketManager(wss, traffic)

wss.on('connection', async function connection (client) {
  let url = new URL(`http://localhost:8082${client.upgradeReq.url}`)
  client.clientId = uid.sync(16)
  client.subscriptions = []

  let bearer = url.searchParams.get('bearer')
  if (bearer) {
    let { user, scope } = await Authentication.bearerAuthenticate(bearer)
    if (user) {
      client.user = user
      client.scope = scope
    }
  }

  websocketManager.onConnection(client)

  client.on('message', (message) => {
    client.websocket = wss
    let request = JSON.parse(message)
    websocketManager.onMessage(client, request)
  })
})

server.listen(port, config.hostname, (error) => {
  if (error) {

  }
  logger.info(`HTTP Server listening on ${config.hostname} port ${port}`)
})

function censor (obj) {
  let censoredObj = {}
  Object.assign(censoredObj, obj)

  if (censoredObj.password) {
    censoredObj.password = '[CENSORED]'
  }
  if (censoredObj.secret) {
    censoredObj.secret = '[CENSORED]'
  }

  return censoredObj
}

function fields (...requiredFields) {
  return async function (ctx, next) {
    let missingFields = requiredFields.filter((requiredField) => {
      return ctx.data.hasOwnProperty(requiredField) === false
    })
    if (missingFields.length > 0) {
      throw Error.template('missing_required_fields', missingFields)
    }
    await next()
  }
}

function clean (...cleanFields) {
  return async function (ctx, next) {
    if (Array.isArray(ctx.data) || typeof ctx.data === 'object') {
      cleanFields.map((cleanField) => {
        ctx.data[cleanField] = undefined
      })
    }
    await next()
  }
}<commit_msg>Handle websocket json parse failures properly<commit_after>'use strict'

// IMPORT
// =============================================================================
const Koa = require('koa')
const session = require('koa-session')
const router = require('koa-router')()
const app = new Koa()
require('koa-qs')(app)
const koaBody = require('koa-body')
const TrafficControl = require('./api/TrafficControl')
const render = require('koa-ejs')
const path = require('path')
const http = require('http')
const ws = require('ws')
const { URL } = require('url')
const logger = require('./api/logger')

const fs = require('fs')
const Permission = require('./api/permission')
const uid = require('uid-safe')
const npid = require('npid')

// Import config
const config = require('./config')

const Error = require('./api/errors')

// Import controllers
const Authentication = require('./api/controllers/auth')
const client = require('./api/controllers/client')
const decal = require('./api/controllers/decal')
const irc = require('./api/controllers/irc').HTTP
const leaderboard = require('./api/controllers/leaderboard')
const login = require('./api/controllers/login')
const ssologin = require('./api/controllers/ssologin')
const logout = require('./api/controllers/logout')
const news = require('./api/controllers/news')
const nicknames = require('./api/controllers/nicknames')
const oauth2 = require('./api/controllers/oauth2')
const profile = require('./api/controllers/profile')
const rat = require('./api/controllers/rat')
const register = require('./api/controllers/register')
const reset = require('./api/controllers/reset')
const rescue = require('./api/controllers/rescue')
const ship = require('./api/controllers/ship')
const statistics = require('./api/controllers/statistics')
const user = require('./api/controllers/user')
const version = require('./api/controllers/version')
const WebSocketManager = require('./api/websocket')
const jiraDrill = require('./api/controllers/jira/drill')
const { AnopeWebhook } = require('./api/controllers/anope-webhook')

try {
  npid.remove('api.pid')
  let pid = npid.create('api.pid')
  pid.removeOnExit()
} catch (err) {
  process.exit(1)
}

app.keys = [config.cookie.secret]

let sessionConfiguration = {
  key: 'fuelrats:session',
  overwrite: true,
  signed: true
}

app.use(session(sessionConfiguration, app))
app.use(require('koa-static')('static', {
  hidden: false,
  gzip: true
}))
app.use(koaBody())

let port = config.port || process.env.PORT

app.use(async function (ctx, next) {
  ctx.data = ctx.request.body
  ctx.meta = WebSocketManager.meta
  ctx.requireFields = WebSocketManager.requireFields
  ctx.client = {}

  let query = ctx.query
  ctx.query = parseQuery(query)

  ctx.inet = ctx.request.req.headers['x-forwarded-for'] || ctx.request.ip
  await next()
})

app.use(async function (ctx, next) {
  if (Array.isArray(ctx.data) || typeof ctx.data === 'object') {
    ['id', 'createdAt', 'updatedAt', 'deletedAt'].map((cleanField) => {
      delete ctx.data[cleanField]
    })
  }
  await next()
})

const traffic = new TrafficControl()

app.use(async (ctx, next) => {
  try {
    await Authentication.authenticate(ctx)

    let rateLimit = traffic.validateRateLimit(ctx)

    ctx.set('X-API-Version', '2.0')
    ctx.set('X-Rate-Limit-Limit', rateLimit.total)
    ctx.set('X-Rate-Limit-Remaining', rateLimit.remaining)
    ctx.set('X-Rate-Limit-Reset', traffic.nextResetDate)

    logger.info({ tags: ['request'] }, `Request by ${ctx.inet} to ${ctx.request.path}`, {
      'ip': ctx.inet,
      'path': ctx.request.path,
      'rate-limit-limit': rateLimit.total,
      'rate-limit-remaining': rateLimit.remaining,
      'query': ctx.query,
      'body': censor(ctx.data),
      'method': ctx.request.req.method
    })

    if (rateLimit.exceeded) {
      return next(Error.template('rate_limit_exceeded'))
    }

    let result = await next()
    if (result === true) {
      ctx.status = 204
    } else if (result) {
      ctx.body = result
    }
  } catch (ex) {
    let error = ex
    if (!error.code) {
      error = Error.template('server_error', error)
    }
    ctx.body = {
      errors: [error]
    }

    ctx.status = error.code
    if (error.code === 500) {
      logger.error(error)
      ctx.app.emit('error', ex, ctx)
    }
  }
})

render(app, {
  root: path.join(__dirname, 'views'),
  layout: false,
  viewExt: 'html',
  cache: false,
  debug: true
})

// ROUTES
// =============================================================================
router.get('/rescues', Authentication.isAuthenticated, Permission.required(['rescue.read']), rescue.search)
router.get('/rescues/:id', Authentication.isAuthenticated, Permission.required(['rescue.read']), rescue.findById)
router.post('/rescues', Authentication.isAuthenticated, Permission.required(['rescue.write']), rescue.create)
router.put('/rescues/:id', Authentication.isAuthenticated, rescue.update)
router.put('/rescues/assign/:id', Authentication.isAuthenticated, rescue.assign)
router.put('/rescues/addquote/:id', Authentication.isAuthenticated, rescue.assign)
router.put('/rescues/unassign/:id', Authentication.isAuthenticated, rescue.unassign)
router.delete('/rescues/:id', Authentication.isAuthenticated, Permission.required(['rescue.delete']), rescue.delete)

router.get('/clients', Authentication.isAuthenticated, Permission.required(['client.read']), client.search)
router.get('/clients/:id', Authentication.isAuthenticated, client.findById)
router.post('/clients', Authentication.isAuthenticated, client.create)
router.put('/clients/:id', Authentication.isAuthenticated, client.update)
router.delete('/clients/:id', Authentication.isAuthenticated, Permission.required(['client.delete']), client.delete)

router.get('/users', Authentication.isAuthenticated, Permission.required(['user.read']), user.search)
router.get('/users/:id', Authentication.isAuthenticated, user.findById)
router.get('/users/image/:id', user.image)
router.post('/users', Authentication.isAuthenticated, user.create)
router.put('/users/setpassword', Authentication.isAuthenticated, user.setpassword)
router.post('/users/image/:id', Authentication.isAuthenticated, user.setimage)
router.put('/users/:id/updatevirtualhost', Authentication.isAuthenticated,
  Permission.required(['user.write']), user.updatevirtualhost)
router.put('/users/:id', clean('image', 'password'), Authentication.isAuthenticated, user.update)
router.delete('/users/:id', Authentication.isAuthenticated, Permission.required(['user.delete']), user.delete)

router.get('/nicknames/info/:nickname', Authentication.isAuthenticated, nicknames.info)
router.get('/nicknames/:nickname', Authentication.isAuthenticated, nicknames.search)
router.post('/nicknames', Authentication.isAuthenticated, nicknames.register)
router.put('/nicknames', Authentication.isAuthenticated, nicknames.connect)
router.delete('/nicknames/:nickname', Authentication.isAuthenticated, nicknames.delete)

router.get('/rats', rat.search)
router.get('/rats/:id', rat.findById)
router.post('/rats', rat.create)
router.put('/rats/:id', rat.update)
router.delete('/rats/:id', Permission.required(['rat.delete']), rat.delete)

router.get('/ships', ship.search)
router.get('/ships/:id', ship.findById)
router.post('/ships', fields('name', 'shipType', 'ratId'), clean('shipId'), ship.create)
router.put('/ships/:id', clean('shipId'), ship.update)
router.delete('/ships/:id', rat.delete)

router.get('/welcome', (ctx) => {
  ctx.redirect('https://fuelrats.com/profile')
  ctx.status = 301
})

router.post('/login', fields('email', 'password'), login.login)
router.post('/register', fields('email', 'password', 'name', 'platform', 'nickname'),
  register.create)
router.get('/profile', Authentication.isAuthenticated, Permission.required(['user.read.me']), profile.read)

router.post('/anope', Authentication.isWhitelisted, AnopeWebhook.update)

router.get('/oauth2/authorize',
  Authentication.isAuthenticated,
  oauth2.authorizationValidateFields,
  oauth2.authorizationValidateRedirect,
  oauth2.authorizationRender
)

router.post('/oauth2/authorize', Authentication.isAuthenticated, ...oauth2.server.decision())

// Create endpoint handlers for oauth2 token
router.post('/oauth2/token',
  Authentication.isClientAuthenticated,
  oauth2.server.token(),
  oauth2.server.errorHandler())

router.post('/oauth2/revoke', Authentication.isClientAuthenticated, oauth2.revoke)
router.post('/oauth2/revokeall', Authentication.isClientAuthenticated, oauth2.revokeAll)

router.get('/statistics/rescues', statistics.rescues)
router.get('/statistics/systems', statistics.systems)
router.get('/statistics/rats', statistics.rats)

router.get('/version', version.read)
router.post('/reset', fields('email'), reset.requestReset)
router.get('/reset/:token', reset.validateReset)
router.post('/reset/:token', fields('password'), reset.resetPassword)

router.get('/decals/check', Authentication.isAuthenticated, decal.check)
router.get('/decals/redeem', Authentication.isAuthenticated, decal.redeem)
router.post('/jira/drill', Authentication.isAuthenticated, Permission.required(['user.update']), jiraDrill.update)

/*

router.get('/news', API.route(news.list))

router.get('/logout', logout.post)
router.post('/logout', logout.post)

router.post('/jira/drill', auth.isJiraAuthenticated(), Permission.required('user.update', false), jiraDrill.post)
router.post('/irc/message', auth.isAuthenticated(false), Permission.required('irc.oper', false), irc.message)
router.post('/irc/action', auth.isAuthenticated(false), Permission.required('irc.oper', false), irc.action)

 */

app.use(router.routes())
app.use(router.allowedMethods())

function parseQuery (query) {
  let queryObj = {}

  // Iterate over each individual query item
  for (let key of Object.keys(query)) {
    // Split them into period delimited arrays
    let keys = key.split('.')
    let target = queryObj

    // Iterate over the period delimited arrays to construct a nested hierarchy
    for (let keyPair of keys.entries()) {
      let subkey = keyPair[1]
      if (keyPair[0] === keys.length - 1) {
        // We have reached the end of the delimited array which means we can insert the value

        target[subkey] = query[key]
      } else if (!target[subkey]) {
        /* We have not reached the end of the delimited array so we need to create a nested object unless
        it already exists */
        target[subkey] = {}
        target = target[subkey]
      }
    }
  }
  return queryObj
}

let server = http.createServer(app.callback())
const wss = new ws.Server({ server })

const websocketManager = new WebSocketManager(wss, traffic)

wss.on('connection', async function connection (client) {
  let url = new URL(`http://localhost:8082${client.upgradeReq.url}`)
  client.clientId = uid.sync(16)
  client.subscriptions = []

  let bearer = url.searchParams.get('bearer')
  if (bearer) {
    let { user, scope } = await Authentication.bearerAuthenticate(bearer)
    if (user) {
      client.user = user
      client.scope = scope
    }
  }

  websocketManager.onConnection(client)

  client.on('message', (message) => {
    client.websocket = wss
    try {
      let request = JSON.parse(message)
      websocketManager.onMessage(client, request)
    } catch (ex) {
      logger.info('Failed to parse incoming websocket message')
    }
  })
})

server.listen(port, config.hostname, (error) => {
  if (error) {

  }
  logger.info(`HTTP Server listening on ${config.hostname} port ${port}`)
})

function censor (obj) {
  let censoredObj = {}
  Object.assign(censoredObj, obj)

  if (censoredObj.password) {
    censoredObj.password = '[CENSORED]'
  }
  if (censoredObj.secret) {
    censoredObj.secret = '[CENSORED]'
  }

  return censoredObj
}

function fields (...requiredFields) {
  return async function (ctx, next) {
    let missingFields = requiredFields.filter((requiredField) => {
      return ctx.data.hasOwnProperty(requiredField) === false
    })
    if (missingFields.length > 0) {
      throw Error.template('missing_required_fields', missingFields)
    }
    await next()
  }
}

function clean (...cleanFields) {
  return async function (ctx, next) {
    if (Array.isArray(ctx.data) || typeof ctx.data === 'object') {
      cleanFields.map((cleanField) => {
        ctx.data[cleanField] = undefined
      })
    }
    await next()
  }
}<|endoftext|>


<commit_before>'use strict';

/**
 * Export all data from an IndexedDB database
 * @param {IDBDatabase} idbDatabase - to export from
 * @param {function(Object?, string?)} cb - callback with signature (error, jsonString)
 */
function exportToJsonString(idbDatabase, cb) {
  const exportObject = {};
  const objectStoreNamesSet = new Set(idbDatabase.objectStoreNames);
  const size = objectStoreNamesSet.size;
  if (size === 0) {
    cb(null, JSON.stringify(exportObject));
  } else {
    const objectStoreNames = Array.from(objectStoreNamesSet);
    const transaction = idbDatabase.transaction(
        objectStoreNames,
        'readonly'
    );
    transaction.onerror = (event) => cb(event, null);

    objectStoreNames.forEach((storeName) => {
      const allObjects = [];
      transaction.objectStore(storeName).openCursor().onsuccess = (event) => {
        const cursor = event.target.result;
        if (cursor) {
          allObjects.push(cursor.value);
          cursor.continue();
        } else {
          exportObject[storeName] = allObjects;
          if (
            objectStoreNames.length ===
            Object.keys(exportObject).length
          ) {
            cb(null, JSON.stringify(exportObject));
          }
        }
      };
    });
  }
}

/**
 * Import data from JSON into an IndexedDB database. This does not delete any existing data
 *  from the database, so keys could clash.
 *
 * Only object stores that already exist will be imported.
 *
 * @param {IDBDatabase} idbDatabase - to import into
 * @param {string} jsonString - data to import, one key per object store
 * @param {function(Object)} cb - callback with signature (error), where error is null on success
 * @return {void}
 */
function importFromJsonString(idbDatabase, jsonString, cb) {
  const objectStoreNamesSet = new Set(idbDatabase.objectStoreNames);
  const size = objectStoreNamesSet.size;
  if (size === 0) {
    cb(null);
  } else {
    const objectStoreNames = Array.from(objectStoreNamesSet);
    const transaction = idbDatabase.transaction(
        objectStoreNames,
        'readwrite'
    );
    transaction.onerror = (event) => cb(event);

    const importObject = JSON.parse(jsonString);
    objectStoreNames.forEach((storeName) => {
      let count = 0;
      const aux = Array.from(importObject[storeName]);
      if (importObject[storeName] && aux.length > 0) {
        aux.forEach((toAdd) => {
          const request = transaction.objectStore(storeName).add(toAdd);
          request.onsuccess = () => {
            count++;
            if (count === importObject[storeName].length) {
              // added all objects for this store
              delete importObject[storeName];
              if (Object.keys(importObject).length === 0) {
                // added all object stores
                cb(null);
              }
            }
          };
          request.onerror = (event) => {
            console.log(event);
          };
        });
      } else {
        delete importObject[storeName];
        if (Object.keys(importObject).length === 0) {
          // added all object stores
          cb(null);
        }
      }
    });
  }
}

/**
 * Clears a database of all data.
 *
 * The object stores will still exist but will be empty.
 *
 * @param {IDBDatabase} idbDatabase - to delete all data from
 * @param {function(Object)} cb - callback with signature (error), where error is null on success
 * @return {void}
 */
function clearDatabase(idbDatabase, cb) {
  const objectStoreNamesSet = new Set(idbDatabase.objectStoreNames);
  const size = objectStoreNamesSet.size;
  if (size === 0) {
    cb(null);
  } else {
    const objectStoreNames = Array.from(objectStoreNamesSet);
    const transaction = idbDatabase.transaction(
        objectStoreNames,
        'readwrite'
    );
    transaction.onerror = (event) => cb(event);

    let count = 0;
    objectStoreNames.forEach(function(storeName) {
      transaction.objectStore(storeName).clear().onsuccess = () => {
        count++;
        if (count === size) {
          // cleared all object stores
          cb(null);
        }
      };
    });
  }
}

if (typeof module !== 'undefined' && module.exports) {
  // We are running on Node.js so need to export the module
  module.exports = {
    exportToJsonString: exportToJsonString,
    importFromJsonString: importFromJsonString,
    clearDatabase: clearDatabase,
  };
}
<commit_msg>fixed a bug where callback is never called<commit_after>'use strict';

/**
 * Export all data from an IndexedDB database
 * @param {IDBDatabase} idbDatabase - to export from
 * @param {function(Object?, string?)} cb - callback with signature (error, jsonString)
 */
function exportToJsonString(idbDatabase, cb) {
  const exportObject = {};
  const objectStoreNamesSet = new Set(idbDatabase.objectStoreNames);
  const size = objectStoreNamesSet.size;
  if (size === 0) {
    cb(null, JSON.stringify(exportObject));
  } else {
    const objectStoreNames = Array.from(objectStoreNamesSet);
    const transaction = idbDatabase.transaction(
        objectStoreNames,
        'readonly'
    );
    transaction.onerror = (event) => cb(event, null);

    objectStoreNames.forEach((storeName) => {
      const allObjects = [];
      transaction.objectStore(storeName).openCursor().onsuccess = (event) => {
        const cursor = event.target.result;
        if (cursor) {
          allObjects.push(cursor.value);
          cursor.continue();
        } else {
          exportObject[storeName] = allObjects;
          if (
            objectStoreNames.length ===
            Object.keys(exportObject).length
          ) {
            cb(null, JSON.stringify(exportObject));
          }
        }
      };
    });
  }
}

/**
 * Import data from JSON into an IndexedDB database. This does not delete any existing data
 *  from the database, so keys could clash.
 *
 * Only object stores that already exist will be imported.
 *
 * @param {IDBDatabase} idbDatabase - to import into
 * @param {string} jsonString - data to import, one key per object store
 * @param {function(Object)} cb - callback with signature (error), where error is null on success
 * @return {void}
 */
function importFromJsonString(idbDatabase, jsonString, cb) {
  const objectStoreNamesSet = new Set(idbDatabase.objectStoreNames);
  const size = objectStoreNamesSet.size;
  if (size === 0) {
    cb(null);
  } else {
    const objectStoreNames = Array.from(objectStoreNamesSet);
    const transaction = idbDatabase.transaction(
        objectStoreNames,
        'readwrite'
    );
    transaction.onerror = (event) => cb(event);

    const importObject = JSON.parse(jsonString);

    //deleting keys present in json that are not present in database, causing callback to never be called.
    Object.keys(importObject).forEach(item=> {
      if(!objectStoreNames.includes(item)){
        console.log('deleted '+item)
        delete importObject[item]
      }
    })

    objectStoreNames.forEach((storeName) => {
      let count = 0;
      const aux = Array.from(importObject[storeName]);
      if (importObject[storeName] && aux.length > 0) {
        aux.forEach((toAdd) => {
          const request = transaction.objectStore(storeName).add(toAdd);
          request.onsuccess = () => {
            count++;
            if (count === importObject[storeName].length) {
              // added all objects for this store
              delete importObject[storeName];
              if (Object.keys(importObject).length === 0) {
                // added all object stores
                cb(null);
              }
            }
          };
          request.onerror = (event) => {
            console.log(event);
          };
        });
      } else {
        delete importObject[storeName];
        if (Object.keys(importObject).length === 0) {
          // added all object stores
          cb(null);
        }
      }
    });
  }
}

/**
 * Clears a database of all data.
 *
 * The object stores will still exist but will be empty.
 *
 * @param {IDBDatabase} idbDatabase - to delete all data from
 * @param {function(Object)} cb - callback with signature (error), where error is null on success
 * @return {void}
 */
function clearDatabase(idbDatabase, cb) {
  const objectStoreNamesSet = new Set(idbDatabase.objectStoreNames);
  const size = objectStoreNamesSet.size;
  if (size === 0) {
    cb(null);
  } else {
    const objectStoreNames = Array.from(objectStoreNamesSet);
    const transaction = idbDatabase.transaction(
        objectStoreNames,
        'readwrite'
    );
    transaction.onerror = (event) => cb(event);

    let count = 0;
    objectStoreNames.forEach(function(storeName) {
      transaction.objectStore(storeName).clear().onsuccess = () => {
        count++;
        if (count === size) {
          // cleared all object stores
          cb(null);
        }
      };
    });
  }
}

if (typeof module !== 'undefined' && module.exports) {
  // We are running on Node.js so need to export the module
  module.exports = {
    exportToJsonString: exportToJsonString,
    importFromJsonString: importFromJsonString,
    clearDatabase: clearDatabase,
  };
}
<|endoftext|>


<commit_before>'use strict';

var http = require('http');

http.createServer(function(req, res) {
  res.writeHead(200);
  res.end('Hello!');
}).listen(8080);<commit_msg>Update index.js<commit_after>'use strict';

var http = require('http');

http.createServer(function(req, res) {
  res.writeHead(200);
  res.end('Hello!');
}).listen(8080);

process.on('message', function(msg) {
  if (msg === 'shutdown') {
    close_all_connections();
    delete_cache();
    server.close();
    process.exit(0);
  }
});<|endoftext|>


<commit_before>/* eslint no-console: 0 */
'use strict';

const express = require('express');
const bodyParser = require('body-parser');

const app = module.exports.app = express();
const jira = require('./lib/jira');

app.set('x-powered-by', false);
app.set('trust proxy', 1);

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

app.get('/favicon.ico', (req, res) => {
  res.set('Content-Type', 'image/x-icon');
  res.end();
});

// slack token check
app.use('/api/v1', (req, res, next) => {
  const slackTokens = new Set(process.env.SLACK_TOKENS.split(','));

  if (!slackTokens.has(req.body.token)) {
    res.status(403).end('Invalid Slack Token');
  } else {
    next();
  }
});

// slack user check
app.use('/api/v1', (req, res, next) => {
  if (!jira.USERS.has(req.body.user_name)) {
    res.status(403).end('Forbidden Slack User');
  } else {
    next();
  }
});

app.param('type', (req, res, next, type) => {
  if (!jira.TYPES.has(type)) {
    res.status(400).end('Invalid Task Type');
  } else {
    req.params.type = jira.TYPES.get(type);
    next();
  }
});

app.post('/api/v1/create/:type', (req, res) => {
  const type = req.params.type;

  let project = process.env.JIRA_DEFAULT_PROJECT;
  let summary = req.body.text;
  const reporter = jira.USERS.get(req.body.user_name);

  if (/^[A-Z]+ /.test(summary)) {
    summary = summary.split(' ');
    project = summary.splice(0, 1).join('');
    summary = summary.join(' ');
  }

  jira.create(type, project, summary, reporter, (err, issue) => {
    if (err) {
      if (process.env.NODE_ENV !== 'testing') { console.error(err); }
      res.status(400).end('Issue creation failed!');
    } else {
      res.end(`${type} ${issue.key} created successfully!`);
    }
  });
});

app.post('/api/v1/assign', (req, res) => {
  const argv = req.body.text.split(' ');
  const issue = argv[0];
  const userName = (argv[1] || '').replace('@', '') || req.body.user_name;

  if (!issue || !userName) {
    return res.status(400).end('Usage: /assign [ISSUE] @[USER]');
  }

  if (!jira.USERS.has(userName)) {
    return res.status(400).end(`User "@${userName}" was not found!`);
  }

  return jira.assign(issue, jira.USERS.get(userName), (err) => {
    if (err) {
      if (process.env.NODE_ENV !== 'testing') { console.error(err); }
      res.status(400).end('Issue assigning failed!');
    } else {
      res.end(`${issue} assigned to @${userName}!`);
    }
  });
});

app.param('status', (req, res, next, status) => {
  if (!jira.TRANSITIONS.has(status)) {
    return res.status(400).end(`Invalid status ${status}`);
  }

  return next();
});

app.post('/api/v1/issue/:status', (req, res) => {
  const status = req.params.status;
  const user = jira.USERS.get(req.body.user_name);

  const argv = req.body.text.split(' ');
  const key = argv.splice(0, 1)[0];
  const comment = argv.join(' ');

  jira.issue(key, (issueErr, issue) => {
    if (issueErr) { throw issueErr; }

    if (!issue || issue.errors) {
      return res.status(404).end(`Issue ${key} was not found!`);
    }

    // issue is not in the sprint
    if (!issue.fields.sprint) {
      console.log('issue not in a sprint');

      // jira.sprint((err, sprint) => {
      //   if (err) { throw err; }

      //   console.log(sprint);
      // });
    }

    return jira.transition(key, status, user, comment, (transitionErr) => {
      if (transitionErr) { throw transitionErr; }

      res.end(`Status for ${key} updated successfully`);
    });
  });
});

// eslint-disable-next-line
app.use((err, req, res, next) => {
  throw err;
});

if (!module.parent) {
  app.listen(8080);
  console.log('Server is ready for connections on port 8080');
}
<commit_msg>feat(api): return and end session when something breaks<commit_after>/* eslint no-console: 0 */
'use strict';

const express = require('express');
const bodyParser = require('body-parser');

const app = module.exports.app = express();
const jira = require('./lib/jira');

app.set('x-powered-by', false);
app.set('trust proxy', 1);

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

app.get('/favicon.ico', (req, res) => {
  res.set('Content-Type', 'image/x-icon');
  res.end();
});

// slack token check
app.use('/api/v1', (req, res, next) => {
  const slackTokens = new Set(process.env.SLACK_TOKENS.split(','));

  if (!slackTokens.has(req.body.token)) {
    res.status(403).end('Invalid Slack Token');
  } else {
    next();
  }
});

// slack user check
app.use('/api/v1', (req, res, next) => {
  if (!jira.USERS.has(req.body.user_name)) {
    res.status(403).end('Forbidden Slack User');
  } else {
    next();
  }
});

app.param('type', (req, res, next, type) => {
  if (!jira.TYPES.has(type)) {
    res.status(400).end('Invalid Task Type');
  } else {
    req.params.type = jira.TYPES.get(type);
    next();
  }
});

app.post('/api/v1/create/:type', (req, res) => {
  const type = req.params.type;

  let project = process.env.JIRA_DEFAULT_PROJECT;
  let summary = req.body.text;
  const reporter = jira.USERS.get(req.body.user_name);

  if (/^[A-Z]+ /.test(summary)) {
    summary = summary.split(' ');
    project = summary.splice(0, 1).join('');
    summary = summary.join(' ');
  }

  jira.create(type, project, summary, reporter, (err, issue) => {
    if (err) {
      if (process.env.NODE_ENV !== 'testing') { console.error(err); }
      res.status(400).end('Issue creation failed!');
    } else {
      res.end(`${type} ${issue.key} created successfully!`);
    }
  });
});

app.post('/api/v1/assign', (req, res) => {
  const argv = req.body.text.split(' ');
  const issue = argv[0];
  const userName = (argv[1] || '').replace('@', '') || req.body.user_name;

  if (!issue || !userName) {
    return res.status(400).end('Usage: /assign [ISSUE] @[USER]');
  }

  if (!jira.USERS.has(userName)) {
    return res.status(400).end(`User "@${userName}" was not found!`);
  }

  return jira.assign(issue, jira.USERS.get(userName), (err) => {
    if (err) {
      if (process.env.NODE_ENV !== 'testing') { console.error(err); }
      res.status(400).end('Issue assigning failed!');
    } else {
      res.end(`${issue} assigned to @${userName}!`);
    }
  });
});

app.param('status', (req, res, next, status) => {
  if (!jira.TRANSITIONS.has(status)) {
    return res.status(400).end(`Invalid status ${status}`);
  }

  return next();
});

app.post('/api/v1/issue/:status', (req, res) => {
  const status = req.params.status;
  const user = jira.USERS.get(req.body.user_name);

  const argv = req.body.text.split(' ');
  const key = argv.splice(0, 1)[0];
  const comment = argv.join(' ');

  jira.issue(key, (issueErr, issue) => {
    if (issueErr) { throw issueErr; }

    if (!issue || issue.errors) {
      return res.status(404).end(`Issue ${key} was not found!`);
    }

    // issue is not in the sprint
    if (!issue.fields.sprint) {
      console.log('issue not in a sprint');

      // jira.sprint((err, sprint) => {
      //   if (err) { throw err; }

      //   console.log(sprint);
      // });
    }

    return jira.transition(key, status, user, comment, (transitionErr) => {
      if (transitionErr) { throw transitionErr; }

      res.end(`Status for ${key} updated successfully`);
    });
  });
});

// eslint-disable-next-line
app.use((err, req, res, next) => {
  res.end('ε(´סּ︵סּ`)з');

  throw err;
});

if (!module.parent) {
  app.listen(8080);
  console.log('Server is ready for connections on port 8080');
}
<|endoftext|>