<commit_before>'use strict';

/**
 * Module dependencies.
 */

var http = require('http');
var url = require('url');

var request = require('./request');
var utils = require('./utils');

/**
 * Initialize a new `Shutterstock` v1 client.
 */

function Shutterstock(options) {
  if (!(this instanceof Shutterstock)) {
    return new Shutterstock(options);
  }

  options = options || {};
  options.url = url.parse(options.url || 'http://api.shutterstock.com');

  if (!options.timeout) options.timeout = 30 * 1000;
  if (!options.user) throw new Error('user option required');
  if (!options.access_token && !options.key) {
    throw new Error('key option required');
  }

  this.options = options;
}

/**
 * Check request options for required auth parameters.
 */

Shutterstock.prototype._requireAuth = function(options) {
  if (this.options.access_token) {
    if (!options.auth_user) {
      options.auth_user = this.options.auth_user || this.options.user;
    }
  } else {
    if (!options.auth_token) options.auth_token = this.options.auth_token;
    if (!options.auth_token) throw new Error('auth_token required');
  }

  if (!options.auth_user) throw new Error('auth_user required');
};

/**
 * Execute API requests.
 */

Shutterstock.prototype._request = function(options, callback) {
  // we always send headeres
  if (!options.headers) options.headers = {};

  // api auth
  if (this.options.access_token) {
    options.headers.authorization = 'Bearer ' + this.options.access_token;
  } else {
    options.auth = this.options.user + ':' + this.options.key;
  }

  // url
  options.scheme = this.options.scheme;
  options.hostname = this.options.url.hostname;
  if (this.options.url.port) options.port = this.options.url.port;

  // response format
  options.path += '.json';

  // timeout
  options.timeout = this.options.timeout;

  // request
  request(options, function(err, res) {
    if (err) return callback(err);

    var isHtml, isJson, isText, type;

    if (res.body) {
      type = res.headers['content-type'];

      if (type) {
        isJson = ~type.indexOf('application/json');
        isText = !isJson && ~type.indexOf('text/plain');
        isHtml = !isJson && !isText && ~type.indexOf('html');
      }

      if (isJson || isText || isHtml) {
        res.body = res.body.toString('utf8');
      }

      if (isJson) {
        try {
          res.body = JSON.parse(res.body);
        } catch (err) {
          err.message = 'Invalid JSON: ' + err.message;
          err.res = res;
          return callback(err);
        }
      }
    }

    if (!isJson || res.statusCode >= 400) {
      var error = new Error(http.STATUS_CODES[res.statusCode]);

      error.res = res;

      if (isText) error.message = res.body;

      return callback(error);
    }

    return callback(null, res.body);
  });
};

/**
 * http://api.shutterstock.com/#resources
 */

Shutterstock.prototype.getResources = function(callback) {
  this._request({
    method: 'GET',
    path: '/resources',
  }, callback);
};

/**
 * http://api.shutterstock.com/#testecho
 */

Shutterstock.prototype.echo = function(options, callback) {
  this._request({
    method: 'GET',
    path: '/test/echo',
    query: options,
  }, callback);
};

/**
 * http://api.shutterstock.com/#authcustomer
 */

Shutterstock.prototype.authCustomer = function(options, callback) {
  if (this.options.access_token) {
    return callback(new Error('login not supported with access_token'));
  }

  this._request({
    method: 'POST',
    path: '/auth/customer',
    type: 'form',
    body: utils.pick(options, 'email', 'password', 'username'),
  }, callback);
};

/**
 * http://api.shutterstock.com/#categories
 */

Shutterstock.prototype.getCategories = function(callback) {
  this._request({
    method: 'GET',
    path: '/categories',
  }, callback);
};<commit_msg>Always support 2 parameter signature<commit_after>'use strict';

/**
 * Module dependencies.
 */

var http = require('http');
var url = require('url');

var request = require('./request');
var utils = require('./utils');

/**
 * Initialize a new `Shutterstock` v1 client.
 */

function Shutterstock(options) {
  if (!(this instanceof Shutterstock)) {
    return new Shutterstock(options);
  }

  options = options || {};
  options.url = url.parse(options.url || 'http://api.shutterstock.com');

  if (!options.timeout) options.timeout = 30 * 1000;
  if (!options.user) throw new Error('user option required');
  if (!options.access_token && !options.key) {
    throw new Error('key option required');
  }

  this.options = options;
}

/**
 * Check request options for required auth parameters.
 */

Shutterstock.prototype._requireAuth = function(options) {
  if (this.options.access_token) {
    if (!options.auth_user) {
      options.auth_user = this.options.auth_user || this.options.user;
    }
  } else {
    if (!options.auth_token) options.auth_token = this.options.auth_token;
    if (!options.auth_token) throw new Error('auth_token required');
  }

  if (!options.auth_user) throw new Error('auth_user required');
};

/**
 * Execute API requests.
 */

Shutterstock.prototype._request = function(options, callback) {
  // we always send headeres
  if (!options.headers) options.headers = {};

  // api auth
  if (this.options.access_token) {
    options.headers.authorization = 'Bearer ' + this.options.access_token;
  } else {
    options.auth = this.options.user + ':' + this.options.key;
  }

  // url
  options.scheme = this.options.scheme;
  options.hostname = this.options.url.hostname;
  if (this.options.url.port) options.port = this.options.url.port;

  // response format
  options.path += '.json';

  // timeout
  options.timeout = this.options.timeout;

  // request
  request(options, function(err, res) {
    if (err) return callback(err);

    var isHtml, isJson, isText, type;

    if (res.body) {
      type = res.headers['content-type'];

      if (type) {
        isJson = ~type.indexOf('application/json');
        isText = !isJson && ~type.indexOf('text/plain');
        isHtml = !isJson && !isText && ~type.indexOf('html');
      }

      if (isJson || isText || isHtml) {
        res.body = res.body.toString('utf8');
      }

      if (isJson) {
        try {
          res.body = JSON.parse(res.body);
        } catch (err) {
          err.message = 'Invalid JSON: ' + err.message;
          err.res = res;
          return callback(err);
        }
      }
    }

    if (!isJson || res.statusCode >= 400) {
      var error = new Error(http.STATUS_CODES[res.statusCode]);

      error.res = res;

      if (isText) error.message = res.body;

      return callback(error);
    }

    return callback(null, res.body);
  });
};

/**
 * http://api.shutterstock.com/#resources
 */

Shutterstock.prototype.getResources = function(options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = {};
  }

  this._request({
    method: 'GET',
    path: '/resources',
  }, callback);
};

/**
 * http://api.shutterstock.com/#testecho
 */

Shutterstock.prototype.echo = function(options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = {};
  }

  this._request({
    method: 'GET',
    path: '/test/echo',
    query: options,
  }, callback);
};

/**
 * http://api.shutterstock.com/#authcustomer
 */

Shutterstock.prototype.authCustomer = function(options, callback) {
  if (this.options.access_token) {
    return callback(new Error('login not supported with access_token'));
  }

  this._request({
    method: 'POST',
    path: '/auth/customer',
    type: 'form',
    body: utils.pick(options, 'email', 'password', 'username'),
  }, callback);
};

/**
 * http://api.shutterstock.com/#categories
 */

Shutterstock.prototype.getCategories = function(options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options = {};
  }

  this._request({
    method: 'GET',
    path: '/categories',
  }, callback);
};
{'fraction_non_alphanumeric': 0.16254550018827665, 'fraction_numerical': 0.0028869084975524035, 'mean_word_length': 2.9622078567876677, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5947196', 'n_tokens_mistral': 2545, 'n_tokens_neox': 2491, 'n_words': 537}