<commit_before>require('es6-promise').polyfill();
require('isomorphic-fetch');

const Atrium = module.exports = {};

Atrium.environments = {
  local: 'http://localhost:3000',
  development: 'https://vestibule.mx.com/',
  production: 'https://atrium.mx.com/'
};

Atrium.endpoints = [
  //MX Connect
  {
    method: 'post',
    url: '/users/:userGuid/connect_widget_url',
    clientMethod: 'getConnectWidgetUrl'
  },
  //Users
  {
    method: 'post',
    url: '/users',
    clientMethod: 'createUser'
  },
  {
    method: 'get',
    url: '/users/:userGuid',
    clientMethod: 'readUser'
  },
  {
    method: 'put',
    url: '/users/:userGuid',
    clientMethod: 'updateUser'
  },
  {
    method: 'get',
    url: '/users',
    clientMethod: 'listUsers'
  },
  {
    method: 'delete',
    url: '/users/:userGuid',
    clientMethod: 'deleteUser'
  },
  //Institutions
  {
    method: 'get',
    url: '/institutions',
    clientMethod: 'listInstitutions'
  },
  {
    method: 'get',
    url: '/institutions/:institutionCode',
    clientMethod: 'readInstitution'
  },
  //Credentials
  {
    method: 'get',
    url: '/institutions/:institutionCode/credentials',
    clientMethod: 'listCredentials'
  },
  //Members
  {
    method: 'get',
    url: '/users/:userGuid/members',
    clientMethod: 'listMembers'
  },
  {
    method: 'post',
    url: '/users/:userGuid/members',
    clientMethod: 'createMember'
  },
  {
    method: 'get',
    url: '/users/:userGuid/members/:memberGuid',
    clientMethod: 'readMember'
  },
  {
    method: 'put',
    url: '/users/:userGuid/members/:memberGuid',
    clientMethod: 'updateMember'
  },
  {
    method: 'delete',
    url: '/users/:userGuid/members/:memberGuid',
    clientMethod: 'deleteMember'
  },
  {
    method: 'get',
    url: '/users/:userGuid/members',
    clientMethod: 'listMembers'
  },
  {
    method: 'post',
    url: '/users/:userGuid/members/:memberGuid/aggregate',
    clientMethod: 'aggregateMember'
  },
  {
    method: 'put',
    url: '/users/:userGuid/members/:memberGuid/resume',
    clientMethod: 'resumeMemberAggregation'
  },
  {
    method: 'get',
    url: '/users/:userGuid/members/:memberGuid/credentials',
    clientMethod: 'listMemberCredentials'
  },
  {
    method: 'get',
    url: '/users/:userGuid/members/:memberGuid/accounts',
    clientMethod: 'listMemberAccounts'
  },
  {
    method: 'get',
    url: '/users/:userGuid/members/:memberGuid/transactions',
    clientMethod: 'listMemberTransactions'
  },
  {
    method: 'get',
    url: '/users/:userGuid/members/:memberGuid/challenges',
    clientMethod: 'listMemberChallenges'
  },
  {
    method: 'get',
    url: '/users/:userGuid/members/:memberGuid/status',
    clientMethod: 'checkMemberStatus'
  },
  {
    method: 'get',
    url: '/users/:userGuid/accounts',
    clientMethod: 'listAccounts'
  },
  {
    method: 'get',
    url: '/users/:userGuid/accounts/:accountGuid',
    clientMethod: 'readAccount'
  },
  {
    method: 'get',
    url: '/users/:userGuid/accounts/:accountGuid/transactions',
    clientMethod: 'listAccountTransactions'
  },
  //Holdings
  {
    method: 'get',
    url: '/users/:userGuid/holdings',
    clientMethod: 'listHoldings'
  },
  {
    method: 'get',
    url: '/users/:userGuid/holdings/:holdingGuid',
    clientMethod: 'readHolding'
  },
  //Transactions
  {
    method: 'get',
    url: '/users/:userGuid/transactions',
    clientMethod: 'listTransactions'
  },
  {
    method: 'get',
    url: '/users/:userGuid/transactions/:transactionGuid',
    clientMethod: 'readTransaction'
  }
];

Atrium.Client = function (apiKey, clientID, url) {
  if (!clientID) {
    throw new Error('Missing client ID');
  }

  if (!apiKey) {
    throw new Error('Missing API key');
  }

  if (url !== Atrium.environments.production && url !== Atrium.environments.development && url !== Atrium.environments.local) {
    throw new Error('Invalid environment');
  }

  this.url = url;
  this.clientID = clientID;
  this.apiKey = apiKey;
};

//Fetch utility
Atrium.Client.prototype._fetchUtility = function (endpoint, method, params = null) {
  const body = params ? JSON.stringify(params) : null;

  return (fetch(this.url + '/' + endpoint, {
    method,
    body,
    headers: {
      'Accept': 'application/vnd.mx.atrium.v1+json',
      'Content-Type': 'application/json',
      'MX-API-KEY': this.apiKey,
      'MX-CLIENT-ID': this.clientID
    }
  }))
  .then(response => {
    if (response.ok) {
      return response.json();
    } else {
      return response;
    }
  });
};

//Parameters utility
Atrium.Client.prototype.optionalParameters = function (name, fromDate, toDate, pageNumber, recordsPerPage) {
  var params = "?";
  if (name != null) {
    params += "name=" + name + "&";
  }
  if (fromDate != null) {
    params += "from_date=" + fromDate + "&";
  }
  if (toDate != null) {
    params += "to_date=" + toDate + "&";
  }
  if (pageNumber != null) {
    params += "page=" + pageNumber + "&";
  }
  if (recordsPerPage != null) {
    params += "records_per_page=" + recordsPerPage + "&";
  }
  params = params.slice(0, -1);

  return params;
};

//Users
Atrium.Client.prototype.createUser = function (request) {
  return this._fetchUtility('users', 'POST', request.body);
};

Atrium.Client.prototype.readUser = function (request) {
  return this._fetchUtility('users/' + request.params.userGuid, 'GET');
};

Atrium.Client.prototype.updateUser = function (request) {
  const user = Object.assign({}, request.body.user);

  delete user.guid;
  delete user.id;
  delete user.logged_in_at;

  return this._fetchUtility('users/' + request.body.user.guid, 'PUT', { user });
};

Atrium.Client.prototype.listUsers = function (request) {
  var params = this.optionalParameters(null, null, null, request.params.pageNumber, request.params.recordsPerPage);

  return this._fetchUtility('users' + params, 'GET');
};

Atrium.Client.prototype.deleteUser = function (request) {
  return this._fetchUtility('users/' + request.params.userGuid, 'DELETE');
};

//Institutions
Atrium.Client.prototype.listInstitutions = function (request) {
  var params = this.optionalParameters(request.params.name, null, null, request.params.pageNumber, request.params.recordsPerPage);

  return this._fetchUtility('institutions' + params, 'GET');
};

Atrium.Client.prototype.readInstitution = function (request) {
  return this._fetchUtility('institutions/' + request.params.institutionCode, 'GET');
};

Atrium.Client.prototype.listCredentials = function (request) {
  var params = this.optionalParameters(null, null, null, request.params.pageNumber, request.params.recordsPerPage);

  return this._fetchUtility(`institutions/${request.params.institutionCode}/credentials` + params, 'GET');
};

//Members
Atrium.Client.prototype.createMember = function (request) {
  return this._fetchUtility(`users/${request.params.userGuid}/members`, 'POST', request.body);
};

Atrium.Client.prototype.readMember = function (request) {
  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}`, 'GET');
};

Atrium.Client.prototype.updateMember = function (request) {
  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}`, 'PUT', request.body);
};

Atrium.Client.prototype.deleteMember = function (request) {
  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}`, 'DELETE');
};

Atrium.Client.prototype.listMembers = function (request) {
  var params = this.optionalParameters(null, null, null, request.params.pageNumber, request.params.recordsPerPage);

  return this._fetchUtility(`users/${request.params.userGuid}/members` + params, 'GET');
};

Atrium.Client.prototype.aggregateMember = function (request) {
  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}/aggregate`, 'POST');
};

Atrium.Client.prototype.checkMemberStatus = function (request) {
  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}/status`, 'GET');
};

Atrium.Client.prototype.listMemberChallenges = function (request) {
  var params = this.optionalParameters(null, null, null, request.params.pageNumber, request.params.recordsPerPage);

  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}/challenges` + params, 'GET');
};

Atrium.Client.prototype.resumeMemberAggregation = function (request) {
  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}/resume`, 'PUT', request.body);
};

Atrium.Client.prototype.listMemberCredentials = function (request) {
  var params = this.optionalParameters(null, null, null, request.params.pageNumber, request.params.recordsPerPage);

  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}/credentials` + params, 'GET');
};

Atrium.Client.prototype.listMemberAccounts = function (request) {
  var params = this.optionalParameters(null, null, null, request.params.pageNumber, request.params.recordsPerPage);

  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}/accounts` + params, 'GET');
};

Atrium.Client.prototype.listMemberTransactions = function (request) {
  var params = this.optionalParameters(null, request.params.fromDate, request.params.toDate, request.params.pageNumber, request.params.recordsPerPage);

  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}/transactions` + params, 'GET');
};

//Accounts
Atrium.Client.prototype.readAccount = function (request) {
  return this._fetchUtility(`users/${request.params.userGuid}/accounts/${request.params.accountGuid}`, 'GET');
};

Atrium.Client.prototype.listAccounts = function (request) {
  var params = this.optionalParameters(null, null, null, request.params.pageNumber, request.params.recordsPerPage);

  return this._fetchUtility(`users/${request.params.userGuid}/accounts` + params, 'GET');
};

Atrium.Client.prototype.listAccountTransactions = function (request) {
  var params = this.optionalParameters(null, request.params.fromDate, request.params.toDate, request.params.pageNumber, request.params.recordsPerPage);

  return this._fetchUtility(`users/${request.params.userGuid}/accounts/${request.params.accountGuid}/transactions` + params, 'GET');
};

//Transactions
Atrium.Client.prototype.readTransaction = function (request) {
  return this._fetchUtility(`users/${request.params.userGuid}/transactions/${request.params.transactionGuid}`, 'GET');
};

Atrium.Client.prototype.listTransactions = function (request) {
  var params = this.optionalParameters(null, request.params.fromDate, request.params.toDate, request.params.pageNumber, request.params.recordsPerPage);

  return this._fetchUtility(`users/${request.params.userGuid}/transactions` + params, 'GET');
};

//MX Connect
Atrium.Client.prototype.getConnectWidgetUrl = function (request) {
  return this._fetchUtility(`users/${request.params.userGuid}/connect_widget_url`, 'POST');
};
<commit_msg>updated optional params<commit_after>require('es6-promise').polyfill();
require('isomorphic-fetch');

const Atrium = module.exports = {};

Atrium.environments = {
  local: 'http://localhost:3000',
  development: 'https://vestibule.mx.com/',
  production: 'https://atrium.mx.com/'
};

Atrium.endpoints = [
  //MX Connect
  {
    method: 'post',
    url: '/users/:userGuid/connect_widget_url',
    clientMethod: 'getConnectWidgetUrl'
  },
  //Users
  {
    method: 'post',
    url: '/users',
    clientMethod: 'createUser'
  },
  {
    method: 'get',
    url: '/users/:userGuid',
    clientMethod: 'readUser'
  },
  {
    method: 'put',
    url: '/users/:userGuid',
    clientMethod: 'updateUser'
  },
  {
    method: 'get',
    url: '/users',
    clientMethod: 'listUsers'
  },
  {
    method: 'delete',
    url: '/users/:userGuid',
    clientMethod: 'deleteUser'
  },
  //Institutions
  {
    method: 'get',
    url: '/institutions',
    clientMethod: 'listInstitutions'
  },
  {
    method: 'get',
    url: '/institutions/:institutionCode',
    clientMethod: 'readInstitution'
  },
  //Credentials
  {
    method: 'get',
    url: '/institutions/:institutionCode/credentials',
    clientMethod: 'listCredentials'
  },
  //Members
  {
    method: 'get',
    url: '/users/:userGuid/members',
    clientMethod: 'listMembers'
  },
  {
    method: 'post',
    url: '/users/:userGuid/members',
    clientMethod: 'createMember'
  },
  {
    method: 'get',
    url: '/users/:userGuid/members/:memberGuid',
    clientMethod: 'readMember'
  },
  {
    method: 'put',
    url: '/users/:userGuid/members/:memberGuid',
    clientMethod: 'updateMember'
  },
  {
    method: 'delete',
    url: '/users/:userGuid/members/:memberGuid',
    clientMethod: 'deleteMember'
  },
  {
    method: 'get',
    url: '/users/:userGuid/members',
    clientMethod: 'listMembers'
  },
  {
    method: 'post',
    url: '/users/:userGuid/members/:memberGuid/aggregate',
    clientMethod: 'aggregateMember'
  },
  {
    method: 'put',
    url: '/users/:userGuid/members/:memberGuid/resume',
    clientMethod: 'resumeMemberAggregation'
  },
  {
    method: 'get',
    url: '/users/:userGuid/members/:memberGuid/credentials',
    clientMethod: 'listMemberCredentials'
  },
  {
    method: 'get',
    url: '/users/:userGuid/members/:memberGuid/accounts',
    clientMethod: 'listMemberAccounts'
  },
  {
    method: 'get',
    url: '/users/:userGuid/members/:memberGuid/transactions',
    clientMethod: 'listMemberTransactions'
  },
  {
    method: 'get',
    url: '/users/:userGuid/members/:memberGuid/challenges',
    clientMethod: 'listMemberChallenges'
  },
  {
    method: 'get',
    url: '/users/:userGuid/members/:memberGuid/status',
    clientMethod: 'checkMemberStatus'
  },
  {
    method: 'get',
    url: '/users/:userGuid/accounts',
    clientMethod: 'listAccounts'
  },
  {
    method: 'get',
    url: '/users/:userGuid/accounts/:accountGuid',
    clientMethod: 'readAccount'
  },
  {
    method: 'get',
    url: '/users/:userGuid/accounts/:accountGuid/transactions',
    clientMethod: 'listAccountTransactions'
  },
  //Holdings
  {
    method: 'get',
    url: '/users/:userGuid/holdings',
    clientMethod: 'listHoldings'
  },
  {
    method: 'get',
    url: '/users/:userGuid/holdings/:holdingGuid',
    clientMethod: 'readHolding'
  },
  //Transactions
  {
    method: 'get',
    url: '/users/:userGuid/transactions',
    clientMethod: 'listTransactions'
  },
  {
    method: 'get',
    url: '/users/:userGuid/transactions/:transactionGuid',
    clientMethod: 'readTransaction'
  }
];

Atrium.Client = function (apiKey, clientID, url) {
  if (!clientID) {
    throw new Error('Missing client ID');
  }

  if (!apiKey) {
    throw new Error('Missing API key');
  }

  if (url !== Atrium.environments.production && url !== Atrium.environments.development && url !== Atrium.environments.local) {
    throw new Error('Invalid environment');
  }

  this.url = url;
  this.clientID = clientID;
  this.apiKey = apiKey;
};

//Fetch utility
Atrium.Client.prototype._fetchUtility = function (endpoint, method, params = null) {
  const body = params ? JSON.stringify(params) : null;

  return (fetch(this.url + '/' + endpoint, {
    method,
    body,
    headers: {
      'Accept': 'application/vnd.mx.atrium.v1+json',
      'Content-Type': 'application/json',
      'MX-API-KEY': this.apiKey,
      'MX-CLIENT-ID': this.clientID
    }
  }))
  .then(response => {
    if (response.ok && response.status != 204) {
      return response.json();
    } else {
      return response;
    }
  });
};

//Parameters utility
Atrium.Client.prototype.optionalParameters = function (request) {
  var params = "?";
  if ("params" in request) {
    var passedParams = request.params;
    if ("name" in passedParams && request.params.name != null) {
      params += "name=" + request.params.name + "&";
    }
    if ("from_date" in passedParams && request.params.from_date != null) {
      params += "from_date=" + request.params.from_date + "&";
    }
    if ("to_date" in passedParams && request.params.to_date != null) {
      params += "to_date=" + request.params.to_date + "&";
    }
    if ("page" in passedParams && request.params.page != null) {
      params += "page=" + request.params.page + "&";
    }
    if ("records_per_page" in passedParams && request.params.records_per_page != null) {
      params += "records_per_page=" + request.params.records_per_page + "&";
    }
  }
  params = params.slice(0, -1);

  return params;
};

//Users
Atrium.Client.prototype.createUser = function (request = {}) {
  return this._fetchUtility('users', 'POST', request.body);
};

Atrium.Client.prototype.readUser = function (request = {}) {
  return this._fetchUtility('users/' + request.params.userGuid, 'GET');
};

Atrium.Client.prototype.updateUser = function (request = {}) {
  const user = Object.assign({}, request.body.user);

  delete user.guid;
  delete user.id;
  delete user.logged_in_at;

  return this._fetchUtility('users/' + request.body.user.guid, 'PUT', { user });
};

Atrium.Client.prototype.listUsers = function (request = {}) {
  var params = this.optionalParameters(request);

  return this._fetchUtility('users' + params, 'GET');
};

Atrium.Client.prototype.deleteUser = function (request = {}) {
  return this._fetchUtility('users/' + request.params.userGuid, 'DELETE');
};

//Institutions
Atrium.Client.prototype.listInstitutions = function (request = {}) {
  var params = this.optionalParameters(request);

  return this._fetchUtility('institutions' + params, 'GET');
};

Atrium.Client.prototype.readInstitution = function (request = {}) {
  return this._fetchUtility('institutions/' + request.params.institutionCode, 'GET');
};

Atrium.Client.prototype.listCredentials = function (request = {}) {
  var params = this.optionalParameters(request);

  return this._fetchUtility(`institutions/${request.params.institutionCode}/credentials` + params, 'GET');
};

//Members
Atrium.Client.prototype.createMember = function (request = {}) {
  return this._fetchUtility(`users/${request.params.userGuid}/members`, 'POST', request.body);
};

Atrium.Client.prototype.readMember = function (request = {}) {
  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}`, 'GET');
};

Atrium.Client.prototype.updateMember = function (request = {}) {
  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}`, 'PUT', request.body);
};

Atrium.Client.prototype.deleteMember = function (request = {}) {
  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}`, 'DELETE');
};

Atrium.Client.prototype.listMembers = function (request = {}) {
  var params = this.optionalParameters(request);

  return this._fetchUtility(`users/${request.params.userGuid}/members` + params, 'GET');
};

Atrium.Client.prototype.aggregateMember = function (request = {}) {
  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}/aggregate`, 'POST');
};

Atrium.Client.prototype.checkMemberStatus = function (request = {}) {
  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}/status`, 'GET');
};

Atrium.Client.prototype.listMemberChallenges = function (request = {}) {
  var params = this.optionalParameters(request);

  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}/challenges` + params, 'GET');
};

Atrium.Client.prototype.resumeMemberAggregation = function (request = {}) {
  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}/resume`, 'PUT', request.body);
};

Atrium.Client.prototype.listMemberCredentials = function (request = {}) {
  var params = this.optionalParameters(request);

  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}/credentials` + params, 'GET');
};

Atrium.Client.prototype.listMemberAccounts = function (request = {}) {
  var params = this.optionalParameters(request);

  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}/accounts` + params, 'GET');
};

Atrium.Client.prototype.listMemberTransactions = function (request = {}) {
  var params = this.optionalParameters(request);

  return this._fetchUtility(`users/${request.params.userGuid}/members/${request.params.memberGuid}/transactions` + params, 'GET');
};

//Accounts
Atrium.Client.prototype.readAccount = function (request = {}) {
  return this._fetchUtility(`users/${request.params.userGuid}/accounts/${request.params.accountGuid}`, 'GET');
};

Atrium.Client.prototype.listAccounts = function (request = {}) {
  var params = this.optionalParameters(request);

  return this._fetchUtility(`users/${request.params.userGuid}/accounts` + params, 'GET');
};

Atrium.Client.prototype.listAccountTransactions = function (request = {}) {
  var params = this.optionalParameters(request);

  return this._fetchUtility(`users/${request.params.userGuid}/accounts/${request.params.accountGuid}/transactions` + params, 'GET');
};

//Transactions
Atrium.Client.prototype.readTransaction = function (request = {}) {
  return this._fetchUtility(`users/${request.params.userGuid}/transactions/${request.params.transactionGuid}`, 'GET');
};

Atrium.Client.prototype.listTransactions = function (request = {}) {
  var params = this.optionalParameters(request);

  return this._fetchUtility(`users/${request.params.userGuid}/transactions` + params, 'GET');
};

//MX Connect
Atrium.Client.prototype.getConnectWidgetUrl = function (request = {}) {
  return this._fetchUtility(`users/${request.params.userGuid}/connect_widget_url`, 'POST');
};
<|endoftext|>


<commit_before>require('colors');

var SpecReporter = function(baseReporterDecorator, formatError) {
  baseReporterDecorator(this);

  // colorize output of BaseReporter functions
  this.USE_COLORS = true;
  this.SPEC_FAILURE = '%s %s FAILED'.red + '\n';
  this.SPEC_SLOW = '%s SLOW %s: %s'.yellow + '\n';
  this.ERROR = '%s ERROR'.red + '\n';
  this.FINISHED_ERROR = ' ERROR'.red;
  this.FINISHED_SUCCESS = ' SUCCESS'.green;
  this.FINISHED_DISCONNECTED = ' DISCONNECTED'.red;
  this.X_FAILED = ' (%d FAILED)'.red;
  this.TOTAL_SUCCESS = 'TOTAL: %d SUCCESS'.green + '\n';
  this.TOTAL_FAILED = 'TOTAL: %d FAILED, %d SUCCESS'.red + '\n';

  this.onRunStart = function(browsers) {
    browsers.forEach(function(browser) {
      // useful properties
      browser.id;
      browser.fullName;
    });
  };

  this.onBrowserComplete = function(browser) {
    // useful properties
    var result = browser.lastResult;
    result.total;
    result.disconnected;
    result.error;
    result.failed;
    result.netTime; // in millieseconds? or microseconds?
  };

  this.onRunComplete = function(browsers, results) {
    // the renderBrowser function is defined in karma/reporters/Base.js
    this.writeCommonMsg(browsers.map(this.renderBrowser).join('\n') + '\n');

    if (browsers.length > 1 && !results.disconnected && !results.error) {
      if (!results.failed) {
        this.write(this.TOTAL_SUCCESS, results.success);
      } else {
        this.write(this.TOTAL_FAILED, results.failed, results.success);
      }
    }

    this.write("\n");
  };

  this.currentSuite = [];
  this.writeSpecMessage = function(status) {
    return (function(browser, result) {
      var suite = result.suite
      var indent = "";
      suite.forEach(
        // beware, this in the context of a foreach loop is not what you expect!
        // To be sure, we bind this explicitly
        (function(value, index) {
          if (index >= this.currentSuite.length || this.currentSuite[index] != value) {
            if (index == 0) {
              this.writeCommonMsg('\n');
            }
            this.writeCommonMsg(indent + value + ':\n');
            this.currentSuite = [];
          }
          indent += "    ";
        }).bind(this)
      );
      this.currentSuite = suite;

      var specName = result.description;
      //TODO: add timing information
      var msg = '  '  + indent + status + " - " + specName, specName

      result.log.forEach(function(log) {
        // TODO: have to find out, what this line exactly does. just copied it from karma's BaseReporter
        msg += formatError(log, '\t');
      });

      this.writeCommonMsg(msg + '\n');

      // other useful properties
      browser.id;
      browser.fullName;
      result.time;
      result.skipped;
      result.success;
    }).bind(this);
  };

  this.specSuccess = this.writeSpecMessage('PASSED '.green);
  this.specSkipped = this.writeSpecMessage('SKIPPED'.gray);
  this.specFailure = this.writeSpecMessage('FAILED '.red);
};

SpecReporter.$inject = ['baseReporterDecorator', 'logger', 'formatError'];

module.exports = {
  'reporter:spec': ['type', SpecReporter]
};
<commit_msg>removed unused and mismatched logger statement from inject<commit_after>require('colors');

var SpecReporter = function(baseReporterDecorator, formatError) {
  baseReporterDecorator(this);

  // colorize output of BaseReporter functions
  this.USE_COLORS = true;
  this.SPEC_FAILURE = '%s %s FAILED'.red + '\n';
  this.SPEC_SLOW = '%s SLOW %s: %s'.yellow + '\n';
  this.ERROR = '%s ERROR'.red + '\n';
  this.FINISHED_ERROR = ' ERROR'.red;
  this.FINISHED_SUCCESS = ' SUCCESS'.green;
  this.FINISHED_DISCONNECTED = ' DISCONNECTED'.red;
  this.X_FAILED = ' (%d FAILED)'.red;
  this.TOTAL_SUCCESS = 'TOTAL: %d SUCCESS'.green + '\n';
  this.TOTAL_FAILED = 'TOTAL: %d FAILED, %d SUCCESS'.red + '\n';

  this.onRunStart = function(browsers) {
    browsers.forEach(function(browser) {
      // useful properties
      browser.id;
      browser.fullName;
    });
  };

  this.onBrowserComplete = function(browser) {
    // useful properties
    var result = browser.lastResult;
    result.total;
    result.disconnected;
    result.error;
    result.failed;
    result.netTime; // in millieseconds? or microseconds?
  };

  this.onRunComplete = function(browsers, results) {
    // the renderBrowser function is defined in karma/reporters/Base.js
    this.writeCommonMsg(browsers.map(this.renderBrowser).join('\n') + '\n');

    if (browsers.length > 1 && !results.disconnected && !results.error) {
      if (!results.failed) {
        this.write(this.TOTAL_SUCCESS, results.success);
      } else {
        this.write(this.TOTAL_FAILED, results.failed, results.success);
      }
    }

    this.write("\n");
  };

  this.currentSuite = [];
  this.writeSpecMessage = function(status) {
    return (function(browser, result) {
      var suite = result.suite
      var indent = "";
      suite.forEach(
        // beware, this in the context of a foreach loop is not what you expect!
        // To be sure, we bind this explicitly
        (function(value, index) {
          if (index >= this.currentSuite.length || this.currentSuite[index] != value) {
            if (index == 0) {
              this.writeCommonMsg('\n');
            }
            this.writeCommonMsg(indent + value + ':\n');
            this.currentSuite = [];
          }
          indent += "    ";
        }).bind(this)
      );
      this.currentSuite = suite;

      var specName = result.description;
      //TODO: add timing information
      var msg = '  '  + indent + status + " - " + specName, specName

      result.log.forEach(function(log) {
        // TODO: have to find out, what this line exactly does. just copied it from karma's BaseReporter
        msg += formatError(log, '\t');
      });

      this.writeCommonMsg(msg + '\n');

      // other useful properties
      browser.id;
      browser.fullName;
      result.time;
      result.skipped;
      result.success;
    }).bind(this);
  };

  this.specSuccess = this.writeSpecMessage('PASSED '.green);
  this.specSkipped = this.writeSpecMessage('SKIPPED'.gray);
  this.specFailure = this.writeSpecMessage('FAILED '.red);
};

SpecReporter.$inject = ['baseReporterDecorator', 'formatError'];

module.exports = {
  'reporter:spec': ['type', SpecReporter]
};
<|endoftext|>


<commit_before>'use strict';

let os = require('os');
let http = require('http');
let request = require('request');
let debug = require('debug')('open-falcon:index');

function getTrimedHostname() {
    let hostname = os.hostname();
    if (hostname.split('.').length) {
        return hostname.split('.')[0];
    }
    return hostname;
}

/**
 * var Falcon = require('open-falcon');
 * Falcon.init('http://localhost:6060', 'exampleProject');
 *
 * var falcon1 = new Falcon({
 *   tags: 'tagkey=tagvalue',
 * });
 *
 * falcon1
 *   .step(60)
 *   .tag('anotherkey', 'anothervalue')
 *   .gauge('metricName', 100);
 *
 * var falcon2 = new Falcon();
 * falcon2.counter('metricName2', 20);
 *
 * var falcon3 = new Falcon();
 * falcon3
 *   .step(20)
 *   .increment('incrementMetric');
 */

/**
 * options
 *   step: optional, integer, seconds, default 60
 *   counterType: optional, default 'GAUGE'
 *   tags: optional
 *   flush: optional, seconds, automatically flush timeout
 */
function Falcon(options) {
    debug('constructor', options);
    options = options || {};

    this._lock = false;
    this._queue = [];
    this._increment = null;

    // step trigger autoFlush
    this.step(options.step === undefined ? Falcon.DEFAULT_STEP : options.step);
    this.counterType(options.counterType === undefined ?
              Falcon.DEFAULT_COUNTER_TYPE : options.counterType);
    this.tag('project', Falcon.PROJECT);
    this._handler = options.handler || Falcon.DEFAULT_HANDLER;
    if (options.tags) {
        this.tag(options.tags);
    }
}

/**
 * api: Falcon push api
 * options
 *   project: project name, set as project=<project> tag
 */
Falcon.DEFAULT_STEP = 60;
Falcon.DEFAULT_COUNTER_TYPE = 'GAUGE';
Falcon.ENDPOINT = getTrimedHostname();

/**
 * @param {string} api
 * @param {string} project project name
 * @param {Function} handler optional request handler
 */
Falcon.init = function(api, project, handler) {
    debug('init', api, project);
    Falcon.API = api;
    Falcon.PROJECT = project;
    Falcon.DEFAULT_HANDLER = handler || function noop(){};
};

Falcon.prototype.now = function() {
    return Math.floor(Date.now() / 1000);
};

Falcon.prototype.tag = function(key, value) {
    debug('tag', key, value);
    if (this._lock) {
        this.emit('error', new Error('Falcon locked, can\'t alter tag'));
        return this;
    }

    if (!this._tags) {
        this._tags = '';
    } else {
        this._tags = this._tags + ',';
    }
    if (arguments.length === 2) {
        this._tags = this._tags + key + '=' + value;
    } else {
        this._tags = this._tags + key;
    }
    return this;
};

Falcon.prototype.step = function(step) {
    debug('step', step);
    if (this._lock) {
        this.emit('error', new Error('Falcon locked, can\'t alter step'));
        return this;
    }

    this._step = step;
    // autoFlush timeout should change everytime step changes
    this.autoFlush();
    return this;
};

Falcon.prototype.counterType = function(counterType) {
    debug('counterType', counterType);
    if (this._lock) {
        this.emit('error', new Error('Falcon locked, can\'t alter counterType'));
        return this;
    }

    this._counterType = counterType;
    return this;
};

Falcon.prototype.gauge = function(metric, value, options) {
    debug('gauge', metric, value, options);
    options = options || {};
    options.counterType = 'GAUGE';
    this.push(metric, value, options);
    return this;
};

Falcon.prototype.counter = function(metric, value, options) {
    debug('counter', metric, value, options);
    options = options || {};
    options.counterType = 'COUNTER';
    this.push(metric, value, options);
    return this;
};

Falcon.prototype.increment = function(metric, options) {
    debug('increment', metric, options);
    this._lock = true;
    options = options || {};
    options.counterType = 'INCREMENT';
    this.push(metric, 1, options);
    return this;
};

Falcon.prototype.push = function(metric, value, options) {
    options = options || {};
    options.tags = options.tags ? (','+options.tags) : '';

    let endpoint = Falcon.ENDPOINT;
    let timestamp = this.now();
    let step = options.step || this._step;
    let counterType = options.counterType || this._counterType;
    let tags = this._tags + options.tags;

    if (counterType === 'GAUGE' || counterType === 'COUNTER') {
        this._queue.push({
            metric,
            value,
            endpoint,
            timestamp,
            step,
            counterType,
            tags,
        });
    } else if (counterType === 'INCREMENT') {
        // reset fake counterType
        counterType = 'GAUGE';
        if (!this._increment) {
            this._increment = {
                metric,
                value,
                endpoint,
                timestamp,
                step,
                counterType,
                tags,
            };
        } else {
            this._increment.value = this._increment.value + 1;
        }
    }
    this.checkAndFlush();
    return this;
};

Falcon.prototype.autoFlush = function() {
    debug('autoFlush');
    clearTimeout(this._timeout);
    this.checkAndFlush();

    // if step equals to zero, reset it to 1
    let step = this._step || 1;
    let self = this;
    this._timeout = setTimeout(function() {
        self.autoFlush();
    }, step * 1000);
};

Falcon.prototype.checkAndFlush = function() {
    debug('checkAndFlush');
    let timestamp = this.now();
    if (this._increment) {
        if (timestamp - this._increment.timestamp >= this._step) {
            this._queue.push(this._increment);
            this._increment = null;
        }
    }

    if (this._queue.length) {
        if (timestamp - this._queue[0].timestamp >= this._step) {
            this.flush();
        }
    }
};

Falcon.prototype.flush = function() {
    debug('flush', this._queue);
    let queue = this._queue;
    if (!queue.length) {
        return;
    }
    this._queue = [];

    let self = this;
    request.post({
        url: Falcon.API,
        body: JSON.stringify(queue),
    }, this._handler)
        .on('error', this._handler);
};

module.exports = Falcon;
<commit_msg>Send INCREMENT metric if no count available<commit_after>'use strict';

let os = require('os');
let http = require('http');
let request = require('request');
let debug = require('debug')('open-falcon:index');

function getTrimedHostname() {
    let hostname = os.hostname();
    if (hostname.split('.').length) {
        return hostname.split('.')[0];
    }
    return hostname;
}

/**
 * var Falcon = require('open-falcon');
 * Falcon.init('http://localhost:6060', 'exampleProject');
 *
 * var falcon1 = new Falcon({
 *   tags: 'tagkey=tagvalue',
 * });
 *
 * falcon1
 *   .step(60)
 *   .tag('anotherkey', 'anothervalue')
 *   .gauge('metricName', 100);
 *
 * var falcon2 = new Falcon();
 * falcon2.counter('metricName2', 20);
 *
 * var falcon3 = new Falcon();
 * falcon3
 *   .step(20)
 *   .increment('incrementMetric');
 */

/**
 * options
 *   step: optional, integer, seconds, default 60
 *   tags: optional
 */
function Falcon(options) {
    debug('constructor', options);
    options = options || {};

    this._lock = false;
    this._queue = [];
    this._increment = null;

    // step trigger autoFlush
    this.step(options.step === undefined ? Falcon.DEFAULT_STEP : options.step);
    this.tag('project', Falcon.PROJECT);
    this._handler = options.handler || Falcon.DEFAULT_HANDLER;
    if (options.tags) {
        this.tag(options.tags);
    }
}

/**
 * api: Falcon push api
 * options
 *   project: project name, set as project=<project> tag
 */
Falcon.DEFAULT_STEP = 60;
Falcon.DEFAULT_COUNTER_TYPE = 'GAUGE';
Falcon.ENDPOINT = getTrimedHostname();

/**
 * @param {string} api
 * @param {string} project project name
 * @param {Function} handler optional request handler
 */
Falcon.init = function(api, project, handler) {
    debug('init', api, project);
    Falcon.API = api;
    Falcon.PROJECT = project;
    Falcon.DEFAULT_HANDLER = handler || function noop(){};
};

Falcon.prototype.tag = function(key, value) {
    debug('tag', key, value);
    if (this._lock) {
        this.emit('error', new Error('Falcon locked, can\'t alter tag'));
        return this;
    }

    if (!this._tags) {
        this._tags = '';
    } else {
        this._tags = this._tags + ',';
    }
    if (arguments.length === 2) {
        this._tags = this._tags + key + '=' + value;
    } else {
        this._tags = this._tags + key;
    }
    return this;
};

Falcon.prototype.step = function(step) {
    debug('step', step);
    if (this._lock) {
        this.emit('error', new Error('Falcon locked, can\'t alter step'));
        return this;
    }

    this._step = step;
    // autoFlush timeout should change everytime step changes
    this.autoFlush();
    return this;
};

Falcon.prototype.gauge = function(metric, value, options) {
    debug('gauge', metric, value, options);
    options = options || {};
    options.counterType = 'GAUGE';
    this.push(metric, value, options);
    return this;
};

Falcon.prototype.counter = function(metric, value, options) {
    debug('counter', metric, value, options);
    options = options || {};
    options.counterType = 'COUNTER';
    this.push(metric, value, options);
    return this;
};

Falcon.prototype.increment = function(metric, options) {
    debug('increment', metric, options);
    options = options || {};
    options.counterType = 'INCREMENT';
    this.push(metric, 1, options);
    return this;
};

/**
 * @private
 */
Falcon.prototype.now = function() {
    return Math.floor(Date.now() / 1000);
};

/**
 * @private
 */
Falcon.prototype.createItem = function(metric, value, options) {
    options.tags = options.tags ? (','+options.tags) : '';

    let endpoint = Falcon.ENDPOINT;
    let timestamp = this.now();
    let step = options.step || this._step;
    let counterType = options.counterType;
    let tags = this._tags + options.tags;

    if (counterType === 'INCREMENT') {
        // reset fake counterType
        counterType = 'GAUGE';
    }

    return {
        metric,
        value,
        endpoint,
        timestamp,
        step,
        counterType,
        tags,
    };
};

/**
 * @private
 */
Falcon.prototype.push = function(metric, value, options) {
    let counterType = options.counterType || Falcon.DEFAULT_COUNTER_TYPE;
    if (counterType === 'GAUGE' || counterType === 'COUNTER') {
        this._queue.push(this.createItem(metric, value, options));
    } else if (counterType === 'INCREMENT') {
        if (!this._increment) {
            this._increment = this.createItem(metric, value, options);
        } else {
            this._increment.value = this._increment.value + 1;
        }
    }
    this.checkAndFlush();
    return this;
};

/**
 * @private
 */
Falcon.prototype.autoFlush = function() {
    debug('autoFlush');
    clearTimeout(this._timeout);
    this.checkAndFlush();

    // if step equals to zero, reset it to 1
    let step = this._step || 1;
    let self = this;
    this._timeout = setTimeout(function() {
        self.autoFlush();
    }, step * 1000);
};

/**
 * @private
 */
Falcon.prototype.checkAndFlush = function() {
    debug('checkAndFlush');
    let timestamp = this.now();
    if (this._increment) {
        if (timestamp - this._increment.timestamp >= this._step) {
            let increment = this._increment;
            this._queue.push(increment);
            // reset increment rather than delete it
            this._increment = this.createItem(increment.metric, 0, {counterType: 'INCREMENT'});
        }
    }

    if (this._queue.length) {
        if (timestamp - this._queue[0].timestamp >= this._step) {
            this.flush();
        }
    }
};

/**
 * @private
 */
Falcon.prototype.flush = function() {
    debug('flush', this._queue);
    let queue = this._queue;
    if (!queue.length) {
        return;
    }
    this._queue = [];

    let self = this;
    request.post({
        url: Falcon.API,
        body: JSON.stringify(queue),
    }, this._handler)
        .on('error', this._handler);
};

module.exports = Falcon;
<|endoftext|>


<commit_before>var spsave = require('spsave'),
    gutil = require('gulp-util'),
    PluginError = gutil.PluginError,
    path = require("path"),
	through = require("through2");

var PLUGIN_NAME = 'gulp-spsave';

function gulpspsave(options) {
	if (!options) {
		throw new PluginError(PLUGIN_NAME, 'Missing options');
	}

	return through.obj(function (file, enc, cb) {
		if (file.isNull()) {
			cb(null, file);
			return;
		}

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

		if (file.isBuffer()) {
			if(typeof options.flatten !== "boolean"){
				options.flatten = true;
			}
			if (options.flatten){
				options.fileName = path.basename(file.path);
			} else {
				var relative = path.relative(file.base, file.path);
				options.fileName = path.basename(file.path);
				var addFolder = relative.replace(options.fileName, "");
				var destFolder = path.join(options.folder, addFolder).replace(/\\/g, '/');
				options.folder = destFolder;
			}
			options.fileContent = file.contents.toString(enc);
			var self = this;
			spsave(options, function (err, data) {
				if (err) {
					console.log(err);
					cb(new gutil.PluginError(PLUGIN_NAME, err.message));
					return;
				}
				cb(null, file);
			});
		}
	});
}

function randomIntFromInterval(min,max)
{
    return Math.floor(Math.random()*(max-min+1)+min);
}

module.exports = gulpspsave;<commit_msg>Removed redundant method.<commit_after>var spsave = require('spsave'),
    gutil = require('gulp-util'),
    PluginError = gutil.PluginError,
    path = require("path"),
	through = require("through2");

var PLUGIN_NAME = 'gulp-spsave';

function gulpspsave(options) {
	if (!options) {
		throw new PluginError(PLUGIN_NAME, 'Missing options');
	}

	return through.obj(function (file, enc, cb) {
		if (file.isNull()) {
			cb(null, file);
			return;
		}

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

		if (file.isBuffer()) {
			if(typeof options.flatten !== "boolean"){
				options.flatten = true;
			}
			if (options.flatten){
				options.fileName = path.basename(file.path);
			} else {
				var relative = path.relative(file.base, file.path);
				options.fileName = path.basename(file.path);
				var addFolder = relative.replace(options.fileName, "");
				var destFolder = path.join(options.folder, addFolder).replace(/\\/g, '/');
				options.folder = destFolder;
			}
			options.fileContent = file.contents.toString(enc);
			var self = this;
			spsave(options, function (err, data) {
				if (err) {
					console.log(err);
					cb(new gutil.PluginError(PLUGIN_NAME, err.message));
					return;
				}
				cb(null, file);
			});
		}
	});
}

module.exports = gulpspsave;<|endoftext|>


<commit_before>'use strict';

var React = require('react');
var window = require('global/window');
var r = require('r-dom');
var WebGLHeatmap = require('webgl-heatmap');

module.exports = React.createClass({

  displayName: 'ExampleOverlay',

  propTypes: {
    locations: React.PropTypes.array.isRequired,
    latLngAccessor: React.PropTypes.func,
    intensityAccessor: React.PropTypes.func,
    sizeAccessor: React.PropTypes.func
  },

  getDefaultProps: function getDefaultProps() {
    return {
      latLngAccessor: function lagLngAccessor(location) {
        return [location.latitude, location.longitude];
      },
      intensityAccessor: function intensityAccessor(location) {
        return 1 / 10;
      },
      sizeAccessor: function sizeAccessor(location) {
        return 40;
      }
    };
  },

  componentDidMount: function componentDidMount() {
    var canvas = this.getDOMNode();
    this._heatmap = new WebGLHeatmap({
      canvas: canvas,
      intensityToAlpha: true,
      alphaRange: [0, 0.1]
    });
    this._redraw();
  },

  componentWillUnmount: function componentWillUnmount() {
    this._heatmap = null;
  },

  componentDidUpdate: function componentDidUpdate() {
    this._redraw();
  },

  _redraw: function _redraw() {
    var heatmap = this._heatmap;
    var project = this.props.project;
    heatmap.clear();
    this.props.locations.forEach(function each(location) {
      var size = this.props.sizeAccessor(location);
      var intensity = this.props.intensityAccessor(location);
      var pixel = project(this.props.latLngAccessor(location));
      heatmap.addPoint(pixel.x, pixel.y, size, intensity);
    }, this);
    heatmap.adjustSize();
    heatmap.update();
    heatmap.display();
  },

  render: function render() {
    var pixelRatio = window.devicePixelRatio || 1;
    return r.canvas({
      ref: 'overlay',
      width: this.props.width * pixelRatio,
      height: this.props.height * pixelRatio,
      style: {
        width: this.props.width + 'px',
        height: this.props.height + 'px',
        position: 'absolute',
        pointerEvents: 'none',
        left: 0,
        top: 0
      }
    });
  }
});
<commit_msg>Fix a bug with that caused the overlay to not resize in some cases.<commit_after>'use strict';

var React = require('react');
var Immutable = require('immutable');
var window = require('global/window');
var r = require('r-dom');
var WebGLHeatmap = require('webgl-heatmap');

module.exports = React.createClass({

  displayName: 'ExampleOverlay',

  propTypes: {
    locations: React.PropTypes.oneOfType([
      React.PropTypes.array,
      React.PropTypes.instanceOf(Immutable.List)
    ]),
    latLngAccessor: React.PropTypes.func,
    intensityAccessor: React.PropTypes.func,
    sizeAccessor: React.PropTypes.func
  },

  getDefaultProps: function getDefaultProps() {
    return {
      latLngAccessor: function lagLngAccessor(location) {
        return [location.latitude, location.longitude];
      },
      intensityAccessor: function intensityAccessor(location) {
        return 1 / 10;
      },
      sizeAccessor: function sizeAccessor(location) {
        return 40;
      }
    };
  },

  componentDidMount: function componentDidMount() {
    var canvas = this.getDOMNode();
    this._heatmap = new WebGLHeatmap({
      canvas: canvas,
      intensityToAlpha: true,
      alphaRange: [0, 0.1]
    });
    this._redraw();
  },

  componentWillUnmount: function componentWillUnmount() {
    this._heatmap = null;
  },

  componentDidUpdate: function componentDidUpdate() {
    this._redraw();
  },

  _redraw: function _redraw() {
    var heatmap = this._heatmap;
    var project = this.props.project;
    heatmap.clear();
    heatmap.adjustSize();
    this.props.locations.forEach(function each(location) {
      var size = this.props.sizeAccessor(location);
      var intensity = this.props.intensityAccessor(location);
      var pixel = project(this.props.latLngAccessor(location));
      heatmap.addPoint(pixel.x, pixel.y, size, intensity);
    }, this);
    heatmap.update();
    heatmap.display();
  },

  render: function render() {
    var pixelRatio = window.devicePixelRatio || 1;
    return r.canvas({
      ref: 'overlay',
      width: this.props.width * pixelRatio,
      height: this.props.height * pixelRatio,
      style: {
        width: this.props.width + 'px',
        height: this.props.height + 'px',
        position: 'absolute',
        pointerEvents: 'none',
        left: 0,
        top: 0
      }
    });
  }
});
<|endoftext|>


<commit_before>// app start entry:

var
    fs = require('fs'),
    express = require('express'),
    swig = require('swig'),
    _ = require('lodash');

// load config:
var
    config = require('./config'),
    api = require('./api'),
    db = require('./db'),
    constants = require('./constants'),
    utils = require('./controllers/_utils'),
    api_console = require('./api_console');

// init http server:
var app = express();

// set engine to swig:
app.engine('html', swig.renderFile);

// set for production:
if ('production' === app.get('env')) {
    app.enable('trust proxy');
}

// set for development:
if ('development' === app.get('env')) {
    swig.setDefaults({ cache: false });
    app.use('/static', express.static(__dirname + '/static'));
    app.use('/api/', function(req, res, next) {
        setTimeout(function() {
            next();
        }, 250 + Math.floor(Math.random() * 250));
    });
}

app.use(express.cookieParser());

// set upload dir:
var tmp_upload_dir = '/tmp/itranswarp';
if (! fs.existsSync(tmp_upload_dir)) {
    console.log('creating tmp upload dir: ' + tmp_upload_dir);
    fs.mkdirSync(tmp_upload_dir);
}
app.use(express.urlencoded());
app.use(express.json());
app.use(express.multipart({ keepExtensions: true, uploadDir: tmp_upload_dir }));

// set content type: json for api:
app.use('/api/', function(req, res, next) {
    res.type('application/json');
    next();
});

// auto set current user with each request:
app.use(utils.userIdentityParser);

// check user for manage:
app.use('/manage/', function(req, res, next) {
    if (req.user && req.user.role<=constants.ROLE_CONTRIBUTOR) {
        res.manage = function(view, model) {
            var m = model || {};
            m.__user__ = req.user;
            return res.render(view, m);
        };
        return next();
    }
    res.redirect('/auth/');
});

// api error handling:
app.use(app.router);
app.use(function(err, req, res, next) {
    if (err instanceof api.APIError) {
        console.log('send api error to client: ' + err.error);
        return res.send(err);
    }
    console.log('ERROR >>> ' + JSON.stringify(err));
    next(err);
});

// scan all modules:

function loadControllerFilenames() {
    var files = fs.readdirSync(__dirname + '/controllers');
    var re = new RegExp("^[A-Za-z][A-Za-z0-9\\_]*\\.js$");
    var jss = _.filter(files, function(f) {
        return re.test(f);
    });
    return _.map(jss, function(f) {
        return f.substring(0, f.length - 3);
    });
}

function loadControllers() {
    var ctrls = {};
    _.each(loadControllerFilenames(), function(filename) {
        ctrls[filename] = require('./controllers/' + filename);
    });
    return ctrls;
}

var controllers = loadControllers();

_.each(controllers, function(ctrl, fname) {
    _.each(ctrl, function(fn, path) {
        var ss = path.split(' ', 2);
        if (ss.length != 2) {
            console.log('Not a route definition: ' + path);
            return;
        }
        var verb = ss[0];
        var route = ss[1];
        if (verb=='GET') {
            console.log('found: GET ' + route + ' in ' + fname + '.js');
            app.get(route, fn);
        }
        else if (verb=='POST') {
            console.log('found: POST ' + route + ' in ' + fname + '.js');
            app.post(route, fn);
        }
        else {
            console.log('error: Invalid verb: ' + verb);
            return;
        }
        if (route.indexOf('/api/')==0) {
            var docs = fn.toString().match(/.*\/\*\*?([\d\D]*)\*?\*\/.*/);
            if (docs) {
                api_console.process_api_doc(fname, verb, route, docs[1]);
            }
            else {
                console.log('WARNING: no api docs found for api: ' + route);
            }
        }
    });
});

app.get('/error', function(req, res, next) {
    next(new Error('test error.'));
});

app.listen(3000);
console.log('Start app on port 3000...');
<commit_msg>add res.theme<commit_after>// app start entry:

var
    fs = require('fs'),
    express = require('express'),
    swig = require('swig'),
    _ = require('lodash');

// load config:
var
    config = require('./config'),
    api = require('./api'),
    db = require('./db'),
    constants = require('./constants'),
    utils = require('./controllers/_utils'),
    api_console = require('./api_console');

// init http server:
var app = express();

// set engine to swig:
app.engine('html', swig.renderFile);

// set for production:
if ('production' === app.get('env')) {
    app.enable('trust proxy');
}

// set for development:
if ('development' === app.get('env')) {
    swig.setDefaults({ cache: false });
    app.use('/static', express.static(__dirname + '/static'));
    app.use('/api/', function(req, res, next) {
        setTimeout(function() {
            next();
        }, 250 + Math.floor(Math.random() * 250));
    });
}

// set theme functions:

var themePath = 'themes/' + config.theme + '/';

var processThemeView = function(path) {
    return themePath + path;
}

var processThemeModel = function(model, req) {
    var m = model || {};
    m.__theme__ = themePath;
    m.__user__ = req.user;
    m.__time__ = Date.now();
    m.__website__ = {
        name: 'Website Name',
        description: 'website blablabla...',
        custom_header: '',
        custom_footer: ''
    };
    return m;
};

app.use(express.cookieParser());

// set upload dir:
var tmp_upload_dir = '/tmp/itranswarp';
if (! fs.existsSync(tmp_upload_dir)) {
    console.log('creating tmp upload dir: ' + tmp_upload_dir);
    fs.mkdirSync(tmp_upload_dir);
}
app.use(express.urlencoded());
app.use(express.json());
app.use(express.multipart({ keepExtensions: true, uploadDir: tmp_upload_dir }));

// set content type: json for api:
app.use('/api/', function(req, res, next) {
    res.type('application/json');
    next();
});

// auto set current user with each request:
app.use(utils.userIdentityParser);

// check user for manage and theme:
app.use(function(req, res, next) {
    var prefix = req.path.substring(0, 8);
    if (prefix==='/manage/') {
        if (req.user && req.user.role<=constants.ROLE_CONTRIBUTOR) {
            res.manage = function(view, model) {
                var m = model || {};
                m.__user__ = req.user;
                return res.render(view, m);
            };
            return next();
        }
        return res.redirect('/auth/');
    }
    // add theme for other page:
    res.theme = function(view, model) {
        return res.render(processThemeView(view), processThemeModel(model, req));
    }
    next();
});

// api error handling:
app.use(app.router);
app.use(function(err, req, res, next) {
    if (err instanceof api.APIError) {
        console.log('send api error to client: ' + err.error);
        return res.send(err);
    }
    console.log('ERROR >>> ' + JSON.stringify(err));
    next(err);
});

// scan all modules:

function loadControllerFilenames() {
    var files = fs.readdirSync(__dirname + '/controllers');
    var re = new RegExp("^[A-Za-z][A-Za-z0-9\\_]*\\.js$");
    var jss = _.filter(files, function(f) {
        return re.test(f);
    });
    return _.map(jss, function(f) {
        return f.substring(0, f.length - 3);
    });
}

function loadControllers() {
    var ctrls = {};
    _.each(loadControllerFilenames(), function(filename) {
        ctrls[filename] = require('./controllers/' + filename);
    });
    return ctrls;
}

var controllers = loadControllers();

_.each(controllers, function(ctrl, fname) {
    _.each(ctrl, function(fn, path) {
        var ss = path.split(' ', 2);
        if (ss.length != 2) {
            console.log('Not a route definition: ' + path);
            return;
        }
        var verb = ss[0];
        var route = ss[1];
        if (verb=='GET') {
            console.log('found: GET ' + route + ' in ' + fname + '.js');
            app.get(route, fn);
        }
        else if (verb=='POST') {
            console.log('found: POST ' + route + ' in ' + fname + '.js');
            app.post(route, fn);
        }
        else {
            console.log('error: Invalid verb: ' + verb);
            return;
        }
        if (route.indexOf('/api/')==0) {
            var docs = fn.toString().match(/.*\/\*\*?([\d\D]*)\*?\*\/.*/);
            if (docs) {
                api_console.process_api_doc(fname, verb, route, docs[1]);
            }
            else {
                console.log('WARNING: no api docs found for api: ' + route);
            }
        }
    });
});

app.get('/error', function(req, res, next) {
    next(new Error('test error.'));
});

app.listen(3000);
console.log('Start app on port 3000...');
<|endoftext|>


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

const resolve = require('path').resolve;
const Flow = require(__dirname + '/node_modules/flow');
const Store = require(__dirname + '/node_modules/flow-api/lib/store');
const Adapter = require(__dirname + '/lib/adapter');
const Entrypoint = require(__dirname + '/lib/entrypoint');
const entrypoint_name = process.argv[2];
const application_dir = resolve(process.argv[3] || '.');

if (!entrypoint_name) {
    process.stderr.write('Missing entrypoint argument.');
    process.exit(0);
}

// create store instance from config file
const store = Store(require(__dirname + '/config.json'));

// get entrypoint
Entrypoint(store, entrypoint_name, (entrypoint) => {

    entrypoint.base = __dirname;
    entrypoint.module_root = entrypoint.base + '/node_modules/';
    entrypoint.env._modDir = entrypoint.module_root;
    entrypoint.env._appDir = application_dir;

    // init flow and emit first sequence
    const event = Flow(entrypoint.env, Adapter(store, entrypoint))(entrypoint.sequence)
    process.stdin.pipe(event).pipe(process.stdout);
    event.on("error", (err) => {
        err = err.stack ? err.stack : err;
        process.stderr.write(err.toString());
    });
});
<commit_msg>sequences can now have arguments, this makes entrypoint redundant<commit_after>#!/usr/bin/env node

const resolve = require('path').resolve;
const Flow = require(__dirname + '/node_modules/flow');
const Adapter = require(__dirname + '/lib/adapter');
const sequence_id = process.argv[2];
const application_dir = resolve(process.argv[3] || '.');

if (!sequence_id) {
    process.stderr.write('Start sequence missing. Example: flow sequenceId');
    process.exit(0);
}

// TODO get sequence id by name, or just ID?

//entrypoint.env._modDir = entrypoint.module_root;
//entrypoint.env._appDir = application_dir;

// init flow and emit first sequence
const event = Flow(Adapter(application_dir))({
    sequence: sequence_id,
    role: '_:3389dae361af79b04c9c8e7057f60cc6'
});
process.stdin.pipe(event).pipe(process.stdout);
event.on("error", (err) => {
    err = err.stack ? err.stack : err;
    process.stderr.write(err.toString());
});
<|endoftext|>


<commit_before>var map;

window.onload = function() {
    var mm = com.modestmaps;
    var dmap = document.getElementById('map');
    wax.tilejson('https://a.tiles.mapbox.com/v3/examples.map-vyofok3q.jsonp',
        function(tj) {
        map = new com.modestmaps.Map(dmap,
            new wax.mm.connector(tj), null, [
                easey_handlers.DragHandler(),
                easey_handlers.TouchHandler(),
                easey_handlers.MouseWheelHandler(),
                easey_handlers.DoubleClickHandler()
            ]);
        map.setCenterZoom(new com.modestmaps.Location(-10, 50), 3);

        map.addCallback('zoomed', function() {
            // console.log(map.getZoom());
        });

        var pres = document.getElementsByTagName('pre');

        for (var i = 0; i < pres.length; i++) {
          pres[i].onclick = function() {
            eval(this.innerHTML);
          };
        }

        var scrolly = document.getElementById('scrolly');

        var positions = [
          map.locationCoordinate({ lat: 33.5, lon: 65.6 }).zoomTo(6),
          map.locationCoordinate({ lat: 33.1, lon: 44.6 }).zoomTo(6),
          map.locationCoordinate({ lat: 28.7, lon: 69.2 }).zoomTo(6)];

        var ea = easey().map(map).easing('easeInOut');

        function update() {
          var pos = scrolly.scrollTop / 200;

          ea.from(positions[Math.floor(pos)])
            .to(positions[Math.ceil(pos)])
            .t(pos - Math.floor(pos));
        }

        scrolly.addEventListener('scroll', update, false);
    });
};
<commit_msg>Rotate map id<commit_after>var map;

window.onload = function() {
    var mm = com.modestmaps;
    var dmap = document.getElementById('map');
    wax.tilejson('https://a.tiles.mapbox.com/v3/examples.map-i86l3621.jsonp',
        function(tj) {
        map = new com.modestmaps.Map(dmap,
            new wax.mm.connector(tj), null, [
                easey_handlers.DragHandler(),
                easey_handlers.TouchHandler(),
                easey_handlers.MouseWheelHandler(),
                easey_handlers.DoubleClickHandler()
            ]);
        map.setCenterZoom(new com.modestmaps.Location(-10, 50), 3);

        map.addCallback('zoomed', function() {
            // console.log(map.getZoom());
        });

        var pres = document.getElementsByTagName('pre');

        for (var i = 0; i < pres.length; i++) {
          pres[i].onclick = function() {
            eval(this.innerHTML);
          };
        }

        var scrolly = document.getElementById('scrolly');

        var positions = [
          map.locationCoordinate({ lat: 33.5, lon: 65.6 }).zoomTo(6),
          map.locationCoordinate({ lat: 33.1, lon: 44.6 }).zoomTo(6),
          map.locationCoordinate({ lat: 28.7, lon: 69.2 }).zoomTo(6)];

        var ea = easey().map(map).easing('easeInOut');

        function update() {
          var pos = scrolly.scrollTop / 200;

          ea.from(positions[Math.floor(pos)])
            .to(positions[Math.ceil(pos)])
            .t(pos - Math.floor(pos));
        }

        scrolly.addEventListener('scroll', update, false);
    });
};
<|endoftext|>


<commit_before>const { exec } = require('child_process');

let curPid;
let uids = {};

const setCwd = (pid) =>
  exec(`lsof -p ${pid} | grep cwd | awk '$4 == "cwd" {print $9}'`, (err, cwd) => {
    if (err) {
      console.error(err);
    } else {
      cwd = cwd.trim();
      store.dispatch({
        type: 'UPDATE_CWD',
        cwd
      });
    }
  });

exports.middleware = (store) => (next) => (action) => {
  switch (action.type) {
    case 'SESSION_ADD_DATA':
      if (curPid) setCwd(curPid);
      break;
    case 'SESSION_ADD':
      uids[action.uid] = action.pid;
      curPid = action.pid;
      setCwd(curPid);
      break;
    case 'SESSION_SET_ACTIVE':
      curPid = uids[action.uid];
      setCwd(curPid);
      break;
    case 'SESSION_PTY_EXIT':
      delete uids[action.uid];
      break;
    case 'SESSION_USER_EXIT':
      delete uids[action.uid];
      break;
  }
  next(action);
};

exports.reduceUI = (state, action) => {
  switch (action.type) {
    case 'UPDATE_CWD':
      return state.set('cwd', action.cwd);
  }
  return state;
};
<commit_msg>only update cwd if data was received on current session<commit_after>const { exec } = require('child_process');

let curPid;
let uids = {};

const setCwd = (pid) =>
  exec(`lsof -p ${pid} | grep cwd | awk '$4 == "cwd" {print $9}'`, (err, cwd) => {
    if (err) {
      console.error(err);
    } else {
      cwd = cwd.trim();
      store.dispatch({
        type: 'UPDATE_CWD',
        cwd
      });
    }
  });

exports.middleware = (store) => (next) => (action) => {
  switch (action.type) {
    case 'SESSION_PTY_DATA':
      if (curPid && uids[action.uid] === curPid) setCwd(curPid);
      break;
    case 'SESSION_ADD':
      uids[action.uid] = action.pid;
      curPid = action.pid;
      setCwd(curPid);
      break;
    case 'SESSION_SET_ACTIVE':
      curPid = uids[action.uid];
      setCwd(curPid);
      break;
    case 'SESSION_PTY_EXIT':
      delete uids[action.uid];
      break;
    case 'SESSION_USER_EXIT':
      delete uids[action.uid];
      break;
  }
  next(action);
};

exports.reduceUI = (state, action) => {
  switch (action.type) {
    case 'UPDATE_CWD':
      return state.set('cwd', action.cwd);
  }
  return state;
};
<|endoftext|>


<commit_before>'use strict';
const fs = require('fs');
const path = require('path');
const fileType = require('file-type');
const globby = require('globby');
const mkdirp = require('mkdirp');
const pify = require('pify');
const promisePipe = require('promise.pipe');
const replaceExt = require('replace-ext');
const fsP = pify(fs);

const handleFile = (input, output, opts) => fsP.readFile(input).then(data => {
	const dest = output ? path.join(output, path.basename(input)) : null;
	const pipe = opts.plugins.length > 0 ? promisePipe(opts.plugins)(data) : Promise.resolve(data);

	return pipe
		.then(buf => {
			buf = buf.length < data.length ? buf : data;

			const ret = {
				data: buf,
				path: (fileType(buf) && fileType(buf).ext === 'webp') ? replaceExt(dest, '.webp') : dest
			};

			if (!dest) {
				return ret;
			}

			return pify(mkdirp)(path.dirname(dest))
				.then(() => fsP.writeFile(dest, buf))
				.then(() => ret);
		})
		.catch(err => {
			err.message = `Error in file: ${input}\n\n${err.message}`;
			throw err;
		});
});

module.exports = (input, output, opts) => {
	if (!Array.isArray(input)) {
		return Promise.reject(new TypeError('Expected an array'));
	}

	if (typeof output === 'object') {
		opts = output;
		output = null;
	}

	opts = Object.assign({plugins: []}, opts);
	opts.plugins = opts.use || opts.plugins;

	return globby(input, {nodir: true}).then(paths => Promise.all(paths.map(x => handleFile(x, output, opts))));
};

module.exports.buffer = (input, opts) => {
	if (!Buffer.isBuffer(input)) {
		return Promise.reject(new TypeError('Expected a buffer'));
	}

	opts = Object.assign({plugins: []}, opts);
	opts.plugins = opts.use || opts.plugins;

	const pipe = opts.plugins.length > 0 ? promisePipe(opts.plugins)(input) : Promise.resolve(input);

	return pipe.then(buf => buf.length < input.length ? buf : input);
};
<commit_msg>Use `path` and `data` from `ret` when writing files<commit_after>'use strict';
const fs = require('fs');
const path = require('path');
const fileType = require('file-type');
const globby = require('globby');
const mkdirp = require('mkdirp');
const pify = require('pify');
const promisePipe = require('promise.pipe');
const replaceExt = require('replace-ext');
const fsP = pify(fs);

const handleFile = (input, output, opts) => fsP.readFile(input).then(data => {
	const dest = output ? path.join(output, path.basename(input)) : null;
	const pipe = opts.plugins.length > 0 ? promisePipe(opts.plugins)(data) : Promise.resolve(data);

	return pipe
		.then(buf => {
			buf = buf.length < data.length ? buf : data;

			const ret = {
				data: buf,
				path: (fileType(buf) && fileType(buf).ext === 'webp') ? replaceExt(dest, '.webp') : dest
			};

			if (!dest) {
				return ret;
			}

			return pify(mkdirp)(path.dirname(ret.path))
				.then(() => fsP.writeFile(ret.path, ret.data))
				.then(() => ret);
		})
		.catch(err => {
			err.message = `Error in file: ${input}\n\n${err.message}`;
			throw err;
		});
});

module.exports = (input, output, opts) => {
	if (!Array.isArray(input)) {
		return Promise.reject(new TypeError('Expected an array'));
	}

	if (typeof output === 'object') {
		opts = output;
		output = null;
	}

	opts = Object.assign({plugins: []}, opts);
	opts.plugins = opts.use || opts.plugins;

	return globby(input, {nodir: true}).then(paths => Promise.all(paths.map(x => handleFile(x, output, opts))));
};

module.exports.buffer = (input, opts) => {
	if (!Buffer.isBuffer(input)) {
		return Promise.reject(new TypeError('Expected a buffer'));
	}

	opts = Object.assign({plugins: []}, opts);
	opts.plugins = opts.use || opts.plugins;

	const pipe = opts.plugins.length > 0 ? promisePipe(opts.plugins)(input) : Promise.resolve(input);

	return pipe.then(buf => buf.length < input.length ? buf : input);
};
<|endoftext|>


<commit_before>var fs      = require('fs');
var spawn   = require('child_process').spawn;

              require('colors');
var program = require('commander');
var esprima = require('esprima');
var glob    = require('glob');
var _       = require('lodash');
var request = require('request');

var headers = {

  // GitHub API requires the User-Agent Header to be set
  'User-Agent': 'mdlint'
};

var tokenFile = __dirname + '/authtoken.txt';

module.exports = function () {

  // Use Auth Token if present
  if (fs.existsSync(tokenFile)) {
    headers.Authorization = 'token ' + fs.readFileSync(tokenFile, 'utf8');
  }

  program
    .version('0.0.0')
    .option('-s, --silent',  'only report failing lints');

  program
    .command('repo <repo>')
    .description('lints a README from a GitHub repo')
    .action(function (repo) {
      fetchREADME(repo);
    });

  program
    .command('user <username>')
    .description('lints all READMEs from a user\'s GitHub repos')
    .action(function (user) {
      getUserREADMEs(user);
    });

  program
    .command('glob <glob>')
    .description('lints local markdown files that match a file glob')
    .action(function (fileGlob) {
      glob.sync(fileGlob).forEach(function (file) {
        lintMarkdown(fs.readFileSync(file, 'utf8'), file);
      });
    });

  program
    .command('query <query>')
    .option('--page', 'The page of results to return. Defaults to 0.')
    .description('lints READMEs from repos returned by a GitHub query.')
    .action(function (query) {
      request({
        uri: 'https://api.github.com/legacy/repos/search/' +
             query +
             '?language=JavaScript' +
             '&start_page=' + program.page || '0',
        headers: headers
      }, function (error, response, body) {
        if (!error && response.statusCode === 200) {
          JSON.parse(body)
            .repositories
            .forEach(function (repo) {
              fetchREADME(repo.owner + '/' + repo.name);
            });
        } else {
          if (response.headers['x-ratelimit-remaining'] === '0') {
            getAuthToken();
          } else {
            console.log(body);
            console.log(response.headers);
            console.log('Unable to reach the GitHub API :('.red);
          }
          return;
        }
      });
    });

  program
    .command('*')
    .action(function (command) {
      if (command.indexOf('*') !== -1 || command.indexOf('.') !== -1) {
        glob.sync(command).forEach(function (file) {
          lintMarkdown(fs.readFileSync(file, 'utf8'), file);
        });
      } else if (command.indexOf('/') !== -1) {
        fetchREADME(command);
      } else {
        getUserREADMEs(command);
      }
    });

  program
    .parse(process.argv);

  if (!program.args.length) {
    program.help();
  }
};

/**
 * Fetches READMEs from a user's GitHub repos
 * @param  {String} GitHub username
 */
function getUserREADMEs (user) {
  request({
    uri: 'https://api.github.com/users/' + user + '/repos',
    headers: headers
  }, function (error, response, body) {
    var responseBody = JSON.parse(body);

    if (responseBody.message) {
      console.log('Error: the following user was not found: '.red + user.blue);
      return;
    }

    JSON.parse(body)
      .forEach(function (repo) {
        fetchREADME(repo.full_name);
      });
  });
}

/**
 * Fetches a README from GitHub
 * @param  {String} repo URL of repo to fetch
 */
function fetchREADME (repo) {
  request({
    uri: 'https://api.github.com/repos/' + repo + '/readme',
    headers: _.extend(headers, {

      // Get raw README content
      'Accept': 'application/vnd.github.VERSION.raw'
    })
  },
  function (error, response, body) {
    if (!error && response.statusCode === 200) {
      lintMarkdown(body, repo);
    } else {
      if (response.headers['x-ratelimit-remaining'] === '0') {
        getAuthToken();
      } else {
        console.log('README for https://github.com/' + repo.blue + ' not found.'.red);
        return;
      }
    }
  });
}

/**
 * [parseMarkdown description]
 * @param  {String} markdownContent Content of markdown file
 * @return {Array}                  Array of objects with a language and code property
 */
function parseMarkdown (markdownContent) {
  var codeBlocks =  markdownContent

  .split('```')

  .filter(function (codeBlock, index) {

    // Delete the text in between code sections
    if (index % 2 === 0 ||

        // Remove non JavaScript and JSON code blocks
        (codeBlock.trim().toLowerCase().indexOf('js')         !== 0 &&
         codeBlock.trim().toLowerCase().indexOf('javascript') !== 0)) {
      return false;
    }
    return true;
  })

  .map(function (codeBlock) {
    return {
      lang: codeBlock.split('\n')[0].trim().toLowerCase(),
      code: codeBlock.slice(codeBlock.indexOf('\n') + 1)
    };
  });

  return codeBlocks;
}

/**
 * Parses the JavaScript code blocks from the markdown file
 * @param  {String} body Body of markdown file
 * @param  {String} file Filename
 */
function lintMarkdown (body, file) {

  if (!program.silent) {
    console.log(file.blue.bold);
  }
  var codeBlocks = parseMarkdown(body);
  if (_.all(_.compact(codeBlocks), validateCodeBlock)) {
    if (!program.silent) {
      console.log('Markdown passed linting.\n'.green);
    }
  } else {
    console.log('Markdown failed linting.\n'.red);
  }
}

/**
 * Validates that code blocks are valid JavaScript
 * @param  {Object} code A block of code from the markdown file containg the lang and code
 */
function validateCodeBlock (codeBlock) {
  var lang = codeBlock.lang;
  var code = codeBlock.code;

  if (lang === 'json') {
    try {
      JSON.parse(code);
    } catch (e) {
      console.log(e);
      console.log(code);
      return false;
    }
    return true;
  } else if (lang === 'js' || lang === 'javascript') {
    code = preprocessCode(code);
    try {
      esprima.parse(code, { tolerant: true });
    } catch (e) {

      // Get indeces from lineNumber and column
      var line   = e.lineNumber - 1;
      var column = e.column - 1;

      // Highlight error in code
      code = code.split('\n');

      code[line] = code[line].slice(0, column).magenta +
                   code[line][column].red +
                   code[line].slice(column + 1).magenta;

      code = code.join('\n');

      console.log(e);
      console.log(code);
      return false;
    }
    return true;
  }
}

/**
 * Retrieves an auth token so that the user can exceed the uauthenticated rate limit
 */
function getAuthToken () {
  console.log('You have hit the rate limit for unauthenticated requests, please log in to raise your rate limit:\n'.red);

  program.prompt('GitHub Username: ', function (user) {

    console.log('\nAfter entering your password, hit return' + ' twice.\n'.green);
    var authProcess = spawn('curl', [
      '-u',
      user,
      '-d',
      '{"scopes":["repo"],"note":"mdlint"}',
      '-s',
      'https://api.github.com/authorizations'
    ], {
      stdio: [process.stdin, 'pipe', process.stderr]
    });

    authProcess.stdout.setEncoding('utf8');
    authProcess.stdout.on('data', function (data) {
      var response = JSON.parse(data);
      if (response.message) {
        console.log(response.message.red + '\n');
        process.exit();
      } else {
        fs.writeFileSync(tokenFile, response.token);
        console.log('Authenticated :). Now try your lint again. \n'.green);
        process.exit();
      }
    });
  });
}

/**
 * Preprocesses the code block and re-formats it to allow for partial code
 * @param  {String} code A block of code from the markdown file
 * @return {String} Processed code transformed from partial code
 */
function preprocessCode (code) {

  // Remove starting comments
  if (code.indexOf('//') === 0) {
    code = code.slice(code.indexOf('\n'));
  }

  // Starts with an object literal
  if (code.indexOf('{') === 0) {
    code = 'var json = ' + code + ';';

  // Starts with an object property
  } else if (code.indexOf(': {') !== -1 && code.indexOf(': {') < code.indexOf('{')) {
    code = 'var json = {' + code + '};';
  }

  // Starts with an anonymous function
  if (code.indexOf('function') === 0) {
    code = 'var func = ' + code + ';';
  }

  // Contains ...
  return code.replace('...', '');
}<commit_msg>Added repo link, strict mode, and license info<commit_after>/*
 * mdlint
 * https://github.com/ChrisWren/mdlint
 *
 * Copyright (c) 2013 Chris Wren & Contributors
 * Licensed under the MIT license.
 */
'use strict';

var fs      = require('fs');
var spawn   = require('child_process').spawn;

              require('colors');
var program = require('commander');
var esprima = require('esprima');
var glob    = require('glob');
var _       = require('lodash');
var request = require('request');

var headers = {

  // GitHub API requires the User-Agent Header to be set
  'User-Agent': 'mdlint'
};

var tokenFile = __dirname + '/authtoken.txt';

module.exports = function () {

  // Use Auth Token if present
  if (fs.existsSync(tokenFile)) {
    headers.Authorization = 'token ' + fs.readFileSync(tokenFile, 'utf8');
  }

  program
    .version('0.0.0')
    .option('-s, --silent',  'only report failing lints');

  program
    .command('repo <repo>')
    .description('lints a README from a GitHub repo')
    .action(function (repo) {
      fetchREADME(repo);
    });

  program
    .command('user <username>')
    .description('lints all READMEs from a user\'s GitHub repos')
    .action(function (user) {
      getUserREADMEs(user);
    });

  program
    .command('glob <glob>')
    .description('lints local markdown files that match a file glob')
    .action(function (fileGlob) {
      glob.sync(fileGlob).forEach(function (file) {
        lintMarkdown(fs.readFileSync(file, 'utf8'), file);
      });
    });

  program
    .command('query <query>')
    .option('--page', 'The page of results to return. Defaults to 0.')
    .description('lints READMEs from repos returned by a GitHub query.')
    .action(function (query) {
      request({
        uri: 'https://api.github.com/legacy/repos/search/' +
             query +
             '?language=JavaScript' +
             '&start_page=' + program.page || '0',
        headers: headers
      }, function (error, response, body) {
        if (!error && response.statusCode === 200) {
          JSON.parse(body)
            .repositories
            .forEach(function (repo) {
              fetchREADME(repo.owner + '/' + repo.name);
            });
        } else {
          if (response.headers['x-ratelimit-remaining'] === '0') {
            getAuthToken();
          } else {
            console.log(body);
            console.log(response.headers);
            console.log('Unable to reach the GitHub API :('.red);
          }
          return;
        }
      });
    });

  program
    .command('*')
    .action(function (command) {
      if (command.indexOf('*') !== -1 || command.indexOf('.') !== -1) {
        glob.sync(command).forEach(function (file) {
          lintMarkdown(fs.readFileSync(file, 'utf8'), file);
        });
      } else if (command.indexOf('/') !== -1) {
        fetchREADME(command);
      } else {
        getUserREADMEs(command);
      }
    });

  program
    .parse(process.argv);

  if (!program.args.length) {
    program.help();
  }
};

/**
 * Fetches READMEs from a user's GitHub repos
 * @param  {String} GitHub username
 */
function getUserREADMEs (user) {
  request({
    uri: 'https://api.github.com/users/' + user + '/repos',
    headers: headers
  }, function (error, response, body) {
    var responseBody = JSON.parse(body);

    if (responseBody.message) {
      console.log('Error: the following user was not found: '.red + user.blue);
      return;
    }

    JSON.parse(body)
      .forEach(function (repo) {
        fetchREADME(repo.full_name);
      });
  });
}

/**
 * Fetches a README from GitHub
 * @param  {String} repo URL of repo to fetch
 */
function fetchREADME (repo) {
  request({
    uri: 'https://api.github.com/repos/' + repo + '/readme',
    headers: _.extend(headers, {

      // Get raw README content
      'Accept': 'application/vnd.github.VERSION.raw'
    })
  },
  function (error, response, body) {
    if (!error && response.statusCode === 200) {
      lintMarkdown(body, repo);
    } else {
      if (response.headers['x-ratelimit-remaining'] === '0') {
        getAuthToken();
      } else {
        console.log('README for https://github.com/' + repo.blue + ' not found.'.red);
        return;
      }
    }
  });
}

/**
 * [parseMarkdown description]
 * @param  {String} markdownContent Content of markdown file
 * @return {Array}                  Array of objects with a language and code property
 */
function parseMarkdown (markdownContent) {
  var codeBlocks =  markdownContent

  .split('```')

  .filter(function (codeBlock, index) {

    // Delete the text in between code sections
    if (index % 2 === 0 ||

        // Remove non JavaScript and JSON code blocks
        (codeBlock.trim().toLowerCase().indexOf('js')         !== 0 &&
         codeBlock.trim().toLowerCase().indexOf('javascript') !== 0)) {
      return false;
    }
    return true;
  })

  .map(function (codeBlock) {
    return {
      lang: codeBlock.split('\n')[0].trim().toLowerCase(),
      code: codeBlock.slice(codeBlock.indexOf('\n') + 1)
    };
  });

  return codeBlocks;
}

/**
 * Parses the JavaScript code blocks from the markdown file
 * @param  {String} body Body of markdown file
 * @param  {String} file Filename
 */
function lintMarkdown (body, file) {

  if (!program.silent) {
    console.log(file.blue.bold);
  }
  var codeBlocks = parseMarkdown(body);
  if (_.all(_.compact(codeBlocks), validateCodeBlock)) {
    if (!program.silent) {
      console.log('Markdown passed linting.\n'.green);
    }
  } else {
    console.log('Markdown failed linting.\n'.red);
  }
}

/**
 * Validates that code blocks are valid JavaScript
 * @param  {Object} code A block of code from the markdown file containg the lang and code
 */
function validateCodeBlock (codeBlock) {
  var lang = codeBlock.lang;
  var code = codeBlock.code;

  if (lang === 'json') {
    try {
      JSON.parse(code);
    } catch (e) {
      console.log(e);
      console.log(code);
      return false;
    }
    return true;
  } else if (lang === 'js' || lang === 'javascript') {
    code = preprocessCode(code);
    try {
      esprima.parse(code, { tolerant: true });
    } catch (e) {

      // Get indeces from lineNumber and column
      var line   = e.lineNumber - 1;
      var column = e.column - 1;

      // Highlight error in code
      code = code.split('\n');

      code[line] = code[line].slice(0, column).magenta +
                   code[line][column].red +
                   code[line].slice(column + 1).magenta;

      code = code.join('\n');

      console.log(e);
      console.log(code);
      return false;
    }
    return true;
  }
}

/**
 * Retrieves an auth token so that the user can exceed the uauthenticated rate limit
 */
function getAuthToken () {
  console.log('You have hit the rate limit for unauthenticated requests, please log in to raise your rate limit:\n'.red);

  program.prompt('GitHub Username: ', function (user) {

    console.log('\nAfter entering your password, hit return' + ' twice.\n'.green);
    var authProcess = spawn('curl', [
      '-u',
      user,
      '-d',
      '{"scopes":["repo"],"note":"mdlint"}',
      '-s',
      'https://api.github.com/authorizations'
    ], {
      stdio: [process.stdin, 'pipe', process.stderr]
    });

    authProcess.stdout.setEncoding('utf8');
    authProcess.stdout.on('data', function (data) {
      var response = JSON.parse(data);
      if (response.message) {
        console.log(response.message.red + '\n');
        process.exit();
      } else {
        fs.writeFileSync(tokenFile, response.token);
        console.log('Authenticated :). Now try your lint again. \n'.green);
        process.exit();
      }
    });
  });
}

/**
 * Preprocesses the code block and re-formats it to allow for partial code
 * @param  {String} code A block of code from the markdown file
 * @return {String} Processed code transformed from partial code
 */
function preprocessCode (code) {

  // Remove starting comments
  if (code.indexOf('//') === 0) {
    code = code.slice(code.indexOf('\n'));
  }

  // Starts with an object literal
  if (code.indexOf('{') === 0) {
    code = 'var json = ' + code + ';';

  // Starts with an object property
  } else if (code.indexOf(': {') !== -1 && code.indexOf(': {') < code.indexOf('{')) {
    code = 'var json = {' + code + '};';
  }

  // Starts with an anonymous function
  if (code.indexOf('function') === 0) {
    code = 'var func = ' + code + ';';
  }

  // Contains ...
  return code.replace('...', '');
}<|endoftext|>


<commit_before>'use strict';
/*
Copyright 2014 Yahoo! Inc. All rights reserved.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/

/*jslint nomen: true */
var util = require('util'),
    EventEmitter = require('events').EventEmitter,
    through = require('through'),
    stream = require('stream'),
    lastPid = 1;

function MockProcess(runner, signals) {
    var that = this,
        streamer = function () {
            /* istanbul ignore next - fallback */
            return stream.PassThrough ? new stream.PassThrough() : through();
        },
        emitted = false,
        emitter = function () {
            if (!emitted) {
                emitted = true;
                that.emit('close', that.exitCode, that.signal);
            }
        };
    EventEmitter.call(this);
    this.stdin = streamer();
    this.stdout = streamer();
    this.stderr = streamer();

    this.stderr.on('end', emitter);
    this.stderr.on('close', emitter);

    /* istanbul ignore next - polyfill */
    if (!this.stdout.setEncoding) {
        this.stdout.setEncoding = this.stderr.setEncoding = function (encoding) {
            this.encoding = encoding;
        };
    }
    this._runner = runner;
    this.signal = null;
    if(signals){
        this.signals = signals;
    }
}

util.inherits(MockProcess, EventEmitter);

MockProcess.prototype._start = function (command, args, opts) {
    var that = this,
        runner = this._runner;

    this.command = command;
    this.args = args;
    this.opts = opts;
    this.pid = lastPid;
    this.ended = false;
    lastPid += 1;

    if(runner.throws instanceof Error){
        throw runner.throws;
    }
    process.nextTick(function () {
        runner.call(that, function (exitCode) {
            if(!that.ended){
                that.ended = true;
                that.exitCode = exitCode;
                that.emit('exit', exitCode);
                that.stdout.end();
                that.stderr.end();
            }
        });
    });
    return this;
};

MockProcess.prototype.kill = function (signal) {
    var that = this;
    // if the signals object contains this signal and is *truthy*, and it is still running, exit
    if(this.signals[signal]){
        this.signal = signal;
        /* istanbul ignore else - no-op if ended */
        if(!this.ended){
            this.ended = true;
            process.nextTick(function(){
                that.emit('exit',null,signal);
                that.stdout.end();
                that.stderr.end();
            });
        }
    }
};

var ezRunner = function (exitCode, stdout, stderr) {
    var verbose,
        fn = function (cb) {
            if (verbose) {
                console.log('Run:' + this.command + ', with args');
                console.log(this.args);
                console.log('With stdout = ' + stdout);
                console.log('With stderr = ' + stderr);
                console.log('Exit code = ' + exitCode);
            }
            if (stdout) {
                this.stdout.write(stdout);
            }
            if (stderr) {
                this.stderr.write(stderr);
            }
            process.nextTick(function () {
                return cb(exitCode);
            });
        };
    fn.setVerbose = function (v) {
        verbose = !!v;
        return fn;
    };
    return fn;
};

function makeSeq(verbose) {
    var runners = [],
        fn = function (/* command, args, opts */) {
            var runner;
            if (runners.length) {
                if (verbose) {
                    console.log('Running first of ' + runners.length +
                        ' remaining functions');
                }
                runner = runners.shift();
            } else if (verbose) {
                console.log('No runners left, using default');
            }
            return runner;
        };

    fn.add = function (runner) {
        runners.push(runner);
    };
    return fn;
}

function ProcessList(verbose) {
    this.verbose = verbose;
    this.fns = [];
    this.defaultFn = ezRunner(0).setVerbose(verbose);
    this.strategy = null;
    this.calls = [];
}

ProcessList.prototype.setStrategy = function (strategy) {
    this.strategy = strategy;
};

ProcessList.prototype.setSignals = function (sigs) {
    this.signals = sigs;
};

ProcessList.prototype.next = function (command, args, opts) {
    var runner,
        mp;

    if (this.strategy) {
        runner = this.strategy(command, args, opts);
    }
    runner = runner || this.defaultFn;
    mp = new MockProcess(runner,this.signals);
    this.calls.push(mp);
    return mp._start(command, args, opts);
};

ProcessList.prototype.__defineGetter__('sequence', function () {
    if (!this.strategy) {
        this.strategy = makeSeq(this.verbose);
    }
    return this.strategy;
});

module.exports = function (verbose) {
    var pm = new ProcessList(verbose),
        main = function (command, args, opts) {
            return pm.next(command, args, opts);
        };

    main.__defineGetter__('sequence', function () { return pm.sequence; });
    main.__defineGetter__('calls', function () { return pm.calls.slice(); });
    main.setDefault = function (fn) { pm.defaultFn = fn; };
    main.setStrategy = function (s) { pm.setStrategy(s); };
    main.simple = function (exitCode, stdout, stderr) {
        return ezRunner(exitCode, stdout, stderr).setVerbose(verbose);
    };
    main.setSignals = function (sigs) { pm.setSignals(sigs); };

    return main;
};
<commit_msg>Default signal - SIGTERM<commit_after>'use strict';
/*
Copyright 2014 Yahoo! Inc. All rights reserved.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/

/*jslint nomen: true */
var util = require('util'),
    EventEmitter = require('events').EventEmitter,
    through = require('through'),
    stream = require('stream'),
    lastPid = 1;

function MockProcess(runner, signals) {
    var that = this,
        streamer = function () {
            /* istanbul ignore next - fallback */
            return stream.PassThrough ? new stream.PassThrough() : through();
        },
        emitted = false,
        emitter = function () {
            if (!emitted) {
                emitted = true;
                that.emit('close', that.exitCode, that.signal);
            }
        };
    EventEmitter.call(this);
    this.stdin = streamer();
    this.stdout = streamer();
    this.stderr = streamer();

    this.stderr.on('end', emitter);
    this.stderr.on('close', emitter);

    /* istanbul ignore next - polyfill */
    if (!this.stdout.setEncoding) {
        this.stdout.setEncoding = this.stderr.setEncoding = function (encoding) {
            this.encoding = encoding;
        };
    }
    this._runner = runner;
    this.signal = null;
    if(signals){
        this.signals = signals;
    }
}

util.inherits(MockProcess, EventEmitter);

MockProcess.prototype._start = function (command, args, opts) {
    var that = this,
        runner = this._runner;

    this.command = command;
    this.args = args;
    this.opts = opts;
    this.pid = lastPid;
    this.ended = false;
    lastPid += 1;

    if(runner.throws instanceof Error){
        throw runner.throws;
    }
    process.nextTick(function () {
        runner.call(that, function (exitCode) {
            if(!that.ended){
                that.ended = true;
                that.exitCode = exitCode;
                that.emit('exit', exitCode);
                that.stdout.end();
                that.stderr.end();
            }
        });
    });
    return this;
};

MockProcess.prototype.kill = function (signal) {
    signal = signal || 'SIGTERM';
    var that = this;
    // if the signals object contains this signal and is *truthy*, and it is still running, exit
    if(this.signals[signal]){
        this.signal = signal;
        /* istanbul ignore else - no-op if ended */
        if(!this.ended){
            this.ended = true;
            process.nextTick(function(){
                that.emit('exit',null,signal);
                that.stdout.end();
                that.stderr.end();
            });
        }
    }
};

var ezRunner = function (exitCode, stdout, stderr) {
    var verbose,
        fn = function (cb) {
            if (verbose) {
                console.log('Run:' + this.command + ', with args');
                console.log(this.args);
                console.log('With stdout = ' + stdout);
                console.log('With stderr = ' + stderr);
                console.log('Exit code = ' + exitCode);
            }
            if (stdout) {
                this.stdout.write(stdout);
            }
            if (stderr) {
                this.stderr.write(stderr);
            }
            process.nextTick(function () {
                return cb(exitCode);
            });
        };
    fn.setVerbose = function (v) {
        verbose = !!v;
        return fn;
    };
    return fn;
};

function makeSeq(verbose) {
    var runners = [],
        fn = function (/* command, args, opts */) {
            var runner;
            if (runners.length) {
                if (verbose) {
                    console.log('Running first of ' + runners.length +
                        ' remaining functions');
                }
                runner = runners.shift();
            } else if (verbose) {
                console.log('No runners left, using default');
            }
            return runner;
        };

    fn.add = function (runner) {
        runners.push(runner);
    };
    return fn;
}

function ProcessList(verbose) {
    this.verbose = verbose;
    this.fns = [];
    this.defaultFn = ezRunner(0).setVerbose(verbose);
    this.strategy = null;
    this.calls = [];
}

ProcessList.prototype.setStrategy = function (strategy) {
    this.strategy = strategy;
};

ProcessList.prototype.setSignals = function (sigs) {
    this.signals = sigs;
};

ProcessList.prototype.next = function (command, args, opts) {
    var runner,
        mp;

    if (this.strategy) {
        runner = this.strategy(command, args, opts);
    }
    runner = runner || this.defaultFn;
    mp = new MockProcess(runner,this.signals);
    this.calls.push(mp);
    return mp._start(command, args, opts);
};

ProcessList.prototype.__defineGetter__('sequence', function () {
    if (!this.strategy) {
        this.strategy = makeSeq(this.verbose);
    }
    return this.strategy;
});

module.exports = function (verbose) {
    var pm = new ProcessList(verbose),
        main = function (command, args, opts) {
            return pm.next(command, args, opts);
        };

    main.__defineGetter__('sequence', function () { return pm.sequence; });
    main.__defineGetter__('calls', function () { return pm.calls.slice(); });
    main.setDefault = function (fn) { pm.defaultFn = fn; };
    main.setStrategy = function (s) { pm.setStrategy(s); };
    main.simple = function (exitCode, stdout, stderr) {
        return ezRunner(exitCode, stdout, stderr).setVerbose(verbose);
    };
    main.setSignals = function (sigs) { pm.setSignals(sigs); };

    return main;
};
<|endoftext|>