<commit_before>var tty = require('tty'),
fs = require('fs'),
_buffer = '',
plugin = require("plugin");

require("colors");

require("keypress")(process.stdin);

exports.utils = require('./utils');

var queue = require('tq').queue().start();

exports.queue = queue.fn;

var _inputPrefix = '> ';

/**
 * queued commands
 */

exports.next = function(callback) {
	queue.push(callback);

	return this;
}

/**
 * size of the terminal window
 */

exports.size = function() {
    return process.stdout.getWindowSize();
}

/**
 * number of columns in the terminal window (characters / width)
 */

exports.columns = function() {
    return exports.size()[0] || exports.size();
}

/**
 * number of rows in the terminal window
 */

exports.rows = function() {
    return exports.size()[1];
}

/**
 */

exports.inputPrefix = function(prefix) {
    if(!arguments.length) return _inputPrefix;

    return _inputPrefix = prefix || '';
}

/**
 */

exports.buffer = function(value, ignoreReplace) {
    if(!arguments.length) return _buffer;

    _buffer = value;

    return !ignoreReplace ? exports.replaceLine(value) : value;
}

/**
 * Replaces the current line in the terminal window
 */

exports.replaceLine = function(buffer, cursorTo) {

    if(!buffer) buffer = "";

    //need to clear the line before replacing it
    process.stdout.clearLine();

    //set the cursor to zero, otherwise we'll have padding we don't want
    exports.cursor(0);

    //write the buffer
    process.stdout.write(buffer);

    //set the cursor to the new position!
    exports.cursor(cursorTo != undefined ? cursorTo : buffer.length);

    return _buffer = buffer;
}

/**
 * inserts text into the current line
 */

exports.insertText = function(str, position) {
    var buffer = exports.buffer();
    exports.replaceLine(buffer.substr(0, position) + str + buffer.substr(position), position + str.length);
}

/**
 * Takes a chunk of text out of the current line
 */

exports.spliceLine = function(position, length, newCursor) {

    var buffer = exports.buffer();
    exports.replaceLine(buffer.substr(0, position) + buffer.substr(position + length), newCursor);
}

var _cursorPosition = 0;

/**
 */

exports.cursor = function(position) {
   if(!arguments.length) return _cursorPosition;

   process.stdout.cursorTo(position);

   return _cursorPosition = position;
}

function stringRep(key) {
    var chain = [key.name];

    if(key.shift) chain.unshift("shift-");
    if(key.ctrl) chain.unshift("ctrl-");
    if(key.meta) chain.unshift("meta-");

    return chain.join("")
}

exports.write = function(string) {
    process.stdout.write(string);
}

exports.newLine = function(buffer) {
    if(buffer) exports.write(buffer);
    exports.write('\n');
    exports.buffer('');
}

exports.open = function(ops) {
    if(ops) {
        if(ops.prefix) exports.inputPrefix(ops.prefix);
    }

    if(exports.opened) return;
    exports.opened = true;

	stdin = process.openStdin();
    stdin.setEncoding('utf8');
    process.stdin.setRawMode(true);

    stdin.on('keypress', function(c, key) {

        //integer?
        if(!key) key = { name: c.toString() };
        if(!c) c = key.name;

        var chain = stringRep(key);

        var emitSuccess = chain.length > 1 ? exports.emit(chain) : false;

        //not a handled item to boot? Probably enter, delete, left, right, up, etc. Append it.
        if(!emitSuccess && c) {
            if(!_buffer.length) {
                exports.insertText(exports.inputPrefix(), _cursorPosition);
            }
            exports.insertText(c, _cursorPosition);
            //exports.insertText(c, Math.max(_cursorPosition, exports.inputPrefix().length));
        }

        //new line? reset
        if(key && key.name == 'enter') {
            //exports.replaceLine(exports.buffer().magenta);
            process.stdout.write('\n');
            _buffer = '';
            _cursorPosition = 0;
            //exports.insertText(exports.inputPrefix(), _cursorPosition);
            //exports.cursor(0);
        }

        //for custom handlers: password, confirm, etc.
        exports.emit('keypress', { char: c, key: key });

        //character code?
        if(key.name.length == 1) {
            exports.emit('charpress', c);
        }

    });
}

exports.parse = function(args, callback) {

    args = args.concat().splice(2);

    var self = this;
    var command = [],
    data = {};

    while(args.length) {
        var arg = args.shift();

        if(arg.substr(0,2) != '--') {
            command.push(arg);
        } else {
            args.unshift(arg);
            break;
        }
    }

    while(args.length) {
        var arg = args.shift();

        if(arg.substr(0,2) == '--') {
            var argParts = arg.substr(2).split('=');
            data[argParts[0]] = argParts[1] || true;
        }
    }

    var cmd = { command: command, data: data };

    exports.next(function() {

        if(!self.emit(command, data)) {
            if(command.join('').length) {
                var err = new Error('command "'+command.join(' ')+'" does not exist')

                if(callback) return callback(err, cmd);

                console.error(err.message);
            }
            self.emit('help');
            return;
        }

        this();
        if(callback) callback(null, cmd);
    });

    return cmd;
}

plugin(exports).
params({}).
require(__dirname + "/plugins").
load(function(err) {
    if(err) {
        console.error(err.stack);
        process.exit();
    }
});

exports.plugin = function() {
    return celeri
}

<commit_msg>cleanup<commit_after>var tty = require('tty'),
fs = require('fs'),
_buffer = '',
plugin = require("plugin");

require("colors");

require("keypress")(process.stdin);

exports.utils = require('./utils');

var queue = require('tq').queue().start();

exports.queue = queue.fn;

var _inputPrefix = '> ';

/**
 * queued commands
 */

exports.next = function(callback) {
	queue.push(callback);

	return this;
}

/**
 * size of the terminal window
 */

exports.size = function() {
    return process.stdout.getWindowSize();
}

/**
 * number of columns in the terminal window (characters / width)
 */

exports.columns = function() {
    return exports.size()[0] || exports.size();
}

/**
 * number of rows in the terminal window
 */

exports.rows = function() {
    return exports.size()[1];
}

/**
 */

exports.inputPrefix = function(prefix) {
    if(!arguments.length) return _inputPrefix;

    return _inputPrefix = prefix || '';
}

/**
 */

exports.buffer = function(value, ignoreReplace) {
    if(!arguments.length) return _buffer;

    _buffer = value;

    return !ignoreReplace ? exports.replaceLine(value) : value;
}

/**
 * Replaces the current line in the terminal window
 */

exports.replaceLine = function(buffer, cursorTo) {

    if(!buffer) buffer = "";

    //need to clear the line before replacing it
    process.stdout.clearLine();

    //set the cursor to zero, otherwise we'll have padding we don't want
    exports.cursor(0);

    //write the buffer
    process.stdout.write(buffer);

    //set the cursor to the new position!
    exports.cursor(cursorTo != undefined ? cursorTo : buffer.length);

    return _buffer = buffer;
}

/**
 * inserts text into the current line
 */

exports.insertText = function(str, position) {
    var buffer = exports.buffer();
    exports.replaceLine(buffer.substr(0, position) + str + buffer.substr(position), position + str.length);
}

/**
 * Takes a chunk of text out of the current line
 */

exports.spliceLine = function(position, length, newCursor) {

    var buffer = exports.buffer();
    exports.replaceLine(buffer.substr(0, position) + buffer.substr(position + length), newCursor);
}

var _cursorPosition = 0;

/**
 */

exports.cursor = function(position) {
   if(!arguments.length) return _cursorPosition;

   process.stdout.cursorTo(position);

   return _cursorPosition = position;
}

function stringRep(key) {
    var chain = [key.name];

    if(key.shift) chain.unshift("shift-");
    if(key.ctrl) chain.unshift("ctrl-");
    if(key.meta) chain.unshift("meta-");

    return chain.join("")
}

exports.write = function(string) {
    process.stdout.write(string);
}

exports.newLine = function(buffer) {
    if(buffer) exports.write(buffer);
    exports.write('\n');
    exports.buffer('');
}

exports.open = function(ops) {
    if(ops) {
        if(ops.prefix) exports.inputPrefix(ops.prefix);
    }

    if(exports.opened) return;
    exports.opened = true;

	stdin = process.openStdin();
    stdin.setEncoding('utf8');
    process.stdin.setRawMode(true);

    stdin.on('keypress', function(c, key) {

        //integer?
        if(!key) key = { name: c.toString() };
        if(!c) c = key.name;

        var chain = stringRep(key);

        var emitSuccess = chain.length > 1 ? exports.emit(chain) : false;

        //not a handled item to boot? Probably enter, delete, left, right, up, etc. Append it.
        if(!emitSuccess && c) {
            if(!_buffer.length) {
                exports.insertText(exports.inputPrefix(), _cursorPosition);
            }
            exports.insertText(c, _cursorPosition);
            //exports.insertText(c, Math.max(_cursorPosition, exports.inputPrefix().length));
        }

        //new line? reset
        if(key && key.name == 'enter') {
            //exports.replaceLine(exports.buffer().magenta);
            process.stdout.write('\n');
            _buffer = '';
            _cursorPosition = 0;
            //exports.insertText(exports.inputPrefix(), _cursorPosition);
            //exports.cursor(0);
        }

        //for custom handlers: password, confirm, etc.
        exports.emit('keypress', { char: c, key: key });

        //character code?
        if(key.name.length == 1) {
            exports.emit('charpress', c);
        }

    });
}

exports.parse = function(args, callback) {

    args = args.concat().splice(2);

    var self = this;
    var command = [],
    data = {};

    while(args.length) {
        var arg = args.shift();

        if(arg.substr(0,2) != '--') {
            command.push(arg);
        } else {
            args.unshift(arg);
            break;
        }
    }

    while(args.length) {
        var arg = args.shift();

        if(arg.substr(0,2) == '--') {
            var argParts = arg.substr(2).split('=');
            data[argParts[0]] = argParts[1] || true;
        }
    }

    var cmd = { command: command, data: data };

    exports.next(function() {

        if(!self.emit(command, data)) {
            if(command.join('').length) {
                var err = new Error('command "'+command.join(' ')+'" does not exist')

                if(callback) return callback(err, cmd);

                console.error(err.message);
            }
            self.emit('help');
            return;
        }

        this();
        if(callback) callback(null, cmd);
    });

    return cmd;
}

plugin(exports).
params({}).
require(__dirname + "/plugins").
load(function(err) {
    if(err) {
        console.error(err.stack);
        process.exit();
    }
});

exports.plugin = function() {
    return exports;
}

<|endoftext|>


<commit_before>var webfinger = require('webfinger').webfinger;
var ProtoNoSupportError = require('./errors/protonosupporterror');
var NoDataError = require('./errors/nodataerror');

module.exports = function() {

  var plugin = {};

  plugin.resolveAliases = function(identifier, cb) {
    webfinger(identifier, { webfingerOnly: true }, function(err, jrd) {
      if (err) {
        // Ignore the error under the assumption that Webfinger is not
        // implemented by the host.  The expectation is that other discovery
        // mechanisms are registered with `fingro` that will be used as
        // alternatives.
        return cb(null);
      }
      if (!jrd.aliases || jrd.aliases.length == 0) {
        return cb(new NoDataError('No aliases in JRD'));
      }

      return cb(null, jrd.aliases);
    });
  }

  plugin.resolveProperties = function(identifier, cb) {
    webfinger(identifier, { webfingerOnly: true }, function(err, jrd) {
      if (err) {
        // Ignore the error under the assumption that Webfinger is not
        // implemented by the host.  The expectation is that other discovery
        // mechanisms are registered with `fingro` that will be used as
        // alternatives.
        return cb(null);
      }
      if (!jrd.properties || jrd.properties.length == 0) {
        return cb(new NoDataError('No properties in JRD'));
      }

      return cb(null, jrd.properties);
    });
  }

  plugin.resolveServices = function(identifier, type, cb) {
    if (typeof type == 'function') {
      cb = type;
      type = undefined;
    }

    webfinger(identifier, type, { webfingerOnly: true }, function(err, jrd) {
      if (err) { return cb(new ProtoNoSupportError(err.message)); }
      if (!jrd.links || jrd.links.length == 0) {
        return cb(new NoDataError('No link relations in resource descriptor'));
      }

      var services = {}
        , links = jrd.links
        , link, i, len
        , instances;
      for (i = 0, len = links.length; i < len; ++i) {
        link = links[i];
        services[link.rel] = (services[link.rel] || []).concat({
          location: link.href,
          mediaType: link.type
        });
      }

      if (type) {
        instances = services[type];
        if (!instances) { return cb(new NoDataError('Link relation not found: ' + type)); }
        return cb(null, instances);
      }
      return cb(null, services);
    });
  }

  return plugin;
}
<commit_msg>Better error handling.<commit_after>var webfinger = require('webfinger').webfinger;
var ProtoNoSupportError = require('./errors/protonosupporterror');
var NoDataError = require('./errors/nodataerror');

module.exports = function() {

  var plugin = {};

  plugin.resolveAliases = function(identifier, cb) {
    webfinger(identifier, { webfingerOnly: true }, function(err, jrd) {
      if (err) { return cb(new ProtoNoSupportError(err.message)); }
      if (!jrd.aliases || jrd.aliases.length == 0) {
        return cb(new NoDataError('No aliases in JRD'));
      }

      return cb(null, jrd.aliases);
    });
  }

  plugin.resolveProperties = function(identifier, cb) {
    webfinger(identifier, { webfingerOnly: true }, function(err, jrd) {
      if (err) { return cb(new ProtoNoSupportError(err.message)); }
      if (!jrd.properties || jrd.properties.length == 0) {
        return cb(new NoDataError('No properties in JRD'));
      }

      return cb(null, jrd.properties);
    });
  }

  plugin.resolveServices = function(identifier, type, cb) {
    if (typeof type == 'function') {
      cb = type;
      type = undefined;
    }

    webfinger(identifier, type, { webfingerOnly: true }, function(err, jrd) {
      if (err) { return cb(new ProtoNoSupportError(err.message)); }
      if (!jrd.links || jrd.links.length == 0) {
        return cb(new NoDataError('No link relations in resource descriptor'));
      }

      var services = {}
        , links = jrd.links
        , link, i, len
        , instances;
      for (i = 0, len = links.length; i < len; ++i) {
        link = links[i];
        services[link.rel] = (services[link.rel] || []).concat({
          location: link.href,
          mediaType: link.type
        });
      }

      if (type) {
        instances = services[type];
        if (!instances) { return cb(new NoDataError('Link relation not found: ' + type)); }
        return cb(null, instances);
      }
      return cb(null, services);
    });
  }

  return plugin;
}
<|endoftext|>


<commit_before>'use strict';

const debug = require('debug')('koa-spec');
const _ = require('lodash');
const path = require('path');
const HTTPStatus = require('http-status');
const utils = require('./utils');
const parseBoolean = utils.parseBoolean;
const errors = require('./errors');

const RouterError = errors.RouterError;

const RouteError = errors.RouteError;
const RouteNotImplementedError = errors.RouteNotImplementedError;

const ParameterValidationError = errors.ParameterValidationError;

const SourceValidationError = errors.SourceValidationError;
const RequiredValidationError = errors.RequiredValidationError;
const NullableValidationError = errors.NullableValidationError;
const TypeValidationError = errors.TypeValidationError;
const FormatValidationError = errors.FormatValidationError;

const CONTROLLER_DIRECTORY_DEFAULT = './controllers';
const STRICT_MODE_DEFAULT = true;

const INTEGER_INT32_MAX_VALUE = 2147483647;
const INTEGER_INT32_MIN_VALUE = -2147483648;
const INTEGER_INT64_MAX_VALUE = Number.MAX_SAFE_INTEGER;
const INTEGER_INT64_MIN_VALUE = Number.MIN_SAFE_INTEGER;
const NUMBER_FLOAT_MIN_VALUE = -3.4028235E38;
const NUMBER_FLOAT_MAX_VALUE = 3.4028235E38;

module.exports = function (uri, options) {
  const refOptions = (options && options.refOptions) ? options.refOptions : undefined;
  const spec = utils.readSpec(uri, refOptions);

  const routerOptions = (options && options.routerOptions) ? options.routerOptions : undefined;
  const router = createRouter(spec, routerOptions);

  return {
    spec   : spec.resolved,
    refs   : spec.refs,
    router : router
  }
};

function createRouter(spec, options) {
  function getControllerMethod(controllerDirectory, controllerName, controllerMethodName, strictMode, method, route) {
    if (!controllerName) {
      throw new RouteError(method, route, `Controller name not specified. Specify via 'x-controller'.`);
    }

    const controllerPath = path.join(controllerDirectory, controllerName);
    if (!utils.isRequireResolvable(controllerPath)) {
      if (strictMode) {
        throw new RouteError(method, route, `Controller '${controllerName}' does not exist.`);
      }
    } else {
      if (!controllerMethodName) {
        throw new RouteError(method, route, `Controller '${controllerName}' method name not specified. Specify via 'x-controller-method'.`);
      }
      const controller = require(controllerPath);
      const controllerMethod = controller[controllerMethodName];
      if (controllerMethod) {
        return controllerMethod;
      }
      if (strictMode) {
        throw new RouteError(method, route, `Controller '${controllerName}' does not have a method '${controllerMethodName}'.`);
      }
    }

    /* Fallback */
    return createNotImplementedControllerMethod(method, route);
  }

  function createNotImplementedControllerMethod(method, route) {
    return function* (next) {
      this.status = HTTPStatus.NOT_IMPLEMENTED;
      const err = new RouteNotImplementedError(method, route);
      this.body = {
        code    : err.code,
        message : err.message,
        route   : {
          method : method,
          path   : route
        }
      };
    }
  }

  return function () {
    const koarouter = require('koa-router');
    if (!koarouter) {
      throw new RouterError(`Module 'koa-router' isn't available. Install via 'npm install --save koa-router'.`)
    }
    const router = koarouter();

    const controllerDirectory = (options && !_.isUndefined(options.controllerDirectory)) ? options.controllerDirectory : CONTROLLER_DIRECTORY_DEFAULT;
    const strictMode = (options && !_.isUndefined(options.strictMode)) ? options.strictMode : STRICT_MODE_DEFAULT;

    if (!utils.isDirectory(controllerDirectory)) {
      throw new RouterError(`Controller directory '${controllerDirectory}' does not exist.`);
    }

    const routes = spec.resolved.paths;
    _.forOwn(routes, function (methods, route) {

      /* Convert from spec to router parameter syntax: */
      route = route.replace(/{[^/]*}/g, function replacer(match) {
        /* Cut first and last character, prepend with colon: */
        return ':' + match.slice(1, -1);
      });

      _.forOwn(methods, function (methodInfo, method) {
        const controllerName = methodInfo['x-controller'];
        const controllerMethodName = methodInfo['x-controller-method'];

        const controllerMethod = getControllerMethod(controllerDirectory, controllerName, controllerMethodName, strictMode, method, route);

        if (router[method]) {
          // Check if any of the parameters of this method uses a body parameter:
          const bodyParameter = _.find(methodInfo.parameters, {in : 'body'});
          if (bodyParameter) {
            // Make sure the koa-bodyparser is available:
            if (!require('koa-bodyparser')) {
              throw new RouteError(method, route, `Detected 'body' parameter: '${bodyParameter.name}' but module 'koa-bodyparser' isn't available. Install via 'npm install --save koa-bodyparser'.`)
            }
          }
          const requestValidator = createRequestValidator(spec, method, route, methodInfo.parameters);
          router[method](route, requestValidator, controllerMethod);
        } else {
          throw new RouteError(method, route, `Method '${method}' does not exist.`);
        }
      });
    });

    return router;
  }
}

function createRequestValidator(spec, method, route, parameterDefinitions) {
  function validateBoolean(name, type, format, value) {
    const actualValue = parseBoolean(value);

    if (!_.isBoolean(actualValue)) {
      throw new TypeValidationError(name, type, format, value, `Not a 'boolean'.`);
    }

    return actualValue;
  }

  function validateInteger(name, type, format, value) {
    const actualValue = parseInt(value, 10);

    if (isNaN(actualValue)) {
      throw new TypeValidationError(name, type, format, value, `Not an 'integer'.`);
    } else if (parseFloat(value) % 1 !== 0) { // Checks if this actually was a float, not an integer!
      throw new TypeValidationError(name, type, format, value, `Not an 'integer'.`);
    }

    switch (format) {
      case 'int32':
        return validateIntegerInt32(name, type, format, value, actualValue);
      case 'int64':
        return validateIntegerInt64(name, type, format, value, actualValue);
      default:
        throw new FormatValidationError(name, type, format, value, `Unknown format: ${format}.`);
    }
  }

  function validateIntegerInt32(name, type, format, value, actualValue) {
    if (actualValue > INTEGER_INT32_MAX_VALUE) {
      throw new FormatValidationError(name, type, format, value, `Maximum integer (int32) value: ${INTEGER_INT32_MAX_VALUE}.`);
    } else if (actualValue < INTEGER_INT32_MIN_VALUE) {
      throw new FormatValidationError(name, type, format, value, `Minimum integer (int32) value: ${INTEGER_INT32_MIN_VALUE}.`);
    }
    return actualValue;
  }

  function validateIntegerInt64(name, type, format, value, actualValue) {
    if (actualValue > INTEGER_INT64_MAX_VALUE) {
      throw new FormatValidationError(name, type, format, value, `Maximum integer (int64) value: ${INTEGER_INT64_MAX_VALUE}.`);
    } else if (actualValue < INTEGER_INT64_MIN_VALUE) {
      throw new FormatValidationError(name, type, format, value, `Minimum integer (int64) value: ${INTEGER_INT64_MIN_VALUE}.`);
    }
    return actualValue;
  }

  function validateNumber(name, type, format, value) {
    const actualValue = parseFloat(value);
    if (isNaN(actualValue)) {
      throw new TypeValidationError(name, type, format, value, `Not a 'number'.`);
    }

    switch (format) {
      case 'float':
        return validateNumberFloat(name, type, format, value, actualValue);
      case 'double':
        return validateNumberDouble(name, type, format, value, actualValue);
      default:
        throw new FormatValidationError(name, type, format, value, `Unknown format: ${format}.`);
    }
  }

  function validateNumberFloat(name, type, format, value, actualValue) {
    if (actualValue > NUMBER_FLOAT_MAX_VALUE) {
      throw new FormatValidationError(name, type, format, value, `Maximum number (float) value: ${NUMBER_FLOAT_MAX_VALUE}.`);
    } else if (actualValue < NUMBER_FLOAT_MIN_VALUE) {
      throw new FormatValidationError(name, type, format, value, `Minimum number (float) value: ${NUMBER_FLOAT_MIN_VALUE}.`);
    }
    return actualValue;
  }

  function validateNumberDouble(name, type, format, value, actualValue) {
    return actualValue;
  }

  function validateString(name, type, format, value) {
    const actualValue = value;
    if (!_.isString(actualValue)) {
      throw new TypeValidationError(name, type, format, value, `Not a 'string'.`);
    }

    switch (format) {
      case undefined:
        // No specified format means a simple string. Nothing to check for here.
        return actualValue;
      case 'uuid':
        return validateStringUUID(name, type, format, value, actualValue);
      case 'isbn':
        return validateStringISBN(name, type, format, value, actualValue);
      default:
        throw new FormatValidationError(name, type, format, value, `Unknown format: ${format}.`);
    }
  }

  function validateStringUUID(name, type, format, value, actualValue) {
    if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)) {
      throw new FormatValidationError(name, type, format, value, `Not a 'uuid'.`);
    }
    return actualValue;
  }

  function validateStringISBN(name, type, format, value, actualValue) {
    if (!/^(?=[0-9X]{10}$|(?=(?:[0-9]+[- ]){3})[- 0-9X]{13}$|97[89][0-9]{10}$|(?=(?:[0-9]+[- ]){4})[- 0-9]{17}$)(?:97[89][- ]?)?[0-9]{1,5}[- ]?[0-9]+[- ]?[0-9]+[- ]?[0-9X]$/i.test(value)) {
      throw new FormatValidationError(name, type, format, value, `Not a 'isbn'.`);
    }
    return actualValue;
  }

  function validateArray(name, type, format, items, values) {
    if (!_.isArray(values)) {
      throw new TypeValidationError(name, type, format, values, `Not an 'array'.`);
    }
    if (!items) {
      throw new TypeValidationError(name, type, format, values, `Items not found.`);
    }
    const refName = items['$ref'];
    if (refName) {
      const ref = spec.refs[`${refName}/properties/${name}/items`];
      items = _.get(spec.resolved, utils.pathFromPtr(ref.uri).join('.'));
    }

    return _.map(values, value => {
      return validateProperties(name, type, format, items.properties, items.required, value);
    });
  }

  function validateProperties(name, type, format, properties, required, value) {
    const actualValue = {};
    if (!properties) {
      throw new TypeValidationError(name, type, format, value, `Properties not found.`);
    }

    _.forOwn(properties, (propertyInfo, propertyName) => {
      const refName = propertyInfo['$ref'];
      if (refName) {
        const ref = spec.refs[`${refName}/properties/${propertyName}`];
        propertyInfo = _.get(spec.resolved, utils.pathFromPtr(ref.uri).join('.'));
      }

      const propertyValue = value[propertyName];
      /* Check for required properties: */
      if (_.includes(required, propertyName)) {
        if (_.isUndefined(propertyValue)) {
          throw new RequiredValidationError(propertyName, propertyInfo.type, propertyInfo.format, undefined, '');
        }
      } else {
        if (_.isUndefined(propertyValue)) {
          return;
        }
      }

      const validatedPropertyValue = validateValue(propertyName, propertyInfo.type, propertyInfo.format, propertyInfo['x-nullable'], propertyInfo.items, propertyInfo.properties, propertyInfo.required, propertyValue);
      actualValue[propertyName] = validatedPropertyValue;
    });
    return actualValue;
  }

  function validateValue(name, type, format, nullable, items, properties, required, value) {
    if (_.isNull(value)){
      if (!_.isUndefined(nullable)) {
        if (nullable) {
          return null;
        } else {
          throw new NullableValidationError(name, type, format, value, `Can not be 'null'.`);
        }
      }
    }

    switch (type) {
      case 'boolean':
        return validateBoolean(name, type, format, value);
      case 'integer':
        return validateInteger(name, type, format, value);
      case 'number':
        return validateNumber(name, type, format, value);
      case 'string':
        return validateString(name, type, format, value);
      case 'object':
        return validateProperties(name, type, format, properties, required, value);
      case 'array':
        return validateArray(name, type, format, items, value);
      default:
        throw new TypeValidationError(name, type, format, value, `Unsupported type: '${type}'.`);
    }
  }

  function validateSchema(name, type, format, schema, value) {
    if (!schema) {
      throw new TypeValidationError(name, type, format, value, `Schema not found.`);
    }

    switch (schema.type) {
      case 'object':
        return validateProperties(name, type, format, schema.properties, schema.required, value);
      case 'array':
        return validateArray(name, type, format, schema.items, value);
      default:
        throw new TypeValidationError(name, type, format, value, `Unsupported schema type: '${schema.type}'.`);
    }
  }

  function validateParameter(parameterDefinition, parameterValue) {
    try {
      if (parameterDefinition.required) {
        if (_.isUndefined(parameterValue)) {
          throw new RequiredValidationError(parameterDefinition.name, parameterDefinition.type, parameterDefinition.format, undefined, '');
        }
      } else {
        if (_.isUndefined(parameterValue)) {
          return parameterValue;
        }
      }

      if (parameterDefinition.in === 'body') {
        return validateSchema(parameterDefinition.name, parameterDefinition.type, parameterDefinition.format, parameterDefinition.schema, parameterValue);
      } else {
        return validateValue(parameterDefinition.name, parameterDefinition.type, parameterDefinition.format, undefined, parameterDefinition.items, undefined, undefined, parameterValue);
      }
    } catch (err) {
      throw new ParameterValidationError(parameterDefinition, parameterValue, err);
    }
  }

  function getParameterValue(ctx, parameterDefinition) {
    const parameterSource = getRequestParameterSource(ctx, parameterDefinition);
    switch (parameterDefinition.in) {
      case 'body':
        return parameterSource;
      default:
        return parameterSource[parameterDefinition.name];
    }
  }

  function setParameterValue(ctx, parameterDefinition, validatedParameterValue) {
    if (parameterDefinition.in === 'body') {
      ctx.request.body = validatedParameterValue;
    } else {
      const parameterSource = getRequestParameterSource(ctx, parameterDefinition);
      parameterSource[parameterDefinition.name] = validatedParameterValue;
    }
  }

  function getRequestParameterSource(ctx, parameterDefinition) {
    switch (parameterDefinition.in) {
      case 'path':
        return ctx.params;
      case 'query':
        return ctx.query;
      case 'body':
        return ctx.request.body;
      default:
        throw new ParameterValidationError(parameterDefinition, undefined, new SourceValidationError(parameterDefinition.name, parameterDefinition.type, parameterDefinition.format, undefined, `Unknown source: '${parameterDefinition.in}'.`));
    }
  }

  function validateParameters(ctx) {
    _.forEach(parameterDefinitions, parameterDefinition => {
      const parameterValue = getParameterValue(ctx, parameterDefinition);
      const validatedParameterValue = validateParameter(parameterDefinition, parameterValue);
      setParameterValue(ctx, parameterDefinition, validatedParameterValue);
    });
  }

  return function* validateRequest(next) {
    try {
      validateParameters(this);

      yield next;
    } catch (err) {
      debug(err);

      this.status = HTTPStatus.BAD_REQUEST;
      this.body = {
        code      : err.code,
        message   : err.message,
        route     : {
          method : method,
          path   : route
        },
        parameter : {
          expected : err.parameterDefinition,
          actual   : err.parameterValue
        }
      }
    }
  };
}<commit_msg>:lipstick: Codeclimate complexity analysis change.<commit_after>'use strict';

const debug = require('debug')('koa-spec');
const _ = require('lodash');
const path = require('path');
const HTTPStatus = require('http-status');
const utils = require('./utils');
const parseBoolean = utils.parseBoolean;
const errors = require('./errors');

const RouterError = errors.RouterError;

const RouteError = errors.RouteError;
const RouteNotImplementedError = errors.RouteNotImplementedError;

const ParameterValidationError = errors.ParameterValidationError;

const SourceValidationError = errors.SourceValidationError;
const RequiredValidationError = errors.RequiredValidationError;
const NullableValidationError = errors.NullableValidationError;
const TypeValidationError = errors.TypeValidationError;
const FormatValidationError = errors.FormatValidationError;

const CONTROLLER_DIRECTORY_DEFAULT = './controllers';
const STRICT_MODE_DEFAULT = true;

const INTEGER_INT32_MAX_VALUE = 2147483647;
const INTEGER_INT32_MIN_VALUE = -2147483648;
const INTEGER_INT64_MAX_VALUE = Number.MAX_SAFE_INTEGER;
const INTEGER_INT64_MIN_VALUE = Number.MIN_SAFE_INTEGER;
const NUMBER_FLOAT_MIN_VALUE = -3.4028235E38;
const NUMBER_FLOAT_MAX_VALUE = 3.4028235E38;

module.exports = function (uri, options) {
  const refOptions = (options && options.refOptions) ? options.refOptions : undefined;
  const spec = utils.readSpec(uri, refOptions);

  const routerOptions = (options && options.routerOptions) ? options.routerOptions : undefined;
  const router = createRouter(spec, routerOptions);

  return {
    spec   : spec.resolved,
    refs   : spec.refs,
    router : router
  }
};

function createRouter(spec, options) {
  function getControllerMethod(controllerDirectory, controllerName, controllerMethodName, strictMode, method, route) {
    if (!controllerName) {
      throw new RouteError(method, route, `Controller name not specified. Specify via 'x-controller'.`);
    }

    const controllerPath = path.join(controllerDirectory, controllerName);
    if (!utils.isRequireResolvable(controllerPath)) {
      if (strictMode) {
        throw new RouteError(method, route, `Controller '${controllerName}' does not exist.`);
      }
    } else {
      if (!controllerMethodName) {
        throw new RouteError(method, route, `Controller '${controllerName}' method name not specified. Specify via 'x-controller-method'.`);
      }
      const controller = require(controllerPath);
      const controllerMethod = controller[controllerMethodName];
      if (controllerMethod) {
        return controllerMethod;
      }
      if (strictMode) {
        throw new RouteError(method, route, `Controller '${controllerName}' does not have a method '${controllerMethodName}'.`);
      }
    }

    /* Fallback */
    return createNotImplementedControllerMethod(method, route);
  }

  function createNotImplementedControllerMethod(method, route) {
    return function* (next) {
      this.status = HTTPStatus.NOT_IMPLEMENTED;
      const err = new RouteNotImplementedError(method, route);
      this.body = {
        code    : err.code,
        message : err.message,
        route   : {
          method : method,
          path   : route
        }
      };
    }
  }

  return function () {
    const koarouter = require('koa-router');
    if (!koarouter) {
      throw new RouterError(`Module 'koa-router' isn't available. Install via 'npm install --save koa-router'.`)
    }
    const router = koarouter();

    const controllerDirectory = (options && !_.isUndefined(options.controllerDirectory)) ? options.controllerDirectory : CONTROLLER_DIRECTORY_DEFAULT;
    const strictMode = (options && !_.isUndefined(options.strictMode)) ? options.strictMode : STRICT_MODE_DEFAULT;

    if (!utils.isDirectory(controllerDirectory)) {
      throw new RouterError(`Controller directory '${controllerDirectory}' does not exist.`);
    }

    const routes = spec.resolved.paths;
    _.forOwn(routes, function (methods, route) {

      /* Convert from spec to router parameter syntax: */
      route = route.replace(/{[^/]*}/g, function replacer(match) {
        /* Cut first and last character, prepend with colon: */
        return ':' + match.slice(1, -1);
      });

      _.forOwn(methods, function (methodInfo, method) {
        const controllerName = methodInfo['x-controller'];
        const controllerMethodName = methodInfo['x-controller-method'];

        const controllerMethod = getControllerMethod(controllerDirectory, controllerName, controllerMethodName, strictMode, method, route);

        if (router[method]) {
          // Check if any of the parameters of this method uses a body parameter:
          const bodyParameter = _.find(methodInfo.parameters, {in : 'body'});
          if (bodyParameter) {
            // Make sure the koa-bodyparser is available:
            if (!require('koa-bodyparser')) {
              throw new RouteError(method, route, `Detected 'body' parameter: '${bodyParameter.name}' but module 'koa-bodyparser' isn't available. Install via 'npm install --save koa-bodyparser'.`)
            }
          }
          const requestValidator = createRequestValidator(spec, method, route, methodInfo.parameters);
          router[method](route, requestValidator, controllerMethod);
        } else {
          throw new RouteError(method, route, `Method '${method}' does not exist.`);
        }
      });
    });

    return router;
  }
}

function createRequestValidator(spec, method, route, parameterDefinitions) {
  function validateBoolean(name, type, format, value) {
    const actualValue = parseBoolean(value);

    if (!_.isBoolean(actualValue)) {
      throw new TypeValidationError(name, type, format, value, `Not a 'boolean'.`);
    }

    return actualValue;
  }

  function validateInteger(name, type, format, value) {
    const actualValue = parseInt(value, 10);

    if (isNaN(actualValue)) {
      throw new TypeValidationError(name, type, format, value, `Not an 'integer'.`);
    } else if (parseFloat(value) % 1 !== 0) { // Checks if this actually was a float, not an integer!
      throw new TypeValidationError(name, type, format, value, `Not an 'integer'.`);
    }

    switch (format) {
      case 'int32':
        return validateIntegerInt32(name, type, format, value, actualValue);
      case 'int64':
        return validateIntegerInt64(name, type, format, value, actualValue);
      default:
        throw new FormatValidationError(name, type, format, value, `Unknown format: ${format}.`);
    }
  }

  function validateIntegerInt32(name, type, format, value, actualValue) {
    if (actualValue > INTEGER_INT32_MAX_VALUE) {
      throw new FormatValidationError(name, type, format, value, `Maximum integer (int32) value: ${INTEGER_INT32_MAX_VALUE}.`);
    } else if (actualValue < INTEGER_INT32_MIN_VALUE) {
      throw new FormatValidationError(name, type, format, value, `Minimum integer (int32) value: ${INTEGER_INT32_MIN_VALUE}.`);
    }
    return actualValue;
  }

  function validateIntegerInt64(name, type, format, value, actualValue) {
    if (actualValue > INTEGER_INT64_MAX_VALUE) {
      throw new FormatValidationError(name, type, format, value, `Maximum integer (int64) value: ${INTEGER_INT64_MAX_VALUE}.`);
    } else if (actualValue < INTEGER_INT64_MIN_VALUE) {
      throw new FormatValidationError(name, type, format, value, `Minimum integer (int64) value: ${INTEGER_INT64_MIN_VALUE}.`);
    }
    return actualValue;
  }

  function validateNumber(name, type, format, value) {
    const actualValue = parseFloat(value);
    if (isNaN(actualValue)) {
      throw new TypeValidationError(name, type, format, value, `Not a 'number'.`);
    }

    switch (format) {
      case 'float':
        return validateNumberFloat(name, type, format, value, actualValue);
      case 'double':
        return validateNumberDouble(name, type, format, value, actualValue);
      default:
        throw new FormatValidationError(name, type, format, value, `Unknown format: ${format}.`);
    }
  }

  function validateNumberFloat(name, type, format, value, actualValue) {
    if (actualValue > NUMBER_FLOAT_MAX_VALUE) {
      throw new FormatValidationError(name, type, format, value, `Maximum number (float) value: ${NUMBER_FLOAT_MAX_VALUE}.`);
    } else if (actualValue < NUMBER_FLOAT_MIN_VALUE) {
      throw new FormatValidationError(name, type, format, value, `Minimum number (float) value: ${NUMBER_FLOAT_MIN_VALUE}.`);
    }
    return actualValue;
  }

  function validateNumberDouble(name, type, format, value, actualValue) {
    return actualValue;
  }

  function validateString(name, type, format, value) {
    const actualValue = value;
    if (!_.isString(actualValue)) {
      throw new TypeValidationError(name, type, format, value, `Not a 'string'.`);
    }

    switch (format) {
      case undefined:
        // No specified format means a simple string. Nothing to check for here.
        return actualValue;
      case 'uuid':
        return validateStringUUID(name, type, format, value, actualValue);
      case 'isbn':
        return validateStringISBN(name, type, format, value, actualValue);
      default:
        throw new FormatValidationError(name, type, format, value, `Unknown format: ${format}.`);
    }
  }

  function validateStringUUID(name, type, format, value, actualValue) {
    if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)) {
      throw new FormatValidationError(name, type, format, value, `Not a 'uuid'.`);
    }
    return actualValue;
  }

  function validateStringISBN(name, type, format, value, actualValue) {
    if (!/^(?=[0-9X]{10}$|(?=(?:[0-9]+[- ]){3})[- 0-9X]{13}$|97[89][0-9]{10}$|(?=(?:[0-9]+[- ]){4})[- 0-9]{17}$)(?:97[89][- ]?)?[0-9]{1,5}[- ]?[0-9]+[- ]?[0-9]+[- ]?[0-9X]$/i.test(value)) {
      throw new FormatValidationError(name, type, format, value, `Not a 'isbn'.`);
    }
    return actualValue;
  }

  function validateArray(name, type, format, items, values) {
    if (!_.isArray(values)) {
      throw new TypeValidationError(name, type, format, values, `Not an 'array'.`);
    }
    if (!items) {
      throw new TypeValidationError(name, type, format, values, `Items not found.`);
    }
    const refName = items['$ref'];
    if (refName) {
      const ref = spec.refs[`${refName}/properties/${name}/items`];
      items = _.get(spec.resolved, utils.pathFromPtr(ref.uri).join('.'));
    }

    return _.map(values, value => {
      return validateProperties(name, type, format, items.properties, items.required, value);
    });
  }

  function validateProperties(name, type, format, properties, required, value) {
    const actualValue = {};
    if (!properties) {
      throw new TypeValidationError(name, type, format, value, `Properties not found.`);
    }

    _.forOwn(properties, (propertyInfo, propertyName) => {
      const refName = propertyInfo['$ref'];
      if (refName) {
        const ref = spec.refs[`${refName}/properties/${propertyName}`];
        propertyInfo = _.get(spec.resolved, utils.pathFromPtr(ref.uri).join('.'));
      }

      const propertyValue = value[propertyName];
      /* Check for required properties: */
      if (_.includes(required, propertyName)) {
        if (_.isUndefined(propertyValue)) {
          throw new RequiredValidationError(propertyName, propertyInfo.type, propertyInfo.format, undefined, '');
        }
      } else {
        if (_.isUndefined(propertyValue)) {
          return;
        }
      }

      const validatedPropertyValue = validateValue(propertyName, propertyInfo.type, propertyInfo.format, propertyInfo['x-nullable'], propertyInfo.items, propertyInfo.properties, propertyInfo.required, propertyValue);
      actualValue[propertyName] = validatedPropertyValue;
    });
    return actualValue;
  }

  function validateValue(name, type, format, nullable, items, properties, required, value) {
    if (_.isNull(value)){
      if (!_.isUndefined(nullable)) {
        if (nullable) {
          return null;
        } else {
          throw new NullableValidationError(name, type, format, value, `Can not be 'null'.`);
        }
      }
    }

    return validateValueType(name, type, format, nullable, items, properties, required, value);
  }

  function validateValueType(name, type, format, nullable, items, properties, required, value) {
    switch (type) {
      case 'boolean':
        return validateBoolean(name, type, format, value);
      case 'integer':
        return validateInteger(name, type, format, value);
      case 'number':
        return validateNumber(name, type, format, value);
      case 'string':
        return validateString(name, type, format, value);
      case 'object':
        return validateProperties(name, type, format, properties, required, value);
      case 'array':
        return validateArray(name, type, format, items, value);
      default:
        throw new TypeValidationError(name, type, format, value, `Unsupported type: '${type}'.`);
    }
  }

  function validateSchema(name, type, format, schema, value) {
    if (!schema) {
      throw new TypeValidationError(name, type, format, value, `Schema not found.`);
    }

    switch (schema.type) {
      case 'object':
        return validateProperties(name, type, format, schema.properties, schema.required, value);
      case 'array':
        return validateArray(name, type, format, schema.items, value);
      default:
        throw new TypeValidationError(name, type, format, value, `Unsupported schema type: '${schema.type}'.`);
    }
  }

  function validateParameter(parameterDefinition, parameterValue) {
    try {
      if (parameterDefinition.required) {
        if (_.isUndefined(parameterValue)) {
          throw new RequiredValidationError(parameterDefinition.name, parameterDefinition.type, parameterDefinition.format, undefined, '');
        }
      } else {
        if (_.isUndefined(parameterValue)) {
          return parameterValue;
        }
      }

      if (parameterDefinition.in === 'body') {
        return validateSchema(parameterDefinition.name, parameterDefinition.type, parameterDefinition.format, parameterDefinition.schema, parameterValue);
      } else {
        return validateValue(parameterDefinition.name, parameterDefinition.type, parameterDefinition.format, undefined, parameterDefinition.items, undefined, undefined, parameterValue);
      }
    } catch (err) {
      throw new ParameterValidationError(parameterDefinition, parameterValue, err);
    }
  }

  function getParameterValue(ctx, parameterDefinition) {
    const parameterSource = getRequestParameterSource(ctx, parameterDefinition);
    switch (parameterDefinition.in) {
      case 'body':
        return parameterSource;
      default:
        return parameterSource[parameterDefinition.name];
    }
  }

  function setParameterValue(ctx, parameterDefinition, validatedParameterValue) {
    if (parameterDefinition.in === 'body') {
      ctx.request.body = validatedParameterValue;
    } else {
      const parameterSource = getRequestParameterSource(ctx, parameterDefinition);
      parameterSource[parameterDefinition.name] = validatedParameterValue;
    }
  }

  function getRequestParameterSource(ctx, parameterDefinition) {
    switch (parameterDefinition.in) {
      case 'path':
        return ctx.params;
      case 'query':
        return ctx.query;
      case 'body':
        return ctx.request.body;
      default:
        throw new ParameterValidationError(parameterDefinition, undefined, new SourceValidationError(parameterDefinition.name, parameterDefinition.type, parameterDefinition.format, undefined, `Unknown source: '${parameterDefinition.in}'.`));
    }
  }

  function validateParameters(ctx) {
    _.forEach(parameterDefinitions, parameterDefinition => {
      const parameterValue = getParameterValue(ctx, parameterDefinition);
      const validatedParameterValue = validateParameter(parameterDefinition, parameterValue);
      setParameterValue(ctx, parameterDefinition, validatedParameterValue);
    });
  }

  return function* validateRequest(next) {
    try {
      validateParameters(this);

      yield next;
    } catch (err) {
      debug(err);

      this.status = HTTPStatus.BAD_REQUEST;
      this.body = {
        code      : err.code,
        message   : err.message,
        route     : {
          method : method,
          path   : route
        },
        parameter : {
          expected : err.parameterDefinition,
          actual   : err.parameterValue
        }
      }
    }
  };
}<|endoftext|>


<commit_before>var Account = require("./Account")

exports.Account = Account

exports.createClient = function(credentials) {
  return new Account(credentials).database
}<commit_msg>fall back to env credentials<commit_after>var Account = require("./Account")

exports.Account = Account

exports.createClient = function(credentials) {
  if (!credentials) {
    credentials = {
      accessKeyId: process.env.AWS_ACCESS_KEY_ID,
      secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
    }
  }

  return new Account(credentials).database
}<|endoftext|>


<commit_before>const $npm = {
  dbMigrate: require('./dbMigrate'),
  debug: require('debug')('pg-migration:index'),
  promise: require('bluebird'),
  dbConnection: require('./dbConnection')
};

function $main(opts) {
  $npm.debug('run');

  if(!(opts.connection || process.env.DATABASE_URL)) {
    throw new Error('connection or connection string not provided');
  }
  if( !opts.migrations ) {
    throw new Error('Migrations not provided.');
  }

  //document available options and default them.
  var options = {
    connection: $npm.dbConnection(opts.connection || process.env.DATABASE_URL), //establish the connection
    migrations: opts.migrations
  };

  return $npm
    .dbMigrate(options.connection, options.migrations)
    .then(function(r) {
      //Whether we should use this is debatable. I imagine the author of pg-promise would say not to.
      // The alternative is allow the pgp instance to be passed in and thus allow us to use the
      //  parent app's instance. This complicates the interface, however.
      options.connection.$config.pgp.end(); //https://github.com/vitaly-t/pg-promise/issues/261
      return r;
    });
}

module.exports = $main;<commit_msg>Starting point documentation.<commit_after>const $npm = {
  dbMigrate: require('./dbMigrate'),
  debug: require('debug')('pg-migration:index'),
  promise: require('bluebird'),
  dbConnection: require('./dbConnection')
};

/**
 * Entry point.
 * @param opts object with {connection: [see url], migrations: [see readme]
 * @returns {*} A promise which resolves when we're done.
 */
function $main(opts) {
  $npm.debug('run');

  if(!(opts.connection || process.env.DATABASE_URL)) {
    throw new Error('connection or connection string not provided');
  }
  if( !opts.migrations ) {
    throw new Error('Migrations not provided.');
  }

  //document available options and default them.
  var options = {
    connection: $npm.dbConnection(opts.connection || process.env.DATABASE_URL), //establish the connection
    migrations: opts.migrations
  };

  return $npm
    .dbMigrate(options.connection, options.migrations)
    .then(function(r) {
      //Whether we should use this is debatable. I imagine the author of pg-promise would say not to.
      // The alternative is allow the pgp instance to be passed in and thus allow us to use the
      //  parent app's instance. This complicates the interface, however.
      options.connection.$config.pgp.end(); //https://github.com/vitaly-t/pg-promise/issues/261
      return r;
    });
}

module.exports = $main;<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';

export default class Truncate extends Component {
    static propTypes = {
        children: PropTypes.node,
        ellipsis: PropTypes.node,
        lines: PropTypes.oneOfType([
            PropTypes.oneOf([false]),
            PropTypes.number
        ])
    };

    static defaultProps = {
        children: '',
        ellipsis: '…',
        lines: 1
    };

    state = {};

    componentDidMount() {
        // Node not needed in document tree to read its content
        this.refs.raw.parentNode.removeChild(this.refs.raw);

        let canvas = document.createElement('canvas');
        this.canvas = canvas.getContext('2d');

        window.addEventListener('resize', this.onResize);

        this.onResize();
    }

    componentWillUnmount() {
        window.removeEventListener('resize', this.onResize);
    }

    onResize = () => {
        this.calcTargetWidth();
    };

    calcTargetWidth = () => {
        let {
            refs: {
                target
            },
            calcTargetWidth,
            canvas
        } = this;

        // Calculation is no longer relevant, since node has been removed
        if (!target) {
            return;
        }

        let targetWidth = target.parentNode.getBoundingClientRect().width;

        // Delay calculation until parent node is inserted to the document
        // Mounting order in React is ChildComponent, ParentComponent
        if (!targetWidth) {
            return requestAnimationFrame(calcTargetWidth);
        }

        let style = window.getComputedStyle(target);

        let font = [
            style['font-weight'],
            style['font-style'],
            style['font-size'],
            style['font-family']
        ].join(' ');

        canvas.font = font;

        this.setState({
            targetWidth
        });
    };

    measureWidth = text => {
        return this.canvas.measureText(text).width;
    };

    getLines = () => {
        let {
            refs: {
                text: {
                    textContent: text
                },
                ellipsis: {
                    textContent: ellipsisText
                }
            },
            props: {
                lines: numLines,
                ellipsis
            },
            state: {
                targetWidth
            },
            measureWidth
        } = this;

        let lines = [];
        let textWords = text.split(' ');

        for (let line = 1; line <= numLines; line++) {
            let resultLine = textWords.join(' ');

            if (measureWidth(resultLine) < targetWidth) {
                // Line is end of text and fits without truncating //
                lines.push(resultLine);
                break;
            }

            if (line === numLines) {
                // Binary search determining the longest possible line inluding truncate string //
                let textRest = textWords.join(' ');

                let lower = 0;
                let upper = textRest.length - 1;

                while (lower <= upper) {
                    let middle = Math.floor((lower + upper) / 2);

                    let testLine = textRest.slice(0, middle + 1);

                    if (measureWidth(testLine + ellipsisText) <= targetWidth) {
                        lower = middle + 1;
                    } else {
                        upper = middle - 1;
                    }
                }

                resultLine = {textRest.slice(0, lower)}{ellipsis};
            } else {
                // Binary search determining when the line breaks //
                let lower = 0;
                let upper = textWords.length - 1;

                while (lower <= upper) {
                    let middle = Math.floor((lower + upper) / 2);

                    let testLine = textWords.slice(0, middle + 1).join(' ');

                    if (measureWidth(testLine) <= targetWidth) {
                        lower = middle + 1;
                    } else {
                        upper = middle - 1;
                    }
                }

                // The first word of this line is too long to fit it
                if (lower === 0) {
                    // Jump to processing of last line
                    line = numLines - 1;
                    continue;
                }

                resultLine = textWords.slice(0, lower).join(' ');
                textWords = textWords.slice(lower, textWords.length);
            }

            lines.push(resultLine);
        }

        return lines;
    };

    renderLine = (line, i, arr) => {
        if (i === arr.length - 1) {
            return {line};
        } else {
            return [
                {line},

            ];
        }
    };

    render() {
        let {
            refs: {
                target
            },
            props: {
                children,
                ellipsis,
                lines,
                ...spanProps
            },
            state: {
                targetWidth
            },
            getLines,
            renderLine
        } = this;

        let text = children;

        if (target && targetWidth && lines > 0) {
            text = getLines().map(renderLine);
        }

        return (

                {text}

                    {children}
                    {ellipsis}

        );
    }

    styles = {
        raw: {
            display: 'none'
        }
    };
};
<commit_msg>Favor testable member methods over function values in property initialization<commit_after>import React, { Component, PropTypes } from 'react';

export default class Truncate extends Component {
    static propTypes = {
        children: PropTypes.node,
        ellipsis: PropTypes.node,
        lines: PropTypes.oneOfType([
            PropTypes.oneOf([false]),
            PropTypes.number
        ])
    };

    static defaultProps = {
        children: '',
        ellipsis: '…',
        lines: 1
    };

    state = {};

    constructor(...args) {
        super(...args);

        this.onResize = this.onResize.bind(this);
        this.calcTargetWidth = this.calcTargetWidth.bind(this);
        this.measureWidth = this.measureWidth.bind(this);
        this.getLines = this.getLines.bind(this);
        this.renderLine = this.renderLine.bind(this);
    }

    componentDidMount() {
        // Node not needed in document tree to read its content
        this.refs.raw.parentNode.removeChild(this.refs.raw);

        let canvas = document.createElement('canvas');
        this.canvas = canvas.getContext('2d');

        window.addEventListener('resize', this.onResize);

        this.onResize();
    }

    componentWillUnmount() {
        window.removeEventListener('resize', this.onResize);
    }

    onResize() {
        this.calcTargetWidth();
    }

    calcTargetWidth() {
        let {
            refs: {
                target
            },
            calcTargetWidth,
            canvas
        } = this;

        // Calculation is no longer relevant, since node has been removed
        if (!target) {
            return;
        }

        let targetWidth = target.parentNode.getBoundingClientRect().width;

        // Delay calculation until parent node is inserted to the document
        // Mounting order in React is ChildComponent, ParentComponent
        if (!targetWidth) {
            return requestAnimationFrame(calcTargetWidth);
        }

        let style = window.getComputedStyle(target);

        let font = [
            style['font-weight'],
            style['font-style'],
            style['font-size'],
            style['font-family']
        ].join(' ');

        canvas.font = font;

        this.setState({
            targetWidth
        });
    }

    measureWidth(text) {
        return this.canvas.measureText(text).width;
    }

    getLines() {
        let {
            refs: {
                text: {
                    textContent: text
                },
                ellipsis: {
                    textContent: ellipsisText
                }
            },
            props: {
                lines: numLines,
                ellipsis
            },
            state: {
                targetWidth
            },
            measureWidth
        } = this;

        let lines = [];
        let textWords = text.split(' ');

        for (let line = 1; line <= numLines; line++) {
            let resultLine = textWords.join(' ');

            if (measureWidth(resultLine) < targetWidth) {
                // Line is end of text and fits without truncating //
                lines.push(resultLine);
                break;
            }

            if (line === numLines) {
                // Binary search determining the longest possible line inluding truncate string //
                let textRest = textWords.join(' ');

                let lower = 0;
                let upper = textRest.length - 1;

                while (lower <= upper) {
                    let middle = Math.floor((lower + upper) / 2);

                    let testLine = textRest.slice(0, middle + 1);

                    if (measureWidth(testLine + ellipsisText) <= targetWidth) {
                        lower = middle + 1;
                    } else {
                        upper = middle - 1;
                    }
                }

                resultLine = {textRest.slice(0, lower)}{ellipsis};
            } else {
                // Binary search determining when the line breaks //
                let lower = 0;
                let upper = textWords.length - 1;

                while (lower <= upper) {
                    let middle = Math.floor((lower + upper) / 2);

                    let testLine = textWords.slice(0, middle + 1).join(' ');

                    if (measureWidth(testLine) <= targetWidth) {
                        lower = middle + 1;
                    } else {
                        upper = middle - 1;
                    }
                }

                // The first word of this line is too long to fit it
                if (lower === 0) {
                    // Jump to processing of last line
                    line = numLines - 1;
                    continue;
                }

                resultLine = textWords.slice(0, lower).join(' ');
                textWords = textWords.slice(lower, textWords.length);
            }

            lines.push(resultLine);
        }

        return lines;
    }

    renderLine(line, i, arr) {
        if (i === arr.length - 1) {
            return {line};
        } else {
            return [
                {line},

            ];
        }
    }

    render() {
        let {
            refs: {
                target
            },
            props: {
                children,
                ellipsis,
                lines,
                ...spanProps
            },
            state: {
                targetWidth
            },
            getLines,
            renderLine
        } = this;

        let text = children;

        if (target && targetWidth && lines > 0) {
            text = getLines().map(renderLine);
        }

        return (

                {text}

                    {children}
                    {ellipsis}

        );
    }

    styles = {
        raw: {
            display: 'none'
        }
    };
};
<|endoftext|>


<commit_before>'use babel';
'use strict';

const {EventEmitter}     = require ('events');
const {Client}           = require ('_debugger');
const {spawn}            = require ('child_process');
const watt               = require ('watt');
const escapeStringRegexp = require ('escape-string-regexp');
const path               = require ('path');
const fs                 = require ('fs');
const tmp                = require ('tmp');

const Extractor = require ('./extractor.js');

class Wannabe extends EventEmitter {
  /**
   * Construct the Wannabe object.
   *
   * @param {string} script - Test script.
   */
  constructor (script) {
    super ();

    this._frames = {};
    this._script = script;
    this._client = new Client ();
    this._mocha  = {
      kill: () => {}
    };

    watt.wrapAll (this);
  }

  /**
   * Spawn mocha with the node debugger.
   *
   * @param {string|RegExp} regtest - Tests cases to grep.
   */
  _spawn (pattern, next) {
    const regex = pattern instanceof RegExp ?
                  pattern.toString ().replace (/^\/(.*)\/.?$/, '$1') :
                  escapeStringRegexp (pattern);

    this._mocha = spawn ('node', [
      '--debug',
      '--debug-brk',
      path.join (__dirname, './mocha.js'),
      this._script,
      regex
    ], {
      detached: false,
      stdio: ['ignore', 'ignore', 'pipe']
    });

    this._mocha.unref ();

    this._mocha.stderr.once ('data', () => next ());

    this._mocha.on ('close', () => {});
    this._mocha.on ('error', (err) => {
      console.error (err);
    });
  }

  /**
   * Inspect the frame on the current breakpoint.
   *
   * It populates this._frames with the local variables.
   * The key of this._frames is the line number.
   *
   * NOTE: setBreakpoint is slow!
   */
  * _inspect (next) {
    const {frames} = yield this._client.reqBacktrace (next);
    const line = `${frames[0].line}`;

    if (!this._frames[line]) {
      this._frames[line] = [];
    }

    const frame = {
      locals: [],
      arguments: [],
      returnValue: null
    };

    frames[0].locals.forEach ((local) => {
      /* Local variables */
      frame.locals.push ({
        name:  local.name,
        type:  local.value.type,
        value: local.value.value || local.value.className
      });
    });

    frames[0].arguments.forEach ((argument) => {
      /* Arguments */
      frame.arguments.push ({
        name:  argument.name,
        type:  argument.value.type,
        value: argument.value.value
      });
    });

    /* Return value */
    if (frames[0].returnValue && frames[0].returnValue.type !== 'undefined') {
      frame.returnValue = {
        type: frames[0].returnValue.type,
        value: frames[0].returnValue.value
      };
    }

    this._frames[line].push (frame);
  }

  _exception (ex, next) {
    const line = `${ex.body.sourceLine + 1}`;

    if (!this._frames[line]) {
      this._frames[line] = [];
    }

    this._frames[line].push ({
      exception: {
        type: ex.body.exception.type,
        text: ex.body.exception.text
      }
    });

    next ();
  }

  /**
   * Initialize the client connection.
   *
   * It waits on the first breakpoint because the child is executed with
   * the --debug-brk argument.
   *
   * @param {string|RegExp} regtest - Tests cases to grep.
   */
  * init (pattern, next) {
    yield this._spawn (pattern, next);

    let first = true;
    this._client.on ('break', () => {
      if (first) {
        this.emit ('ready');
        first = false;
        return;
      }

      this._inspect (() => this._client.reqContinue (() => {}));
    });

    this._client.on ('exception', (ex) => {
      this._exception (ex, () => this._client.reqContinue (() => {}));
    });

    this._client.once ('connect', next.parallel ());
    this._client.connect (5858);
    yield next.sync ();

    yield this.once ('ready', next); // wait for the first breakpoint (--debug-brk)
    yield this._client.reqSetExceptionBreak ('all', next);
  }

  /**
   * Set one or more breakpoints according to the current script.
   *
   * @param {number[]} lines - Lines where put the breakpoints.
   */
  * setBreakpoints (lines, next) {
    for (const line of lines) {
      this._client.setBreakpoint ({
        type:   'script',
        target: this._script,
        line:   line
      }, next.parallel ());
    }

    yield next.sync ();
  }

  /**
   * Run Wannabe.
   *
   * When a new breakpoint is reached, the continue request is automatically
   * sent until that the child is terminated.
   *
   * @returns all frames.
   */
  * run (next) {
    const promise = new Promise ((resolve) => {
      this._client.once ('error', (err) => {
        resolve (this._frames);
      });

      this._client.once ('close', () => {
        resolve (this._frames);
      });
    });

    yield this._client.reqContinue (next);
    return yield promise;
  }

  dispose () {
    this._mocha.kill ('SIGKILL');
  }
}

const extract = watt (function * (script, data, extractor, next) {
  let file = null;
  if (data) {
    /* We must create a new script in the same location that {script}.
     * The reason is that we can not pass a buffer to mocha; only files
     * can be passed to the runner.
     */
    file = yield tmp.tmpName ({
      template: path.join (script, '../.wannabe-XXXXXX')
    }, next);
    yield fs.writeFile (file, data, next);
  } else {
    file = script;
  }

  let _exThrown = false;
  let frames = null;
  const wannabe = new Wannabe (file);

  try {
    const {lines, pattern} = extractor (file);
    if (!lines.length) {
      return {};
    }

    yield wannabe.init (pattern);

    yield wannabe.setBreakpoints (lines);
    frames = yield wannabe.run ();
  } catch (ex) {
    _exThrown = true;
    throw ex;
  } finally {
    wannabe.dispose ();
    if (data) {
      yield fs.unlink (file, next);
    }
    // FIXME: see watt bug: https://github.com/mappum/watt/issues/16
    if (!_exThrown) {
      return frames;
    }
  }
});

exports.byPattern = watt (function * (script, data, funcName, pattern, next) {
  return yield extract (script, data, (file) => {
    const lines = data ?
      Extractor.byFuncInData (data, funcName, pattern) :
      Extractor.byFuncInFile (file, funcName, pattern);
    return {
      lines,
      pattern
    }
  }, next);
});

exports.byLine = watt (function * (script, data, funcName, line, next) {
  return yield extract (script, data, (file) => {
    return data ?
      Extractor.byLineInData (data, funcName, line) :
      Extractor.byLineInFile (file, funcName, line);
  }, next);
});
<commit_msg>Retrieve the right line number with all exceptions<commit_after>'use babel';
'use strict';

const {EventEmitter}     = require ('events');
const {Client}           = require ('_debugger');
const {spawn}            = require ('child_process');
const watt               = require ('watt');
const escapeStringRegexp = require ('escape-string-regexp');
const path               = require ('path');
const fs                 = require ('fs');
const tmp                = require ('tmp');

const Extractor = require ('./extractor.js');

class Wannabe extends EventEmitter {
  /**
   * Construct the Wannabe object.
   *
   * @param {string} script - Test script.
   */
  constructor (script) {
    super ();

    this._frames = {};
    this._script = script;
    this._client = new Client ();
    this._mocha  = {
      kill: () => {}
    };

    watt.wrapAll (this);
  }

  /**
   * Spawn mocha with the node debugger.
   *
   * @param {string|RegExp} regtest - Tests cases to grep.
   */
  _spawn (pattern, next) {
    const regex = pattern instanceof RegExp ?
                  pattern.toString ().replace (/^\/(.*)\/.?$/, '$1') :
                  escapeStringRegexp (pattern);

    this._mocha = spawn ('node', [
      '--debug',
      '--debug-brk',
      path.join (__dirname, './mocha.js'),
      this._script,
      regex
    ], {
      detached: false,
      stdio: ['ignore', 'ignore', 'pipe']
    });

    this._mocha.unref ();

    this._mocha.stderr.once ('data', () => next ());

    this._mocha.on ('close', () => {});
    this._mocha.on ('error', (err) => {
      console.error (err);
    });
  }

  /**
   * Inspect the frame on the current breakpoint.
   *
   * It populates this._frames with the local variables.
   * The key of this._frames is the line number.
   *
   * NOTE: setBreakpoint is slow!
   */
  * _inspect (next) {
    const {frames} = yield this._client.reqBacktrace (next);
    const line = `${frames[0].line}`;

    if (!this._frames[line]) {
      this._frames[line] = [];
    }

    const frame = {
      locals: [],
      arguments: [],
      returnValue: null
    };

    frames[0].locals.forEach ((local) => {
      /* Local variables */
      frame.locals.push ({
        name:  local.name,
        type:  local.value.type,
        value: local.value.value || local.value.className
      });
    });

    frames[0].arguments.forEach ((argument) => {
      /* Arguments */
      frame.arguments.push ({
        name:  argument.name,
        type:  argument.value.type,
        value: argument.value.value
      });
    });

    /* Return value */
    if (frames[0].returnValue && frames[0].returnValue.type !== 'undefined') {
      frame.returnValue = {
        type: frames[0].returnValue.type,
        value: frames[0].returnValue.value
      };
    }

    this._frames[line].push (frame);
  }

  /**
   * Extract the first frame which is corresponding with our script.
   *
   * @returns the frame or null.
   */
  * _extractFrame (next) {
    let found = null;
    const {frames} = yield this._client.fullTrace (next);

    frames.some ((frame) => {
      found = frame;
      return frame.script.name == this._script;
    });

    return found;
  }

  /**
   * Inspect the exception.
   *
   * It populates this._frames with an exception member.
   * The key of this._frames is the line number.
   */
  * _exception (ex, next) {
    let line = 0;

    if (ex.body.script.name === this._script) {
      line = `${ex.body.sourceLine + 1}`;
    } else {
      const frame = yield this._extractFrame (next);
      if (frame) {
        line = `${frame.line + 1}`;
      }
    }

    if (!this._frames[line]) {
      this._frames[line] = [];
    }

    this._frames[line].push ({
      exception: {
        type: ex.body.exception.type,
        text: ex.body.exception.text
      }
    });

    next ();
  }

  /**
   * Initialize the client connection.
   *
   * It waits on the first breakpoint because the child is executed with
   * the --debug-brk argument.
   *
   * @param {string|RegExp} regtest - Tests cases to grep.
   */
  * init (pattern, next) {
    yield this._spawn (pattern, next);

    let first = true;
    this._client.on ('break', () => {
      if (first) {
        this.emit ('ready');
        first = false;
        return;
      }

      this._inspect (() => this._client.reqContinue (() => {}));
    });

    this._client.on ('exception', (ex) => {
      this._exception (ex, () => this._client.reqContinue (() => {}));
    });

    this._client.once ('connect', next.parallel ());
    this._client.connect (5858);
    yield next.sync ();

    yield this.once ('ready', next); // wait for the first breakpoint (--debug-brk)
    yield this._client.reqSetExceptionBreak ('all', next);
  }

  /**
   * Set one or more breakpoints according to the current script.
   *
   * @param {number[]} lines - Lines where put the breakpoints.
   */
  * setBreakpoints (lines, next) {
    for (const line of lines) {
      this._client.setBreakpoint ({
        type:   'script',
        target: this._script,
        line:   line
      }, next.parallel ());
    }

    yield next.sync ();
  }

  /**
   * Run Wannabe.
   *
   * When a new breakpoint is reached, the continue request is automatically
   * sent until that the child is terminated.
   *
   * @returns all frames.
   */
  * run (next) {
    const promise = new Promise ((resolve) => {
      this._client.once ('error', (err) => {
        resolve (this._frames);
      });

      this._client.once ('close', () => {
        resolve (this._frames);
      });
    });

    yield this._client.reqContinue (next);
    return yield promise;
  }

  dispose () {
    this._mocha.kill ('SIGKILL');
  }
}

const extract = watt (function * (script, data, extractor, next) {
  let file = null;
  if (data) {
    /* We must create a new script in the same location that {script}.
     * The reason is that we can not pass a buffer to mocha; only files
     * can be passed to the runner.
     */
    file = yield tmp.tmpName ({
      template: path.join (script, '../.wannabe-XXXXXX')
    }, next);
    yield fs.writeFile (file, data, next);
  } else {
    file = script;
  }

  let _exThrown = false;
  let frames = null;
  const wannabe = new Wannabe (file);

  try {
    const {lines, pattern} = extractor (file);
    if (!lines.length) {
      return {};
    }

    yield wannabe.init (pattern);

    yield wannabe.setBreakpoints (lines);
    frames = yield wannabe.run ();
  } catch (ex) {
    _exThrown = true;
    throw ex;
  } finally {
    wannabe.dispose ();
    if (data) {
      yield fs.unlink (file, next);
    }
    // FIXME: see watt bug: https://github.com/mappum/watt/issues/16
    if (!_exThrown) {
      return frames;
    }
  }
});

exports.byPattern = watt (function * (script, data, funcName, pattern, next) {
  return yield extract (script, data, (file) => {
    const lines = data ?
      Extractor.byFuncInData (data, funcName, pattern) :
      Extractor.byFuncInFile (file, funcName, pattern);
    return {
      lines,
      pattern
    }
  }, next);
});

exports.byLine = watt (function * (script, data, funcName, line, next) {
  return yield extract (script, data, (file) => {
    return data ?
      Extractor.byLineInData (data, funcName, line) :
      Extractor.byLineInFile (file, funcName, line);
  }, next);
});
<|endoftext|>


<commit_before>'use strict';

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

module.exports = Zermelo;

function Zermelo (inputSchool, inputSecure) {
  var inputSchoolType;
  var inputSecureType;

  if (typeof inputSchool === 'undefined') {
    throw new Error('School parameter not supplied; it is necessary to run!');
  } else if (typeof inputSchool === 'string') {
    this._school = escape(inputSchool);

    inputSecureType = typeof inputSecure;
    switch (inputSecureType) {
      case 'undefined':
        this.call('debug', 'Secure parameter not supplied;  using default: true!');
        this._secure = true;
        break;

      case 'boolean':
        this._secure = inputSecure;
        break;

      case 'string':
        inputSecure = escape(inputSecure).toLowerCase();
        switch (inputSecure) {
          case 'true':
            this._secure = true;
            break;

          case 'false':
            this._secure = false;
            break;

          default:
            throw new Error('Secure parameter must be TRUE or FALSE; not ' + inputSecure);
        }
        break;

      default:
        throw new Error('Secure parameter must be boolean; not ' + inputSecureType);
    }
  } else if (typeof inputSchool === 'object') {
    var options = inputSchool;

    var inputSchoolType1 = typeof options.school;
    var inputSchoolType2 = typeof options.School;

    if (inputSchoolType1 === 'undefined' && inputSchoolType2 !== 'undefined') {
      inputSchool = options.School;
      inputSchoolType = inputSchoolType2;
    } else if (inputSchoolType1 !== 'undefined' && inputSchoolType2 === 'undefined') {
      inputSchool = options.school;
      inputSchoolType = inputSchoolType1;
    } else {
      inputSchoolType = 'undefined';
    }

    switch (inputSchoolType) {
      case 'undefined':
        throw new Error('School parameter not supplied; it is necessary to run!');
        break;

      case 'string':
        this._school = escape(inputSchool);

        var inputSecureType1 = typeof options.secure;
        var inputSecureType2 = typeof options.Secure;

        if (inputSecureType1 === 'undefined' && inputSecureType2 !== 'undefined') {
          inputSecure = options.Secure;
          inputSecureType = inputSecureType2;
        } else if (inputSecureType1 !== 'undefined' && inputSecureType2 === 'undefined') {
          inputSecure = options.secure;
          inputSecureType = inputSecureType1;
        } else {
          inputSecureType = 'undefined';
        }

        switch (inputSecureType) {
          case 'undefined':
            this.call('debug', 'Secure parameter not supplied;  using default: true!');
            this._secure = true;
            break;

          case 'boolean':
            this._secure = (escape(inputSecure) === 'true');
            break;

          case 'string':
            inputSecure = escape(inputSecure).toLowerCase();
            switch (inputSecure) {
              case 'true':
                this._secure = true;
                break;

              case 'false':
                this._secure = false;
                break;

              default:
                throw new Error('Secure parameter must be TRUE or FALSE; not ' + inputSecure);
            }
            break;

          default:
            throw new Error('Secure parameter must be boolean; not ' + inputSecureType);
        }
        break;

      default:
        throw new Error('School parameter must be string; not ' + inputSchoolType);
    }
  } else {
    throw new Error('School parameter must be string or object; not ' + typeof inputSchool);
  }

  this.call('debug', '[Zermelo] Successfully set School (' + this._school + ') and Secure (' + this._secure + ')');
}

Zermelo.prototype.call = function (emitEvent, emitData = '') {
  var self = this;

  emitData = emitData.split(' ');
  while (emitData[0].length < 10) {
    emitData[0] = ' ' + emitData[0];
  }
  emitData = emitData.join(' ');

  setImmediate(function () {
    self.emit(emitEvent, emitData);
  });
};

require('./components/http.js');
require('./components/logon.js');
require('./components/schedule.js');
<commit_msg>Removed Unreachable Code<commit_after>'use strict';

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

module.exports = Zermelo;

function Zermelo (inputSchool, inputSecure) {
  var inputSchoolType;
  var inputSecureType;

  if (typeof inputSchool === 'undefined') {
    throw new Error('School parameter not supplied; it is necessary to run!');
  } else if (typeof inputSchool === 'string') {
    this._school = escape(inputSchool);

    inputSecureType = typeof inputSecure;
    switch (inputSecureType) {
      case 'undefined':
        this.call('debug', 'Secure parameter not supplied;  using default: true!');
        this._secure = true;
        break;

      case 'boolean':
        this._secure = inputSecure;
        break;

      case 'string':
        inputSecure = escape(inputSecure).toLowerCase();
        switch (inputSecure) {
          case 'true':
            this._secure = true;
            break;

          case 'false':
            this._secure = false;
            break;

          default:
            throw new Error('Secure parameter must be TRUE or FALSE; not ' + inputSecure);
        }
        break;

      default:
        throw new Error('Secure parameter must be boolean; not ' + inputSecureType);
    }
  } else if (typeof inputSchool === 'object') {
    var options = inputSchool;

    var inputSchoolType1 = typeof options.school;
    var inputSchoolType2 = typeof options.School;

    if (inputSchoolType1 === 'undefined' && inputSchoolType2 !== 'undefined') {
      inputSchool = options.School;
      inputSchoolType = inputSchoolType2;
    } else if (inputSchoolType1 !== 'undefined' && inputSchoolType2 === 'undefined') {
      inputSchool = options.school;
      inputSchoolType = inputSchoolType1;
    } else {
      inputSchoolType = 'undefined';
    }

    switch (inputSchoolType) {
      case 'undefined':
        throw new Error('School parameter not supplied; it is necessary to run!');

      case 'string':
        this._school = escape(inputSchool);

        var inputSecureType1 = typeof options.secure;
        var inputSecureType2 = typeof options.Secure;

        if (inputSecureType1 === 'undefined' && inputSecureType2 !== 'undefined') {
          inputSecure = options.Secure;
          inputSecureType = inputSecureType2;
        } else if (inputSecureType1 !== 'undefined' && inputSecureType2 === 'undefined') {
          inputSecure = options.secure;
          inputSecureType = inputSecureType1;
        } else {
          inputSecureType = 'undefined';
        }

        switch (inputSecureType) {
          case 'undefined':
            this.call('debug', 'Secure parameter not supplied;  using default: true!');
            this._secure = true;
            break;

          case 'boolean':
            this._secure = (escape(inputSecure) === 'true');
            break;

          case 'string':
            inputSecure = escape(inputSecure).toLowerCase();
            switch (inputSecure) {
              case 'true':
                this._secure = true;
                break;

              case 'false':
                this._secure = false;
                break;

              default:
                throw new Error('Secure parameter must be TRUE or FALSE; not ' + inputSecure);
            }
            break;

          default:
            throw new Error('Secure parameter must be boolean; not ' + inputSecureType);
        }
        break;

      default:
        throw new Error('School parameter must be string; not ' + inputSchoolType);
    }
  } else {
    throw new Error('School parameter must be string or object; not ' + typeof inputSchool);
  }

  this.call('debug', '[Zermelo] Successfully set School (' + this._school + ') and Secure (' + this._secure + ')');
}

Zermelo.prototype.call = function (emitEvent, emitData = '') {
  var self = this;

  emitData = emitData.split(' ');
  while (emitData[0].length < 10) {
    emitData[0] = ' ' + emitData[0];
  }
  emitData = emitData.join(' ');

  setImmediate(function () {
    self.emit(emitEvent, emitData);
  });
};

require('./components/http.js');
require('./components/logon.js');
require('./components/schedule.js');
<|endoftext|>