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

const async = require('async');
const concat = require('concat-stream');
const debug = require('debug')('cloudant:client');
const EventRelay = require('./eventrelay.js');
const PassThroughDuplex = require('./passthroughduplex.js');
const pkg = require('../package.json');
const utils = require('./clientutils.js');

const DEFAULTS = {
  maxAttempt: 3
};

/**
 * Create a Cloudant client for managing requests.
 *
 * @param {Object} cfg - Request client configuration.
 */
class CloudantClient {
  constructor(cfg) {
    var self = this;

    cfg = cfg || {};
    self._cfg = Object.assign({}, DEFAULTS, cfg);

    var client;
    self._plugins = [];
    self._pluginIds = [];
    self.useLegacyPlugin = false;

    // Build plugin array.
    var plugins = [];

    if (self._cfg.creds && self._cfg.creds.iamApiKey) {
      // => Found IAM API key in VCAP - Add 'iamauth' plugin.
      plugins = [ { iamauth: { iamApiKey: self._cfg.creds.iamApiKey } } ];
    } else if (typeof this._cfg.plugins === 'undefined') {
      // => No plugins specified - Add 'cookieauth' plugin.
      plugins = [ 'cookieauth' ];
    }

    // Add user specified plugins.
    if (typeof this._cfg.plugins !== 'undefined') {
      [].concat(self._cfg.plugins).forEach(function(plugin) {
        if (typeof plugin !== 'function' || plugin.pluginVersion >= 2) {
          plugins.push(plugin);
        } else if (self.useLegacyPlugin) {
          throw new Error('Using multiple legacy plugins is not permitted');
        } else {
          self.useLegacyPlugin = true;
          client = plugin; // use legacy plugin as client
        }
      });
    }

    // initialize the internal client
    self._initClient(client);

    // add plugins
    self._addPlugins(plugins);
  }

  _addPlugins(plugins) {
    var self = this;

    if (!Array.isArray(plugins)) {
      plugins = [ plugins ];
    }

    plugins.forEach(function(plugin) {
      var cfg, Plugin;

      switch (typeof plugin) {
        // 1). Custom plugin
        case 'function':
          debug(`Found custom plugin: '${plugin.id}'`);
          Plugin = plugin;
          cfg = {};
          break;

        // 2). Plugin (with configuration): { 'pluginName': { 'configKey1': 'configValue1', ... } }
        case 'object':
          if (Array.isArray(plugin) || Object.keys(plugin).length !== 1) {
            throw new Error(`Invalid plugin configuration: '${plugin}'`);
          }

          var pluginName = Object.keys(plugin)[0];

          try {
            Plugin = require('../plugins/' + pluginName);
          } catch (e) {
            throw new Error(`Failed to load plugin - ${e.message}`);
          }

          cfg = plugin[pluginName];
          if (typeof cfg !== 'object' || Array.isArray(cfg)) {
            throw new Error(`Invalid plugin configuration: '${plugin}'`);
          }
          break;

        // 3). Plugin (no configuration): 'pluginName'
        case 'string':
          if (plugin === 'base' || plugin === 'default') {
            return; // noop
          }

          try {
            Plugin = require('../plugins/' + plugin);
          } catch (e) {
            throw new Error(`Failed to load plugin - ${e.message}`);
          }

          cfg = {};
          break;

        // 4). Noop
        case 'undefined':
          return;
        default:
          throw new Error(`Invalid plugin configuration: '${plugin}'`);
      }

      if (self._pluginIds.indexOf(Plugin.id) !== -1) {
        debug(`Not adding duplicate plugin: '${Plugin.id}'`);
      } else {
        debug(`Adding plugin: '${Plugin.id}'`);
        self._plugins.push(<commit_msg>Make `promises` plugin a noop<commit_after>// Copyright © 2017, 2018 IBM Corp. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
'use strict';

const async = require('async');
const concat = require('concat-stream');
const debug = require('debug')('cloudant:client');
const EventRelay = require('./eventrelay.js');
const PassThroughDuplex = require('./passthroughduplex.js');
const pkg = require('../package.json');
const utils = require('./clientutils.js');

const DEFAULTS = {
  maxAttempt: 3
};

/**
 * Create a Cloudant client for managing requests.
 *
 * @param {Object} cfg - Request client configuration.
 */
class CloudantClient {
  constructor(cfg) {
    var self = this;

    cfg = cfg || {};
    self._cfg = Object.assign({}, DEFAULTS, cfg);

    var client;
    self._plugins = [];
    self._pluginIds = [];
    self.useLegacyPlugin = false;

    // Build plugin array.
    var plugins = [];

    if (self._cfg.creds && self._cfg.creds.iamApiKey) {
      // => Found IAM API key in VCAP - Add 'iamauth' plugin.
      plugins = [ { iamauth: { iamApiKey: self._cfg.creds.iamApiKey } } ];
    } else if (typeof this._cfg.plugins === 'undefined') {
      // => No plugins specified - Add 'cookieauth' plugin.
      plugins = [ 'cookieauth' ];
    }

    // Add user specified plugins.
    if (typeof this._cfg.plugins !== 'undefined') {
      [].concat(self._cfg.plugins).forEach(function(plugin) {
        if (typeof plugin !== 'function' || plugin.pluginVersion >= 2) {
          plugins.push(plugin);
        } else if (self.useLegacyPlugin) {
          throw new Error('Using multiple legacy plugins is not permitted');
        } else {
          self.useLegacyPlugin = true;
          client = plugin; // use legacy plugin as client
        }
      });
    }

    // initialize the internal client
    self._initClient(client);

    // add plugins
    self._addPlugins(plugins);
  }

  _addPlugins(plugins) {
    var self = this;

    if (!Array.isArray(plugins)) {
      plugins = [ plugins ];
    }

    plugins.forEach(function(plugin) {
      var cfg, Plugin;

      switch (typeof plugin) {
        // 1). Custom plugin
        case 'function':
          debug(`Found custom plugin: '${plugin.id}'`);
          Plugin = plugin;
          cfg = {};
          break;

        // 2). Plugin (with configuration): { 'pluginName': { 'configKey1': 'configValue1', ... } }
        case 'object':
          if (Array.isArray(plugin) || Object.keys(plugin).length !== 1) {
            throw new Error(`Invalid plugin configuration: '${plugin}'`);
          }

          var pluginName = Object.keys(plugin)[0];

          try {
            Plugin = require('../plugins/' + pluginName);
          } catch (e) {
            throw new Error(`Failed to load plugin - ${e.message}`);
          }

          cfg = plugin[pluginName];
          if (typeof cfg !== 'object' || Array.isArray(cfg)) {
            throw new Error(`Invalid plugin configuration: '${plugin}'`);
          }
          break;

        // 3). Plugin (no configuration): 'pluginName'
        case 'string':
          if (plugin === 'base' || plugin === 'default' || plugin === 'promises') {
            return; // noop
          }

          try {
            Plugin = require('../plugins/' + plugin);
          } catch (e) {
            throw new Error(`Failed to load plugin - ${e.message}`);
          }

          cfg = {};
          break;

        // 4). Noop
        case 'undefined':
          return;
        default:
          throw new Error(`Invalid plugin configuration: '${plugin}'`);
      }

      if (self._pluginIds.indexOf(Plugin.id) !== -1) {
        debug(`Not adding duplicate plugin: '${Plugin.id}'`);
      } else {
        debug(`Adding plugin: '${Plugin.id}'`);
        self._plugins.push(
{'fraction_non_alphanumeric': 0.1440214227500291, 'fraction_numerical': 0.00535568750727675, 'mean_word_length': 2.2136176580621023, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '5579922', 'n_tokens_mistral': 2418, 'n_tokens_neox': 2350, 'n_words': 719}