<commit_before>var extend = require('xtend');
var Route = require('./Route');
var Request = require('./Request');
var Response = require('./Response');
var Unhandled = require('./errors/Unhandled');
var once = require('once');
var delayed = require('./utils/delayed');
var getDefaultHistory = require('./history/getHistory');
var invokeHandlers = require('./utils/invokeHandlers');
var noop = require('./utils/noop');
var inherits = require('inherits');
var EventEmitter = require('EventEmitter2').EventEmitter2;

function Router() {
  this.state = {};
}

inherits(Router, EventEmitter);

/**
 * Expose the `Unhandled` error so it can be used in handlers more easily.
 */
Router.Unhandled = Unhandled;

/**
 * Add a route to the router class. This API can be used in a manner similar
 * to many server-side JS routing libraries—by chainging calls to `route`—
 * however, it's more likely that you'll want to pass your routes to the
 * router class constructor using JSX.
 *
 * This function accepts either `(path, handlers...)`, or
 * `(name, path, handlers...)`.
 */
Router.route = function() {
  var RouterClass = this;
  var args = Array.prototype.slice.call(arguments, 0);
  var name, path, handlers;

  if (typeof args[1] !== 'function') name = args.shift();
  path = args.shift();
  handlers = args;

  var route = new Route(path);

  // Create and register a middleware to represent this route.
  RouterClass.use(function(req, next) {
    // Only one route should handle any given request.
    if (req.handled) return next();

    // If this route doesn't match, skip it.
    var match = route.match(req.path);
    if (!match) return next();

    // A match! Mark the request as handled and store the params.
    req.handled = true;
    req.params = match;

    invokeHandlers(handlers, req, this, next);
  });

  // For chaining!
  return this;
};

Router.prototype.setState = function(state) {
  this.state = extend(this.state, state);
  this.emit('stateChange');
};

Router.prototype.setView = function(view) {
  this.view = view;
  this.emit('viewChange');
};

/**
 *
 * @param {string} url
 * @param {function?} callback
 */
Router.prototype.dispatch = function(url, opts, callback) {
  var RouterClass = this.constructor;

  if (typeof arguments[1] === 'function') {
    callback = arguments[1];
    opts = null;
  }

  // TODO: Handle this better.
  if (url.indexOf(RouterClass.rootURL) === 0) {
    url = url.substr(RouterClass.rootURL.length);
  } else {
    throw new Error('URL not within root: ' + url);
  }

  // Wrap the callback, imposing a delay to force asynchronousness in
  // case the user calls it synchronously.
  var cb = once(delayed(function(err) {
    this._currentResponse = null;
    if (!err && !res.handled)
      err = new Unhandled(req);
    if (callback)
      callback(err, err ? null : res);
  }.bind(this)));

  var req = new Request(url, opts);
  var res = new Response(req, this)
    .on('error', cb)
    .on('end', cb);

  if (this._currentResponse) {
    this._currentResponse.request.cancel();
  }
  this._currentResponse = res;

  // Force async behavior so you have a chance to add listeners to the
  // request object.
  delayed(function() {
    invokeHandlers(RouterClass.middleware, req, res, cb);
  })();

  return res;
};

Router.use = function(middleware) {
  var RouterClass = this;
  RouterClass.middleware.push(middleware);
  return this;
};

Router.extend = function(opts) {
  var SuperClass = this;
  var NewRouter = function() {
    if (!(this instanceof NewRouter)) {
      return new NewRouter();
    }
    SuperClass.call(this);
  };
  inherits(NewRouter, SuperClass);

  // Add "static" props to the new router.
  for (var k in SuperClass) {
    if (SuperClass.hasOwnProperty(k)) {
      NewRouter[k] = SuperClass[k];
    }
  }

  NewRouter.rootURL = opts && opts.rootURL || '/';
  NewRouter.middleware = [];

  return NewRouter;
};

module.exports = Router;
<commit_msg>Register named routes<commit_after>var extend = require('xtend');
var Route = require('./Route');
var Request = require('./Request');
var Response = require('./Response');
var Unhandled = require('./errors/Unhandled');
var once = require('once');
var delayed = require('./utils/delayed');
var getDefaultHistory = require('./history/getHistory');
var invokeHandlers = require('./utils/invokeHandlers');
var noop = require('./utils/noop');
var inherits = require('inherits');
var EventEmitter = require('EventEmitter2').EventEmitter2;

function Router() {
  this.state = {};
}

inherits(Router, EventEmitter);

/**
 * Expose the `Unhandled` error so it can be used in handlers more easily.
 */
Router.Unhandled = Unhandled;

/**
 * Add a route to the router class. This API can be used in a manner similar
 * to many server-side JS routing libraries—by chainging calls to `route`—
 * however, it's more likely that you'll want to pass your routes to the
 * router class constructor using JSX.
 *
 * This function accepts either `(path, handlers...)`, or
 * `(name, path, handlers...)`.
 */
Router.route = function() {
  var RouterClass = this;
  var args = Array.prototype.slice.call(arguments, 0);
  var name, path, handlers;

  if (typeof args[1] !== 'function') name = args.shift();
  path = args.shift();
  handlers = args;

  var route = new Route(path);

  if (name) {
    if (RouterClass.namedRoutes[name])
      throw new Error('Route with name "' + name + '" already exists.');
    RouterClass.namedRoutes[name] = route;
  }

  // Create and register a middleware to represent this route.
  RouterClass.use(function(req, next) {
    // Only one route should handle any given request.
    if (req.handled) return next();

    // If this route doesn't match, skip it.
    var match = route.match(req.path);
    if (!match) return next();

    // A match! Mark the request as handled and store the params.
    req.handled = true;
    req.params = match;

    invokeHandlers(handlers, req, this, next);
  });

  // For chaining!
  return this;
};

Router.prototype.setState = function(state) {
  this.state = extend(this.state, state);
  this.emit('stateChange');
};

Router.prototype.setView = function(view) {
  this.view = view;
  this.emit('viewChange');
};

/**
 *
 * @param {string} url
 * @param {function?} callback
 */
Router.prototype.dispatch = function(url, opts, callback) {
  var RouterClass = this.constructor;

  if (typeof arguments[1] === 'function') {
    callback = arguments[1];
    opts = null;
  }

  // TODO: Handle this better.
  if (url.indexOf(RouterClass.rootURL) === 0) {
    url = url.substr(RouterClass.rootURL.length);
  } else {
    throw new Error('URL not within root: ' + url);
  }

  // Wrap the callback, imposing a delay to force asynchronousness in
  // case the user calls it synchronously.
  var cb = once(delayed(function(err) {
    this._currentResponse = null;
    if (!err && !res.handled)
      err = new Unhandled(req);
    if (callback)
      callback(err, err ? null : res);
  }.bind(this)));

  var req = new Request(url, opts);
  var res = new Response(req, this)
    .on('error', cb)
    .on('end', cb);

  if (this._currentResponse) {
    this._currentResponse.request.cancel();
  }
  this._currentResponse = res;

  // Force async behavior so you have a chance to add listeners to the
  // request object.
  delayed(function() {
    invokeHandlers(RouterClass.middleware, req, res, cb);
  })();

  return res;
};

Router.use = function(middleware) {
  var RouterClass = this;
  RouterClass.middleware.push(middleware);
  return this;
};

Router.extend = function(opts) {
  var SuperClass = this;
  var NewRouter = function() {
    if (!(this instanceof NewRouter)) {
      return new NewRouter();
    }
    SuperClass.call(this);
  };
  inherits(NewRouter, SuperClass);

  // Add "static" props to the new router.
  for (var k in SuperClass) {
    if (SuperClass.hasOwnProperty(k)) {
      NewRouter[k] = SuperClass[k];
    }
  }

  NewRouter.rootURL = opts && opts.rootURL || '/';
  NewRouter.middleware = [];
  NewRouter.namedRoutes = {};

  return NewRouter;
};

module.exports = Router;
<|endoftext|>


<commit_before>/*!
 * numeral.js language configuration
 * language : Farsi Iran
 * author : neo13 : https://github.com/neo13
 */
(function () {
    var language = {
        delimiters: {
            thousands: '،',
            decimal: '.'
        },
        abbreviations: {
            thousand: 'هزار',
            million: 'میلیون',
            billion: 'میلیارد',
            trillion: 'تریلیون'
        },
        ordinal: function (number) {
            return 'ام';
        },
        currency: {
            symbol: '﷼'
        }
    };

    // Node
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = language;
    }
    // Browser
    if (typeof window !== 'undefined' && this.numeral && this.numeral.language) {
        this.numeral.language('en-gb', language);
    }
}());
<commit_msg>Register for proper lang-locale code<commit_after>/*!
 * numeral.js language configuration
 * language : Farsi Iran
 * author : neo13 : https://github.com/neo13
 */
(function () {
    var language = {
        delimiters: {
            thousands: '،',
            decimal: '.'
        },
        abbreviations: {
            thousand: 'هزار',
            million: 'میلیون',
            billion: 'میلیارد',
            trillion: 'تریلیون'
        },
        ordinal: function (number) {
            return 'ام';
        },
        currency: {
            symbol: '﷼'
        }
    };

    // Node
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = language;
    }
    // Browser
    if (typeof window !== 'undefined' && this.numeral && this.numeral.language) {
        this.numeral.language('fa-IR', language);
    }
}());
<|endoftext|>


<commit_before>const buble = require('rollup-plugin-buble');
const tapSpec = require('tap-spec');

module.exports = (config) => {
  config.set({
    autoWatch: false,
    // client: { captureConsole: false },
    browsers: [ 'Chrome', 'Firefox' ],
    browserConsoleLogOptions: {
      level: 'error',
      format: '%b %T: %m',
      terminal: false
    },
    colors: true,
    files: [
      './build/tape.js',
      './test.js'
    ],
    frameworks: ['tap'],
    // logLevel: 'LOG_DEBUG',
    logLevel: config.LOG_ERROR,
    plugins: [
      'karma-rollup-preprocessor',
      'karma-chrome-launcher',
      'karma-firefox-launcher',
      'karma-tap',
      'karma-tap-pretty-reporter'
    ],
    preprocessors: {
      './test.js': [ 'rollup' ]
    },
    reporters: ['tap-pretty'],
    rollupPreprocessor: {
      // context: 'this',
      external: ['tape'],
      output: {
        format: 'iife',
        globals: {
          'tape': 'tape'
        }
      },
      plugins: [
        buble()
      ],
      sourcemap: false // 'inline'
    },
    singleRun: true,
    tapReporter: {
      prettify: tapSpec
    }
  });
};
<commit_msg>without karma-tap-pretty-reporter<commit_after>const buble = require('rollup-plugin-buble');
const tapSpec = require('tap-spec');

module.exports = (config) => {
  config.set({
    autoWatch: false,
    // client: { captureConsole: false },
    browsers: [ 'Chrome', 'Firefox' ],
    browserConsoleLogOptions: {
      level: 'error',
      format: '%b %T: %m',
      terminal: false
    },
    colors: true,
    files: [
      './build/tape.js',
      './test.js'
    ],
    frameworks: ['tap'],
    // logLevel: 'LOG_DEBUG',
    logLevel: config.LOG_ERROR,
    plugins: [
      'karma-rollup-preprocessor',
      'karma-chrome-launcher',
      'karma-firefox-launcher',
      'karma-tap'
      // 'karma-tap-pretty-reporter'
    ],
    preprocessors: {
      './test.js': [ 'rollup' ]
    },
    //reporters: ['tap-pretty'],
    rollupPreprocessor: {
      // context: 'this',
      external: ['tape'],
      output: {
        format: 'iife',
        globals: {
          'tape': 'tape'
        }
      },
      plugins: [
        buble()
      ],
      sourcemap: false // 'inline'
    },
    singleRun: true/*,
    tapReporter: {
      prettify: tapSpec
    }*/
  });
};
<|endoftext|>


<commit_before>/* WePay API for Node.js
 * (c)2012 Matt Farmer
 * Release without warranty under the terms of the
 * Apache License. For more details, see the LICENSE
 * file at the root of this project.
*/
var UserInstance = function(params) {
  //TODO
}

module.exports = UserInstance;
<commit_msg>Implement the User instance constructor.<commit_after>/* WePay API for Node.js
 * (c)2012 Matt Farmer
 * Release without warranty under the terms of the
 * Apache License. For more details, see the LICENSE
 * file at the root of this project.
*/
var UserInstance = function(params) {
  // Populate any params passed in.
  if (params && ! params instanceof Object)
    throw "Parameters passed to an instance constructor must be an object or undefined.";

  if (params){
    for (key in params) {
      this[key] = params[key];
    }
  }
}

module.exports = UserInstance;
<|endoftext|>


<commit_before>/* eslint-env node */
const path = require('path')
const webpackConfig = require('./webpack.config')[0]
const isWindows = /^win/.test(process.platform)
const isTravis = Boolean(process.env.TRAVIS)

module.exports = function (config) {
  config.set({
    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: 'test',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha'],

    // list of files / patterns to load in the browser
    files: [
      '**/*_spec.js'
    ],

    // list of files to exclude
    exclude: [],

    client: {
      mocha: {}
    },

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      '**/*_spec.js': ['webpack']
    },

    webpack: {
      module: (function () {
        const module = webpackConfig.module
        if (process.argv.indexOf('--auto-watch') === -1) {
          module.postLoaders = [{
            test: /\.js$/,
            exclude: /(test|node_modules)/,
            loader: 'istanbul-instrumenter'
          }]
        }
        return module
      })()
    },

    webpackMiddleware: {
      noInfo: true
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['dots', 'coverage', 'threshold'],

    coverageReporter: {
      dir: path.join(__dirname, 'coverage'),
      reporters: [
        {type: 'html', subdir: 'report-html'},
        {type: 'lcov', subdir: 'report-lcov'}
      ]
    },

    thresholdReporter: {
      statements: 87,
      branches: 70,
      functions: 90,
      lines: 100
    },

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: [
      'PhantomJS',
      isTravis ? 'Chrome_travis_ci' : 'Chrome',
      'Firefox'
    ].concat(isWindows ? ['IE'] : []),

    customLaunchers: {
      'Chrome_travis_ci': {
        base: 'Chrome',
        flags: ['--no-sandbox']
      }
    },

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultanous
    concurrency: Infinity
  })
}
<commit_msg>chore(karma): refactor karma config<commit_after>/* eslint-env node */
const path = require('path')
const webpackConfig = require('./webpack.config')[0]
const isWindows = /^win/.test(process.platform)
const isTravis = Boolean(process.env.TRAVIS)

module.exports = function (config) {
  const autoWatch = config.autoWatch
  config.set({
    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: 'test',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha'],

    // list of files / patterns to load in the browser
    files: [
      '**/*_spec.js'
    ],

    // list of files to exclude
    exclude: [],

    client: {
      mocha: {}
    },

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      '**/*_spec.js': ['webpack']
    },

    webpack: {
      devtool: autoWatch ? 'cheap-module-inline-source-map' : null,
      module: (function () {
        const module = webpackConfig.module
        if (!autoWatch) {
          module.postLoaders = [{
            test: /\.js$/,
            exclude: /(test|node_modules)/,
            loader: 'istanbul-instrumenter'
          }]
        }
        return module
      })()
    },

    webpackMiddleware: {
      noInfo: true
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['dots', 'coverage', 'threshold'],

    coverageReporter: {
      dir: path.join(__dirname, 'coverage'),
      reporters: [
        {type: 'html', subdir: 'report-html'},
        {type: 'lcov', subdir: 'report-lcov'}
      ]
    },

    thresholdReporter: {
      statements: 87,
      branches: 70,
      functions: 90,
      lines: 100
    },

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: [
      'PhantomJS',
      isTravis ? 'Chrome_travis_ci' : 'Chrome',
      'Firefox'
    ].concat(isWindows ? ['IE'] : []),

    customLaunchers: {
      'Chrome_travis_ci': {
        base: 'Chrome',
        flags: ['--no-sandbox']
      }
    },

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultanous
    concurrency: Infinity
  })
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */

/*jslint anon:true, sloppy:true, regexp:true, nomen:true, stupid:true*/

var fs = require('fs'),
    path = require('path'),
    existsSync = fs.existsSync || path.existsSync,
    utils = require(path.join(__dirname, '../../management/utils')),
    usage = 'mojito jslint [app | mojit] [<name>] {options}\n' +
            '\nOPTIONS: \n' +
            '\t  --print      :  print results to stdout \n' +
            '\t   -p          :  short for --print\n',
    options = [
        {
            shortName: 'p',
            longName: 'print',
            hasValue: false
        }
    ];

// ---------- Generic file system utilities ----------

/*
 * A version of fs.mkdirSync that ensures that all intermediate directories
 * are created.
 */
function mkdirsSync(dir, mode) {
    var modeDefault = parseInt('755', 8); // Avoid octal per JSLint

    if (existsSync(dir)) {
        return;
    }
    mode = mode || modeDefault;
    mkdirsSync(path.dirname(dir), mode);
    fs.mkdirSync(dir, mode);
}

/*
 * Deletes a directory including any contained files and directories. This is
 * roughly equivalent to the Unix "rm -rf" command.
 */
function rmSync(file) {
    var failures = [],
        files,
        stat;

    try {
        stat = fs.lstatSync(file);
    } catch (e1) {
        if (/^ENOENT/.test(e1.message)) {
            return null;
        }
        return [file];
    }

    if (stat.isFile() || stat.isSymbolicLink()) {
        try {
            fs.unlinkSync(file);
        } catch (e2) {
            failures.push(file);
        }
    } else if (stat.isDirectory()) {
        files = fs.readdirSync(file);
        files.forEach(function(f) {
            try {
                failures.concat(rmSync(path.join(file, f)));
            } catch (e3) {
                failures.push(path.join(file, f));
            }
        });
    }

    return failures;
}

/*
 * Recursively processes all of the files in a directory tree. Each file is
 * passed to a 'processor' function that can do whatever it needs to do. An
 * optional 'filter' function allows files to be skipped (i.e. not passed to
 * the processor) by returning false.
 */
function processDir(dir, processor, filter) {
    var files = fs.readdirSync(dir),
        file,
        stat;

    filter = filter || function() { return true; };

    files.forEach(function(f) {
        file = path.join(dir, f);
        stat = fs.statSync(file);
        if (filter(file, stat)) {
            if (stat.isDirectory()) {
                processDir(file, processor, filter);
            } else {
                processor(file);
            }
        }
    });
}

/*
 * A very simple class to allow writes to a file that is created only if it
 * needs to be written to, without the caller needing to check on every write.
 */
function OutputFile(filename) {
    var outstream = null;

    this.write = function(s) {
        if (!outstream) {
            mkdirsSync(path.dirname(filename));
            outstream = fs.createWriteStream(filename);
        }
        outstream.write(s);
    };
    this.done = function() {
        if (outstream) {
            outstream.end();
            outstream = null;
        }
    };
}

/*
 * A very simple class to allow writes to stdout.
 */
function OutputStdout(filename) {
    var printedName = false;

    this.write = function(s) {
        if (!printedName) {
            printedName = true;
            process.stdout.write(filename + '\n');
        }
        process.stdout.write(s);
    };
    this.done = function() {};
}

// ---------- JSLint processing ----------

/*
 * Run JSLint over a single file, writing any errors to the provided output,
 * and returning the number of errors encountered.
 */
function lintOneFile(infile, outfile) {
    var jslint = require('jslint'),
        OPTS = {
            'continue': true, // Tolerate continue
            node: true,
            predef: [
                // CommonJS
                'exports',
                // YUI
                'YUI', 'YUI_config', 'YAHOO', 'YAHOO_config', 'Y',
                // Node
                'global', 'process', 'require', '__filename', 'module',
                // Browser
                'document', 'navigator', 'console', 'self', 'window'
            ]
        },
        errors = 0,
        i = 0,
        e,
        input,
        len,
        success,
        pad,
        data;

    input = fs.readFileSync(infile);
    if (!input) {
        utils.error("Failed to open file '" + infile + "'.", usage);
        return 0;
    }
    input = input.toString('utf8');

    // remove shebang (lifted from node.js)
    input = input.replace(/^\#\!.*/, '');

    success = jslint(input, OPTS);
    if (!success) {
        errors = len = jslint.errors.length;
        for (i = 0; i < len; i += 1) {
            pad = String(i + 1);
            while (pad.length < 4) {
                pad = ' ' + pad;
            }
            e = jslint.errors[i];
            if (e) {
                outfile.write(pad + ' ' + e.line + ',' + e.character + ': ' +
                        e.reason + '\n');
                outfile.write('     ' +
                        (e.evidence || '').replace(/^\s+|\s+$/, '') + '\n');
            }
        }
    }

    data = jslint.data();
    data.functions.forEach(function(f) {
        if (f.name.charAt(0) === '_') {
            pad = String(i + 1);
            while (pad.length < 4) {
                pad = ' ' + pad;
            }
            outfile.write(pad + ' ' + f.line + ': ' +
                    "Unexpected leading '_' in '" + f.name + "'.\n");
            i += 1;
            errors += 1;
        }
        if (f['var']) {
            f['var'].forEach(function(v) {
                if (v.charAt(0) === '_') {
                    pad = String(i + 1);
                    while (pad.length < 4) {
                        pad = ' ' + pad;
                    }
                    outfile.write(pad + ' ' + f.line + ': ' +
                            "Unexpected leading '_' in '" + v + "'.\n");
                    outfile.write('     ' +
                            'function ' + f.name + '\n');
                    i += 1;
                    errors += 1;
                }
            });
        }
    });

    return errors;
}

// ---------- Mojito JSLint usage ----------

/*
 * Return the location of te Mojito framework. We're currently making an
 * assumption about relative location; we really need a way to validate that.
 */
function getFrameworkDir() {
    return path.normalize(__dirname + '/../../../lib');
}

/*
 * Return the directory for the application. If no application name is given,
 * we look to see if we are inside an application already. If a name is given,
 * we check for an app in the current directory, and then look to see if we
 * are already there.
 */
function getAppDir(appName) {
    var cwd = process.cwd(),
        dir,
        file,
        stat,
        parts;

    // If appName was not supplied, see if we're in an app.
    if (!appName) {
        file = path.join(cwd, 'server.js');
        return (existsSync(file) ? cwd : null);
    }

    // Look for the app where we are.
    dir = path.join(cwd, appName);
    if (existsSync(dir)) {
        stat = fs.statSync(dir);
        if (stat.isDirectory()) {
            return dir;
        }
    }

    // See if we are already in the app.
    parts = cwd.split('/');
    if (parts[parts.length - 1] === appName) {
        return cwd;
    }

    // App not found.
    return null;
}

/*
 * Return the directory for the mojit. Currently assumes we are in the app.
 */
function getMojitDir(mojitPath) {
    var cwd = process.cwd();

    return path.join(cwd, mojitPath);
}

/*
 * Return the name of the mojit, extracted from the path supplied.
 */
function getMojitName(mojitPath) {
    var parts = mojitPath.split('/');

    return parts[parts.length - 1];
}

/*
 * Write an HTML page that makes it easy to navigate through the results. The
 * implementation of this is very "lazy" but also very simple in terms of file
 * system interaction.
 */
function writePage(outDir, rowdata, totalErrors) {
    var outfile = path.join(outDir, 'jslint.html'),
        html = '' +
            '<title>JSLint Report</title>' +
            '
JSLint Report
' +
            '
Total of ' + totalErrors + ' errors in ' +
            rowdata.length + ' files.
' +
            '
\n';

    rowdata.forEach(function(row) {
        html += '
' +
            row.count +
            "	" +
            row.text +
            '
\n';
    });

    html += '
';

    fs.writeFileSync(outfile, html);
}

/*
 * Process all of the files in the input directory, writing any JSLint errors
 * encountered to the output directory. Return the total count of errors.
 */
function processFiles(inDir, outDir, excludeMatcher) {
    var totalErrors = 0,
        rowdata = [];

    inDir = path.normalize(inDir);
    if (outDir) {
        outDir = path.normalize(outDir);
    }

    processDir(inDir,
        function(f) {
            var relname = f.replace(inDir, '').replace(/^\//, ''),
                outname = relname.replace(/\.js$/, '.txt'),
                out,
                errors;

            if (!outDir) {
                out = new OutputStdout(relname);
            } else {
                out = new OutputFile(path.join(outDir, outname));
            }

            errors = lintOneFile(f, out);

            if (errors > 0) {
                rowdata.push({count: errors, text: relname, url: outname});
            }
            totalErrors += errors;
            out.done();
        },
        function(f, s) {
            var p;

            if (excludeMatcher(f, s.isDirectory() ? 'dir' : 'file')) {
                return false;
            }
            p = f.split('/');
            return (p[p.length - 1]).charAt(0) !== '.' &&
                (s.isDirectory() || /\.js$/.test(p));
        });

    if (outDir && totalErrors > 0) {
        writePage(outDir, rowdata, totalErrors);
    }

    return totalErrors;
}

/*
 * Run this command. The options (framework, application, or mojit check, and
 * an optional path) are processed, and JSLint is run on each file. If there
 * are errors, a non-zero process exit is made.
 */
function run(params, options) {
    var excludes,
        inDir,
        outDir,
        failures,
        errors,
        print = options && options.print;

    // Process params to determine input and output locations.
    if (!params || params.length === 0) {
        // framework
        inDir = getFrameworkDir();
        outDir = path.join(process.cwd(), 'artifacts/framework/jslint');
        excludes = [
            /\/artifacts$/,
            /\/tests$/,
            /\/libs$/,
            /\/app\/autoload\/transport$/,
            /\/app\/autoload\/handlebars\.common\.js$/,
            /\/app\/libs$/,
            /\/management$/,
            /\/node_modules$/,
            /\/mojito$/ // for the CI environment
        ];
    } else if (params[0] === 'app') {
        // application
        inDir = getAppDir(params[1]);
        if (!inDir) {
            utils.error('Application not found.', usage);
            return;
        }
        outDir = path.join(inDir, 'artifacts/jslint');
        excludes = [
            /\/tests$/,
            /\/artifacts$/,
            /\/node_modules$/
        ];
    } else if (params[0] === 'mojit') {
        // mojit
        inDir = getMojitDir(params[1]);
        if (!inDir) {
            utils.error('Mojit not found.', usage);
            return;
        }
        outDir = path.join(inDir, 'artifacts/jslint/mojits',
            getMojitName(params[1]));
        excludes = [
            /\/tests$/,
            /\/artifacts$/,
            /\/node_modules$/
        ];
    } else {
        // TODO: [Issue 85] Maybe allow for a single file?
        utils.error('Unrecognized option: ' + params[0], usage);
        return;
    }

    // Delete any files currently in the output location.
    failures = rmSync(outDir);
    if (failures && failures.length) {
        console.log('Some files could not be deleted:\n');
        failures.forEach(function(f) {
            console.log('\t' + f);
        });
    }

    // Set outDir to null if we just plan on printing to stdout
    if (print) {
        outDir = null;
    }

    // Process the files with JSLint.
    errors = processFiles(inDir, outDir, utils.getExclusionMatcher(excludes));
    if (!print && errors) {
        console.log('Lint report: ' + path.normalize(outDir));
    }
    process.stdout.write(errors + ' errors found.\n', 'utf8',
        function() {
            if (errors) {
                // Make sure file streams have the opportunity to finish
                setTimeout(function () {
                    process.exit(1);
                });
            }
        });
}

/**
 * Standard usage string export.
 */
exports.usage = usage;

/**
 * Standard options export.
 */
exports.options = options;

/**
 * Standard run method hook export.
 */
exports.run = run;
<commit_msg>Fixed handling of bad input for mojito jslint mojit command, modified the help/usage message<commit_after>/*
 * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */

/*jslint anon:true, sloppy:true, regexp:true, nomen:true, stupid:true*/

var fs = require('fs'),
    path = require('path'),
    existsSync = fs.existsSync || path.existsSync,
    utils = require(path.join(__dirname, '../../management/utils')),
    usage = 'mojito jslint [app | mojit] [<path>] {options}\n' +
            '\t- target: app or mojit\n' +
            '\t- path (required for a mojit target): the path to the mojit to run jslint on\n\n' +
            'Run jslint on the app in the current directory:\n' +
            '\tmojito jslint app .\n' +
            'Run jslint on mojits/Bar:\n' +
            '\tmojito jslint mojit ./mojits/Bar\n' +
            'Run jslint on the mojito framework itself!\n' +
            '\tmojito jslint\n' +
            '\nOPTIONS: \n' +
            '\t  --print      :  print results to stdout \n' +
            '\t   -p          :  short for --print\n',
    options = [
        {
            shortName: 'p',
            longName: 'print',
            hasValue: false
        }
    ];

// ---------- Generic file system utilities ----------

/*
 * A version of fs.mkdirSync that ensures that all intermediate directories
 * are created.
 */
function mkdirsSync(dir, mode) {
    var modeDefault = parseInt('755', 8); // Avoid octal per JSLint

    if (existsSync(dir)) {
        return;
    }
    mode = mode || modeDefault;
    mkdirsSync(path.dirname(dir), mode);
    fs.mkdirSync(dir, mode);
}

/*
 * Deletes a directory including any contained files and directories. This is
 * roughly equivalent to the Unix "rm -rf" command.
 */
function rmSync(file) {
    var failures = [],
        files,
        stat;

    try {
        stat = fs.lstatSync(file);
    } catch (e1) {
        if (/^ENOENT/.test(e1.message)) {
            return null;
        }
        return [file];
    }

    if (stat.isFile() || stat.isSymbolicLink()) {
        try {
            fs.unlinkSync(file);
        } catch (e2) {
            failures.push(file);
        }
    } else if (stat.isDirectory()) {
        files = fs.readdirSync(file);
        files.forEach(function(f) {
            try {
                failures.concat(rmSync(path.join(file, f)));
            } catch (e3) {
                failures.push(path.join(file, f));
            }
        });
    }

    return failures;
}

/*
 * Recursively processes all of the files in a directory tree. Each file is
 * passed to a 'processor' function that can do whatever it needs to do. An
 * optional 'filter' function allows files to be skipped (i.e. not passed to
 * the processor) by returning false.
 */
function processDir(dir, processor, filter) {
    var files = fs.readdirSync(dir),
        file,
        stat;

    filter = filter || function() { return true; };

    files.forEach(function(f) {
        file = path.join(dir, f);
        stat = fs.statSync(file);
        if (filter(file, stat)) {
            if (stat.isDirectory()) {
                processDir(file, processor, filter);
            } else {
                processor(file);
            }
        }
    });
}

/*
 * A very simple class to allow writes to a file that is created only if it
 * needs to be written to, without the caller needing to check on every write.
 */
function OutputFile(filename) {
    var outstream = null;

    this.write = function(s) {
        if (!outstream) {
            mkdirsSync(path.dirname(filename));
            outstream = fs.createWriteStream(filename);
        }
        outstream.write(s);
    };
    this.done = function() {
        if (outstream) {
            outstream.end();
            outstream = null;
        }
    };
}

/*
 * A very simple class to allow writes to stdout.
 */
function OutputStdout(filename) {
    var printedName = false;

    this.write = function(s) {
        if (!printedName) {
            printedName = true;
            process.stdout.write(filename + '\n');
        }
        process.stdout.write(s);
    };
    this.done = function() {};
}

// ---------- JSLint processing ----------

/*
 * Run JSLint over a single file, writing any errors to the provided output,
 * and returning the number of errors encountered.
 */
function lintOneFile(infile, outfile) {
    var jslint = require('jslint'),
        OPTS = {
            'continue': true, // Tolerate continue
            node: true,
            predef: [
                // CommonJS
                'exports',
                // YUI
                'YUI', 'YUI_config', 'YAHOO', 'YAHOO_config', 'Y',
                // Node
                'global', 'process', 'require', '__filename', 'module',
                // Browser
                'document', 'navigator', 'console', 'self', 'window'
            ]
        },
        errors = 0,
        i = 0,
        e,
        input,
        len,
        success,
        pad,
        data;

    input = fs.readFileSync(infile);
    if (!input) {
        utils.error("Failed to open file '" + infile + "'.", usage);
        return 0;
    }
    input = input.toString('utf8');

    // remove shebang (lifted from node.js)
    input = input.replace(/^\#\!.*/, '');

    success = jslint(input, OPTS);
    if (!success) {
        errors = len = jslint.errors.length;
        for (i = 0; i < len; i += 1) {
            pad = String(i + 1);
            while (pad.length < 4) {
                pad = ' ' + pad;
            }
            e = jslint.errors[i];
            if (e) {
                outfile.write(pad + ' ' + e.line + ',' + e.character + ': ' +
                        e.reason + '\n');
                outfile.write('     ' +
                        (e.evidence || '').replace(/^\s+|\s+$/, '') + '\n');
            }
        }
    }

    data = jslint.data();
    data.functions.forEach(function(f) {
        if (f.name.charAt(0) === '_') {
            pad = String(i + 1);
            while (pad.length < 4) {
                pad = ' ' + pad;
            }
            outfile.write(pad + ' ' + f.line + ': ' +
                    "Unexpected leading '_' in '" + f.name + "'.\n");
            i += 1;
            errors += 1;
        }
        if (f['var']) {
            f['var'].forEach(function(v) {
                if (v.charAt(0) === '_') {
                    pad = String(i + 1);
                    while (pad.length < 4) {
                        pad = ' ' + pad;
                    }
                    outfile.write(pad + ' ' + f.line + ': ' +
                            "Unexpected leading '_' in '" + v + "'.\n");
                    outfile.write('     ' +
                            'function ' + f.name + '\n');
                    i += 1;
                    errors += 1;
                }
            });
        }
    });

    return errors;
}

// ---------- Mojito JSLint usage ----------

/*
 * Return the location of te Mojito framework. We're currently making an
 * assumption about relative location; we really need a way to validate that.
 */
function getFrameworkDir() {
    return path.normalize(__dirname + '/../../../lib');
}

/*
 * Return the directory for the application. If no application name is given,
 * we look to see if we are inside an application already. If a name is given,
 * we check for an app in the current directory, and then look to see if we
 * are already there.
 */
function getAppDir(appName) {
    var cwd = process.cwd(),
        dir,
        file,
        stat,
        parts;

    // If appName was not supplied, see if we're in an app.
    if (!appName) {
        file = path.join(cwd, 'server.js');
        return (existsSync(file) ? cwd : null);
    }

    // Look for the app where we are.
    dir = path.join(cwd, appName);
    if (existsSync(dir)) {
        stat = fs.statSync(dir);
        if (stat.isDirectory()) {
            return dir;
        }
    }

    // See if we are already in the app.
    parts = cwd.split('/');
    if (parts[parts.length - 1] === appName) {
        return cwd;
    }

    // App not found.
    return null;
}

/*
 * Return the directory for the mojit. Currently assumes we are in the app.
 */
function getMojitDir(mojitPath) {
    var cwd = process.cwd();

    return path.join(cwd, mojitPath);
}

/*
 * Return the name of the mojit, extracted from the path supplied.
 */
function getMojitName(mojitPath) {
    var parts = mojitPath.split('/');

    return parts[parts.length - 1];
}

/*
 * Write an HTML page that makes it easy to navigate through the results. The
 * implementation of this is very "lazy" but also very simple in terms of file
 * system interaction.
 */
function writePage(outDir, rowdata, totalErrors) {
    var outfile = path.join(outDir, 'jslint.html'),
        html = '' +
            '<title>JSLint Report</title>' +
            '
JSLint Report
' +
            '
Total of ' + totalErrors + ' errors in ' +
            rowdata.length + ' files.
' +
            '
\n';

    rowdata.forEach(function(row) {
        html += '
' +
            row.count +
            "	" +
            row.text +
            '
\n';
    });

    html += '
';

    fs.writeFileSync(outfile, html);
}

/*
 * Process all of the files in the input directory, writing any JSLint errors
 * encountered to the output directory. Return the total count of errors.
 */
function processFiles(inDir, outDir, excludeMatcher) {
    var totalErrors = 0,
        rowdata = [];

    inDir = path.normalize(inDir);
    if (outDir) {
        outDir = path.normalize(outDir);
    }

    processDir(inDir,
        function(f) {
            var relname = f.replace(inDir, '').replace(/^\//, ''),
                outname = relname.replace(/\.js$/, '.txt'),
                out,
                errors;

            if (!outDir) {
                out = new OutputStdout(relname);
            } else {
                out = new OutputFile(path.join(outDir, outname));
            }

            errors = lintOneFile(f, out);

            if (errors > 0) {
                rowdata.push({count: errors, text: relname, url: outname});
            }
            totalErrors += errors;
            out.done();
        },
        function(f, s) {
            var p;

            if (excludeMatcher(f, s.isDirectory() ? 'dir' : 'file')) {
                return false;
            }
            p = f.split('/');
            return (p[p.length - 1]).charAt(0) !== '.' &&
                (s.isDirectory() || /\.js$/.test(p));
        });

    if (outDir && totalErrors > 0) {
        writePage(outDir, rowdata, totalErrors);
    }

    return totalErrors;
}

/*
 * Run this command. The options (framework, application, or mojit check, and
 * an optional path) are processed, and JSLint is run on each file. If there
 * are errors, a non-zero process exit is made.
 */
function run(params, options) {
    var excludes,
        inDir,
        outDir,
        failures,
        errors,
        mojit_path,
        print = options && options.print;

    // Process params to determine input and output locations.
    if (!params || params.length === 0) {
        // framework
        inDir = getFrameworkDir();
        outDir = path.join(process.cwd(), 'artifacts/framework/jslint');
        excludes = [
            /\/artifacts$/,
            /\/tests$/,
            /\/libs$/,
            /\/app\/autoload\/transport$/,
            /\/app\/autoload\/handlebars\.common\.js$/,
            /\/app\/libs$/,
            /\/management$/,
            /\/node_modules$/,
            /\/mojito$/ // for the CI environment
        ];
    } else if (params[0] === 'app') {
        // application
        inDir = getAppDir(params[1]);
        if (!inDir) {
            utils.error('Application not found.', usage);
            return;
        }
        outDir = path.join(inDir, 'artifacts/jslint');
        excludes = [
            /\/tests$/,
            /\/artifacts$/,
            /\/node_modules$/
        ];
    } else if (params[0] === 'mojit') {
        // mojit
        mojit_path = params[1];
        if (!mojit_path) {
            utils.error('Please specify mojit name', exports.usage);
            return;
        }
        inDir = getMojitDir(mojit_path);
        if (!existsSync(inDir)) {
            utils.error('Mojit ' + mojit_path + ' not found.', usage);
            return;
        }
        if (!inDir) {
            utils.error('Mojit ' + mojit_path + ' not found.', usage);
            return;
        }
        outDir = path.join(inDir, 'artifacts/jslint/mojits',
            getMojitName(mojit_path));
        excludes = [
            /\/tests$/,
            /\/artifacts$/,
            /\/node_modules$/
        ];
    } else {
        // TODO: [Issue 85] Maybe allow for a single file?
        utils.error('Unrecognized option: ' + params[0], usage);
        return;
    }

    // Delete any files currently in the output location.
    failures = rmSync(outDir);
    if (failures && failures.length) {
        console.log('Some files could not be deleted:\n');
        failures.forEach(function(f) {
            console.log('\t' + f);
        });
    }

    // Set outDir to null if we just plan on printing to stdout
    if (print) {
        outDir = null;
    }

    // Process the files with JSLint.
    errors = processFiles(inDir, outDir, utils.getExclusionMatcher(excludes));
    if (!print && errors) {
        console.log('Lint report: ' + path.normalize(outDir));
    }
    process.stdout.write(errors + ' errors found.\n', 'utf8',
        function() {
            if (errors) {
                // Make sure file streams have the opportunity to finish
                setTimeout(function () {
                    process.exit(1);
                });
            }
        });
}

/**
 * Standard usage string export.
 */
exports.usage = usage;

/**
 * Standard options export.
 */
exports.options = options;

/**
 * Standard run method hook export.
 */
exports.run = run;
<|endoftext|>


<commit_before>/* global describe, it */

var expect = require('chai').expect;
var sinon = require('sinon');
var factory = require('../../../app/http/handlers/authorize');

describe('handlers/authorize', function() {

  it('should export factory function', function() {
    expect(factory).to.be.a('function');
  });

  describe('creating handler', function() {
    var server = {
      authorization: function(){},
      authorizationErrorHandler: function(){}
    };
    var validateClient = function(){};
    var processTransaction = function(){};
    var completeTransaction = function(){};
    var prompt = function(){};
    var authenticate = sinon.spy();
    var errorLogging = sinon.spy();

    var server_authorizationStub = sinon.stub(server, 'authorization').returns(
      function authorization(req, res, next){}
    );
    var server_authorizationErrorHandlerStub = sinon.stub(server, 'authorizationErrorHandler').returns([
      function transactionLoader(err, req, res, next){},
      function authorization(err, req, res, next){}
    ]);
    var handler = factory(server, validateClient, processTransaction, completeTransaction, prompt, authenticate, errorLogging);

    it('should return handler', function() {
      expect(handler).to.be.an('array');
      expect(handler[2]).to.equal(prompt);
    });

    it('should apply authenticate', function() {
      expect(authenticate).to.have.been.calledWithExactly([ 'session', 'anonymous' ]);
    });

    it('should apply authorization', function() {
      expect(server_authorizationStub).to.have.been.calledWithExactly(validateClient, processTransaction, completeTransaction);
    });

    it('should apply authorization error handler', function() {
      expect(server_authorizationStub).to.have.been.calledOnce;
    });
  });

});
<commit_msg>Improve authorize test.<commit_after>/* global describe, it */

var expect = require('chai').expect;
var sinon = require('sinon');
var factory = require('../../../app/http/handlers/authorize');

describe('http/handlers/authorize', function() {

  it('should export factory function', function() {
    expect(factory).to.be.a('function');
  });

  describe('creating handler', function() {
    var server = {
      authorization: function(){},
      authorizationErrorHandler: function(){}
    };
    var validateClient = function(){};
    var processTransaction = function(){};
    var completeTransaction = function(){};

    var authenticate = function(){};
    var authorization = function(){};
    var prompt = function(){};
    var errorLogging = function(){};
    var errorHandler = function(){};

    var authenticateStub = sinon.stub().returns(authenticate);
    var authorizationStub = sinon.stub(server, 'authorization').returns(authorization);
    var errorLoggingStub = sinon.stub().returns(errorLogging);
    var errorHandlerStub = sinon.stub(server, 'authorizationErrorHandler').returns(errorHandler);

    var handler = factory(server, validateClient, processTransaction, completeTransaction, prompt, authenticateStub, errorLoggingStub);

    it('should return handler', function() {
      expect(handler).to.be.an('array');
      expect(handler[0]).to.equal(authenticate);
      expect(handler[1]).to.equal(authorization);
      expect(handler[2]).to.equal(prompt);
      expect(handler[3]).to.equal(errorLogging);
      expect(handler[4]).to.equal(errorHandler);
    });

    it('should apply authenticate', function() {
      expect(authenticateStub).to.have.been.calledWithExactly([ 'session', 'anonymous' ]);
    });

    it('should apply authorization', function() {
      expect(authorizationStub).to.have.been.calledWithExactly(validateClient, processTransaction, completeTransaction);
    });

    it('should apply error handler', function() {
      expect(errorHandlerStub).to.have.been.calledOnce;
    });
  });

});
<|endoftext|>


<commit_before>const gulp = require('gulp');
const replace = require('gulp-replace');

const Builder = require('jspm').Builder;

const conf = require('../conf/gulp.conf');

gulp.task('systemjs', systemjs);
gulp.task('systemjs:html', updateIndexHtml);

function systemjs(done) {
  const builder = new Builder('./', 'jspm.config.js');
  builder.config({
    paths: {
      "github:*": "jspm_packages/github/*",
      "npm:*": "jspm_packages/npm/*"
    },
    packageConfigPaths: [
      'npm:@*/*.json',
      'npm:*.json',
      'github:*/*.json'
    ]
  });
  builder.buildStatic(
    <%- entry %>,
    conf.path.tmp('index.js')
  ).then(() => done(), done);
}

function updateIndexHtml() {
  return gulp.src(conf.path.src('index.html'))
    .pipe(replace(
      /<script>\n\s*System.import.*\n\s*<\/script>/,
      `<script src="index.js"></script>`
    ))
    .pipe(gulp.dest(conf.path.tmp()));
}
<commit_msg>Remove jspm scripts on build<commit_after>const gulp = require('gulp');
const replace = require('gulp-replace');

const Builder = require('jspm').Builder;

const conf = require('../conf/gulp.conf');

gulp.task('systemjs', systemjs);
gulp.task('systemjs:html', updateIndexHtml);

function systemjs(done) {
  const builder = new Builder('./', 'jspm.config.js');
  builder.config({
    paths: {
      "github:*": "jspm_packages/github/*",
      "npm:*": "jspm_packages/npm/*"
    },
    packageConfigPaths: [
      'npm:@*/*.json',
      'npm:*.json',
      'github:*/*.json'
    ]
  });
  builder.buildStatic(
    <%- entry %>,
    conf.path.tmp('index.js')
  ).then(() => done(), done);
}

function updateIndexHtml() {
  return gulp.src(conf.path.src('index.html'))
    .pipe(replace(
      /<script src="jspm_packages\/system.js">[\s\S]*System.import.*\n\s*<\/script>/,
      `<script src="index.js"></script>`
    ))
    .pipe(gulp.dest(conf.path.tmp()));
}
<|endoftext|>


<commit_before>'use strict';

const Promise = require('bluebird');
const MongoClient = require('mongodb').MongoClient;
const Assert = require('assert');

exports.plugin = {

    async register(server, options) {

        if (!options.connection) {
            const str = 'Invalid connection options';
            server.log(['hapi-multi-mongo', 'error'], str);
            throw new Error(str);
        }

        // main connection object
        const connections = {};
        // base, ref: Creating a regex for mongoose URI http://stackoverflow.com/a/25072703/12078
        const uriPattern = '^(mongodb:(?:\\/{2})?)((\\w+?):(\\w+?)@|:?@?)([\\w\\.]+?):(\\d+)(\\/(\\w+?))?$';
        // connection uris can be array or string
        const uris = Array.isArray(options.connection) ? options.connection : [options.connection];
        // global mongodb connection options, :/ sorry for ugly definition
        const globalOptions = options.options || {};
        const exposeName = options.name || 'mongo';

        const makeConnectionObject = (conf) => {

            let connObj = conf;
            // if this is a string, init with initial parameters
            if (typeof conf === 'string') {
                connObj = {
                    'uri': conf
                };
            }

            // merge options with globals
            // better to use Object methods
            connObj.options = Object.assign({}, globalOptions, connObj.options);

            return connObj;
        };

        const connect = async (uri) => {

            const connectionObj = makeConnectionObject(uri);
            const uriMatch = new RegExp(uriPattern).exec(connectionObj.uri);
            // validate mongodb connection uri
            if (uriMatch === null) {
                const str = 'Invalid mongo connection uri ' + connectionObj.uri;
                throw Error(str);
            }

            // set or get connection name
            // check name if it is not there
            if (!connectionObj.hasOwnProperty('name')) {
                // we assume last element of the connection uri has to be database name or user
                // has to provide a name for connection
                // check if there is a database name in connection
                Assert(uriMatch[uriMatch.length - 1], 'You have to provide a name for uri or have to connect to ' +
                    'directly to specific database.');

                // set connection objects name
                connectionObj.name = uriMatch[uriMatch.length - 1];
            }

            const connection = await MongoClient.connect(connectionObj.uri, connectionObj.options);
            server.log(['hapi-multi-mongo', 'info'], 'Mongo connection has been established: ' + connectionObj.name);

            connections[connectionObj.name] = connection;

            return connectionObj.name;
        };

        try {
            const allConnections = await Promise.all(uris.map(connect));
            server.log(['hapi-multi-mongo', 'info'], 'Mongo connections has been established: ' + allConnections);
        }
        catch (e) {
            const str = 'An error occurred during connection uri iteration: ' + e;
            server.log(['hapi-multi-mongo', 'error'], str);
            throw new Error(str);
        }

        // handy decorate option, borrowed from hapi-mongodb
        if (options.decorate === true) {
            server.decorate('server', exposeName, connections);
            server.decorate('request', exposeName, connections);
        }
        else {
            server.expose(exposeName, connections);
        }

        server.events.on('stop', () => {

            Promise.each(Object.keys(connections), (name) => {

                const conn = connections[name];

                // close mongo connection
                server.log(['hapi-multi-mongo', 'info'], 'Closing mongodb connection for: ' + name);
                conn.close((err) => {

                    server.log(['hapi-multi-mongo', 'error'], 'An error occurred while closing mongodb connection for. ' + name + ' => ' + err);
                });
            }).then(() => {

                server.log(['hapi-multi-mongo', 'info'], 'Mongo connections has been closed through app termination');
            });
        });
    },
    pkg: require('../package.json')
};

<commit_msg>Typo fixes<commit_after>'use strict';

const Promise = require('bluebird');
const MongoClient = require('mongodb').MongoClient;
const Assert = require('assert');

exports.plugin = {

    async register(server, options) {

        if (!options.connection) {
            const str = 'Invalid connection options';
            server.log(['hapi-multi-mongo', 'error'], str);
            throw new Error(str);
        }

        // main connection object
        const connections = {};
        // base, ref: Creating a regex for mongoose URI http://stackoverflow.com/a/25072703/12078
        const uriPattern = '^(mongodb:(?:\\/{2})?)((\\w+?):(\\w+?)@|:?@?)([\\w\\.]+?):(\\d+)(\\/(\\w+?))?$';
        // connection uris can be array or string
        const uris = Array.isArray(options.connection) ? options.connection : [options.connection];
        // global mongodb connection options, :/ sorry for ugly definition
        const globalOptions = options.options || {};
        const exposeName = options.name || 'mongo';

        const makeConnectionObject = (conf) => {

            let connObj = conf;
            // if this is a string, init with initial parameters
            if (typeof conf === 'string') {
                connObj = {
                    'uri': conf
                };
            }

            // merge options with globals
            connObj.options = Object.assign({}, globalOptions, connObj.options);

            return connObj;
        };

        const connect = async (uri) => {

            const connectionObj = makeConnectionObject(uri);
            const uriMatch = new RegExp(uriPattern).exec(connectionObj.uri);
            // validate mongodb connection uri
            if (uriMatch === null) {
                const str = 'Invalid mongo connection uri ' + connectionObj.uri;
                throw Error(str);
            }

            // set or get connection name
            // check name if it is not there
            if (!connectionObj.hasOwnProperty('name')) {
                // we assume the last element of the connection uri has to be database name or
                // user has to provide a name for the connection
                // check if there is a database name in connection
                Assert(uriMatch[uriMatch.length - 1], 'You have to provide a name for uri or have to connect to ' +
                    'directly to specific database.');

                // set connection objects name
                connectionObj.name = uriMatch[uriMatch.length - 1];
            }

            const connection = await MongoClient.connect(connectionObj.uri, connectionObj.options);
            server.log(['hapi-multi-mongo', 'info'], 'Mongo connection has been established: ' + connectionObj.name);

            connections[connectionObj.name] = connection;

            return connectionObj.name;
        };

        try {
            const allConnections = await Promise.all(uris.map(connect));
            server.log(['hapi-multi-mongo', 'info'], 'Mongo connections has been established: ' + allConnections);
        }
        catch (e) {
            const str = 'An error occurred during connection uri iteration: ' + e;
            server.log(['hapi-multi-mongo', 'error'], str);
            throw new Error(str);
        }

        // handy decorate option, borrowed from hapi-mongodb
        if (options.decorate === true) {
            server.decorate('server', exposeName, connections);
            server.decorate('request', exposeName, connections);
        }
        else {
            server.expose(exposeName, connections);
        }

        server.events.on('stop', () => {

            Promise.each(Object.keys(connections), (name) => {

                const conn = connections[name];

                // close mongo connection
                server.log(['hapi-multi-mongo', 'info'], 'Closing mongodb connection for: ' + name);
                conn.close((err) => {

                    server.log(['hapi-multi-mongo', 'error'], 'An error occurred while closing mongodb connection for. ' + name + ' => ' + err);
                });
            }).then(() => {

                server.log(['hapi-multi-mongo', 'info'], 'Mongo connections has been closed through app termination');
            });
        });
    },
    pkg: require('../package.json')
};

<|endoftext|>


<commit_before>var mkdirp = require('mkdirp');
var async = require('async');
var fs = require('fs');

/**
 * Ensures a directory exists using mkdir -p.
 *
 * @param {String} path
 * @param {Function} callback
 * @api public
 */

exports.ensureDir = function (path, callback) {
  mkdirp(path, callback);
};

/**
 * Creates a deep-clone of a JSON-serializable object
 *
 * @param obj - the object to serialize
 * @api public
 */

exports.jsonClone = function (obj) {
  return JSON.parse(JSON.stringify(obj));
};

/**
 * Send a 302 (Found) redirect response for a HTTP Server
 * Request object
 */

exports.redirect = function (loc, res) {
  res.writeHead(302, {Location: loc});
  return res.end(
    '' +
      '' +
        '<title>302 Found</title>' +
      '' +
      '' +
        '
' +
          'Found: ' + loc + '' +
        '
' +
      '' +
    ''
  );
};

/**
 * Makes sure the appropriate app directories exists
 */

exports.ensurePaths = function (config, callback) {
  var paths = [config.hoodie.app_path];

  async.map(paths, exports.ensureDir, callback);
};

/**
 * write app config to stack.json
 */

exports.writeConfig = function (config, callback) {

  var stackJSON = config.project_dir + '/data/stack.json';
  var stack = {
    couch: {
      port: Number(config.couch.port),
      host: config.host
    },
    www: {
      port: config.www_port,
      host: config.host
    },
    admin: {
      port: config.admin_port,
      host: config.host
    }
  };

  fs.writeFile(stackJSON, JSON.stringify(stack), function (err) {
    if (err) {
      return callback(new Error(
        'Hoodie could not write stack.json.\n' +
        'Please try again.'
      ));
    } else {
      return callback();
    }
  });

};

exports.processSend = function (err, callback) {
  if (process.send) {
    process.send({
      app: {
        started: true
      }
    });
  }

  return callback();
};

<commit_msg>call callback after process.send * * *<commit_after>var mkdirp = require('mkdirp');
var async = require('async');
var fs = require('fs');

/**
 * Ensures a directory exists using mkdir -p.
 *
 * @param {String} path
 * @param {Function} callback
 * @api public
 */

exports.ensureDir = function (path, callback) {
  mkdirp(path, callback);
};

/**
 * Creates a deep-clone of a JSON-serializable object
 *
 * @param obj - the object to serialize
 * @api public
 */

exports.jsonClone = function (obj) {
  return JSON.parse(JSON.stringify(obj));
};

/**
 * Send a 302 (Found) redirect response for a HTTP Server
 * Request object
 */

exports.redirect = function (loc, res) {
  res.writeHead(302, {Location: loc});
  return res.end(
    '' +
      '' +
        '<title>302 Found</title>' +
      '' +
      '' +
        '
' +
          'Found: ' + loc + '' +
        '
' +
      '' +
    ''
  );
};

/**
 * Makes sure the appropriate app directories exists
 */

exports.ensurePaths = function (config, callback) {
  var paths = [config.hoodie.app_path];

  async.map(paths, exports.ensureDir, callback);
};

/**
 * write app config to stack.json
 */

exports.writeConfig = function (config, callback) {

  var stackJSON = config.project_dir + '/data/stack.json';
  var stack = {
    couch: {
      port: Number(config.couch.port),
      host: config.host
    },
    www: {
      port: config.www_port,
      host: config.host
    },
    admin: {
      port: config.admin_port,
      host: config.host
    }
  };

  fs.writeFile(stackJSON, JSON.stringify(stack), function (err) {
    if (err) {
      return callback(new Error(
        'Hoodie could not write stack.json.\n' +
        'Please try again.'
      ));
    } else {
      return callback();
    }
  });

};

exports.processSend = function (config, callback) {
  if (process.send) {
    process.send({
      app: {
        started: true
      }
    });
  }
  return callback();
};

<|endoftext|>


<commit_before>// ================================================================
//  Description: Avatar Upload supporting script
//  License:     MIT - check License.txt file for details
//  Author:      Codative Corp. (http://www.codative.com/)
// ================================================================
var jcrop_api,
    boundx,
    boundy,
    xsize,
    ysize;

// ToDo - change the size limit of the file. You may need to change web.config if larger files are necessary.
var maxSizeAllowed = 2;     // Upload limit in MB
var maxSizeInBytes = maxSizeAllowed * 1024 * 1024;
var keepUploadBox = false;  // ToDo - Remove if you want to keep the upload box
var keepCropBox = false;    // ToDo - Remove if you want to keep the crop box

$(function () {
    if (typeof $('#avatar-upload-form') !== undefined) {
        initAvatarUpload();
        $('#avatar-max-size').html(maxSizeAllowed);
        $('#avatar-upload-form input:file').on("change", function (e) {
            var files = e.currentTarget.files;
            for (var x in files) {
                if (files[x].name != "item" && typeof files[x].name != "undefined") {
                    if (files[x].size <= maxSizeInBytes) {
                        // Submit the selected file
                        $('#avatar-upload-form .upload-file-notice').removeClass('bg-danger');
                        $('#avatar-upload-form').submit();
                    } else {
                        // File too large
                        $('#avatar-upload-form .upload-file-notice').addClass('bg-danger');
                    }
                }
            }
        });
    }
});

function initAvatarUpload() {
    $('#avatar-upload-form').ajaxForm({
        beforeSend: function () {
            updateProgress(0);
            $('#avatar-upload-form').addClass('hidden');
        },
        uploadProgress: function (event, position, total, percentComplete) {
            updateProgress(percentComplete);
        },
        success: function (data) {
            updateProgress(100);
            if (data.success === false) {
                $('#status').html(data.errorMessage);
            } else {
                $('#preview-pane .preview-container img').attr('src', data.avatarFileLocation);
                var img = $('#crop-avatar-target');
                img.attr('src', data.avatarFileLocation);

                if (!keepUploadBox) {
                    $('#avatar-upload-box').addClass('hidden');
                }
                $('#avatar-crop-box').removeClass('hidden');
                initAvatarCrop(img);
            }
        },
        complete: function (xhr) {
        }
    });
}

function updateProgress(percentComplete) {
    $('.upload-percent-bar').width(percentComplete + '%');
    $('.upload-percent-value').html(percentComplete + '%');
    if (percentComplete === 0) {
        $('#upload-status').empty();
        $('.upload-progress').removeClass('hidden');
    }
}

function initAvatarCrop(img) {
    img.Jcrop({
        onChange: updatePreviewPane,
        onSelect: updatePreviewPane,
        aspectRatio: xsize / ysize
    }, function () {
        var bounds = this.getBounds();
        boundx = bounds[0];
        boundy = bounds[1];

        jcrop_api = this;
        jcrop_api.setOptions({ allowSelect: true });
        jcrop_api.setOptions({ allowMove: true });
        jcrop_api.setOptions({ allowResize: true });
        jcrop_api.setOptions({ aspectRatio: 1 });

        // Maximise initial selection around the centre of the image,
        // but leave enough space so that the boundaries are easily identified.
        var padding = 10;
        var shortEdge = (boundx < boundy ? boundx : boundy) - padding;
        var longEdge = boundx < boundy ? boundy : boundx;
        var xCoord = longEdge / 2 - shortEdge / 2;
        jcrop_api.animateTo([xCoord, padding, shortEdge, shortEdge]);

        var pcnt = $('#preview-pane .preview-container');
        xsize = pcnt.width();
        ysize = pcnt.height();
        $('#preview-pane').appendTo(jcrop_api.ui.holder);
        jcrop_api.focus();
    });
}

function updatePreviewPane(c) {
    if (parseInt(c.w) > 0) {
        var rx = xsize / c.w;
        var ry = ysize / c.h;

        $('#preview-pane .preview-container img').css({
            width: Math.round(rx * boundx) + 'px',
            height: Math.round(ry * boundy) + 'px',
            marginLeft: '-' + Math.round(rx * c.x) + 'px',
            marginTop: '-' + Math.round(ry * c.y) + 'px'
        });
    }
}

function saveAvatar() {
    var img = $('#preview-pane .preview-container img');
    $('#avatar-crop-box button').addClass('disabled');

    $.ajax({
        type: "POST",
        url: "/UploadImage/Save",
        traditional: true,
        data: {
            w: img.css('width'),
            h: img.css('height'),
            l: img.css('marginLeft'),
            t: img.css('marginTop'),
            fileName: img.attr('src')
        }
    }).done(function (data) {
        if (data.success === true) {
            $(location).attr('href', '/account/register');
            toastr.success('Done! Please continue your registration');
        } else {
            toastr.error(data.errorMessage)
        }
    }).fail(function (e) {
        toastr.error('Cannot upload avatar at this time');
    });
}<commit_msg>fix toaster error<commit_after>// ================================================================
//  Description: Avatar Upload supporting script
//  License:     MIT - check License.txt file for details
//  Author:      Codative Corp. (http://www.codative.com/)
// ================================================================
var jcrop_api,
    boundx,
    boundy,
    xsize,
    ysize;

// ToDo - change the size limit of the file. You may need to change web.config if larger files are necessary.
var maxSizeAllowed = 2;     // Upload limit in MB
var maxSizeInBytes = maxSizeAllowed * 1024 * 1024;
var keepUploadBox = false;  // ToDo - Remove if you want to keep the upload box
var keepCropBox = false;    // ToDo - Remove if you want to keep the crop box

$(function () {
    if (typeof $('#avatar-upload-form') !== undefined) {
        initAvatarUpload();
        $('#avatar-max-size').html(maxSizeAllowed);
        $('#avatar-upload-form input:file').on("change", function (e) {
            var files = e.currentTarget.files;
            for (var x in files) {
                if (files[x].name != "item" && typeof files[x].name != "undefined") {
                    if (files[x].size <= maxSizeInBytes) {
                        // Submit the selected file
                        $('#avatar-upload-form .upload-file-notice').removeClass('bg-danger');
                        $('#avatar-upload-form').submit();
                    } else {
                        // File too large
                        toastr.error("File too large");
                    }
                }
            }
        });
    }
});

function initAvatarUpload() {
    $('#avatar-upload-form').ajaxForm({
        beforeSend: function () {
            updateProgress(0);
            $('#avatar-upload-form').addClass('hidden');
        },
        uploadProgress: function (event, position, total, percentComplete) {
            updateProgress(percentComplete);
        },
        success: function (data) {
            updateProgress(100);
            if (data.success === false) {
                $('#status').html(data.errorMessage);
            } else {
                $('#preview-pane .preview-container img').attr('src', data.avatarFileLocation);
                var img = $('#crop-avatar-target');
                img.attr('src', data.avatarFileLocation);

                if (!keepUploadBox) {
                    $('#avatar-upload-box').addClass('hidden');
                }
                $('#avatar-crop-box').removeClass('hidden');
                initAvatarCrop(img);
            }
        },
        complete: function (xhr) {
        }
    });
}

function updateProgress(percentComplete) {
    $('.upload-percent-bar').width(percentComplete + '%');
    $('.upload-percent-value').html(percentComplete + '%');
    if (percentComplete === 0) {
        $('#upload-status').empty();
        $('.upload-progress').removeClass('hidden');
    }
}

function initAvatarCrop(img) {
    img.Jcrop({
        onChange: updatePreviewPane,
        onSelect: updatePreviewPane,
        aspectRatio: xsize / ysize
    }, function () {
        var bounds = this.getBounds();
        boundx = bounds[0];
        boundy = bounds[1];

        jcrop_api = this;
        jcrop_api.setOptions({ allowSelect: true });
        jcrop_api.setOptions({ allowMove: true });
        jcrop_api.setOptions({ allowResize: true });
        jcrop_api.setOptions({ aspectRatio: 1 });

        // Maximise initial selection around the centre of the image,
        // but leave enough space so that the boundaries are easily identified.
        var padding = 10;
        var shortEdge = (boundx < boundy ? boundx : boundy) - padding;
        var longEdge = boundx < boundy ? boundy : boundx;
        var xCoord = longEdge / 2 - shortEdge / 2;
        jcrop_api.animateTo([xCoord, padding, shortEdge, shortEdge]);

        var pcnt = $('#preview-pane .preview-container');
        xsize = pcnt.width();
        ysize = pcnt.height();
        $('#preview-pane').appendTo(jcrop_api.ui.holder);
        jcrop_api.focus();
    });
}

function updatePreviewPane(c) {
    if (parseInt(c.w) > 0) {
        var rx = xsize / c.w;
        var ry = ysize / c.h;

        $('#preview-pane .preview-container img').css({
            width: Math.round(rx * boundx) + 'px',
            height: Math.round(ry * boundy) + 'px',
            marginLeft: '-' + Math.round(rx * c.x) + 'px',
            marginTop: '-' + Math.round(ry * c.y) + 'px'
        });
    }
}

function saveAvatar() {
    var img = $('#preview-pane .preview-container img');
    $('#avatar-crop-box button').addClass('disabled');

    $.ajax({
        type: "POST",
        url: "/UploadImage/Save",
        traditional: true,
        data: {
            w: img.css('width'),
            h: img.css('height'),
            l: img.css('marginLeft'),
            t: img.css('marginTop'),
            fileName: img.attr('src')
        }
    }).done(function (data) {
        if (data.success === true) {
            $(location).attr('href', '/account/register');
            toastr.success('Done! Please continue your registration');
        } else {
            toastr.error(data.errorMessage)
        }
    }).fail(function (e) {
        toastr.error('Cannot upload avatar at this time');
    });
}<|endoftext|>


<commit_before>udefine(['mixedice', 'eventmap'], function(mixedice, EventMap) {
  'use strict';

  var Texture = function() {
    mixedice([this, Texture.prototype], new EventMap());

    var self = this;

    this.width = 0;
    this.height = 0;

    this.parent = null;

    this.image = {
      offset: {
        x: 0,
        y: 0
      },
      data: null,
      width: 0,
      height: 0
    };

    var filename = '';

    // TODO: Filename is not clear enough, maybe
    // image.filename
    Object.defineProperty(this.image, 'filename', {
      get: function() {
        return filename;
      },
      set: function(value) {
        filename = value;

        // TODO: Most of this should already be handled by the preloader
        var img = new Image();
        img.src = filename;

        img.onload = function() {
          self.image.data = img;
          self.image.width = img.width;
          self.image.height = img.height;

          self.trigger('image-loaded');
        };
      },
      enumerable: true
    });

    this.label = {
      font: {
        size: 10,
        name: 'Arial',
        color: 'rgb(0, 0, 0)'
      }
    };

    var text = '';

    Object.defineProperty(this.label, 'text', {
    	get: function() {
    		return text;
    	},
    	set: function(value) {
    		text = value;

    		self.trigger('label-loaded');
    	}
    });

    this.color = 'rgb(255, 255, 255)';

  };

  return Texture;
});
<commit_msg>Add property for label alignment<commit_after>udefine(['mixedice', 'eventmap'], function(mixedice, EventMap) {
  'use strict';

  var Texture = function() {
    mixedice([this, Texture.prototype], new EventMap());

    var self = this;

    this.width = 0;
    this.height = 0;

    this.parent = null;

    this.image = {
      offset: {
        x: 0,
        y: 0
      },
      data: null,
      width: 0,
      height: 0
    };

    var filename = '';

    // TODO: Filename is not clear enough, maybe
    // image.filename
    Object.defineProperty(this.image, 'filename', {
      get: function() {
        return filename;
      },
      set: function(value) {
        filename = value;

        // TODO: Most of this should already be handled by the preloader
        var img = new Image();
        img.src = filename;

        img.onload = function() {
          self.image.data = img;
          self.image.width = img.width;
          self.image.height = img.height;

          self.trigger('image-loaded');
        };
      },
      enumerable: true
    });

    this.label = {
      font: {
        size: 10,
        name: 'Arial',
        color: 'rgb(0, 0, 0)'
      },
      align: {
      	x: 'center',
      	y: 'center'
      }
    };

    var text = '';

    Object.defineProperty(this.label, 'text', {
    	get: function() {
    		return text;
    	},
    	set: function(value) {
    		text = value;

    		self.trigger('label-loaded');
    	}
    });

    this.color = 'rgb(255, 255, 255)';

  };

  return Texture;
});
<|endoftext|>


<commit_before>/**
 * ///////////////////////////////////////
 * ////////// Gravatar module ////////////
 * ///////////////////////////////////////
 *
 * This module offers object caching mechanisms for
 * third-party modules. It also allows to set a time-to-live
 * to the cached objects.
 */

 /**
  * Exporting the `Gravatar` module appropriately given
  * the environment (AMD, Node.js and the browser).
  */
 (function (name, definition) {
    if (typeof define === 'function' && define.amd) {
        // Defining the module in an AMD fashion.
        define(['blueimp-md5', 'isomorphic-fetch', 'proxify-url'], definition);
    } else if (typeof module !== 'undefined' && module.exports) {
        // Exporting the module for Node.js/io.js.
        module.exports = definition(
          require('blueimp-md5').md5,
          require('isomorphic-fetch'),
          require('proxify-url')
        );
    } else {
        var instance = definition(this.md5, this.fetch, this.proxify);
        var old      = this[name];

        /**
         * Allowing to scope the module
         * avoiding global namespace pollution.
         */
        instance.noConflict = function () {
            this[name] = old;
            return instance;
        };
        this[name] = instance;
    }
 })('gravatar', function (md5, fetch, proxify) {

  /**
   * The Gravatar service base URL.
   */
  var serviceUrl = 'https://secure.gravatar.com';

  /**
   * The default values associated with the
   * request.
   */
  var defaults = {

    /**
     * The default behaviour when no image is
     * associated with the given e-mail address.
     */
    defaultIcon: '404',

    /**
     * Defines whether to retrieve an avatar given
     * its category, or rating.
     * See https://en.gravatar.com/site/implement/images#rating
     */
    rating: 'G',

    /**
     * Defines the size of the image in pixels.
     */
    size: '80'
  };

  /**
   * Shorthand function to use with the fetch API
   * to obtain a JSON payload from a reponse.
   */
  var toJson = function (res) {
    return (res.json());
  };

  /**
   * Helper used to stringify the key/value pairs
   * of an object into a query string.
   */
  var encodeParameters = function (data) {
    var params = [];

    for (var d in data) {
      if (data.hasOwnProperty(d) && data[d]) {
        params.push(encodeURIComponent(d) + '=' + encodeURIComponent(data[d]));
      }
    }
    return params.join('&');
  };

  /**
   * Returns a MD5-hashed representation
   * of the given e-mail address according to
   * Gravatar's specifications.
   * See https://en.gravatar.com/site/implement/hash/
   */
  var hash = function (email) {
    return md5(email.trim().toLowerCase());
  };

  /**
   * Helper used to build the actual avatar
   * endpoint URL.
   */
  var avatarUrl = function (email, options) {
      options = options || {};
      var serviceAvatar = serviceUrl + '/avatar/';
      var opts = {
        'default': options.defaultIcon || defaults.defaultIcon,
        rating: options.rating || defaults.rating,
        size: options.size || defaults.size
      };
      if (!email) { throw new Error('An email address is required'); }
      return serviceAvatar + hash(email) + '?' + encodeParameters(opts);
  };

  /**
   * Helper used to build the profile endpoint
   * URL.
   */
  var profileUrl = function (email, options) {
    options = options || {};
    if (!email) { throw new Error('An email address is required'); }
    return proxify(serviceUrl + '/'
      + (options.hash === false ? email : hash(email))
      + '.'
      + options.format);
  };

  return {
    get: {

      /**
       * Constructs the user avatar URL associated with
       * the given e-mail address.
       */
      url: function (email, options) {
        return avatarUrl(email, options);
      },

      /**
       * Retrieves the personal informations associated
       * with the owner of the given e-mail address.
       */
      profiles: function (email) {
        var url = profileUrl(email, { format: 'json' });

        return fetch(url)
          .then(toJson)
          .then(function (data) {
            return (data.query.count > 0) ?
              Promise.resolve(data.query.results.json.entry) :
              Promise.reject('Unexpected response');
          });
      }
    },

    /**
     * Tries to resolve the given e-mail address using the
     * given options. This method is handy to determine
     * whether an avatar actually exists on the Gravatar
     * service for the given e-mail address.
     * @returns a promise resolved if the avatar was able to
     * be retrieved, and rejected if the retrieval failed.
     */
    resolve: function (email, options) {
      var url = this.get.url(email, options);

      return fetch(url, { method: 'HEAD' }).then(function (response) {
        return (response.status === 200) ?
          Promise.resolve(url) :
          Promise.reject('Avatar does not exist');
      });
    }
  };
 });
<commit_msg>Using blueimp-md5 root object in Node.js.<commit_after>/**
 * ///////////////////////////////////////
 * ////////// Gravatar module ////////////
 * ///////////////////////////////////////
 *
 * This module offers object caching mechanisms for
 * third-party modules. It also allows to set a time-to-live
 * to the cached objects.
 */

 /**
  * Exporting the `Gravatar` module appropriately given
  * the environment (AMD, Node.js and the browser).
  */
 (function (name, definition) {
    if (typeof define === 'function' && define.amd) {
        // Defining the module in an AMD fashion.
        define(['blueimp-md5', 'isomorphic-fetch', 'proxify-url'], definition);
    } else if (typeof module !== 'undefined' && module.exports) {
        // Exporting the module for Node.js/io.js.
        module.exports = definition(
          require('blueimp-md5'),
          require('isomorphic-fetch'),
          require('proxify-url')
        );
    } else {
        var instance = definition(this.md5, this.fetch, this.proxify);
        var old      = this[name];

        /**
         * Allowing to scope the module
         * avoiding global namespace pollution.
         */
        instance.noConflict = function () {
            this[name] = old;
            return instance;
        };
        this[name] = instance;
    }
 })('gravatar', function (md5, fetch, proxify) {

  /**
   * The Gravatar service base URL.
   */
  var serviceUrl = 'https://secure.gravatar.com';

  /**
   * The default values associated with the
   * request.
   */
  var defaults = {

    /**
     * The default behaviour when no image is
     * associated with the given e-mail address.
     */
    defaultIcon: '404',

    /**
     * Defines whether to retrieve an avatar given
     * its category, or rating.
     * See https://en.gravatar.com/site/implement/images#rating
     */
    rating: 'G',

    /**
     * Defines the size of the image in pixels.
     */
    size: '80'
  };

  /**
   * Shorthand function to use with the fetch API
   * to obtain a JSON payload from a reponse.
   */
  var toJson = function (res) {
    return (res.json());
  };

  /**
   * Helper used to stringify the key/value pairs
   * of an object into a query string.
   */
  var encodeParameters = function (data) {
    var params = [];

    for (var d in data) {
      if (data.hasOwnProperty(d) && data[d]) {
        params.push(encodeURIComponent(d) + '=' + encodeURIComponent(data[d]));
      }
    }
    return params.join('&');
  };

  /**
   * Returns a MD5-hashed representation
   * of the given e-mail address according to
   * Gravatar's specifications.
   * See https://en.gravatar.com/site/implement/hash/
   */
  var hash = function (email) {
    return md5(email.trim().toLowerCase());
  };

  /**
   * Helper used to build the actual avatar
   * endpoint URL.
   */
  var avatarUrl = function (email, options) {
      options = options || {};
      var serviceAvatar = serviceUrl + '/avatar/';
      var opts = {
        'default': options.defaultIcon || defaults.defaultIcon,
        rating: options.rating || defaults.rating,
        size: options.size || defaults.size
      };
      if (!email) { throw new Error('An email address is required'); }
      return serviceAvatar + hash(email) + '?' + encodeParameters(opts);
  };

  /**
   * Helper used to build the profile endpoint
   * URL.
   */
  var profileUrl = function (email, options) {
    options = options || {};
    if (!email) { throw new Error('An email address is required'); }
    return proxify(serviceUrl + '/'
      + (options.hash === false ? email : hash(email))
      + '.'
      + options.format);
  };

  return {
    get: {

      /**
       * Constructs the user avatar URL associated with
       * the given e-mail address.
       */
      url: function (email, options) {
        return avatarUrl(email, options);
      },

      /**
       * Retrieves the personal informations associated
       * with the owner of the given e-mail address.
       */
      profiles: function (email) {
        var url = profileUrl(email, { format: 'json' });

        return fetch(url)
          .then(toJson)
          .then(function (data) {
            return (data.query.count > 0) ?
              Promise.resolve(data.query.results.json.entry) :
              Promise.reject('Unexpected response');
          });
      }
    },

    /**
     * Tries to resolve the given e-mail address using the
     * given options. This method is handy to determine
     * whether an avatar actually exists on the Gravatar
     * service for the given e-mail address.
     * @returns a promise resolved if the avatar was able to
     * be retrieved, and rejected if the retrieval failed.
     */
    resolve: function (email, options) {
      var url = this.get.url(email, options);

      return fetch(url, { method: 'HEAD' }).then(function (response) {
        return (response.status === 200) ?
          Promise.resolve(url) :
          Promise.reject('Avatar does not exist');
      });
    }
  };
 });
<|endoftext|>


<commit_before>var fs     = require('fs'),
Handlebars = require('handlebars'),
Assets     = require('./Assets'),
sass       = require('node-sass');

var Router = function() {
	this.routes = ['/'];
};

Router.prototype.map = function() {
	var _this = this;
	[].forEach.call(arguments, function (el) {
		_this.routes.push(el);
	});
};

Router.prototype.validRoute = function(route) {
	var found     = false,
	paramsValue    = {},
	originalRoute = null;

	route = route == "" ? "/" : route;

	this.routes.forEach(function(element, index) {
		if (!found) {
			originalRoute = element;
		}

		if (element === route) {
			found = true;
		}
		else if (element.indexOf(':') != -1) {
			var t1 = element.match(/\//g);
			var t2 = route.match(/\//g);

			if (t1.length === t2.length) {
				var originalRouteSplited = element.split("/");
				var routeSplited = route.split("/");

				originalRouteSplited.forEach(function (el, i) {
					if (el.indexOf(':') != -1) {
						var tmp = el.slice(1, el.length);
						paramsValue[tmp] = routeSplited[i];
					}
				});
				found = true;
			}
		}
	});

	return {
    found: found,
    originalRoute: originalRoute,
    paramsValue: paramsValue
	};
};

Router.prototype.manage = function(req, res) {
	var method = req.method;
	var urlRequested = req.url;
	var assets = new Assets(res);
	var path = '';

	if (assets.check(urlRequested)) {
		assets.getPath();

		if (assets.isCSS()) {
			assets.compileSCSS();
		}
		else {
			assets.readImage();
		}
	}
	else {
		var questionMark = urlRequested.indexOf("?");

		if (questionMark != -1) {
			var parameters = urlRequested.slice(questionMark + 1, urlRequested.length);
			urlRequested = urlRequested.slice(0, questionMark);
		}

		var validRoute = this.validRoute(urlRequested);

		if (!validRoute.found) {
			path += "app/views/global/404.html";
			fs.readFile(path, function(err, data) {
				if (err) { console.log("ERROR LOADING FILE WITH " + _this.url + " URL"); }
		    res.end(data);
			});
		}
		else {
			var controllerPath = "../app/controllers/";
			controllerPath +=  urlRequested.length > 1 ? Router.getFileName(validRoute.originalRoute) : "index";
			controllerPath += ".js";

			var controller = require('./smart').Controller.setup(req, res, validRoute.paramsValue);

			fs.exists(__dirname +'/'+ controllerPath, function(exist) {
				if (exist) {
					require(controllerPath)();
				}
			});

			path += "app/views/";
			path += urlRequested.length > 1 ? Router.getFileName(validRoute.originalRoute) : "index";
			path += ".hbs";

			controller.execute(Handlebars, fs, path);

		}
	}
};

Router.parseURL = function(url) {
	var colon = url.indexOf(':');

	if (colon != -1) {
		var tmp = url.slice(colon, url.length);
		var tmp2 = tmp.slice(0, tmp.indexOf('/') != -1 ? tmp.indexOf('/') : tmp.length );

		if (url.indexOf(tmp2) + tmp2.length == url.length) {
			url = url.replace(tmp2, 'Show');
		}
		else {
			url = url.replace("/"+ tmp2, '');
		}
	}

	return url;
}

Router.getFileName = function(urlRequested) {
	var urlParsed = Router.parseURL(urlRequested);

	return urlParsed.toLowerCase().replace(/\/(.)/g, function(match, group1) {
  	return group1.toUpperCase();
	});
}

module.exports = Router;<commit_msg>Fix path issues about cross plateform support<commit_after>var fs     = require('fs'),
Handlebars = require('handlebars'),
Assets     = require('./Assets'),
Path       = require('path'),
sass       = require('node-sass');

var Router = function() {
	this.routes = ['/'];
};

Router.prototype.map = function() {
	var _this = this;
	[].forEach.call(arguments, function (el) {
		_this.routes.push(el);
	});
};

Router.prototype.validRoute = function(route) {
	var found     = false,
	paramsValue    = {},
	originalRoute = null;

	route = route == "" ? "/" : route;

	this.routes.forEach(function(element, index) {
		if (!found) {
			originalRoute = element;
		}

		if (element === route) {
			found = true;
		}
		else if (element.indexOf(':') != -1) {
			var t1 = element.match(/\//g);
			var t2 = route.match(/\//g);

			if (t1.length === t2.length) {
				var originalRouteSplited = element.split("/");
				var routeSplited = route.split("/");

				originalRouteSplited.forEach(function (el, i) {
					if (el.indexOf(':') != -1) {
						var tmp = el.slice(1, el.length);
						paramsValue[tmp] = routeSplited[i];
					}
				});
				found = true;
			}
		}
	});

	return {
    found: found,
    originalRoute: originalRoute,
    paramsValue: paramsValue
	};
};

Router.prototype.manage = function(req, res) {
	var method = req.method;
	var urlRequested = req.url;
	var assets = new Assets(res);
	var path = '';

	if (assets.check(urlRequested)) {
		assets.getPath();

		if (assets.isCSS()) {
			assets.compileSCSS();
		}
		else {
			assets.readImage();
		}
	}
	else {
		var questionMark = urlRequested.indexOf("?");

		if (questionMark != -1) {
			var parameters = urlRequested.slice(questionMark + 1, urlRequested.length);
			urlRequested = urlRequested.slice(0, questionMark);
		}

		var validRoute = this.validRoute(urlRequested);

		if (!validRoute.found) {
			path += "app/views/global/404.html";
			fs.readFile(path, function(err, data) {
				if (err) { console.log("ERROR LOADING FILE WITH " + _this.url + " URL"); }
		    res.end(data);
			});
		}
		else {
			var controllerPath = "/app/controllers/";
			controllerPath +=  urlRequested.length > 1 ? Router.getFileName(validRoute.originalRoute) : "index";
			controllerPath += ".js";

			var controller = require('./smart').Controller.setup(req, res, validRoute.paramsValue);

			var folder = Path.dirname(require.main.filename);

			fs.exists( Path.join(folder, controllerPath), function(exist) {
				if (exist) {
					require(Path.join(folder, controllerPath))();
				}
			});

			path += "app/views/";
			path += urlRequested.length > 1 ? Router.getFileName(validRoute.originalRoute) : "index";
			path += ".hbs";

			controller.execute(Handlebars, fs, path);

		}
	}
};

Router.parseURL = function(url) {
	var colon = url.indexOf(':');

	if (colon != -1) {
		var tmp = url.slice(colon, url.length);
		var tmp2 = tmp.slice(0, tmp.indexOf('/') != -1 ? tmp.indexOf('/') : tmp.length );

		if (url.indexOf(tmp2) + tmp2.length == url.length) {
			url = url.replace(tmp2, 'Show');
		}
		else {
			url = url.replace("/"+ tmp2, '');
		}
	}

	return url;
}

Router.getFileName = function(urlRequested) {
	var urlParsed = Router.parseURL(urlRequested);

	return urlParsed.toLowerCase().replace(/\/(.)/g, function(match, group1) {
  	return group1.toUpperCase();
	});
}

module.exports = Router;<|endoftext|>