<commit_before>var EventEmitter = require('events').EventEmitter;
var Promise = require("bluebird");
var request = require("request");
var stream = require('stream');
var https = require('https');
var http = require('http');
var util = require('util');
var mime = require('mime');
var path = require('path');
var URL = require('url');
var fs = require('fs');

var requestPromise = Promise.promisify(request);

/**
 * NodeJS class for Telegram Bot API. Support for WebHooks and long polling. Emits `message` when
 * message arrives.
 *
 * @class TelegramBot
 * @constructor
 * @param {String} token Bot Token
 * @param {Object} [options]
 * @param {Boolean|Object} [options.polling=false] Set true to enable polling
 * @param {String|Number} [options.polling.timeout=4] Polling time
 * @param {Boolean|Object} [options.webHook=false] Set true to enable WebHook
 * @param {String} [options.webHook.key] PEM private key to webHook server
 * @param {String} [options.webHook.cert] PEM certificate key to webHook server
 * @see https://core.telegram.org/bots/api
 */
var TelegramBot = function (token, options) {
  options = options || {};
  this.token = token;
  this.offset = 0;
  this._webServer = null;

  if (options.polling) {
    // By default polling for 4 seconds
    var timeout = options.polling.timeout || 4;
    this._polling(timeout);
  }

  if (options.webHook) {
    var port = options.webHook.port || 8443;
    var key = options.webHook.key;
    var cert = options.webHook.cert;
    this._configureWebHook(port, key, cert);
  }
};

util.inherits(TelegramBot, EventEmitter);

TelegramBot.prototype._configureWebHook = function (port, key, cert) {
  var protocol = 'HTTP';
  var self = this;

  if (key && cert) { // HTTPS Server
    protocol = 'HTTPS';
    var options = {
      key: fs.readFileSync(key),
      cert: fs.readFileSync(cert)
    };
    this._webServer = https.createServer(options, function (req, res) {
       self._requestListener.call(self, req, res);
    });
  } else { // HTTP Server
    this._webServer = http.createServer(function (req, res) {
      self._requestListener.call(self, req, res);
    });
  }

  this._webServer.listen(port, function () {
    console.log(protocol+" WebHook listening on:", port);
  });
};

TelegramBot.prototype._requestListener = function (req, res) {
  var self = this;
  if (req.url == '/bot' && req.method == 'POST') {
    var fullBody = '';
    req.on('data', function (chunk) {
      fullBody += chunk.toString();
    });
    req.on('end', function () {
      try {
        var data = JSON.parse(fullBody);
        self.emit('message', data);
      } catch (error) {
        console.error(error);
      }
      res.end('OK\n');
    });
  } else {
    res.end('OK\n');
  }
};

TelegramBot.prototype._processUpdates = function (updates) {
  for (var i = 0; i < updates.length; i++) {
    if (updates[i].message) {
      this.emit('message', updates[i].message);
    }
  }
};

TelegramBot.prototype._polling = function (timeout) {
  var self = this;
  this.getUpdates(timeout).then(function (data) {
    self._processUpdates(data);
    self._polling(timeout);
  });
};

TelegramBot.prototype._request = function (path, options) {
  if (!this.token) {
    throw new Error('Telegram Bot Token not provided!');
  }
  options = options || {};
  options.url = URL.format({
    protocol: 'https',
    host: 'api.telegram.org',
    pathname: '/bot'+this.token+'/'+path
  });

  return requestPromise(options)
    .then(function (resp) {
      if (resp[0].statusCode != 200) {
        throw new Error(resp[0].statusCode+' '+resp[0].body);
      }
      var data = JSON.parse(resp[0].body);
      if (data.ok) {
        return data.result;
      } else {
        throw new Error(data.error_code+' '+data.description);
      }
    });
};

/**
 * Returns basic information about the bot in form of a `User` object.
 * @return {Promise}
 */
TelegramBot.prototype.getMe = function () {
  var path = 'getMe';
  return this._request(path);
};

/**
 * Specify a url to receive incoming updates via an outgoing webHook.
 * @param {String} url URL
 */
TelegramBot.prototype.setWebHook = function (url) {
  var path = 'setWebHook';
  var qs = {url: url};
  return this._request(path, {method: 'POST'})
    .then(function (resp) {
      if (!resp) {
        throw new Error(resp);
      }
    });
};

/**
 * Use this method to receive incoming updates using long polling
 * @param  {Number|String} [timeout] Timeout in seconds for long polling.
 * @param  {Number|String} [limit] Limits the number of updates to be retrieved.
 * @param  {Number|String} [offset] Identifier of the first update to be returned.
 * @return {Promise} Updates
 * @see https://core.telegram.org/bots/api#getupdates
 */
TelegramBot.prototype.getUpdates = function (timeout, limit, offset) {
  var self = this;
  var query = {
    offset: offset || this.offset+1,
    limit: limit,
    timeout: timeout
  };

  return this._request('getUpdates', {qs: query})
    .then(function (result) {
      var last = result[result.length-1];
      if (last) {
        self.offset = last.update_id;
      }
      return result;
    });
};

/**
 * Send text message.
 * @param  {Number|String} chatId Unique identifier for the message recipient
 * @param  {Sting} text Text of the message to be sent
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendmessage
 */
TelegramBot.prototype.sendMessage = function (chatId, text, options) {
  var query = options || {};
  query.chat_id = chatId;
  query.text = text;
  return this._request('sendMessage', {qs: query});
};

/**
 * Forward messages of any kind.
 * @param  {Number|String} chatId     Unique identifier for the message recipient
 * @param  {Number|String} fromChatId Unique identifier for the chat where the
 * original message was sent
 * @param  {Number|String} messageId  Unique message identifier
 * @return {Promise}
 */
TelegramBot.prototype.forwardMessage = function (chatId, fromChatId, messageId) {
  var query = {
    chat_id: chatId,
    from_chat_id: fromChatId,
    message_id: messageId
  };
  return this._request('forwardMessage', {qs: query});
};

TelegramBot.prototype._formatSendData = function (type, data) {
  var formData;
  var fileName;
  var fileId;
  if (data instanceof stream.Stream) {
    fileName = path.basename(data.path);
    formData = {};
    formData[type] = {
      value: data,
      options: {
        filename: fileName,
        contentType: mime.lookup(fileName)
      }
    };
  } else if (fs.existsSync(data)) {
    fileName = path.basename(data);
    formData = {};
    formData[type] = {
      value: fs.createReadStream(data),
      options: {
        filename: fileName,
        contentType: mime.lookup(fileName)
      }
    };
  } else {
    fileId = data;
  }
  return [formData, fileId];
};

/**
 * Send photo
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String|stream.Stream} photo A file path or a Stream. Can
 * also be a `file_id` previously uploaded
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendphoto
 */
TelegramBot.prototype.sendPhoto = function (chatId, photo, options) {
  var opts = {
    qs: options || {}
  };
  opts.qs.chat_id = chatId;
  var content = this._formatSendData('photo', photo);
  opts.formData = content[0];
  opts.qs.photo = content[1];
  return this._request('sendPhoto', opts);
};

/**
 * Send audio
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String|stream.Stream} audio A file path or a Stream. Can
 * also be a `file_id` previously uploaded.
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendaudio
 */
TelegramBot.prototype.sendAudio = function (chatId, audio, options) {
  var opts = {
    qs: options || {}
  };
  opts.qs.chat_id = chatId;
  var content = this._formatSendData('audio', audio);
  opts.formData = content[0];
  opts.qs.audio = content[1];
  return this._request('sendAudio', opts);
};

module.exports = TelegramBot;
<commit_msg>Query strings on webHook<commit_after>var EventEmitter = require('events').EventEmitter;
var Promise = require("bluebird");
var request = require("request");
var stream = require('stream');
var https = require('https');
var http = require('http');
var util = require('util');
var mime = require('mime');
var path = require('path');
var URL = require('url');
var fs = require('fs');

var requestPromise = Promise.promisify(request);

/**
 * NodeJS class for Telegram Bot API. Support for WebHooks and long polling. Emits `message` when
 * message arrives.
 *
 * @class TelegramBot
 * @constructor
 * @param {String} token Bot Token
 * @param {Object} [options]
 * @param {Boolean|Object} [options.polling=false] Set true to enable polling
 * @param {String|Number} [options.polling.timeout=4] Polling time
 * @param {Boolean|Object} [options.webHook=false] Set true to enable WebHook
 * @param {String} [options.webHook.key] PEM private key to webHook server
 * @param {String} [options.webHook.cert] PEM certificate key to webHook server
 * @see https://core.telegram.org/bots/api
 */
var TelegramBot = function (token, options) {
  options = options || {};
  this.token = token;
  this.offset = 0;
  this._webServer = null;

  if (options.polling) {
    // By default polling for 4 seconds
    var timeout = options.polling.timeout || 4;
    this._polling(timeout);
  }

  if (options.webHook) {
    var port = options.webHook.port || 8443;
    var key = options.webHook.key;
    var cert = options.webHook.cert;
    this._configureWebHook(port, key, cert);
  }
};

util.inherits(TelegramBot, EventEmitter);

TelegramBot.prototype._configureWebHook = function (port, key, cert) {
  var protocol = 'HTTP';
  var self = this;

  if (key && cert) { // HTTPS Server
    protocol = 'HTTPS';
    var options = {
      key: fs.readFileSync(key),
      cert: fs.readFileSync(cert)
    };
    this._webServer = https.createServer(options, function (req, res) {
       self._requestListener.call(self, req, res);
    });
  } else { // HTTP Server
    this._webServer = http.createServer(function (req, res) {
      self._requestListener.call(self, req, res);
    });
  }

  this._webServer.listen(port, function () {
    console.log(protocol+" WebHook listening on:", port);
  });
};

TelegramBot.prototype._requestListener = function (req, res) {
  var self = this;
  if (req.url == '/bot' && req.method == 'POST') {
    var fullBody = '';
    req.on('data', function (chunk) {
      fullBody += chunk.toString();
    });
    req.on('end', function () {
      try {
        var data = JSON.parse(fullBody);
        self.emit('message', data);
      } catch (error) {
        console.error(error);
      }
      res.end('OK\n');
    });
  } else {
    res.end('OK\n');
  }
};

TelegramBot.prototype._processUpdates = function (updates) {
  for (var i = 0; i < updates.length; i++) {
    if (updates[i].message) {
      this.emit('message', updates[i].message);
    }
  }
};

TelegramBot.prototype._polling = function (timeout) {
  var self = this;
  this.getUpdates(timeout).then(function (data) {
    self._processUpdates(data);
    self._polling(timeout);
  });
};

TelegramBot.prototype._request = function (path, options) {
  if (!this.token) {
    throw new Error('Telegram Bot Token not provided!');
  }
  options = options || {};
  options.url = URL.format({
    protocol: 'https',
    host: 'api.telegram.org',
    pathname: '/bot'+this.token+'/'+path
  });

  return requestPromise(options)
    .then(function (resp) {
      if (resp[0].statusCode != 200) {
        throw new Error(resp[0].statusCode+' '+resp[0].body);
      }
      var data = JSON.parse(resp[0].body);
      if (data.ok) {
        return data.result;
      } else {
        throw new Error(data.error_code+' '+data.description);
      }
    });
};

/**
 * Returns basic information about the bot in form of a `User` object.
 * @return {Promise}
 */
TelegramBot.prototype.getMe = function () {
  var path = 'getMe';
  return this._request(path);
};

/**
 * Specify a url to receive incoming updates via an outgoing webHook.
 * @param {String} url URL
 */
TelegramBot.prototype.setWebHook = function (url) {
  var path = 'setWebHook';
  var qs = {url: url};
  return this._request(path, {method: 'POST', qs: qs})
    .then(function (resp) {
      if (!resp) {
        throw new Error(resp);
      }
    });
};

/**
 * Use this method to receive incoming updates using long polling
 * @param  {Number|String} [timeout] Timeout in seconds for long polling.
 * @param  {Number|String} [limit] Limits the number of updates to be retrieved.
 * @param  {Number|String} [offset] Identifier of the first update to be returned.
 * @return {Promise} Updates
 * @see https://core.telegram.org/bots/api#getupdates
 */
TelegramBot.prototype.getUpdates = function (timeout, limit, offset) {
  var self = this;
  var query = {
    offset: offset || this.offset+1,
    limit: limit,
    timeout: timeout
  };

  return this._request('getUpdates', {qs: query})
    .then(function (result) {
      var last = result[result.length-1];
      if (last) {
        self.offset = last.update_id;
      }
      return result;
    });
};

/**
 * Send text message.
 * @param  {Number|String} chatId Unique identifier for the message recipient
 * @param  {Sting} text Text of the message to be sent
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendmessage
 */
TelegramBot.prototype.sendMessage = function (chatId, text, options) {
  var query = options || {};
  query.chat_id = chatId;
  query.text = text;
  return this._request('sendMessage', {qs: query});
};

/**
 * Forward messages of any kind.
 * @param  {Number|String} chatId     Unique identifier for the message recipient
 * @param  {Number|String} fromChatId Unique identifier for the chat where the
 * original message was sent
 * @param  {Number|String} messageId  Unique message identifier
 * @return {Promise}
 */
TelegramBot.prototype.forwardMessage = function (chatId, fromChatId, messageId) {
  var query = {
    chat_id: chatId,
    from_chat_id: fromChatId,
    message_id: messageId
  };
  return this._request('forwardMessage', {qs: query});
};

TelegramBot.prototype._formatSendData = function (type, data) {
  var formData;
  var fileName;
  var fileId;
  if (data instanceof stream.Stream) {
    fileName = path.basename(data.path);
    formData = {};
    formData[type] = {
      value: data,
      options: {
        filename: fileName,
        contentType: mime.lookup(fileName)
      }
    };
  } else if (fs.existsSync(data)) {
    fileName = path.basename(data);
    formData = {};
    formData[type] = {
      value: fs.createReadStream(data),
      options: {
        filename: fileName,
        contentType: mime.lookup(fileName)
      }
    };
  } else {
    fileId = data;
  }
  return [formData, fileId];
};

/**
 * Send photo
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String|stream.Stream} photo A file path or a Stream. Can
 * also be a `file_id` previously uploaded
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendphoto
 */
TelegramBot.prototype.sendPhoto = function (chatId, photo, options) {
  var opts = {
    qs: options || {}
  };
  opts.qs.chat_id = chatId;
  var content = this._formatSendData('photo', photo);
  opts.formData = content[0];
  opts.qs.photo = content[1];
  return this._request('sendPhoto', opts);
};

/**
 * Send audio
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String|stream.Stream} audio A file path or a Stream. Can
 * also be a `file_id` previously uploaded.
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendaudio
 */
TelegramBot.prototype.sendAudio = function (chatId, audio, options) {
  var opts = {
    qs: options || {}
  };
  opts.qs.chat_id = chatId;
  var content = this._formatSendData('audio', audio);
  opts.formData = content[0];
  opts.qs.audio = content[1];
  return this._request('sendAudio', opts);
};

module.exports = TelegramBot;
<|endoftext|>


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

'use strict';

var program = require('commander');
var request = require('request');
var URL = require('url');
var languages = require('./languages');

var defaultSource = process.env.JA_GTC_SOURCE
var defaultTarget = process.env.JA_GTC_TARGET
if (defaultSource === undefined) defaultSource = 'en'
if (defaultTarget === undefined) defaultTarget = 'es'

/* Supported languages: https://cloud.google.com/translate/v2/translate-reference#supported_languages */

/* This function creates the URL to get the translation from Google's server
(source: https://ctrlq.org/code/19909-google-translate-api) */
function createTranslatorURL(sourceLang, targetLang, sourceText) {
  return URL.format({
    protocol: 'https:',
    hostname: 'translate.googleapis.com',
    pathname: '/translate_a/single',
    query: {
      client: 'gtx',
      ie: 'UTF-8',
      oe: 'UTF-8',
      sl: sourceLang,
      tl: targetLang,
      dt: 't',
      // dj: 1, // For more detailed JSON response
      q: sourceText,
    }
  });
}

/* Commander configuration */
program
  .version('0.0.1')
  .usage('[options] <text ...>')
  .option('-a, --auto', 'Auto-detect source language')
  /* TODO: Create defaults and let users change them [auto, source, target] */
  .option('-d, --details', 'View details')
  .option('-l, --list', 'List all available languages')
  .option('-s, --source [language]', 'Source language [en]', new RegExp(languages.getLanguagesCodesRegex(), 'i'), defaultSource)
  .option('-t, --target [language]', 'Target language [es]', new RegExp(languages.getLanguagesCodesRegex(), 'i'), defaultTarget)
  .on('--help', function () {
    console.log('  Examples:\n');
    console.log("     $ translate 'I want to translate this text'");
    console.log("     $ translate -s es -t en 'Quiero traducir este texto'");
    console.log("     $ translate -s en -t es I want to translate this text");
    console.log("     $ translate -a 'Au revoir' -d");
  })
  .parse(process.argv);

/* This option shows all languages (code and name) */
if (program.list) {
  console.log(languages.getLanguagesList());
  process.exit(0);
}

var sourceText = '';

var runTranslation = function() {
  var sourceLang = (program.auto) ? 'auto' : program.source;
  var targetLang = program.target;

  var targetURL = createTranslatorURL(sourceLang, targetLang, sourceText);

  /* Performing the request */
  request(targetURL, function(error, response, body) {
      if (!error && response.statusCode == 200) {
        /* Outdated: JSON.parse() doesn't work (empty values in array)
        Retrieved results from Google's server:
        [[["Hola Mundo","Hello World",,,1]],,"en"]
        Parsed results (with language name):
        { targetText: 'Hola Mundo',
          sourceText: 'Hello World',
          isReliable: 1,
          sourceLang: { code: 'en', language: 'English' },
          targetLang: { code: 'es', language: 'Spanish' }
        } */
        /* JSON.parse works but we delete null fields */
        var Intermed = body.replace(/,null{1,}/g, '');
        var Values = JSON.parse(Intermed);
        var Sentences = Values[0];
        var results = {};
        var text = '';
        for (var i = 0; i < Sentences.length; i++) {
          var res = {
          targetText : Sentences[i][0],
          sourceText : Sentences[i][1],
          isReliable : Sentences[i][2],
          sourceLang : languages.getLanguage(Values[1]),
          targetLang : languages.getLanguage(targetLang)
          };
          results["sentence_"+String(i)] = res;
          text += res.targetText;
        }
        /* TODO: Check confidence when auto-detection is enabled to know if the translation is accurate. */
        if (program.auto) {
          results.confidence = Values[2];
        }
        /* Finally: Printing results */
        var textToPrint;
        if (program.details) {
          textToPrint = '[' + results.sentence_0.sourceLang.name + ' -> ' + results.sentence_0.targetLang.name  + ']\n' + text;
        } else {
          textToPrint = text;
        }
        console.log(textToPrint);
        process.exit(0);

      } else {
        /* Something went wrong */
        console.log('⚠  Cannot translate now, an error occurred 🙁');
        process.exit(1);
      }
    }
  );
};

/* Let's translate! */
if (program.args.length === 0) {
  // console.log('❗ Cannot translate an empty text❗');
  // process.exit(1);
  process.stdin.resume();
  process.stdin.on('data', function(buf) { sourceText += buf.toString(); });
  process.stdin.on('end', function() {
    runTranslation();
});
} else {
  /* I prefer typing 'All the text inside simple quotes' but it's possible to use separated words */
  sourceText = (program.args.length > 1)  ? program.args.join(' ') : program.args[0];
  runTranslation();
}
<commit_msg>Updated version.<commit_after>#!/usr/bin/env node

'use strict';

var program = require('commander');
var request = require('request');
var URL = require('url');
var languages = require('./languages');

var defaultSource = process.env.JA_GTC_SOURCE
var defaultTarget = process.env.JA_GTC_TARGET
if (defaultSource === undefined) defaultSource = 'en'
if (defaultTarget === undefined) defaultTarget = 'es'

/* Supported languages: https://cloud.google.com/translate/v2/translate-reference#supported_languages */

/* This function creates the URL to get the translation from Google's server
(source: https://ctrlq.org/code/19909-google-translate-api) */
function createTranslatorURL(sourceLang, targetLang, sourceText) {
  return URL.format({
    protocol: 'https:',
    hostname: 'translate.googleapis.com',
    pathname: '/translate_a/single',
    query: {
      client: 'gtx',
      ie: 'UTF-8',
      oe: 'UTF-8',
      sl: sourceLang,
      tl: targetLang,
      dt: 't',
      // dj: 1, // For more detailed JSON response
      q: sourceText,
    }
  });
}

/* Commander configuration */
program
  .version('1.0.1')
  .usage('[options] <text ...>')
  .option('-a, --auto', 'Auto-detect source language')
  /* TODO: Create defaults and let users change them [auto, source, target] */
  .option('-d, --details', 'View details')
  .option('-l, --list', 'List all available languages')
  .option('-s, --source [language]', 'Source language [en]', new RegExp(languages.getLanguagesCodesRegex(), 'i'), defaultSource)
  .option('-t, --target [language]', 'Target language [es]', new RegExp(languages.getLanguagesCodesRegex(), 'i'), defaultTarget)
  .on('--help', function () {
    console.log('  Examples:\n');
    console.log("     $ translate 'I want to translate this text'");
    console.log("     $ translate -s es -t en 'Quiero traducir este texto'");
    console.log("     $ translate -s en -t es I want to translate this text");
    console.log("     $ translate -a 'Au revoir' -d");
  })
  .parse(process.argv);

/* This option shows all languages (code and name) */
if (program.list) {
  console.log(languages.getLanguagesList());
  process.exit(0);
}

var sourceText = '';

var runTranslation = function() {
  var sourceLang = (program.auto) ? 'auto' : program.source;
  var targetLang = program.target;

  var targetURL = createTranslatorURL(sourceLang, targetLang, sourceText);

  /* Performing the request */
  request(targetURL, function(error, response, body) {
      if (!error && response.statusCode == 200) {
        /* Outdated: JSON.parse() doesn't work (empty values in array)
        Retrieved results from Google's server:
        [[["Hola Mundo","Hello World",,,1]],,"en"]
        Parsed results (with language name):
        { targetText: 'Hola Mundo',
          sourceText: 'Hello World',
          isReliable: 1,
          sourceLang: { code: 'en', language: 'English' },
          targetLang: { code: 'es', language: 'Spanish' }
        } */
        /* JSON.parse works but we delete null fields */
        var Intermed = body.replace(/,null{1,}/g, '');
        var Values = JSON.parse(Intermed);
        var Sentences = Values[0];
        var results = {};
        var text = '';
        for (var i = 0; i < Sentences.length; i++) {
          var res = {
          targetText : Sentences[i][0],
          sourceText : Sentences[i][1],
          isReliable : Sentences[i][2],
          sourceLang : languages.getLanguage(Values[1]),
          targetLang : languages.getLanguage(targetLang)
          };
          results["sentence_"+String(i)] = res;
          text += res.targetText;
        }
        /* TODO: Check confidence when auto-detection is enabled to know if the translation is accurate. */
        if (program.auto) {
          results.confidence = Values[2];
        }
        /* Finally: Printing results */
        var textToPrint;
        if (program.details) {
          textToPrint = '[' + results.sentence_0.sourceLang.name + ' -> ' + results.sentence_0.targetLang.name  + ']\n' + text;
        } else {
          textToPrint = text;
        }
        console.log(textToPrint);
        process.exit(0);

      } else {
        /* Something went wrong */
        console.log('⚠  Cannot translate now, an error occurred 🙁');
        process.exit(1);
      }
    }
  );
};

/* Let's translate! */
if (program.args.length === 0) {
  // console.log('❗ Cannot translate an empty text❗');
  // process.exit(1);
  process.stdin.resume();
  process.stdin.on('data', function(buf) { sourceText += buf.toString(); });
  process.stdin.on('end', function() {
    runTranslation();
});
} else {
  /* I prefer typing 'All the text inside simple quotes' but it's possible to use separated words */
  sourceText = (program.args.length > 1)  ? program.args.join(' ') : program.args[0];
  runTranslation();
}
<|endoftext|>


<commit_before>'use strict'

const path = require('path')
const queryString = require('querystring')

const resolveFilename = require('./resolveFilename')
const processSourceMaps = require('./processSourceMaps')

function getCompiler(source, options) {
  // it's important to not give an absolute path to Opal (only relative to load path)
  // otherwise absolute paths end up in the compiled code
  const relativePath = options.relativeFileName
    // don't want Opal.modules to have an extension
  const withoutExtension = relativePath.replace(path.extname(relativePath), '')
  const compilerOptions = Object.assign({
    file: withoutExtension // opal calls it file
  }, options)
  delete compilerOptions.filename
  return Opal.Opal.Compiler.$new(source, Opal.hash(compilerOptions))
}

function filterNonQueryPassOptions(options) {
  const passOnOptions = Object.assign({}, options)
  delete passOnOptions.sourceRoot
  delete passOnOptions.currentLoader
  delete passOnOptions.filename
  delete passOnOptions.sourceMap
  delete passOnOptions.relativeFileName
  // stubs are global, do not want to locally override these
  delete passOnOptions.stubs
  return passOnOptions
}

// TODO: Own file, call it getWebpackRequire(options, relativePath, absolutePath)
// filename => relativePath, resolved => absolutePath
// prepend can be dealt with by calling code
function addToWebpack(options, filename, prepend, resolved) {
  const passOnOptions = filterNonQueryPassOptions(options)
  Object.assign(passOnOptions, {
    file: filename,
    requirable: true
  })
  const flat = queryString.stringify(passOnOptions)
  prepend.push(`require('!!${options.currentLoader}?${flat}!${resolved}');`)
}

// TODO: own file, call getOpalStub(relativePath)
// don't need options for stubs
// prepend can be dealt with by calling code
function compileStub(options, filename, prepend) {
  const compilerOptions = filterNonQueryPassOptions(options)
  Object.assign(compilerOptions, {
    relativeFileName: filename,
    requirable: true
  })
  // if a stub is require'ed in a require'ed file, then file will be present and will override
  // the stubbed filename we're supplying
  delete compilerOptions.file
  const compiler = getCompiler('', compilerOptions)
  compiler.$compile()
  prepend.push(compiler.$result())
}

module.exports = function transpile(source, options) {
  const compiler = getCompiler(source, options)

  compiler.$compile()

  const result = compiler.$result()

  /*
    Workaround to make IO work,
    webpack polyfill global "process" module by default,
    while Opal::IO rely on it to deterimine in node environment or not
  */
  let prepend = ['process = undefined;']

  const addRequires = files => {
    files.forEach(filename => {
      var isStub = options.stubs && options.stubs.indexOf(filename) != -1
      var resolved = isStub ? null : resolveFilename(filename).absolute
      if (resolved && resolved.match(/\.js$/)) {
        // TODO: Move this to a getJsRequire function
        prepend.push(`require('${require.resolve('imports-loader')}!${resolved}');`)
        prepend.push(`Opal.loaded('${filename}');`)
      } else {
        if (isStub) {
          compileStub(options, filename, prepend)
        }
        else {
          addToWebpack(options, filename, prepend, resolved)
        }
      }
    })
  }

  addRequires(compiler.$requires())

  compiler.$required_trees().forEach(function(dirname) {
    // path will only be relative to the file we're processing
    let resolved = path.resolve(options.filename, '..', dirname)
      // TODO: Look into making this async
    let files = fs.readdirSync(resolved)
    let withPath = []
      // fs.readdir only returns the filenames, not the base directory
    files.forEach(function(filename) {
      withPath.push(path.join(dirname, filename))
    })
    addRequires(withPath)
  })

  let response = {
    code: prepend.join(' ') + '\n' + result
  }
  if (options.sourceMap) {
    response.map = processSourceMaps(compiler, source, options.filename, result, prepend)
  }
  return response
}
<commit_msg>another note<commit_after>'use strict'

const path = require('path')
const queryString = require('querystring')

const resolveFilename = require('./resolveFilename')
const processSourceMaps = require('./processSourceMaps')

// TODO: might want to move this to its own file as well
// spend some time looking at the exact convention of 'file' as it goes into here
// with different load paths and relative vs. not
// Make sure we match that so we can depend on opal compiler code for exact path resolution
function getCompiler(source, options) {
  // it's important to not give an absolute path to Opal (only relative to load path)
  // otherwise absolute paths end up in the compiled code
  const relativePath = options.relativeFileName
    // don't want Opal.modules to have an extension
  const withoutExtension = relativePath.replace(path.extname(relativePath), '')
  const compilerOptions = Object.assign({
    file: withoutExtension // opal calls it file
  }, options)
  delete compilerOptions.filename
  return Opal.Opal.Compiler.$new(source, Opal.hash(compilerOptions))
}

function filterNonQueryPassOptions(options) {
  const passOnOptions = Object.assign({}, options)
  delete passOnOptions.sourceRoot
  delete passOnOptions.currentLoader
  delete passOnOptions.filename
  delete passOnOptions.sourceMap
  delete passOnOptions.relativeFileName
  // stubs are global, do not want to locally override these
  delete passOnOptions.stubs
  return passOnOptions
}

// TODO: Own file, call it getWebpackRequire(options, relativePath, absolutePath)
// filename => relativePath, resolved => absolutePath
// prepend can be dealt with by calling code
function addToWebpack(options, filename, prepend, resolved) {
  const passOnOptions = filterNonQueryPassOptions(options)
  Object.assign(passOnOptions, {
    file: filename,
    requirable: true
  })
  const flat = queryString.stringify(passOnOptions)
  prepend.push(`require('!!${options.currentLoader}?${flat}!${resolved}');`)
}

// TODO: own file, call getOpalStub(relativePath)
// don't need options for stubs
// prepend can be dealt with by calling code
function compileStub(options, filename, prepend) {
  const compilerOptions = filterNonQueryPassOptions(options)
  Object.assign(compilerOptions, {
    relativeFileName: filename,
    requirable: true
  })
  // if a stub is require'ed in a require'ed file, then file will be present and will override
  // the stubbed filename we're supplying
  delete compilerOptions.file
  const compiler = getCompiler('', compilerOptions)
  compiler.$compile()
  prepend.push(compiler.$result())
}

module.exports = function transpile(source, options) {
  const compiler = getCompiler(source, options)

  compiler.$compile()

  const result = compiler.$result()

  /*
    Workaround to make IO work,
    webpack polyfill global "process" module by default,
    while Opal::IO rely on it to deterimine in node environment or not
  */
  let prepend = ['process = undefined;']

  const addRequires = files => {
    files.forEach(filename => {
      var isStub = options.stubs && options.stubs.indexOf(filename) != -1
      var resolved = isStub ? null : resolveFilename(filename).absolute
      if (resolved && resolved.match(/\.js$/)) {
        // TODO: Move this to a getJsRequire function
        prepend.push(`require('${require.resolve('imports-loader')}!${resolved}');`)
        prepend.push(`Opal.loaded('${filename}');`)
      } else {
        if (isStub) {
          compileStub(options, filename, prepend)
        }
        else {
          addToWebpack(options, filename, prepend, resolved)
        }
      }
    })
  }

  addRequires(compiler.$requires())

  compiler.$required_trees().forEach(function(dirname) {
    // path will only be relative to the file we're processing
    let resolved = path.resolve(options.filename, '..', dirname)
      // TODO: Look into making this async
    let files = fs.readdirSync(resolved)
    let withPath = []
      // fs.readdir only returns the filenames, not the base directory
    files.forEach(function(filename) {
      withPath.push(path.join(dirname, filename))
    })
    addRequires(withPath)
  })

  let response = {
    code: prepend.join(' ') + '\n' + result
  }
  if (options.sourceMap) {
    response.map = processSourceMaps(compiler, source, options.filename, result, prepend)
  }
  return response
}
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var util = require('./util')
  , parser = require('./parser')
  , EventEmitter = require('./event-emitter')

/**
 * Module exports.
 */

module.exports = Transport;

/**
 * Transport abstract constructor.
 *
 * @param {Object} options.
 * @api private
 */

function Transport (opts) {
  this.path = opts.path;
  this.host = opts.host;
  this.port = opts.port;
  this.secure = opts.secure;
  this.query = opts.query;
  this.readyState = '';
  this.writeBuffer = [];
};

/**
 * Inherits from EventEmitter.
 */

util.inherits(Transport, EventEmitter);

/**
 * Whether to buffer outgoing data.
 *
 * @api public
 */

Transport.prototype.buffer = true;

/**
 * Emits an error.
 *
 * @param {String} str
 * @return {Transport} for chaining
 * @api public
 */

Transport.prototype.onError = function (msg, desc) {
  var err = new Error(msg);
  err.type = 'TransportError';
  err.description = desc;
  this.emit('error', err);
  return this;
};

/**
 * Opens the transport.
 *
 * @api public
 */

Transport.prototype.open = function () {
  if ('closed' == this.readyState || '' == this.readyState) {
    this.readyState = 'opening';
    this.doOpen();
  }

  return this;
};

/**
 * Closes the transport.
 *
 * @api private
 */

Transport.prototype.close = function () {
  if ('opening' == this.readyState || 'open' == this.readyState) {
    this.doClose();
    this.onClose();
  }

  return this;
};

/**
 * Sends a packet.
 *
 * @param {Object} packet
 * @api public
 */

Transport.prototype.send = function (packet) {
  if (this.readyState != 'open') {
    this.error('not open');
  } else {
    if (this.buffer) {
      this.writeBuffer.push(data);
    } else {
      var self = this;
      this.buffer = true;
      this.write(parser.encodePacket(data), function () {
        self.flush();
      });
    }
  }

  return this;
};

/**
 * Flushes the buffer.
 *
 * @api private
 */

Transport.prototype.flush = function () {
  this.buffer = false;
  this.emit('flush');

  if (this.writeBuffer.length) {
    this.writeMany(self.writeBuffer);
    this.writeBuffer = [];
  }

  return this;
};

/**
 * Called upon open
 *
 * @api private
 */

Transport.prototype.onOpen = function () {
  this.readyState = 'open';
  this.emit('open');
};

/**
 * Called with data.
 *
 * @param {String} data
 * @api private
 */

Transport.prototype.onData = function (data) {
  this.onPacket(parser.decodePacket(data));
};

/**
 * Called with a decoded packet.
 */

Transport.prototype.onPacket = function (packet) {
  this.emit('packet', packet);
};

/**
 * Called upon close.
 *
 * @api private
 */

Transport.prototype.onClose = function () {
  this.readyState = 'closed';
  this.emit('close');
};
<commit_msg>Fixed style and throw instead of silencing the error in Transport#send<commit_after>
/**
 * Module dependencies.
 */

var util = require('./util')
  , parser = require('./parser')
  , EventEmitter = require('./event-emitter')

/**
 * Module exports.
 */

module.exports = Transport;

/**
 * Transport abstract constructor.
 *
 * @param {Object} options.
 * @api private
 */

function Transport (opts) {
  this.path = opts.path;
  this.host = opts.host;
  this.port = opts.port;
  this.secure = opts.secure;
  this.query = opts.query;
  this.readyState = '';
  this.writeBuffer = [];
};

/**
 * Inherits from EventEmitter.
 */

util.inherits(Transport, EventEmitter);

/**
 * Whether to buffer outgoing data.
 *
 * @api public
 */

Transport.prototype.buffer = true;

/**
 * Emits an error.
 *
 * @param {String} str
 * @return {Transport} for chaining
 * @api public
 */

Transport.prototype.onError = function (msg, desc) {
  var err = new Error(msg);
  err.type = 'TransportError';
  err.description = desc;
  this.emit('error', err);
  return this;
};

/**
 * Opens the transport.
 *
 * @api public
 */

Transport.prototype.open = function () {
  if ('closed' == this.readyState || '' == this.readyState) {
    this.readyState = 'opening';
    this.doOpen();
  }

  return this;
};

/**
 * Closes the transport.
 *
 * @api private
 */

Transport.prototype.close = function () {
  if ('opening' == this.readyState || 'open' == this.readyState) {
    this.doClose();
    this.onClose();
  }

  return this;
};

/**
 * Sends a packet.
 *
 * @param {Object} packet
 * @api public
 */

Transport.prototype.send = function (packet) {
  if ('open' == this.readyState) {
    if (this.buffer) {
      this.writeBuffer.push(packet);
    } else {
      var self = this;
      this.buffer = true;
      this.write(parser.encodePacket(data), function () {
        self.flush();
      });
    }
  } else {
    throw new Error('Transport not open');
  }

  return this;
};

/**
 * Flushes the buffer.
 *
 * @api private
 */

Transport.prototype.flush = function () {
  this.buffer = false;
  this.emit('flush');

  if (this.writeBuffer.length) {
    this.writeMany(self.writeBuffer);
    this.writeBuffer = [];
  }

  return this;
};

/**
 * Called upon open
 *
 * @api private
 */

Transport.prototype.onOpen = function () {
  this.readyState = 'open';
  this.emit('open');
};

/**
 * Called with data.
 *
 * @param {String} data
 * @api private
 */

Transport.prototype.onData = function (data) {
  this.onPacket(parser.decodePacket(data));
};

/**
 * Called with a decoded packet.
 */

Transport.prototype.onPacket = function (packet) {
  this.emit('packet', packet);
};

/**
 * Called upon close.
 *
 * @api private
 */

Transport.prototype.onClose = function () {
  this.readyState = 'closed';
  this.emit('close');
};
<|endoftext|>


<commit_before>/* function to find the transpose */
module.exports = function transpose(arr) {
    const calc_shape = require('./calc_shape'),
    flatten = require('./flatten'),
    form_arr = require('./form_arr'),
    arrange = require('./arrange'),

    s = calc_shape(arr);
    let flat_arr = [];
    flatten(arr,flat_arr);
    let t = form_arr(flat_arr),
    r = s.length > 1 ? s[0] : 1, c = s.length > 1 ? s[1] : s[0], k=0,
    b = [];
    for(let i=0; i<c; i++){
        //form some genius algo that has never been formed before.....
        for(let j=i; j<t.length; j+=c){
            console.log(t[j]);
            b[k++] = t[j];
        }
    }
    let final = form_arr(b);
    return arrange([c,r],final);
}
<commit_msg>fixed support for 1d arrays transpose<commit_after>/* function to find the transpose */
module.exports = function transpose(arr) {
    const calc_shape = require('./calc_shape'),
    flatten = require('./flatten'),
    form_arr = require('./form_arr'),
    arrange = require('./arrange'),

    s = calc_shape(arr);
    let flat_arr = [];
    flatten(arr,flat_arr);
    let t = form_arr(flat_arr),
    r = s.length > 1 ? s[0] : 1, c = s.length > 1 ? s[1] : s[0], k=0,
    b = [];
    for(let i=0; i<c; i++){
        for(let j=i; j<t.length; j+=c){
            console.log(t[j]);
            b[k++] = t[j];
        }
    }
    let final = form_arr(b);
    return arrange([c,r],final);
}
<|endoftext|>


<commit_before>!function(n){"use strict";function t(n){function t(){i()&&o()}function i(){return u("when",t)}function u(t,r){return g(n,t)?(v(n),x(n)?h(n):A(r,b(n)),!1):!0}function o(){return d(n)?(j(n),e()):(j(n,function(){e()}),void 0)}function e(){u("until",o)&&w(n)}n=r(n),t()}function r(n){return{count:0,when:i(n.when),until:i(n.until),action:e(n.action),fail:e(n.fail),pass:e(n.pass),interval:a(n.interval,-1e3),limit:a(n.limit,-1),context:s(n.context),args:m(n.args)}}function i(n){return f(n,u,o)}function u(n){return"function"==typeof n}function o(){return!0}function e(n){return f(n,u,c)}function c(){}function f(n,t,r){return t(n)?n:r}function a(n,t){return f(n,l,t)}function l(n){return"number"==typeof n&&n===n}function s(n){return f(n,p,{})}function p(n){return"object"==typeof n&&null!==n&&y(n)===!1}function y(n){return Array.isArray?Array.isArray(n):"[object Array]"===Object.prototype.toString.call(n)}function m(n){return f(n,y,[])}function d(n){return 0===n.action.length}function g(n,t){return!n[t].apply(n.context,n.args)}function v(n){n.count+=1}function x(n){return n.limit>=0&&n.count>=n.limit}function h(n){n.fail.apply(n.context,n.args)}function b(n){var t=n.interval;return n.interval<0&&(n.interval*=2),t}function A(n,t){setTimeout(n,Math.abs(t))}function j(n,t){n.action.apply(n.context,t?n.args.concat(t):n.args)}function w(n){n.pass.apply(n.context,n.args)}function M(){"function"==typeof define&&define.amd?define(function(){return O}):"undefined"!=typeof module&&null!==module?module.exports=O:n.trier=O}var O={attempt:t};M()}(this);<commit_msg>Update minified script.<commit_after>!function(n){"use strict";function t(n){function t(){i()&&e()}function i(){return u("when",t)}function u(t,r){return g(n,t)?(v(n),x(n)?h(n):A(r,b(n)),!1):!0}function e(){return d(n)?(j(n),o()):(j(n,o),void 0)}function o(){u("until",e)&&w(n)}n=r(n),t()}function r(n){return{count:0,when:i(n.when),until:i(n.until),action:o(n.action),fail:o(n.fail),pass:o(n.pass),interval:a(n.interval,-1e3),limit:a(n.limit,-1),context:s(n.context),args:m(n.args)}}function i(n){return f(n,u,e)}function u(n){return"function"==typeof n}function e(){return!0}function o(n){return f(n,u,c)}function c(){}function f(n,t,r){return t(n)?n:r}function a(n,t){return f(n,l,t)}function l(n){return"number"==typeof n&&n===n}function s(n){return f(n,p,{})}function p(n){return"object"==typeof n&&null!==n&&y(n)===!1}function y(n){return Array.isArray?Array.isArray(n):"[object Array]"===Object.prototype.toString.call(n)}function m(n){return f(n,y,[])}function d(n){return 0===n.action.length}function g(n,t){return!n[t].apply(n.context,n.args)}function v(n){n.count+=1}function x(n){return n.limit>=0&&n.count>=n.limit}function h(n){n.fail.apply(n.context,n.args)}function b(n){var t=n.interval;return n.interval<0&&(n.interval*=2),t}function A(n,t){setTimeout(n,Math.abs(t))}function j(n,t){n.action.apply(n.context,t?n.args.concat(t):n.args)}function w(n){n.pass.apply(n.context,n.args)}function M(){"function"==typeof define&&define.amd?define(function(){return O}):"undefined"!=typeof module&&null!==module?module.exports=O:n.trier=O}var O={attempt:t};M()}(this);<|endoftext|>


<commit_before>'use strict';
var _ = require('lodash');
var MuteStream = require('mute-stream');
var readline = require('readline');

/**
 * Base interface class other can inherits from
 */

var UI = module.exports = function (opt) {
  // Instantiate the Readline interface
  // @Note: Don't reassign if already present (allow test to override the Stream)
  if (!this.rl) {
    this.rl = readline.createInterface(setupReadlineOptions(opt));
  }
  this.rl.resume();

  this.onForceClose = this.onForceClose.bind(this);

  // Make sure new prompt start on a newline when closing
  this.rl.on('SIGINT', this.onForceClose);
  process.on('exit', this.onForceClose);
};

/**
 * Handle the ^C exit
 * @return {null}
 */

UI.prototype.onForceClose = function () {
  this.close();
  console.log('');
};

/**
 * Close the interface and cleanup listeners
 */

UI.prototype.close = function () {
  // Remove events listeners
  this.rl.removeListener('SIGINT', this.onForceClose);
  process.removeListener('exit', this.onForceClose);

  this.rl.output.unmute();

  if (this.activePrompt && typeof this.activePrompt.close === 'function') {
    this.activePrompt.close();
  }

  // Close the readline
  this.rl.output.end();
  this.rl.pause();
  this.rl.close();
};

function setupReadlineOptions(opt) {
  opt = opt || {};

  // Default `input` to stdin
  var input = opt.input || process.stdin;

  // Add mute capabilities to the output
  var ms = new MuteStream();
  ms.pipe(opt.output || process.stdout);
  var output = ms;

  return _.extend({
    terminal: true,
    input: input,
    output: output
  }, _.omit(opt, ['input', 'output']));
}
<commit_msg>[fix] #293 Exit script when SIGINT signal received (#564)<commit_after>'use strict';
var _ = require('lodash');
var MuteStream = require('mute-stream');
var readline = require('readline');

/**
 * Base interface class other can inherits from
 */

var UI = module.exports = function (opt) {
  // Instantiate the Readline interface
  // @Note: Don't reassign if already present (allow test to override the Stream)
  if (!this.rl) {
    this.rl = readline.createInterface(setupReadlineOptions(opt));
  }
  this.rl.resume();

  this.onForceClose = this.onForceClose.bind(this);

  // Make sure new prompt start on a newline when closing
  process.on('exit', this.onForceClose);

  // Terminate process on SIGINT (which will call process.on('exit') in return)
  this.rl.on('SIGINT', function () {
    process.exit(0);
  });
};

/**
 * Handle the ^C exit
 * @return {null}
 */

UI.prototype.onForceClose = function () {
  this.close();
  console.log('');
};

/**
 * Close the interface and cleanup listeners
 */

UI.prototype.close = function () {
  // Remove events listeners
  this.rl.removeListener('SIGINT', this.onForceClose);
  process.removeListener('exit', this.onForceClose);

  this.rl.output.unmute();

  if (this.activePrompt && typeof this.activePrompt.close === 'function') {
    this.activePrompt.close();
  }

  // Close the readline
  this.rl.output.end();
  this.rl.pause();
  this.rl.close();
};

function setupReadlineOptions(opt) {
  opt = opt || {};

  // Default `input` to stdin
  var input = opt.input || process.stdin;

  // Add mute capabilities to the output
  var ms = new MuteStream();
  ms.pipe(opt.output || process.stdout);
  var output = ms;

  return _.extend({
    terminal: true,
    input: input,
    output: output
  }, _.omit(opt, ['input', 'output']));
}
<|endoftext|>


<commit_before>var Path = require('path');
var Blessed = require('blessed');

exports = module.exports = function (context) {
  // Create the screen object.
  var screen = Blessed.screen({
    autoPadding: true,
    smartCSR: true,
    useBCE: true,
    cursor: {
      artificial: true,
      blink: true,
      shape: 'underline'
    },
    log: Path.join(__dirname, '..', '..', 'gitter-cli-blessed.log'),
    dump: true,
    fullUnicode: true,
    dockBorders: true,
    ignoreLocked: ['C-c']
  });

  // Set the terminal title.
  screen.title = 'Gitter';

  return screen;
};
<commit_msg>squash! Merge branch 'master' of https://github.com/juliosueiras/gitter-cli<commit_after>var Path = require('path');
var Blessed = require('blessed');

exports = module.exports = function (context) {
  // Create the screen object.
  var screen = Blessed.screen({
    autoPadding: true,
    smartCSR: true,
    useBCE: foalse,
    cursor: {
      artificial: true,
      blink: true,
      shape: 'underline'
    },
    log: Path.join(__dirname, '..', '..', 'gitter-cli-blessed.log'),
    dump: true,
    fullUnicode: true,
    dockBorders: true,
    ignoreLocked: ['C-c']
  });

  // Set the terminal title.
  screen.title = 'Gitter';

  return screen;
};
<|endoftext|>


<commit_before>/*
 * a node.js test runner that executes all conformance
 * tests and outputs results to console.
 * Process returns zero on success, non-zero on failure.
 */

const   fs = require('fs'),
      path = require('path'),
jsonselect = require('../jsonselect.js'),
       sys = require('sys');

var pathToTests = path.join(__dirname, "tests");

// a map: document nametest name -> list of se
var numTests = 0;
var numPassed = 0;
var tests = {};

function runOneSync(name, selname, p) {
    var testDocPath = path.join(p, name + ".json");
    var selDocPath = path.join(p, name + '_' +
                               selname + ".selector");
    var outputDocPath = selDocPath.replace(/selector$/, "output");

    // take `obj`, apply `sel, get `got`, is it what we `want`?
    var obj = JSON.parse(fs.readFileSync(testDocPath));
    var want = String(fs.readFileSync(outputDocPath)).trim();
    var got = "";
    var sel = String(fs.readFileSync(selDocPath)).trim();

    try {
        jsonselect.forEach(sel, obj, function(m) {
            got += JSON.stringify(m, undefined, 4) + "\n";
        });
    } catch(e) {
        got = e.toString();
        if (want.trim() != got.trim()) {

            // The error messages will have consistent prefix strings, but variant context strings
            if ( want.trim().indexOf("Error") === -1 && got.trim().indexOf( want.trim() ) !== 0 ) {
              throw e;
            }
            //console.log( "want: " + want.trim() );
            //console.log( "got: " + got.trim() );
        }
    }
    if (want.trim() != got.trim()) {
      //console.log( "want: " + want.trim() );
      //console.log( "got: " + got.trim() );
      if ( want.trim().indexOf("Error") === -1 && got.trim().indexOf( want.trim() ) !== 0 ) {
        throw "mismatch";
      }
    }
}

function runTests() {
    console.log("Running Tests:");
    for (var l in tests) {
        for (var d in tests[l]) {
            console.log("  level " + l + " tests against \"" + d + ".json\":");
            for (var i = 0; i < tests[l][d].length; i++) {
                sys.print("    " + tests[l][d][i][0] + ": ");
                try {
                    runOneSync(d, tests[l][d][i][0], tests[l][d][i][1]);
                    numPassed++;
                    console.log("pass");
                } catch (e) {
                    console.log("fail (" + e.toString() + ")");
                }
            }
        }
    }
    console.log(numPassed + "/" + numTests + " passed");
    process.exit(numPassed == numTests ? 0 : 1);
}

// discover all tests
var pathToTests = path.join(__dirname, "tests");

fs.readdirSync(pathToTests).forEach(function(subdir) {
    var p = path.join(pathToTests, subdir);
    if (!fs.statSync(p).isDirectory()) return;
    var l = /^level_([\d+])$/.exec(subdir);
    if (!l) return;
    l = l[1];
    var files = fs.readdirSync(p);
    for (var i = 0; i < files.length; i++) {
        var f = files[i];
        var m = /^([A-Za-z]+)_(.+)\.selector$/.exec(f);
        if (m) {
            if (!tests.hasOwnProperty(l)) tests[l] = [];
            if (!tests[l].hasOwnProperty(m[1])) tests[l][m[1]] = [];
            numTests++;
            tests[l][m[1]].push([m[2], p]);
        }
    }
});
runTests();
<commit_msg>Revert changes to run.js<commit_after>/*
 * a node.js test runner that executes all conformance
 * tests and outputs results to console.
 * Process returns zero on success, non-zero on failure.
 */

const   fs = require('fs'),
      path = require('path'),
jsonselect = require('../jsonselect.js'),
       sys = require('sys');

var pathToTests = path.join(__dirname, "tests");

// a map: document nametest name -> list of se
var numTests = 0;
var numPassed = 0;
var tests = {};

function runOneSync(name, selname, p) {
    var testDocPath = path.join(p, name + ".json");
    var selDocPath = path.join(p, name + '_' +
                               selname + ".selector");
    var outputDocPath = selDocPath.replace(/selector$/, "output");

    // take `obj`, apply `sel, get `got`, is it what we `want`?
    var obj = JSON.parse(fs.readFileSync(testDocPath));
    var want = String(fs.readFileSync(outputDocPath)).trim();
    var got = "";
    var sel = String(fs.readFileSync(selDocPath)).trim();

    try {
        jsonselect.forEach(sel, obj, function(m) {
            got += JSON.stringify(m, undefined, 4) + "\n";
        });
    } catch(e) {
        got = e.toString();
        if (want.trim() != got.trim()) throw e;
    }
    if (want.trim() != got.trim()) throw "mismatch";
}

function runTests() {
    console.log("Running Tests:");
    for (var l in tests) {
        for (var d in tests[l]) {
            console.log("  level " + l + " tests against \"" + d + ".json\":");
            for (var i = 0; i < tests[l][d].length; i++) {
                sys.print("    " + tests[l][d][i][0] + ": ");
                try {
                    runOneSync(d, tests[l][d][i][0], tests[l][d][i][1]);
                    numPassed++;
                    console.log("pass");
                } catch (e) {
                    console.log("fail (" + e.toString() + ")");
                }
            }
        }
    }
    console.log(numPassed + "/" + numTests + " passed");
    process.exit(numPassed == numTests ? 0 : 1);
}

// discover all tests
var pathToTests = path.join(__dirname, "tests");

fs.readdirSync(pathToTests).forEach(function(subdir) {
    var p = path.join(pathToTests, subdir);
    if (!fs.statSync(p).isDirectory()) return;
    var l = /^level_([\d+])$/.exec(subdir);
    if (!l) return;
    l = l[1];
    var files = fs.readdirSync(p);
    for (var i = 0; i < files.length; i++) {
        var f = files[i];
        var m = /^([A-Za-z]+)_(.+)\.selector$/.exec(f);
        if (m) {
            if (!tests.hasOwnProperty(l)) tests[l] = [];
            if (!tests[l].hasOwnProperty(m[1])) tests[l][m[1]] = [];
            numTests++;
            tests[l][m[1]].push([m[2], p]);
        }
    }
});
runTests();
<|endoftext|>


<commit_before>/*
 * Licensed to Cloudkick, Inc ('Cloudkick') under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * Cloudkick licenses this file to You 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.
 */

/**
 * Short utility functions that otherwise wouldn't have a home.
 */

var path = require('path');
var async = require('extern/async');
var fs = require('fs');

/*
* very simple object merging
* TODO: import mixin from jquery / dojo for real objects
*/
exports.merge = function (a, b)
{
  var c = {};
  var attrname;
  for (attrname in a) {
    if (a.hasOwnProperty(attrname)) {
      c[attrname] = a[attrname];
    }
  }
  for (attrname in b) {
    if (b.hasOwnProperty(attrname)) {
      c[attrname] = b[attrname];
    }
  }
  return c;
};

exports.expanduser = function(pstr)
{
  if (pstr.indexOf("~") !== 0) {
    return pstr;
  }

  var splitter = pstr.indexOf('/');
  var user = "";
  if (splitter == -1) {
    user = pstr.substr(1);
    pstr = "/";
  }
  else {
    user = pstr.substring(1, splitter);
    pstr = pstr.substr(splitter+1);
  }

  if (user.length !== 0) {
    /* TODO: need bindings to getpwnam to make this work for the non-current */
    throw "no bindings to getpwnam, so you can't do get info for user: "+ user;
  }

  if (process.env.HOME === undefined) {
    throw "no bindings to getpwnam, and env[HOME] was undefined";
  }

  return path.join(process.env.HOME, pstr);
};

/**
 * Converts an object to a directory tree, where objects are treated as
 * directories and anything else is dumped to a regular file as a string.
 *
 * @param {String} basedir  The path to the tree's (not-yet-existing) root
 * @param {Object} basedir  The object to use as a template
 * @param {Function} cb     Callback, taking a possible error
 */
exports.template_to_tree = function(basedir, template, cb) {
  var actions = [
    async.apply(fs.mkdir, basedir, 0700)
  ];

  function recurse_action(basedir, key) {
    var curpath = path.join(basedir, key);
    return function(callback) {
      // Recurse on sub-templates
      if (typeof(template[key]) === 'object') {
        exports.template_to_tree(curpath, template[key], callback);
      }
      // Render anything else to files
      else {
        fs.open(curpath, 'w', 0700, function(err, fd) {
          if (err) {
            callback(err);
          }
          else {
            fs.write(fd, template[key].toString(), callback);
          }
        });
      }
    };
  }

  // Build a list of actions to fill in this level of the tree
  for (var key in template) {
    if (template.hasOwnProperty(key)) {
      actions.push(recurse_action(basedir, key));
    }
  }

  // Execute the action sequence
  async.parallel(actions, cb);
};

<commit_msg>Document and use new Error to throw nicely.<commit_after>/*
 * Licensed to Cloudkick, Inc ('Cloudkick') under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * Cloudkick licenses this file to You 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.
 */

/**
 * Short utility functions that otherwise wouldn't have a home.
 */

var path = require('path');
var async = require('extern/async');
var fs = require('fs');

/*
* very simple object merging
* TODO: import mixin from jquery / dojo for real objects
*/
exports.merge = function (a, b)
{
  var c = {};
  var attrname;
  for (attrname in a) {
    if (a.hasOwnProperty(attrname)) {
      c[attrname] = a[attrname];
    }
  }
  for (attrname in b) {
    if (b.hasOwnProperty(attrname)) {
      c[attrname] = b[attrname];
    }
  }
  return c;
};

/**
 * Expands a path with a ~user or ~ to an absolute path.
 * Note: This currently depends on the HOME enviroment variable,
 * because there are no bindings to getpwnam.
 *
 * @param {String} pstr Original path.
 * @return {string} Expanded path
 */
exports.expanduser = function(pstr)
{
  if (pstr.indexOf("~") !== 0) {
    return pstr;
  }

  var splitter = pstr.indexOf('/');
  var user = "";
  if (splitter == -1) {
    user = pstr.substr(1);
    pstr = "/";
  }
  else {
    user = pstr.substring(1, splitter);
    pstr = pstr.substr(splitter+1);
  }

  if (user.length !== 0) {
    /* TODO: need bindings to getpwnam to make this work for the non-current */
    throw Error("no bindings to getpwnam, so you can't do get info for user: "+ user);
  }

  if (process.env.HOME === undefined) {
    throw Error("no bindings to getpwnam, and env[HOME] was undefined");
  }

  return path.join(process.env.HOME, pstr);
};

/**
 * Converts an object to a directory tree, where objects are treated as
 * directories and anything else is dumped to a regular file as a string.
 *
 * @param {String} basedir  The path to the tree's (not-yet-existing) root
 * @param {Object} basedir  The object to use as a template
 * @param {Function} cb     Callback, taking a possible error
 */
exports.template_to_tree = function(basedir, template, cb) {
  var actions = [
    async.apply(fs.mkdir, basedir, 0700)
  ];

  function recurse_action(basedir, key) {
    var curpath = path.join(basedir, key);
    return function(callback) {
      // Recurse on sub-templates
      if (typeof(template[key]) === 'object') {
        exports.template_to_tree(curpath, template[key], callback);
      }
      // Render anything else to files
      else {
        fs.open(curpath, 'w', 0700, function(err, fd) {
          if (err) {
            callback(err);
          }
          else {
            fs.write(fd, template[key].toString(), callback);
          }
        });
      }
    };
  }

  // Build a list of actions to fill in this level of the tree
  for (var key in template) {
    if (template.hasOwnProperty(key)) {
      actions.push(recurse_action(basedir, key));
    }
  }

  // Execute the action sequence
  async.parallel(actions, cb);
};

<|endoftext|>


<commit_before>const mime = require('mime')
const ETag = require('etag')
const zlib = require('zlib')
const pkg = require('../../package.json')
const isText = pathname => !!mime.charsets.lookup(mime.lookup(pathname), false)

const version = `${pkg.name} ${pkg.version}`

module.exports = conf => {
    const {gzip} = conf

    return {
        handleError: (resp, error) => {
            resp.writeHead(500, {
                'Content-Type': 'text/html; charset=utf-8',
                'X-Powered-By': version
            })
            resp.end(JSON.stringify(error))
            return resp
        },
        handleSuccess: (req, resp, pathname, data) => {
            const tag = req.headers['if-none-match']
            const newTag = data && ETag(data)
            const txt = isText(pathname)
            if (tag && data && tag === newTag) {
                resp.writeHead(304, 'Not Modified')
                resp.end()
            } else {
                let header = {
                    'Content-Type': mime.lookup(pathname) + '; charset=utf-8',
                    'Content-Encoding': gzip && txt ? 'gzip' : 'utf-8',
                    'X-Powered-By': version
                }
                newTag && (header['ETag'] = newTag)
                resp.writeHead(200, header)
                if (data) {
                    resp.end(gzip && txt ? zlib.gzipSync(data.toString()) : data)
                } else {
                    return resp
                }
            }
        },
        handleNotFound: (resp, pathname) => {
            resp.writeHead(404, {
                'Content-Type': 'text/html; charset=utf-8',
                'X-Powered-By': version
            })
            resp.end('<meta charset="utf-8"/>' +
                '
 404: "' + pathname + '"  is gone!
')
            return resp
        }
    }
}
<commit_msg>etag toString<commit_after>const mime = require('mime')
const ETag = require('etag')
const zlib = require('zlib')
const pkg = require('../../package.json')
const isText = pathname => !!mime.charsets.lookup(mime.lookup(pathname), false)

const version = `${pkg.name} ${pkg.version}`

module.exports = conf => {
    const {gzip} = conf

    return {
        handleError: (resp, error) => {
            resp.writeHead(500, {
                'Content-Type': 'text/html; charset=utf-8',
                'X-Powered-By': version
            })
            resp.end(JSON.stringify(error))
            return resp
        },
        handleSuccess: (req, resp, pathname, data) => {
            const tag = req.headers['if-none-match']
            const newTag = data && ETag(data.toString())
            const txt = isText(pathname)
            if (tag && data && tag === newTag) {
                resp.writeHead(304, 'Not Modified')
                resp.end()
            } else {
                let header = {
                    'Content-Type': mime.lookup(pathname) + '; charset=utf-8',
                    'Content-Encoding': gzip && txt ? 'gzip' : 'utf-8',
                    'X-Powered-By': version
                }
                newTag && (header['ETag'] = newTag)
                resp.writeHead(200, header)
                if (data) {
                    resp.end(gzip && txt ? zlib.gzipSync(data.toString()) : data)
                } else {
                    return resp
                }
            }
        },
        handleNotFound: (resp, pathname) => {
            resp.writeHead(404, {
                'Content-Type': 'text/html; charset=utf-8',
                'X-Powered-By': version
            })
            resp.end('<meta charset="utf-8"/>' +
                '
 404: "' + pathname + '"  is gone!
')
            return resp
        }
    }
}
<|endoftext|>


<commit_before>/*!
 * UtilityJS
 *
 * Copyright(c) 2016 Mohammad Fares
 * MIT Licensed
 */

;(function(root, factory) {

  // For CommonJS-like enviroments (node.js)
  if (typeof module === 'object' && typeof module.exports === 'object') {

    module.exports = factory();

  // For AMD and browser
  } else {

    // Define the module globally in case of some libraries doesn't use AMD
    root.u = factory();

    // For AMD (requireJS)
    if (typeof define === 'function' && define.amd) {

      // Define an anonymous module
      define(function() {
        return factory();
      });

    }

  }

}(this, function() {

  /**
   * UtilityJS
   *
   * @module u
   */

  var root      = this || global
    , previousU = root.u
    , u         = {};

  // The current version of the module
  u.VERSION = '0.1.3';

  ////////////////////////////////////////////////////
  // Helpers /////////////////////////////////////////
  ////////////////////////////////////////////////////

  /**
   * Return a the default value if the passed variable is undefined
   *
   * @param  {*} variable     the value
   * @param  {*} defaultValue the default value of the variable
   * @return {*}
   */
  function defaultValue(variable, defaultValue) {

    return typeof variable === 'undefined'
      ? defaultValue
      : variable;

  }

  ////////////////////////////////////////////////////
  // Methods > Variable Handeling ////////////////////
  ////////////////////////////////////////////////////

  /**
   * Check if a giving value is a number
   *
   * @method isNumber
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isNumber(value) {
    return !u.isNan(value) && Object.prototype.toString.call(value) === '[object Number]';
  };

  /**
   * Check if a giving value is an object
   *
   * @method isObject
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isObject(value) {
    return type === 'function' || (type === 'object' && !u.isNull(value));
  };

  /**
   * Check if a giving value is an array
   *
   * @method isArray
   * @param  {*} value a value to be checked
   * @return {Boolean}
   */
  isArray = Array.isArray || function(value) {
    return Object.prototype.toString.call(value) === '[object Array]';
  };

  /**
   * Check if a giving value is a boolean
   *
   * @method isBoolean
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isBoolean(value) {
    return value === true || value === false || Object.prototype.toString.call(value) === '[object Boolean]';
  };

  /**
   * Check if a giving value is a null
   *
   * @method isNull
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  isNull = Number.isNaN || function(value) {
    return value === null;
  };

  /**
   * Check if a giving value is a date
   *
   * @method isDate
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isDate(value) {
    return Object.prototype.toString.call(value) === '[object Date]';
  };

  /**
   * Check if a giving value is an error
   *
   * @method isError
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isError(value) {
    return Object.prototype.toString.call(value) === '[object Error]';
  };

  /**
   * Check if a giving value is an function
   *
   * @method isFunction
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isFunction(value) {
    return typeof value === 'function' || Object.prototype.toString.call(value) === '[object Function]';
  };

  /**
   * Check if a giving value is a NaN
   *
   * @method isNan
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isNan(value) {
    return value !== value;
  };

  /**
   * Check if a giving value is a undefined
   *
   * @method isUndefined
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isUndefined(value) {
    return typeof value === 'undefined';
  };

  /**
   * Check if a giving value is a string
   *
   * @method isString
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isString(value) {
    return Object.prototype.toString.call(value) === '[object String]';
  };

  /**
   * Convert a giving value to a string
   *
   * @method toString
   * @param  {*} value a value to be converted
   * @return {String}
   */
  function toString(value) {

    // If the value is aready a string
    if (u.isString(value)) {
      return value;
    }

    // If the value is null, nan or undefined
    if (u.isNull(value) || u.isNan(value) || u.isUndefined(value)) {
      return '';
    }

    return value + '';

  };

  ////////////////////////////////////////////////////
  // Methods > String ////////////////////////////////
  ////////////////////////////////////////////////////

  /**
   * Split a string by a delimiter string
   *
   * @method explode
   * @param  {String} delimiter the string that indicates the spliting positions
   * @param  {String} string    the original string
   * @param  {Number} limit     limit the number of spliting positions
   * @return {Array}
   */
  function explode(delimiter, string, limit) {
    return u.toString(string).split(delimiter);
  };

  ////////////////////////////////////////////////////
  // Module //////////////////////////////////////////
  ////////////////////////////////////////////////////

  u.isNumber   = isNumber;
  u.isObject   = isObject;
  u.isArray    = isArray;
  u.isBoolean  = isBoolean;
  u.isNull     = isNull;
  u.isDate     = isDate;
  u.isError    = isError;
  u.isFunction = isFunction;
  u.isNan      = isNan;
  u.isString   = isString;
  u.toString   = toString;
  u.explode    = explode;

  // Aliases /////////////////////////////////////////

  u.is_number   = u.isNumber;
  u.is_object   = u.isObject;
  u.is_array    = u.isArray;
  u.is_boolean  = u.isBoolean;
  u.is_null     = u.isNull;
  u.is_date     = u.isDate;
  u.is_error    = u.isError;
  u.is_function = u.isFunction;
  u.is_nan      = u.isNan;
  u.isNaN       = u.isNan;
  u.is_string   = u.isString;
  u.string      = u.toString;
  u.split       = u.explode;

  /**
   * Switch to "no conflict mode", set u to
   * the previously defined u and return the utilityJS module
   *
   * @method noConflict
   * @return {Object} utilityJS
   */
  function noConflict() {
    root.u = previousU;
    return u;
  };

  return u;

}));
<commit_msg>Remove extra semicolons<commit_after>/*!
 * UtilityJS
 *
 * Copyright(c) 2016 Mohammad Fares
 * MIT Licensed
 */

;(function(root, factory) {

  // For CommonJS-like enviroments (node.js)
  if (typeof module === 'object' && typeof module.exports === 'object') {

    module.exports = factory();

  // For AMD and browser
  } else {

    // Define the module globally in case of some libraries doesn't use AMD
    root.u = factory();

    // For AMD (requireJS)
    if (typeof define === 'function' && define.amd) {

      // Define an anonymous module
      define(function() {
        return factory();
      });

    }

  }

}(this, function() {

  /**
   * UtilityJS
   *
   * @module u
   */

  var root      = this || global
    , previousU = root.u
    , u         = {};

  // The current version of the module
  u.VERSION = '0.1.3';

  ////////////////////////////////////////////////////
  // Helpers /////////////////////////////////////////
  ////////////////////////////////////////////////////

  /**
   * Return a the default value if the passed variable is undefined
   *
   * @param  {*} variable     the value
   * @param  {*} defaultValue the default value of the variable
   * @return {*}
   */
  function defaultValue(variable, defaultValue) {

    return typeof variable === 'undefined'
      ? defaultValue
      : variable;

  }

  ////////////////////////////////////////////////////
  // Methods > Variable Handeling ////////////////////
  ////////////////////////////////////////////////////

  /**
   * Check if a giving value is a number
   *
   * @method isNumber
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isNumber(value) {
    return !u.isNan(value) && Object.prototype.toString.call(value) === '[object Number]';
  }

  /**
   * Check if a giving value is an object
   *
   * @method isObject
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isObject(value) {
    return typeof value === 'function' || (typeof value === 'object' && !u.isNull(value));
  }

  /**
   * Check if a giving value is an array
   *
   * @method isArray
   * @param  {*} value a value to be checked
   * @return {Boolean}
   */
  isArray = Array.isArray || function(value) {
    return Object.prototype.toString.call(value) === '[object Array]';
  };

  /**
   * Check if a giving value is a boolean
   *
   * @method isBoolean
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isBoolean(value) {
    return value === true || value === false || Object.prototype.toString.call(value) === '[object Boolean]';
  }

  /**
   * Check if a giving value is a null
   *
   * @method isNull
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isNull(value) {
    return value === null;
  }

  /**
   * Check if a giving value is a date
   *
   * @method isDate
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isDate(value) {
    return Object.prototype.toString.call(value) === '[object Date]';
  }

  /**
   * Check if a giving value is an error
   *
   * @method isError
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isError(value) {
    return Object.prototype.toString.call(value) === '[object Error]';
  }

  /**
   * Check if a giving value is an function
   *
   * @method isFunction
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isFunction(value) {
    return typeof value === 'function' || Object.prototype.toString.call(value) === '[object Function]';
  }

  /**
   * Check if a giving value is a NaN
   *
   * @method isNan
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isNan(value) {
    return value !== value;
  }

  /**
   * Check if a giving value is a undefined
   *
   * @method isUndefined
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isUndefined(value) {
    return typeof value === 'undefined';
  }

  /**
   * Check if a giving value is a string
   *
   * @method isString
   * @param  {*}  value a value to be check
   * @return {Boolean}
   */
  function isString(value) {
    return Object.prototype.toString.call(value) === '[object String]';
  }

  /**
   * Convert a giving value to a string
   *
   * @method toString
   * @param  {*} value a value to be converted
   * @return {String}
   */
  function toString(value) {

    // If the value is aready a string
    if (u.isString(value)) {
      return value;
    }

    // If the value is null, nan or undefined
    if (u.isNull(value) || u.isNan(value) || u.isUndefined(value)) {
      return '';
    }

    return value + '';

  };

  ////////////////////////////////////////////////////
  // Methods > String ////////////////////////////////
  ////////////////////////////////////////////////////

  /**
   * Split a string by a delimiter string
   *
   * @method explode
   * @param  {String} delimiter the string that indicates the spliting positions
   * @param  {String} string    the original string
   * @param  {Number} limit     limit the number of spliting positions
   * @return {Array}
   */
  function explode(delimiter, string, limit) {
    return u.toString(string).split(delimiter);
  };

  ////////////////////////////////////////////////////
  // Module //////////////////////////////////////////
  ////////////////////////////////////////////////////

  u.isNumber   = isNumber;
  u.isObject   = isObject;
  u.isArray    = isArray;
  u.isBoolean  = isBoolean;
  u.isNull     = isNull;
  u.isDate     = isDate;
  u.isError    = isError;
  u.isFunction = isFunction;
  u.isNan      = isNan;
  u.isString   = isString;
  u.toString   = toString;
  u.explode    = explode;

  // Aliases /////////////////////////////////////////

  u.is_number   = u.isNumber;
  u.is_object   = u.isObject;
  u.is_array    = u.isArray;
  u.is_boolean  = u.isBoolean;
  u.is_null     = u.isNull;
  u.is_date     = u.isDate;
  u.is_error    = u.isError;
  u.is_function = u.isFunction;
  u.is_nan      = u.isNan;
  u.isNaN       = u.isNan;
  u.is_string   = u.isString;
  u.string      = u.toString;
  u.split       = u.explode;

  /**
   * Switch to "no conflict mode", set u to
   * the previously defined u and return the utilityJS module
   *
   * @method noConflict
   * @return {Object} utilityJS
   */
  function noConflict() {
    root.u = previousU;
    return u;
  };

  return u;

}));
<|endoftext|>


<commit_before>// handle some git configuration for windows

exports.spawn = spawnGit
exports.chainableExec = chainableExec
exports.whichAndExec = whichAndExec

var exec = require('child_process').execFile
var spawn = require('./spawn')
var npm = require('../npm.js')
var which = require('which')
var git = npm.config.get('git')
var assert = require('assert')
var log = require('npmlog')

function prefixGitArgs () {
  return process.platform === 'win32' ? ['-c', 'core.longpaths=true'] : []
}

function execGit (args, options, cb) {
  log.info('git', args)
  var fullArgs = prefixGitArgs().concat(args || [])
  return exec(git, fullArgs, options, cb)
}

function spawnGit (args, options) {
  log.info('git', args)
  return spawn(git, prefixGitArgs().concat(args || []), options)
}

function chainableExec () {
  var args = Array.prototype.slice.call(arguments)
  return [execGit].concat(args)
}

function whichGit (cb) {
  return which(git, cb)
}

function whichAndExec (args, options, cb) {
  assert.equal(typeof cb, 'function', 'no callback provided')
  // check for git
  whichGit(function (err) {
    if (err) {
      err.code = 'ENOGIT'
      return cb(err)
    }

    execGit(args, options, cb)
  })
}
<commit_msg>git: remove a function call from Git helper<commit_after>// handle some git configuration for windows

exports.spawn = spawnGit
exports.chainableExec = chainableExec
exports.whichAndExec = whichAndExec

var exec = require('child_process').execFile
var spawn = require('./spawn')
var npm = require('../npm.js')
var which = require('which')
var git = npm.config.get('git')
var assert = require('assert')
var log = require('npmlog')

function prefixGitArgs () {
  return process.platform === 'win32' ? ['-c', 'core.longpaths=true'] : []
}

function execGit (args, options, cb) {
  log.info('git', args)
  var fullArgs = prefixGitArgs().concat(args || [])
  return exec(git, fullArgs, options, cb)
}

function spawnGit (args, options) {
  log.info('git', args)
  return spawn(git, prefixGitArgs().concat(args || []), options)
}

function chainableExec () {
  var args = Array.prototype.slice.call(arguments)
  return [execGit].concat(args)
}

function whichAndExec (args, options, cb) {
  assert.equal(typeof cb, 'function', 'no callback provided')
  // check for git
  which(git, function (err) {
    if (err) {
      err.code = 'ENOGIT'
      return cb(err)
    }

    execGit(args, options, cb)
  })
}
<|endoftext|>


<commit_before>'use strict';

var DEFAULT_LIMIT = 10;

function extend(dest, src) {
  for (var k in src) {
    if (src.hasOwnProperty(k)) {
      dest[k] = src[k];
    }
  }
  return dest;
}

var ViewFields = ['descending', 'endkey', 'endkey_docid',
  'full_set', 'group', 'group_level', 'inclusive_end',
  'include_docs',
  'key', 'keys', 'limit', 'on_error', 'reduce', 'skip',
  'stale', 'startkey', 'startkey_docid'];
var JsonFields = ['endkey', 'key', 'keys', 'startkey'];

function normalizeQuery(query) {
  for (var q in query) {
    if (query.hasOwnProperty(q)) {
      if (ViewFields.indexOf(q) === -1) {
        delete query[q];
      } else if (JsonFields.indexOf(q) !== -1) {
        query[q] = JSON.stringify(query[q]);
      }
    }
  }
  return query;
}

/**
 * @class Paginator
 * @classdesc
 * A class used to handle pagination of view result sets.  This class is
 * instantiated by using the {@link ViewQuery#firstPage} method.
 *
 * @private
 */

/**
 * @constructor
 *
 * @param {object} qobj
 * The ViewQuery instance this paginator should operate on.
 * @param {object} cb
 * The Couchbase object to use to execute operations.
 *
 * @private
 * @ignore
 */
function Paginator(qobj, cb) {
  this._prevkey = null;
  this._nextkey = null;
  this._prevkey_docid = null;
  this._nextkey_docid = null;
  this._prevpages = [];
  this._qobj = qobj;
  this._cb = cb;
}

/**
 * local callback, that will adjust startkey_docid and endkey_docid before
 * supplying the results to the application callback.
 *
 * @private
 * @ignore
 */
Paginator.prototype._paginate = function(err, results, callback) {
  if (results) {
    if (results.length > 0) {
      if (this._prevkey !== null && this._prevkey_docid !== null ) {
        this._prevpages.push([this._prevkey, this._prevkey_docid]);
      }
      this._prevkey = results[0].key;
      this._prevkey_docid = results[0].id;
    }
    if (results.length > this._qobj.q.limit) {
      var x = results.pop();
      this._nextkey = x.key;
      this._nextkey_docid = x.id;
    } else {
      this._nextkey = null;
      this._nextkey_docid = null;
    }
  }
  callback.call( this._cb, err, results === null ? [] : results );
};

/**
 * Check whether a next page for result set is available.
 *
 * @returns {boolean} Whether another page is available
 */
Paginator.prototype.hasNext = function() {
  return this._nextkey !== null;
};

/**
 * Retrieves the next set of results.
 *
 * @param {QueryCallback} callback
 * The callback to invoke once the page of results is available.
 */
Paginator.prototype.next = function(callback) {
  if (this._nextkey && this._nextkey_docid) {
    var q = extend(extend({}, this._qobj.q),{
      startkey: JSON.stringify(this._nextkey),
      startkey_docid: JSON.stringify(this._nextkey_docid)
    });
    var p = this;
    var paginate_ = function(err, results) {
      p._paginate.call(p, err, results, callback);
    };
    q.limit += 1;
    this._qobj._request(q, paginate_);

  } else {
    this._paginate.call(this, null, [], callback);
  }
  return this;
};

/**
 * Retrieves the previous set of results.
 *
 * @param {QueryCallback} callback
 * The callback to invoke once the page of results is available.
 */
Paginator.prototype.prev = function(callback) {
  if( this._prevpages.length === 0 ) {
    this._paginate.call(this, null, null, callback);
  } else {
    var nk = this._prevpages.pop();
    var p = this;
    var paginate_ = function(err, results) {
      p._prevkey = null;
      p._prevkey_docid = null;
      p._paginate.call(p, err, results, callback);
    };
    var q = extend(extend({}, this._qobj.q), {
      startkey: JSON.stringify(nk[0]),
      startkey_docid: JSON.stringify(nk[1])
    });
    q.limit += 1;
    this._qobj._request(q, paginate_);
  }
  return this;
};

/**
 * @class ViewQuery
 * @classdesc
 * A class used to execute view queries.  This class is instantiated by using
 * the {@link Connection#view} method.
 *
 * @private
 */

/**
 * @constructor
 *
 * @param {object} cb connection object.
 * @param {string} ddoc name of design-document containing the view.
 * @param {string} name view name on which to apply this query.
 * @param {object} params key,value pairs supplying the initial set of query
 *    parameters to be used for subsequent queries. This can be
 *    overriden while calling clone() and query() on this instance.
 *
 * @private

 */
function ViewQuery(cb, ddoc, name, params) {
  this._cb = cb;
  this.ddoc = ddoc;
  this.name = name;
  this.q = normalizeQuery( params === undefined ? {} : params );
}

/**
 * Query callback.
 * This callback is invoked by the query operations.
 *
 * @typedef {function} QueryCallback
 *
 * @param {undefined|Error} error
 *  An error indicator. Note that this error
 *  value may be ignored, but its absence is indicative that the
 *  response in the results parameter is ok. If it
 *  is set, then the request failed.
 * @param {object} results
 *  The results returned from the server
 * @param {object} misc
 *  @param {integer} misc.total_rows
 *  The total number of rows available in the view.
 */

/**
 * FirstPage query callback.
 * This callback is invoked by the firstPage query operation.
 *
 * @typedef {function} FirstPageCallback
 *
 * @param {undefined|Error} error
 *  An error indicator. Note that this error
 *  value may be ignored, but its absence is indicative that the
 *  response in the results parameter is ok. If it
 *  is set, then the request failed.
 * @param {object} results
 *  The results returned from the server
 * @param {Paginator} paginator
 *   The paginator for paged iteration through the view
 */

/**
 * Query for result set.
 *
 * @param {object} q key,value pairs supplying additional set of query
 *    parameters to be used for this queries.
 * @param {QueryCallback} callback
 */
ViewQuery.prototype.query = function(q, callback) {
  if (typeof q === 'function') {
    callback = arguments[0];
    q = {};
  }
  var qe = extend( extend({}, this.q), normalizeQuery(q) );
  this._request(qe, callback);
  return this;
};

/**
 * Clone this query instance, with a new set of initial parameters overriding
 * current set.
 *
 * @private
 * @ignore
 *
 * @param {object} cparams key,value pairs supplying a new set of query
 *    parameters, to be used for subsequent queries.
 */
ViewQuery.prototype.clone = function( cparams ) {
  var newq = new ViewQuery( this._cb, this.ddoc, this.name, {} );
  newq.q = extend( extend({}, this.q), normalizeQuery(cparams) );
  return newq;
};

/**
 * Get the first page of query's result set, along with a paginator instance.
 * subsequently paginator.next(), and paginator.prev() can be used to navigate
 * within result set.
 *
 * Maximum number of entries in each page is determined by query's `limit`
 * parameter or `DEFAULT_LIMIT`.
 *
 * @param {object} q key,value pairs supplying additional set of query
 *    parameters to be used for this query.
 * @param {FirstPageCallback} callback
 */
ViewQuery.prototype.firstPage = function(q, callback) {
  var self = this;

  var p = new Paginator(this, this._cb);
  if (typeof q === 'function') {
    callback = arguments[0];
    q = {};
  }
  var qn = extend( extend({}, this.q), normalizeQuery(q) );
  if (qn.limit === undefined) {
    this.q.limit = qn.limit = DEFAULT_LIMIT;
  }
  qn.limit += 1;

  function startPage(err, results) {
    if (results) {
      if (results.length > 0) {
        p._prevkey = results[0].key;
        p._prevkey_docid = results[0].id;
      }
      if (results.length >= qn.limit) {
        var x = results.pop();
        p._nextkey = x.key;
        p._nextkey_docid = x.id;
      } else {
        p._nextkey = null;
        p._nextkey_docid = null;
      }
    }
    callback.call(self._cb, err, results, p);
  }

  this._request(qn, startPage);
};

/**
 * HTTP query request.
 *
 * @private
 * @ignore
 */
ViewQuery.prototype._request = function(q, callback) {
  this._cb._view(this.ddoc, this.name, q, callback);
};

module.exports = ViewQuery;
<commit_msg>Updated query normalization to avoid trampling user object.<commit_after>'use strict';

var DEFAULT_LIMIT = 10;

function extend(dest, src) {
  for (var k in src) {
    if (src.hasOwnProperty(k)) {
      dest[k] = src[k];
    }
  }
  return dest;
}

var ViewFields = ['descending', 'endkey', 'endkey_docid',
  'full_set', 'group', 'group_level', 'inclusive_end',
  'include_docs',
  'key', 'keys', 'limit', 'on_error', 'reduce', 'skip',
  'stale', 'startkey', 'startkey_docid'];
var JsonFields = ['endkey', 'key', 'keys', 'startkey'];

function normalizeQuery(query) {
  var queryOut = {};
  for (var q in query) {
    if (query.hasOwnProperty(q)) {
      if (JsonFields.indexOf(q) >= 0) {
        queryOut[q] = JSON.stringify(query[q]);
      } else if (ViewFields.indexOf(q) >= 0) {
        queryOut[q] = query[q];
      }
    }
  }
  return queryOut;
}

/**
 * @class Paginator
 * @classdesc
 * A class used to handle pagination of view result sets.  This class is
 * instantiated by using the {@link ViewQuery#firstPage} method.
 *
 * @private
 */

/**
 * @constructor
 *
 * @param {object} qobj
 * The ViewQuery instance this paginator should operate on.
 * @param {object} cb
 * The Couchbase object to use to execute operations.
 *
 * @private
 * @ignore
 */
function Paginator(qobj, cb) {
  this._prevkey = null;
  this._nextkey = null;
  this._prevkey_docid = null;
  this._nextkey_docid = null;
  this._prevpages = [];
  this._qobj = qobj;
  this._cb = cb;
}

/**
 * local callback, that will adjust startkey_docid and endkey_docid before
 * supplying the results to the application callback.
 *
 * @private
 * @ignore
 */
Paginator.prototype._paginate = function(err, results, callback) {
  if (results) {
    if (results.length > 0) {
      if (this._prevkey !== null && this._prevkey_docid !== null ) {
        this._prevpages.push([this._prevkey, this._prevkey_docid]);
      }
      this._prevkey = results[0].key;
      this._prevkey_docid = results[0].id;
    }
    if (results.length > this._qobj.q.limit) {
      var x = results.pop();
      this._nextkey = x.key;
      this._nextkey_docid = x.id;
    } else {
      this._nextkey = null;
      this._nextkey_docid = null;
    }
  }
  callback.call( this._cb, err, results === null ? [] : results );
};

/**
 * Check whether a next page for result set is available.
 *
 * @returns {boolean} Whether another page is available
 */
Paginator.prototype.hasNext = function() {
  return this._nextkey !== null;
};

/**
 * Retrieves the next set of results.
 *
 * @param {QueryCallback} callback
 * The callback to invoke once the page of results is available.
 */
Paginator.prototype.next = function(callback) {
  if (this._nextkey && this._nextkey_docid) {
    var q = extend(extend({}, this._qobj.q),{
      startkey: JSON.stringify(this._nextkey),
      startkey_docid: JSON.stringify(this._nextkey_docid)
    });
    var p = this;
    var paginate_ = function(err, results) {
      p._paginate.call(p, err, results, callback);
    };
    q.limit += 1;
    this._qobj._request(q, paginate_);

  } else {
    this._paginate.call(this, null, [], callback);
  }
  return this;
};

/**
 * Retrieves the previous set of results.
 *
 * @param {QueryCallback} callback
 * The callback to invoke once the page of results is available.
 */
Paginator.prototype.prev = function(callback) {
  if( this._prevpages.length === 0 ) {
    this._paginate.call(this, null, null, callback);
  } else {
    var nk = this._prevpages.pop();
    var p = this;
    var paginate_ = function(err, results) {
      p._prevkey = null;
      p._prevkey_docid = null;
      p._paginate.call(p, err, results, callback);
    };
    var q = extend(extend({}, this._qobj.q), {
      startkey: JSON.stringify(nk[0]),
      startkey_docid: JSON.stringify(nk[1])
    });
    q.limit += 1;
    this._qobj._request(q, paginate_);
  }
  return this;
};

/**
 * @class ViewQuery
 * @classdesc
 * A class used to execute view queries.  This class is instantiated by using
 * the {@link Connection#view} method.
 *
 * @private
 */

/**
 * @constructor
 *
 * @param {object} cb connection object.
 * @param {string} ddoc name of design-document containing the view.
 * @param {string} name view name on which to apply this query.
 * @param {object} params key,value pairs supplying the initial set of query
 *    parameters to be used for subsequent queries. This can be
 *    overriden while calling clone() and query() on this instance.
 *
 * @private

 */
function ViewQuery(cb, ddoc, name, params) {
  this._cb = cb;
  this.ddoc = ddoc;
  this.name = name;
  this.q = normalizeQuery( params === undefined ? {} : params );
}

/**
 * Query callback.
 * This callback is invoked by the query operations.
 *
 * @typedef {function} QueryCallback
 *
 * @param {undefined|Error} error
 *  An error indicator. Note that this error
 *  value may be ignored, but its absence is indicative that the
 *  response in the results parameter is ok. If it
 *  is set, then the request failed.
 * @param {object} results
 *  The results returned from the server
 * @param {object} misc
 *  @param {integer} misc.total_rows
 *  The total number of rows available in the view.
 */

/**
 * FirstPage query callback.
 * This callback is invoked by the firstPage query operation.
 *
 * @typedef {function} FirstPageCallback
 *
 * @param {undefined|Error} error
 *  An error indicator. Note that this error
 *  value may be ignored, but its absence is indicative that the
 *  response in the results parameter is ok. If it
 *  is set, then the request failed.
 * @param {object} results
 *  The results returned from the server
 * @param {Paginator} paginator
 *   The paginator for paged iteration through the view
 */

/**
 * Query for result set.
 *
 * @param {object} q key,value pairs supplying additional set of query
 *    parameters to be used for this queries.
 * @param {QueryCallback} callback
 */
ViewQuery.prototype.query = function(q, callback) {
  if (typeof q === 'function') {
    callback = arguments[0];
    q = {};
  }
  var qe = extend( extend({}, this.q), normalizeQuery(q) );
  this._request(qe, callback);
  return this;
};

/**
 * Clone this query instance, with a new set of initial parameters overriding
 * current set.
 *
 * @private
 * @ignore
 *
 * @param {object} cparams key,value pairs supplying a new set of query
 *    parameters, to be used for subsequent queries.
 */
ViewQuery.prototype.clone = function( cparams ) {
  var newq = new ViewQuery( this._cb, this.ddoc, this.name, {} );
  newq.q = extend( extend({}, this.q), normalizeQuery(cparams) );
  return newq;
};

/**
 * Get the first page of query's result set, along with a paginator instance.
 * subsequently paginator.next(), and paginator.prev() can be used to navigate
 * within result set.
 *
 * Maximum number of entries in each page is determined by query's `limit`
 * parameter or `DEFAULT_LIMIT`.
 *
 * @param {object} q key,value pairs supplying additional set of query
 *    parameters to be used for this query.
 * @param {FirstPageCallback} callback
 */
ViewQuery.prototype.firstPage = function(q, callback) {
  var self = this;

  var p = new Paginator(this, this._cb);
  if (typeof q === 'function') {
    callback = arguments[0];
    q = {};
  }
  var qn = extend( extend({}, this.q), normalizeQuery(q) );
  if (qn.limit === undefined) {
    this.q.limit = qn.limit = DEFAULT_LIMIT;
  }
  qn.limit += 1;

  function startPage(err, results) {
    if (results) {
      if (results.length > 0) {
        p._prevkey = results[0].key;
        p._prevkey_docid = results[0].id;
      }
      if (results.length >= qn.limit) {
        var x = results.pop();
        p._nextkey = x.key;
        p._nextkey_docid = x.id;
      } else {
        p._nextkey = null;
        p._nextkey_docid = null;
      }
    }
    callback.call(self._cb, err, results, p);
  }

  this._request(qn, startPage);
};

/**
 * HTTP query request.
 *
 * @private
 * @ignore
 */
ViewQuery.prototype._request = function(q, callback) {
  this._cb._view(this.ddoc, this.name, q, callback);
};

module.exports = ViewQuery;
<|endoftext|>