<commit_before>'use strict';

var assert = require('assert');
var URI = require('urijs');
var _ = require('lodash');
var jsonCompat = require('json-schema-compatibility');
var HttpStatus = require('http-status-codes').getStatusText;
var jp = require('jsonpath');

exports.convert = function (raml) {
  //FIXME:
  //console.log(raml.documentation);

  var swagger = _.assign({
    swagger: '2.0',
    info: {
      title: raml.title,
      version: raml.version,
    },
    securityDefinitions: parseSecuritySchemes(raml.securitySchemes),
    paths: parseResources(raml.resources),
    definitions: parseSchemas(raml.schemas)
  }, parseBaseUri(raml));

  jp.apply(swagger.paths, '$..*.schema' , function (schema) {
    if (!schema || _.isEmpty(schema))
      return;

    var result = schema;
    _.each(swagger.definitions, function (definition, name) {
      if (!_.isEqual(schema, definition))
        return;
      result = { $ref: '#/definitions/' + name};
    });
    return result;
  });

  if ('mediaType' in raml) {
    swagger.consumes = [raml.mediaType];
    swagger.produces = [raml.mediaType];
  }

  //TODO: refactor into function
  //Fix incorrect arrays in RAML
  //TODO: add description
  _.each(swagger.definitions, function (schema, name) {
    if (!schema || schema.type !== 'array' || !_.isUndefined(schema.items))
      return;

    if (_.isArray(schema[name]) && _.isPlainObject(schema[name][0])) {
      schema.items = schema[name][0];
      delete schema[name];
    }
  });

  return swagger;
};

function parseBaseUri(raml) {
  var baseUri = raml.baseUri;

  if (!baseUri)
    return {};

  baseUri = baseUri.replace(/{version}/g, raml.version);
  //Don't support other URI templates right now.
  assert(baseUri.indexOf('{') == -1);

  baseUri = URI(baseUri);

  assert(!('baseUriParameters' in raml) ||
    _.isEqual(_.keys(raml.baseUriParameters), ['version']));
  assert(!('uriParameters' in raml));

  return {
    host: baseUri.host(),
    basePath: '/' + baseUri.pathname().replace(/^\/|\/$/, ''),
    schemes: parseProtocols(raml.protocols) || [baseUri.scheme()]
  };
}

function parseSecuritySchemes(ramlSecuritySchemes) {
  var srSecurityDefinitions = {};

  _.each(ramlSecuritySchemes, function (ramlSecurityArray) {
    _.each(ramlSecurityArray, function (ramlSecurityObj, name) {
      assert(ramlSecurityObj.type);

      //Swagger 2.0 doesn't support Oauth 1.0 so just skip it.
      //FIXME: add warning
      if (ramlSecurityObj.type === 'OAuth 1.0')
        return;

      var srType = {
        'OAuth 2.0': 'oauth2',
        'Basic Authentication': 'basic',
      }[ramlSecurityObj.type];
      assert(srType);

      var srSecurity = {
        type: srType,
        description: ramlSecurityObj.description,
      };

      if (srType !== 'oauth2') {
        srSecurityDefinitions[name] = srSecurity;
        return;
      }

      var ramlSettings = ramlSecurityObj.settings;
      _.assign(srSecurity, {
        authorizationUrl: ramlSettings.authorizationUri,
        tokenUrl: ramlSettings.accessTokenUri,
        scopes: _.transform(ramlSettings.scopes, function (result, name) {
          result[name] = '';
        }, {})
      });

      var ramlFlows = ramlSettings.authorizationGrants;
      _.each(ramlFlows, function (ramlFlow) {
         var srFlowSecurity = _.clone(srSecurity);
         var srFlow = srFlowSecurity.flow = {
           'code': 'accessCode',
           'token': 'implicit',
           'owner': 'password',
           'credentials': 'application'
         }[ramlFlow];

         if (srFlow === 'password' || srFlow === 'application')
           delete srFlowSecurity.authorizationUrl;

         if (srFlow === 'implicit')
           delete srFlowSecurity.tokenUrl;

         var fullName = name;
         if (_.size(ramlFlows) > 1)
           fullName = name + '_' + srFlowSecurity.flow;

         srSecurityDefinitions[fullName] = srFlowSecurity;
      });
    });
  });
  return srSecurityDefinitions;
}

function parseSchemas(ramlSchemas) {
  return _.reduce(ramlSchemas, function (definitions, ramlSchemasMap) {
    return _.assignWith(definitions, ramlSchemasMap, function (dummy, ramlSchema) {
      return convertSchema(ramlSchema);
    });
  }, {});
}

function parseProtocols(ramlProtocols) {
  return _.map(ramlProtocols, function (str) {
    return str.toLowerCase();
  });
}

function parseResources(ramlResources, srPathParameters) {
  var srPaths = {};

  _.each(ramlResources, function (ramlResource) {

    //FIXME: convert or create warning
    //assert(!('displayName' in ramlResource));
    //assert(!('description' in ramlResource && ramlResource.description !== ''));
    assert(!('baseUriParameters' in ramlResource));

    var resourceName = ramlResource.relativeUri;
    assert(resourceName);

    var srResourceParameters = (srPathParameters || []).concat(
      parseParametersList(ramlResource.uriParameters, 'path'));

    var srMethods = parseMethodList(ramlResource.methods, srResourceParameters);
    if (!_.isEmpty(srMethods))
      srPaths[resourceName] = srMethods;

    var srSubPaths = parseResources(ramlResource.resources, srResourceParameters);
    _.each(srSubPaths, function (subResource, subResourceName) {
      srPaths[resourceName + subResourceName] = subResource;
    });
  });
  return srPaths;
}

function parseMethodList(ramlMethods, srPathParameters) {
  var srMethods = {};
  _.each(ramlMethods, function (ramlMethod) {
    var srMethod = parseMethod(ramlMethod);
    if (!_.isEmpty(srPathParameters))
      srMethod.parameters = srPathParameters.concat(srMethod.parameters);
    srMethods[ramlMethod.method] = srMethod;
  });
  return srMethods;
}

function parseMethod(ramlMethod) {
  //FIXME:
  //assert(!('protocols' in data));
  //assert(!('securedBy' in data));

  var srMethod = {
    description: ramlMethod.description,
  };

  var srParameters = parseParametersList(ramlMethod.queryParameters, 'query');
  srParameters = srParameters.concat(
    parseParametersList(ramlMethod.headers, 'header'));

  if (!_.isEmpty(srParameters))
    srMethod.parameters = srParameters;

  parseBody(ramlMethod.body, srMethod);

  parseResponses(ramlMethod, srMethod);

  return srMethod;
}

function parseResponses(ramlMethod, srMethod) {
  var ramlResponces = ramlMethod.responses;
  if (_.isEmpty(ramlResponces)) {
    return {
      200: { description: HttpStatus(200) }
    };
  }

  srMethod.responses = {};
  _.each(ramlResponces, function (ramlResponce, httpCode) {
    var defaultDescription = HttpStatus(parseInt(httpCode));
    var srResponse = srMethod.responses[httpCode] = {
      description: _.get(ramlResponce, 'description') || defaultDescription
    };

    if (!_.has(ramlResponce, 'body'))
      return;

    var jsonMIME = 'application/json';
    var produces = _.without(_.keys(ramlResponce.body), jsonMIME);
    //TODO: types could have examples.
    if (!_.isEmpty(produces))
      srMethod.produces = produces;

    var jsonSchema = _.get(ramlResponce.body, jsonMIME);
    if (!_.isUndefined(jsonSchema)) {
      //TODO:
      //assert(!_.has(jsonSchema, 'example'));
      srResponse.schema = convertSchema(_.get(jsonSchema, 'schema'));
    }
  });
}

function parseParametersList(params, inValue) {
  assert(_.isUndefined(params) || _.isPlainObject(params));

  return _.map(params, function (value, key) {
     //FIXME:
     //assert(!_.has(value, 'example'));
     //assert(!_.has(value, 'displayName'));
     assert(_.has(value, 'type') &&
       ['date', 'string', 'number', 'integer', 'boolean'].indexOf(value.type) !== -1);

     var srParameter = {
       type: value.type,
       enum: value.enum,
       default: value.default,
       maximum: value.maximum,
       minimum: value.minimum,
       maxLength: value.maxLength,
       minLength: value.minLength,
       pattern: value.pattern
     };

     if (srParameter.type === 'date') {
       srParameter.type = 'string';
       srParameter.format = 'date';
     }

     if (value.repeat === true) {
       assert(['query', 'formData'].indexOf(inValue) !== -1);
       srParameter = {
         type: 'array',
         items: srParameter,
         collectionFormat: 'multi'
       }
     }

     _.assign(srParameter, {
       name: key,
       in: inValue,
       description: value.description,
       required: value.required
     });

     return srParameter;
  });
}

function parseBody(ramlBody, srMethod) {
  if (!ramlBody)
    return;

  var keys = _.keys(ramlBody)
  assert(!_.has(keys, 'application/x-www-form-urlencoded'));
  assert(!_.has(keys, 'multipart/form-data'));
  //TODO: All parsers of RAML MUST be able to interpret ... and XML Schema
  var jsonMIME = 'application/json';

  var consumes = _.without(keys, jsonMIME);
  //TODO: types could have examples.
  if (!_.isEmpty(consumes))
    srMethod.consumes = consumes;

  if (_.indexOf(keys, jsonMIME) === -1)
    return;

  if (_.isUndefined(srMethod.parameters))
    srMethod.parameters = [];

  srMethod.parameters.push({
    //FIXME: check if name is used;
    name: 'body',
    in: 'body',
    required: true,
    //TODO: copy example
    schema: convertSchema(_.get(ramlBody[jsonMIME], 'schema'))
  });
}

function convertSchema(schema) {
  if (_.isUndefined(schema))
    return;

  assert(_.isString(schema));

  try {
    var schema = JSON.parse(schema);
  }
  catch (e) {
    return undefined;
  }

  delete schema.id;
  delete schema.$schema;
  delete schema[''];

  //Convertion is safe even for Draft4 schemas, so convert everything
  schema = jsonCompat.v4(schema);

  //Add '#/definitions/' prefix to all internal refs
  jp.apply(schema, '$..*["$ref"]' , function (ref) {
    return '#/definitions/' + ref;
  });

  //Fixes for common mistakes in RAML 0.8

  // Fix case where 'list' keyword used instead of 'items':
  // {
  //   "type": "array",
  //   "list": [{
  //     ...
  //   ]}
  // }
  if (schema.type === 'array' && !_.isUndefined(schema.list)) {
    assert(_.isUndefined(schema.items));
    assert(_.size(schema.list) === 1);
    assert(_.isPlainObject(schema.list[0]));
    schema.items = schema.list[0];
    delete schema.list;
  }

  // Fix case when instead of 'additionalProperties' schema put in following wrappers:
  // {
  //   "type": "object",
  //   "": [{
  //     ...
  //   }]
  // }
  // or
  // {
  //   "type": "object",
  //   "properties": {
  //     "": [{
  //       ...
  //     }]
  //   }
  // }
  // Or simular case for arrays, when same wrapper used instead of 'items'.
  _.each(jp.nodes(schema, '$..*[""]'), function(result) {
    var value = result.value;
    var path = result.path;

    if (!_.isArray(value) || _.size(value) !== 1 || !_.isPlainObject(value[0]))
      return;

    path = _.dropRight(path);
    var parent = jp.value(schema, jp.stringify(path));
    delete parent[''];

    if (_.isEmpty(parent) && ['properties', 'items'].indexOf(_.last(path)) !== -1) {
      parent = jp.value(schema, jp.stringify(_.dropRight(path)));
      delete parent.properties;
    }

    switch (parent.type) {
      case 'object':
        parent.additionalProperties = value[0];
        break;
      case 'array':
        parent.items = value[0];
        break;
      default:
        assert(false);
    }
  });

  // Fix case when arrays definition wrapped with array, like that:
  // [{
  //   "type": "array",
  //   ...
  // }]
  jp.apply(schema, '$..properties[?(@.length === 1 && @[0].type === "array")]', function(schema) {
    return schema[0];
  });

  // Fix incorrect array properties, like that:
  // {
  //   "properties": {
  //     "type": array,
  //     "<name>": [{
  //       ...
  //     }]
  //   }
  // }
  _.each(jp.nodes(schema, '$..properties[?(@.length === 1)]'), function(result) {
    var name = _.last(result.path);
    var parent = jp.value(schema, jp.stringify(_.dropRight(result.path)));

    if (parent['type'] === 'array') {
      parent[name] = {type: 'array', items: result.value[0]}
      delete parent['type'];
    }
  });

  // Fix case then 'items' value is empty or single element array.
  function unwrapItems(schema) {
    if (_.isEmpty(schema.items))
      schema.items = {};
    else {
      assert(_.isPlainObject(schema.items[0]));
      schema.items = schema.items[0];
    }

    return schema;
  }

  jp.apply(schema, '$..*[?(@.type === "array" && @.items && @.items.length <= 1)]', unwrapItems);
  //JSON Path can't apply to root object so do this manually
  if (schema.type === 'array' && _.isArray(schema.items) && _.size(schema.items) <= 1)
    unwrapItems(schema);

  return schema;
}
<commit_msg>Support url tempates inside path of baseUri<commit_after>'use strict';

var assert = require('assert');
var URI = require('urijs');
var _ = require('lodash');
var jsonCompat = require('json-schema-compatibility');
var HttpStatus = require('http-status-codes').getStatusText;
var jp = require('jsonpath');

exports.convert = function (raml) {
  //FIXME:
  //console.log(raml.documentation);

  var swagger = {
    swagger: '2.0',
    info: {
      title: raml.title,
      version: raml.version,
    },
    securityDefinitions: parseSecuritySchemes(raml.securitySchemes),
    paths: parseResources(raml.resources),
    definitions: parseSchemas(raml.schemas)
  };

  parseBaseUri(raml, swagger);

  jp.apply(swagger.paths, '$..*.schema' , function (schema) {
    if (!schema || _.isEmpty(schema))
      return;

    var result = schema;
    _.each(swagger.definitions, function (definition, name) {
      if (!_.isEqual(schema, definition))
        return;
      result = { $ref: '#/definitions/' + name};
    });
    return result;
  });

  if ('mediaType' in raml) {
    swagger.consumes = [raml.mediaType];
    swagger.produces = [raml.mediaType];
  }

  //TODO: refactor into function
  //Fix incorrect arrays in RAML
  //TODO: add description
  _.each(swagger.definitions, function (schema, name) {
    if (!schema || schema.type !== 'array' || !_.isUndefined(schema.items))
      return;

    if (_.isArray(schema[name]) && _.isPlainObject(schema[name][0])) {
      schema.items = schema[name][0];
      delete schema[name];
    }
  });

  return swagger;
};

function parseBaseUri(raml, swagger) {
  var baseUri = raml.baseUri;

  if (!baseUri)
    return;

  var baseUriParameters = _.omit(raml.baseUriParameters, 'version');
  baseUri = baseUri.replace(/{version}/g, raml.version);
  baseUri = URI(baseUri);

  // Split out part path segments starting from first template param
  var match = /^(.*?)(\/[^\/]*?{.*)?$/.exec(baseUri.path());
  baseUri.path(match[1]);
  var pathPrefix = match[2];

  //Don't support other URI templates right now.
  assert(baseUri.href().indexOf('{') == -1);
  assert(!('uriParameters' in raml));

  _.assign(swagger, {
    host: baseUri.host(),
    basePath: '/' + baseUri.pathname().replace(/^\/|\/$/, ''),
    schemes: parseProtocols(raml.protocols) || [baseUri.scheme()]
  });

  if (!pathPrefix)
    return;

  pathPrefix = pathPrefix.replace(/\/$/, '');
  baseUriParameters = parseParametersList(baseUriParameters);
  swagger.paths = _.mapKeys(swagger.paths, function (value, key) {
    value.parameters = _.concat(baseUriParameters, value.parameters);
    return pathPrefix + key;
  });
}

function parseSecuritySchemes(ramlSecuritySchemes) {
  var srSecurityDefinitions = {};

  _.each(ramlSecuritySchemes, function (ramlSecurityArray) {
    _.each(ramlSecurityArray, function (ramlSecurityObj, name) {
      assert(ramlSecurityObj.type);

      //Swagger 2.0 doesn't support Oauth 1.0 so just skip it.
      //FIXME: add warning
      if (ramlSecurityObj.type === 'OAuth 1.0')
        return;

      var srType = {
        'OAuth 2.0': 'oauth2',
        'Basic Authentication': 'basic',
      }[ramlSecurityObj.type];
      assert(srType);

      var srSecurity = {
        type: srType,
        description: ramlSecurityObj.description,
      };

      if (srType !== 'oauth2') {
        srSecurityDefinitions[name] = srSecurity;
        return;
      }

      var ramlSettings = ramlSecurityObj.settings;
      _.assign(srSecurity, {
        authorizationUrl: ramlSettings.authorizationUri,
        tokenUrl: ramlSettings.accessTokenUri,
        scopes: _.transform(ramlSettings.scopes, function (result, name) {
          result[name] = '';
        }, {})
      });

      var ramlFlows = ramlSettings.authorizationGrants;
      _.each(ramlFlows, function (ramlFlow) {
         var srFlowSecurity = _.clone(srSecurity);
         var srFlow = srFlowSecurity.flow = {
           'code': 'accessCode',
           'token': 'implicit',
           'owner': 'password',
           'credentials': 'application'
         }[ramlFlow];

         if (srFlow === 'password' || srFlow === 'application')
           delete srFlowSecurity.authorizationUrl;

         if (srFlow === 'implicit')
           delete srFlowSecurity.tokenUrl;

         var fullName = name;
         if (_.size(ramlFlows) > 1)
           fullName = name + '_' + srFlowSecurity.flow;

         srSecurityDefinitions[fullName] = srFlowSecurity;
      });
    });
  });
  return srSecurityDefinitions;
}

function parseSchemas(ramlSchemas) {
  return _.reduce(ramlSchemas, function (definitions, ramlSchemasMap) {
    return _.assignWith(definitions, ramlSchemasMap, function (dummy, ramlSchema) {
      return convertSchema(ramlSchema);
    });
  }, {});
}

function parseProtocols(ramlProtocols) {
  return _.map(ramlProtocols, function (str) {
    return str.toLowerCase();
  });
}

function parseResources(ramlResources, srPathParameters) {
  var srPaths = {};

  _.each(ramlResources, function (ramlResource) {

    //FIXME: convert or create warning
    //assert(!('displayName' in ramlResource));
    //assert(!('description' in ramlResource && ramlResource.description !== ''));
    assert(!('baseUriParameters' in ramlResource));

    var resourceName = ramlResource.relativeUri;
    assert(resourceName);

    var srResourceParameters = (srPathParameters || []).concat(
      parseParametersList(ramlResource.uriParameters, 'path'));

    var srMethods = parseMethodList(ramlResource.methods, srResourceParameters);
    if (!_.isEmpty(srMethods))
      srPaths[resourceName] = srMethods;

    var srSubPaths = parseResources(ramlResource.resources, srResourceParameters);
    _.each(srSubPaths, function (subResource, subResourceName) {
      srPaths[resourceName + subResourceName] = subResource;
    });
  });
  return srPaths;
}

function parseMethodList(ramlMethods, srPathParameters) {
  var srMethods = {};
  _.each(ramlMethods, function (ramlMethod) {
    var srMethod = parseMethod(ramlMethod);
    if (!_.isEmpty(srPathParameters))
      srMethod.parameters = srPathParameters.concat(srMethod.parameters);
    srMethods[ramlMethod.method] = srMethod;
  });
  return srMethods;
}

function parseMethod(ramlMethod) {
  //FIXME:
  //assert(!('protocols' in data));
  //assert(!('securedBy' in data));

  var srMethod = {
    description: ramlMethod.description,
  };

  var srParameters = parseParametersList(ramlMethod.queryParameters, 'query');
  srParameters = srParameters.concat(
    parseParametersList(ramlMethod.headers, 'header'));

  if (!_.isEmpty(srParameters))
    srMethod.parameters = srParameters;

  parseBody(ramlMethod.body, srMethod);

  parseResponses(ramlMethod, srMethod);

  return srMethod;
}

function parseResponses(ramlMethod, srMethod) {
  var ramlResponces = ramlMethod.responses;
  if (_.isEmpty(ramlResponces)) {
    return {
      200: { description: HttpStatus(200) }
    };
  }

  srMethod.responses = {};
  _.each(ramlResponces, function (ramlResponce, httpCode) {
    var defaultDescription = HttpStatus(parseInt(httpCode));
    var srResponse = srMethod.responses[httpCode] = {
      description: _.get(ramlResponce, 'description') || defaultDescription
    };

    if (!_.has(ramlResponce, 'body'))
      return;

    var jsonMIME = 'application/json';
    var produces = _.without(_.keys(ramlResponce.body), jsonMIME);
    //TODO: types could have examples.
    if (!_.isEmpty(produces))
      srMethod.produces = produces;

    var jsonSchema = _.get(ramlResponce.body, jsonMIME);
    if (!_.isUndefined(jsonSchema)) {
      //TODO:
      //assert(!_.has(jsonSchema, 'example'));
      srResponse.schema = convertSchema(_.get(jsonSchema, 'schema'));
    }
  });
}

function parseParametersList(params, inValue) {
  assert(_.isUndefined(params) || _.isPlainObject(params));

  return _.map(params, function (value, key) {
     //FIXME:
     //assert(!_.has(value, 'example'));
     //assert(!_.has(value, 'displayName'));
     assert(_.has(value, 'type') &&
       ['date', 'string', 'number', 'integer', 'boolean'].indexOf(value.type) !== -1);

     var srParameter = {
       type: value.type,
       enum: value.enum,
       default: value.default,
       maximum: value.maximum,
       minimum: value.minimum,
       maxLength: value.maxLength,
       minLength: value.minLength,
       pattern: value.pattern
     };

     if (srParameter.type === 'date') {
       srParameter.type = 'string';
       srParameter.format = 'date';
     }

     if (value.repeat === true) {
       assert(['query', 'formData'].indexOf(inValue) !== -1);
       srParameter = {
         type: 'array',
         items: srParameter,
         collectionFormat: 'multi'
       }
     }

     _.assign(srParameter, {
       name: key,
       in: inValue,
       description: value.description,
       required: value.required
     });

     return srParameter;
  });
}

function parseBody(ramlBody, srMethod) {
  if (!ramlBody)
    return;

  var keys = _.keys(ramlBody)
  assert(!_.has(keys, 'application/x-www-form-urlencoded'));
  assert(!_.has(keys, 'multipart/form-data'));
  //TODO: All parsers of RAML MUST be able to interpret ... and XML Schema
  var jsonMIME = 'application/json';

  var consumes = _.without(keys, jsonMIME);
  //TODO: types could have examples.
  if (!_.isEmpty(consumes))
    srMethod.consumes = consumes;

  if (_.indexOf(keys, jsonMIME) === -1)
    return;

  if (_.isUndefined(srMethod.parameters))
    srMethod.parameters = [];

  srMethod.parameters.push({
    //FIXME: check if name is used;
    name: 'body',
    in: 'body',
    required: true,
    //TODO: copy example
    schema: convertSchema(_.get(ramlBody[jsonMIME], 'schema'))
  });
}

function convertSchema(schema) {
  if (_.isUndefined(schema))
    return;

  assert(_.isString(schema));

  try {
    var schema = JSON.parse(schema);
  }
  catch (e) {
    return undefined;
  }

  delete schema.id;
  delete schema.$schema;
  delete schema[''];

  //Convertion is safe even for Draft4 schemas, so convert everything
  schema = jsonCompat.v4(schema);

  //Add '#/definitions/' prefix to all internal refs
  jp.apply(schema, '$..*["$ref"]' , function (ref) {
    return '#/definitions/' + ref;
  });

  //Fixes for common mistakes in RAML 0.8

  // Fix case where 'list' keyword used instead of 'items':
  // {
  //   "type": "array",
  //   "list": [{
  //     ...
  //   ]}
  // }
  if (schema.type === 'array' && !_.isUndefined(schema.list)) {
    assert(_.isUndefined(schema.items));
    assert(_.size(schema.list) === 1);
    assert(_.isPlainObject(schema.list[0]));
    schema.items = schema.list[0];
    delete schema.list;
  }

  // Fix case when instead of 'additionalProperties' schema put in following wrappers:
  // {
  //   "type": "object",
  //   "": [{
  //     ...
  //   }]
  // }
  // or
  // {
  //   "type": "object",
  //   "properties": {
  //     "": [{
  //       ...
  //     }]
  //   }
  // }
  // Or simular case for arrays, when same wrapper used instead of 'items'.
  _.each(jp.nodes(schema, '$..*[""]'), function(result) {
    var value = result.value;
    var path = result.path;

    if (!_.isArray(value) || _.size(value) !== 1 || !_.isPlainObject(value[0]))
      return;

    path = _.dropRight(path);
    var parent = jp.value(schema, jp.stringify(path));
    delete parent[''];

    if (_.isEmpty(parent) && ['properties', 'items'].indexOf(_.last(path)) !== -1) {
      parent = jp.value(schema, jp.stringify(_.dropRight(path)));
      delete parent.properties;
    }

    switch (parent.type) {
      case 'object':
        parent.additionalProperties = value[0];
        break;
      case 'array':
        parent.items = value[0];
        break;
      default:
        assert(false);
    }
  });

  // Fix case when arrays definition wrapped with array, like that:
  // [{
  //   "type": "array",
  //   ...
  // }]
  jp.apply(schema, '$..properties[?(@.length === 1 && @[0].type === "array")]', function(schema) {
    return schema[0];
  });

  // Fix incorrect array properties, like that:
  // {
  //   "properties": {
  //     "type": array,
  //     "<name>": [{
  //       ...
  //     }]
  //   }
  // }
  _.each(jp.nodes(schema, '$..properties[?(@.length === 1)]'), function(result) {
    var name = _.last(result.path);
    var parent = jp.value(schema, jp.stringify(_.dropRight(result.path)));

    if (parent['type'] === 'array') {
      parent[name] = {type: 'array', items: result.value[0]}
      delete parent['type'];
    }
  });

  // Fix case then 'items' value is empty or single element array.
  function unwrapItems(schema) {
    if (_.isEmpty(schema.items))
      schema.items = {};
    else {
      assert(_.isPlainObject(schema.items[0]));
      schema.items = schema.items[0];
    }

    return schema;
  }

  jp.apply(schema, '$..*[?(@.type === "array" && @.items && @.items.length <= 1)]', unwrapItems);
  //JSON Path can't apply to root object so do this manually
  if (schema.type === 'array' && _.isArray(schema.items) && _.size(schema.items) <= 1)
    unwrapItems(schema);

  return schema;
}
<|endoftext|>


<commit_before>/*
 * svgicons2svgfont
 * https://github.com/nfroidure/svgicons2svgfont
 *
 * Copyright (c) 2013 Nicolas Froidure, Cameron Hunter
 * Licensed under the MIT license.
 */
"use strict";

// http://en.wikipedia.org/wiki/Private_Use_(Unicode)
var UNICODE_PRIVATE_USE_AREA = {
    start: 0xE001,
    end: 0xF8FF
  }
// http://www.whizkidtech.redprince.net/bezier/circle/
  , KAPPA = ((Math.sqrt(2)-1)/3)*4;

// Required modules
var Path = require("path")
  , Stream = require("stream").PassThrough
  , Fs = require("fs")
  , Sax = require("sax")
  , SVGPathData = require("svg-pathdata");

function svgicons2svgfont(glyphs, options) {
  options = options || {};
  options.fontName = options.fontName || 'iconfont';
  var outputStream = new Stream()
    , log = (options.log || console.log.bind(console))
    , error = options.error || console.error.bind(console);
  glyphs = glyphs.forEach(function (glyph, index, glyphs) {
    // Parsing each icons asynchronously
    var saxStream = Sax.createStream(true);
    saxStream.on('opentag', function(tag) {
      // Change rect elements to the corresponding path
      if('rect' === tag.name) {
        glyph.d.push(
          // Move to the left corner
          'M' + parseFloat(tag.attributes.x,10).toString(10)
          + ' ' + parseFloat(tag.attributes.y,10).toString(10)
          // Draw the rectangle
          + 'h' + parseFloat(tag.attributes.width, 10).toString(10)
          + 'v' + (parseFloat(tag.attributes.height, 10)).toString(10)
          + 'h' + (parseFloat(tag.attributes.width, 10)*-1).toString(10)
          + 'z'
        );
      } else if('line' === tag.name) {
        log('Found a line element in the icon "' + glyph.name + '" the result'
          +' could be different than expected.');
        glyph.d.push(
          // Move to the line start
          'M' + parseFloat(tag.attributes.x1,10).toString(10)
          + ' ' + parseFloat(tag.attributes.y1,10).toString(10)
          + ' ' + (parseFloat(tag.attributes.x1,10)+1).toString(10)
          + ' ' + (parseFloat(tag.attributes.y1,10)+1).toString(10)
          + ' ' + (parseFloat(tag.attributes.x2,10)+1).toString(10)
          + ' ' + (parseFloat(tag.attributes.y2,10)+1).toString(10)
          + ' ' + parseFloat(tag.attributes.x2,10).toString(10)
          + ' ' + parseFloat(tag.attributes.y2,10).toString(10)
          + 'Z'
        );
      } else if('polyline' === tag.name) {
        log('Found a polyline element in the icon "' + glyph.name + '" the'
          +' result could be different than expected.');
        glyph.d.push(
          'M' + tag.attributes.points
        );
      } else if('polygon' === tag.name) {
        glyph.d.push(
          'M' + tag.attributes.points + 'Z'
        );
      } else if('circle' === tag.name || 'ellipse' === tag.name) {
        var cx = parseFloat(tag.attributes.cx,10)
          , cy = parseFloat(tag.attributes.cy,10)
          , rx = 'undefined' !== typeof tag.attributes.rx ?
              parseFloat(tag.attributes.rx,10) : parseFloat(tag.attributes.r,10)
          , ry = 'undefined' !== typeof tag.attributes.ry ?
              parseFloat(tag.attributes.ry,10) : parseFloat(tag.attributes.r,10);
        glyph.d.push(
          'M' + (cx - rx) + ',' + cy
          + 'C' + (cx - rx) + ',' + (cy + ry*KAPPA)
          + ' ' + (cx - rx*KAPPA) + ',' + (cy + ry)
          + ' ' + cx + ',' + (cy + ry)
          + 'C' + (cx + rx*KAPPA) + ',' + (cy+ry)
          + ' ' + (cx + rx) + ',' + (cy + ry*KAPPA)
          + ' ' + (cx + rx) + ',' + cy
          + 'C' + (cx + rx) + ',' + (cy - ry*KAPPA)
          + ' ' + (cx + rx*KAPPA) + ',' + (cy - ry)
          + ' ' + cx + ',' + (cy - ry)
          + 'C' + (cx - rx*KAPPA) + ',' + (cy - ry)
          + ' ' + (cx - rx) + ',' + (cy - ry*KAPPA)
          + ' ' + (cx - rx) + ',' + cy
          + 'Z'
        );
      }
    });
    saxStream.on('attribute', function(attr) {
      if('width' === attr.name && 'svg' === saxStream._parser.tag.name) {
        glyph.width = parseFloat(attr.value, 10);
      } else if('height' === attr.name && 'svg' === saxStream._parser.tag.name) {
        glyph.height = parseFloat(attr.value, 10);
      } else if('d' === attr.name && 'path' === saxStream._parser.tag.name) {
        if(attr.value) {
          glyph.d.push(attr.value);
        }
      }
    });
    saxStream.on('end', function() {
      glyph.running = false;
      if(glyphs.every(function(glyph) {
        return !glyph.running;
      })) {
        var fontHeight = (glyphs.length > 1 ? glyphs.reduce(function (gA, gB) {
          return Math.max(gA.height || gA, gB.height || gB);
        }) : glyphs[0].height);
        if(fontHeight>(glyphs.length > 1 ? glyphs.reduce(function (gA, gB) {
          return Math.min(gA.height || gA, gB.height || gB);
        }) : glyphs[0].height)) {
          log('The provided icons does not have the same height it could lead'
            +' to unexpected results.');
        }
        // Output the SVG file
        // (find a SAX parser that allows modifying SVG on the fly)
        outputStream.write('<?xml version="1.0" standalone="no"?> \n\
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >\n\
<svg xmlns="http://www.w3.org/2000/svg">\n\
<defs>\n\
  \n\
    \n\
    <missing-glyph horiz-adv-x="0" />\n');
        glyphs.forEach(function(glyph) {
          var d = '';
          glyph.d.forEach(function(cD) {
            d+=' '+new SVGPathData(cD).ySymetry(glyph.height).encode();
          });
          delete glyph.d;
          delete glyph.running;
          outputStream.write('\
    <glyph glyph-name="' + glyph.name + '"\n\
      unicode="&#x' + (glyph.codepoint.toString(16)).toUpperCase() + ';"\n\
      horiz-adv-x="' + glyph.width + '" d="' + d +'" />\n');
        });
        outputStream.write('\
  \n\
</defs>\n\
</svg>\n');
        outputStream.on('finish', function() {
          log("Font created");
          'function' === (typeof options.callback) && (options.callback)(glyphs);
        });
        outputStream.end();
      }
    });
    if('string' !== typeof glyph.name) {
      throw Error('Please provide a name for the glyph at index ' + index);
    }
    if(glyphs.some(function(g) {
      return (g !== glyph && g.name === glyph.name);
    })) {
      throw Error('The glyph name "' + glyph.name + '" must be unique.');
    }
    if('number' !== typeof glyph.codepoint) {
      throw Error('Please provide a codepoint for the glyph "' + glyph.name + '"');
    }
    if(glyphs.some(function(g) {
      return (g !== glyph && g.codepoint === glyph.codepoint);
    })) {
      throw Error('The glyph "' + glyph.name
        + '" codepoint seems to be used already elsewhere.');
    }
    glyph.running = true;
    glyph.d = [];
    glyph.stream.pipe(saxStream);
  });
  return outputStream;
}

module.exports = svgicons2svgfont;

<commit_msg>Remove unecessary consts<commit_after>/*
 * svgicons2svgfont
 * https://github.com/nfroidure/svgicons2svgfont
 *
 * Copyright (c) 2013 Nicolas Froidure, Cameron Hunter
 * Licensed under the MIT license.
 */
"use strict";

// http://www.whizkidtech.redprince.net/bezier/circle/
var KAPPA = ((Math.sqrt(2)-1)/3)*4;

// Required modules
var Path = require("path")
  , Stream = require("stream").PassThrough
  , Fs = require("fs")
  , Sax = require("sax")
  , SVGPathData = require("svg-pathdata");

function svgicons2svgfont(glyphs, options) {
  options = options || {};
  options.fontName = options.fontName || 'iconfont';
  var outputStream = new Stream()
    , log = (options.log || console.log.bind(console))
    , error = options.error || console.error.bind(console);
  glyphs = glyphs.forEach(function (glyph, index, glyphs) {
    // Parsing each icons asynchronously
    var saxStream = Sax.createStream(true);
    saxStream.on('opentag', function(tag) {
      // Change rect elements to the corresponding path
      if('rect' === tag.name) {
        glyph.d.push(
          // Move to the left corner
          'M' + parseFloat(tag.attributes.x,10).toString(10)
          + ' ' + parseFloat(tag.attributes.y,10).toString(10)
          // Draw the rectangle
          + 'h' + parseFloat(tag.attributes.width, 10).toString(10)
          + 'v' + (parseFloat(tag.attributes.height, 10)).toString(10)
          + 'h' + (parseFloat(tag.attributes.width, 10)*-1).toString(10)
          + 'z'
        );
      } else if('line' === tag.name) {
        log('Found a line element in the icon "' + glyph.name + '" the result'
          +' could be different than expected.');
        glyph.d.push(
          // Move to the line start
          'M' + parseFloat(tag.attributes.x1,10).toString(10)
          + ' ' + parseFloat(tag.attributes.y1,10).toString(10)
          + ' ' + (parseFloat(tag.attributes.x1,10)+1).toString(10)
          + ' ' + (parseFloat(tag.attributes.y1,10)+1).toString(10)
          + ' ' + (parseFloat(tag.attributes.x2,10)+1).toString(10)
          + ' ' + (parseFloat(tag.attributes.y2,10)+1).toString(10)
          + ' ' + parseFloat(tag.attributes.x2,10).toString(10)
          + ' ' + parseFloat(tag.attributes.y2,10).toString(10)
          + 'Z'
        );
      } else if('polyline' === tag.name) {
        log('Found a polyline element in the icon "' + glyph.name + '" the'
          +' result could be different than expected.');
        glyph.d.push(
          'M' + tag.attributes.points
        );
      } else if('polygon' === tag.name) {
        glyph.d.push(
          'M' + tag.attributes.points + 'Z'
        );
      } else if('circle' === tag.name || 'ellipse' === tag.name) {
        var cx = parseFloat(tag.attributes.cx,10)
          , cy = parseFloat(tag.attributes.cy,10)
          , rx = 'undefined' !== typeof tag.attributes.rx ?
              parseFloat(tag.attributes.rx,10) : parseFloat(tag.attributes.r,10)
          , ry = 'undefined' !== typeof tag.attributes.ry ?
              parseFloat(tag.attributes.ry,10) : parseFloat(tag.attributes.r,10);
        glyph.d.push(
          'M' + (cx - rx) + ',' + cy
          + 'C' + (cx - rx) + ',' + (cy + ry*KAPPA)
          + ' ' + (cx - rx*KAPPA) + ',' + (cy + ry)
          + ' ' + cx + ',' + (cy + ry)
          + 'C' + (cx + rx*KAPPA) + ',' + (cy+ry)
          + ' ' + (cx + rx) + ',' + (cy + ry*KAPPA)
          + ' ' + (cx + rx) + ',' + cy
          + 'C' + (cx + rx) + ',' + (cy - ry*KAPPA)
          + ' ' + (cx + rx*KAPPA) + ',' + (cy - ry)
          + ' ' + cx + ',' + (cy - ry)
          + 'C' + (cx - rx*KAPPA) + ',' + (cy - ry)
          + ' ' + (cx - rx) + ',' + (cy - ry*KAPPA)
          + ' ' + (cx - rx) + ',' + cy
          + 'Z'
        );
      }
    });
    saxStream.on('attribute', function(attr) {
      if('width' === attr.name && 'svg' === saxStream._parser.tag.name) {
        glyph.width = parseFloat(attr.value, 10);
      } else if('height' === attr.name && 'svg' === saxStream._parser.tag.name) {
        glyph.height = parseFloat(attr.value, 10);
      } else if('d' === attr.name && 'path' === saxStream._parser.tag.name) {
        if(attr.value) {
          glyph.d.push(attr.value);
        }
      }
    });
    saxStream.on('end', function() {
      glyph.running = false;
      if(glyphs.every(function(glyph) {
        return !glyph.running;
      })) {
        var fontHeight = (glyphs.length > 1 ? glyphs.reduce(function (gA, gB) {
          return Math.max(gA.height || gA, gB.height || gB);
        }) : glyphs[0].height);
        if(fontHeight>(glyphs.length > 1 ? glyphs.reduce(function (gA, gB) {
          return Math.min(gA.height || gA, gB.height || gB);
        }) : glyphs[0].height)) {
          log('The provided icons does not have the same height it could lead'
            +' to unexpected results.');
        }
        // Output the SVG file
        // (find a SAX parser that allows modifying SVG on the fly)
        outputStream.write('<?xml version="1.0" standalone="no"?> \n\
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >\n\
<svg xmlns="http://www.w3.org/2000/svg">\n\
<defs>\n\
  \n\
    \n\
    <missing-glyph horiz-adv-x="0" />\n');
        glyphs.forEach(function(glyph) {
          var d = '';
          glyph.d.forEach(function(cD) {
            d+=' '+new SVGPathData(cD).ySymetry(glyph.height).encode();
          });
          delete glyph.d;
          delete glyph.running;
          outputStream.write('\
    <glyph glyph-name="' + glyph.name + '"\n\
      unicode="&#x' + (glyph.codepoint.toString(16)).toUpperCase() + ';"\n\
      horiz-adv-x="' + glyph.width + '" d="' + d +'" />\n');
        });
        outputStream.write('\
  \n\
</defs>\n\
</svg>\n');
        outputStream.on('finish', function() {
          log("Font created");
          'function' === (typeof options.callback) && (options.callback)(glyphs);
        });
        outputStream.end();
      }
    });
    if('string' !== typeof glyph.name) {
      throw Error('Please provide a name for the glyph at index ' + index);
    }
    if(glyphs.some(function(g) {
      return (g !== glyph && g.name === glyph.name);
    })) {
      throw Error('The glyph name "' + glyph.name + '" must be unique.');
    }
    if('number' !== typeof glyph.codepoint) {
      throw Error('Please provide a codepoint for the glyph "' + glyph.name + '"');
    }
    if(glyphs.some(function(g) {
      return (g !== glyph && g.codepoint === glyph.codepoint);
    })) {
      throw Error('The glyph "' + glyph.name
        + '" codepoint seems to be used already elsewhere.');
    }
    glyph.running = true;
    glyph.d = [];
    glyph.stream.pipe(saxStream);
  });
  return outputStream;
}

module.exports = svgicons2svgfont;

<|endoftext|>


<commit_before>'use strict';

var proxyLoader = function(source)
{
	if (this && this.cacheable) this.cacheable();
	var extract = /(require\s*\()['"]?([^\)'"]*)['"]?(\))/g;

	var cache = {};

	var x;
	while (x = extract.exec(source))
	{
		cache[x[2]] = {
			prefix: x[1],
			name: x[2],
			postfix: x[3]
		};
	}

	var results = [
		'\'use strict\';',
		'var cache = {'
	];

	var cacheToRequire = [];
	for (var key in cache)
	{
		var value = cache[key];
		cacheToRequire.push('\'' + key + '\': function(){return require(\'' + value.name + '\');}');
	}

	results.push(cacheToRequire.join(',\n'));
	results.push('};');

	// The injector function
	function injector(inject)
	{
		// Override require
		var require = function(moduleName)
		{
			if (inject[moduleName])
			{
				return inject[moduleName];
			}

			if (!cache[moduleName])
			{
				throw 'Could not find module: ' + moduleName;
			}
			return cache[moduleName]();
		};

		// Global module exporters
		var module = {exports: {}};

		// A getter that can switch between CommonJS or AMD
		var getResult = function()
		{
			return module.exports;
		};

		var define = function(moduleDef)
		{
			// Update getResult to support AMD
			getResult = function()
			{
				var result;
				if (moduleDef instanceof Function)
				{
					result = moduleDef(require, module.exports, module);
				}
				else if (moduleDef instanceof Object)
				{
					result = moduleDef;
				}

				// Support AMD modules which export through module.exports inside a define
				if (!result && module.exports)
				{
					return module.exports;
				}

				return result;
			};

			return getResult;
		};
		define.amd = true;

		// Finally, run the module with the overridden define and module objects.
		return (function()
		{
			__INJECTION_POINT__

			return getResult();
		})();
	}

	// Grab the injection block's source and implant the module's source
	var injectorBlock = injector.toString().split('__INJECTION_POINT__').join(source);

	results.push(injectorBlock);

	var tail = [
		'module.exports = injector;'
	];

	return results.concat(tail).join('\n');
};

module.exports = proxyLoader;
<commit_msg>Fixed a bug when using the factory with no inject object.<commit_after>'use strict';

var proxyLoader = function(source)
{
	if (this && this.cacheable) this.cacheable();
	var extract = /(require\s*\()['"]?([^\)'"]*)['"]?(\))/g;

	var cache = {};

	var x;
	while (x = extract.exec(source))
	{
		cache[x[2]] = {
			prefix: x[1],
			name: x[2],
			postfix: x[3]
		};
	}

	var results = [
		'\'use strict\';',
		'var cache = {'
	];

	var cacheToRequire = [];
	for (var key in cache)
	{
		var value = cache[key];
		cacheToRequire.push('\'' + key + '\': function(){return require(\'' + value.name + '\');}');
	}

	results.push(cacheToRequire.join(',\n'));
	results.push('};');

	// The injector function
	function injector(inject)
	{
		// Override require
		var require = function(moduleName)
		{
			if (inject && inject[moduleName])
			{
				return inject[moduleName];
			}

			if (!cache[moduleName])
			{
				throw 'Could not find module: ' + moduleName;
			}
			return cache[moduleName]();
		};

		// Global module exporters
		var module = {exports: {}};

		// A getter that can switch between CommonJS or AMD
		var getResult = function()
		{
			return module.exports;
		};

		var define = function(moduleDef)
		{
			// Update getResult to support AMD
			getResult = function()
			{
				var result;
				if (moduleDef instanceof Function)
				{
					result = moduleDef(require, module.exports, module);
				}
				else if (moduleDef instanceof Object)
				{
					result = moduleDef;
				}

				// Support AMD modules which export through module.exports inside a define
				if (!result && module.exports)
				{
					return module.exports;
				}

				return result;
			};

			return getResult;
		};
		define.amd = true;

		// Finally, run the module with the overridden define and module objects.
		return (function()
		{
			__INJECTION_POINT__

			return getResult();
		})();
	}

	// Grab the injection block's source and implant the module's source
	var injectorBlock = injector.toString().split('__INJECTION_POINT__').join(source);

	results.push(injectorBlock);

	var tail = [
		'module.exports = injector;'
	];

	return results.concat(tail).join('\n');
};

module.exports = proxyLoader;
<|endoftext|>


<commit_before>"use strict";

const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const requireAll = require('require-all');
const TelegramBot = require('node-telegram-bot-api');
const GitHubNotifications = require('./services/GitHubNotifications');
const User = require('./models/User');
const BOT_COMMANDS = requireAll({dirname: `${__dirname}/commands`});
const app = express();

if (!process.env.TELEGRAM_BOT_TOKEN) throw new Error('You must provide TELEGRAM_BOT_TOKEN');
if (!process.env.MONGODB_URI) throw new Error('You must provide MONGODB_URI');
if (!process.env.PORT) throw new Error('You must provide PORT');

const bot = new TelegramBot(process.env.TELEGRAM_BOT_TOKEN, {polling: process.env.NODE_ENV !== 'production'});
if (process.env.NODE_ENV === 'production') bot.setWebHook(`https://telegram-bot-github.herokuapp.com/${bot.token}`);

Object.keys(BOT_COMMANDS).forEach(command => BOT_COMMANDS[command](bot));

app.use(bodyParser.json());
app.get(`/`, (req, res) => res.redirect('http://telegram.me/GitHubNotificationsBot'));
app.post(`/${process.env.TELEGRAM_BOT_TOKEN}`, (req, res) => {
  bot.processUpdate(req.body);
  res.sendStatus(200);
});
app.listen(process.env.PORT);

mongoose.connect(process.env.MONGODB_URI);

User.find({}, (error, users) => {
  if (error) throw new Error(error);

  users.forEach(user => {
    new GitHubNotifications(user.username, user.token).on('notification', data => {
      bot.sendMessage(user.telegramId, `${data}`);
    });
  });
});
<commit_msg>fix(bot): Fix issue with setting webhook<commit_after>"use strict";

const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const requireAll = require('require-all');
const TelegramBot = require('node-telegram-bot-api');
const GitHubNotifications = require('./services/GitHubNotifications');
const User = require('./models/User');
const MESSAGES = require('./common/messages');
const BOT_COMMANDS = requireAll({dirname: `${__dirname}/commands`});
const app = express();

if (!process.env.TELEGRAM_BOT_TOKEN) throw new Error('You must provide TELEGRAM_BOT_TOKEN');
if (!process.env.MONGODB_URI) throw new Error('You must provide MONGODB_URI');
if (!process.env.PORT) throw new Error('You must provide PORT');

const bot = new TelegramBot(process.env.TELEGRAM_BOT_TOKEN, {polling: process.env.NODE_ENV !== 'production'});
if (process.env.NODE_ENV === 'production') {
  bot.setWebHook(`https://telegram-bot-github.herokuapp.com/${bot.token}`)
} else {
  bot.setWebHook('');
}

Object.keys(BOT_COMMANDS).forEach(command => BOT_COMMANDS[command](bot));

app.use(bodyParser.json());
app.get(`/`, (req, res) => res.redirect('http://telegram.me/GitHubNotificationsBot'));
app.post(`/${process.env.TELEGRAM_BOT_TOKEN}`, (req, res) => {
  bot.processUpdate(req.body);
  res.sendStatus(200);
});
app.listen(process.env.PORT);

mongoose.connect(process.env.MONGODB_URI);

User.find({}, (error, users) => {
  if (error) throw new Error(error);

  users.forEach(user => {
    GitHubNotifications.subscribe(user.username, user.token)
      .on('notification', notification => bot.sendMessage(user.telegramId, `${notification}`))
      .once('unauthorized', () => bot.sendMessage(user.telegramId, MESSAGES.UNAUTHORIZED));
  });
});
<|endoftext|>


<commit_before>module.exports = {
    Framework: require('./struct/Framework'),
    Command: require('./struct/commands/Command'),
    Inhibitor: require('./struct/commands/Inhibitor'),
    Listener: require('./struct/events/Listener'),
    DatabaseHandler: require('./struct/databases/DatabaseHandler'),
    SQLiteHandler: require('./struct/databases/SQLiteHandler')
};<commit_msg>expose version<commit_after>module.exports = {
    Framework: require('./struct/Framework'),
    Command: require('./struct/commands/Command'),
    Inhibitor: require('./struct/commands/Inhibitor'),
    Listener: require('./struct/events/Listener'),
    DatabaseHandler: require('./struct/databases/DatabaseHandler'),
    SQLiteHandler: require('./struct/databases/SQLiteHandler'),
    version: require('../package.json').version
};<|endoftext|>


<commit_before>import React from 'react'

import cs from 'classnames'
import moment from 'moment'
import 'moment-range'

import DaysView from './day-view'
import MonthsView from './month-view'
import YearsView from './year-view'
import Util from './util'

class Calendar extends React.Component {
  constructor(props, context) {
    super(props, context)
    const date = props.date ? moment(Util.toDate(props.date)) : null
    const minDate = props.minDate ? moment(Util.toDate(props.minDate)) : null
    const maxDate = props.maxDate ? moment(Util.toDate(props.maxDate)) : null
    const format = props.format || 'MM-DD-YYYY'
    const minView = parseInt(props.minView, 10) || 0
    const computableFormat = props.computableFormat || 'MM-DD-YYYY'
    const strictDateParsing = props.strictDateParsing || false
    const parsingFormat = props.parsingFormat || format

    this.state = {
      date,
      minDate,
      maxDate,
      format,
      computableFormat,
      inputValue: date ? date.format(format) : undefined,
      views: ['days', 'months', 'years'],
      minView,
      currentView: minView || 0,
      isVisible: false,
      strictDateParsing,
      parsingFormat
    }
  }

  componentDidMount() {
    document.addEventListener('click', this.documentClick)
  }

  componentWillReceiveProps(nextProps) {

    this.setState({
      date: nextProps.date ? moment(Util.toDate(nextProps.date)) : this.state.date,
      inputValue: nextProps.date
        ? moment(Util.toDate(nextProps.date)).format(this.state.format) : null,
        isVisible: nextProps.disabled === true
    })
  }

  componentWillUnmount() {
    document.removeEventListener('click', this.documentClick)
  }

  changeDate = e => { //eslint-disable-line
    this.setState({ inputValue: e.target.value })
  }

  checkIfDateDisabled(date) {
    return date && this.state.minDate && date.isBefore(this.state.minDate, 'day')
      || date && this.state.maxDate && date.isAfter(this.state.maxDate, 'day')
  }

  documentClick = e => {
    e.preventDefault();
    if (!this.state.isCalendar) {
      this.setVisibility(false)
    }
    this.setState({ isCalendar: false })

  }

  inputBlur = e => {
    let newDate = null
    let computableDate = null
    const date = this.state.inputValue
    const format = this.state.format
    const parsingFormat = this.state.parsingFormat

    if (date) {
      // format, with strict parsing true, so we catch bad dates
      newDate = moment(date, parsingFormat, true)
      // if the new date didn't match our format, see if the native
      // js date can parse it
      if (!newDate.isValid() && !this.props.strictDateParsing) {
        let d = new Date(date)
        // if native js cannot parse, just make a new date
        if (isNaN(d.getTime())) {
          d = new Date()
        }
        newDate = moment(d)
      }

      computableDate = newDate.format(this.state.computableFormat)
    }

    this.setState({
      date: newDate,
      inputValue: newDate ? newDate.format(format) : null
    })

    if (this.props.onChange) {
      this.props.onChange(computableDate)
    }

    if (this.props.onBlur) {
      this.props.onBlur(e, computableDate)
    }
  }

  inputFocus = e => {
    if (this.props.openOnInputFocus) {
      this.toggleClick()
    }

    if (this.props.onFocus) {
      this.props.onFocus(e)
    }
  }

  keyDown = e => {
    Util.keyDownActions.call(this, e.keyCode)
  }

  nextView = () => {
    if (this.checkIfDateDisabled(this.state.date)) return
    this.setState({ currentView: ++this.state.currentView })
  }

  prevView = date => {
    let newDate = date
    if (this.state.minDate && date.isBefore(this.state.minDate, 'day')) {
      newDate = this.state.minDate.clone()
    }

    if (this.state.maxDate && date.isAfter(this.state.maxDate, 'day')) {
      newDate = this.state.maxDate.clone()
    }

    if (this.state.currentView === this.state.minView) {
      this.setState({
        date: newDate,
        inputValue: date.format(this.state.format),
        isVisible: false
      })
      if (this.props.onChange) {
        this.props.onChange(date.format(this.state.computableFormat))
      }
    } else {
      this.setState({
        date,
        currentView: --this.state.currentView
      })
    }
  }

  setDate = (date, isDayView = true) => {
    if (this.checkIfDateDisabled(date)) return

    this.setState({
      date,
      inputValue: date.format(this.state.format),
      isVisible: this.props.closeOnSelect
        && isDayView ? !this.state.isVisible : this.state.isVisible
    })

    if (this.props.onChange) {
      this.props.onChange(date.format(this.state.computableFormat))
    }
  }

  setVisibility(val) {
    const value = val !== undefined ? val : !this.state.isVisible
    const eventMethod = value ? 'addEventListener' : 'removeEventListener'

    document[eventMethod]('keydown', this.keyDown)

    if (this.state.isVisible !== value && !this.props.disabled) {
      this.setState({ isVisible: value })
    }
  }

  calendarClick = () => {
    this.setState({ isCalendar: true })
  }

  todayClick = () => {
    const today = moment().startOf('day')

    if (this.checkIfDateDisabled(today)) return

    this.setState({
      date: today,
      inputValue: today.format(this.state.format),
      currentView: this.state.minView
    })

    if (this.props.onChange) {
      this.props.onChange(today.format(this.state.computableFormat))
    }
  }

  toggleClick = () => {
    this.setState({ isCalendar: true })
    this.setVisibility()
  }

  render() {
    // its ok for this.state.date to be null, but we should never
    // pass null for the date into the calendar pop up, as we want
    // it to just start on todays date if there is no date set
    let calendarDate = this.state.date || moment()
    let view

    switch (this.state.currentView) {
      case 0:
        view = (<DaysView
          date={calendarDate}
          nextView={this.nextView}
          maxDate={this.state.maxDate}
          minDate={this.state.minDate}
          setDate={this.setDate}
        />)
        break
      case 1:
        view = (<MonthsView
          date={calendarDate}
          nextView={this.nextView}
          maxDate={this.state.maxDate}
          minDate={this.state.minDate}
          prevView={this.prevView}
          setDate={this.setDate}
        />)
        break
      case 2:
        view = (<YearsView
          date={calendarDate}
          maxDate={this.state.maxDate}
          minDate={this.state.minDate}
          prevView={this.prevView}
          setDate={this.setDate}
        />)
        break
      default:
        view = (<DaysView
          date={calendarDate}
          nextView={this.nextView}
          maxDate={this.state.maxDate}
          minDate={this.state.minDate}
          setDate={this.setDate}
        />)
    }

    let todayText = this.props.todayText || (moment.locale() === 'de' ? 'Heute' : 'Today')
    let calendarClass = cs({
      'input-calendar-wrapper': true,
      'icon-hidden': this.props.hideIcon
    })

    let calendar = !this.state.isVisible || this.props.disabled ? '' :

        {view}
        <span
          className={
            `today-btn${this.checkIfDateDisabled(moment().startOf('day')) ? ' disabled' : ''}`
          }
          onClick={this.todayClick}>
          {todayText}

    let readOnly = false

    if (this.props.hideTouchKeyboard) {
      // do not break server side rendering:
      try {
        if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i
          .test(navigator.userAgent)) {
          readOnly = true
        }
      } catch (e) {
        console.warn(e) //eslint-disable-line
      }
    }

    let calendarIcon
    if (this.props.customIcon == null) {
      // Do not show calendar icon if hideIcon is true
      calendarIcon = this.props.hideIcon || this.props.disabled ? '' :

          <svg width="16" height="16" viewBox="0 0 16 16">
            <path d="M5 6h2v2h-2zM8 6h2v2h-2zM11 6h2v2h-2zM2 12h2v2h-2zM5
              12h2v2h-2zM8 12h2v2h-2zM5 9h2v2h-2zM8 9h2v2h-2zM11 9h2v2h-2zM2
              9h2v2h-2zM13 0v1h-2v-1h-7v1h-2v-1h-2v16h15v-16h-2zM14
              15h-13v-11h13v11z"
            />
          </svg>

    } else {
      calendarIcon = (

      )
    }

    const inputClass = this.props.inputFieldClass || 'input-calendar-field'

    return (

        <input
          name={this.props.inputName}
          className={inputClass}
          id={this.props.inputFieldId}
          onBlur={this.inputBlur}
          onChange={this.changeDate}
          onFocus={this.inputFocus}
          placeholder={this.props.placeholder}
          readOnly={readOnly}
          disabled={this.props.disabled}
          type="text"
          value={this.state.inputValue}
        />
        {calendarIcon}
        {calendar}

    )
  }
}

Calendar.propTypes = {
  closeOnSelect: React.PropTypes.bool,
  computableFormat: React.PropTypes.string,
  strictDateParsing: React.PropTypes.bool,
  parsingFormat: React.PropTypes.oneOfType([
    React.PropTypes.string,
    React.PropTypes.arrayOf(React.PropTypes.string)
  ]),
  date: React.PropTypes.any,
  minDate: React.PropTypes.any,
  maxDate: React.PropTypes.any,
  format: React.PropTypes.string,
  inputName: React.PropTypes.string,
  inputFieldId: React.PropTypes.string,
  inputFieldClass: React.PropTypes.string,
  minView: React.PropTypes.number,
  onBlur: React.PropTypes.func,
  onChange: React.PropTypes.func,
  onFocus: React.PropTypes.func,
  openOnInputFocus: React.PropTypes.bool,
  placeholder: React.PropTypes.string,
  hideTouchKeyboard: React.PropTypes.bool,
  hideIcon: React.PropTypes.bool,
  customIcon: React.PropTypes.string,
  todayText: React.PropTypes.string,
  disabled: React.PropTypes.bool
}

export default Calendar
<commit_msg>wrong implementation of support for disabled property<commit_after>import React from 'react'

import cs from 'classnames'
import moment from 'moment'
import 'moment-range'

import DaysView from './day-view'
import MonthsView from './month-view'
import YearsView from './year-view'
import Util from './util'

class Calendar extends React.Component {
  constructor(props, context) {
    super(props, context)
    const date = props.date ? moment(Util.toDate(props.date)) : null
    const minDate = props.minDate ? moment(Util.toDate(props.minDate)) : null
    const maxDate = props.maxDate ? moment(Util.toDate(props.maxDate)) : null
    const format = props.format || 'MM-DD-YYYY'
    const minView = parseInt(props.minView, 10) || 0
    const computableFormat = props.computableFormat || 'MM-DD-YYYY'
    const strictDateParsing = props.strictDateParsing || false
    const parsingFormat = props.parsingFormat || format

    this.state = {
      date,
      minDate,
      maxDate,
      format,
      computableFormat,
      inputValue: date ? date.format(format) : undefined,
      views: ['days', 'months', 'years'],
      minView,
      currentView: minView || 0,
      isVisible: false,
      strictDateParsing,
      parsingFormat
    }
  }

  componentDidMount() {
    document.addEventListener('click', this.documentClick)
  }

  componentWillReceiveProps(nextProps) {
    let newState = {
      date: nextProps.date ? moment(Util.toDate(nextProps.date)) : this.state.date,
      inputValue:
        nextProps.date ? moment(Util.toDate(nextProps.date)).format(this.state.format) : null,
    }

    if (nextProps.disabled === true) {
      newState.isVisible = false
    }

    this.setState(newState)
  }

  componentWillUnmount() {
    document.removeEventListener('click', this.documentClick)
  }

  changeDate = e => { //eslint-disable-line
    this.setState({ inputValue: e.target.value })
  }

  checkIfDateDisabled(date) {
    return date && this.state.minDate && date.isBefore(this.state.minDate, 'day')
      || date && this.state.maxDate && date.isAfter(this.state.maxDate, 'day')
  }

  documentClick = e => {
    e.preventDefault();
    if (!this.state.isCalendar) {
      this.setVisibility(false)
    }
    this.setState({ isCalendar: false })

  }

  inputBlur = e => {
    let newDate = null
    let computableDate = null
    const date = this.state.inputValue
    const format = this.state.format
    const parsingFormat = this.state.parsingFormat

    if (date) {
      // format, with strict parsing true, so we catch bad dates
      newDate = moment(date, parsingFormat, true)
      // if the new date didn't match our format, see if the native
      // js date can parse it
      if (!newDate.isValid() && !this.props.strictDateParsing) {
        let d = new Date(date)
        // if native js cannot parse, just make a new date
        if (isNaN(d.getTime())) {
          d = new Date()
        }
        newDate = moment(d)
      }

      computableDate = newDate.format(this.state.computableFormat)
    }

    this.setState({
      date: newDate,
      inputValue: newDate ? newDate.format(format) : null
    })

    if (this.props.onChange) {
      this.props.onChange(computableDate)
    }

    if (this.props.onBlur) {
      this.props.onBlur(e, computableDate)
    }
  }

  inputFocus = e => {
    if (this.props.openOnInputFocus) {
      this.toggleClick()
    }

    if (this.props.onFocus) {
      this.props.onFocus(e)
    }
  }

  keyDown = e => {
    Util.keyDownActions.call(this, e.keyCode)
  }

  nextView = () => {
    if (this.checkIfDateDisabled(this.state.date)) return
    this.setState({ currentView: ++this.state.currentView })
  }

  prevView = date => {
    let newDate = date
    if (this.state.minDate && date.isBefore(this.state.minDate, 'day')) {
      newDate = this.state.minDate.clone()
    }

    if (this.state.maxDate && date.isAfter(this.state.maxDate, 'day')) {
      newDate = this.state.maxDate.clone()
    }

    if (this.state.currentView === this.state.minView) {
      this.setState({
        date: newDate,
        inputValue: date.format(this.state.format),
        isVisible: false
      })
      if (this.props.onChange) {
        this.props.onChange(date.format(this.state.computableFormat))
      }
    } else {
      this.setState({
        date,
        currentView: --this.state.currentView
      })
    }
  }

  setDate = (date, isDayView = true) => {
    if (this.checkIfDateDisabled(date)) return

    this.setState({
      date,
      inputValue: date.format(this.state.format),
      isVisible: this.props.closeOnSelect
        && isDayView ? !this.state.isVisible : this.state.isVisible
    })

    if (this.props.onChange) {
      this.props.onChange(date.format(this.state.computableFormat))
    }
  }

  setVisibility(val) {
    const value = val !== undefined ? val : !this.state.isVisible
    const eventMethod = value ? 'addEventListener' : 'removeEventListener'

    document[eventMethod]('keydown', this.keyDown)

    if (this.state.isVisible !== value && !this.props.disabled) {
      this.setState({ isVisible: value })
    }
  }

  calendarClick = () => {
    this.setState({ isCalendar: true })
  }

  todayClick = () => {
    const today = moment().startOf('day')

    if (this.checkIfDateDisabled(today)) return

    this.setState({
      date: today,
      inputValue: today.format(this.state.format),
      currentView: this.state.minView
    })

    if (this.props.onChange) {
      this.props.onChange(today.format(this.state.computableFormat))
    }
  }

  toggleClick = () => {
    this.setState({ isCalendar: true })
    this.setVisibility()
  }

  render() {
    // its ok for this.state.date to be null, but we should never
    // pass null for the date into the calendar pop up, as we want
    // it to just start on todays date if there is no date set
    let calendarDate = this.state.date || moment()
    let view

    switch (this.state.currentView) {
      case 0:
        view = (<DaysView
          date={calendarDate}
          nextView={this.nextView}
          maxDate={this.state.maxDate}
          minDate={this.state.minDate}
          setDate={this.setDate}
        />)
        break
      case 1:
        view = (<MonthsView
          date={calendarDate}
          nextView={this.nextView}
          maxDate={this.state.maxDate}
          minDate={this.state.minDate}
          prevView={this.prevView}
          setDate={this.setDate}
        />)
        break
      case 2:
        view = (<YearsView
          date={calendarDate}
          maxDate={this.state.maxDate}
          minDate={this.state.minDate}
          prevView={this.prevView}
          setDate={this.setDate}
        />)
        break
      default:
        view = (<DaysView
          date={calendarDate}
          nextView={this.nextView}
          maxDate={this.state.maxDate}
          minDate={this.state.minDate}
          setDate={this.setDate}
        />)
    }

    let todayText = this.props.todayText || (moment.locale() === 'de' ? 'Heute' : 'Today')
    let calendarClass = cs({
      'input-calendar-wrapper': true,
      'icon-hidden': this.props.hideIcon
    })

    let calendar = !this.state.isVisible || this.props.disabled ? '' :

        {view}
        <span
          className={
            `today-btn${this.checkIfDateDisabled(moment().startOf('day')) ? ' disabled' : ''}`
          }
          onClick={this.todayClick}>
          {todayText}

    let readOnly = false

    if (this.props.hideTouchKeyboard) {
      // do not break server side rendering:
      try {
        if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i
          .test(navigator.userAgent)) {
          readOnly = true
        }
      } catch (e) {
        console.warn(e) //eslint-disable-line
      }
    }

    let calendarIcon
    if (this.props.customIcon == null) {
      // Do not show calendar icon if hideIcon is true
      calendarIcon = this.props.hideIcon || this.props.disabled ? '' :

          <svg width="16" height="16" viewBox="0 0 16 16">
            <path d="M5 6h2v2h-2zM8 6h2v2h-2zM11 6h2v2h-2zM2 12h2v2h-2zM5
              12h2v2h-2zM8 12h2v2h-2zM5 9h2v2h-2zM8 9h2v2h-2zM11 9h2v2h-2zM2
              9h2v2h-2zM13 0v1h-2v-1h-7v1h-2v-1h-2v16h15v-16h-2zM14
              15h-13v-11h13v11z"
            />
          </svg>

    } else {
      calendarIcon = (

      )
    }

    const inputClass = this.props.inputFieldClass || 'input-calendar-field'

    return (

        <input
          name={this.props.inputName}
          className={inputClass}
          id={this.props.inputFieldId}
          onBlur={this.inputBlur}
          onChange={this.changeDate}
          onFocus={this.inputFocus}
          placeholder={this.props.placeholder}
          readOnly={readOnly}
          disabled={this.props.disabled}
          type="text"
          value={this.state.inputValue}
        />
        {calendarIcon}
        {calendar}

    )
  }
}

Calendar.propTypes = {
  closeOnSelect: React.PropTypes.bool,
  computableFormat: React.PropTypes.string,
  strictDateParsing: React.PropTypes.bool,
  parsingFormat: React.PropTypes.oneOfType([
    React.PropTypes.string,
    React.PropTypes.arrayOf(React.PropTypes.string)
  ]),
  date: React.PropTypes.any,
  minDate: React.PropTypes.any,
  maxDate: React.PropTypes.any,
  format: React.PropTypes.string,
  inputName: React.PropTypes.string,
  inputFieldId: React.PropTypes.string,
  inputFieldClass: React.PropTypes.string,
  minView: React.PropTypes.number,
  onBlur: React.PropTypes.func,
  onChange: React.PropTypes.func,
  onFocus: React.PropTypes.func,
  openOnInputFocus: React.PropTypes.bool,
  placeholder: React.PropTypes.string,
  hideTouchKeyboard: React.PropTypes.bool,
  hideIcon: React.PropTypes.bool,
  customIcon: React.PropTypes.string,
  todayText: React.PropTypes.string,
  disabled: React.PropTypes.bool
}

export default Calendar
<|endoftext|>


<commit_before>import dotenv from 'dotenv';
import { spawnSync } from 'child_process';

dotenv.config({ silent: true });

const args = process.argv.slice(2);
const res = spawnSync(
  args[0],
  args.slice(1),
  {
    env: process.env,
    stdio: 'inherit',
  },
);

if (res.status) {
  process.exit(res.status);
} else if (res.error) {
  process.exit(1);
}
<commit_msg>Implemented dotenv path option via -p argument<commit_after>import dotenv from 'dotenv';
import path from 'path';
import { spawnSync } from 'child_process';

let args = process.argv.slice(2);
const opts = {
  silent: true
};

// Check if a path option has been passed.
if (args[0] === '-p') {
  Object.assign(opts, {
    path: path.resolve(process.cwd(), args[1])
  });
  // remove both args.
  args.splice(0, 2)
}

dotenv.config(opts);

const res = spawnSync(
  args[0],
  args.slice(1), {
    env: process.env,
    stdio: 'inherit',
  },
);

if (res.status) {
  process.exit(res.status);
} else if (res.error) {
  process.exit(1);
}<|endoftext|>


<commit_before>const async = require('async')
const path = require('path')
const fs = require('fs')
require('colors')

let Compiler = require('./compiler.js')
let Deployer = require('./deployer.js')
let TestRunner = require('./testRunner.js')

const Web3 = require('web3')
const Provider = require('remix-simulator').Provider

var createWeb3Provider = function() {
  let web3 = new Web3()
  web3.setProvider(new Provider())
  return web3
}

var runTestSources = function (contractSources, testCallback, resultCallback, finalCallback) {
  async.waterfall([
    function compile (next) {
      Compiler.compileContractSources(contractSources, next)
    },
    function deployAllContracts (compilationResult, next) {
      let web3 = createWeb3Provider();
      Deployer.deployAll(compilationResult, web3, function (err, contracts) {
        if (err) {
          next(err)
        }

        next(null, compilationResult, contracts)
      })
    },
    function determineTestContractsToRun (compilationResult, contracts, next) {
      let contractsToTest = []

      for (let filename in compilationResult) {
        let contract = compilationResult[filename];
        if (filename.indexOf('_test.sol') < 0) {
          continue
        }
        Object.keys(compilationResult[filename]).forEach(contractName => {
          contractsToTest.push(contractName)
        })
      }

      next(null, contractsToTest, contracts)
    },
    function runTests (contractsToTest, contracts, next) {
      let totalPassing = 0
      let totalFailing = 0
      let totalTime = 0
      let errors = []

      var _testCallback = function (result) {
        if (result.type === 'testFailure') {
          errors.push(result)
        }
        testCallback(result);
      }

      var _resultsCallback = function (_err, result, cb) {
        resultCallback(_err, result, () => {});
        totalPassing += result.passingNum
        totalFailing += result.failureNum
        totalTime += result.timePassed
        cb()
      }

      async.eachOfLimit(contractsToTest, 1, (contractName, index, cb) => {
        TestRunner.runTest(contractName, contracts[contractName], _testCallback, (err, result) => {
          if (err) {
            return cb(err)
          }
          _resultsCallback(null, result, cb)
        })
      }, function (err, _results) {
        if (err) {
          return next(err)
        }

        let finalResults = {};

        finalResults.totalPassing = totalPassing || 0;
        finalResults.totalFailing = totalFailing || 0;
        finalResults.totalTime = totalTime || 0;
        finalResults.errors = [];

        errors.forEach((error, _index) => {
          finalResults.errors.push({context: error.context, value: error.value, message: error.errMsg});
        })

        next(null, finalResults);
      })
    }
  ], finalCallback);
}

var runTestFiles = function (filepath, isDirectory, web3) {
  async.waterfall([
    function compile (next) {
      Compiler.compileFileOrFiles(filepath, isDirectory, next)
    },
    function deployAllContracts (compilationResult, next) {
      Deployer.deployAll(compilationResult, web3, function (err, contracts) {
        if (err) {
          next(err)
        }

        next(null, compilationResult, contracts)
      })
    },
    function determineTestContractsToRun (compilationResult, contracts, next) {
      let contractsToTest = []
      if (isDirectory) {
        fs.readdirSync(filepath).forEach(filename => {
          if (filename.indexOf('_test.sol') < 0) {
            return
          }
          Object.keys(compilationResult[path.basename(filename)]).forEach(contractName => {
            contractsToTest.push(contractName)
          })
        })
      } else {
        contractsToTest = Object.keys(compilationResult[path.basename(filepath)])
      }

      next(null, contractsToTest, contracts)
    },
    function runTests (contractsToTest, contracts, next) {
      let totalPassing = 0
      let totalFailing = 0
      let totalTime = 0
      let errors = []

      var testCallback = function (result) {
        if (result.type === 'contract') {
          console.log('\n  ' + result.value)
        } else if (result.type === 'testPass') {
          console.log('\t✓ '.green.bold + result.value.grey)
        } else if (result.type === 'testFailure') {
          console.log('\t✘ '.bold.red + result.value.red)
          errors.push(result)
        }
      }
      var resultsCallback = function (_err, result, cb) {
        totalPassing += result.passingNum
        totalFailing += result.failureNum
        totalTime += result.timePassed
        cb()
      }

      async.eachOfLimit(contractsToTest, 1, (contractName, index, cb) => {
        TestRunner.runTest(contractName, contracts[contractName], testCallback, (err, result) => {
          if (err) {
            return cb(err)
          }
          resultsCallback(null, result, cb)
        })
      }, function (err, _results) {
        if (err) {
          return next(err)
        }

        console.log('\n')
        if (totalPassing > 0) {
          console.log(('  ' + totalPassing + ' passing ').green + ('(' + totalTime + 's)').grey)
        }
        if (totalFailing > 0) {
          console.log(('  ' + totalFailing + ' failing').red)
        }
        console.log('')

        errors.forEach((error, index) => {
          console.log('  ' + (index + 1) + ') ' + error.context + ' ' + error.value)
          console.log('')
          console.log(('\t error: ' + error.errMsg).red)
        })
        console.log('')

        next()
      })
    }
  ], function () {
  })
}

module.exports = {
  runTestFiles: runTestFiles,
  runTestSources: runTestSources,
  runTest: TestRunner.runTest,
  assertLibCode: require('../sol/tests.sol.js')
}
<commit_msg>Add importFileCb to index.js<commit_after>const async = require('async')
const path = require('path')
const fs = require('fs')
require('colors')

let Compiler = require('./compiler.js')
let Deployer = require('./deployer.js')
let TestRunner = require('./testRunner.js')

const Web3 = require('web3')
const Provider = require('remix-simulator').Provider

var createWeb3Provider = function() {
  let web3 = new Web3()
  web3.setProvider(new Provider())
  return web3
}

var runTestSources = function (contractSources, testCallback, resultCallback, finalCallback, importFileCb) {
  async.waterfall([
    function compile (next) {
      Compiler.compileContractSources(contractSources, importFileCb, next)
    },
    function deployAllContracts (compilationResult, next) {
      let web3 = createWeb3Provider();
      Deployer.deployAll(compilationResult, web3, function (err, contracts) {
        if (err) {
          next(err)
        }

        next(null, compilationResult, contracts)
      })
    },
    function determineTestContractsToRun (compilationResult, contracts, next) {
      let contractsToTest = []

      for (let filename in compilationResult) {
        let contract = compilationResult[filename];
        if (filename.indexOf('_test.sol') < 0) {
          continue
        }
        Object.keys(compilationResult[filename]).forEach(contractName => {
          contractsToTest.push(contractName)
        })
      }

      next(null, contractsToTest, contracts)
    },
    function runTests (contractsToTest, contracts, next) {
      let totalPassing = 0
      let totalFailing = 0
      let totalTime = 0
      let errors = []

      var _testCallback = function (result) {
        if (result.type === 'testFailure') {
          errors.push(result)
        }
        testCallback(result);
      }

      var _resultsCallback = function (_err, result, cb) {
        resultCallback(_err, result, () => {});
        totalPassing += result.passingNum
        totalFailing += result.failureNum
        totalTime += result.timePassed
        cb()
      }

      async.eachOfLimit(contractsToTest, 1, (contractName, index, cb) => {
        TestRunner.runTest(contractName, contracts[contractName], _testCallback, (err, result) => {
          if (err) {
            return cb(err)
          }
          _resultsCallback(null, result, cb)
        })
      }, function (err, _results) {
        if (err) {
          return next(err)
        }

        let finalResults = {};

        finalResults.totalPassing = totalPassing || 0;
        finalResults.totalFailing = totalFailing || 0;
        finalResults.totalTime = totalTime || 0;
        finalResults.errors = [];

        errors.forEach((error, _index) => {
          finalResults.errors.push({context: error.context, value: error.value, message: error.errMsg});
        })

        next(null, finalResults);
      })
    }
  ], finalCallback);
}

var runTestFiles = function (filepath, isDirectory, web3) {
  async.waterfall([
    function compile (next) {
      Compiler.compileFileOrFiles(filepath, isDirectory, next)
    },
    function deployAllContracts (compilationResult, next) {
      Deployer.deployAll(compilationResult, web3, function (err, contracts) {
        if (err) {
          next(err)
        }

        next(null, compilationResult, contracts)
      })
    },
    function determineTestContractsToRun (compilationResult, contracts, next) {
      let contractsToTest = []
      if (isDirectory) {
        fs.readdirSync(filepath).forEach(filename => {
          if (filename.indexOf('_test.sol') < 0) {
            return
          }
          Object.keys(compilationResult[path.basename(filename)]).forEach(contractName => {
            contractsToTest.push(contractName)
          })
        })
      } else {
        contractsToTest = Object.keys(compilationResult[path.basename(filepath)])
      }

      next(null, contractsToTest, contracts)
    },
    function runTests (contractsToTest, contracts, next) {
      let totalPassing = 0
      let totalFailing = 0
      let totalTime = 0
      let errors = []

      var testCallback = function (result) {
        if (result.type === 'contract') {
          console.log('\n  ' + result.value)
        } else if (result.type === 'testPass') {
          console.log('\t✓ '.green.bold + result.value.grey)
        } else if (result.type === 'testFailure') {
          console.log('\t✘ '.bold.red + result.value.red)
          errors.push(result)
        }
      }
      var resultsCallback = function (_err, result, cb) {
        totalPassing += result.passingNum
        totalFailing += result.failureNum
        totalTime += result.timePassed
        cb()
      }

      async.eachOfLimit(contractsToTest, 1, (contractName, index, cb) => {
        TestRunner.runTest(contractName, contracts[contractName], testCallback, (err, result) => {
          if (err) {
            return cb(err)
          }
          resultsCallback(null, result, cb)
        })
      }, function (err, _results) {
        if (err) {
          return next(err)
        }

        console.log('\n')
        if (totalPassing > 0) {
          console.log(('  ' + totalPassing + ' passing ').green + ('(' + totalTime + 's)').grey)
        }
        if (totalFailing > 0) {
          console.log(('  ' + totalFailing + ' failing').red)
        }
        console.log('')

        errors.forEach((error, index) => {
          console.log('  ' + (index + 1) + ') ' + error.context + ' ' + error.value)
          console.log('')
          console.log(('\t error: ' + error.errMsg).red)
        })
        console.log('')

        next()
      })
    }
  ], function () {
  })
}

module.exports = {
  runTestFiles: runTestFiles,
  runTestSources: runTestSources,
  runTest: TestRunner.runTest,
  assertLibCode: require('../sol/tests.sol.js')
}
<|endoftext|>


<commit_before>/**
 * Created by thram on 21/01/17.
 */
import forEach from "lodash/forEach";
import assign from "lodash/assign";
import isArray from "lodash/isArray";
import {observe, state, removeObserver} from "thrux";

export const connect = (stateKey, ReactComponent) => {
  class ThruxComponent extends ReactComponent {

    observers = {};

    constructor(props) {
      super(props);
      this.state = assign(this.state || {}, state([].concat(stateKey)));
    }

    addObserver = (key) => {
      this.observers[key] = (state) => {
        let newState  = {};
        newState[key] = state;
        this.setState(newState);
      };
      observe(key, this.observers[key]);
    };

    componentDidMount(...args) {
      isArray(stateKey) ? forEach(stateKey, this.addObserver) : this.addObserver(stateKey);
      super.componentDidMount.apply(this, args);
    }

    componentWillUnmount(...args) {
      super.componentWillUnmount.apply(this, args);
      forEach(this.observers, (observer, key) => removeObserver(key, observer));
    }
  }
  return ThruxComponent;
};<commit_msg>fix(mount): Check first if the componentDidMount and componentWillUnmount are defined<commit_after>/**
 * Created by thram on 21/01/17.
 */
import forEach from "lodash/forEach";
import assign from "lodash/assign";
import isArray from "lodash/isArray";
import {observe, state, removeObserver} from "thrux";

export const connect = (stateKey, ReactComponent) => {
  class ThruxComponent extends ReactComponent {

    observers = {};

    constructor(props) {
      super(props);
      this.state = assign(this.state || {}, state([].concat(stateKey)));
    }

    addObserver = (key) => {
      this.observers[key] = (state) => {
        let newState  = {};
        newState[key] = state;
        this.setState(newState);
      };
      observe(key, this.observers[key]);
    };

    componentDidMount(...args) {
      isArray(stateKey) ? forEach(stateKey, this.addObserver) : this.addObserver(stateKey);
      super.componentDidMount && super.componentDidMount.apply(this, args);
    }

    componentWillUnmount(...args) {
      super.componentWillUnmount && super.componentWillUnmount.apply(this, args);
      forEach(this.observers, (observer, key) => removeObserver(key, observer));
    }
  }
  return ThruxComponent;
};<|endoftext|>


<commit_before>'use strict';

var loaders = {},
    projectPath = '',
    // variables for testing
    locals = {},
    depth = 0;

exports._require = require;

exports.test = {};

/**
 * Set the project path
 *
 * @param {String} path
 *
 * @returns {Object} The module object
 */
exports.setPath = function(path) {
    projectPath = path;

    // fluent interface
    return exports;
};

/**
 * Reset the loader module
 *
 * @returns {Object} The module object
 */
exports.reset = function() {
    exports._require = require;
    projectPath = '';
    for(var name in loaders) {
        delete exports[name];
        delete exports.test[name];
    }
    loaders = {};

    // fluent interface
    return exports;
};

/**
 * Add a loader function
 *
 * @param {String}   name     The name of the loader function
 * @param {Function} callback The loader function
 *
 * @returns {Object} The module object
 */
exports.addLoader = function(name, callback) {
    var req = exports._require;
    exports[name] = loaders[name] = function(identifier) {
        var returnValue = callback.call(exports, projectPath, identifier);

        return (typeof returnValue === 'string') ? req(returnValue) : returnValue;
    };
    exports.test[name] = function(identifier, loc) {
        var locals = loc || {},
            depth = 0;

        // change how the normal loader function reacts
        for(var loaderName in loaders) {
            exports[loaderName] = (function(loader, local) {
                return function(identifier) {
                    var module;
                    depth++;
                    if(depth === 1 && local && local[identifier]) {
                        module = local[identifier];
                    } else {
                        module = loader(identifier);
                    }
                    depth--;
                    return module;
                };
            }(loaders[loaderName], locals[loaderName]));
        }

        var returnValue = callback.call(exports, projectPath, identifier);

        var filename = req.resolve(returnValue),
            cached = req.cache[filename];

        // delete cache
        delete req.cache[filename];
        var moduleToTest = req(returnValue);
        // restore cache
        req.cache[filename] = cached;

        // reset the normal loader function
        for(var loaderName in loaders) {
            exports[loaderName] = loaders[loaderName];
        }

        return moduleToTest;
    };

    // fluent interface
    return exports;
};<commit_msg>better restoring<commit_after>'use strict';

var loaders = {},
    projectPath = '',
    // variables for testing
    locals = {},
    depth = 0;

exports._require = require;

exports.test = {};

/**
 * Set the project path
 *
 * @param {String} path
 *
 * @returns {Object} The module object
 */
exports.setPath = function(path) {
    projectPath = path;

    // fluent interface
    return exports;
};

/**
 * Reset the loader module
 *
 * @returns {Object} The module object
 */
exports.reset = function() {
    exports._require = require;
    projectPath = '';
    for(var name in loaders) {
        delete exports[name];
        delete exports.test[name];
    }
    loaders = {};

    // fluent interface
    return exports;
};

/**
 * Add a loader function
 *
 * @param {String}   name     The name of the loader function
 * @param {Function} callback The loader function
 *
 * @returns {Object} The module object
 */
exports.addLoader = function(name, callback) {
    var req = exports._require;
    exports[name] = loaders[name] = function(identifier) {
        var returnValue = callback.call(exports, projectPath, identifier);

        return (typeof returnValue === 'string') ? req(returnValue) : returnValue;
    };
    exports.test[name] = function(identifier, loc) {
        var locals = loc || {},
            depth = 0;

        // change how the normal loader function reacts
        for(var loaderName in loaders) {
            exports[loaderName] = (function(loader, local) {
                return function(identifier) {
                    var module;
                    depth++;
                    if(depth === 1 && local && local[identifier]) {
                        module = local[identifier];
                    } else {
                        module = loader(identifier);
                    }
                    depth--;
                    return module;
                };
            }(loaders[loaderName], locals[loaderName]));
        }

        var returnValue = callback.call(exports, projectPath, identifier);

        var filename = req.resolve(returnValue),
            cached = req.cache[filename],
            isCached = !!cached;

        // delete cache
        delete req.cache[filename];
        var moduleToTest = req(returnValue);
        // restore cache
        if(isCached) {
            req.cache[filename] = cached;
        } else {
            delete req.cache[filename];
        }

        // reset the normal loader function
        for(var loaderName in loaders) {
            exports[loaderName] = loaders[loaderName];
        }

        return moduleToTest;
    };

    // fluent interface
    return exports;
};<|endoftext|>


<commit_before>/**
 * Configuration
 * @type {Object}
 */
let config = {
  debug: false,
  excludes: []
}

/**
 * Event tracking
 * @param  {String} category
 * @param  {String} action
 * @param  {String} [label='']
 * @param  {Number} [value=0]
 */
const event = (category, action, label = '', value = 0) => {
  if (typeof window.ga === 'undefined') {
    return
  }

  if (config.debug) {
    /* eslint-disable */
    console.groupCollapsed(`[VueAnalytics] Track event category "${category}"`)
    console.log(`category: ${category}`)
    console.log(`action: ${action}`)
    console.log(`label: ${label}`)
    console.log(`value: ${value}`)
    console.groupEnd()
    /* eslint-enable */
  }

  window.ga('send', 'event', category, action, label, value)
}

/**
 * Page tracking
 * @param  {String} page
 * @param  {String} title
 * @param  {String} location
 */
const page = (page, title = '', location = '') => {
  if (typeof window.ga === 'undefined') {
    return
  }

  if (config.debug) {
    /* eslint-disable */
    console.groupCollapsed(`[VueAnalytics] Track page "${page}"`)
    console.log(`page: ${page}`)
    console.log(`title: ${title}`)
    console.log(`location: ${location}`)
    console.groupEnd()
    /* eslint-enable */
  }

  window.ga('send', 'pageview', { page, title, location })
}

/**
 * Vue installer
 * @param  {Vue instance} Vue
 * @param  {Object} [options={}]
 */
const install = (Vue, options = {}) => {
  const { router, debug, excludeRoutes } = options

  config.excludes = excludeRoutes || config.excludes
  config.debug = !!debug

  Vue['$track'] = { event, page }

  if (router) {
    const { excludes } = config

    router.afterEach(({ path, name }) => {
      if (excludes.length && excludes.indexOf(name) !== -1) {
        return
      }

      Vue.$track.page(path, name, window.location.href)
    })
  }
}

export default { install }
<commit_msg>refactor(alias) add "ga" as alias of the "track" object<commit_after>/**
 * Configuration
 * @type {Object}
 */
let config = {
  debug: false,
  excludes: []
}

/**
 * Event tracking
 * @param  {String} category
 * @param  {String} action
 * @param  {String} [label='']
 * @param  {Number} [value=0]
 */
const event = (category, action, label = '', value = 0) => {
  if (typeof window.ga === 'undefined') {
    return
  }

  if (config.debug) {
    /* eslint-disable */
    console.groupCollapsed(`[VueAnalytics] Track event category "${category}"`)
    console.log(`category: ${category}`)
    console.log(`action: ${action}`)
    console.log(`label: ${label}`)
    console.log(`value: ${value}`)
    console.groupEnd()
    /* eslint-enable */
  }

  window.ga('send', 'event', category, action, label, value)
}

/**
 * Page tracking
 * @param  {String} page
 * @param  {String} title
 * @param  {String} location
 */
const page = (page, title = '', location = '') => {
  if (typeof window.ga === 'undefined') {
    return
  }

  if (config.debug) {
    /* eslint-disable */
    console.groupCollapsed(`[VueAnalytics] Track page "${page}"`)
    console.log(`page: ${page}`)
    console.log(`title: ${title}`)
    console.log(`location: ${location}`)
    console.groupEnd()
    /* eslint-enable */
  }

  window.ga('send', 'pageview', { page, title, location })
}

/**
 * Vue installer
 * @param  {Vue instance} Vue
 * @param  {Object} [options={}]
 */
const install = (Vue, options = {}) => {
  const { router, debug, excludeRoutes } = options

  config.excludes = excludeRoutes || config.excludes
  config.debug = !!debug

  /**
   * Naming conventions
   * Using "track" for semantic purposes
   * Using "ga", as an alias, for a more familiar feeling
   */
  Vue.track = Vue.ga = { event, page }

  Vue.prototype.$track = Vue.prototype.$ga = { event, page }

  if (router) {
    const { excludes } = config

    router.afterEach(({ path, name }) => {
      if (excludes.length && excludes.indexOf(name) !== -1) {
        return
      }

      Vue.track.page(path, name, window.location.href)
    })
  }
}

export default { install }
<|endoftext|>


<commit_before>// import ReactDom from 'react-dom'

// ReactDom.render((
//

//
hello world

//

// ) , document.getElementById('app'));

var React = require('react');
var ReactDOM = require('react-dom');

class Hello extends React.Component {
  render() {
    return
Hello world
;
  }
}

ReactDOM.render(
  <Hello />,
  document.getElementById('app')
);<commit_msg>add material-ui<commit_after>// import ReactDom from 'react-dom'

// ReactDom.render((
//

//
hello world

//

// ) , document.getElementById('app'));

import mui from 'material-ui';
// let MenuItem = mui.MenuItem;
// let LeftNav = mui.LeftNav;
let RaisedButton = mui.RaisedButton;

var React = require('react');
var ReactDOM = require('react-dom');

class Hello extends React.Component{
  render() {
    return
Hello world
;
  }
}

ReactDOM.render(

	  <Hello />
	  <RaisedButton label="hello" primary={true}/>

  ,
  document.getElementById('app')
);<|endoftext|>


<commit_before>import './index.css';
import * as storage from 'redux-storage'
import App from './components';
import React from 'react';
import ReactDOM from 'react-dom';
import createEngine from 'redux-storage-engine-indexed-db';
import filter from 'redux-storage-decorator-filter';
import rootReducer from './reducers/';
import thunk from 'redux-thunk';
import { ActionTypes } from './config/constants';
import { Provider } from 'react-redux';
import { applyMiddleware, createStore } from 'redux';

const reducer = storage.reducer(rootReducer);
const engine = filter(createEngine('tickets'), [
  ['tickets', 'nested'],
  ['tickets', 'flattened'],
]);

const store = createStore(
  reducer,
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
  applyMiddleware(
    thunk,
    storage.createMiddleware(engine, [], [ActionTypes.TICKETS_UPDATE]),
  ),
);

const load = storage.createLoader(engine);
load(store);

 ReactDOM.render(
   <Provider store={store}>
     <App />
   </Provider>,
  document.getElementById('root')
);
<commit_msg>Update IndexedDB on TICKETS_REMOVE<commit_after>import './index.css';
import * as storage from 'redux-storage'
import App from './components';
import React from 'react';
import ReactDOM from 'react-dom';
import createEngine from 'redux-storage-engine-indexed-db';
import filter from 'redux-storage-decorator-filter';
import rootReducer from './reducers/';
import thunk from 'redux-thunk';
import { ActionTypes } from './config/constants';
import { Provider } from 'react-redux';
import { applyMiddleware, createStore } from 'redux';

const reducer = storage.reducer(rootReducer);
const engine = filter(createEngine('tickets'), [
  ['tickets', 'nested'],
  ['tickets', 'flattened'],
]);

// Actions that trigger an IndexedDB update
const engineActions = [
  ActionTypes.TICKETS_REMOVE,
  ActionTypes.TICKETS_UPDATE,
];

const store = createStore(
  reducer,
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
  applyMiddleware(
    thunk,
    storage.createMiddleware(engine, [], engineActions),
  ),
);

const load = storage.createLoader(engine);
load(store);

 ReactDOM.render(
   <Provider store={store}>
     <App />
   </Provider>,
  document.getElementById('root')
);
<|endoftext|>