<commit_before>var assert       = require('assert'),
    assign       = require('object-assign'),
    onerr        = require('on-error'),
    eventuate    = require('eventuate'),
    once         = require('once'),
    Promise      = require('promise-polyfill'),
    setImmediate = require('set-immediate-shim'),
    errors       = require('./lib/errors')

module.exports = function () {
    var pending     = [],
        processing  = [],
        maxSize     = Infinity,
        concurrency = Infinity,
        drained     = true,
        processor

    function cq (task, cb) {
        cb = typeof cb === 'function' ? cb : function () {}
        if (pending.length >= maxSize) {
            var err = new errors.MaxSizeExceededError('unable to queue item')
            cb(err)
            cq.rejected.produce({ item: task, err: err })
            return Promise.reject(err)
        }
        drained = false
        setImmediate(drain)
        return new Promise(function (resolve, reject) {
            pending.push({
                task: task,
                resolve: function (value) {
                    cb.apply(undefined, [null].concat(Array.prototype.slice.call(arguments, 0)))
                    resolve.apply(undefined, arguments)
                    cq.processingEnded.produce({ item: task })
                },
                reject: function (err) {
                    cb(err)
                    reject(err)
                    cq.processingEnded.produce({ err: err, item: task })
                }
            })
            cq.enqueued.produce({ item: task })
        })
    }
    Object.defineProperties(cq, {
        size: { enumerable: true, get: function () {
            return pending.length
        }},
        isDrained: { enumerable: true, get: function () {
            return drained
        }},
        pending: { enumerable: true, get: function () {
            return pending.map(function (item) {
                return item.task
            })
        }},
        processing: { enumerable: true, get: function () {
            return processing.map(function (item) {
                return item.task
            })
        }},
        concurrency: { enumerable: true, get: function () {
            return concurrency
        }, set: function (value) {
            if (typeof value !== 'number') throw new TypeError('concurrency must be a number')
            concurrency = value
        }},
        maxSize: { enumerable: true, get: function () {
            return maxSize
        }, set: function (value) {
            if (typeof value !== 'number') throw new TypeError('maxSize must be a number')
            maxSize = value
        }},
        processor: { get: function () {
            return processor
        }},
        limit: { value: function (limits) {
            limits = assign({ concurrency: Infinity, maxSize: Infinity }, limits)
            assert(typeof limits.maxSize === 'number', 'maxSize must be a number')
            assert(typeof limits.concurrency === 'number', 'concurrency must be a number')
            maxSize = limits.maxSize
            concurrency = limits.concurrency
            return cq
        }},
        process: { value: function (func) {
            assert(typeof func === 'function', 'process requires a processor function')
            assert(!processor, 'queue processor already defined')
            processor = func
            setImmediate(drain)
            return cq
        }},
        enqueued: { value: eventuate() },
        rejected: { value: eventuate() },
        processingStarted: { value: eventuate() },
        processingEnded: { value: eventuate() },
        drained: { value: eventuate() }
    })

    function drain () {
        if (!drained && pending.length === 0 && processing.length === 0) {
            drained = true
            cq.drained.produce()
        }
        while (processor && pending.length > 0 && processing.length < concurrency) drainItem()
        function drainItem () {
            var item = pending.shift()
            processing.push(item)
            cq.processingStarted.produce({ item: item.task })

            var reject = once(function reject (err) {
                processing.splice(processing.indexOf(item), 1)
                item.reject(err)
                setImmediate(drain)
            })
            var resolve = once(function resolve () {
                processing.splice(processing.indexOf(item), 1)
                item.resolve.apply(undefined, arguments)
                setImmediate(drain)
            })

            var p
            try {
                p = processor(item.task, onerr(reject).otherwise(resolve))
            }
            catch (err) {
                return reject(err)
            }
            if (p && typeof p.then === 'function') p.then(resolve, reject)
        }
    }

    return cq
}

assign(module.exports, errors)
<commit_msg>more consistent terminology<commit_after>var assert       = require('assert'),
    assign       = require('object-assign'),
    onerr        = require('on-error'),
    eventuate    = require('eventuate'),
    once         = require('once'),
    Promise      = require('promise-polyfill'),
    setImmediate = require('set-immediate-shim'),
    errors       = require('./lib/errors')

module.exports = function () {
    var pending     = [],
        processing  = [],
        maxSize     = Infinity,
        concurrency = Infinity,
        drained     = true,
        processor

    function cq (item, cb) {
        cb = typeof cb === 'function' ? cb : function () {}
        if (pending.length >= maxSize) {
            var err = new errors.MaxSizeExceededError('unable to queue item')
            cb(err)
            cq.rejected.produce({ item: item, err: err })
            return Promise.reject(err)
        }
        drained = false
        setImmediate(drain)
        return new Promise(function (resolve, reject) {
            pending.push({
                item: item,
                resolve: function (value) {
                    cb.apply(undefined, [null].concat(Array.prototype.slice.call(arguments, 0)))
                    resolve.apply(undefined, arguments)
                    cq.processingEnded.produce({ item: item })
                },
                reject: function (err) {
                    cb(err)
                    reject(err)
                    cq.processingEnded.produce({ err: err, item: item })
                }
            })
            cq.enqueued.produce({ item: item })
        })
    }
    Object.defineProperties(cq, {
        size: { enumerable: true, get: function () {
            return pending.length
        }},
        isDrained: { enumerable: true, get: function () {
            return drained
        }},
        pending: { enumerable: true, get: function () {
            return pending.map(function (task) {
                return task.item
            })
        }},
        processing: { enumerable: true, get: function () {
            return processing.map(function (task) {
                return task.item
            })
        }},
        concurrency: { enumerable: true, get: function () {
            return concurrency
        }, set: function (value) {
            if (typeof value !== 'number') throw new TypeError('concurrency must be a number')
            concurrency = value
        }},
        maxSize: { enumerable: true, get: function () {
            return maxSize
        }, set: function (value) {
            if (typeof value !== 'number') throw new TypeError('maxSize must be a number')
            maxSize = value
        }},
        processor: { get: function () {
            return processor
        }},
        limit: { value: function (limits) {
            limits = assign({ concurrency: Infinity, maxSize: Infinity }, limits)
            assert(typeof limits.maxSize === 'number', 'maxSize must be a number')
            assert(typeof limits.concurrency === 'number', 'concurrency must be a number')
            maxSize = limits.maxSize
            concurrency = limits.concurrency
            return cq
        }},
        process: { value: function (func) {
            assert(typeof func === 'function', 'process requires a processor function')
            assert(!processor, 'queue processor already defined')
            processor = func
            setImmediate(drain)
            return cq
        }},
        enqueued: { value: eventuate() },
        rejected: { value: eventuate() },
        processingStarted: { value: eventuate() },
        processingEnded: { value: eventuate() },
        drained: { value: eventuate() }
    })

    function drain () {
        if (!drained && pending.length === 0 && processing.length === 0) {
            drained = true
            cq.drained.produce()
        }
        while (processor && pending.length > 0 && processing.length < concurrency) drainItem()
        function drainItem () {
            var task = pending.shift()
            processing.push(task)
            cq.processingStarted.produce({ item: task.item })

            var reject = once(function reject (err) {
                processing.splice(processing.indexOf(task), 1)
                task.reject(err)
                setImmediate(drain)
            })
            var resolve = once(function resolve () {
                processing.splice(processing.indexOf(task), 1)
                task.resolve.apply(undefined, arguments)
                setImmediate(drain)
            })

            var p
            try {
                p = processor(task.item, onerr(reject).otherwise(resolve))
            }
            catch (err) {
                return reject(err)
            }
            if (p && typeof p.then === 'function') p.then(resolve, reject)
        }
    }

    return cq
}

assign(module.exports, errors)
<|endoftext|>


<commit_before>'use strict';

/*
 * index.js: Create an http AND/OR an https server and call the same request handler.
 *
 * (C) 2013, Charlie Robbins.
 *
 */

var fs = require('fs'),
    http = require('http'),
    https = require('https'),
    path = require('path'),
    connected = require('connected'),
    errs = require('errs'),
    assign = require('object-assign');

var CIPHERS = [
  'ECDHE-RSA-AES256-SHA384',
  'DHE-RSA-AES256-SHA384',
  'ECDHE-RSA-AES256-SHA256',
  'DHE-RSA-AES256-SHA256',
  'ECDHE-RSA-AES128-SHA256',
  'DHE-RSA-AES128-SHA256',
  'HIGH',
  '!aNULL',
  '!eNULL',
  '!EXPORT',
  '!DES',
  '!RC4',
  '!MD5',
  '!PSK',
  '!SRP',
  '!CAMELLIA'
].join(':');

//
// ### function createServers (dispatch, options, callback)
// Creates and listens on both HTTP and HTTPS servers.
//
module.exports = function createServers(options, listening) {
  if (!options || (!options.http && !options.https)
      || (!options.handler && !options.http.handler && !options.https.handler)) {
    return listening(new Error('handler, http and/or https are required options.'));
  }

  var handler = options.handler,
      log     = options.log || function () { },
      errors  = {},
      servers = {};

  //
  // ### function onListen(type, err, server)
  // Responds to the `listening` callback if necessary
  // with the appropriate servers.
  //
  function onListen(type, err, server) {
    servers[type] = server || true;
    if (err) {
      errors[type] = err;
    }

    if (servers.http && servers.https) {
      Object.keys(servers)
        .forEach(function (key) {
          if (typeof servers[key] === 'boolean') {
            delete servers[key];
          }
        });

      if (errors.http || errors.https) {
        return listening(errs.create({
          message: (errors.https || errors.http).message,
          https: errors.https,
          http:  errors.http
        }), servers);
      }

      listening(undefined, servers);
    }
  }

  //
  // ### function createHttp ()
  // Attempts to create and listen on the the HTTP server.
  //
  function createHttp() {
    if (!options.http) {
      log('http | no options.http; no server');
      return onListen('http');
    }

    if (typeof options.http !== 'object') {
      options.http = {
        // accept both a string and a number
        port: !isNaN(options.http)
          ? +options.http
          : false
      };
    }

    var server = http.createServer(options.http.handler || handler),
        port   = options.http.port || 80,
        args;

    args = [server, port];
    if (options.http.host) {
      args.push(options.http.host);
    }

    log('http | try listen ' + port);
    args.push(function listener(err) { onListen('http', err, this); });
    connected.apply(null, args);
  }

  //
  // ### function createHttps ()
  // Attempts to create and listen on the HTTPS server.
  //
  function createHttps(next) {
    if (!options.https) {
      log('https | no options.https; no server');
      return onListen('https');
    }

    var ssl  = options.https,
        port = +ssl.port || 443,
        ciphers = ssl.ciphers || CIPHERS,
        ca = ssl.ca,
        key = fs.readFileSync(path.resolve(ssl.root, ssl.key)),
        cert = fs.readFileSync(path.resolve(ssl.root, ssl.cert)),
        honorCipherOrder = !!ssl.honorCipherOrder,
        server,
        args;

    //
    // Remark: If an array is passed in lets join it like we do the defaults
    //
    if (Array.isArray(ciphers)) {
      ciphers = ciphers.join(':');
    }

    if (ca && !Array.isArray(ca)) {
      ca = [ca];
    }

    var finalHttpsOptions = assign({}, ssl, {
      //
      // Load default SSL key, cert and ca(s).
      //
      key: key,
      cert: cert,
      ca: ca && ca.map(
          function (file) {
            return fs.readFileSync(path.resolve(ssl.root, file));
          }
      ),
      //
      // Properly expose ciphers for an A+ SSL rating:
      // https://certsimple.com/blog/a-plus-node-js-ssl
      //
      ciphers: ciphers,
      honorCipherOrder: honorCipherOrder,
      //
      // Protect against the POODLE attack by disabling SSLv3
      // @see http://googleonlinesecurity.blogspot.nl/2014/10/this-poodle-bites-exploiting-ssl-30.html
      //
      secureProtocol: 'SSLv23_method',
      secureOptions: require('constants').SSL_OP_NO_SSLv3
    });

    log('https | listening on %d', port);
    server = https.createServer(finalHttpsOptions, ssl.handler || handler);

    args = [server, port];
    if (options.https.host) {
      args.push(options.https.host);
    }

    args.push(function listener(err) { onListen('https', err, this); });
    connected.apply(null, args);
  }

  [createHttp, createHttps]
    .forEach(function (fn) { fn(); });
};
<commit_msg>Inline unnecessary intermediate variables<commit_after>'use strict';

/*
 * index.js: Create an http AND/OR an https server and call the same request handler.
 *
 * (C) 2013, Charlie Robbins.
 *
 */

var fs = require('fs'),
    http = require('http'),
    https = require('https'),
    path = require('path'),
    connected = require('connected'),
    errs = require('errs'),
    assign = require('object-assign');

var CIPHERS = [
  'ECDHE-RSA-AES256-SHA384',
  'DHE-RSA-AES256-SHA384',
  'ECDHE-RSA-AES256-SHA256',
  'DHE-RSA-AES256-SHA256',
  'ECDHE-RSA-AES128-SHA256',
  'DHE-RSA-AES128-SHA256',
  'HIGH',
  '!aNULL',
  '!eNULL',
  '!EXPORT',
  '!DES',
  '!RC4',
  '!MD5',
  '!PSK',
  '!SRP',
  '!CAMELLIA'
].join(':');

//
// ### function createServers (dispatch, options, callback)
// Creates and listens on both HTTP and HTTPS servers.
//
module.exports = function createServers(options, listening) {
  if (!options || (!options.http && !options.https)
      || (!options.handler && !options.http.handler && !options.https.handler)) {
    return listening(new Error('handler, http and/or https are required options.'));
  }

  var handler = options.handler,
      log     = options.log || function () { },
      errors  = {},
      servers = {};

  //
  // ### function onListen(type, err, server)
  // Responds to the `listening` callback if necessary
  // with the appropriate servers.
  //
  function onListen(type, err, server) {
    servers[type] = server || true;
    if (err) {
      errors[type] = err;
    }

    if (servers.http && servers.https) {
      Object.keys(servers)
        .forEach(function (key) {
          if (typeof servers[key] === 'boolean') {
            delete servers[key];
          }
        });

      if (errors.http || errors.https) {
        return listening(errs.create({
          message: (errors.https || errors.http).message,
          https: errors.https,
          http:  errors.http
        }), servers);
      }

      listening(undefined, servers);
    }
  }

  //
  // ### function createHttp ()
  // Attempts to create and listen on the the HTTP server.
  //
  function createHttp() {
    if (!options.http) {
      log('http | no options.http; no server');
      return onListen('http');
    }

    if (typeof options.http !== 'object') {
      options.http = {
        // accept both a string and a number
        port: !isNaN(options.http)
          ? +options.http
          : false
      };
    }

    var server = http.createServer(options.http.handler || handler),
        port   = options.http.port || 80,
        args;

    args = [server, port];
    if (options.http.host) {
      args.push(options.http.host);
    }

    log('http | try listen ' + port);
    args.push(function listener(err) { onListen('http', err, this); });
    connected.apply(null, args);
  }

  //
  // ### function createHttps ()
  // Attempts to create and listen on the HTTPS server.
  //
  function createHttps(next) {
    if (!options.https) {
      log('https | no options.https; no server');
      return onListen('https');
    }

    var ssl  = options.https,
        port = +ssl.port || 443,
        ciphers = ssl.ciphers || CIPHERS,
        ca = ssl.ca,
        server,
        args;

    //
    // Remark: If an array is passed in lets join it like we do the defaults
    //
    if (Array.isArray(ciphers)) {
      ciphers = ciphers.join(':');
    }

    if (ca && !Array.isArray(ca)) {
      ca = [ca];
    }

    var finalHttpsOptions = assign({}, ssl, {
      //
      // Load default SSL key, cert and ca(s).
      //
      key: fs.readFileSync(path.resolve(ssl.root, ssl.key)),
      cert: fs.readFileSync(path.resolve(ssl.root, ssl.cert)),
      ca: ca && ca.map(
          function (file) {
            return fs.readFileSync(path.resolve(ssl.root, file));
          }
      ),
      //
      // Properly expose ciphers for an A+ SSL rating:
      // https://certsimple.com/blog/a-plus-node-js-ssl
      //
      ciphers: ciphers,
      honorCipherOrder: !!ssl.honorCipherOrder,
      //
      // Protect against the POODLE attack by disabling SSLv3
      // @see http://googleonlinesecurity.blogspot.nl/2014/10/this-poodle-bites-exploiting-ssl-30.html
      //
      secureProtocol: 'SSLv23_method',
      secureOptions: require('constants').SSL_OP_NO_SSLv3
    });

    log('https | listening on %d', port);
    server = https.createServer(finalHttpsOptions, ssl.handler || handler);

    args = [server, port];
    if (options.https.host) {
      args.push(options.https.host);
    }

    args.push(function listener(err) { onListen('https', err, this); });
    connected.apply(null, args);
  }

  [createHttp, createHttps]
    .forEach(function (fn) { fn(); });
};
<|endoftext|>


<commit_before>/* eslint-disable import/no-extraneous-dependencies */
const exec = require('exec-sh');
const inquirer = require('inquirer');
const fs = require('fs');
const path = require('path');
const pkg = require('../package.json');

const pkgCore = require('../packages/core/package.json');
const pkgReact = require('../packages/react/package.json');
const pkgVue = require('../packages/vue/package.json');
const pkgSvelte = require('../packages/svelte/package.json');

async function release() {
  const options = await inquirer.prompt([
    {
      type: 'input',
      name: 'version',
      message: 'Version:',
      default: pkgCore.version,
    },
    {
      type: 'list',
      name: 'alpha',
      message: 'Alpha?',
      when: (opts) => opts.version.indexOf('alpha') >= 0,
      choices: [
        {
          name: 'YES',
          value: true,
        },
        {
          name: 'NO',
          value: false,
        },
      ],
    },
    {
      type: 'list',
      name: 'beta',
      message: 'Beta?',
      when: (opts) => opts.version.indexOf('beta') >= 0,
      choices: [
        {
          name: 'YES',
          value: true,
        },
        {
          name: 'NO',
          value: false,
        },
      ],
    },
  ]);

  // Set version
  pkgCore.version = options.version;
  pkgReact.version = options.version;
  pkgVue.version = options.version;
  pkgSvelte.version = options.version;

  // Copy dependencies
  pkgCore.dependencies = pkg.dependencies;

  fs.writeFileSync(
    path.resolve(__dirname, '../packages/core/package.json'),
    JSON.stringify(pkgCore, null, 2),
  );
  fs.writeFileSync(
    path.resolve(__dirname, '../packages/react/package.json'),
    JSON.stringify(pkgReact, null, 2),
  );
  fs.writeFileSync(
    path.resolve(__dirname, '../packages/vue/package.json'),
    JSON.stringify(pkgVue, null, 2),
  );
  fs.writeFileSync(
    path.resolve(__dirname, '../packages/svelte/package.json'),
    JSON.stringify(pkgSvelte, null, 2),
  );

  await exec.promise('git pull');
  await exec.promise('npm i');

  await exec.promise(`npm run build-core:prod`);
  await exec.promise(`npm run build-react:prod`);
  await exec.promise(`npm run build-vue:prod`);
  await exec.promise(`npm run build-svelte:prod`);

  // NPM publish
  if (options.beta) {
    await exec.promise('cd ./packages/core && npm publish --tag beta');
    await exec.promise('cd ./packages/react && npm publish --tag beta');
    await exec.promise('cd ./packages/vue && npm publish --tag beta');
    await exec.promise('cd ./packages/svelte && npm publish --tag beta');
  } else if (options.alpha) {
    await exec.promise('cd ./packages/core && npm publish --tag next');
    await exec.promise('cd ./packages/react && npm publish --tag next');
    await exec.promise('cd ./packages/vue && npm publish --tag next');
    await exec.promise('cd ./packages/svelte && npm publish --tag next');
  } else {
    await exec.promise('cd ./packages/core && npm publish');
    await exec.promise('cd ./packages/react && npm publish');
    await exec.promise('cd ./packages/vue && npm publish');
    await exec.promise('cd ./packages/svelte && npm publish');
  }

  // Build Production Kitchen Sink
  await exec.promise('npm run build-ks:core');
  await exec.promise('npm run build-ks:react');
  await exec.promise('npm run build-ks:svelte');
  await exec.promise('npm run build-ks:vue');

  // Git commit & push
  await exec.promise('git add .');
  await exec.promise(`git commit -m "${pkgCore.version} release"`);
  await exec.promise('git push');
  await exec.promise(`git tag v${pkgCore.version}`);
  await exec.promise('git push origin --tags');
}

release();
<commit_msg>Update release.js<commit_after>/* eslint-disable import/no-extraneous-dependencies */
const exec = require('exec-sh');
const inquirer = require('inquirer');
const fs = require('fs');
const path = require('path');
const pkg = require('../package.json');

const pkgCore = require('../packages/core/package.json');
const pkgReact = require('../packages/react/package.json');
const pkgVue = require('../packages/vue/package.json');
const pkgSvelte = require('../packages/svelte/package.json');

async function release() {
  const options = await inquirer.prompt([
    {
      type: 'input',
      name: 'version',
      message: 'Version:',
      default: pkgCore.version,
    },
    {
      type: 'list',
      name: 'alpha',
      message: 'Alpha?',
      when: (opts) => opts.version.indexOf('alpha') >= 0,
      choices: [
        {
          name: 'YES',
          value: true,
        },
        {
          name: 'NO',
          value: false,
        },
      ],
    },
    {
      type: 'list',
      name: 'beta',
      message: 'Beta?',
      when: (opts) => opts.version.indexOf('beta') >= 0,
      choices: [
        {
          name: 'YES',
          value: true,
        },
        {
          name: 'NO',
          value: false,
        },
      ],
    },
  ]);

  // Set version
  pkgCore.version = options.version;
  pkgReact.version = options.version;
  pkgVue.version = options.version;
  pkgSvelte.version = options.version;

  // Copy dependencies
  pkgCore.dependencies = pkg.dependencies;

  fs.writeFileSync(
    path.resolve(__dirname, '../packages/core/package.json'),
    JSON.stringify(pkgCore, null, 2),
  );
  fs.writeFileSync(
    path.resolve(__dirname, '../packages/react/package.json'),
    JSON.stringify(pkgReact, null, 2),
  );
  fs.writeFileSync(
    path.resolve(__dirname, '../packages/vue/package.json'),
    JSON.stringify(pkgVue, null, 2),
  );
  fs.writeFileSync(
    path.resolve(__dirname, '../packages/svelte/package.json'),
    JSON.stringify(pkgSvelte, null, 2),
  );

  await exec.promise('git pull');
  await exec.promise('npm i');

  await exec.promise(`npm run build-core:prod`);
  await exec.promise(`npm run build-react:prod`);
  await exec.promise(`npm run build-vue:prod`);
  await exec.promise(`npm run build-svelte:prod`);

  // NPM publish
  if (options.beta) {
    await exec.promise('cd ./packages/core && npm publish --tag next');
    await exec.promise('cd ./packages/react && npm publish --tag next');
    await exec.promise('cd ./packages/vue && npm publish --tag next');
    await exec.promise('cd ./packages/svelte && npm publish --tag next');
  } else if (options.alpha) {
    await exec.promise('cd ./packages/core && npm publish --tag next');
    await exec.promise('cd ./packages/react && npm publish --tag next');
    await exec.promise('cd ./packages/vue && npm publish --tag next');
    await exec.promise('cd ./packages/svelte && npm publish --tag next');
  } else {
    await exec.promise('cd ./packages/core && npm publish');
    await exec.promise('cd ./packages/react && npm publish');
    await exec.promise('cd ./packages/vue && npm publish');
    await exec.promise('cd ./packages/svelte && npm publish');
  }

  // Build Production Kitchen Sink
  await exec.promise('npm run build-ks:core');
  await exec.promise('npm run build-ks:react');
  await exec.promise('npm run build-ks:svelte');
  await exec.promise('npm run build-ks:vue');

  // Git commit & push
  await exec.promise('git add .');
  await exec.promise(`git commit -m "${pkgCore.version} release"`);
  await exec.promise('git push');
  await exec.promise(`git tag v${pkgCore.version}`);
  await exec.promise('git push origin --tags');
}

release();
<|endoftext|>


<commit_before>#! /usr/bin/env node

'use strict';

var tls = require('tls');
var net = require('net');
var eos = require('end-of-stream');
var through = require('through2');
var minimist = require('minimist');
var allContainers = require('docker-allcontainers');
var statsFactory = require('docker-stats');
var logFactory = require('docker-loghose');
var eventsFactory = require('docker-event-log');

function connect(opts) {
  var stream;
  if (opts.secure) {
    stream = tls.connect(443, 'data.logentries.com', onSecure);
  } else {
    stream = net.createConnection(80, 'data.logentries.com');
  }

  function onSecure() {
    // let's just crash if we are not secure
    if (!stream.authorized) throw new Error('secure connection not authorized');
  }

  return stream;
}

function start(opts) {
  var logsToken = opts.logstoken || opts.token;
  var statsToken = opts.statstoken || opts.token;
  var out;
  var noRestart = function() {};

  var filter = through.obj(function(obj, enc, cb) {
    addAll(opts.add, obj);

    if (obj.line) {
      this.push(logsToken);
    } else {
      this.push(statsToken);
    }

    this.push(' ');
    this.push(JSON.stringify(obj));
    this.push('\n');
    cb()
  });
  var events = allContainers(opts);
  var loghose;
  var stats;
  var dockerEvents;

  opts.events = events;

  if (opts.logs !== false) {
    loghose = logFactory(opts);
    loghose.pipe(filter);
  }

  if (opts.stats !== false) {
    stats = statsFactory(opts);
    stats.pipe(filter);
  }

  if (opts.dockerEvents !== false) {
    dockerEvents = eventsFactory(opts);
    dockerEvents.pipe(filter);
  }

  if (!stats && !loghose && !dockerEvents) {
    throw new Error('you should enable at least one of stats, logs or dockerEvents');
  }

  pipe();

  // destroy out if loghose is destroyed
  eos(loghose, function() {
    noRestart()
    out.destroy();
  });

  return loghose;

  function addAll(proto, obj) {
    if (!proto) { return; }

    var key;
    for (key in proto) {
      if (proto.hasOwnProperty(key)) {
        obj[key] = proto[key];
      }
    }
  }

  function pipe() {
    if (out) {
      filter.unpipe(out);
    }

    out = connect(opts);

    filter.pipe(out, { end: false });

    // automatically reconnect on socket failure
    noRestart = eos(out, pipe);
  }
}

function cli() {
  var argv = minimist(process.argv.slice(2), {
    boolean: ['json', 'stats', 'dockerEvents'],
    alias: {
      'token': 't',
      'logstoken': 'l',
      'statstoken': 'k',
      'secure': 's',
      'json': 'j',
      'statsinterval': 'i',
      'add': 'a'
    },
    default: {
      json: false,
      stats: true,
      logs: true,
      dockerEvents: true,
      'statsinterval': 1,
      add: []
    }
  });

  if (!(argv.token || (argv.logstoken && argv.statstoken))) {
    console.log('Usage: docker-logentries [-l LOGSTOKEN] [-k STATSTOKEN]\n' +
                '                         [-t TOKEN] [--secure] [--json]\n' +
                '                         [--no-stats] [--no-logs] [--no-dockerEvents]\n' +
                '                         [-i STATSINTERVAL] [-a KEY=VALUE]\n' +
                '                         [--matchByImage REGEXP] [--matchByName REGEXP]\n' +
                '                         [--skipByImage REGEXP] [--skipByName REGEXP]');

    process.exit(1);
  }

  if (argv.add && !Array.isArray(argv.add)) {
    argv.add = [argv.add];
  }

  argv.add = argv.add.reduce(function(acc, arg) {
    arg = arg.split('=');
    acc[arg[0]] = arg[1];
    return acc
  }, {});

  start(argv);
}

module.exports = start;

if (require.main === module) {
  cli();
}
<commit_msg>Update default value for stats interval<commit_after>#! /usr/bin/env node

'use strict';

var tls = require('tls');
var net = require('net');
var eos = require('end-of-stream');
var through = require('through2');
var minimist = require('minimist');
var allContainers = require('docker-allcontainers');
var statsFactory = require('docker-stats');
var logFactory = require('docker-loghose');
var eventsFactory = require('docker-event-log');

function connect(opts) {
  var stream;
  if (opts.secure) {
    stream = tls.connect(443, 'data.logentries.com', onSecure);
  } else {
    stream = net.createConnection(80, 'data.logentries.com');
  }

  function onSecure() {
    // let's just crash if we are not secure
    if (!stream.authorized) throw new Error('secure connection not authorized');
  }

  return stream;
}

function start(opts) {
  var logsToken = opts.logstoken || opts.token;
  var statsToken = opts.statstoken || opts.token;
  var out;
  var noRestart = function() {};

  var filter = through.obj(function(obj, enc, cb) {
    addAll(opts.add, obj);

    if (obj.line) {
      this.push(logsToken);
    } else {
      this.push(statsToken);
    }

    this.push(' ');
    this.push(JSON.stringify(obj));
    this.push('\n');
    cb()
  });
  var events = allContainers(opts);
  var loghose;
  var stats;
  var dockerEvents;

  opts.events = events;

  if (opts.logs !== false) {
    loghose = logFactory(opts);
    loghose.pipe(filter);
  }

  if (opts.stats !== false) {
    stats = statsFactory(opts);
    stats.pipe(filter);
  }

  if (opts.dockerEvents !== false) {
    dockerEvents = eventsFactory(opts);
    dockerEvents.pipe(filter);
  }

  if (!stats && !loghose && !dockerEvents) {
    throw new Error('you should enable at least one of stats, logs or dockerEvents');
  }

  pipe();

  // destroy out if loghose is destroyed
  eos(loghose, function() {
    noRestart()
    out.destroy();
  });

  return loghose;

  function addAll(proto, obj) {
    if (!proto) { return; }

    var key;
    for (key in proto) {
      if (proto.hasOwnProperty(key)) {
        obj[key] = proto[key];
      }
    }
  }

  function pipe() {
    if (out) {
      filter.unpipe(out);
    }

    out = connect(opts);

    filter.pipe(out, { end: false });

    // automatically reconnect on socket failure
    noRestart = eos(out, pipe);
  }
}

function cli() {
  var argv = minimist(process.argv.slice(2), {
    boolean: ['json', 'stats', 'dockerEvents'],
    alias: {
      'token': 't',
      'logstoken': 'l',
      'statstoken': 'k',
      'secure': 's',
      'json': 'j',
      'statsinterval': 'i',
      'add': 'a'
    },
    default: {
      json: false,
      stats: true,
      logs: true,
      dockerEvents: true,
      'statsinterval': 30,
      add: []
    }
  });

  if (!(argv.token || (argv.logstoken && argv.statstoken))) {
    console.log('Usage: docker-logentries [-l LOGSTOKEN] [-k STATSTOKEN]\n' +
                '                         [-t TOKEN] [--secure] [--json]\n' +
                '                         [--no-stats] [--no-logs] [--no-dockerEvents]\n' +
                '                         [-i STATSINTERVAL] [-a KEY=VALUE]\n' +
                '                         [--matchByImage REGEXP] [--matchByName REGEXP]\n' +
                '                         [--skipByImage REGEXP] [--skipByName REGEXP]');

    process.exit(1);
  }

  if (argv.add && !Array.isArray(argv.add)) {
    argv.add = [argv.add];
  }

  argv.add = argv.add.reduce(function(acc, arg) {
    arg = arg.split('=');
    acc[arg[0]] = arg[1];
    return acc
  }, {});

  start(argv);
}

module.exports = start;

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


<commit_before>#! /usr/bin/env node
/* eslint-disable no-console */

const os = require('os');
const fs = require('fs-extra');
const path = require('path');
const { execSync } = require('child_process');
const inquirer = require('inquirer');

// Configure the arguments parser and documentation
const argv = require('yargs')
  .option('npm-tag', {
    describe: 'Publish a release using a custom npm dist-tag',
    default: 'latest',
    type: 'string'
  })
  .option('skip-git', {
    describe: "Skip git commands. Don't push to GitHub"
  })
  .option('skip-npm', {
    describe: "Skip npm commands. Don't publish to npm"
  })
  .usage('Usage: $0 [options]')
  .example('$0', 'Perform a standard release')
  .example('$0 --npm-tag=next', 'Perform a release using npm dist-tag "next"')
  .example('$0 --skip-git', 'Skip push to GitHub.')
  .example('$0 --skip-npm', 'Skip publish to npm.')
  .help('h')
  .alias('h', 'help').argv;

const exec = command =>
  execSync(command, {
    stdio: 'inherit'
  });

const { npmTag, skipGit, skipNpm } = argv;

// Read dist/package.json and get package version
const packageJsonFile = path.resolve(__dirname, '../dist/package.json');
if (!fs.existsSync(packageJsonFile)) {
  console.log(
    `Unable to find ${packageJsonFile}. You must build a package first. Release aborted.`
  );
  process.exit(0);
}
const version = fs.readJsonSync(packageJsonFile).version;

// Check if version has previously been published
// Note: tmpfile used to get output from npm command
const npmVersionsFile = path.resolve(os.tmpdir(), '.npm-versions');
exec(`echo "$(npm show mineral-ui versions)" > ${npmVersionsFile}`);
const versionPreviouslyPublished = fs
  .readFileSync(npmVersionsFile, { encoding: 'utf8' })
  .includes(version);
fs.removeSync(npmVersionsFile);
if (versionPreviouslyPublished) {
  console.log(
    `Version ${version} has previously been published. Release aborted.`
  );
  process.exit(0);
}

// Publishing - prompt user for confirmation
inquirer
  .prompt([
    {
      type: 'confirm',
      name: 'confirm',
      message: `Ready to release ${version} using npm tag ${npmTag}?`
    }
  ])
  .then(({ confirm }) => {
    if (confirm) {
      // Publish to npm
      if (skipNpm) {
        console.log('Skipped publish to npm...');
      } else {
        console.log('Publishing to npm...');
        exec(`cd dist && npm publish --tag=${npmTag}`);
      }

      // Push commits and tags to GitHub
      if (skipGit) {
        console.log('Skipped push to GitHub...');
      } else {
        console.log('Pushing to GitHub...');
        exec('git push -f --follow-tags');
      }
    } else {
      console.log('Release aborted.');
    }
  });
<commit_msg>chore(scripts): Update release script previously published version check<commit_after>#! /usr/bin/env node
/* eslint-disable no-console */

const os = require('os');
const fs = require('fs-extra');
const path = require('path');
const { execSync } = require('child_process');
const inquirer = require('inquirer');

// Configure the arguments parser and documentation
const argv = require('yargs')
  .option('npm-tag', {
    describe: 'Publish a release using a custom npm dist-tag',
    default: 'latest',
    type: 'string'
  })
  .option('skip-git', {
    describe: "Skip git commands. Don't push to GitHub"
  })
  .option('skip-npm', {
    describe: "Skip npm commands. Don't publish to npm"
  })
  .usage('Usage: $0 [options]')
  .example('$0', 'Perform a standard release')
  .example('$0 --npm-tag=next', 'Perform a release using npm dist-tag "next"')
  .example('$0 --skip-git', 'Skip push to GitHub.')
  .example('$0 --skip-npm', 'Skip publish to npm.')
  .help('h')
  .alias('h', 'help').argv;

const exec = command =>
  execSync(command, {
    stdio: 'inherit'
  });

const { npmTag, skipGit, skipNpm } = argv;

// Read dist/package.json and get package version
const packageJsonFile = path.resolve(__dirname, '../dist/package.json');
if (!fs.existsSync(packageJsonFile)) {
  console.log(
    `Unable to find ${packageJsonFile}. You must build a package first. Release aborted.`
  );
  process.exit(0);
}
const version = fs.readJsonSync(packageJsonFile).version;

// Check if version has previously been published
// Note: tmpfile used to get output from npm command
const npmVersionsFile = path.resolve(os.tmpdir(), '.npm-versions');
exec(`echo "$(npm show mineral-ui versions)" > ${npmVersionsFile}`);
const versionPreviouslyPublished = fs
  .readFileSync(npmVersionsFile, { encoding: 'utf8' })
  .includes(`'${version}'`);
fs.removeSync(npmVersionsFile);
if (versionPreviouslyPublished) {
  console.log(
    `Version ${version} has previously been published. Release aborted.`
  );
  process.exit(0);
}

// Publishing - prompt user for confirmation
inquirer
  .prompt([
    {
      type: 'confirm',
      name: 'confirm',
      message: `Ready to release ${version} using npm tag ${npmTag}?`
    }
  ])
  .then(({ confirm }) => {
    if (confirm) {
      // Publish to npm
      if (skipNpm) {
        console.log('Skipped publish to npm...');
      } else {
        console.log('Publishing to npm...');
        exec(`cd dist && npm publish --tag=${npmTag}`);
      }

      // Push commits and tags to GitHub
      if (skipGit) {
        console.log('Skipped push to GitHub...');
      } else {
        console.log('Pushing to GitHub...');
        exec('git push -f --follow-tags');
      }
    } else {
      console.log('Release aborted.');
    }
  });
<|endoftext|>


<commit_before>/*!
 * modofun
 * Copyright (c) 2017 Filipe Tavares
 * MIT Licensed
 */

'use strict';

const http = require('http');

exports = module.exports = createServiceHandler;

exports.aws = createAwsServiceHandler;
exports.arity = arity;

/**
 * Errors issued by the service handler and passed on to error handler, or next().
 * @private
 */
class ModofunError extends Error {
  constructor(status, code, message) {
    super(message);
    this.status = status;
    this.code = code;
  }
}

/**
 * Request object wrapper for the AWS API Gateway event.
 * @private
 */
class AWSRequest {
  constructor(event, context) {
    this.event = event;
    this.context = context;
    this.method = event.httpMethod;
    this.path = event.path;
    this.query = event.queryStringParameters;
    this.body = event.body;
    this.headers = event.headers;
  }
}

/**
 * Response object wrapper for the AWS API Gateway callback.
 * @private
 */
class AWSResponse extends http.ServerResponse {
  constructor(req, callback) {
    super(req);
    this._callback = callback;
  }
  status(code) {
    this.statusCode = code;
    return this;
  }
  json(body) {
    this.setHeader('Content-Type', 'application/json');
    this._callback(null, {
      statusCode: this.statusCode,
      headers: this.getHeaders(),
      body: JSON.stringify(body)
    });
  }
  end(body) {
    this._callback(null, { statusCode: this.statusCode, headers: this.getHeaders(), body });
  }
  getHeaders() {
    return this._headers; // TODO: use ServerResponse.getHeaders() once available on next LTS
  }
}

/*
 * Service handler type
 */
const AWS_TYPE = 'aws'; // AWS API Gateway event
const REQRES_TYPE = 'reqres'; // Google Cloud, Express and others fn(req, res[, next])
/*
 * Route handler mode
 */
const HTTP_MODE = 'http';
const FUNCTION_MODE = 'function';

/**
 * The exported function that creates the request handler
 * using the supplied handlers and configuration.
 *
 * Returns a handler with function(req, res, next) signature,
 * which is compatible with Express/Connect apps and middlewares,
 * and Google Cloud Functions.
 *
 * Example:
 *
 * var app = modofun(
 *   {
 *     authenticate: authenticate,
 *     user: [authorize, getUser]
 *   },
 *   {
 *     middleware: [logger],
 *     errorHandler: (err, req, res) => res.status(500).send(err.message)
 *   }
 * )
 * @public
 */
function createServiceHandler(handlers = {}, options = {}) {
  const errorHandler = options.errorHandler || defaultErrorHandler;
  const middleware = options.middleware || Array.isArray(options) && options || [];
  const mode = options.mode || HTTP_MODE;
  const type = options.type || REQRES_TYPE;
  const checkArity = Boolean(options.checkArity);

  if (type === AWS_TYPE) {
    // return handler function with fn(event, context, callback) signature
    return (event, context, callback) => {
      // if AWS Lambda request, convert event and context to request and response
      const req = new AWSRequest(event, context);
      const res = new AWSResponse(req, callback);
      // function to call when done
      const done = err => err && setImmediate(errorHandler, err, req, res);
      // handle request
      handleRequest(middleware, handlers, mode, checkArity, req, res, done);
    };
  } else {
    // return handler function with fn(req, res, next) signature
    return (req, res, next) => {
      // function to call when done
      const done = next && (err => setImmediate(next, err))
                   || (err => err && setImmediate(errorHandler, err, req, res));
      // handle request
      handleRequest(middleware, handlers, mode, checkArity, req, res, done);
    };
  }
}

/**
 * Execute middleware stack and handle request.
 * @private
 */
function handleRequest(middleware, handlers, mode, checkArity, req, res, done) {
  // run global middleware first, then start handling request
  // this is important to allow loggers for example to kick-in regardless
  runMiddlewareStack(middleware, req, res, (err) => {
    if (err) {
      done(err);
      return;
    }
    // try to apply supplied handlers to the requested operation
    handleOperation(handlers, mode, checkArity, req, res, done);
  });
}

/**
 * Try to apply supplied handlers to the requested operation.
 * @private
 */
function handleOperation(handlers, mode, checkArity, req, res, done) {
  // parse path:
  // - first part is the operation name
  // - the following components of the path are used as arguments
  const parsedParts = parsePath(req);
  if (parsedParts[0].length === 0) {
    done(new ModofunError(403, 'NoOperation', 'Operation must be specified!'));
    return;
  }
  const [operation, ...args] = parsedParts;

  if (operation && handlers.hasOwnProperty(operation)) {
    // the stack of operation specific middleware
    let operationMiddleware = [];
    // operation handler
    let operationHandler = handlers[operation];

    if (Array.isArray(operationHandler)) {
      // if an array is passed, add operation specific middleware
      // last item in the array should be the operation handler
      operationMiddleware = operationHandler.slice(0, -1);
      operationHandler = operationHandler[operationHandler.length-1];

    } else if (typeof operationHandler !== 'function') {
      // otherwise return internal error
      done(new ModofunError(500, 'InvalidConfig', 'Handler must be a function or array'));
      return;
    }

    // call middleware stack with same req/res context
    runMiddlewareStack(operationMiddleware, req, res, (err) => {
      if (err) {
        done(err);
        return;
      }
      try {
        // call handler function
        if (mode === FUNCTION_MODE) {
          invokeFunctionHandler(operationHandler, args, checkArity, req, res, done);
        } else {
          invokeHTTPHandler(operationHandler, args, req, res, done);
        }
      } catch(err) {
        done(err);
      }
    });

  } else {
    // fail if requested operation cannot be resolved
    done(new ModofunError(404, 'NotFound', `No handler for: ${operation}`));
    return;
  }
}

/**
 * Run through the middleware stack in Connect/Express-like manner.
 * Heavily based on the Connect implementation: https://github.com/senchalabs/connect
 * @private
 */
function runMiddlewareStack(stack, req, res, callback) {
  let index = 0;
  // the middleware layer handover callback
  function next(err) {
    // get next middleware callback from stack
    const handle = stack[index++];
    // if no more layers in stack, invoke done callback and exit recursion
    if (!handle) {
      callback(err);
      return;
    }
    let error = err;
    // call the middleware handler
    try {
      if (err && handle.length === 4) {
        // there is an error and it's an error-handling middleware
        handle(err, req, res, next);
        return;
      } else if (!err && handle.length < 4) {
        // no error and it's a request-handling middleware
        handle(req, res, next);
        return;
      }
    } catch (e) {
      // if new error thrown, replace the error
      error = e;
    }
    // otherwise skip layer
    next(error);
  }
  // start going through middleware stack
  next();
}

/**
 * Invoke the provided request handler function.
 * This handler function must send a response.
 * If the handler returns a Promise,
 * the next() callback will be called after the promise is resolved
 * and will contain the error if the Promise is rejected.
 * @private
 */
function invokeHTTPHandler(handler, args, req, res, done) {
  // inject parsed parameters into request
  req.params = args;
  // call handler with typical HTTP request/response parameters
  let result = handler(req, res);
  // handle results that are not a trusted Promise with Promise.resolve()
  // which also supports other then-ables
  if (result instanceof Promise === false) {
    result = Promise.resolve(result);
  }
  return result.then(() => done()).catch(done);
}

/**
 * Invoke the provided request handler function.
 * The handler should return a value or a Promised value
 * which will be added to the reponse automatically.
 * @private
 */
function invokeFunctionHandler(handler, args, checkArity, req, res, done) {
  // add to function arguments the remaining relevant input
  // could consider pushing the whole request object instead?
  // for now prefer to keep it to minimum to allow maximum flexibility
  args.push({
    body: req.body,
    query: req.query,
    user: req.user
  });
  // check if number of arguments provided matches the handler function arity
  if (checkArity && handler.length !== args.length) {
    done(new ModofunError(400, 'InvalidInput',
      `This operation requires ${handler.length} parameters. Received ${args.length}.`
    ));
    return;
  }
  // call handler function with
  let result = handler.apply(null, args);
  // handle results that are not a trusted Promise with Promise.resolve()
  // which also supports other then-ables
  if (result instanceof Promise === false) {
    result = Promise.resolve(result);
  }
  return result
    .then(value => {
      if (value == null) {
        res.status(204).end();
      } else {
        res.status(200).json(value);
      }
      done();
    })
    .catch(done);
}

/**
 * The default error handler, in case none is provided by the application.
 * @private
 */
function defaultErrorHandler(err, req, res) {
  if (err.name === 'UnauthorizedError') { // authentication is expected to be a common use-case
    res.status(401).end();
  } else {
    if (!err.status || err.status >= 500) {
      console.error(err.stack || err.toString());
    }
    res.status(err.status || 500).json({message: err.message})
  }
}

/**
 * Parse URL path to an array of its components.
 * @private
 */
function parsePath(req) {
  // get path if preprocessed or otherwise separate path from query string
  const path = req.path || req.url && req.url.split('?')[0];
  // ignore start and end slashes, and split the path
  return path.replace(/^\/|\/$/g, '').split('/');
}

/**
 * Utility middleware to enforce an exact number of parameters.
 * @public
 */
function arity(amount) {
  return (req, res, next) => {
    const foundArity = parsePath(req).length-1;
    if (foundArity === amount) {
      next();
    } else {
      next(new ModofunError(400, 'InvalidInput',
        `This operation requires exactly ${amount} parameters. Received ${foundArity}.`
      ));
    }
  }
}

/**
 * Shortcut method to create an application for AWS Lambda with API Gateway events (type='aws').
 * @public
 */
function createAwsServiceHandler(handlers, middleware) {
  return createServiceHandler(handlers, { type: AWS_TYPE, middleware });
}
<commit_msg>Fixed reccursive getHeaders bug<commit_after>/*!
 * modofun
 * Copyright (c) 2017 Filipe Tavares
 * MIT Licensed
 */

'use strict';

const http = require('http');

exports = module.exports = createServiceHandler;

exports.aws = createAwsServiceHandler;
exports.arity = arity;

/**
 * Errors issued by the service handler and passed on to error handler, or next().
 * @private
 */
class ModofunError extends Error {
  constructor(status, code, message) {
    super(message);
    this.status = status;
    this.code = code;
  }
}

/**
 * Request object wrapper for the AWS API Gateway event.
 * @private
 */
class AWSRequest {
  constructor(event, context) {
    this.event = event;
    this.context = context;
    this.method = event.httpMethod;
    this.path = event.path;
    this.query = event.queryStringParameters;
    this.body = event.body;
    this.headers = event.headers;
  }
}

/**
 * Response object wrapper for the AWS API Gateway callback.
 * @private
 */
class AWSResponse extends http.ServerResponse {
  constructor(req, callback) {
    super(req);
    this._callback = callback;
  }
  status(code) {
    this.statusCode = code;
    return this;
  }
  json(body) {
    this.setHeader('Content-Type', 'application/json');
    this._callback(null, {
      statusCode: this.statusCode,
      headers: this._headers, // TODO: use ServerResponse.getHeaders() once available on next LTS
      body: JSON.stringify(body)
    });
  }
  end(body) {
    this._callback(null, { statusCode: this.statusCode, headers: this._headers, body });
  }
}

/*
 * Service handler type
 */
const AWS_TYPE = 'aws'; // AWS API Gateway event
const REQRES_TYPE = 'reqres'; // Google Cloud, Express and others fn(req, res[, next])
/*
 * Route handler mode
 */
const HTTP_MODE = 'http';
const FUNCTION_MODE = 'function';

/**
 * The exported function that creates the request handler
 * using the supplied handlers and configuration.
 *
 * Returns a handler with function(req, res, next) signature,
 * which is compatible with Express/Connect apps and middlewares,
 * and Google Cloud Functions.
 *
 * Example:
 *
 * var app = modofun(
 *   {
 *     authenticate: authenticate,
 *     user: [authorize, getUser]
 *   },
 *   {
 *     middleware: [logger],
 *     errorHandler: (err, req, res) => res.status(500).send(err.message)
 *   }
 * )
 * @public
 */
function createServiceHandler(handlers = {}, options = {}) {
  const errorHandler = options.errorHandler || defaultErrorHandler;
  const middleware = options.middleware || Array.isArray(options) && options || [];
  const mode = options.mode || HTTP_MODE;
  const type = options.type || REQRES_TYPE;
  const checkArity = Boolean(options.checkArity);

  if (type === AWS_TYPE) {
    // return handler function with fn(event, context, callback) signature
    return (event, context, callback) => {
      // if AWS Lambda request, convert event and context to request and response
      const req = new AWSRequest(event, context);
      const res = new AWSResponse(req, callback);
      // function to call when done
      const done = err => err && setImmediate(errorHandler, err, req, res);
      // handle request
      handleRequest(middleware, handlers, mode, checkArity, req, res, done);
    };
  } else {
    // return handler function with fn(req, res, next) signature
    return (req, res, next) => {
      // function to call when done
      const done = next && (err => setImmediate(next, err))
                   || (err => err && setImmediate(errorHandler, err, req, res));
      // handle request
      handleRequest(middleware, handlers, mode, checkArity, req, res, done);
    };
  }
}

/**
 * Execute middleware stack and handle request.
 * @private
 */
function handleRequest(middleware, handlers, mode, checkArity, req, res, done) {
  // run global middleware first, then start handling request
  // this is important to allow loggers for example to kick-in regardless
  runMiddlewareStack(middleware, req, res, (err) => {
    if (err) {
      done(err);
      return;
    }
    // try to apply supplied handlers to the requested operation
    handleOperation(handlers, mode, checkArity, req, res, done);
  });
}

/**
 * Try to apply supplied handlers to the requested operation.
 * @private
 */
function handleOperation(handlers, mode, checkArity, req, res, done) {
  // parse path:
  // - first part is the operation name
  // - the following components of the path are used as arguments
  const parsedParts = parsePath(req);
  if (parsedParts[0].length === 0) {
    done(new ModofunError(403, 'NoOperation', 'Operation must be specified!'));
    return;
  }
  const [operation, ...args] = parsedParts;

  if (operation && handlers.hasOwnProperty(operation)) {
    // the stack of operation specific middleware
    let operationMiddleware = [];
    // operation handler
    let operationHandler = handlers[operation];

    if (Array.isArray(operationHandler)) {
      // if an array is passed, add operation specific middleware
      // last item in the array should be the operation handler
      operationMiddleware = operationHandler.slice(0, -1);
      operationHandler = operationHandler[operationHandler.length-1];

    } else if (typeof operationHandler !== 'function') {
      // otherwise return internal error
      done(new ModofunError(500, 'InvalidConfig', 'Handler must be a function or array'));
      return;
    }

    // call middleware stack with same req/res context
    runMiddlewareStack(operationMiddleware, req, res, (err) => {
      if (err) {
        done(err);
        return;
      }
      try {
        // call handler function
        if (mode === FUNCTION_MODE) {
          invokeFunctionHandler(operationHandler, args, checkArity, req, res, done);
        } else {
          invokeHTTPHandler(operationHandler, args, req, res, done);
        }
      } catch(err) {
        done(err);
      }
    });

  } else {
    // fail if requested operation cannot be resolved
    done(new ModofunError(404, 'NotFound', `No handler for: ${operation}`));
    return;
  }
}

/**
 * Run through the middleware stack in Connect/Express-like manner.
 * Heavily based on the Connect implementation: https://github.com/senchalabs/connect
 * @private
 */
function runMiddlewareStack(stack, req, res, callback) {
  let index = 0;
  // the middleware layer handover callback
  function next(err) {
    // get next middleware callback from stack
    const handle = stack[index++];
    // if no more layers in stack, invoke done callback and exit recursion
    if (!handle) {
      callback(err);
      return;
    }
    let error = err;
    // call the middleware handler
    try {
      if (err && handle.length === 4) {
        // there is an error and it's an error-handling middleware
        handle(err, req, res, next);
        return;
      } else if (!err && handle.length < 4) {
        // no error and it's a request-handling middleware
        handle(req, res, next);
        return;
      }
    } catch (e) {
      // if new error thrown, replace the error
      error = e;
    }
    // otherwise skip layer
    next(error);
  }
  // start going through middleware stack
  next();
}

/**
 * Invoke the provided request handler function.
 * This handler function must send a response.
 * If the handler returns a Promise,
 * the next() callback will be called after the promise is resolved
 * and will contain the error if the Promise is rejected.
 * @private
 */
function invokeHTTPHandler(handler, args, req, res, done) {
  // inject parsed parameters into request
  req.params = args;
  // call handler with typical HTTP request/response parameters
  let result = handler(req, res);
  // handle results that are not a trusted Promise with Promise.resolve()
  // which also supports other then-ables
  if (result instanceof Promise === false) {
    result = Promise.resolve(result);
  }
  return result.then(() => done()).catch(done);
}

/**
 * Invoke the provided request handler function.
 * The handler should return a value or a Promised value
 * which will be added to the reponse automatically.
 * @private
 */
function invokeFunctionHandler(handler, args, checkArity, req, res, done) {
  // add to function arguments the remaining relevant input
  // could consider pushing the whole request object instead?
  // for now prefer to keep it to minimum to allow maximum flexibility
  args.push({
    body: req.body,
    query: req.query,
    user: req.user
  });
  // check if number of arguments provided matches the handler function arity
  if (checkArity && handler.length !== args.length) {
    done(new ModofunError(400, 'InvalidInput',
      `This operation requires ${handler.length} parameters. Received ${args.length}.`
    ));
    return;
  }
  // call handler function with
  let result = handler.apply(null, args);
  // handle results that are not a trusted Promise with Promise.resolve()
  // which also supports other then-ables
  if (result instanceof Promise === false) {
    result = Promise.resolve(result);
  }
  return result
    .then(value => {
      if (value == null) {
        res.status(204).end();
      } else {
        res.status(200).json(value);
      }
      done();
    })
    .catch(done);
}

/**
 * The default error handler, in case none is provided by the application.
 * @private
 */
function defaultErrorHandler(err, req, res) {
  if (err.name === 'UnauthorizedError') { // authentication is expected to be a common use-case
    res.status(401).end();
  } else {
    if (!err.status || err.status >= 500) {
      console.error(err.stack || err.toString());
    }
    res.status(err.status || 500).json({message: err.message})
  }
}

/**
 * Parse URL path to an array of its components.
 * @private
 */
function parsePath(req) {
  // get path if preprocessed or otherwise separate path from query string
  const path = req.path || req.url && req.url.split('?')[0];
  // ignore start and end slashes, and split the path
  return path.replace(/^\/|\/$/g, '').split('/');
}

/**
 * Utility middleware to enforce an exact number of parameters.
 * @public
 */
function arity(amount) {
  return (req, res, next) => {
    const foundArity = parsePath(req).length-1;
    if (foundArity === amount) {
      next();
    } else {
      next(new ModofunError(400, 'InvalidInput',
        `This operation requires exactly ${amount} parameters. Received ${foundArity}.`
      ));
    }
  }
}

/**
 * Shortcut method to create an application for AWS Lambda with API Gateway events (type='aws').
 * @public
 */
function createAwsServiceHandler(handlers, middleware) {
  return createServiceHandler(handlers, { type: AWS_TYPE, middleware });
}
<|endoftext|>


<commit_before>export default function html([first, ...strings], ...values) {
    // Weave the literal strings and the interpolations.
    // We don't have to explicitly handle array-typed values
    // because concat will spread them flat for us.
    return values.reduce(
        (acc, cur) => acc.concat(cur, strings.shift()),
        [first]
    )
    .filter(value => value !== null && value !== undefined)
    .join("");
}

export function createStore(reducer) {
    let state = reducer();
    const roots = new Map();
    const prevs = new Map();

    function render() {
        for (const [root, component] of roots) {
            const output = component();

            // Poor man's Virtual DOM implementation :)  Compare the new output
            // with the last output for this root.  Don't trust the current
            // value of root.innerHTML as it may have been changed by other
            // scripts or extensions.
            if (output !== prevs.get(root)) {
                prevs.set(root, output);
                root.innerHTML = output;
            }
        }
    };

    return {
        attach(component, root) {
            roots.set(root, component);
            render();
        },
        connect(component) {
            // Return a decorated component function.
            return (...args) => component(state, ...args);
        },
        dispatch(action, ...args) {
            state = reducer(state, action, args);
            render();
        },
    };
}
<commit_msg>Filter out null/undefined interpolations by loosely-equal comparing to null<commit_after>export default function html([first, ...strings], ...values) {
    // Weave the literal strings and the interpolations.
    // We don't have to explicitly handle array-typed values
    // because concat will spread them flat for us.
    return values.reduce(
        (acc, cur) => acc.concat(cur, strings.shift()),
        [first]
    )

    // Filter out interpolations which are null or undefined.  null is
    // loosely-equal only to undefined and itself.
    .filter(value => value != null)
    .join("");
}

export function createStore(reducer) {
    let state = reducer();
    const roots = new Map();
    const prevs = new Map();

    function render() {
        for (const [root, component] of roots) {
            const output = component();

            // Poor man's Virtual DOM implementation :)  Compare the new output
            // with the last output for this root.  Don't trust the current
            // value of root.innerHTML as it may have been changed by other
            // scripts or extensions.
            if (output !== prevs.get(root)) {
                prevs.set(root, output);
                root.innerHTML = output;
            }
        }
    };

    return {
        attach(component, root) {
            roots.set(root, component);
            render();
        },
        connect(component) {
            // Return a decorated component function.
            return (...args) => component(state, ...args);
        },
        dispatch(action, ...args) {
            state = reducer(state, action, args);
            render();
        },
    };
}
<|endoftext|>


<commit_before>var vdf = require('vdf');
var fs = require('fs');
var SteamID = require('steamid');

var protomask = 0x80000000;

var Language = require(__dirname + '/language.js');
var Protos = require(__dirname + '/protos.js');

var base_gcmessages = Protos.base_gcmessages;
var tf_gcmessages = Protos.tf_gcmessages;

module.exports = TeamFortress2;

require('util').inherits(TeamFortress2, require('events').EventEmitter);

function TeamFortress2(steam) {
	this._steam = steam;
	this.haveGCSession = false;

	var self = this;

	// "extend" the default steam.gamesPlayed function so we can catch when TF2 starts up
	var gamesPlayed = steam.gamesPlayed;
	steam.gamesPlayed = function(appids) {
		if(appids.indexOf(440) != -1 && !self.haveGCSession) {
			self._connect();
		}

		gamesPlayed.call(steam, appids);
	};

	steam.on('fromGC', function(appID, type, body) {
		if(appID != 440) {
			// Not from the TF2 GC
			return;
		}

		var protobuf = !!(type & protomask);
		type &= ~protomask;

		if(self._handlers[type]) {
			self._handlers[type].call(self, body);
		} else {
			var msgName = type;
			for(var i in Language) {
				if(Language[i] == type) {
					msgName = i;
					break;
				}
			}

			self.emit('debug', "Got unhandled GC message " + msgName + (protobuf ? " (protobuf)" : ""));
		}
	});
}

TeamFortress2.prototype._connect = function() {
	var self = this;
	var interval = setInterval(function() {
		// TODO: Clear interval when we shut down TF2 in case the GC connection is never established
		if(self.haveGCSession) {
			clearInterval(interval);
			return;
		}

		self._send(Language.ClientHello, base_gcmessages.CMsgClientHello, {});
	}, 5000);
};

TeamFortress2.prototype._send = function(type, protobuf, body) {
	var msgName = type;
	for(var i in Language) {
		if(Language[i] == type) {
			msgName = i;
			break;
		}
	}

	this.emit('debug', "Sending GC message " + msgName);

	if(protobuf) {
		this._steam.toGC(440, type | protomask, protobuf.serialize(body));
	} else {
		this._steam.toGC(440, type, body);
	}
};

TeamFortress2.prototype.setLang = function(langFile) {
	var lang = vdf.parse(langFile);
	// The vdf parser appears to add some random characters and quotes to the root 'lang' key, so we'll just use a loop to find it
	for(var i in lang) {
		this.lang = lang[i].Tokens;
	}
};

TeamFortress2.prototype.craft = function(items, recipe) {
	var buffer = new Buffer(2 + 2 + (8 * items.length));
	buffer.writeInt16LE(recipe || -2, 0); // -2 is wildcard
	buffer.writeInt16LE(items.length, 2);
	for(var i = 0; i < items.length; i++) {
		buffer.writeUInt64LE(items[i], 4 + (i * 8));
	}

	this._send(Language.Craft, null, buffer);
};

TeamFortress2.prototype.trade = function(steamID) {
	var buffer = new Buffer(12);
	buffer.writeUInt32LE(0, 0);
	buffer.writeUInt64LE(steamID, 4);
	this._send(Language.Trading_InitiateTradeRequest, null, buffer);
};

TeamFortress2.prototype.setStyle = function(item, style) {
	var buffer = new Buffer(12);
	buffer.writeUInt64LE(item, 0);
	buffer.writeUInt32LE(style, 8);
	this._send(Language.SetItemStyle, null, buffer);
};

TeamFortress2.prototype.setPosition = function(item, position) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(item, 0);
	buffer.writeUInt64LE(position, 8);
	this._send(Language.SetSingleItemPosition, null, buffer);
};

TeamFortress2.prototype.setPositions = function(items) {
	this._send(Language.SetItemPositions, base_gcmessages.CMsgSetItemPositions, {"itemPositions": items});
};

TeamFortress2.prototype.deleteItem = function(item) {
	var buffer = new Buffer(8);
	buffer.writeUInt64LE(item);
	this._send(Language.Delete, null, buffer);
};

TeamFortress2.prototype.wrapItem = function(wrapID, itemID) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(wrapID, 0);
	buffer.writeUInt64LE(itemID, 8);
	this._send(Language.GiftWrapItem, null, buffer);
};

TeamFortress2.prototype.deliverGift = function(gift, steamID) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(gift, 0);
	buffer.writeUInt64LE(steamID, 8);
	this._send(Language.DeliverGift, null, buffer);
};

TeamFortress2.prototype.unwrapGift = function(gift) {
	var buffer = new Buffer(8);
	buffer.writeUInt64LE(gift);
	this._send(Language.UnwrapGiftRequest, null, buffer);
};

TeamFortress2.prototype.useItem = function(item) {
	this._send(Language.UseItemRequest, base_gcmessages.CMsgUseItem, {"itemId": item});
};

TeamFortress2.prototype.sortBackpack = function(sortType) {
	this._send(Language.SortItems, base_gcmessages.CMsgSortItems, {"sortType": sortType});
};

TeamFortress2.prototype.sendProfessorSpeks = function(steamID) {
	this._send(Language.FreeTrial_ChooseMostHelpfulFriend, tf_gcmessages.CMsgTFFreeTrialChooseMostHelpfulFriend, {"accountIdFriend": new SteamID(steamID).accountid});
};

TeamFortress2.prototype.createServerIdentity = function() {
	this._send(Language.GameServer_CreateIdentity, tf_gcmessages.CMsgGC_GameServer_CreateIdentity, {"accountId": new SteamID(this._steam.steamID).accountid});
};

TeamFortress2.prototype.getRegisteredServers = function() {
	this._send(Language.GameServer_List, tf_gcmessages.CMsgGC_GameServer_List, {"accountId": new SteamID(this._steam.steamID).accountid});
};

TeamFortress2.prototype.resetServerIdentity = function(id) {
	this._send(Language.GameServer_ResetIdentity, tf_gcmessages.CMsgGC_GameServer_ResetIdentity, {"gameServerAccountId": id});
};

TeamFortress2.prototype._handlers = {};

require('./enums.js');
require('./handlers.js');<commit_msg>Stop sending ClientHello if TF2 is "quit" before we get ClientWelcome<commit_after>var vdf = require('vdf');
var fs = require('fs');
var SteamID = require('steamid');

var protomask = 0x80000000;

var Language = require(__dirname + '/language.js');
var Protos = require(__dirname + '/protos.js');

var base_gcmessages = Protos.base_gcmessages;
var tf_gcmessages = Protos.tf_gcmessages;

module.exports = TeamFortress2;

require('util').inherits(TeamFortress2, require('events').EventEmitter);

function TeamFortress2(steam) {
	this._steam = steam;
	this.haveGCSession = false;

	var self = this;

	// "extend" the default steam.gamesPlayed function so we can catch when TF2 starts up
	var gamesPlayed = steam.gamesPlayed;
	steam.gamesPlayed = function(appids) {
		if(appids.indexOf(440) != -1 && !self.haveGCSession) {
			self._connect();
		} else if(self._helloInterval) {
			clearInterval(self._helloInterval);
			self._helloInterval = null;
		}

		gamesPlayed.call(steam, appids);
	};

	steam.on('fromGC', function(appID, type, body) {
		if(appID != 440) {
			// Not from the TF2 GC
			return;
		}

		var protobuf = !!(type & protomask);
		type &= ~protomask;

		if(self._handlers[type]) {
			self._handlers[type].call(self, body);
		} else {
			var msgName = type;
			for(var i in Language) {
				if(Language[i] == type) {
					msgName = i;
					break;
				}
			}

			self.emit('debug', "Got unhandled GC message " + msgName + (protobuf ? " (protobuf)" : ""));
		}
	});
}

TeamFortress2.prototype._connect = function() {
	var self = this;
	this._helloInterval = setInterval(function() {
		if(self.haveGCSession) {
			clearInterval(self._helloInterval);
			self._helloInterval = null;
			return;
		}

		self._send(Language.ClientHello, base_gcmessages.CMsgClientHello, {});
	}, 2000);
};

TeamFortress2.prototype._send = function(type, protobuf, body) {
	var msgName = type;
	for(var i in Language) {
		if(Language[i] == type) {
			msgName = i;
			break;
		}
	}

	this.emit('debug', "Sending GC message " + msgName);

	if(protobuf) {
		this._steam.toGC(440, type | protomask, protobuf.serialize(body));
	} else {
		this._steam.toGC(440, type, body);
	}
};

TeamFortress2.prototype.setLang = function(langFile) {
	var lang = vdf.parse(langFile);
	// The vdf parser appears to add some random characters and quotes to the root 'lang' key, so we'll just use a loop to find it
	for(var i in lang) {
		this.lang = lang[i].Tokens;
	}
};

TeamFortress2.prototype.craft = function(items, recipe) {
	var buffer = new Buffer(2 + 2 + (8 * items.length));
	buffer.writeInt16LE(recipe || -2, 0); // -2 is wildcard
	buffer.writeInt16LE(items.length, 2);
	for(var i = 0; i < items.length; i++) {
		buffer.writeUInt64LE(items[i], 4 + (i * 8));
	}

	this._send(Language.Craft, null, buffer);
};

TeamFortress2.prototype.trade = function(steamID) {
	var buffer = new Buffer(12);
	buffer.writeUInt32LE(0, 0);
	buffer.writeUInt64LE(steamID, 4);
	this._send(Language.Trading_InitiateTradeRequest, null, buffer);
};

TeamFortress2.prototype.setStyle = function(item, style) {
	var buffer = new Buffer(12);
	buffer.writeUInt64LE(item, 0);
	buffer.writeUInt32LE(style, 8);
	this._send(Language.SetItemStyle, null, buffer);
};

TeamFortress2.prototype.setPosition = function(item, position) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(item, 0);
	buffer.writeUInt64LE(position, 8);
	this._send(Language.SetSingleItemPosition, null, buffer);
};

TeamFortress2.prototype.setPositions = function(items) {
	this._send(Language.SetItemPositions, base_gcmessages.CMsgSetItemPositions, {"itemPositions": items});
};

TeamFortress2.prototype.deleteItem = function(item) {
	var buffer = new Buffer(8);
	buffer.writeUInt64LE(item);
	this._send(Language.Delete, null, buffer);
};

TeamFortress2.prototype.wrapItem = function(wrapID, itemID) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(wrapID, 0);
	buffer.writeUInt64LE(itemID, 8);
	this._send(Language.GiftWrapItem, null, buffer);
};

TeamFortress2.prototype.deliverGift = function(gift, steamID) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(gift, 0);
	buffer.writeUInt64LE(steamID, 8);
	this._send(Language.DeliverGift, null, buffer);
};

TeamFortress2.prototype.unwrapGift = function(gift) {
	var buffer = new Buffer(8);
	buffer.writeUInt64LE(gift);
	this._send(Language.UnwrapGiftRequest, null, buffer);
};

TeamFortress2.prototype.useItem = function(item) {
	this._send(Language.UseItemRequest, base_gcmessages.CMsgUseItem, {"itemId": item});
};

TeamFortress2.prototype.sortBackpack = function(sortType) {
	this._send(Language.SortItems, base_gcmessages.CMsgSortItems, {"sortType": sortType});
};

TeamFortress2.prototype.sendProfessorSpeks = function(steamID) {
	this._send(Language.FreeTrial_ChooseMostHelpfulFriend, tf_gcmessages.CMsgTFFreeTrialChooseMostHelpfulFriend, {"accountIdFriend": new SteamID(steamID).accountid});
};

TeamFortress2.prototype.createServerIdentity = function() {
	this._send(Language.GameServer_CreateIdentity, tf_gcmessages.CMsgGC_GameServer_CreateIdentity, {"accountId": new SteamID(this._steam.steamID).accountid});
};

TeamFortress2.prototype.getRegisteredServers = function() {
	this._send(Language.GameServer_List, tf_gcmessages.CMsgGC_GameServer_List, {"accountId": new SteamID(this._steam.steamID).accountid});
};

TeamFortress2.prototype.resetServerIdentity = function(id) {
	this._send(Language.GameServer_ResetIdentity, tf_gcmessages.CMsgGC_GameServer_ResetIdentity, {"gameServerAccountId": id});
};

TeamFortress2.prototype._handlers = {};

require('./enums.js');
require('./handlers.js');<|endoftext|>


<commit_before>/*
* @Author: Matteo
* @Date:   2016-04-19 06:39:17
* @Last Modified by:   Matteo Zambon
* @Last Modified time: 2016-04-19 07:13:43
*/

var camelCase = require("camelcase");
var decamelize = require("decamelize");
var isArray = require("is-array");

exports.camelize = function(object) {

	function camelizeObject(object)
	{
		if(isArray(object))
		{
			var newObject = [];

			for(var k in object)
			{
				if(typeof object[k] == "object")
				{
					newObject.push(camelizeObject(object[k]));
				}
				else
				{
					newObject.push(object[k]);
				}
			}
		}
		else
		{
			var newObject = {};

			for(var k in object)
			{
				var newK = camelCase(k);
				newObject[newK] = object[k];

				if(typeof newObject[newK] == "object")
				{
					newObject[newK] = camelizeObject(newObject[newK]);
				}
			}
		}

		return newObject;
	}

	return camelizeObject(object);
};

exports.decamelize = function(object, separator) {
	function decamelizeObject(object, separator)
	{
		if(isArray(object))
		{
			var newObject = [];

			for(var k in object)
			{
				if(typeof object[k] == "object")
				{
					newObject.push(decamelizeObject(object[k]));
				}
				else
				{
					newObject.push(object[k]);
				}
			}
		}
		else
		{
			var newObject = {};

			for(var k in object)
			{
				var newK = decamelize(k, separator);
				newObject[newK] = object[k];

				if(typeof newObject[newK] == "object")
				{
					newObject[newK] = decamelizeObject(newObject[newK]);
				}
			}
		}

		return newObject;
	}

	separator = typeof separator == "undefined" ? "_" : separator == null ? "_" : separator;

	return decamelizeObject(object, separator);
};
<commit_msg>Handled Null<commit_after>/*
* @Author: Matteo
* @Date:   2016-04-19 06:39:17
* @Last Modified by:   Matteo Zambon
* @Last Modified time: 2016-04-19 07:13:43
*/

var camelCase = require("camelcase");
var decamelize = require("decamelize");
var isArray = require("is-array");

exports.camelize = function(object) {

	function camelizeObject(object)
	{
		if(isArray(object))
		{
			var newObject = [];

			for(var k in object)
			{
				if(typeof object[k] == "object" && object[k])
				{
					newObject.push(camelizeObject(object[k]));
				}
				else
				{
					newObject.push(object[k]);
				}
			}
		}
		else
		{
			var newObject = {};

			for(var k in object)
			{
				var newK = camelCase(k);
				newObject[newK] = object[k];

				if(typeof newObject[newK] == "object" && newObject[newK])
				{
					newObject[newK] = camelizeObject(newObject[newK]);
				}
			}
		}

		return newObject;
	}

	return camelizeObject(object);
};

exports.decamelize = function(object, separator) {
	function decamelizeObject(object, separator)
	{
		if(isArray(object))
		{
			var newObject = [];

			for(var k in object)
			{
				if(typeof object[k] == "object" && object[k])
				{
					newObject.push(decamelizeObject(object[k]));
				}
				else
				{
					newObject.push(object[k]);
				}
			}
		}
		else
		{
			var newObject = {};

			for(var k in object)
			{
				var newK = decamelize(k, separator);
				newObject[newK] = object[k];

				if(typeof newObject[newK] == "object" && newObject[newK])
				{
					newObject[newK] = decamelizeObject(newObject[newK]);
				}
			}
		}

		return newObject;
	}

	separator = typeof separator == "undefined" ? "_" : separator == null ? "_" : separator;

	return decamelizeObject(object, separator);
};
<|endoftext|>


<commit_before>var url = require("url"),
  crypto = require("crypto");

var signGMapsURL = function(urlToSign, webSafeKey) {
  var b64Key = fromWebSafeBase64(webSafeKey);
  var path = url.parse(urlToSign).path;
  var hmac = crypto.createHmac("sha1", new Buffer(b64Key, "base64"));
  hmac.update(path);
  return urlToSign + "&signature=" + toWebSafeBase64(hmac.digest("base64"));
};

function toWebSafeBase64(b64) {
  return b64.replace("+", "-").replace("/", "_");
}

function fromWebSafeBase64(b64) {
  return b64.replace("-", "+").replace("_", "/");
}

module.exports = signGMapsURL;
<commit_msg>Replace all the occurences of web-unsafe and web-safe characters in base64 functions<commit_after>var url = require("url"),
  crypto = require("crypto");

var signGMapsURL = function(urlToSign, webSafeKey) {
  var b64Key = fromWebSafeBase64(webSafeKey);
  var path = url.parse(urlToSign).path;
  var hmac = crypto.createHmac("sha1", new Buffer(b64Key, "base64"));
  hmac.update(path);
  return urlToSign + "&signature=" + toWebSafeBase64(hmac.digest("base64"));
};

function toWebSafeBase64(b64) {
  return b64.replace(new RegExp("\\+", "g"), "-").replace(new RegExp("/", "g"), "_");
}

function fromWebSafeBase64(b64) {
  return b64.replace(new RegExp("-", "g"), "+").replace(new RegExp("_", "g"), "/");
}

module.exports = signGMapsURL;
<|endoftext|>


<commit_before>var moment = require('moment');

module.exports = function(scope){
    scope.date = function(scope, args){
        var all = args.all();
        return moment(all)._d;
    };

    function createMomentFunction(key){
        return function(scope, args){
            var all = args.all(),
                momentDate = moment(all.shift()),
                result = momentDate[key].apply(momentDate, all);

            return moment.isMoment(result) ? result._d : result;
        };
    }

    for(var key in moment.fn){
        if(
            typeof moment.fn[key] !== 'function' ||
            key === 'valueOf' ||
            key === 'toString'
        ){
            continue;
        }

        scope.date[key] = createMomentFunction(key);
    }
}

<commit_msg>Added memoisation<commit_after>var moment = require('moment');

function memoise(){

}

module.exports = function(scope){
    scope.date = function(scope, args){
        var all = args.all();
        return moment(all)._d;
    };

    function createMomentFunction(key){
        var fn = function(scope, args){
            var all = args.all(),
                dateArg = all.shift(),
                momentDate;

            if(fn._memoisedDates[''+dateArg]){
                momentDate = fn._memoisedDates[''+dateArg].clone();
            }else{
                momentDate = fn._memoisedDates[''+dateArg] = moment(dateArg);
            }

            var result = momentDate[key].apply(momentDate, all);

            return moment.isMoment(result) ? result._d : result;
        };

        fn._memoisedDates = {};

        return fn;
    }

    for(var key in moment.fn){
        if(
            typeof moment.fn[key] !== 'function' ||
            key === 'valueOf' ||
            key === 'toString'
        ){
            continue;
        }

        scope.date[key] = createMomentFunction(key);
    }
}

<|endoftext|>


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

var isBuffer = Buffer.isBuffer

/*
always do aligned reads,
to a given block size.
keep the read blocks in a sparse array.

have a fixed cache size, and prune least recently used items.
successful writes should also go into the cache immediately.
*/

function frame (data, _offset) {
  var length = data.reduce(function (total, e) { return total + e.value.length }, 0)
  var b = new Buffer(length + data.length * 8)
  var offset = 0
  for(var i = 0; i < data.length; i++) {
    var item = data[i]
    //mutate the items
    var buf = item.value
    item.offset = 0 + offset + _offset
    b.writeUInt32BE(buf.length, 0 + offset) //start
    b.writeUInt32BE(buf.length, 4+buf.length + offset) //end
    item.value.copy(b, 4 + offset, 0, buf.length)
    offset += buf.length + 8
  }
  return b
}

module.exports = function (file, length) {
  length = length || 1024
  var fd
  if(Number.isInteger(file))
    fd = file
  else
    fd = fs.openSync(file, 'a+')

  var queue = [], writing = false
  //TODO: check current size of file!
  var offset = 0

  function write () {
    if(writing) return
    if(!queue.length) return
    writing = true
    var data = []
    var framed = frame(queue, offset)
    var _queue = queue
    queue = []
    fs.write(fd, framed, 0, framed.length, function (err, bytes) {
      writing = false

      offset = offset += bytes
      //empty the queue
      for(var i = 0; i < _queue.length; i++) {
        _queue[i].cb(err, _queue[i].offset)
      }

      if(queue.length) write()
    })
  }

  return {
    createLogStream: function (opts) {
      //create a stream between any two records.
      //read the first value, then scan forward or backwards
      //in the direction of the log
    },
    //if value is an array of buffers, then treat that as a batch.
    append: function (value, cb) {
      if(!isBuffer(value)) throw new Error('value must be a buffer')
      queue.push({value: value, cb: cb})
      write()
    },
    get: function (offset, cb) {
      //read the block that offset is in.
      //if offset is near the end of the block, read two blocks.
      var b = new Buffer(length)
      fs.read(fd, b, 0, b.length, offset, function (err, bytes_read) {
        if(err) return cb(err)
        //read the record length.
        //if we have the entire length already,
        //callback with the value.
        //else read the rest of the blocks necessary.
        var len = b.readUInt32BE(0)

        //check if we have the entire object already.
        if(len  < (length - 4) )
          return cb(null, b.slice(4, len+4))
        else {
          var b2 = new Buffer(len)

          fs.read(fd, b2, length - 4, b2.length - (length - 4), offset + b.length, function (err) {
            if(err) return cb(err)

            //copy the first read into the second buffer.
            b.copy(b2, 0, 4, length)
            cb(null, b2.slice(0, len+4))
          })
        }
      })
    }
  }
}

<commit_msg>streams<commit_after>var fs = require('fs')

var isBuffer = Buffer.isBuffer
var Notify = require('pull-notify')
var Live = require('pull-live')

/*
TODO: always do aligned reads,
to a given block size.
keep the read blocks in a sparse array.

have a fixed cache size, and prune least recently used items.
successful writes should also go into the cache immediately.
*/

function frame (data, _offset) {
  var length = data.reduce(function (total, e) { return total + e.value.length }, 0)
  var b = new Buffer(length + data.length * 8)
  var offset = 0
  for(var i = 0; i < data.length; i++) {
    var item = data[i]
    //mutate the items
    var buf = item.value
    item.offset = 0 + offset + _offset
    b.writeUInt32BE(buf.length, 0 + offset) //start
    b.writeUInt32BE(buf.length, 4+buf.length + offset) //end
    item.value.copy(b, 4 + offset, 0, buf.length)
    offset += buf.length + 8
  }
  return b
}

module.exports = function (file, length) {

  var notify = Notify()
  length = length || 1024
  var fd
  if(Number.isInteger(file))
    fd = file
  else
    fd = fs.openSync(file, 'a+')

  var queue = [], writing = false
  //TODO: check current size of file!
  var offset = 0

  function write () {
    if(writing) return
    if(!queue.length) return
    writing = true
    var data = []
    var framed = frame(queue, offset)
    var _queue = queue
    queue = []
    fs.write(fd, framed, 0, framed.length, function (err, bytes) {
      writing = false

      offset = offset += bytes
      //empty the queue
      for(var i = 0; i < _queue.length; i++) {
        _queue[i].cb(err, _queue[i].offset)
      }

      if(queue.length) write()
    })
  }

  var log
  return log = {
    //create a stream between any two records.
    //read the first value, then scan forward or backwards
    //in the direction of the log
    stream: Live(function (opts) {
      var reverse = opts && opts.reverse
      var next = reverse ? (opts && opts.max || offset) : (opts && opts.min || 0)
      var diff = reverse ? -1 : 1
      var get = reverse ? log.getPrevious : log.get

      return function (abort, cb) {
        if(abort) cb(abort)
        else if(reverse && next <= 0)
          cb(true)
        else
          get(next, function (err, value) {
            if(err) return cb(err)
            if(!value) return cb(true)
            next = next + (value.length + 8)*diff
            cb(null, value)
          })
      }
    }, function (opts) {
      return notify.listen()
    }),
    //if value is an array of buffers, then treat that as a batch.
    append: function (value, cb) {
      if(!isBuffer(value)) throw new Error('value must be a buffer')
      queue.push({value: value, cb: function (err, offset) {
        if(err) return cb(err)
        notify(value)
        cb(null, offset)
      }})
      write()
    },
    get: function (offset, cb) {
      //read the block that offset is in.
      //if offset is near the end of the block, read two blocks.
      var b = new Buffer(length)
      fs.read(fd, b, 0, b.length, offset, function (err, bytes_read) {
        if(err) return cb(err)
        //read the record length.
        //if we have the entire length already,
        //callback with the value.
        //else read the rest of the blocks necessary.
        var len = b.readUInt32BE(0)

        //check if we have the entire object already.
        if(bytes_read == 0)
          cb()
        else if(len  < (length - 4) )
          return cb(null, b.slice(4, len+4))
        else {
          var b2 = new Buffer(len)

          fs.read(fd, b2, length - 4, b2.length - (length - 4), offset + b.length, function (err) {
            if(err) return cb(err)
            //copy the first read into the second buffer.
            b.copy(b2, 0, 4, length)
            cb(null, b2.slice(0, len+4))
          })
        }
      })
    },
    //get the record _before_ the given offset.
    getPrevious: function (_offset, cb) {
      //don't read before start of file...
      var b = new Buffer(Math.min(length, _offset))
      fs.read(fd, b, 0, b.length, _offset - b.length, function (err, bytes_read) {
        if(err) return cb(err)
        var len = b.readUInt32BE(b.length - 4)
        if(len <= (b.length -  4)) {
          return cb(null, b.slice(b.length - len - 4, b.length - 4))
        }
        else {
          var o = _offset - 4 - len
          var b2 = new Buffer(len)
          fs.read(fd, b2, 0, b2.length, o, function (err) {
            if(err) cb(err)
            else cb(null, b2)
          })
        }
      })
    },
  }
}

<|endoftext|>


<commit_before>//var currentlyClicked = null;

var allMarkers = [];

var map = new L.Map('map', {
        center: [43.1850, -77.6115],
        zoom: 12,
        layers: [
            new L.TileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png', {
                attribution: 'Tiles Courtesy of MapQuest — Map data © OpenStreetMap contributors',
                maxZoom: 18,
                subdomains: '1234'
            })
        ]
});

var sidebar = L.control.sidebar('sidebar', {
    position: 'left'
});

map.addControl(sidebar);

function init(){

    //var marker = L.marker([43.1556, -77.6115]).addTo(map);
    //var start_date = '2013-11-18';
   /* var end_date = '2013-11-25';
    var event_ids = '98,99,100,103,104,149';
    var latitude_large = '43.20333823191608'
    var latitude_small = '43.11869245034604';
    var longitude_large = '-77.54431728574195';
    var longitude_small = '-77.67752651425758';

    var queryString = 'https://www.crimereports.com/services/crimedata/crime_list.html/'+start_date+'/'+ end_date+'/'+ event_ids + '/' + latitude_large + '/' + latitude_small + '/' + longitude_large + '/' + longitude_small + '/?limit=false';

    //console.log(queryString);
    loadData(queryString);*/
    plotNeighborhoods();
    loadData();
}

function loadData(){

        var url = "crimeData2.json";

        $.ajax({
			dataType: "json",
			url: url,
			success: function(success){
				handleGeoData(success);
			},
			type: "GET"
		});

}

function handleGeoData(response){
        // for each incident, place a marker on the map
        var n;
        var coords;
        for(n=0; n<response.length; n++)
        {
            //var myLat = parseFloat(response[n].lat);
            //var lng = parseFloat(response[n].lng);
            var identifier = response[n].Identifier;
            var address = response[n].Address + "Rochester, NY";
            address = encodeURIComponent(address);
            var query = "http://maps.googleapis.com/maps/api/geocode/json?address=" + address + "&sensor=true";

            $.ajax({
            	id: identifier,
				dataType: "json",
				url: query,
				success: function(success){
					coords = getlatlong(success);
					plotCrime(coords,this.id);
				},
				type: "GET"
			});
        }
}

function plotCrime(coords,crimeID){
	var marker = L.marker([coords[0], coords[1]]).addTo(map).on('click',function(){
		generateCrimeData(marker.myId,coords);
		for(var i=0; i< allMarkers.length; i++){
			allMarkers[i].setIcon(markerIcon);
		}
		marker.setIcon(highlightedIcon);
		/*currentlyClicked = marker;

			if(currentlyClicked. == null){
				console.log("The currently clicked marker: " + currentlyClicked);
			}else{
				currentlyClicked.setIcon(markerIcon);
				console.log("Resetting to the default icon.");
			}*/
	});
	marker.myId = crimeID;

	allMarkers.push(marker);

}

function generateCrimeData(crimeID,coords){
	console.log("incoming id:"+crimeID);
	 var url = "crimeData2.json";

     $.ajax({
     	streetCoords: coords,
		dataType: "json",
		url: url,
		success: function(response){
			var n;
			for(n=0;n<response.length;n++){
				var id = response[n].Identifier;
				//console.log(id);
				if(id == crimeID){
					console.log(crimeID);
					var address = response[n].Address;
					address = address.replace("Block","");
					var agency = response[n].Agency;
					var type = response[n].CrimeType;
					var time = response[n].DateTime;
					var description = response[n].Description;

					var string = '
'+address+'
';
					string += '
'+agency+'
';
					string += '
'+type+'
';
					string += '
Date and Time:'+time+'
';
					string += '
'+description+'
';
					string += '';

					sidebar.setContent(string);
					break;

				}else{

				}
			}
		},
		type: "GET"
		});

	sidebar.toggle();
}

function plotNeighborhoods(){
	var shpfile = new L.Shapefile('Neighborhoods.zip',{onEachFeature:function(feature, layer) {
    	console.log(layer);
	}});
         shpfile.addTo(map);
}

function getlatlong(response){
	var coords = [];
	var myLat = response.results[0].geometry.location.lat;
	coords.push(myLat);
	var myLng = response.results[0].geometry.location.lng;
	coords.push(myLng);

	return coords;
}

<commit_msg>Marker now deselects when you close the sidebar<commit_after>//var currentlyClicked = null;

$( document ).ready(function() {
	$( ".close" ).click(function() {
		for(var i=0; i<allMarkers.length;i++){
			allMarkers[i].setIcon(markerIcon);
		}
	});
});

var allMarkers = [];

var map = new L.Map('map', {
        center: [43.1850, -77.6115],
        zoom: 12,
        layers: [
            new L.TileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png', {
                attribution: 'Tiles Courtesy of MapQuest — Map data © OpenStreetMap contributors',
                maxZoom: 18,
                subdomains: '1234'
            })
        ]
});

var sidebar = L.control.sidebar('sidebar', {
    position: 'left'
});

map.addControl(sidebar);

function init(){

    //var marker = L.marker([43.1556, -77.6115]).addTo(map);
    //var start_date = '2013-11-18';
   /* var end_date = '2013-11-25';
    var event_ids = '98,99,100,103,104,149';
    var latitude_large = '43.20333823191608'
    var latitude_small = '43.11869245034604';
    var longitude_large = '-77.54431728574195';
    var longitude_small = '-77.67752651425758';

    var queryString = 'https://www.crimereports.com/services/crimedata/crime_list.html/'+start_date+'/'+ end_date+'/'+ event_ids + '/' + latitude_large + '/' + latitude_small + '/' + longitude_large + '/' + longitude_small + '/?limit=false';

    //console.log(queryString);
    loadData(queryString);*/
    plotNeighborhoods();
    loadData();
}

function loadData(){

        var url = "crimeData2.json";

        $.ajax({
			dataType: "json",
			url: url,
			success: function(success){
				handleGeoData(success);
			},
			type: "GET"
		});

}

function handleGeoData(response){
        // for each incident, place a marker on the map
        var n;
        var coords;
        for(n=0; n<response.length; n++)
        {
            //var myLat = parseFloat(response[n].lat);
            //var lng = parseFloat(response[n].lng);
            var identifier = response[n].Identifier;
            var address = response[n].Address + "Rochester, NY";
            address = encodeURIComponent(address);
            var query = "http://maps.googleapis.com/maps/api/geocode/json?address=" + address + "&sensor=true";

            $.ajax({
            	id: identifier,
				dataType: "json",
				url: query,
				success: function(success){
					coords = getlatlong(success);
					plotCrime(coords,this.id);
				},
				type: "GET"
			});
        }
}

function plotCrime(coords,crimeID){
	var marker = L.marker([coords[0], coords[1]]).addTo(map).on('click',function(){
		generateCrimeData(marker.myId,coords);
		for(var i=0; i< allMarkers.length; i++){
			allMarkers[i].setIcon(markerIcon);
		}
		marker.setIcon(highlightedIcon);
		/*currentlyClicked = marker;

			if(currentlyClicked. == null){
				console.log("The currently clicked marker: " + currentlyClicked);
			}else{
				currentlyClicked.setIcon(markerIcon);
				console.log("Resetting to the default icon.");
			}*/
	});
	marker.myId = crimeID;

	allMarkers.push(marker);

}

function generateCrimeData(crimeID,coords){
	console.log("incoming id:"+crimeID);
	 var url = "crimeData2.json";

     $.ajax({
     	streetCoords: coords,
		dataType: "json",
		url: url,
		success: function(response){
			var n;
			for(n=0;n<response.length;n++){
				var id = response[n].Identifier;
				//console.log(id);
				if(id == crimeID){
					console.log(crimeID);
					var address = response[n].Address;
					address = address.replace("Block","");
					var agency = response[n].Agency;
					var type = response[n].CrimeType;
					var time = response[n].DateTime;
					var description = response[n].Description;

					var string = '
'+address+'
';
					string += '
'+agency+'
';
					string += '
'+type+'
';
					string += '
Date and Time:'+time+'
';
					string += '
'+description+'
';
					string += '';

					sidebar.setContent(string);
					break;

				}else{

				}
			}
		},
		type: "GET"
		});

	sidebar.toggle();
}

function plotNeighborhoods(){
	var shpfile = new L.Shapefile('Neighborhoods.zip',{onEachFeature:function(feature, layer) {
    	console.log(layer);
	}});
         shpfile.addTo(map);
}

function getlatlong(response){
	var coords = [];
	var myLat = response.results[0].geometry.location.lat;
	coords.push(myLat);
	var myLng = response.results[0].geometry.location.lng;
	coords.push(myLng);

	return coords;
}

<|endoftext|>