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

'use strict';

var fs = require('fs');
var path = require('path');
var program = require('commander');
var mkdirp = require('mkdirp');
var chalk = require('chalk');
var jade = require('jade');

var basename = path.basename;
var dirname = path.dirname;
var resolve = path.resolve;
var normalize = path.normalize;
var join = path.join;

// jade options

var options = {};

// options

program
  .version(
    'jade version: '     + require('jade/package.json').version + '\n' +
    'jade-cli version: ' + require(   './package.json').version
  )
  .usage('[options] [dir|file ...]')
  .option('-O, --obj <str|path>', 'JSON/JavaScript options object or file')
  .option('-o, --out <dir>', 'output the rendered HTML or compiled JavaScript to <dir>')
  .option('-p, --path <path>', 'filename used to resolve includes')
  .option('-P, --pretty', 'compile pretty html output')
  .option('-c, --client', 'compile function for client-side runtime.js')
  .option('-n, --name <str>', 'the name of the compiled template (requires --client)')
  .option('-D, --no-debug', 'compile without debugging (smaller functions)')
  .option('-w, --watch', 'watch files for changes and automatically re-render')
  .option('-E, --extension <ext>', 'specify the output file extension')
  .option('-H, --hierarchy', 'keep directory hierarchy when a directory is specified')
  .option('-s, --silent', 'do not output logs')
  .option('--name-after-file', 'name the template after the last section of the file path (requires --client and overriden by --name)')
  .option('--doctype <str>', 'specify the doctype on the command line (useful if it is not specified by the template)')

program.on('--help', function(){
  console.log('  Examples:');
  console.log('');
  console.log('    # Render all files in the `templates` directory:');
  console.log('    $ jade templates');
  console.log('');
  console.log('    # Create {foo,bar}.html:');
  console.log('    $ jade {foo,bar}.jade');
  console.log('');
  console.log('    # Using `jade` over standard input and output streams');
  console.log('    $ jade < my.jade > my.html');
  console.log('    $ echo \'h1 Jade!\' | jade');
  console.log('');
  console.log('    # Render all files in `foo` and `bar` directories to `/tmp`:');
  console.log('    $ jade foo bar --out /tmp');
  console.log('');
});

program.parse(process.argv);

// options given, parse them

if (program.obj) {
  options = parseObj(program.obj);
}

/**
 * Parse object either in `input` or in the file called `input`. The latter is
 * searched first.
 */
function parseObj (input) {
  var str;
  try {
    str = fs.readFileSync(program.obj, 'utf8');
  } catch (e) {
    str = program.obj;
  }
  try {
    return JSON.parse(str);
  } catch (e) {
    return eval('(' + str + ')');
  }
}

// --path

options.filename = program.path || options.filename;

// --no-debug

options.compileDebug = program.debug || options.compileDebug;

// --client

options.client = program.client || options.client;

// --pretty

options.pretty = program.pretty || options.pretty;

// --watch

options.watch = program.watch;

// --name

options.name = program.name || options.name;

// --doctype

options.doctype = program.doctype || options.doctype;

// --hierarchy

if (program.hierarchy) {
  console.warn('`-H`, `--hierarchy` option is redundant now, and will be removed in jade-cli@1.0.0');
}

// --silent

var consoleLog = program.silent ? function() {} : console.log;

// left-over args are file paths

var files = program.args;

// object of reverse dependencies of a watched file, including itself if
// applicable

var watchList = {};

// function for rendering
var render = program.watch ? tryRender : renderFile;

// compile files

if (files.length) {
  consoleLog();
  if (options.watch) {
    process.on('SIGINT', function() {
      process.exit(1);
    });
  }
  files.forEach(function (file) {
    render(file);
  });
// stdio
} else {
  stdin();
}

/**
 * Watch for changes on path
 *
 * Renders `base` if specified, otherwise renders `path`.
 */
function watchFile(path, base, rootPath) {
  path = normalize(path);

  var log = '  ' + chalk.gray('watching') + ' ' + chalk.cyan(path);
  if (!base) {
    base = path;
  } else {
    log += '\n    ' + chalk.gray('as a dependency of') + ' ';
    log += chalk.cyan(base);
  }

  if (watchList[path]) {
    if (watchList[path].indexOf(base) !== -1) return;
    consoleLog(log);
    watchList[path].push(base);
    return;
  }

  consoleLog(log);
  watchList[path] = [base];
  fs.watchFile(path, {persistent: true, interval: 200},
               function (curr, prev) {
    // File doesn't exist anymore. Keep watching.
    if (curr.mtime.getTime() === 0) return;
    // istanbul ignore if
    if (curr.mtime.getTime() === prev.mtime.getTime()) return;
    watchList[path].forEach(function(file) {
      tryRender(file, rootPath);
    });
  });
}

/**
 * Convert error to string
 */
function errorToString(e) {
  return e.stack || /* istanbul ignore next */ (e.message || e);
}

/**
 * Try to render `path`; if an exception is thrown it is printed to stderr and
 * otherwise ignored.
 *
 * This is used in watch mode.
 */
function tryRender(path, rootPath) {
  try {
    renderFile(path, rootPath);
  } catch (e) {
    // keep watching when error occured.
    console.error(errorToString(e));
  }
}

/**
 * Compile from stdin.
 */

function stdin() {
  var buf = '';
  process.stdin.setEncoding('utf8');
  process.stdin.on('data', function(chunk){ buf += chunk; });
  process.stdin.on('end', function(){
    var output;
    if (options.client) {
      output = jade.compileClient(buf, options);
    } else {
      var fn = jade.compile(buf, options);
      var output = fn(options);
    }
    process.stdout.write(output);
  }).resume();

  /* istanbul ignore next */
  process.on('SIGINT', function() {
    process.stdout.write('\n');
    process.stdin.emit('end');
    process.stdout.write('\n');
    process.stderr.write('In jade-cli@1.0.0, SIGINT will no longer signify end of input, and `jade` will exit immediately. If you are using a POSIX shell, this means that you will have to press Control-D (EOF) instead of Control-C.\n');
    process.exit();
  })
}

/**
 * Process the given path, compiling the jade files found.
 * Always walk the subdirectories.
 *
 * @param path      path of the file, might be relative
 * @param rootPath  path relative to the directory specified in the command
 */

function renderFile(path, rootPath) {
  var re = /\.jade$/;
  var stat = fs.lstatSync(path);
  // Found jade file/\.jade$/
  if (stat.isFile() && re.test(path)) {
    // Try to watch the file if needed. watchFile takes care of duplicates.
    if (options.watch) watchFile(path, null, rootPath);
    if (program.nameAfterFile) {
      options.name = getNameFromFileName(path);
    }
    var fn = options.client
           ? jade.compileFileClient(path, options)
           : jade.compileFile(path, options);
    if (options.watch && fn.dependencies) {
      // watch dependencies, and recompile the base
      fn.dependencies.forEach(function (dep) {
        watchFile(dep, path, rootPath);
      });
    }

    // --extension
    var extname;
    if (program.extension)   extname = '.' + program.extension;
    else if (options.client) extname = '.js';
    else                     extname = '.html';

    // path: foo.jade -> foo.<ext>
    path = path.replace(re, extname);
    if (program.out) {
      // prepend output directory
      if (rootPath) {
        // replace the rootPath of the resolved path with output directory
        path = resolve(path).replace(new RegExp('^' + resolve(rootPath)), '');
        path = join(program.out, path);
      } else {
        // old behavior or if no rootPath handling is needed
        path = join(program.out, basename(path));
      }
    }
    var dir = resolve(dirname(path));
    mkdirp.sync(dir);
    var output = options.client ? fn : fn(options);
    fs.writeFileSync(path, output);
    consoleLog('  ' + chalk.gray('rendered') + ' ' + chalk.cyan('%s'), normalize(path));
  // Found directory
  } else if (stat.isDirectory()) {
    var files = fs.readdirSync(path);
    files.map(function(filename) {
      return path + '/' + filename;
    }).forEach(function (file) {
      render(file, rootPath || path);
    });
  }
}

/**
 * Get a sensible name for a template function from a file path
 *
 * @param {String} filename
 * @returns {String}
 */
function getNameFromFileName(filename) {
  var file = basename(filename, '.jade');
  return file.toLowerCase().replace(/[^a-z0-9]+([a-z])/g, function (_, character) {
    return character.toUpperCase();
  }) + 'Template';
}
<commit_msg>Fix setting --name<commit_after>#!/usr/bin/env node

'use strict';

var fs = require('fs');
var path = require('path');
var program = require('commander');
var mkdirp = require('mkdirp');
var chalk = require('chalk');
var jade = require('jade');

var basename = path.basename;
var dirname = path.dirname;
var resolve = path.resolve;
var normalize = path.normalize;
var join = path.join;

// jade options

var options = {};

// options

program
  .version(
    'jade version: '     + require('jade/package.json').version + '\n' +
    'jade-cli version: ' + require(   './package.json').version
  )
  .usage('[options] [dir|file ...]')
  .option('-O, --obj <str|path>', 'JSON/JavaScript options object or file')
  .option('-o, --out <dir>', 'output the rendered HTML or compiled JavaScript to <dir>')
  .option('-p, --path <path>', 'filename used to resolve includes')
  .option('-P, --pretty', 'compile pretty html output')
  .option('-c, --client', 'compile function for client-side runtime.js')
  .option('-n, --name <str>', 'the name of the compiled template (requires --client)')
  .option('-D, --no-debug', 'compile without debugging (smaller functions)')
  .option('-w, --watch', 'watch files for changes and automatically re-render')
  .option('-E, --extension <ext>', 'specify the output file extension')
  .option('-H, --hierarchy', 'keep directory hierarchy when a directory is specified')
  .option('-s, --silent', 'do not output logs')
  .option('--name-after-file', 'name the template after the last section of the file path (requires --client and overriden by --name)')
  .option('--doctype <str>', 'specify the doctype on the command line (useful if it is not specified by the template)')

program.on('--help', function(){
  console.log('  Examples:');
  console.log('');
  console.log('    # Render all files in the `templates` directory:');
  console.log('    $ jade templates');
  console.log('');
  console.log('    # Create {foo,bar}.html:');
  console.log('    $ jade {foo,bar}.jade');
  console.log('');
  console.log('    # Using `jade` over standard input and output streams');
  console.log('    $ jade < my.jade > my.html');
  console.log('    $ echo \'h1 Jade!\' | jade');
  console.log('');
  console.log('    # Render all files in `foo` and `bar` directories to `/tmp`:');
  console.log('    $ jade foo bar --out /tmp');
  console.log('');
});

program.parse(process.argv);

// options given, parse them

if (program.obj) {
  options = parseObj(program.obj);
}

/**
 * Parse object either in `input` or in the file called `input`. The latter is
 * searched first.
 */
function parseObj (input) {
  var str;
  try {
    str = fs.readFileSync(program.obj, 'utf8');
  } catch (e) {
    str = program.obj;
  }
  try {
    return JSON.parse(str);
  } catch (e) {
    return eval('(' + str + ')');
  }
}

// --path

options.filename = program.path || options.filename;

// --no-debug

options.compileDebug = program.debug || options.compileDebug;

// --client

options.client = program.client || options.client;

// --pretty

options.pretty = program.pretty || options.pretty;

// --watch

options.watch = program.watch;

// --name

if (typeof program.name === 'string') {
  options.name = program.name;
}

// --doctype

options.doctype = program.doctype || options.doctype;

// --hierarchy

if (program.hierarchy) {
  console.warn('`-H`, `--hierarchy` option is redundant now, and will be removed in jade-cli@1.0.0');
}

// --silent

var consoleLog = program.silent ? function() {} : console.log;

// left-over args are file paths

var files = program.args;

// object of reverse dependencies of a watched file, including itself if
// applicable

var watchList = {};

// function for rendering
var render = program.watch ? tryRender : renderFile;

// compile files

if (files.length) {
  consoleLog();
  if (options.watch) {
    process.on('SIGINT', function() {
      process.exit(1);
    });
  }
  files.forEach(function (file) {
    render(file);
  });
// stdio
} else {
  stdin();
}

/**
 * Watch for changes on path
 *
 * Renders `base` if specified, otherwise renders `path`.
 */
function watchFile(path, base, rootPath) {
  path = normalize(path);

  var log = '  ' + chalk.gray('watching') + ' ' + chalk.cyan(path);
  if (!base) {
    base = path;
  } else {
    log += '\n    ' + chalk.gray('as a dependency of') + ' ';
    log += chalk.cyan(base);
  }

  if (watchList[path]) {
    if (watchList[path].indexOf(base) !== -1) return;
    consoleLog(log);
    watchList[path].push(base);
    return;
  }

  consoleLog(log);
  watchList[path] = [base];
  fs.watchFile(path, {persistent: true, interval: 200},
               function (curr, prev) {
    // File doesn't exist anymore. Keep watching.
    if (curr.mtime.getTime() === 0) return;
    // istanbul ignore if
    if (curr.mtime.getTime() === prev.mtime.getTime()) return;
    watchList[path].forEach(function(file) {
      tryRender(file, rootPath);
    });
  });
}

/**
 * Convert error to string
 */
function errorToString(e) {
  return e.stack || /* istanbul ignore next */ (e.message || e);
}

/**
 * Try to render `path`; if an exception is thrown it is printed to stderr and
 * otherwise ignored.
 *
 * This is used in watch mode.
 */
function tryRender(path, rootPath) {
  try {
    renderFile(path, rootPath);
  } catch (e) {
    // keep watching when error occured.
    console.error(errorToString(e));
  }
}

/**
 * Compile from stdin.
 */

function stdin() {
  var buf = '';
  process.stdin.setEncoding('utf8');
  process.stdin.on('data', function(chunk){ buf += chunk; });
  process.stdin.on('end', function(){
    var output;
    if (options.client) {
      output = jade.compileClient(buf, options);
    } else {
      var fn = jade.compile(buf, options);
      var output = fn(options);
    }
    process.stdout.write(output);
  }).resume();

  /* istanbul ignore next */
  process.on('SIGINT', function() {
    process.stdout.write('\n');
    process.stdin.emit('end');
    process.stdout.write('\n');
    process.stderr.write('In jade-cli@1.0.0, SIGINT will no longer signify end of input, and `jade` will exit immediately. If you are using a POSIX shell, this means that you will have to press Control-D (EOF) instead of Control-C.\n');
    process.exit();
  })
}

/**
 * Process the given path, compiling the jade files found.
 * Always walk the subdirectories.
 *
 * @param path      path of the file, might be relative
 * @param rootPath  path relative to the directory specified in the command
 */

function renderFile(path, rootPath) {
  var re = /\.jade$/;
  var stat = fs.lstatSync(path);
  // Found jade file/\.jade$/
  if (stat.isFile() && re.test(path)) {
    // Try to watch the file if needed. watchFile takes care of duplicates.
    if (options.watch) watchFile(path, null, rootPath);
    if (program.nameAfterFile) {
      options.name = getNameFromFileName(path);
    }
    var fn = options.client
           ? jade.compileFileClient(path, options)
           : jade.compileFile(path, options);
    if (options.watch && fn.dependencies) {
      // watch dependencies, and recompile the base
      fn.dependencies.forEach(function (dep) {
        watchFile(dep, path, rootPath);
      });
    }

    // --extension
    var extname;
    if (program.extension)   extname = '.' + program.extension;
    else if (options.client) extname = '.js';
    else                     extname = '.html';

    // path: foo.jade -> foo.<ext>
    path = path.replace(re, extname);
    if (program.out) {
      // prepend output directory
      if (rootPath) {
        // replace the rootPath of the resolved path with output directory
        path = resolve(path).replace(new RegExp('^' + resolve(rootPath)), '');
        path = join(program.out, path);
      } else {
        // old behavior or if no rootPath handling is needed
        path = join(program.out, basename(path));
      }
    }
    var dir = resolve(dirname(path));
    mkdirp.sync(dir);
    var output = options.client ? fn : fn(options);
    fs.writeFileSync(path, output);
    consoleLog('  ' + chalk.gray('rendered') + ' ' + chalk.cyan('%s'), normalize(path));
  // Found directory
  } else if (stat.isDirectory()) {
    var files = fs.readdirSync(path);
    files.map(function(filename) {
      return path + '/' + filename;
    }).forEach(function (file) {
      render(file, rootPath || path);
    });
  }
}

/**
 * Get a sensible name for a template function from a file path
 *
 * @param {String} filename
 * @returns {String}
 */
function getNameFromFileName(filename) {
  var file = basename(filename, '.jade');
  return file.toLowerCase().replace(/[^a-z0-9]+([a-z])/g, function (_, character) {
    return character.toUpperCase();
  }) + 'Template';
}
<|endoftext|>


<commit_before>'use babel';

/* @flow */
import * as fs from 'fs';
import * as path from 'path';
import _ from 'lodash';
import os from 'os';
import { BufferedProcess } from 'atom';
/* flow-include
import type { TextEditor } from 'atom'
*/

export function run(textEditor/* :TextEditor*/) {
  return new Promise((resolve) => {
    let processOutput = `\u001b[1mTester Jest\u001b[0m${os.EOL}`;
    const fileName = textEditor.getPath();
    let outputFilePath = fileName;
    const projectPath = atom.project.relativizePath(fileName)[0];
    let cwd = projectPath;
    if (!(cwd)) {
      cwd = path.dirname(fileName);
    }
    const fileModified = textEditor.isModified();
    if (fileModified) {
      const outputDir = `${atom.getConfigDirPath()}/tester-jest`;
      if (!fs.existsSync(outputDir)) {
        fs.mkdir(outputDir);
      }
      outputFilePath = `${outputDir}/${path.basename(fileName)}`;
      fs.writeFileSync(outputFilePath, textEditor.getText());
    }
    function parseReporterOutput(outputString) {
      let output = '';
      const messages = [];
      _.forEach(_.split(outputString, os.EOL), (line) => {
        try {
          const summary = JSON.parse(line);
          if (_.has(summary, 'testResults[0].assertionResults') && summary.testResults[0].assertionResults.length > 0) {
            _.forEach(summary.testResults[0].assertionResults, (testResult) => {
              textEditor.scan(new RegExp(testResult.title.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&')), (scanResult) => {
                messages.push({
                  state: testResult.status,
                  title: testResult.title,
                  error: _.get(testResult, 'failureMessages[0]'),
                  duration: summary.testResults[0].endTime - summary.testResults[0].startTime,
                  lineNumber: scanResult.row,
                  filePath: outputFilePath,
                });
              });
            });
          }
          // messages.push(outputEvent);
        } catch (e) {
          output += line.toString() + os.EOL;
        }
      });
      return { messages, output };
    }
    const args = _.union([outputFilePath, '--json'], atom.config.get('tester-jest.args'));
    const options = { cwd };
    const jestBinary = atom.config.get('tester-jest.binaryPath');
    const command = jestBinary !== '' ? jestBinary : `${atom.packages.resolvePackagePath('tester-jest')}/node_modules/.bin/jest`;
    processOutput += `\u001b[1mcommand:\u001b[0m ${command} ${args.join(' ')}${os.EOL}`;
    processOutput += `\u001b[1mcwd:\u001b[0m ${cwd}${os.EOL}`;
    const stdout = data => processOutput += data;
    const stderr = data => processOutput += data;
    const exit = () => resolve(parseReporterOutput(processOutput));
    const process = new BufferedProcess({ command, args, options, stdout, stderr, exit });

    process.onWillThrowError((errorObject) => {
      atom.notifications.addError('Tester is unable to locate the jest command. Please ensure process.env.PATH can access jest.');
      console.error('Tester Jest: ', errorObject);
    });
  });
}
<commit_msg>do not test modified file<commit_after>'use babel';

/* @flow */
import * as fs from 'fs';
import * as path from 'path';
import _ from 'lodash';
import os from 'os';
import { BufferedProcess } from 'atom';
/* flow-include
import type { TextEditor } from 'atom'
*/

export function run(textEditor/* :TextEditor*/) {
  return new Promise((resolve) => {
    let processOutput = `\u001b[1mTester Jest\u001b[0m${os.EOL}`;
    const fileName = textEditor.getPath();
    const outputFilePath = fileName;
    const projectPath = atom.project.relativizePath(fileName)[0];
    let cwd = projectPath;
    if (!(cwd)) {
      cwd = path.dirname(fileName);
    }
    // Need find another way for jest :)
    /* const fileModified = textEditor.isModified();
    if (fileModified) {
      const outputDir = `${atom.getConfigDirPath()}/tester-jest`;
      if (!fs.existsSync(outputDir)) {
        fs.mkdir(outputDir);
      }
      outputFilePath = `${outputDir}/${path.basename(fileName)}`;
      fs.writeFileSync(outputFilePath, textEditor.getText());
    }*/
    function parseReporterOutput(outputString) {
      let output = '';
      const messages = [];
      _.forEach(_.split(outputString, os.EOL), (line) => {
        try {
          const summary = JSON.parse(line);
          if (_.has(summary, 'testResults[0].assertionResults') && summary.testResults[0].assertionResults.length > 0) {
            _.forEach(summary.testResults[0].assertionResults, (testResult) => {
              textEditor.scan(new RegExp(testResult.title.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&')), (scanResult) => {
                messages.push({
                  state: testResult.status,
                  title: testResult.title,
                  error: _.get(testResult, 'failureMessages[0]'),
                  duration: summary.testResults[0].endTime - summary.testResults[0].startTime,
                  lineNumber: scanResult.row,
                  filePath: outputFilePath,
                });
              });
            });
          }
          // messages.push(outputEvent);
        } catch (e) {
          output += line.toString() + os.EOL;
        }
      });
      return { messages, output };
    }
    const args = _.union([outputFilePath, '--json'], atom.config.get('tester-jest.args'));
    const options = { cwd };
    const jestBinary = atom.config.get('tester-jest.binaryPath');
    const command = jestBinary !== '' ? jestBinary : `${atom.packages.resolvePackagePath('tester-jest')}/node_modules/.bin/jest`;
    processOutput += `\u001b[1mcommand:\u001b[0m ${command} ${args.join(' ')}${os.EOL}`;
    processOutput += `\u001b[1mcwd:\u001b[0m ${cwd}${os.EOL}`;
    const stdout = data => processOutput += data;
    const stderr = data => processOutput += data;
    const exit = () => resolve(parseReporterOutput(processOutput));
    const process = new BufferedProcess({ command, args, options, stdout, stderr, exit });

    process.onWillThrowError((errorObject) => {
      atom.notifications.addError('Tester is unable to locate the jest command. Please ensure process.env.PATH can access jest.');
      console.error('Tester Jest: ', errorObject);
    });
  });
}
<|endoftext|>


<commit_before>var merge = require('cli-util').merge
  , argparse = require('cli-argparse');

var nor = function(){
  return /(\[no-?\]-?)/;
}

/**
 *  Retrieve a configuration suitable for passing to
 *  the arguments parser.
 */
function getParserConfiguration(target, config) {
  target = target || this;
  config = config || {alias: {}, flags: [], options: []};
  var k, arg, key
    , conf  = this.configure();
  var no = /^\[?no\]?/, nor = nor();
  for(k in target._options) {
    arg = target._options[k];
    if(!arg.isFlag() && !arg.isOption()) {
      continue;
    }
    var names = arg.names().slice(0);
    names.forEach(function(nm, index, arr) {
      arr[index] = nm.replace(nor, '');
    })
    key = arg.key();
    //console.log('key: %s', key);
    if(no.test(key)) {
      // this works around an issue with args such as --noop
      // without the charAt test the id is *op*
      // ensuring the first character is uppercase is akin to
      // checking the declaration was '[no]-'
      if(/^[A-Z]$/.test(key.charAt(2))) {
        key = key.replace(no, '');
        key = key.charAt(0).toLowerCase() + key.slice(1);
      }
      //console.log('final key: %s', key);
    }
    config.alias[names.join(' ')] = key;
    if(arg.isFlag()) {
      config.flags = config.flags.concat(names);
    }else{
      config.options = config.options.concat(names);
    }
  }

  // TODO: sometimes child options have the same keys
  // TODO: as top-level options, these duplicates can be removed
  for(k in target._commands) {
    getParserConfiguration.call(this, target._commands[k], config);
  }

  if(conf.variables && conf.variables.prefix) {
    config.vars = {variables: conf.variables.prefix};
  }

  return config;
}

/**
 *  Parses command line arguments, typically you would want
 *  this to be the first middleware.
 */
module.exports = function() {
  var conf = this.configure();
  return function parser(req, next) {
    var args = req.argv;
    var config = getParserConfiguration.call(this);

    if(typeof conf.parser.configure === 'function') {
      conf.parser.configure.call(this, config);
    }

    var result = argparse(args, config);
    result.keys =
      Object.keys(result.flags)
      .concat(Object.keys(result.options));

    result.all = {};
    merge(result.flags, result.all);
    merge(result.options, result.all);
    result.config = config;
    req.result = result;
    next();
  }
}
<commit_msg>Use regexp directly.<commit_after>var merge = require('cli-util').merge
  , argparse = require('cli-argparse');

/**
 *  Retrieve a configuration suitable for passing to
 *  the arguments parser.
 */
function getParserConfiguration(target, config) {
  target = target || this;
  config = config || {alias: {}, flags: [], options: []};
  var k, arg, key
    , conf  = this.configure();
  var no = /^\[?no\]?/, nor = /(\[no-?\]-?)/;
  for(k in target._options) {
    arg = target._options[k];
    if(!arg.isFlag() && !arg.isOption()) {
      continue;
    }
    var names = arg.names().slice(0);
    names.forEach(function(nm, index, arr) {
      arr[index] = nm.replace(nor, '');
    })
    key = arg.key();
    //console.log('key: %s', key);
    if(no.test(key)) {
      // this works around an issue with args such as --noop
      // without the charAt test the id is *op*
      // ensuring the first character is uppercase is akin to
      // checking the declaration was '[no]-'
      if(/^[A-Z]$/.test(key.charAt(2))) {
        key = key.replace(no, '');
        key = key.charAt(0).toLowerCase() + key.slice(1);
      }
      //console.log('final key: %s', key);
    }
    config.alias[names.join(' ')] = key;
    if(arg.isFlag()) {
      config.flags = config.flags.concat(names);
    }else{
      config.options = config.options.concat(names);
    }
  }

  // TODO: sometimes child options have the same keys
  // TODO: as top-level options, these duplicates can be removed
  for(k in target._commands) {
    getParserConfiguration.call(this, target._commands[k], config);
  }

  if(conf.variables && conf.variables.prefix) {
    config.vars = {variables: conf.variables.prefix};
  }

  return config;
}

/**
 *  Parses command line arguments, typically you would want
 *  this to be the first middleware.
 */
module.exports = function() {
  var conf = this.configure();
  return function parser(req, next) {
    var args = req.argv;
    var config = getParserConfiguration.call(this);

    if(typeof conf.parser.configure === 'function') {
      conf.parser.configure.call(this, config);
    }

    var result = argparse(args, config);
    result.keys =
      Object.keys(result.flags)
      .concat(Object.keys(result.options));

    result.all = {};
    merge(result.flags, result.all);
    merge(result.options, result.all);
    result.config = config;
    req.result = result;
    next();
  }
}
<|endoftext|>


<commit_before>var qpx = modules.export{
  var request = require('request');
  var data = require('./data.json');
  var key = '';
  var endPoint = "https://www.googleapis.com/qpxExpress/v1/trips/search?key="+key;

  api: function(adultCount, maxPrice, solutions, origin, destination, date){

    data.request.passengers.adultCount = adultCount;
    data.request.maxPrice = maxPrice;
    data.request.solutions = solutions;
    data.request.slice[0].origin = origin;
    data.request.slice[0].destination = destination;
    data.request.slice[0].date = date;

    request({method: "post",  url: endPoint,  body: data,  json: true}, function(err, resp, body){

      var info = [];
      var jsonObject = {};
      var airline;
      var price;

      if (body.error){
        return console.error(body.error);
      } else {
        var price= body.trips.tripOption[0].saleTotal;
        if(solutions >= 2){
          for(i=0; i < body.trips.tripOption.length; i++){
            airline = body.trips.tripOption[i].slice[0].segment[0].flight.carrier
            price = body.trips.tripOption[i].saleTotal
            jsonObject = {"airline": airline , "price": price};
            info.push(jsonObject);
          }
          return info;
        } else {
          airline = body.trips.tripOption[0].slice[0].segment[0].flight.carrier
          price = body.trips.tripOption[0].saleTotal
          jsonObject = {"airline": airline, "price":price}
          info.push(jsonObject);
          return info;
        }
      }
    });
  }
}
<commit_msg>fix export<commit_after>modules.export{
  var request = require('request');
  var data = require('./data.json');
  var key = '';
  var endPoint = "https://www.googleapis.com/qpxExpress/v1/trips/search?key="+key;

  api: function(adultCount, maxPrice, solutions, origin, destination, date){

    data.request.passengers.adultCount = adultCount;
    data.request.maxPrice = maxPrice;
    data.request.solutions = solutions;
    data.request.slice[0].origin = origin;
    data.request.slice[0].destination = destination;
    data.request.slice[0].date = date;

    request({method: "post",  url: endPoint,  body: data,  json: true}, function(err, resp, body){

      var info = [];
      var jsonObject = {};
      var airline;
      var price;

      if (body.error){
        return console.error(body.error);
      } else {
        var price= body.trips.tripOption[0].saleTotal;
        if(solutions >= 2){
          for(i=0; i < body.trips.tripOption.length; i++){
            airline = body.trips.tripOption[i].slice[0].segment[0].flight.carrier
            price = body.trips.tripOption[i].saleTotal
            jsonObject = {"airline": airline , "price": price};
            info.push(jsonObject);
          }
          return info;
        } else {
          airline = body.trips.tripOption[0].slice[0].segment[0].flight.carrier
          price = body.trips.tripOption[0].saleTotal
          jsonObject = {"airline": airline, "price":price}
          info.push(jsonObject);
          return info;
        }
      }
    });
  }
}
<|endoftext|>


<commit_before>/* Licensed under the Apache License, Version 2.0. © 2016 Yury Shulaev <yury.shulaev@gmail.com> */
'use strict'

const escapeHtml = require('escape-html');

class SatoriServer {
	constructor() {
		this.html = this.createTagFactories(this.constructor.TAGS);
		Object.assign(this, this.html);
		this.Key = this.constructor.Key;
	}

	createTagFactories(tags, obj) {
		obj = obj || {};
		tags.forEach(tag => {obj[tag] = (modifiers, content) => this.create(tag, modifiers, content)});
		return obj;
	}

	create(tag, modifiers, content) {
		if (modifiers === null || typeof modifiers !== 'object' || modifiers.constructor !== Object) {
			if (content) {
				throw new Error('Invalid arguments');
			}

			content = modifiers;
			modifiers = {};
		}

		let attrs = [];

		if (modifiers.class) {
			attrs.push(this.class(modifiers.class));
		}

		if (modifiers.attr) {
			attrs.push(this.attr(modifiers.attr));
		}

		if (modifiers.data) {
			attrs.push(this.data(modifiers.data));
		}

		if (modifiers.css) {
			attrs.push(this.css(modifiers.css));
		}

		if (modifiers.bind) {
			attrs.push(this.bind(modifiers.bind, modifiers));
		}

		if (modifiers.list) {
			content = this.list(modifiers.list);
		}

		content = this.getValue(content != null ? content : modifiers.content);
		let hasContent = content != null;
		let contentSafe;

		if (hasContent) {
			if (content instanceof Array) {
				contentSafe = content.map(conditionalEscape).join('');
			} else {
				contentSafe = conditionalEscape(content);
			}
		}

		return new SafeString('<' + tag + (attrs.length ? ' ' + attrs.join(' ') : '') +
			(hasContent ? '>' + contentSafe + '</' + tag + '>' : '/>'));
	}

	class(classes) {
		let classesStr = '';

		if (typeof classes !== 'object') {
			classesStr += escapeHtml(classes);
		} else if (classes instanceof Array) {
			classesStr = escapeHtml(classes.join(' '));
		} else {
			for (let cls in classes) {
				if (this.getValue(classes[cls])) {
					classesStr += (classesStr ? ' ' : '') + escapeHtml(cls);
				}
			}
		}

		return classesStr ? 'class="' + classesStr + '"' : '';
	}

	attr(attrs) {
		let attrsStr = '';

		for (let attr in attrs) {
			let value = this.getValue(attrs[attr]);

			if (value != null && value !== false) {
				attrsStr += (attrsStr ? ' ' : '') + escapeHtml(attr) + '="' + escapeHtml(value) + '"';
			}
		}

		return attrsStr;
	}

	data(data) {
		let dataStr = '';

		for (let key in data) {
			let value = this.getValue(data[key]);

			if (value != null && value !== false) {
				dataStr += (dataStr ? ' ' : '') + 'data-' + escapeHtml(key) + '="' + escapeHtml(value) + '"';
			}
		}

		return dataStr;
	}

	css(css) {
		let cssStr = '';

		for (let key in css) {
			let value = this.getValue(css[key]);

			if (value != null && value !== false) {
				cssStr += (cssStr ? ' ' : '') + escapeHtml(key) + ': ' + escapeHtml(value) + ';';
			}
		}

		return cssStr ? 'style="' + cssStr + '"' : '';
	}

	bind(bind, mods) {
		let to = bind.to || (mods.attr && mods.attr.type === 'checkbox' ? 'checked' : 'value');
		let value = bind.model[bind.key];
		return this.attr({[to]: () => value === true ? '' : value});
	}

	list(params) {
		let array = this.getValue(params.array);
		return array ? array.map(params.item) : [];
	}

	getValue(value) {
		return typeof value === 'function' ? value() : value;
	}

	proxy(obj) {
		return obj;
	}

	unproxy(obj) {
		return obj;
	}

	observer(name, func) {
		func();
	}

	inputKeyHandler() {
	}

	sortCompare(a, b) {
		return a !== b ? +(a > b) || -1 : 0;
	}

	pluralize(word, count) {
		return word + (count !== 1 ? 's' : '');
	}
}

function conditionalEscape(str) {
	return str instanceof SafeString ? str.value : escapeHtml(str);
}

class SafeString {
	constructor(value) {
		this.value = value;
	}

	toString() {
		return this.value;
	}
}

// todo: Reuse between client-side and server-side implementations
SatoriServer.TAGS = [
	'html', 'head', 'body', 'meta', 'title', 'link', 'script', 'div', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
	'ul', 'li', 'strong', 'em', 'a', 'p', 'br', 'section', 'header', 'footer', 'nav', 'article', 'img',
	'table', 'thead', 'tbody', 'tfoot', 'tr', 'td', 'hr', 'form', 'fieldset', 'button', 'input', 'label', 'select', 'option',
	'textarea', 'blockquote', 'pre', 'code', 'sub', 'sup', 'abbr', 'audio', 'video', 'canvas', 'dl', 'dd', 'dt', 'kbd',
];

SatoriServer.Key = {};

module.exports = {SatoriServer};
<commit_msg>Rename a variable<commit_after>/* Licensed under the Apache License, Version 2.0. © 2016 Yury Shulaev <yury.shulaev@gmail.com> */
'use strict'

const escapeHtml = require('escape-html');

class SatoriServer {
	constructor() {
		this.html = this.createTagFactories(this.constructor.TAGS);
		Object.assign(this, this.html);
		this.Key = this.constructor.Key;
	}

	createTagFactories(tags, obj) {
		obj = obj || {};
		tags.forEach(tag => {obj[tag] = (modifiers, content) => this.create(tag, modifiers, content)});
		return obj;
	}

	create(tag, modifiers, content) {
		if (modifiers === null || typeof modifiers !== 'object' || modifiers.constructor !== Object) {
			if (content) {
				throw new Error('Invalid arguments');
			}

			content = modifiers;
			modifiers = {};
		}

		let attrs = [];

		if (modifiers.class) {
			attrs.push(this.class(modifiers.class));
		}

		if (modifiers.attr) {
			attrs.push(this.attr(modifiers.attr));
		}

		if (modifiers.data) {
			attrs.push(this.data(modifiers.data));
		}

		if (modifiers.css) {
			attrs.push(this.css(modifiers.css));
		}

		if (modifiers.bind) {
			attrs.push(this.bind(modifiers.bind, modifiers));
		}

		if (modifiers.list) {
			content = this.list(modifiers.list);
		}

		content = this.getValue(content != null ? content : modifiers.content);
		let hasContent = content != null;
		let escapedContent;

		if (hasContent) {
			if (content instanceof Array) {
				escapedContent = content.map(conditionalEscape).join('');
			} else {
				escapedContent = conditionalEscape(content);
			}
		}

		return new SafeString('<' + tag + (attrs.length ? ' ' + attrs.join(' ') : '') +
			(hasContent ? '>' + escapedContent + '</' + tag + '>' : '/>'));
	}

	class(classes) {
		let classesStr = '';

		if (typeof classes !== 'object') {
			classesStr += escapeHtml(classes);
		} else if (classes instanceof Array) {
			classesStr = escapeHtml(classes.join(' '));
		} else {
			for (let cls in classes) {
				if (this.getValue(classes[cls])) {
					classesStr += (classesStr ? ' ' : '') + escapeHtml(cls);
				}
			}
		}

		return classesStr ? 'class="' + classesStr + '"' : '';
	}

	attr(attrs) {
		let attrsStr = '';

		for (let attr in attrs) {
			let value = this.getValue(attrs[attr]);

			if (value != null && value !== false) {
				attrsStr += (attrsStr ? ' ' : '') + escapeHtml(attr) + '="' + escapeHtml(value) + '"';
			}
		}

		return attrsStr;
	}

	data(data) {
		let dataStr = '';

		for (let key in data) {
			let value = this.getValue(data[key]);

			if (value != null && value !== false) {
				dataStr += (dataStr ? ' ' : '') + 'data-' + escapeHtml(key) + '="' + escapeHtml(value) + '"';
			}
		}

		return dataStr;
	}

	css(css) {
		let cssStr = '';

		for (let key in css) {
			let value = this.getValue(css[key]);

			if (value != null && value !== false) {
				cssStr += (cssStr ? ' ' : '') + escapeHtml(key) + ': ' + escapeHtml(value) + ';';
			}
		}

		return cssStr ? 'style="' + cssStr + '"' : '';
	}

	bind(bind, mods) {
		let to = bind.to || (mods.attr && mods.attr.type === 'checkbox' ? 'checked' : 'value');
		let value = bind.model[bind.key];
		return this.attr({[to]: () => value === true ? '' : value});
	}

	list(params) {
		let array = this.getValue(params.array);
		return array ? array.map(params.item) : [];
	}

	getValue(value) {
		return typeof value === 'function' ? value() : value;
	}

	proxy(obj) {
		return obj;
	}

	unproxy(obj) {
		return obj;
	}

	observer(name, func) {
		func();
	}

	inputKeyHandler() {
	}

	sortCompare(a, b) {
		return a !== b ? +(a > b) || -1 : 0;
	}

	pluralize(word, count) {
		return word + (count !== 1 ? 's' : '');
	}
}

function conditionalEscape(str) {
	return str instanceof SafeString ? str.value : escapeHtml(str);
}

class SafeString {
	constructor(value) {
		this.value = value;
	}

	toString() {
		return this.value;
	}
}

// todo: Reuse between client-side and server-side implementations
SatoriServer.TAGS = [
	'html', 'head', 'body', 'meta', 'title', 'link', 'script', 'div', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
	'ul', 'li', 'strong', 'em', 'a', 'p', 'br', 'section', 'header', 'footer', 'nav', 'article', 'img',
	'table', 'thead', 'tbody', 'tfoot', 'tr', 'td', 'hr', 'form', 'fieldset', 'button', 'input', 'label', 'select', 'option',
	'textarea', 'blockquote', 'pre', 'code', 'sub', 'sup', 'abbr', 'audio', 'video', 'canvas', 'dl', 'dd', 'dt', 'kbd',
];

SatoriServer.Key = {};

module.exports = {SatoriServer};
<|endoftext|>


<commit_before>if (process.env.NODE_ENV === 'production') {
    var smm = require("./legacy/main.js");
    module.exports = {
        loadSave: smm.loadSave,
        loadSaveSync: smm.loadSaveSync,
        loadImage: smm.loadImage,
        loadCourse: smm.loadCourse,
        loadCourseSync: smm.loadCourseSync
    };
} else {
    let smm = require("./src/main.js");
    module.exports = {
        loadSave: smm.loadSave,
        loadSaveSync: smm.loadSaveSync,
        loadImage: smm.loadImage,
        loadCourse: smm.loadCourse,
        loadCourseSync: smm.loadCourseSync
    };
}<commit_msg>prod/dev split<commit_after>let isProd = true;
try {
    require("babel-polyfill");
} catch (err) {
    isProd = false;
}
//if (process.env.NODE_ENV === 'production') {
if (isProd) {
    var smm = require("./legacy/main.js");
    module.exports = {
        loadSave: smm.loadSave,
        loadSaveSync: smm.loadSaveSync,
        loadImage: smm.loadImage,
        loadCourse: smm.loadCourse,
        loadCourseSync: smm.loadCourseSync
    };
} else {
    let smm = require("./src/main.js");
    module.exports = {
        loadSave: smm.loadSave,
        loadSaveSync: smm.loadSaveSync,
        loadImage: smm.loadImage,
        loadCourse: smm.loadCourse,
        loadCourseSync: smm.loadCourseSync
    };
}<|endoftext|>


<commit_before>var fs = require('fs'), path = require('path');

var getExtension = function(filename) {
	var i = filename.lastIndexOf('.');
	return (i < 0) ? '' : filename.substr(i);
}

var mkdir = function(path){
    try{
        fs.mkdirSync(path);
    } catch(e){
        if(e.code != 'EEXIST'){
            throw e;
        }
    }
}

var audio = ["MP3", "WAV", "WMA", "MKA", "AAC", "MID", "RA", "RAM", "RM", "OGG"];
var code = ["CPP", "RB", "PY", "HTML", "CSS", "JS"];
var compressed = ["RAR", "JAR", "ZIP", "TAR", "MAR", "ISO", "LZ", "7ZIP", "TGZ", "GZ", "BZ2"];
var docs = ["DOC", "DOCX", "PPT", "PPTX", "PAGES", "PDF", "ODT", "ODP", "XLSX", "XLS", "ODS", "TXT", "IN", "OUT", "MD"];
var images = ["JPG", "JPEG", "GIF", "PNG", "SVG"];
var sys_files = ["DEB", "EXE", "SH", "BUNDLE"];
var video = ["FLV", "WMV", "MOV", "MP4", "MPEG", "3GP", "MKV"];

var formats = {
    "Music": audio,
    "Codes": code,
    "Compressed": compressed,
    "Documents": docs,
    "Images": images,
    "System Files": sys_files,
    "Video": video
};
var fileNames = fs.readdirSync(__dirname);

for (var i = 0; i < fileNames.length; i++) {
    var fileExtension = getExtension(fileNames[i]).toUpperCase();
	console.log(fileExtension);
}<commit_msg>Directories creation added<commit_after>var fs = require('fs'), path = require('path');

var getExtension = function (filename) {
	var i = filename.lastIndexOf('.');
	return (i < 0) ? '' : filename.substr(i + 1);
}

var mkdir = function (path) {
	try {
		fs.mkdirSync(path);
	} catch (e) {
		if (e.code != 'EEXIST') {
			throw e;
		}
	}
}

var audio = ["MP3", "WAV", "WMA", "MKA", "AAC", "MID", "RA", "RAM", "RM", "OGG"];
var code = ["CPP", "RB", "PY", "HTML", "CSS", "JS"];
var compressed = ["RAR", "JAR", "ZIP", "TAR", "MAR", "ISO", "LZ", "7ZIP", "TGZ", "GZ", "BZ2"];
var docs = ["DOC", "DOCX", "PPT", "PPTX", "PAGES", "PDF", "ODT", "ODP", "XLSX", "XLS", "ODS", "TXT", "IN", "OUT", "MD"];
var images = ["JPG", "JPEG", "GIF", "PNG", "SVG"];
var sys_files = ["DEB", "EXE", "SH", "BUNDLE"];
var video = ["FLV", "WMV", "MOV", "MP4", "MPEG", "3GP", "MKV"];

var formats = {
	"Music" : audio,
	"Codes" : code,
	"Compressed" : compressed,
	"Documents" : docs,
	"Images" : images,
	"System Files" : sys_files,
	"Video" : video
};
var fileNames = fs.readdirSync(__dirname);

for (var i = 0; i < fileNames.length; i++) {
	var fileExtension = getExtension(fileNames[i]).toUpperCase();
	for (var type in formats) {
		if (formats.hasOwnProperty(type) && formats[type].indexOf(fileExtension) >= 0) {
			var path = __dirname + '/' + type;
			mkdir(path);
			/*mv(__dirname+'/'+fileNames[i],path+'/'+fileNames[i],function(err){
			if(err){
			console.log("Couldn't move "+fileNames[i]+" because of following error: "+ err);
			}
			});*/
		}
	}
	console.log(fileExtension);
}<|endoftext|>


<commit_before>module.exports = stringify
stringify.default = stringify
stringify.stable = deterministicStringify
stringify.stableStringify = deterministicStringify

const arr = []

// Regular stringify
function stringify (obj, replacer, spacer) {
  decirc(obj, '', [], undefined)
  const res = JSON.stringify(obj, replacer, spacer)
  while (arr.length !== 0) {
    var part = arr.pop()
    part[0][part[1]] = part[2]
  }
  return res
}
function decirc (val, k, stack, parent) {
  var i
  if (typeof val === 'object' && val !== null) {
    for (i = 0; i < stack.length; i++) {
      if (stack[i] === val) {
        parent[k] = '[Circular]'
        arr.push([parent, k, val])
        return
      }
    }
    stack.push(val)
    // Optimize for Arrays. Big arrays could kill the performance otherwise!
    if (Array.isArray(val)) {
      for (i = 0; i < val.length; i++) {
        decirc(val[i], i, stack, val)
      }
    } else {
      const keys = Object.keys(val)
      for (i = 0; i < keys.length; i++) {
        var key = keys[i]
        decirc(val[key], key, stack, val)
      }
    }
    stack.pop()
  }
}

// Stable-stringify
function compareFunction (a, b) {
  if (a < b) {
    return -1
  }
  if (a > b) {
    return 1
  }
  return 0
}

function deterministicStringify (obj, replacer, spacer) {
  const tmp = deterministicDecirc(obj, '', [], undefined) || obj
  const res = JSON.stringify(tmp, replacer, spacer)
  while (arr.length !== 0) {
    var part = arr.pop()
    part[0][part[1]] = part[2]
  }
  return res
}

function deterministicDecirc (val, k, stack, parent) {
  var i
  if (typeof val === 'object' && val !== null) {
    for (i = 0; i < stack.length; i++) {
      if (stack[i] === val) {
        parent[k] = '[Circular]'
        arr.push([parent, k, val])
        return
      }
    }
    if (typeof val.toJSON === 'function') {
      return
    }
    stack.push(val)
    // Optimize for Arrays. Big arrays could kill the performance otherwise!
    if (Array.isArray(val)) {
      for (i = 0; i < val.length; i++) {
        deterministicDecirc(val[i], i, stack, val)
      }
    } else {
      // Create a temporary object in the required way
      const tmp = {}
      const keys = Object.keys(val).sort(compareFunction)
      for (i = 0; i < keys.length; i++) {
        var key = keys[i]
        deterministicDecirc(val[key], key, stack, val)
        tmp[key] = val[key]
      }
      if (parent !== undefined) {
        arr.push([parent, k, val])
        parent[k] = tmp
      } else {
        return tmp
      }
    }
    stack.pop()
  }
}
<commit_msg>replace const with var to make it work anywhere<commit_after>module.exports = stringify
stringify.default = stringify
stringify.stable = deterministicStringify
stringify.stableStringify = deterministicStringify

var arr = []

// Regular stringify
function stringify (obj, replacer, spacer) {
  decirc(obj, '', [], undefined)
  var res = JSON.stringify(obj, replacer, spacer)
  while (arr.length !== 0) {
    var part = arr.pop()
    part[0][part[1]] = part[2]
  }
  return res
}
function decirc (val, k, stack, parent) {
  var i
  if (typeof val === 'object' && val !== null) {
    for (i = 0; i < stack.length; i++) {
      if (stack[i] === val) {
        parent[k] = '[Circular]'
        arr.push([parent, k, val])
        return
      }
    }
    stack.push(val)
    // Optimize for Arrays. Big arrays could kill the performance otherwise!
    if (Array.isArray(val)) {
      for (i = 0; i < val.length; i++) {
        decirc(val[i], i, stack, val)
      }
    } else {
      var keys = Object.keys(val)
      for (i = 0; i < keys.length; i++) {
        var key = keys[i]
        decirc(val[key], key, stack, val)
      }
    }
    stack.pop()
  }
}

// Stable-stringify
function compareFunction (a, b) {
  if (a < b) {
    return -1
  }
  if (a > b) {
    return 1
  }
  return 0
}

function deterministicStringify (obj, replacer, spacer) {
  var tmp = deterministicDecirc(obj, '', [], undefined) || obj
  var res = JSON.stringify(tmp, replacer, spacer)
  while (arr.length !== 0) {
    var part = arr.pop()
    part[0][part[1]] = part[2]
  }
  return res
}

function deterministicDecirc (val, k, stack, parent) {
  var i
  if (typeof val === 'object' && val !== null) {
    for (i = 0; i < stack.length; i++) {
      if (stack[i] === val) {
        parent[k] = '[Circular]'
        arr.push([parent, k, val])
        return
      }
    }
    if (typeof val.toJSON === 'function') {
      return
    }
    stack.push(val)
    // Optimize for Arrays. Big arrays could kill the performance otherwise!
    if (Array.isArray(val)) {
      for (i = 0; i < val.length; i++) {
        deterministicDecirc(val[i], i, stack, val)
      }
    } else {
      // Create a temporary object in the required way
      var tmp = {}
      var keys = Object.keys(val).sort(compareFunction)
      for (i = 0; i < keys.length; i++) {
        var key = keys[i]
        deterministicDecirc(val[key], key, stack, val)
        tmp[key] = val[key]
      }
      if (parent !== undefined) {
        arr.push([parent, k, val])
        parent[k] = tmp
      } else {
        return tmp
      }
    }
    stack.pop()
  }
}
<|endoftext|>


<commit_before>require('dotenv').config();

const debug = require('debug')('index');
const net = require('net');
const he = require('he');
const slack = require('slack');
const storage = require('node-persist');
const qna = require('./qna');
const sheets = require('./sheets');

const bot = slack.rtm.client();

let botUser = null;
let kbId = null;

/**
 * Extracts a question & answer pair from a message.
 *
 * @param {string} messageText Message text.
 * @returns {array} An array of form [question, answer].
 */
function getQnAPair(messageText) {
  const answerIndex = messageText.indexOf('A:');
  if (answerIndex > 0 && messageText.indexOf('Q:') === 0) {
    const question = messageText.substring(2, answerIndex).trim();
    const answer = messageText.substring(answerIndex + 2).trim();
    return [question, answer];
  }
}

/**
 * Creates a new knowledge base from Google Sheets.
 */
async function createKnowledgeBaseFromSheets() {
  const sheet = await sheets.read();
  const qnaPairs = sheet.values.map(row => {
    return {
      question: row[0],
      answer: row[1],
    };
  });
  if (kbId) {
    await qna.deleteKnowledgeBase(kbId);
    storage.removeItemSync('kbId');
  }
  kbId = await qna.createKnowledgeBase('k9bot', qnaPairs);
  storage.setItemSync('kbId', kbId);
}

/**
 * Makes the bot send a message to a Slack channel.
 *
 * @param {string} channel Channel to post the message in.
 * @param {string} text The message text.
 * @returns {Promise} A promise of a response object.
 */
function say(channel, text) {
  return new Promise(resolve =>
    slack.chat.postMessage(
      {
        token: process.env.BOT_TOKEN,
        channel,
        text,
        as_user: true,
      },
      resolve
    )
  );
}

/**
 * Given a message on Slack, executes the appropriate response.
 *
 * @param {string} messageText Message that was sent to the bot, without
 *  the mentions (@botname).
 * @param {string} channel The channel to respond to.
 */
async function processMessage(messageText, channel) {
  const qnaPair = getQnAPair(messageText);
  if (qnaPair) {
    await qna.addAnswer(kbId, qnaPair[0], qnaPair[1], channel);
    bot.postMessage(channel, 'Got it! :dog:');
  } else if (messageText === 'update') {
    debug('updating');
    say(channel, 'Brb, reading up on the latest questions! :books:');
    await createKnowledgeBaseFromSheets();
    say(channel, 'Back! :dog:');
  } else {
    const data = await qna.getAnswer(kbId, messageText);
    postAnswer(data, channel);
  }
}

/**
 * Posts an answer to a channel.
 *
 * @param {Object} data Data returned by `qna.getAnswer()`.
 * @param {string} channel A Slack channel ID.
 */
function postAnswer(data, channel) {
  say(channel, data.score > 0 ? he.decode(data.answer) : 'Woof? :dog:');
}

const isChatMessage = message =>
  message.type === 'message' && Boolean(message.text);
const isBotMessage = message => message.subtype === 'bot_message';
const isDirectMessage = message =>
  message.channel && message.channel[0] === 'D';
const isFromMe = message => message.user === botUser;
const mentionsMe = message =>
  message.text && message.text.indexOf(`<@${botUser}>`) >= 0;
const getTextWithoutMention = message =>
  message.text && message.text.replace(/<.+>/gi, '').trim();

/**
 * Initialisation.
 */
bot.started(async payload => {
  botUser = payload.self.id;
  await storage.init();
  kbId = storage.getItemSync('kbId');
  await createKnowledgeBaseFromSheets();
  debug(`listening for messages..`);
});

/**
 * Message handler.
 */
bot.message(message => {
  if (!kbId) {
    return;
  }
  if (isChatMessage(message) && !isBotMessage(message) && !isFromMe(message)) {
    if (isDirectMessage(message)) {
      debug('I got a direct message:', message);
      processMessage(message.text, message.channel);
    } else if (mentionsMe(message)) {
      debug('I was mentioned in this message:', message);
      processMessage(getTextWithoutMention(message), message.channel);
    }
  }
});

bot.listen({ token: process.env.BOT_TOKEN });
<commit_msg>Added test for the slack connection<commit_after>require('dotenv').config();

const debug = require('debug')('index');
const net = require('net');
const he = require('he');
const slack = require('slack');
const storage = require('node-persist');
const qna = require('./qna');
const sheets = require('./sheets');

const bot = slack.rtm.client();

let botUser = null;
let kbId = null;

/**
 * Extracts a question & answer pair from a message.
 *
 * @param {string} messageText Message text.
 * @returns {array} An array of form [question, answer].
 */
function getQnAPair(messageText) {
  const answerIndex = messageText.indexOf('A:');
  if (answerIndex > 0 && messageText.indexOf('Q:') === 0) {
    const question = messageText.substring(2, answerIndex).trim();
    const answer = messageText.substring(answerIndex + 2).trim();
    return [question, answer];
  }
}

/**
 * Creates a new knowledge base from Google Sheets.
 */
async function createKnowledgeBaseFromSheets() {
  const sheet = await sheets.read();
  const qnaPairs = sheet.values.map(row => {
    return {
      question: row[0],
      answer: row[1],
    };
  });
  if (kbId) {
    await qna.deleteKnowledgeBase(kbId);
    storage.removeItemSync('kbId');
  }
  kbId = await qna.createKnowledgeBase('k9bot', qnaPairs);
  storage.setItemSync('kbId', kbId);
}

/**
 * Makes the bot send a message to a Slack channel.
 *
 * @param {string} channel Channel to post the message in.
 * @param {string} text The message text.
 * @returns {Promise} A promise of a response object.
 */
function say(channel, text) {
  return new Promise(resolve =>
    slack.chat.postMessage(
      {
        token: process.env.BOT_TOKEN,
        channel,
        text,
        as_user: true,
      },
      resolve
    )
  );
}

/**
 * The bot sends a dummy message to Slack to figure out if the connection is
 * still alive
 */
function keepAlive() {
  debug('NA NA NA NA STAYING ALIVE! Staying alive!');
  slack.api.test({ keepAlive: 'will do', error: 'OH NO!' }, (err, data) => {
    if (err) {
      debug('Oh no! Connection lost. Restarting!');
      debug(err);
      createKnowledgeBaseFromSheets();
    }
  });
  setTimeout(keepAlive, 5000);
}

/**
 * Given a message on Slack, executes the appropriate response.
 *
 * @param {string} messageText Message that was sent to the bot, without
 *  the mentions (@botname).
 * @param {string} channel The channel to respond to.
 */
async function processMessage(messageText, channel) {
  const qnaPair = getQnAPair(messageText);
  if (qnaPair) {
    await qna.addAnswer(kbId, qnaPair[0], qnaPair[1], channel);
    bot.postMessage(channel, 'Got it! :dog:');
  } else if (messageText === 'update') {
    debug('updating');
    say(channel, 'Brb, reading up on the latest questions! :books:');
    await createKnowledgeBaseFromSheets();
    say(channel, 'Back! :dog:');
  } else {
    const data = await qna.getAnswer(kbId, messageText);
    postAnswer(data, channel);
  }
}

/**
 * Posts an answer to a channel.
 *
 * @param {Object} data Data returned by `qna.getAnswer()`.
 * @param {string} channel A Slack channel ID.
 */
function postAnswer(data, channel) {
  say(channel, data.score > 0 ? he.decode(data.answer) : 'Woof? :dog:');
}

const isChatMessage = message =>
  message.type === 'message' && Boolean(message.text);
const isBotMessage = message => message.subtype === 'bot_message';
const isDirectMessage = message =>
  message.channel && message.channel[0] === 'D';
const isFromMe = message => message.user === botUser;
const mentionsMe = message =>
  message.text && message.text.indexOf(`<@${botUser}>`) >= 0;
const getTextWithoutMention = message =>
  message.text && message.text.replace(/<.+>/gi, '').trim();

/**
 * Initialisation.
 */
bot.started(async payload => {
  botUser = payload.self.id;
  await storage.init();
  kbId = storage.getItemSync('kbId');
  await createKnowledgeBaseFromSheets();
  debug(`listening for messages..`);
  keepAlive();
});

/**
 * Message handler.
 */
bot.message(message => {
  if (!kbId) {
    return;
  }
  if (isChatMessage(message) && !isBotMessage(message) && !isFromMe(message)) {
    if (isDirectMessage(message)) {
      debug('I got a direct message:', message);
      processMessage(message.text, message.channel);
    } else if (mentionsMe(message)) {
      debug('I was mentioned in this message:', message);
      processMessage(getTextWithoutMention(message), message.channel);
    }
  }
});

bot.listen({ token: process.env.BOT_TOKEN });
<|endoftext|>


<commit_before>var Readable = require('readable-stream').Readable
;

/**
 * Create a new instance of StreamArray
 *
 * @access private
 * @param {Array} list
 */
function StreamArray(list) {
    if (!Array.isArray(list))
        throw new TypeError('First argument must be an Array');

    Readable.call(this, {objectMode:true});

    this._i = 0;
    this._l = list.length;
    this._list = list;
}

StreamArray.prototype = Object.create(Readable.prototype, {constructor: {value: StreamArray}});

/**
 * Read the next item from the source Array and push into NodeJS stream

 * @access protected
 * @desc Read the next item from the source Array and push into NodeJS stream
 * @param {number} size The amount of data to read (ignored)
 */
StreamArray.prototype._read = function(size) {
    this.push(this._i < this._l ? this._list[this._i++] : null);
};

/**
 * Create a new instance of StreamArray
 *
 * @module stream-array
 * @desc Push Array elements through a NodeJS stream
 * @type {function}
 * @param {Array} list An Array of objects, strings, numbers, etc
 */
module.exports = function(list) {
    return new StreamArray(list);
};
<commit_msg>index.js :: 'use strict'<commit_after>'use strict'

var Readable = require('readable-stream').Readable
;

/**
 * Create a new instance of StreamArray
 *
 * @access private
 * @param {Array} list
 */
function StreamArray(list) {
    if (!Array.isArray(list))
        throw new TypeError('First argument must be an Array');

    Readable.call(this, {objectMode:true});

    this._i = 0;
    this._l = list.length;
    this._list = list;
}

StreamArray.prototype = Object.create(Readable.prototype, {constructor: {value: StreamArray}});

/**
 * Read the next item from the source Array and push into NodeJS stream

 * @access protected
 * @desc Read the next item from the source Array and push into NodeJS stream
 * @param {number} size The amount of data to read (ignored)
 */
StreamArray.prototype._read = function(size) {
    this.push(this._i < this._l ? this._list[this._i++] : null);
};

/**
 * Create a new instance of StreamArray
 *
 * @module stream-array
 * @desc Push Array elements through a NodeJS stream
 * @type {function}
 * @param {Array} list An Array of objects, strings, numbers, etc
 */
module.exports = function(list) {
    return new StreamArray(list);
};
<|endoftext|>


<commit_before>const ExtractTextPlugin = require('extract-text-webpack-plugin');
const WriteFilePlugin = require('write-file-webpack-plugin');
const DrupalTemplatePlugin = require('./drupal-templates-webpack-plugin');
const autoprefixer = require('autoprefixer');

const extractCSS = new ExtractTextPlugin('[name].css');

const path = require('path');

const config = {
  entry: {
    app: ['./src/app.js'],
  },
  devtool: '#source-map',
  output: {
    path: path.resolve(process.cwd(), 'assets'),
    publicPath: 'needs-to-be-set',
    filename: 'app.js',
  },
  devServer: {
    inline: true,
    quiet: false,
    noInfo: false,
    stats: {
      assets: false,
      colors: true,
      version: false,
      hash: false,
      timings: false,
      chunks: false,
      chunkModules: false,
    },
    outputPath: path.join(process.cwd(), 'assets'),
    proxy: {
      '*': {
        target: 'http://localhost:3000',
        secure: false,
      },
    },
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015'],
        },
      },
      {
        test: /\.scss$/,
        loader: extractCSS.extract(['css-loader', 'postcss-loader', 'sass-loader']),
      },
      {
        test: /.*\.(gif|png|jpe?g|svg)(\?v=\d+\.\d+\.\d+)?$/i,
        loaders: [
          'url?limit=10000&hash=sha512&digest=hex&name=[hash].[ext]',
          'image-webpack?{progressive:true, optimizationLevel: 7, interlaced: false, pngquant:{quality: "65-90", speed: 4}}',
        ],
      },
      { test: /\.(tpl\.php|html\.twig)$/, loaders: ['file?regExp=.*\/src\/(.*)&name=[1]'] },
      { test: /(\.php|\.twig)$/, loaders: ['null'] },

      { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file' },
      { test: /\.(woff|woff2)$/, loader: 'url?prefix=font/&limit=5000' },
      { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream' },
    ],
  },
  plugins: [
    new WriteFilePlugin({ log: false }),
    new DrupalTemplatePlugin(),
    extractCSS,
  ],
  postcss: () => [autoprefixer],
};

module.exports = config;
<commit_msg>this isnt good enough<commit_after>const ExtractTextPlugin = require('extract-text-webpack-plugin');
const WriteFilePlugin = require('write-file-webpack-plugin');
const DrupalTemplatePlugin = require('./drupal-templates-webpack-plugin');
const autoprefixer = require('autoprefixer');

const extractCSS = new ExtractTextPlugin('[name].css');

const path = require('path');

const config = {
  entry: {
    app: ['./src/app.js'],
  },
  devtool: '#source-map',
  output: {
    path: path.resolve(process.cwd(), 'assets'),
    publicPath: 'needs-to-be-set',
    filename: 'app.js',
  },
  devServer: {
    inline: true,
    quiet: false,
    noInfo: false,
    stats: {
      assets: false,
      colors: true,
      version: false,
      hash: false,
      timings: false,
      chunks: false,
      chunkModules: false,
    },
    outputPath: path.join(process.cwd(), 'assets'),
    proxy: {
      '*': {
        target: 'http://localhost:3000',
        secure: false,
      },
    },
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015'],
        },
      },
      {
        test: /\.scss$/,
        loader: extractCSS.extract(['css-loader', 'postcss-loader', 'sass-loader']),
      },
      {
        test: /.*\.(gif|png|jpe?g|svg)(\?v=\d+\.\d+\.\d+)?$/i,
        loaders: [
          'url?limit=10000&hash=sha512&digest=hex&name=[hash].[ext]',
          'image-webpack?{progressive:true, optimizationLevel: 7, interlaced: false, pngquant:{quality: "65-90", speed: 4}}',
        ],
      },
      { test: /\.(tpl\.php|html\.twig)$/, loaders: ['file?regExp=.*\/src\/(.*)&name=[1]'] },
      { test: /(\.php|\.twig)$/, loaders: ['file?name=pages/[name].[ext]'] },

      { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file' },
      { test: /\.(woff|woff2)$/, loader: 'url?prefix=font/&limit=5000' },
      { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream' },
    ],
  },
  plugins: [
    new WriteFilePlugin({ log: false }),
    new DrupalTemplatePlugin(),
    extractCSS,
  ],
  postcss: () => [autoprefixer],
};

module.exports = config;
<|endoftext|>


<commit_before>/*
 0 system level critical error: hardError
 1 potentially causing user's data loosing error: error
 2 minor annoyance, recoverable error:   logError
 3 user experience causing issues error:  uxError
 4 warning,possible isues but somehow unclear behaviour: warn
 5 store general info about the system working: info
 6 system level debug: debug
 7 local node/service debug: ldebug
 8 user level debug; udebug
 9 development time debug: ddebug
 10 whyLog for code reasoning
 11 testResult to log running tests
 - 'category    ': the field is usable to create indexes for logs. The mandatory field "type" is such ca category but you can add other. One can see ca category
 - 'level'       : number friom 1-9, identify the level of attention that a log entry should get from operations point of view
 - 'time'        : a value that uniquely identifies in time the log. This parameter is mandatory and normally automatically instantiated by core logging functions
 - 'explanation' : part of the description, environment values relevant for values. All parameters have this aspect so you don't declare
 - 'stack'       : describe an execution stack that caused the log entry
 - 'filename'    : path of a file causing or related to the log entry
 - 'key part'    : a set of fields that together create a key (category)
 - 'swarm'       : the current swarm name (SwarmESB specific)
 - 'phase'       : the current phase name (SwarmESB specific)
 - 'mainGroup'   : the type of the addapter  (SwarmESB specific)
 - 'adapter'     : the uid of the current adapter instance ((SwarmESb specific))
 - 'process'     : the uid of a swarm process (or a process) that automatically stick multiple logs entries together
 - 'var args'    : potential variable number of args

 */

exports.init = function(sf){

    var why = require('whys');
    function createDebugRecord(level, type, message, exception, saveStack, args, pos, data,logOnlyCurrentWhyContext){

        var ret = {
                level: level,
                type:type,
                timestamp:(new Date()).getTime(),
                message: message,
                data:data
            };

        if(saveStack){
            var stack = '';
            if(exception){
                stack = exception.stack;
            } else {
                stack  = (new Error()).stack;
            }
            ret.stack = stack;
        }

        if(exception){
            ret.exception = exception;
        }

        if(args){
            var argsArray = [];
            for(var i= pos, len= args.length; i< len; i++)
                ret.args = argsArray;
        }

        if(process.env["RUN_WITH_WHYS"]){
            if(logOnlyCurrentWhyContext) {
                ret['whyLog'] = why.getGlobalCurrentContext().getExecutionSummary();
            }else{
                ret['whyLog'] = why.getAllContexts().map(function (context) {
                    return context.getExecutionSummary()
                });
            }
        }

        try {
            if (system_working_with_SwarmCore_library_do_not_touch_please === true) {
                ret.swarmName = getCurrentSwarm();
                ret.currentUser = getCurrentUser(true);
                ret.tenant = getCurrentTenant(true);
                ret.outletId = getCurrentOutletId(true);
                ret.sessionId = getCurrentSession(true);
                ret.swarmProcess = getCurrentSwarmProcess(true);
                ret.swarmPhase = getCurrentSwarmPhase(true);
            }
        }
        catch(e) {

        }

        return ret;
    }

    sf.logger.addCase('hardError', function(message, exception, args, pos, data){
        sf.logger.record(createDebugRecord(0, 'systemError', message, exception, true,args, pos, data));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase('error', function(message, exception, args, pos, data){
        sf.logger.record(createDebugRecord(1, 'error', message, exception, true, args, pos, data));
    }, [
        {
            'message':'explanation'
        },
        {
            'exception':'exception'
        }
    ]);

    sf.logger.addCase('logError', function(message, exception, args, pos, data){
        sf.logger.record(createDebugRecord(2, 'logError', message, exception, true, args, pos, data));
    }, [
        {
            'message':'explanation'
        },
        {
            'exception':'exception'
        }
    ]);

    sf.logger.addCase('uxError', function(message){
        sf.logger.record(createDebugRecord(3, 'uxError', message, null, false));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase('throttling', function(message){
        sf.logger.record(createDebugRecord(4, 'throttling', message, null, false));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase('warning', function(message){
        sf.logger.record(createDebugRecord(5, 'warning', message,null, false, arguments, 0));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.alias('warn', 'warning');

    sf.logger.addCase('info', function(message){
        sf.logger.record(createDebugRecord(6, 'info', message,null, false, arguments, 0));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase('debug', function(message){
        sf.logger.record(createDebugRecord(7, 'debug', message,null, false, arguments, 0));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase('ldebug', function(message){
        sf.logger.record(createDebugRecord(8, 'ldebug', message, null, false, arguments, 0));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase('udebug', function(message){
        sf.logger.record(createDebugRecord(9, 'udebug', message ,null, false, arguments, 0));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase('devel', function(message){
        sf.logger.record(createDebugRecord(10, 'devel', message, null, false, arguments, 0));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase("logwhy", function(logOnlyCurrentWhyContext){
        sf.logger.record(createDebugRecord(11,'logwhy',undefined,undefined,undefined,undefined,undefined,undefined,logOnlyCurrentWhyContext))
    });

    sf.logger.addCase("recordAssert", function (message, error,showStack){
        sf.logger.record(createDebugRecord(12,'assert',message,error,showStack))
    });
}
<commit_msg>remove hard dependency by whys<commit_after>/*
 0 system level critical error: hardError
 1 potentially causing user's data loosing error: error
 2 minor annoyance, recoverable error:   logError
 3 user experience causing issues error:  uxError
 4 warning,possible isues but somehow unclear behaviour: warn
 5 store general info about the system working: info
 6 system level debug: debug
 7 local node/service debug: ldebug
 8 user level debug; udebug
 9 development time debug: ddebug
 10 whyLog for code reasoning
 11 testResult to log running tests
 - 'category    ': the field is usable to create indexes for logs. The mandatory field "type" is such ca category but you can add other. One can see ca category
 - 'level'       : number friom 1-9, identify the level of attention that a log entry should get from operations point of view
 - 'time'        : a value that uniquely identifies in time the log. This parameter is mandatory and normally automatically instantiated by core logging functions
 - 'explanation' : part of the description, environment values relevant for values. All parameters have this aspect so you don't declare
 - 'stack'       : describe an execution stack that caused the log entry
 - 'filename'    : path of a file causing or related to the log entry
 - 'key part'    : a set of fields that together create a key (category)
 - 'swarm'       : the current swarm name (SwarmESB specific)
 - 'phase'       : the current phase name (SwarmESB specific)
 - 'mainGroup'   : the type of the addapter  (SwarmESB specific)
 - 'adapter'     : the uid of the current adapter instance ((SwarmESb specific))
 - 'process'     : the uid of a swarm process (or a process) that automatically stick multiple logs entries together
 - 'var args'    : potential variable number of args

 */

exports.init = function(sf){

    function createDebugRecord(level, type, message, exception, saveStack, args, pos, data,logOnlyCurrentWhyContext){

        var ret = {
                level: level,
                type:type,
                timestamp:(new Date()).getTime(),
                message: message,
                data:data
            };

        if(saveStack){
            var stack = '';
            if(exception){
                stack = exception.stack;
            } else {
                stack  = (new Error()).stack;
            }
            ret.stack = stack;
        }

        if(exception){
            ret.exception = exception;
        }

        if(args){
            var argsArray = [];
            for(var i= pos, len= args.length; i< len; i++)
                ret.args = argsArray;
        }

        if(global.__global__enable_RUN_WITH_WHYS){
            var why = require('whys');
            if(logOnlyCurrentWhyContext) {
                ret['whyLog'] = why.getGlobalCurrentContext().getExecutionSummary();
            }else{
                ret['whyLog'] = why.getAllContexts().map(function (context) {
                    return context.getExecutionSummary()
                });
            }
        }

        try {
            if (system_working_with_SwarmCore_library_do_not_touch_please === true) {
                ret.swarmName = getCurrentSwarm();
                ret.currentUser = getCurrentUser(true);
                ret.tenant = getCurrentTenant(true);
                ret.outletId = getCurrentOutletId(true);
                ret.sessionId = getCurrentSession(true);
                ret.swarmProcess = getCurrentSwarmProcess(true);
                ret.swarmPhase = getCurrentSwarmPhase(true);
            }
        }
        catch(e) {

        }

        return ret;
    }

    sf.logger.addCase('hardError', function(message, exception, args, pos, data){
        sf.logger.record(createDebugRecord(0, 'systemError', message, exception, true,args, pos, data));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase('error', function(message, exception, args, pos, data){
        sf.logger.record(createDebugRecord(1, 'error', message, exception, true, args, pos, data));
    }, [
        {
            'message':'explanation'
        },
        {
            'exception':'exception'
        }
    ]);

    sf.logger.addCase('logError', function(message, exception, args, pos, data){
        sf.logger.record(createDebugRecord(2, 'logError', message, exception, true, args, pos, data));
    }, [
        {
            'message':'explanation'
        },
        {
            'exception':'exception'
        }
    ]);

    sf.logger.addCase('uxError', function(message){
        sf.logger.record(createDebugRecord(3, 'uxError', message, null, false));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase('throttling', function(message){
        sf.logger.record(createDebugRecord(4, 'throttling', message, null, false));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase('warning', function(message){
        sf.logger.record(createDebugRecord(5, 'warning', message,null, false, arguments, 0));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.alias('warn', 'warning');

    sf.logger.addCase('info', function(message){
        sf.logger.record(createDebugRecord(6, 'info', message,null, false, arguments, 0));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase('debug', function(message){
        sf.logger.record(createDebugRecord(7, 'debug', message,null, false, arguments, 0));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase('ldebug', function(message){
        sf.logger.record(createDebugRecord(8, 'ldebug', message, null, false, arguments, 0));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase('udebug', function(message){
        sf.logger.record(createDebugRecord(9, 'udebug', message ,null, false, arguments, 0));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase('devel', function(message){
        sf.logger.record(createDebugRecord(10, 'devel', message, null, false, arguments, 0));
    }, [
        {
            'message':'explanation'
        }
    ]);

    sf.logger.addCase("logwhy", function(logOnlyCurrentWhyContext){
        sf.logger.record(createDebugRecord(11,'logwhy',undefined,undefined,undefined,undefined,undefined,undefined,logOnlyCurrentWhyContext))
    });

    sf.logger.addCase("recordAssert", function (message, error,showStack){
        sf.logger.record(createDebugRecord(12,'assert',message,error,showStack))
    });
}
<|endoftext|>


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

require('babel-core/register')({
  stage: 0
});
require('./src/rdx');
<commit_msg>fix(index.js) Fix babel register path issue.<commit_after>#!/usr/bin/env node

require('babel-core/register')({
  stage: 0,
  only: [
    /^((?!\/node_modules\/((?!@resistdesign))).)*$/m
  ]
});
require('./src/rdx');
<|endoftext|>


<commit_before>function Texture(gl, width, height) {
    this.gl = gl;
    this.width = width; this.height = height;
    this.texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, this.texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width, height, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, null);

    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
}
Texture.prototype.bind = function (n, program, name) {
    var gl = this.gl;
    gl.activeTexture([gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2][n]);
    gl.bindTexture(gl.TEXTURE_2D, this.texture);
    gl.uniform1i(gl.getUniformLocation(program, name), n);
}
Texture.prototype.fill = function (data) {
    var gl = this.gl;
    gl.bindTexture(gl.TEXTURE_2D, this.texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, this.width, this.height, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, data);
}

function render(canvas, videoFrame) {
    var gl = canvas.gl;
    var len = videoFrame.length;
    videoFrame.y.fill(videoFrame.subarray(0, videoFrame.uOffset));
    videoFrame.u.fill(videoFrame.subarray(videoFrame.uOffset, videoFrame.vOffset));
    videoFrame.v.fill(videoFrame.subarray(videoFrame.vOffset, len));
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
}

var renderFallback = function(canvas, videoFrame) {
    var buf = canvas.img.data;
    var width = videoFrame.width;
    var height = videoFrame.height;
    for (var i = 0; i < height; ++i) {
        for (var j = 0; j < width; ++j) {
            var o = (j + (width*i))*4;
            buf[o + 0] = videoFrame[o+2];
            buf[o + 1] = videoFrame[o+1];
            buf[o + 2] = videoFrame[o+0];
            buf[o + 3] = videoFrame[o+3];
        }
    };
    canvas.ctx.putImageData(canvas.img, 0, 0);
}

function setupCanvas(canvas, vlc, fallbackRenderer) {
    if (!fallbackRenderer) canvas.gl = canvas.getContext("webgl"); // Comment this line out to test fallback
    var gl = canvas.gl;
    if (!gl || fallbackRenderer) {
        console.log(fallbackRenderer ? "Fallback renderer forced, not using WebGL" : "Unable to initialize WebGL, falling back to canvas rendering");
        vlc.pixelFormat = vlc.RV32;
        canvas.ctx = canvas.getContext("2d");
        delete canvas.gl; // in case of fallback renderer
        return;
    }

    vlc.pixelFormat = vlc.I420;
    canvas.I420Program = gl.createProgram();
    var program = canvas.I420Program;
    var vertexShaderSource = [
        "attribute highp vec4 aVertexPosition;",
        "attribute vec2 aTextureCoord;",
        "varying highp vec2 vTextureCoord;",
        "void main(void) {",
        " gl_Position = aVertexPosition;",
        " vTextureCoord = aTextureCoord;",
        "}"].join("\n");
    var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vertexShaderSource);
    gl.compileShader(vertexShader);
    var fragmentShaderSource = [
        "precision highp float;",
        "varying lowp vec2 vTextureCoord;",
        "uniform sampler2D YTexture;",
        "uniform sampler2D UTexture;",
        "uniform sampler2D VTexture;",
        "const mat4 YUV2RGB = mat4",
        "(",
        " 1.1643828125, 0, 1.59602734375, -.87078515625,",
        " 1.1643828125, -.39176171875, -.81296875, .52959375,",
        " 1.1643828125, 2.017234375, 0, -1.081390625,",
        " 0, 0, 0, 1",
        ");",
        "void main(void) {",
        " gl_FragColor = vec4( texture2D(YTexture, vTextureCoord).x, texture2D(UTexture, vTextureCoord).x, texture2D(VTexture, vTextureCoord).x, 1) * YUV2RGB;",
        "}"].join("\n");

    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fragmentShaderSource);
    gl.compileShader(fragmentShader);
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    gl.useProgram(program);
    if(!gl.getProgramParameter(program, gl.LINK_STATUS)) {
        console.log("Shader link failed.");
    }
    var vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition");
    gl.enableVertexAttribArray(vertexPositionAttribute);
    var textureCoordAttribute = gl.getAttribLocation(program, "aTextureCoord");
    gl.enableVertexAttribArray(textureCoordAttribute);

    var verticesBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, verticesBuffer);
    gl.bufferData(gl.ARRAY_BUFFER,
                  new Float32Array([1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0]),
                  gl.STATIC_DRAW);
    gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
    var texCoordBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
    gl.bufferData(gl.ARRAY_BUFFER,
                  new Float32Array([1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0]),
                  gl.STATIC_DRAW);
    gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
}

var init = function(canvas,params,fallbackRenderer) {
    var wcAddon = require("webchimera.js");

    if (typeof params !== 'undefined') var vlc = wcAddon.createPlayer(params);
    else var vlc = wcAddon.createPlayer();

    if (typeof canvas === 'string') setupCanvas(window.document.querySelector(canvas), vlc, fallbackRenderer);
    else setupCanvas(canvas, vlc, fallbackRenderer);

    vlc.onFrameSetup =
        function(width, height, pixelFormat, videoFrame) {
            frameSetup(canvas, width, height, pixelFormat, videoFrame);

            var ext = canvas.gl.getExtension("WEBGL_lose_context");

            canvas.addEventListener("webglcontextlost", function(e) {
                return function(event) {
                    event.preventDefault();
                    console.log("webgl context lost: restoring after 1 second");
                    setTimeout(function() { e.restoreContext(); },1000);
                }
            }(ext), false);

            canvas.addEventListener("webglcontextrestored", function(w,h,p,v) {
                return function(event) {
                    setupCanvas(canvas, vlc);
                    frameSetup(canvas, w, h, p, v);
                    console.log("webgl context restored");
                }
            }(width,height,pixelFormat,videoFrame), false);

        };
    vlc.onFrameReady =
        function(videoFrame) {
            (canvas.gl ? render : renderFallback)(canvas, videoFrame);
        };
    return vlc;
}

var frameSetup = function(canvas, width, height, pixelFormat, videoFrame) {
    var gl = canvas.gl;
    canvas.width = width;
    canvas.height = height;
    if (! gl) {
        canvas.img = canvas.ctx.createImageData(width, height);
        return;
    }
    var program = canvas.I420Program;
    gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
    videoFrame.y = new Texture(gl, width, height);
    videoFrame.u = new Texture(gl, width >> 1, height >> 1);
    videoFrame.v = new Texture(gl, width >> 1, height >> 1);
    videoFrame.y.bind(0, program, "YTexture");
    videoFrame.u.bind(1, program, "UTexture");
    videoFrame.v.bind(2, program, "VTexture");
}

module.exports = {
    init: init,
    frameSetup: frameSetup
};
<commit_msg>frameSetup() no longer needs to be exposed<commit_after>function Texture(gl, width, height) {
    this.gl = gl;
    this.width = width; this.height = height;
    this.texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, this.texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width, height, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, null);

    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
}
Texture.prototype.bind = function (n, program, name) {
    var gl = this.gl;
    gl.activeTexture([gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2][n]);
    gl.bindTexture(gl.TEXTURE_2D, this.texture);
    gl.uniform1i(gl.getUniformLocation(program, name), n);
}
Texture.prototype.fill = function (data) {
    var gl = this.gl;
    gl.bindTexture(gl.TEXTURE_2D, this.texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, this.width, this.height, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, data);
}

function render(canvas, videoFrame) {
    var gl = canvas.gl;
    var len = videoFrame.length;
    videoFrame.y.fill(videoFrame.subarray(0, videoFrame.uOffset));
    videoFrame.u.fill(videoFrame.subarray(videoFrame.uOffset, videoFrame.vOffset));
    videoFrame.v.fill(videoFrame.subarray(videoFrame.vOffset, len));
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
}

var renderFallback = function(canvas, videoFrame) {
    var buf = canvas.img.data;
    var width = videoFrame.width;
    var height = videoFrame.height;
    for (var i = 0; i < height; ++i) {
        for (var j = 0; j < width; ++j) {
            var o = (j + (width*i))*4;
            buf[o + 0] = videoFrame[o+2];
            buf[o + 1] = videoFrame[o+1];
            buf[o + 2] = videoFrame[o+0];
            buf[o + 3] = videoFrame[o+3];
        }
    };
    canvas.ctx.putImageData(canvas.img, 0, 0);
}

function setupCanvas(canvas, vlc, fallbackRenderer) {
    if (!fallbackRenderer) canvas.gl = canvas.getContext("webgl"); // Comment this line out to test fallback
    var gl = canvas.gl;
    if (!gl || fallbackRenderer) {
        console.log(fallbackRenderer ? "Fallback renderer forced, not using WebGL" : "Unable to initialize WebGL, falling back to canvas rendering");
        vlc.pixelFormat = vlc.RV32;
        canvas.ctx = canvas.getContext("2d");
        delete canvas.gl; // in case of fallback renderer
        return;
    }

    vlc.pixelFormat = vlc.I420;
    canvas.I420Program = gl.createProgram();
    var program = canvas.I420Program;
    var vertexShaderSource = [
        "attribute highp vec4 aVertexPosition;",
        "attribute vec2 aTextureCoord;",
        "varying highp vec2 vTextureCoord;",
        "void main(void) {",
        " gl_Position = aVertexPosition;",
        " vTextureCoord = aTextureCoord;",
        "}"].join("\n");
    var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vertexShaderSource);
    gl.compileShader(vertexShader);
    var fragmentShaderSource = [
        "precision highp float;",
        "varying lowp vec2 vTextureCoord;",
        "uniform sampler2D YTexture;",
        "uniform sampler2D UTexture;",
        "uniform sampler2D VTexture;",
        "const mat4 YUV2RGB = mat4",
        "(",
        " 1.1643828125, 0, 1.59602734375, -.87078515625,",
        " 1.1643828125, -.39176171875, -.81296875, .52959375,",
        " 1.1643828125, 2.017234375, 0, -1.081390625,",
        " 0, 0, 0, 1",
        ");",
        "void main(void) {",
        " gl_FragColor = vec4( texture2D(YTexture, vTextureCoord).x, texture2D(UTexture, vTextureCoord).x, texture2D(VTexture, vTextureCoord).x, 1) * YUV2RGB;",
        "}"].join("\n");

    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fragmentShaderSource);
    gl.compileShader(fragmentShader);
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    gl.useProgram(program);
    if(!gl.getProgramParameter(program, gl.LINK_STATUS)) {
        console.log("Shader link failed.");
    }
    var vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition");
    gl.enableVertexAttribArray(vertexPositionAttribute);
    var textureCoordAttribute = gl.getAttribLocation(program, "aTextureCoord");
    gl.enableVertexAttribArray(textureCoordAttribute);

    var verticesBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, verticesBuffer);
    gl.bufferData(gl.ARRAY_BUFFER,
                  new Float32Array([1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0]),
                  gl.STATIC_DRAW);
    gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
    var texCoordBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
    gl.bufferData(gl.ARRAY_BUFFER,
                  new Float32Array([1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0]),
                  gl.STATIC_DRAW);
    gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
}

var init = function(canvas,params,fallbackRenderer) {
    var wcAddon = require("webchimera.js");

    if (typeof params !== 'undefined') var vlc = wcAddon.createPlayer(params);
    else var vlc = wcAddon.createPlayer();

    if (typeof canvas === 'string') setupCanvas(window.document.querySelector(canvas), vlc, fallbackRenderer);
    else setupCanvas(canvas, vlc, fallbackRenderer);

    vlc.onFrameSetup =
        function(width, height, pixelFormat, videoFrame) {
            frameSetup(canvas, width, height, pixelFormat, videoFrame);

            var ext = canvas.gl.getExtension("WEBGL_lose_context");

            canvas.addEventListener("webglcontextlost", function(e) {
                return function(event) {
                    event.preventDefault();
                    console.log("webgl context lost: restoring after 1 second");
                    setTimeout(function() { e.restoreContext(); },1000);
                }
            }(ext), false);

            canvas.addEventListener("webglcontextrestored", function(w,h,p,v) {
                return function(event) {
                    setupCanvas(canvas, vlc);
                    frameSetup(canvas, w, h, p, v);
                    console.log("webgl context restored");
                }
            }(width,height,pixelFormat,videoFrame), false);

        };
    vlc.onFrameReady =
        function(videoFrame) {
            (canvas.gl ? render : renderFallback)(canvas, videoFrame);
        };
    return vlc;
}

function frameSetup(canvas, width, height, pixelFormat, videoFrame) {
    var gl = canvas.gl;
    canvas.width = width;
    canvas.height = height;
    if (! gl) {
        canvas.img = canvas.ctx.createImageData(width, height);
        return;
    }
    var program = canvas.I420Program;
    gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
    videoFrame.y = new Texture(gl, width, height);
    videoFrame.u = new Texture(gl, width >> 1, height >> 1);
    videoFrame.v = new Texture(gl, width >> 1, height >> 1);
    videoFrame.y.bind(0, program, "YTexture");
    videoFrame.u.bind(1, program, "UTexture");
    videoFrame.v.bind(2, program, "VTexture");
}

module.exports = {
    init: init
};
<|endoftext|>


<commit_before>const request = require('request-promise');

const baseUrl = 'https://api.npmjs.org/downloads/point';
const timings = {
  monthly: 'last-month',
  weekly: 'last-week',
  daily: 'last-day'
};

function fetchStats(timing, packages, cb) {
  if (!packages || !timing) {
    const err = new Error('Function called with package or timing equal to undefined/null/empty-string');

    if (cb) return cb(err);
    return Promise.reject(err);
  }

  let isPackagesArray = Array.isArray(packages);
  let packagesStr = packages;
  if (isPackagesArray) {
    if (!packages.length) {
      const err = new Error('Function called with empty packages array');

      return Promise.reject(err);
      if (cb) return cb(err);

    } else if (packages.some(s => !s)) {
      const err = new Error('Function called with packages array containing undefined/null/empty-string');

      if (cb) return cb(err);
      return Promise.reject(err);
    }
    packagesStr = packages.join(',');
  }

  const resultPromise = request(`${baseUrl}/${timing}/${packagesStr}`, {json: true})
    .then(s => {
      if (s.error) {
        return Promise.reject(new Error(s.error));
      }
      //this case is particular because we want the result to be formated
      //the same way it is when we provide the api wirh a package array with length > 1
      if (isPackagesArray && packages.length === 1) {
        return {
          [packages[0]]: s.downloads
        };
      } else if (isPackagesArray) {
        for (const pkg in s) {
          s[pkg] = s[pkg].downloads;
        }
        return s;
      } else {
        return s.downloads;
      }
    });

  if (cb) {
    return resultPromise
      .then(s => cb(null, s))
      .catch(e => cb(e));
  } else {
    return resultPromise;
  }
}

class packagesStatsFetcher {
  fetchMonthlyStats(packages, cb) {
    return fetchStats(timings.monthly, packages, cb);
  }

  fetchWeeklyStats(packages, cb) {
    return fetchStats(timings.weekly, packages, cb);
  }

  fetchDailyStats(packages, cb) {
    return fetchStats(timings.daily, packages, cb);
  }

  fetchAllStats(packages, cb) {
    const allStatsPromise = Promise.all([
      this.fetchMonthlyStats(packages),
      this.fetchWeeklyStats(packages),
      this.fetchDailyStats(packages)
    ])
    .then(([monthlyStats, weeklyStats, dailyStats]) => {
      const packagesStats = {};
      if (Array.isArray(packages)) {
        packages.forEach(pkg => {
          packagesStats[pkg] = {
            monthly: monthlyStats[pkg],
            weekly: weeklyStats[pkg],
            daily: dailyStats[pkg]
          };
        });
      } else {
        packagesStats.monthly = monthlyStats;
        packagesStats.weekly = weeklyStats;
        packagesStats.daily = dailyStats;
      }
      return packagesStats;
    });

    if (cb) {
      return allStatsPromise.then(s => cb(null, s)).catch(e => cb(e));
    } else {
      return allStatsPromise;
    }
  }
}

module.exports = new packagesStatsFetcher();
<commit_msg>add a missing use strict<commit_after>'use strict';

const request = require('request-promise');

const baseUrl = 'https://api.npmjs.org/downloads/point';
const timings = {
  monthly: 'last-month',
  weekly: 'last-week',
  daily: 'last-day'
};

function fetchStats(timing, packages, cb) {
  if (!packages || !timing) {
    const err = new Error('Function called with package or timing equal to undefined/null/empty-string');

    if (cb) return cb(err);
    return Promise.reject(err);
  }

  let isPackagesArray = Array.isArray(packages);
  let packagesStr = packages;
  if (isPackagesArray) {
    if (!packages.length) {
      const err = new Error('Function called with empty packages array');

      return Promise.reject(err);
      if (cb) return cb(err);

    } else if (packages.some(s => !s)) {
      const err = new Error('Function called with packages array containing undefined/null/empty-string');

      if (cb) return cb(err);
      return Promise.reject(err);
    }
    packagesStr = packages.join(',');
  }

  const resultPromise = request(`${baseUrl}/${timing}/${packagesStr}`, {json: true})
    .then(s => {
      if (s.error) {
        return Promise.reject(new Error(s.error));
      }
      //this case is particular because we want the result to be formated
      //the same way it is when we provide the api wirh a package array with length > 1
      if (isPackagesArray && packages.length === 1) {
        return {
          [packages[0]]: s.downloads
        };
      } else if (isPackagesArray) {
        for (const pkg in s) {
          s[pkg] = s[pkg].downloads;
        }
        return s;
      } else {
        return s.downloads;
      }
    });

  if (cb) {
    return resultPromise
      .then(s => cb(null, s))
      .catch(e => cb(e));
  } else {
    return resultPromise;
  }
}

class packagesStatsFetcher {
  fetchMonthlyStats(packages, cb) {
    return fetchStats(timings.monthly, packages, cb);
  }

  fetchWeeklyStats(packages, cb) {
    return fetchStats(timings.weekly, packages, cb);
  }

  fetchDailyStats(packages, cb) {
    return fetchStats(timings.daily, packages, cb);
  }

  fetchAllStats(packages, cb) {
    const allStatsPromise = Promise.all([
      this.fetchMonthlyStats(packages),
      this.fetchWeeklyStats(packages),
      this.fetchDailyStats(packages)
    ])
    .then(([monthlyStats, weeklyStats, dailyStats]) => {
      const packagesStats = {};
      if (Array.isArray(packages)) {
        packages.forEach(pkg => {
          packagesStats[pkg] = {
            monthly: monthlyStats[pkg],
            weekly: weeklyStats[pkg],
            daily: dailyStats[pkg]
          };
        });
      } else {
        packagesStats.monthly = monthlyStats;
        packagesStats.weekly = weeklyStats;
        packagesStats.daily = dailyStats;
      }
      return packagesStats;
    });

    if (cb) {
      return allStatsPromise.then(s => cb(null, s)).catch(e => cb(e));
    } else {
      return allStatsPromise;
    }
  }
}

module.exports = new packagesStatsFetcher();
<|endoftext|>