<commit_before>const log4js = require('log4js');
const reqLogger = require('./request-logger');

/**
 *
 * @param {{ config: string; request: any; }} options
 * @param {{ hub: any; }} imports
 * @param  {(arg0: null, arg1: { onDestroy: () => void; log: typeof log4js; }) => void}  register
 */
module.exports = function (options, imports, register) {
    let hub = imports.hub;
    let config = JSON.parse(JSON.stringify(options.config));

    let fileDateAppenders = Object.keys(config.appenders).filter((a) => config.appenders[a] && config.appenders[a].type === 'dateFile');

    fileDateAppenders.forEach((appenderName) => {
        // ensure defaults
        let appender = config.appenders[appenderName];
        if (appender) {
            appender.pattern = appender.pattern || 'yyyy-MM-dd'
            appender.encoding = appender.encoding || 'utf8';
            appender.mode = appender.mode || '0o644';
            appender.numBackups = appender.numBackups || 90;
            appender.compress = appender.hasOwnProperty('compress') ? appender.compress : true;
            appender.keepFileExt = appender.hasOwnProperty('keepFileExt') ? appender.keepFileExt : true;
            appender.alwaysIncludePattern = appender.hasOwnProperty('alwaysIncludePattern') ? appender.alwaysIncludePattern : false;
            // appender.fileNameSep = appender.fileNameSep || '.';
        }
    });

    log4js.configure(config);
    log4js.requestLogger = reqLogger(options.request || {}, log4js);

    let logger = log4js.getLogger('app');

    if (hub) {
        hub.on('log.error', logger.error.bind(logger));
        hub.on('log.info', logger.info.bind(logger));
    }

    register(null, {
        onDestroy: function destroy() {
            log4js.shutdown(function () {//flush on destroy
                //flushed
            });
        },
        log: log4js
    });
};

module.exports.provides = ['log'];
module.exports.consumes = ['hub'];
<commit_msg>fix default mode value<commit_after>const log4js = require('log4js');
const reqLogger = require('./request-logger');

/**
 *
 * @param {{ config: string; request: any; }} options
 * @param {{ hub: any; }} imports
 * @param  {(arg0: null, arg1: { onDestroy: () => void; log: typeof log4js; }) => void}  register
 */
module.exports = function (options, imports, register) {
    let hub = imports.hub;
    let config = JSON.parse(JSON.stringify(options.config));

    let fileDateAppenders = Object.keys(config.appenders).filter((a) => config.appenders[a] && config.appenders[a].type === 'dateFile');

    fileDateAppenders.forEach((appenderName) => {
        // ensure defaults
        let appender = config.appenders[appenderName];
        if (appender) {
            appender.pattern = appender.pattern || 'yyyy-MM-dd'
            appender.encoding = appender.encoding || 'utf8';
            appender.mode = appender.mode || 0o644;
            appender.numBackups = appender.numBackups || 90;
            appender.compress = appender.hasOwnProperty('compress') ? appender.compress : true;
            appender.keepFileExt = appender.hasOwnProperty('keepFileExt') ? appender.keepFileExt : true;
            appender.alwaysIncludePattern = appender.hasOwnProperty('alwaysIncludePattern') ? appender.alwaysIncludePattern : false;
            // appender.fileNameSep = appender.fileNameSep || '.';
        }
    });

    log4js.configure(config);
    log4js.requestLogger = reqLogger(options.request || {}, log4js);

    let logger = log4js.getLogger('app');

    if (hub) {
        hub.on('log.error', logger.error.bind(logger));
        hub.on('log.info', logger.info.bind(logger));
    }

    register(null, {
        onDestroy: function destroy() {
            log4js.shutdown(function () {//flush on destroy
                //flushed
            });
        },
        log: log4js
    });
};

module.exports.provides = ['log'];
module.exports.consumes = ['hub'];
<|endoftext|>


<commit_before>const adapter = require('./node/index.js')
const circularize = require('./common/circularize.js')
const TesseractJob = require('./common/job');
const version = require('../package.json').version;

function create(workerOptions = {}){
	return new TesseractWorker(Object.assign({}, adapter.defaultOptions, workerOptions, {create, version}));
}

class TesseractWorker {
	constructor(workerOptions){
		this.worker = null;
		this.workerOptions = workerOptions;
		this._currentJob = null;
		this._queue = [];
	}

	recognize(image, options = {}){
		return this._delay(job => {
			options.lang = options.lang || 'eng';

			job._send('recognize', { image, options, workerOptions: this.workerOptions });
		})
	}
	detect(image, options = {}){
		return this._delay(job => {
			job._send('detect', { image, options, workerOptions: this.workerOptions });
		})
	}

	terminate(){
		if(this.worker) adapter.terminateWorker(this);
		this.worker = null;
	}

	_delay(fn){
		if(!this.worker) this.worker = adapter.spawnWorker(this, this.workerOptions);

		var job = new TesseractJob(this);
		this._queue.push(e => {
			this._queue.shift();
			this._currentJob = job;
			fn(job);
		});
		if(!this._currentJob) this._dequeue();
		return job;
	}

	_dequeue(){
		this._currentJob = null;
		if(this._queue.length){
			this._queue[0]();
		}
	}

	_recv(packet){
        if(packet.status === 'resolve' && packet.action === 'recognize'){
            packet.data = circularize(packet.data);
        }

		if(this._currentJob.id === packet.jobId){
			this._currentJob._handle(packet)
		} else {
			console.warn('Job ID ' + packet.jobId + ' not known.')
		}
	}
}

module.exports = create();<commit_msg>add back lang string as a valid option<commit_after>const adapter = require('./node/index.js')
const circularize = require('./common/circularize.js')
const TesseractJob = require('./common/job');
const version = require('../package.json').version;

function create(workerOptions = {}){
	return new TesseractWorker(Object.assign({}, adapter.defaultOptions, workerOptions, {create, version}));
}

class TesseractWorker {
	constructor(workerOptions){
		this.worker = null;
		this.workerOptions = workerOptions;
		this._currentJob = null;
		this._queue = [];
	}

	recognize(image, options = {}){
		return this._delay(job => {
			if (typeof options === 'string') options = {lang: options}
			options.lang = options.lang || 'eng';

			job._send('recognize', { image, options, workerOptions: this.workerOptions });
		})
	}
	detect(image, options = {}){
		return this._delay(job => {
			job._send('detect', { image, options, workerOptions: this.workerOptions });
		})
	}

	terminate(){
		if(this.worker) adapter.terminateWorker(this);
		this.worker = null;
	}

	_delay(fn){
		if(!this.worker) this.worker = adapter.spawnWorker(this, this.workerOptions);

		var job = new TesseractJob(this);
		this._queue.push(e => {
			this._queue.shift();
			this._currentJob = job;
			fn(job);
		});
		if(!this._currentJob) this._dequeue();
		return job;
	}

	_dequeue(){
		this._currentJob = null;
		if(this._queue.length){
			this._queue[0]();
		}
	}

	_recv(packet){
        if(packet.status === 'resolve' && packet.action === 'recognize'){
            packet.data = circularize(packet.data);
        }

		if(this._currentJob.id === packet.jobId){
			this._currentJob._handle(packet)
		} else {
			console.warn('Job ID ' + packet.jobId + ' not known.')
		}
	}
}

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


<commit_before>import createLogger from './logger'

export default createLogger()
export { default as middleware } from './middleware'
<commit_msg>Export middleware correctly.<commit_after>import createLogger from './logger'
import middleware from './middleware'

const rootLogger = createLogger()
rootLogger.middleware = middleware
export default rootLogger
<|endoftext|>


<commit_before>var Canvas = require('canvas');
var express = require('express');
var fs = require('fs');

var Font = Canvas.Font;
var Image = Canvas.Image;

var app = express();

app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));

app.get('/:txt', function(request, response) {
	var text = request.params.txt;

	fs.readFile(__dirname + '/images/bg.jpg', function(err, data){
	    if (err) throw err;

	    // データをcanvasのcontextに設定
	    var img = new Image;
	    img.src = data;
	    var canvas = new Canvas(img.width, img.height);
	    var ctx = canvas.getContext('2d');
	    ctx.drawImage(img, 0, 0, img.width, img.height);

	    var textMeasure;

	    ctx.font = '45px "Rounded Mgen+ 1c"';
	    ctx.textAlign = 'center';
		ctx.fillStyle = 'rgba(255, 255, 255, 1.0)';

	    var tmpText = '';
	    var textPosY = 105;

	    for (var i = 0, len = text.length; i < len; i++) {
	    	tmpText += text[i];
	    	textMeasure = ctx.measureText(tmpText);

	    	if (textMeasure.width >= 370) {
	    		ctx.fillText(tmpText, canvas.width / 2, textPosY);

	    		tmpText = '';
	    		textPosY += 50;
	    	}
	    }

	    if (tmpText.length !== 0) {
	    	ctx.fillText(tmpText, canvas.width / 2, textPosY);
	    	tmpText = '';
	    }

	    response.send('');
	});
});

app.listen(app.get('port'), function() {
  console.log("Node app is running at localhost:" + app.get('port'));
});<commit_msg>request test<commit_after>var Canvas = require('canvas');
var express = require('express');
var fs = require('fs');

var Font = Canvas.Font;
var Image = Canvas.Image;

var app = express();

app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));

app.get('/:txt', function(request, response) {
	var text = request.params.txt;

	fs.readFile(__dirname + '/images/bg.jpg', function(err, data){
	    if (err) throw err;

	    var img = new Image;
	    img.src = data;
	    var canvas = new Canvas(img.width, img.height);
	    var ctx = canvas.getContext('2d');
	    ctx.drawImage(img, 0, 0, img.width, img.height);

	    var textMeasure;

	    ctx.font = '45px "Rounded Mgen+ 1c"';
	    ctx.textAlign = 'center';
		ctx.fillStyle = 'rgba(255, 255, 255, 1.0)';

	    var tmpText = '';
	    var textPosY = 105;

	    for (var i = 0, len = text.length; i < len; i++) {
	    	tmpText += text[i];
	    	textMeasure = ctx.measureText(tmpText);

	    	if (textMeasure.width >= 370) {
	    		ctx.fillText(tmpText, canvas.width / 2, textPosY);

	    		tmpText = '';
	    		textPosY += 50;
	    	}
	    }

	    if (tmpText.length !== 0) {
	    	ctx.fillText(tmpText, canvas.width / 2, textPosY);
	    	tmpText = '';
	    }

	    var base64 = canvas.toDataURL('image/jpeg');

	    response.set('Content-Type', 'image/jpeg');
	    response.send(base64);
	    //response.send('');
	});
});

app.listen(app.get('port'), function() {
  console.log("Node app is running at localhost:" + app.get('port'));
});<|endoftext|>


<commit_before>(function(Chart) {
  var cloneArray = function(srcAry) {
    var dstAry = [];
    var length = srcAry.length;

    for (var i = 0; i < length; i++) {
      dstAry.push(srcAry[i]);
    }
    return dstAry;
  };

  var setOriginalData = function(data) {
    data.originalData = data.datasets.map(function(dataset) {
      return cloneArray(dataset.data);
    });
  };

  // set calculated rate (xx%) to data.calculatedData
  var calculateRate = function(data) {
    var visibles = data.datasets.map(function(dataset) {
      if (!dataset._meta) return true;

      for (var i in dataset._meta) {
        return !dataset._meta[i].hidden;
      }
    });

    var datasetDataLength = 0;
    if (data && data.datasets && data.datasets[0] && data.datasets[0].data) {
      datasetDataLength = data.datasets[0].data.length;
    }
    var totals = Array.apply(null, new Array(datasetDataLength)).map(function(el, i) {
      return data.datasets.reduce(function(sum, dataset, j) {
        var key = dataset.stack;
        if (!sum[key]) sum[key] = 0;
        sum[key] += dataset.data[i] * visibles[j];

        return sum;
      }, {});
    });

    data.calculatedData = data.datasets.map(function(dataset, i) {
      return dataset.data.map(function(val, i) {
        var total = totals[i][dataset.stack];
        return val && total ? Math.round(val * 1000 / total) / 10 : 0;
      });
    });
  };

  var tooltipLabel = function(tooltipItem, data) {
    var datasetIndex = tooltipItem.datasetIndex;
    var index = tooltipItem.index;
    var datasetLabel = data.datasets[datasetIndex].label || "";
    var originalValue = data.originalData[datasetIndex][index];
    var rateValue = data.calculatedData[datasetIndex][index];

    return "" + datasetLabel + ": " + rateValue + "% (" + originalValue + ")";
  };

  var reflectData = function(srcData, datasets) {
    if (!srcData) return;

    srcData.forEach(function(data, i) {
      datasets[i].data = data;
    });
  };

  var Stacked100Plugin = {
    id: "stacked100",

    beforeInit: function(chartInstance, pluginOptions) {
      if (!pluginOptions.enable) return;

      var xAxes = chartInstance.options.scales.xAxes;
      var yAxes = chartInstance.options.scales.yAxes;
      var isVertical = chartInstance.config.type === "bar" || chartInstance.config.type === "line";

      [xAxes, yAxes].forEach(function(axes) {
        axes.forEach(function(hash) {
          hash.stacked = true;
        });
      });
      (isVertical ? yAxes : xAxes).forEach(function(hash) {
        hash.ticks.min = 0;
        hash.ticks.max = 100;
      });

      // Replace tooltips
      if (pluginOptions.hasOwnProperty("replaceTooltipLabel") && !pluginOptions.replaceTooltipLabel) return;
      chartInstance.options.tooltips.callbacks.label = tooltipLabel;
    },

    beforeDatasetsUpdate: function(chartInstance, pluginOptions) {
      if (!pluginOptions.enable) return;

      setOriginalData(chartInstance.data);
      calculateRate(chartInstance.data);
      reflectData(chartInstance.data.calculatedData, chartInstance.data.datasets);
    },

    afterDatasetsUpdate: function(chartInstance, pluginOptions) {
      if (!pluginOptions.enable) return;

      reflectData(chartInstance.data.originalData, chartInstance.data.datasets);
    }
  };

  Chart.pluginService.register(Stacked100Plugin);
}.call(this, Chart));
<commit_msg>Update index.js<commit_after>(function(Chart) {
  var cloneArray = function(srcAry) {
    var dstAry = [];
    var length = srcAry.length;

    for (var i = 0; i < length; i++) {
      dstAry.push(srcAry[i]);
    }
    return dstAry;
  };

  var setOriginalData = function(data) {
    data.originalData = data.datasets.map(function(dataset) {
      return cloneArray(dataset.data);
    });
  };

  // set calculated rate (xx%) to data.calculatedData
  var calculateRate = function(data) {
    var visibles = data.datasets.map(function(dataset) {
      if (!dataset._meta) return true;

      for (var i in dataset._meta) {
        return !dataset._meta[i].hidden;
      }
    });

    var datasetDataLength = 0;
    if (data && data.datasets && data.datasets[0] && data.datasets[0].data) {
      datasetDataLength = data.datasets[0].data.length;
    }
    var totals = Array.apply(null, new Array(datasetDataLength)).map(function(el, i) {
      return data.datasets.reduce(function(sum, dataset, j) {
        var key = dataset.stack;
        if (!sum[key]) sum[key] = 0;
        sum[key] += dataset.data[i] * visibles[j];

        return sum;
      }, {});
    });

    data.calculatedData = data.datasets.map(function(dataset, i) {
      return dataset.data.map(function(val, i) {
        var total = totals[i][dataset.stack];
        return val && total ? Math.round(val * 1000 / total) / 10 : 0;
      });
    });
  };

  var tooltipLabel = function(tooltipItem, data) {
    var datasetIndex = tooltipItem.datasetIndex;
    var index = tooltipItem.index;
    var datasetLabel = data.datasets[datasetIndex].label || "";
    var originalValue = data.originalData[datasetIndex][index];
    var rateValue = data.calculatedData[datasetIndex][index];

    return "" + datasetLabel + ": " + rateValue + "% (" + originalValue + ")";
  };

  var reflectData = function(srcData, datasets) {
    if (!srcData) return;

    srcData.forEach(function(data, i) {
      datasets[i].data = data;
    });
  };

  var Stacked100Plugin = {
    id: "stacked100",

    beforeInit: function(chartInstance, pluginOptions) {
      if (!pluginOptions.enable) return;

      var xAxes = chartInstance.options.scales.xAxes;
      var yAxes = chartInstance.options.scales.yAxes;
      var isVertical = chartInstance.config.type === "bar" || chartInstance.config.type === "line";

      [xAxes, yAxes].forEach(function(axes) {
        axes.forEach(function(hash) {
          hash.stacked = true;
        });
      });
      (isVertical ? yAxes : xAxes).forEach(function(hash) {
        if (!hash.ticks.min) hash.ticks.min = 0;
        if (!hash.ticks.max) hash.ticks.max = 100;
      });

      // Replace tooltips
      if (pluginOptions.hasOwnProperty("replaceTooltipLabel") && !pluginOptions.replaceTooltipLabel) return;
      chartInstance.options.tooltips.callbacks.label = tooltipLabel;
    },

    beforeDatasetsUpdate: function(chartInstance, pluginOptions) {
      if (!pluginOptions.enable) return;

      setOriginalData(chartInstance.data);
      calculateRate(chartInstance.data);
      reflectData(chartInstance.data.calculatedData, chartInstance.data.datasets);
    },

    afterDatasetsUpdate: function(chartInstance, pluginOptions) {
      if (!pluginOptions.enable) return;

      reflectData(chartInstance.data.originalData, chartInstance.data.datasets);
    }
  };

  Chart.pluginService.register(Stacked100Plugin);
}.call(this, Chart));
<|endoftext|>


<commit_before>/* globals process */

import chokidar from 'chokidar'

import globBase from './lib/glob-base'
import mirror from './lib/mirror'
import trimQuotes from './lib/trim-quotes'
import { watcherCopy, watcherDestroy, watcherError } from './lib/watcher'

const defaults = {
  watch: false,
  delete: false,
  depth: Infinity,
}

const syncGlob = (sources, target, options, notify) => {
  if (!Array.isArray(sources)) {
    sources = [sources]
  }
  sources = sources.map(trimQuotes)
  options = {
    ...defaults,
    base: globBase(sources),
    ...options,
  }

  if (typeof options.depth !== 'number' || isNaN(options.depth)) {
    notify('error', 'Expected valid number for option "depth"')
    return false
  }

  // Initial mirror
  const mirrored = mirror(sources, target, options, notify, 0)

  if (!mirrored) {
    notify('error', 'Initial mirror failed')
    return false
  }

  if (options.watch) {
    // Watcher to keep in sync from that
    const watcher = chokidar.watch(sources, {
      persistent: true,
      depth: options.depth,
      ignoreInitial: true,
    })
      .on('ready', notify.bind(undefined, 'watch', sources))
      .on('add', watcherCopy(target, options, notify))
      .on('addDir', watcherCopy(target, options, notify))
      .on('change', watcherCopy(target, options, notify))
      .on('unlink', watcherDestroy(target, options, notify))
      .on('unlinkDir', watcherDestroy(target, options, notify))
      .on('error', watcherError(options, notify))

    process.on('SIGINT', stopWatching)
    process.on('SIGQUIT', stopWatching)
    process.on('SIGTERM', stopWatching)

    function stopWatching() {
      watcher.close()
    }
  }
}

export default syncGlob
<commit_msg>resolve transform module relative to cwd<commit_after>/* globals process */

import path from 'path'
import chokidar from 'chokidar'

import globBase from './lib/glob-base'
import mirror from './lib/mirror'
import trimQuotes from './lib/trim-quotes'
import { watcherCopy, watcherDestroy, watcherError } from './lib/watcher'

const defaults = {
  watch: false,
  delete: false,
  depth: Infinity,
}

const syncGlob = (sources, target, options, notify) => {
  if (!Array.isArray(sources)) {
    sources = [sources]
  }
  sources = sources.map(trimQuotes)
  options = {
    ...defaults,
    base: globBase(sources),
    ...options,
  }

  if (typeof options.depth !== 'number' || isNaN(options.depth)) {
    notify('error', 'Expected valid number for option "depth"')
    return false
  }

  if (options.transform) {
    let transformPath = options.transform

    try {
      console.log(require.resolve(transformPath))
    } catch(e) {
      transformPath = path.join(process.cwd(), transformPath)
    }

    options.transform = require(transformPath)
  }

  // Initial mirror
  const mirrored = mirror(sources, target, options, notify, 0)

  if (!mirrored) {
    notify('error', 'Initial mirror failed')
    return false
  }

  if (options.watch) {
    // Watcher to keep in sync from that
    const watcher = chokidar.watch(sources, {
      persistent: true,
      depth: options.depth,
      ignoreInitial: true,
    })
      .on('ready', notify.bind(undefined, 'watch', sources))
      .on('add', watcherCopy(target, options, notify))
      .on('addDir', watcherCopy(target, options, notify))
      .on('change', watcherCopy(target, options, notify))
      .on('unlink', watcherDestroy(target, options, notify))
      .on('unlinkDir', watcherDestroy(target, options, notify))
      .on('error', watcherError(options, notify))

    process.on('SIGINT', stopWatching)
    process.on('SIGQUIT', stopWatching)
    process.on('SIGTERM', stopWatching)

    function stopWatching() {
      watcher.close()
    }
  }
}

export default syncGlob
<|endoftext|>


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

'use strict';

/**
 * Modules
 */

var $ = require('jquery');
window.$ = $;
window.jQuery = $;
var _ = require('underscore');
var Backbone = require('backbone');
var Automation = require('automationjs');
var vis = require('vis');
var moment = require('moment');

/**
 * Setup
 */

Backbone.$ = window.$;
var app = app || {};

/**
 * MODELS
 **/

app.Container = Backbone.Model.extend({
  url: function() {
    return '/';
  },
  wsUrl: function() {
    return 'ws://wot.city/object/' + this.attributes.name + '/viewer';
  },
  defaults: {
    name: 'test',
    data: '',
    cid: 0
  },
  // AutomationJS plugins
  parseJSON: function() {
    // remove internal properties from model
    var objCopy = function(object) {
      var o = {};
      for (var p in object) {
        if (object.hasOwnProperty(p)) {
          // AutomationJS:
          // don't copy internal properties
          if (p === 'name' || p === 'data' || p === 'cid') {
              continue;
          }
          o[p] = object[p];
        }
      }
      return o;
    };

    var o = objCopy(this.attributes);

    this.set('data', JSON.stringify(o));
    this.trigger('sync');
  },
  // Y-Axis getter
  getY: function() {
    return this.get('temperature');
  }
});

/**
 * VIEWS
 **/

app.ContainerView = Backbone.View.extend({
  el: '#status',
  template: _.template( $('#tmpl-status').html() ),
  initialize: function() {
    this.component = new Automation({
      el: this.$el,
      model: app.Container,
      template: this.template
    });

    var container = document.getElementById('container');
    var options = {
    };
    this.dataset = new vis.DataSet();
    this.graph2d = new vis.Graph2d(container, this.dataset, options);
  },
  render: function(name) {
    this.model = this.component.add({
        name: name
    });
    this.listenTo(this.model, 'sync', this.update);
  },
  syncUp: function(name) {
    this.render(name);
  },
  update: function() {
    var y = this.model.getY();
    var x = moment().format();
    this.dataset.add([
       {x: x, y: y},
    ]);
  }
});

/*
 * ROUTES
 */

app.AppRoutes = Backbone.Router.extend({
  routes: {
    ':name': 'appByName'
  },
  appByName: function(name) {
    app.containerView = new app.ContainerView();
    app.containerView.syncUp(name);
  }
});

/**
 * BOOTUP
 **/

$(function() {
  app.appRoutes = new app.AppRoutes();
  Backbone.history.start();
});
<commit_msg>Fix legal name<commit_after>/**
 *
 *  Copyright 2015 WoT.City Open Source Project
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License
 *
 */

'use strict';

/**
 * Modules
 */

var $ = require('jquery');
window.$ = $;
window.jQuery = $;
var _ = require('underscore');
var Backbone = require('backbone');
var Automation = require('automationjs');
var vis = require('vis');
var moment = require('moment');

/**
 * Setup
 */

Backbone.$ = window.$;
var app = app || {};

/**
 * MODELS
 **/

app.Container = Backbone.Model.extend({
  url: function() {
    return '/';
  },
  wsUrl: function() {
    return 'ws://wot.city/object/' + this.attributes.name + '/viewer';
  },
  defaults: {
    name: 'test',
    data: '',
    cid: 0
  },
  // AutomationJS plugins
  parseJSON: function() {
    // remove internal properties from model
    var objCopy = function(object) {
      var o = {};
      for (var p in object) {
        if (object.hasOwnProperty(p)) {
          // AutomationJS:
          // don't copy internal properties
          if (p === 'name' || p === 'data' || p === 'cid') {
              continue;
          }
          o[p] = object[p];
        }
      }
      return o;
    };

    var o = objCopy(this.attributes);

    this.set('data', JSON.stringify(o));
    this.trigger('sync');
  },
  // Y-Axis getter
  getY: function() {
    return this.get('temperature');
  }
});

/**
 * VIEWS
 **/

app.ContainerView = Backbone.View.extend({
  el: '#status',
  template: _.template( $('#tmpl-status').html() ),
  initialize: function() {
    this.component = new Automation({
      el: this.$el,
      model: app.Container,
      template: this.template
    });

    var container = document.getElementById('container');
    var options = {
    };
    this.dataset = new vis.DataSet();
    this.graph2d = new vis.Graph2d(container, this.dataset, options);
  },
  render: function(name) {
    this.model = this.component.add({
        name: name
    });
    this.listenTo(this.model, 'sync', this.update);
  },
  syncUp: function(name) {
    this.render(name);
  },
  update: function() {
    var y = this.model.getY();
    var x = moment().format();
    this.dataset.add([
       {x: x, y: y},
    ]);
  }
});

/*
 * ROUTES
 */

app.AppRoutes = Backbone.Router.extend({
  routes: {
    ':name': 'appByName'
  },
  appByName: function(name) {
    app.containerView = new app.ContainerView();
    app.containerView.syncUp(name);
  }
});

/**
 * BOOTUP
 **/

$(function() {
  app.appRoutes = new app.AppRoutes();
  Backbone.history.start();
});
<|endoftext|>


<commit_before>/* @flow */

import Err from 'es6-error'

export type StrDict = {[id: string]: string}

/**
 * Bound values to url placeholders or add query string
 */
export type SerializeParams = (url: string, params: StrDict) => string

export type PostProcess<I, O> = (params: I) => O
export type Preprocess<Result, Params>
    = (req: IFetcher<Result, Params>) => Promise<IFetcher<Result, Params>>

/**
 * Input args for Fetcher
 *
 * @example
```js
{
    baseUrl: '/api',
    headers: {
        'Accept-Language': 'ru;q=0.8,en-US;q=0.6,en;q=0.4'
    },
    method: 'GET',
    postProcess,
    serializeParams
}
```
 */
export type FetcherRec<Params: Object> = {
    /**
     * `baseUrl` will be prepended to `url`.
     *
     * Supported placeholders like `:id`.
     *
     * @example https://some-server.org/
     */
    baseUrl?: ?string;

    /**
     * Relative server url.
     *
     * Supported placeholders like `:id`.
     *
     * @example /user/:id
     */
    url?: ?string;

    /**
     * Url parameters key-value dict.
     *
     * If exists url placeholder with key, this value replaces url placeholder.
     * If no placeholder found - parameters adds as querystring.
     *
     * @example /user/:id/:some + {id: 1, some: 'test'} = /user/1?some=test
     */
    params?: ?Params;

    /**
     * Params serializer function.
     *
     * @example
     ```js
     //@flow
     function serializeParams(url: string, params: ?Object): string {
         const qStr: ?string = params ? querystring.stringify(params) : null
         return url + (qStr ? ('?' + qStr) : '')
     }
     ```
     */
    serializeParams?: ?SerializeParams;

    /**
     * Composable postProcess function.
     *
     * @example
     * ```js
     * // @flow
     *
     * function postProcess<Result>(response: Promise<Response>): Promise<Result> {
     *     return response.then(r => r.json)
     * }
     *
     * fetch(fullUrl, options).then(postProcess)
     * ```
     */
    postProcess?: ?PostProcess<*, *>;

    /**
     * Preprocess Request options before fetch
     *
     * @example
     * ```js
     * // @flow
     *
     * function preProcess<R, P>(opts: IFetcher<R, P>): Promise<IFetcher<R, P>> {
     *     return Promise.resolve(opts)
     * }
     *
     * preprocess(fetcher).then((f) => fetch(f.fullUrl, f.options).then(f.postProcess))
     * ```
     */
    preProcess?: ?Preprocess<*, *>;

    /**
     * Whatwg fetch function, default to global fetch
     */
    fetchFn?: ?FetchFn;

    /**
     * Request body.
     *
     * Plain objects will be searilzed to json string.
     */
    body?: ?(Blob | FormData | URLSearchParams | string | Object);

    /**
     * Below parameters from RequestOptions
     *
     * @see RequestOptions in https://github.com/facebook/flow/blob/master/lib/bom.js
     */
    cache?: ?CacheType;
    credentials?: ?CredentialsType;
    headers?: ?HeadersInit;
    integrity?: ?string;
    method?: ?MethodType;
    mode?: ?ModeType;
    redirect?: ?RedirectType;
    referrer?: ?string;
    referrerPolicy?: ?ReferrerPolicyType;
}

export interface IFetcher<Result, Params: Object> {
    /**
     * Request options.
     */
    options: RequestOptions;

    /**
     * Generated full url from baseUrl, url and params.
     */
    fullUrl: string;

    /**
     * Composable fetch.then postProcess function.
     */
    postProcess: (response: Promise<Response>) => Promise<Result>;

    /**
     * Create new copy of Fetcher with some options redefined.
     *
     * Headers will be merged with existing headers.
     * postProcess will be composed with existing postProcess.
     */
    copy<R, P: Object>(rec: FetcherRec<P>): IFetcher<R, P>;

    /**
     * Fetch data
     *
     */
    fetch(rec?: FetcherRec<*>): Promise<Result>;
}

function isFormData(val: Object): boolean {
    return (typeof FormData !== 'undefined') && (val instanceof FormData)
}

function isBlob(val: Object): boolean {
    return toString.call(val) === '[object Blob]'
}

function isURLSearchParams(val: Object): boolean {
    return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams
}

/**
 * Merge headers objects.
 *
 * Uses global Headers class if exists.
 *
 * @example
 * ```js
 * // @flow
 * mergeHeaders({a: 1}, {a: 2, b: 3})
 * // If Headers not supported, result is object: {a: 2, b: 3}
 * // Else result is new Headers({a: 2, b: 3})
 * ```
 */
export function mergeHeaders(...headerSets: (?HeadersInit)[]): HeadersInit {
    const isSupported: boolean = typeof Headers !== 'undefined'
    let result: HeadersInit = isSupported ? new Headers() : {}

    for (let i = 0, l = headerSets.length; i < l; i++) {
        const headers: ?HeadersInit = headerSets[i]
        if (!headers || typeof headers !== 'object') {
            continue
        }

        if (isSupported && result instanceof Headers) {
            if (headers instanceof Headers && Array.from) {
                const entries: [string, string][] = Array.from(headers.entries())
                for (let j = 0, k = entries.length; j < k; j++) {
                    const [name, v] = entries[j]
                    result.append(name, v)
                }
            } else {
                const entries: string[] = Object.keys(headers)
                for (let j = 0, k = entries.length; j < k; j++) {
                    result.append(entries[j], headers[entries[j]])
                }
            }
        } else {
            result = {...result, ...(headers: Object)}
        }
    }

    return result
}

export class HttpError extends Err {
    response: Response;

    constructor(response: Response) {
        super(response.statusText)
        this.response = response
    }
}

/**
 * Check response status value and throw error if it not in 200-300 range.
 */
export function checkStatus(response: Response): Response {
    if (response.status >= 200 && response.status < 300) {
        return response
    }
    throw new HttpError(response)
}

function regExpMapString(replaceRegExp: RegExp, template: string, params: StrDict): {
    str: string,
    newParams: StrDict
} {
    const newParams: StrDict = {...params}
    const str: string = template.replace(replaceRegExp, (v, k: string) => {
        if (!params[k]) {
            throw new Error(`No parameter provided to params: ${k}`)
        }
        delete newParams[k]
        return params[k]
    })

    return {
        str,
        newParams
    }
}

const DEFAULT_MAP_REGEXP = new RegExp(':([\\w]+)', 'g')

/**
 * Create params serializer.
 */
export function createSerializeParams(
    stringify: (params: StrDict) => string,
    placeholderRegExp: RegExp = DEFAULT_MAP_REGEXP
): SerializeParams {
    function serializeParams(url: string, params: StrDict): string {
        const {str, newParams} = regExpMapString(placeholderRegExp, url, params)
        const qStr: string = stringify(newParams)

        return str + (qStr ? ('?' + qStr) : '')
    }

    return serializeParams
}

function compose<In1, Out1, Out2>(
    f1: (arg: In1) => Out1,
    f2: (arg: Out1) => Out2
): (arg: In1) => Out2 {
    return (arg: In1) => f2(f1(arg))
}

function pass<V>(arg: V): any {
    return arg
}

export type FetchFn = (url: string, options: RequestOptions) => Promise<Response>;

/**
 * Cacheable data loader
 */
export class Loader<Result> {
    _result: ?Promise<Result>;
    _fetcher: IFetcher<Result, {}>;

    constructor(
        fetcher: IFetcher<Result, {}>
    ) {
        this._result = null
        this._fetcher = fetcher
    }

    _fetch: (
        rec: IFetcher<Result, {}>
    ) => Promise<Result> = (rec: IFetcher<Result, {}>) => rec.fetch();

    _onError: (err: Error) => void = (err: Error) => {
        this.reset()
        throw err
    };

    fetch(params?: FetcherRec<*>): Promise<Result> {
        let result: ?Promise<Result> = this._result
        if (result) {
            return result
        }

        result = this._fetcher.fetch(params)
            .catch(this._onError)

        this._result = result

        return result
    }

    reset(): Loader<Result> {
        this._result = null
        return this
    }
}

function defaultGetKey(rec: FetcherRec<*>): string {
    const params: {[id: string]: string} = rec.params || {}
    return Object.keys(params).sort().map((key: string) => `${key}:${params[key]}`).join('.')
}

export class Repository<Result> {
    _fetcher: IFetcher<Result, *>;
    _loaders: Map<string, Loader<Result>>;
    _getKey: (params: FetcherRec<*>) => string;

    constructor(
        fetcher: IFetcher<Result, *>,
        getKey?: ?(params: FetcherRec<*>) => string
    ) {
        this._loaders = new Map()
        this._getKey = getKey || defaultGetKey
        this._fetcher = fetcher
    }

    fetch(params: FetcherRec<*>): Promise<Result> {
        const key: string = this._getKey(params)
        let loader: ?Loader<Result> = this._loaders.get(key)
        if (!loader) {
            loader = new Loader(this._fetcher)
            this._loaders.set(key, loader)
        }

        return loader.fetch(params)
    }

    _clearAll: (loader: Loader<Result>) => void = (loader: Loader<Result>) => {
        loader.reset()
    };

    reset(params?: FetcherRec<*>): Repository<Result> {
        if (!params) {
            this._loaders.forEach(this._clearAll)
            return this
        }

        const loader: ?Loader<Result> = this._loaders.get(this._getKey(params))
        if (loader) {
            loader.reset()
        }

        return this
    }
}

/**
 * Fetch options builder
 */
export class Fetcher<Result, Params: Object> {
    _baseUrl: string;
    _serializeParams: ?SerializeParams;
    _url: string;
    _params: ?Params;
    _fetchFn: FetchFn;

    /**
     * Request options.
     */
    options: RequestOptions;

    /**
     * Generated full url from baseUrl, url and params.
     */
    fullUrl: string;

    postProcess: (req: Promise<Response>) => Promise<Result>;

    preProcess: ?Preprocess<Result, Params>;

    constructor(rec?: FetcherRec<Params> = {}) {
        this._baseUrl = rec.baseUrl || '/'
        this._serializeParams = rec.serializeParams
        this._params = rec.params || null
        this._url = rec.url || ''
        this.postProcess = rec.postProcess || pass
        this._fetchFn = rec.fetchFn || (typeof fetch === 'undefined' ? pass : fetch)
        this.preProcess = rec.preProcess || null
        let headers: ?HeadersInit = rec.headers || {}

        let isPlainObject: boolean = false
        const body = rec.body || null
        if (body && typeof body === 'object') {
            const isUrlSearchParams: boolean = isURLSearchParams(body)
            isPlainObject =
                !isFormData(body)
                && !isBlob(body)
                && !isUrlSearchParams

            if (isUrlSearchParams) {
                if (!headers) {
                    headers = {}
                }
                if (typeof Headers !== 'undefined' && headers instanceof Headers) {
                    if (!headers.has('Content-type')) {
                        headers.set(
                            'Content-Type',
                            'application/x-www-form-urlencoded;charset=utf-8'
                        )
                    }
                } else if (!(headers: Object)['Content-Type']) {
                    (headers: Object)['Content-Type']
                        = 'application/x-www-form-urlencoded;charset=utf-8'
                }
            }
        }

        this.options = {
            body: isPlainObject && body ? JSON.stringify(body) : body,
            headers,
            cache: rec.cache || null,
            credentials: rec.credentials || null,
            integrity: rec.integrity || null,
            method: rec.method || null,
            mode: rec.mode || null,
            redirect: rec.redirect || null,
            referrer: rec.referrer || null,
            referrerPolicy: rec.referrerPolicy || null
        }

        if (this._params) {
            if (!this._serializeParams) {
                throw new TypeError('params exists, but no serializeParams method provided')
            }
            this.fullUrl = this._serializeParams(this._baseUrl + this._url, this._params)
        } else {
            this.fullUrl = this._baseUrl + this._url
        }
    }

    /**
     * Create new copy of Fetcher with some options redefined.
     *
     * Headers will be merged with existing headers.
     * postProcessors will be composed with existing postProcessors.
     */
    copy<R, P: Object>(rec: FetcherRec<any>): IFetcher<R, P> {
        const headers: ?HeadersInit = this.options.headers
        return (new this.constructor({
            baseUrl: rec.baseUrl || this._baseUrl,
            serializeParams: this._serializeParams,
            url: this._url,
            ...this.options,
            ...rec,
            postProcess: rec.postProcess
                ? compose(this.postProcess, rec.postProcess)
                : this.postProcess,
            params: this._params
                ? {...this._params, ...rec.params || {}}
                : rec.params,
            headers: rec.headers
                ? mergeHeaders(headers, rec.headers)
                : headers
        }): any)
    }

    _fetch: (f: IFetcher<Result, Params>) => Promise<Result> = (f: IFetcher<Result, Params>) =>
        f.postProcess(this._fetchFn(f.fullUrl, f.options));

    fetch(rec?: FetcherRec<*>): Promise<Result> {
        const opts: IFetcher<Result, Params> = rec
            ? this.copy(rec)
            : this

        return this.preProcess
            ? this.preProcess(opts).then(this._fetch)
            : this._fetch(opts)
    }
}

if (0) ((new Fetcher(...(0: any))): IFetcher<*, *>) // eslint-disable-line
<commit_msg>preprocess inheritance fix<commit_after>/* @flow */

import Err from 'es6-error'

export type StrDict = {[id: string]: string}

/**
 * Bound values to url placeholders or add query string
 */
export type SerializeParams = (url: string, params: StrDict) => string

export type PostProcess<I, O> = (params: I) => O
export type Preprocess<Result, Params>
    = (req: IFetcher<Result, Params>) => Promise<IFetcher<Result, Params>>

/**
 * Input args for Fetcher
 *
 * @example
```js
{
    baseUrl: '/api',
    headers: {
        'Accept-Language': 'ru;q=0.8,en-US;q=0.6,en;q=0.4'
    },
    method: 'GET',
    postProcess,
    serializeParams
}
```
 */
export type FetcherRec<Params: Object> = {
    /**
     * `baseUrl` will be prepended to `url`.
     *
     * Supported placeholders like `:id`.
     *
     * @example https://some-server.org/
     */
    baseUrl?: ?string;

    /**
     * Relative server url.
     *
     * Supported placeholders like `:id`.
     *
     * @example /user/:id
     */
    url?: ?string;

    /**
     * Url parameters key-value dict.
     *
     * If exists url placeholder with key, this value replaces url placeholder.
     * If no placeholder found - parameters adds as querystring.
     *
     * @example /user/:id/:some + {id: 1, some: 'test'} = /user/1?some=test
     */
    params?: ?Params;

    /**
     * Params serializer function.
     *
     * @example
     ```js
     //@flow
     function serializeParams(url: string, params: ?Object): string {
         const qStr: ?string = params ? querystring.stringify(params) : null
         return url + (qStr ? ('?' + qStr) : '')
     }
     ```
     */
    serializeParams?: ?SerializeParams;

    /**
     * Composable postProcess function.
     *
     * @example
     * ```js
     * // @flow
     *
     * function postProcess<Result>(response: Promise<Response>): Promise<Result> {
     *     return response.then(r => r.json)
     * }
     *
     * fetch(fullUrl, options).then(postProcess)
     * ```
     */
    postProcess?: ?PostProcess<*, *>;

    /**
     * Preprocess Request options before fetch
     *
     * @example
     * ```js
     * // @flow
     *
     * function preProcess<R, P>(opts: IFetcher<R, P>): Promise<IFetcher<R, P>> {
     *     return Promise.resolve(opts)
     * }
     *
     * preprocess(fetcher).then((f) => fetch(f.fullUrl, f.options).then(f.postProcess))
     * ```
     */
    preProcess?: ?Preprocess<*, *>;

    /**
     * Whatwg fetch function, default to global fetch
     */
    fetchFn?: ?FetchFn;

    /**
     * Request body.
     *
     * Plain objects will be searilzed to json string.
     */
    body?: ?(Blob | FormData | URLSearchParams | string | Object);

    /**
     * Below parameters from RequestOptions
     *
     * @see RequestOptions in https://github.com/facebook/flow/blob/master/lib/bom.js
     */
    cache?: ?CacheType;
    credentials?: ?CredentialsType;
    headers?: ?HeadersInit;
    integrity?: ?string;
    method?: ?MethodType;
    mode?: ?ModeType;
    redirect?: ?RedirectType;
    referrer?: ?string;
    referrerPolicy?: ?ReferrerPolicyType;
}

export interface IFetcher<Result, Params: Object> {
    /**
     * Request options.
     */
    options: RequestOptions;

    /**
     * Generated full url from baseUrl, url and params.
     */
    fullUrl: string;

    /**
     * Composable fetch.then postProcess function.
     */
    postProcess: (response: Promise<Response>) => Promise<Result>;

    /**
     * Create new copy of Fetcher with some options redefined.
     *
     * Headers will be merged with existing headers.
     * postProcess will be composed with existing postProcess.
     */
    copy<R, P: Object>(rec: FetcherRec<P>): IFetcher<R, P>;

    /**
     * Fetch data
     *
     */
    fetch(rec?: FetcherRec<*>): Promise<Result>;
}

function isFormData(val: Object): boolean {
    return (typeof FormData !== 'undefined') && (val instanceof FormData)
}

function isBlob(val: Object): boolean {
    return toString.call(val) === '[object Blob]'
}

function isURLSearchParams(val: Object): boolean {
    return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams
}

/**
 * Merge headers objects.
 *
 * Uses global Headers class if exists.
 *
 * @example
 * ```js
 * // @flow
 * mergeHeaders({a: 1}, {a: 2, b: 3})
 * // If Headers not supported, result is object: {a: 2, b: 3}
 * // Else result is new Headers({a: 2, b: 3})
 * ```
 */
export function mergeHeaders(...headerSets: (?HeadersInit)[]): HeadersInit {
    const isSupported: boolean = typeof Headers !== 'undefined'
    let result: HeadersInit = isSupported ? new Headers() : {}

    for (let i = 0, l = headerSets.length; i < l; i++) {
        const headers: ?HeadersInit = headerSets[i]
        if (!headers || typeof headers !== 'object') {
            continue
        }

        if (isSupported && result instanceof Headers) {
            if (headers instanceof Headers && Array.from) {
                const entries: [string, string][] = Array.from(headers.entries())
                for (let j = 0, k = entries.length; j < k; j++) {
                    const [name, v] = entries[j]
                    result.append(name, v)
                }
            } else {
                const entries: string[] = Object.keys(headers)
                for (let j = 0, k = entries.length; j < k; j++) {
                    result.append(entries[j], headers[entries[j]])
                }
            }
        } else {
            result = {...result, ...(headers: Object)}
        }
    }

    return result
}

export class HttpError extends Err {
    response: Response;

    constructor(response: Response) {
        super(response.statusText)
        this.response = response
    }
}

/**
 * Check response status value and throw error if it not in 200-300 range.
 */
export function checkStatus(response: Response): Response {
    if (response.status >= 200 && response.status < 300) {
        return response
    }
    throw new HttpError(response)
}

function regExpMapString(replaceRegExp: RegExp, template: string, params: StrDict): {
    str: string,
    newParams: StrDict
} {
    const newParams: StrDict = {...params}
    const str: string = template.replace(replaceRegExp, (v, k: string) => {
        if (!params[k]) {
            throw new Error(`No parameter provided to params: ${k}`)
        }
        delete newParams[k]
        return params[k]
    })

    return {
        str,
        newParams
    }
}

const DEFAULT_MAP_REGEXP = new RegExp(':([\\w]+)', 'g')

/**
 * Create params serializer.
 */
export function createSerializeParams(
    stringify: (params: StrDict) => string,
    placeholderRegExp: RegExp = DEFAULT_MAP_REGEXP
): SerializeParams {
    function serializeParams(url: string, params: StrDict): string {
        const {str, newParams} = regExpMapString(placeholderRegExp, url, params)
        const qStr: string = stringify(newParams)

        return str + (qStr ? ('?' + qStr) : '')
    }

    return serializeParams
}

function compose<In1, Out1, Out2>(
    f1: (arg: In1) => Out1,
    f2: (arg: Out1) => Out2
): (arg: In1) => Out2 {
    return (arg: In1) => f2(f1(arg))
}

function pass<V>(arg: V): any {
    return arg
}

export type FetchFn = (url: string, options: RequestOptions) => Promise<Response>;

/**
 * Cacheable data loader
 */
export class Loader<Result> {
    _result: ?Promise<Result>;
    _fetcher: IFetcher<Result, {}>;

    constructor(
        fetcher: IFetcher<Result, {}>
    ) {
        this._result = null
        this._fetcher = fetcher
    }

    _fetch: (
        rec: IFetcher<Result, {}>
    ) => Promise<Result> = (rec: IFetcher<Result, {}>) => rec.fetch();

    _onError: (err: Error) => void = (err: Error) => {
        this.reset()
        throw err
    };

    fetch(params?: FetcherRec<*>): Promise<Result> {
        let result: ?Promise<Result> = this._result
        if (result) {
            return result
        }

        result = this._fetcher.fetch(params)
            .catch(this._onError)

        this._result = result

        return result
    }

    reset(): Loader<Result> {
        this._result = null
        return this
    }
}

function defaultGetKey(rec: FetcherRec<*>): string {
    const params: {[id: string]: string} = rec.params || {}
    return Object.keys(params).sort().map((key: string) => `${key}:${params[key]}`).join('.')
}

export class Repository<Result> {
    _fetcher: IFetcher<Result, *>;
    _loaders: Map<string, Loader<Result>>;
    _getKey: (params: FetcherRec<*>) => string;

    constructor(
        fetcher: IFetcher<Result, *>,
        getKey?: ?(params: FetcherRec<*>) => string
    ) {
        this._loaders = new Map()
        this._getKey = getKey || defaultGetKey
        this._fetcher = fetcher
    }

    fetch(params: FetcherRec<*>): Promise<Result> {
        const key: string = this._getKey(params)
        let loader: ?Loader<Result> = this._loaders.get(key)
        if (!loader) {
            loader = new Loader(this._fetcher)
            this._loaders.set(key, loader)
        }

        return loader.fetch(params)
    }

    _clearAll: (loader: Loader<Result>) => void = (loader: Loader<Result>) => {
        loader.reset()
    };

    reset(params?: FetcherRec<*>): Repository<Result> {
        if (!params) {
            this._loaders.forEach(this._clearAll)
            return this
        }

        const loader: ?Loader<Result> = this._loaders.get(this._getKey(params))
        if (loader) {
            loader.reset()
        }

        return this
    }
}

function callFetch<Result, Params: Object>(f: IFetcher<Result, Params>): Promise<Result> {
    return f.fetch()
}

/**
 * Fetch options builder
 */
export class Fetcher<Result, Params: Object> {
    _baseUrl: string;
    _serializeParams: ?SerializeParams;
    _url: string;
    _params: ?Params;
    _fetchFn: FetchFn;

    /**
     * Request options.
     */
    options: RequestOptions;

    /**
     * Generated full url from baseUrl, url and params.
     */
    fullUrl: string;

    postProcess: (req: Promise<Response>) => Promise<Result>;

    preProcess: ?Preprocess<Result, Params>;

    constructor(rec?: FetcherRec<Params> = {}) {
        this._baseUrl = rec.baseUrl || '/'
        this._serializeParams = rec.serializeParams
        this._params = rec.params || null
        this._url = rec.url || ''
        this.postProcess = rec.postProcess || pass
        this._fetchFn = rec.fetchFn || (typeof fetch === 'undefined' ? pass : fetch)
        this.preProcess = rec.preProcess || null
        let headers: ?HeadersInit = rec.headers || {}

        let isPlainObject: boolean = false
        const body = rec.body || null
        if (body && typeof body === 'object') {
            const isUrlSearchParams: boolean = isURLSearchParams(body)
            isPlainObject =
                !isFormData(body)
                && !isBlob(body)
                && !isUrlSearchParams

            if (isUrlSearchParams) {
                if (!headers) {
                    headers = {}
                }
                if (typeof Headers !== 'undefined' && headers instanceof Headers) {
                    if (!headers.has('Content-type')) {
                        headers.set(
                            'Content-Type',
                            'application/x-www-form-urlencoded;charset=utf-8'
                        )
                    }
                } else if (!(headers: Object)['Content-Type']) {
                    (headers: Object)['Content-Type']
                        = 'application/x-www-form-urlencoded;charset=utf-8'
                }
            }
        }

        this.options = {
            body: isPlainObject && body ? JSON.stringify(body) : body,
            headers,
            cache: rec.cache || null,
            credentials: rec.credentials || null,
            integrity: rec.integrity || null,
            method: rec.method || null,
            mode: rec.mode || null,
            redirect: rec.redirect || null,
            referrer: rec.referrer || null,
            referrerPolicy: rec.referrerPolicy || null
        }

        if (this._params) {
            if (!this._serializeParams) {
                throw new TypeError('params exists, but no serializeParams method provided')
            }
            this.fullUrl = this._serializeParams(this._baseUrl + this._url, this._params)
        } else {
            this.fullUrl = this._baseUrl + this._url
        }
    }

    /**
     * Create new copy of Fetcher with some options redefined.
     *
     * Headers will be merged with existing headers.
     * postProcessors will be composed with existing postProcessors.
     */
    copy<R, P: Object>(rec: FetcherRec<any>): IFetcher<R, P> {
        const headers: ?HeadersInit = this.options.headers
        return (new this.constructor({
            baseUrl: rec.baseUrl || this._baseUrl,
            serializeParams: this._serializeParams,
            url: this._url,
            ...this.options,
            ...rec,
            postProcess: rec.postProcess
                ? compose(this.postProcess, rec.postProcess)
                : this.postProcess,
            params: this._params
                ? {...this._params, ...rec.params || {}}
                : rec.params,
            headers: rec.headers
                ? mergeHeaders(headers, rec.headers)
                : headers
        }): any)
    }

    _fetch(f: IFetcher<Result, Params>): Promise<Result> {
        const result = this._fetchFn.call(null, f.fullUrl, f.options)
        return f.postProcess(result)
    }

    fetch(rec?: FetcherRec<*>): Promise<Result> {
        const opts: IFetcher<Result, Params> = rec
            ? this.copy(rec)
            : this

        return this.preProcess
            ? this.preProcess(opts).then(callFetch)
            : this._fetch(opts)
    }
}

if (0) ((new Fetcher(...(0: any))): IFetcher<*, *>) // eslint-disable-line
<|endoftext|>


<commit_before>var Socket = require("./socket");

module.exports = Messenger;

Messenger.Socket = Socket;

function Messenger(socket) {
    var MESSAGE_ID = 0,
        listeners = {},
        messages = {};

    socket.onMessage = function(data) {
        var message = JSON.parse(data),
            id = message.id,
            name = message.name,
            callback = messages[id];

        if (name) {
            if (listeners[name]) {
                emit(listeners[name], message.data, function callback(error, data) {
                    socket.postMessage(JSON.stringify({
                        id: id,
                        error: error || undefined,
                        data: data
                    }));
                });
            }
        } else {
            if (callback) {
                callback(message.error, message.data);
                delete messages[id];
            }
        }
    };

    this.emit = function(name, data, callback) {
        var id = MESSAGE_ID++;

        messages[id] = callback;

        socket.postMessage(JSON.stringify({
            id: id,
            name: name,
            data: data
        }));
    };

    this.on = function(name, callback) {
        var listener = listeners[name] || (listeners[name] = []);
        listener[listener.length] = callback;
    };

    this.off = function(name, callback) {
        var listener = listeners[name],
            i;

        if (listener) {
            i = listener.length;

            while (i--) {
                if (listener[i] === callback) {
                    listener.splice(i, 1);
                }
            }
        }
    };
}

function emit(listeners, data, callback) {
    var index = 0,
        length = listeners.length,
        called = false;

    function done(err, data) {
        if (called === false) {
            called = true;
            callback(err, data);
        }
    }

    function next(err, data) {
        if (err || index === length) {
            done(err, data);
        } else {
            listeners[index++](data, next);
        }
    }

    next(undefined, data);
}
<commit_msg>updates<commit_after>var Socket = require("./socket");

module.exports = Messenger;

Messenger.Socket = Socket;

function Messenger(socket) {
    var MESSAGE_ID = 0,
        listeners = {},
        messages = {};

    socket.onMessage = function(data) {
        var message = data,
            id = message.id,
            name = message.name,
            callback = messages[id];

        if (name) {
            if (listeners[name]) {
                emit(listeners[name], message.data, function callback(error, data) {
                    socket.postMessage({
                        id: id,
                        error: error || undefined,
                        data: data
                    });
                });
            }
        } else {
            if (callback) {
                callback(message.error, message.data);
                delete messages[id];
            }
        }
    };

    this.emit = function(name, data, callback) {
        var id = MESSAGE_ID++;

        messages[id] = callback;

        socket.postMessage({
            id: id,
            name: name,
            data: data
        });
    };

    this.on = function(name, callback) {
        var listener = listeners[name] || (listeners[name] = []);
        listener[listener.length] = callback;
    };

    this.off = function(name, callback) {
        var listener = listeners[name],
            i;

        if (listener) {
            i = listener.length;

            while (i--) {
                if (listener[i] === callback) {
                    listener.splice(i, 1);
                }
            }
        }
    };
}

function emit(listeners, data, callback) {
    var index = 0,
        length = listeners.length,
        called = false;

    function done(err, data) {
        if (called === false) {
            called = true;
            callback(err, data);
        }
    }

    function next(err, data) {
        if (err || index === length) {
            done(err, data);
        } else {
            listeners[index++](data, next);
        }
    }

    next(undefined, data);
}
<|endoftext|>


<commit_before>import Observer from './observer';
import View from './view';

export default class Bee extends Observer {
	constructor( { data, template } ) {
		console.log( data );
		super( data );
		this.view = new View({
			template: template,
			vm: this,
		});
	}
	$mount( node ) {
		this.view.mount( node );
	}
};
<commit_msg>Clean code<commit_after>import Observer from './observer';
import View from './view';

export default class Bee extends Observer {
	constructor( { data, template } ) {
		super( data );
		this.view = new View({
			template: template,
			vm: this,
		});
	}
	$mount( node ) {
		this.view.mount( node );
	}
};
<|endoftext|>


<commit_before>const fs = require('fs')
  ,   os = require('os')
  ,   path = require('path')
  ,   assert = require('assert')
  ,   child_process = require('child_process')
  ,   glob = require('glob')
  ,   express = require('express')
  ,   multer = require('multer')
  ,   bodyParser = require('body-parser')

const resResultProperty = 'dafuq_result'
const resTypeProperty = 'dafuq_type'

/**
 * @typedef DafuqPath
 * @type {object}
 * @property {string} absolute Absolute path pointing to a file
 * @property {string} relative Path to the same file pointed by absolute property,
 *                             but relative to the invoking script
 */

/**
 * Exit code that determines a file response should be used instead of JSON
 * @type {Number}
 */
const EXIT_CODE_FILE = 10

/**
 * Result types when executing a command
 * @type {String}
 */
const RESULT_TYPE_OBJECT = 'object'
const RESULT_TYPE_FILE = 'file'

/**
 * Asserts the provided **absolute** path is a directory
 *
 * @param  {String} path - the path to check if is a directory
 * @return {String} the provided path
 * @throws {AssertionError} If the path is not a directory
 */
function assertIsDirectory(path) {
    let dirStats
    try {
        assert(fs.statSync(path).isDirectory(), `path ${path} is not a directory`)
    } catch(e) {
        const msg = `path ${path} does not exists or doesn't have proper permissions`
        assert(false, msg)
    }
    return path
}

/**
 * Glob pattern that matches all the files that would generate a route
 * @type {String}
 */
const globPattern = '**/+(all|get|post|put|delete|head|options).*'

/**
 * Returns the files at dir matching the given glob pattern
 *
 * @param  {String} dir The directory to search for files
 * @param  {String} pattern A glob pattern that files must match
 * @return {DafuqPath[]} All the files that mattched the pattern at the given dir
 */
function findFilesAt(dir, pattern) {
    return glob.sync(path.join(dir, pattern), { nocase: true })
        .map(p => ({
            absolute: p,
            relative: path.relative(dir, p)
        }))
}

/**
 * Binary mask for files mode. Checks against user execution permision.
 * @type {number}
 */
const MASK_EXEC = parseInt('0100', 8)

/**
 * Returns true if the provided path can be executed, false otherwise
 *
 * @param  {String} path the absolute path to check if is executable
 * @return {Boolean}     true if the path is executable, false otherwise
 */
function isExecutable(path) {
    try {
        const stats = fs.statSync(path)
        return !!(stats.mode & MASK_EXEC)
    } catch(e) { return false }
}

/**
 * Matches and extracts the headers that would be used as commadn line params
 * @type {RegExp}
 */
const HEADER_X_ARG_REGEX = /^x-arg-(.*)$/i

/**
 * Builds the command line arguments string (--option1 value1 --option2) by
 * searching on the necessary request fields.
 *
 * The fields and order or prevailing is as follows:
 *  * Headers: Header fields that match {@link HEADER_X_ARG_REGEX}
 *  * Query Params
 *  * URL params
 *  * Body members
 *  * Multipart uploaded files
 *
 * @param  {Object} req - express request object
 * @return {String} The command options string
 */
function buildCommandFlags(req) {
    let cmdFlags = ''

    // Build headers object for later merge
    const headerFlags = Object.keys(req.headers).reduce((headers, header) => {
        const mtch = HEADER_X_ARG_REGEX.exec(header)
        if (mtch)
            headers[mtch[1]] = req.headers[header]
        return headers
    }, {})

    // Build files
    const uploadFlags = (req.files || []).reduce((files, file) => {
        files[file.fieldname] = file.path
        return files
    }, {})

    const flags = Object.assign({}, headerFlags, req.query, req.params, req.body, uploadFlags)
    Object.keys(flags).forEach(function(flagName) {
        const flagValue = flags[flagName]
        cmdFlags += ` --${flagName}`
        if (flagValue)
            cmdFlags += ` "${flagValue}"`
    })

    return cmdFlags
}

/**
 * Executes the specified command on the OS terminal and returns via cb the
 * response written to the stdout and stderr wrapped arround a JSON object.
 *
 * The result will always contain a field named succes that tells if the
 * command executed properly or not. A command is cosidered successful when
 * its exit code is 0 and no errors are thrown.
 *
 * The output of the command is considered in the following order, the first
 * one to match will be considered as the command output:
 * * The content of strderr if it is not empty
 * * The content of stdout if it is not empty
 * * The error message if the error was reported while using
 *  node's `child_process.exec`
 *
 * Finally, once the output is determined, we try to parse it as json. If
 * successful and the parsed JSON contains the success property the output
 * just generated will be treated as the result of the command execution.
 * If the JSON was correctly parsed but didn't contain any success field, the
 * result will be an object containing `success` and `result`, being result
 * the just parsed JSON.
 * If the output string couldn't be parsed as JSON, the result field will be
 * directly the string.
 *
 * @param  {String}   cmd Command to be executed via `child_process.exec`
 * @param  {Function} cb  Completion callback. The result object and the
 *                        the result type are pased as arguments
 */
function execCommand(command, cb) {
    child_process.exec(command, function(err, stdout, stderr) {
        const code = err && err.code ? err.code : 0
        let result =  stderr || stdout || (err || {}).message
        let type = RESULT_TYPE_OBJECT

        if (result)
            result = result.trim()

        if (code === EXIT_CODE_FILE) {
            type = RESULT_TYPE_FILE
        } else {
            try {
                // Try to parse it as JSON
                const json = JSON.parse(result)
                result = json
            } catch(e) {} // If an error occurs parsing the json leave it as it was

            // If the result doesn't contain the field success, treat its
            // contents as the result part and add the succes field
            if (result.success === undefined) {
                result = {
                    success: code === 0,
                    result: result
                }
            }
        }

        cb(result, type)
    })
}

export default function dafuq(config) {

    // Allow constructor to be only the commands directory
    if (typeof config === 'string')
        config = { path: path }

    // Assign default values
    const opts = Object.assign({
        shebang: '',
        debug: false
    }, config)

    // Options validation

    // Valid string path is mandatory
    if (!opts.path || typeof opts.path !== 'string' || opts.path.length == 0)
        throw new TypeError('path must be a string pointing to the commands directory')

    // If shebang provided, but not valid
    if (opts.shebang && (typeof opts.shebang !== 'string' || opts.shebang.length == 0))
        throw new TypeError('shebang must be a non empty string')

    // If intercept provided, but not valid
    if (opts.intercept && (typeof opts.intercept !== 'function'))
        throw new TypeError('intercept must be a function')

    if (opts.debug !== undefined) {
        if (opts.debug === true)
            opts.debug = console.log
        else if (opts.debug === false)
            opts.debug = (() => {})
        else if (typeof opts.debug !== 'function')
            throw new TypeError('debug must be a boolean or a logging function')
    }

    opts.debug('Building dafuq instance with %j', config)

    // Build an absolute path to the commands directory and assert it is actually a directory
    const commandsPath = path.resolve(path.dirname(module.parent.filename), opts.path)
    assertIsDirectory(commandsPath)

    // Find the files to be mounted as execution points
    let files = findFilesAt(commandsPath, globPattern)

    // If no shebang is specified, the file need to be executable by itself
    if (!opts.shebang) {
        files = files.filter(file => {
            const isExe = isExecutable(file.absolute)
            if (!isExe)
                opts.debug(`${ file.absolute } is not executable, ignoring`)
            return isExe
        })
    }

    const app = express()
    const upload = multer({ dest: os.tmpdir() })

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

    /**
     * Returns a middleware that once inkoed will execute the specified file and
     * put the result of its execution on response object in the property pointed
     * by moduleName.
     *
     * @param {String} file
     */
    function executionMiddleware(file) {
        return (req, res, next) => {
            // Build the base command
            let cmd = file
            if (opts.shebang)
                cmd = `${ opts.shebang } ${ cmd }`
            /*
             Append all the parameters provided via:
                * query params
                * url params
                * body members
                * x-args headers
            */
            cmd += buildCommandFlags(req)

            opts.debug(`$ ${cmd}`)
            execCommand(cmd, (result, type) => {
                Object.defineProperty(res, resResultProperty, { value: result })
                Object.defineProperty(res, resTypeProperty, { value: type })
                next()
            })
        }
    }

    // Add all the files routes
    files.forEach(file => {
        const filePath = file.relative
        const url = '/' + path.dirname(file.relative)
        const method = path.basename(filePath, path.extname(filePath)).toLowerCase()
        const middleware = executionMiddleware(file.absolute)
        opts.debug(`Adding ${ method } ${ url }`)
        if (method === 'get' || method === 'head' || method === 'options')
            app[method](url, middleware)
        else
            app[method](url, upload.any(), middleware)
    })

    // Fallback behaviour, send the result
    app.all('*', (req, res, next) => {
        if (res[resTypeProperty] === RESULT_TYPE_OBJECT)
            res.type('json').json(res[resResultProperty])
        else if (res[resTypeProperty] === RESULT_TYPE_FILE)
            res.download(res[resResultProperty])
        else
            res.status(404).send()
    })

    return app
}
<commit_msg>Remove undocumented/unused code<commit_after>const fs = require('fs')
  ,   os = require('os')
  ,   path = require('path')
  ,   assert = require('assert')
  ,   child_process = require('child_process')
  ,   glob = require('glob')
  ,   express = require('express')
  ,   multer = require('multer')
  ,   bodyParser = require('body-parser')

const resResultProperty = 'dafuq_result'
const resTypeProperty = 'dafuq_type'

/**
 * @typedef DafuqPath
 * @type {object}
 * @property {string} absolute Absolute path pointing to a file
 * @property {string} relative Path to the same file pointed by absolute property,
 *                             but relative to the invoking script
 */

/**
 * Exit code that determines a file response should be used instead of JSON
 * @type {Number}
 */
const EXIT_CODE_FILE = 10

/**
 * Result types when executing a command
 * @type {String}
 */
const RESULT_TYPE_OBJECT = 'object'
const RESULT_TYPE_FILE = 'file'

/**
 * Asserts the provided **absolute** path is a directory
 *
 * @param  {String} path - the path to check if is a directory
 * @return {String} the provided path
 * @throws {AssertionError} If the path is not a directory
 */
function assertIsDirectory(path) {
    let dirStats
    try {
        assert(fs.statSync(path).isDirectory(), `path ${path} is not a directory`)
    } catch(e) {
        const msg = `path ${path} does not exists or doesn't have proper permissions`
        assert(false, msg)
    }
    return path
}

/**
 * Glob pattern that matches all the files that would generate a route
 * @type {String}
 */
const globPattern = '**/+(all|get|post|put|delete|head|options).*'

/**
 * Returns the files at dir matching the given glob pattern
 *
 * @param  {String} dir The directory to search for files
 * @param  {String} pattern A glob pattern that files must match
 * @return {DafuqPath[]} All the files that mattched the pattern at the given dir
 */
function findFilesAt(dir, pattern) {
    return glob.sync(path.join(dir, pattern), { nocase: true })
        .map(p => ({
            absolute: p,
            relative: path.relative(dir, p)
        }))
}

/**
 * Binary mask for files mode. Checks against user execution permision.
 * @type {number}
 */
const MASK_EXEC = parseInt('0100', 8)

/**
 * Returns true if the provided path can be executed, false otherwise
 *
 * @param  {String} path the absolute path to check if is executable
 * @return {Boolean}     true if the path is executable, false otherwise
 */
function isExecutable(path) {
    try {
        const stats = fs.statSync(path)
        return !!(stats.mode & MASK_EXEC)
    } catch(e) { return false }
}

/**
 * Matches and extracts the headers that would be used as commadn line params
 * @type {RegExp}
 */
const HEADER_X_ARG_REGEX = /^x-arg-(.*)$/i

/**
 * Builds the command line arguments string (--option1 value1 --option2) by
 * searching on the necessary request fields.
 *
 * The fields and order or prevailing is as follows:
 *  * Headers: Header fields that match {@link HEADER_X_ARG_REGEX}
 *  * Query Params
 *  * URL params
 *  * Body members
 *  * Multipart uploaded files
 *
 * @param  {Object} req - express request object
 * @return {String} The command options string
 */
function buildCommandFlags(req) {
    let cmdFlags = ''

    // Build headers object for later merge
    const headerFlags = Object.keys(req.headers).reduce((headers, header) => {
        const mtch = HEADER_X_ARG_REGEX.exec(header)
        if (mtch)
            headers[mtch[1]] = req.headers[header]
        return headers
    }, {})

    // Build files
    const uploadFlags = (req.files || []).reduce((files, file) => {
        files[file.fieldname] = file.path
        return files
    }, {})

    const flags = Object.assign({}, headerFlags, req.query, req.params, req.body, uploadFlags)
    Object.keys(flags).forEach(function(flagName) {
        const flagValue = flags[flagName]
        cmdFlags += ` --${flagName}`
        if (flagValue)
            cmdFlags += ` "${flagValue}"`
    })

    return cmdFlags
}

/**
 * Executes the specified command on the OS terminal and returns via cb the
 * response written to the stdout and stderr wrapped arround a JSON object.
 *
 * The result will always contain a field named succes that tells if the
 * command executed properly or not. A command is cosidered successful when
 * its exit code is 0 and no errors are thrown.
 *
 * The output of the command is considered in the following order, the first
 * one to match will be considered as the command output:
 * * The content of strderr if it is not empty
 * * The content of stdout if it is not empty
 * * The error message if the error was reported while using
 *  node's `child_process.exec`
 *
 * Finally, once the output is determined, we try to parse it as json. If
 * successful and the parsed JSON contains the success property the output
 * just generated will be treated as the result of the command execution.
 * If the JSON was correctly parsed but didn't contain any success field, the
 * result will be an object containing `success` and `result`, being result
 * the just parsed JSON.
 * If the output string couldn't be parsed as JSON, the result field will be
 * directly the string.
 *
 * @param  {String}   cmd Command to be executed via `child_process.exec`
 * @param  {Function} cb  Completion callback. The result object and the
 *                        the result type are pased as arguments
 */
function execCommand(command, cb) {
    child_process.exec(command, function(err, stdout, stderr) {
        const code = err && err.code ? err.code : 0
        let result =  stderr || stdout || (err || {}).message
        let type = RESULT_TYPE_OBJECT

        if (result)
            result = result.trim()

        if (code === EXIT_CODE_FILE) {
            type = RESULT_TYPE_FILE
        } else {
            try {
                // Try to parse it as JSON
                const json = JSON.parse(result)
                result = json
            } catch(e) {} // If an error occurs parsing the json leave it as it was

            // If the result doesn't contain the field success, treat its
            // contents as the result part and add the succes field
            if (result.success === undefined) {
                result = {
                    success: code === 0,
                    result: result
                }
            }
        }

        cb(result, type)
    })
}

export default function dafuq(config) {

    // Allow constructor to be only the commands directory
    if (typeof config === 'string')
        config = { path: path }

    // Assign default values
    const opts = Object.assign({
        shebang: '',
        debug: false
    }, config)

    // Options validation

    // Valid string path is mandatory
    if (!opts.path || typeof opts.path !== 'string' || opts.path.length == 0)
        throw new TypeError('path must be a string pointing to the commands directory')

    // If shebang provided, but not valid
    if (opts.shebang && (typeof opts.shebang !== 'string' || opts.shebang.length == 0))
        throw new TypeError('shebang must be a non empty string')

    if (opts.debug !== undefined) {
        if (opts.debug === true)
            opts.debug = console.log
        else if (opts.debug === false)
            opts.debug = (() => {})
        else if (typeof opts.debug !== 'function')
            throw new TypeError('debug must be a boolean or a logging function')
    }

    opts.debug('Building dafuq instance with %j', config)

    // Build an absolute path to the commands directory and assert it is actually a directory
    const commandsPath = path.resolve(path.dirname(module.parent.filename), opts.path)
    assertIsDirectory(commandsPath)

    // Find the files to be mounted as execution points
    let files = findFilesAt(commandsPath, globPattern)

    // If no shebang is specified, the file need to be executable by itself
    if (!opts.shebang) {
        files = files.filter(file => {
            const isExe = isExecutable(file.absolute)
            if (!isExe)
                opts.debug(`${ file.absolute } is not executable, ignoring`)
            return isExe
        })
    }

    const app = express()
    const upload = multer({ dest: os.tmpdir() })

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

    /**
     * Returns a middleware that once inkoed will execute the specified file and
     * put the result of its execution on response object in the property pointed
     * by moduleName.
     *
     * @param {String} file
     */
    function executionMiddleware(file) {
        return (req, res, next) => {
            // Build the base command
            let cmd = file
            if (opts.shebang)
                cmd = `${ opts.shebang } ${ cmd }`
            /*
             Append all the parameters provided via:
                * query params
                * url params
                * body members
                * x-args headers
            */
            cmd += buildCommandFlags(req)

            opts.debug(`$ ${cmd}`)
            execCommand(cmd, (result, type) => {
                Object.defineProperty(res, resResultProperty, { value: result })
                Object.defineProperty(res, resTypeProperty, { value: type })
                next()
            })
        }
    }

    // Add all the files routes
    files.forEach(file => {
        const filePath = file.relative
        const url = '/' + path.dirname(file.relative)
        const method = path.basename(filePath, path.extname(filePath)).toLowerCase()
        const middleware = executionMiddleware(file.absolute)
        opts.debug(`Adding ${ method } ${ url }`)
        if (method === 'get' || method === 'head' || method === 'options')
            app[method](url, middleware)
        else
            app[method](url, upload.any(), middleware)
    })

    // Fallback behaviour, send the result
    app.all('*', (req, res, next) => {
        if (res[resTypeProperty] === RESULT_TYPE_OBJECT)
            res.type('json').json(res[resResultProperty])
        else if (res[resTypeProperty] === RESULT_TYPE_FILE)
            res.download(res[resResultProperty])
        else
            res.status(404).send()
    })

    return app
}
<|endoftext|>


<commit_before>export default {};
<commit_msg>Import code from react-waypoint<commit_after>const CAN_USE_DOM = !!(
  (typeof window !== 'undefined' &&
  window.document && window.document.createElement)
);

// Adapted from Modernizr
// https://github.com/Modernizr/Modernizr/blob/5eea7e2a/feature-detects/dom/passiveeventlisteners.js#L26-L35
function canUsePassiveEventListener() {
  if (!CAN_USE_DOM) {
    return false;
  }

  let supportsPassiveOption = false;
  try {
    const opts = Object.defineProperty({}, 'passive', {
      get() {
        supportsPassiveOption = true;
      }
    });
    window.addEventListener('test', null, opts);
  } catch (e) {
    // do nothing
  }

  return supportsPassiveOption;
}
const EVENT_OPTIONS = canUsePassiveEventListener() ? { passive: true } : undefined;

class TargetEventHandlers {
  constructor(target) {
    this.target = target;
    this.events = {};
  }

  getEventHandlers(eventName) {
    if (!this.events[eventName]) {
      this.events[eventName] = {
        size: 0,
        index: 0,
        handlers: {},
        handleEvent: undefined,
      };
    }
    return this.events[eventName];
  }

  handleEvent(eventName, event) {
    const { handlers } = this.getEventHandlers(eventName);
    Object.keys(handlers).forEach(function(index) {
      const handler = handlers[index];
      if (handler) {
        // We need to check for presence here because a handler function may
        // cause later handlers to get removed. This can happen if you for
        // instance have a waypoint that unmounts another waypoint as part of an
        // onEnter/onLeave handler.
        handler(event);
      }
    });
  }

  add(eventName, listener) {
    const eventHandlers = this.getEventHandlers(eventName);

    if (eventHandlers.size === 0) {
      eventHandlers.handleEvent = this.handleEvent.bind(this, eventName);

      this.target.addEventListener(
        eventName,
        eventHandlers.handleEvent,
        EVENT_OPTIONS
      );
    }

    eventHandlers.size++;
    eventHandlers.index++;
    eventHandlers.handlers[eventHandlers.index] = listener;
    return eventHandlers.index;
  }

  delete(eventName, index) {
    const eventHandlers = this.getEventHandlers(eventName);
    delete eventHandlers.handlers[index];
    eventHandlers.size--;

    if (eventHandlers.size === 0) {
      this.target.removeEventListener(
        eventName,
        eventHandlers.handleEvent,
        EVENT_OPTIONS
      );

      eventHandlers.handleEvent = undefined;
    }
  }
}

const EVENT_HANDLERS_KEY = '__react_waypoint_event_handlers__';

function addEventListener(target, eventName, listener) {
  if (!target[EVENT_HANDLERS_KEY]) {
    target[EVENT_HANDLERS_KEY] = new TargetEventHandlers(target);
  }
  return target[EVENT_HANDLERS_KEY].add(eventName, listener);
}

function removeEventListener(target, eventName, index) {
  if (target) {
    // At the time of unmounting, the target might no longer exist. Guarding
    // against this prevents the following error:
    //
    //   Cannot read property 'removeEventListener' of undefined
    target[EVENT_HANDLERS_KEY].delete(eventName, index);
  }
}

export default {};
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from './components/App';

ReactDOM.render(
  <BrowserRouter basename="/repo-name">
    <App />
  </BrowserRouter>,
  document.getElementById('root'),
);
<commit_msg>fix(router): Set basepath"<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from './components/App';

ReactDOM.render(
  <BrowserRouter basename="/panomod">
    <App />
  </BrowserRouter>,
  document.getElementById('root'),
);
<|endoftext|>


<commit_before>import Debug from 'debug';
import { fromJS, Map } from 'immutable';
import fp from 'lodash/fp';

const error = Debug('webpack-config-builder:error');
const debug = Debug('webpack-config-builder:debug');

const defaultReducers = [c => c];

/**
 * @type Config
 * @param {Object|Immutable.Map} state
 * @param {Function[]} reducers
 */
export default function Config(state, reducers = defaultReducers) {
  state = Map.isMap(state) ? state : fromJS(state);

  return {
    use: use,
    useIf: useIf,
    toJs: toJs
  };

  /**
   * toJs
   * @returns {Object|Boolean}
   */
  function toJs() {
    try {
      return fp.flow(reducers)(state).toJS();
    } catch(err) {
      error(err);

      return false;
    }
  }

  /**
   * Use
   * @param {Function} reducer - function that receives the state object
   * @returns {Config}
   */
  function use(reducer) {
    debug(`Added reducer: '${reducer.name || 'Anonymous'}'`);
    return Config(state, reducers.concat(reducer));
  }

  /**
   * Run reducer only if condition in config is met
   * @param {String[]} getInPath - Path in configurator to value
   * @param {Function} reducer   - state 'changer'
   * @returns {Config}
   */
  function useIf(getInPath, reducer) {
    return this.use(c => {
      if (c.getIn(getInPath)) {
        return reducer(c);
      }
      return c;
    });
  }
}

/**
 * exportForWebpack
 * @note exportForWebpack doesn't cover all webpack settings that require mapping from object to array.
 */
export function exportForWebpack(c) {
  return c.withMutations(c => {
    return c
      .updateIn(['module', 'loaders'], objectToArray)
      .updateIn(['plugins'], objectToArray)
      .updateIn(['resolve', 'modulesDirectories'], objectToArray)
      .updateIn(['externals'], objectToArray);
  });
}

function objectToArray(obj) {
  return obj ? obj.toArray(): void(0);
}
<commit_msg>Use empty object for state when state is not provided<commit_after>import Debug from 'debug';
import { fromJS, Map } from 'immutable';
import fp from 'lodash/fp';

const error = Debug('webpack-config-builder:error');
const debug = Debug('webpack-config-builder:debug');

const defaultReducers = [c => c];

/**
 * @type Config
 * @param {Object|Immutable.Map} state
 * @param {Function[]} reducers
 */
export default function Config(state, reducers = defaultReducers) {
  state = Map.isMap(state) ? state : fromJS(state || {});

  return {
    use: use,
    useIf: useIf,
    toJs: toJs
  };

  /**
   * toJs
   * @returns {Object|Boolean}
   */
  function toJs() {
    try {
      return fp.flow(reducers)(state).toJS();
    } catch(err) {
      error(err);

      return false;
    }
  }

  /**
   * Use
   * @param {Function} reducer - function that receives the state object
   * @returns {Config}
   */
  function use(reducer) {
    debug(`Added reducer: '${reducer.name || 'Anonymous'}'`);
    return Config(state, reducers.concat(reducer));
  }

  /**
   * Run reducer only if condition in config is met
   * @param {String[]} getInPath - Path in configurator to value
   * @param {Function} reducer   - state 'changer'
   * @returns {Config}
   */
  function useIf(getInPath, reducer) {
    return this.use(c => {
      if (c.getIn(getInPath)) {
        return reducer(c);
      }
      return c;
    });
  }
}

/**
 * exportForWebpack
 * @note exportForWebpack doesn't cover all webpack settings that require mapping from object to array.
 */
export function exportForWebpack(c) {
  return c.withMutations(c => {
    return c
      .updateIn(['module', 'loaders'], objectToArray)
      .updateIn(['plugins'], objectToArray)
      .updateIn(['resolve', 'modulesDirectories'], objectToArray)
      .updateIn(['externals'], objectToArray);
  });
}

function objectToArray(obj) {
  return obj ? obj.toArray(): void(0);
}
<|endoftext|>


<commit_before>var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var fs = require("fs");
var romcount = 0;
var joincount = 0;

app.set('view engine', 'jade');
app.set('views', __dirname + '/views');

app.get('/', function (req, res) {
	res.render("index.jade");
});

app.get('/old', function (req, res) {
	res.render("old-index.jade");
});

app.get('/count', function (req, res) {
	res.writeHeader(200, { "content-type": "text/json" });
	res.end(JSON.stringify({ rom: romcount - joincount, join: joincount }));
});

app.get('/script.js', function (req, res) {
	fs.readFile(__dirname + "/script.js", function (a, b) {
		res.writeHeader(200, { "content-type": "text/javascript" });
		res.end(b);
	});
});
app.get('/style.css', function (req, res) {
	fs.readFile(__dirname + "/style.css", function (a, b) {
		res.writeHeader(200, { "content-type": "text/css" });
		res.end(b);
	});
});
app.get('/common.css', function (req, res) {
	fs.readFile(__dirname + "/common.css", function (a, b) {
		res.writeHeader(200, { "content-type": "text/css" });
		res.end(b);
	});
});
setTimeout(function () {
	io.emit("reload");
}, 5000);
var nameList = [];
io.on('connection', function (socket) {
	console.log('a user connected');
	romcount++;
	io.emit("updateinfo");
	var name = "";
	socket.on("join", function (_name) {
		if (nameList.indexOf(_name) !== -1) {
			io.emit("system", _name + "という名前はすでに使われています。");
			return;
		}
		if (name !== "") {
			io.emit("system", name + "さんが" + _name + "として入ろうとしましたが、すでに入室していました。");
			return;
		}
		if (_name.length > 20) {
			socket.emit("system", "名前は３０文字までです");
			return;
		}
		name = _name;
		nameList.push(name);
		joincount++;
		socket.emit("join");
		console.log("join",name,socket.handshake.address);
		io.emit("system",name+"さんが入室しました");
		io.emit("updateinfo");
		socket.on("chat message", function (msg) {
			console.log(msg);
			io.emit("updateinfo");
			io.emit("chat message", { name, msg });
		});
		socket.on("disconnect", function () {
			nameList.pop(name);
			joincount--;
			io.emit("updateinfo");
			io.emit("system", name + "さんが退室したようです");
		});
		socket.on("unko", function () {
			io.emit("unko", name);
		});
	});
	socket.on("disconnect", function () {
		romcount--;
		io.emit("updateinfo");
	});
});

http.listen(2000, function () {
	console.log('listening on *:2000');
});
<commit_msg>名前が重複してた場合のエラーを自分だけに返すように<commit_after>var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var fs = require("fs");
var romcount = 0;
var joincount = 0;

app.set('view engine', 'jade');
app.set('views', __dirname + '/views');

app.get('/', function (req, res) {
	res.render("index.jade");
});

app.get('/old', function (req, res) {
	res.render("old-index.jade");
});

app.get('/count', function (req, res) {
	res.writeHeader(200, { "content-type": "text/json" });
	res.end(JSON.stringify({ rom: romcount - joincount, join: joincount }));
});

app.get('/script.js', function (req, res) {
	fs.readFile(__dirname + "/script.js", function (a, b) {
		res.writeHeader(200, { "content-type": "text/javascript" });
		res.end(b);
	});
});
app.get('/style.css', function (req, res) {
	fs.readFile(__dirname + "/style.css", function (a, b) {
		res.writeHeader(200, { "content-type": "text/css" });
		res.end(b);
	});
});
app.get('/common.css', function (req, res) {
	fs.readFile(__dirname + "/common.css", function (a, b) {
		res.writeHeader(200, { "content-type": "text/css" });
		res.end(b);
	});
});
setTimeout(function () {
	io.emit("reload");
}, 5000);
var nameList = [];
io.on('connection', function (socket) {
	console.log('a user connected');
	romcount++;
	io.emit("updateinfo");
	var name = "";
	socket.on("join", function (_name) {
		if (nameList.indexOf(_name) !== -1) {
			sock.emit("system", _name + "という名前はすでに使われています。");
			return;
		}
		if (name !== "") {
			io.emit("system", name + "さんが" + _name + "として入ろうとしましたが、すでに入室していました。");
			return;
		}
		if (_name.length > 20) {
			socket.emit("system", "名前は３０文字までです");
			return;
		}
		name = _name;
		nameList.push(name);
		joincount++;
		socket.emit("join");
		console.log("join",name,socket.handshake.address);
		io.emit("system",name+"さんが入室しました");
		io.emit("updateinfo");
		socket.on("chat message", function (msg) {
			console.log(msg);
			io.emit("updateinfo");
			io.emit("chat message", { name, msg });
		});
		socket.on("disconnect", function () {
			nameList.pop(name);
			joincount--;
			io.emit("updateinfo");
			io.emit("system", name + "さんが退室したようです");
		});
		socket.on("unko", function () {
			io.emit("unko", name);
		});
	});
	socket.on("disconnect", function () {
		romcount--;
		io.emit("updateinfo");
	});
});

http.listen(2000, function () {
	console.log('listening on *:2000');
});
<|endoftext|>