<commit_before>'use strict';

require('node-jsx').install({ extension: '.jsx' });

var _       = require('lodash');
var config  = require('app/config');
var Hapi    = require('hapi');
var isDev   = process.env.NODE_ENV === 'development';
var server  = new Hapi.Server(process.env.REACT_COMPONENTS_PORT || 3000);
var render  = require('app/react/renderer');
var pkgInfo = require('./package.json');
var tpl     = function(file) { return __dirname + '/templates/' + file + '.html'; };
var params = {
    'package': pkgInfo,
    'page': {
        description: pkgInfo.description,
        title: 'React Components'
    },
    'resources': {
        css: [
            '/css/pure-min.css',
            '/css/codemirror.css',
            '/css/components.css'
        ],
        js: [
            '/js/codemirror-compressed.js',
            '/js/analytics.js',
            '/dist/vendor.bundle.js',
            '/dist/bundle.js',
        ]
    }
};

var ServerActions = require('app/actions/server');
var NpmApi = require('app/api/npm-api');
var GithubApi = require('app/api/github-api');

var controllers = {
    components: require('app/controllers/components')
};

var stores = {
    components: require('app/stores/components-store')
};

function startNpmModulesPolling() {
    // Prime the github API cache so we don't hammer the API
    GithubApi.initStarCountCache(function(err) {
        if (err) {
            return console.error('Failed to init star count cache: ', err);
        }

        // Have the API modules listen for actions
        NpmApi.listen();
        GithubApi.listen();

        // Do a request every once in a while
        setInterval(ServerActions.getModulesFromNpm, config['poll-interval']);

        // Fetch straight away so we have something to deliver to clients
        ServerActions.getModulesFromNpm();
    });
}

function getPageTitle(query) {
    if (!query) {
        return params.page.title;
    }

    return query + ' - ' + params.page.title;
}

function handleRequest(request, reply) {
    var reqParams = _.merge({}, params, {
        page: {
            title: getPageTitle(request.params.query || request.params.component)
        }
    });

    var liveReloadSrc = isDev ? ' localhost:35729' : '';
    var analyticsSrc = ' http://www.google-analytics.com https://www.google-analytics.com';

    reply(render(request, reqParams, tpl('default')))
        .header('X-UA-Compatible', 'IE=edge,chrome=1')
        .header('Cache-Control', 'public, must-revalidate, max-age=150')
        .header('Content-Security-Policy', [
            'script-src \'self\'' + liveReloadSrc + analyticsSrc,
            'frame-src \'none\'',
            'object-src \'none\''
        ].join(';'));
}

server.route({
    method: 'GET',
    path: '/',
    handler: handleRequest
});

server.route({
    method: 'GET',
    path: '/search/{query}',
    handler: handleRequest
});

server.route({
    method: 'GET',
    path: '/component/{component}',
    handler: handleRequest
});

server.route({
    method: 'GET',
    path: '/api/components',
    config: {
        handler: controllers.components.componentsList,
        cache: { expiresIn: config['poll-interval'], privacy: 'public' }
    }
});

server.route({
    method: 'GET',
    path: '/api/components/{component}',
    config: {
        handler: controllers.components.componentInfo
    }
});

server.route({
    method: 'GET',
    path: '/{param*}',
    handler: {
        directory: {
            path: 'public',
            lookupCompressed: true
        }
    }
});

server.start(function() {
    console.log('Server running at:', server.info.uri);

    startNpmModulesPolling();
});<commit_msg>Cache static assets for 1 hour<commit_after>'use strict';

require('node-jsx').install({ extension: '.jsx' });

var _       = require('lodash');
var config  = require('app/config');
var Hapi    = require('hapi');
var isDev   = process.env.NODE_ENV === 'development';
var server  = new Hapi.Server(process.env.REACT_COMPONENTS_PORT || 3000);
var render  = require('app/react/renderer');
var pkgInfo = require('./package.json');
var tpl     = function(file) { return __dirname + '/templates/' + file + '.html'; };
var params = {
    'package': pkgInfo,
    'page': {
        description: pkgInfo.description,
        title: 'React Components'
    },
    'resources': {
        css: [
            '/css/pure-min.css',
            '/css/codemirror.css',
            '/css/components.css'
        ],
        js: [
            '/js/codemirror-compressed.js',
            '/js/analytics.js',
            '/dist/vendor.bundle.js',
            '/dist/bundle.js',
        ]
    }
};

var ServerActions = require('app/actions/server');
var NpmApi = require('app/api/npm-api');
var GithubApi = require('app/api/github-api');

var controllers = {
    components: require('app/controllers/components')
};

var stores = {
    components: require('app/stores/components-store')
};

function startNpmModulesPolling() {
    // Prime the github API cache so we don't hammer the API
    GithubApi.initStarCountCache(function(err) {
        if (err) {
            return console.error('Failed to init star count cache: ', err);
        }

        // Have the API modules listen for actions
        NpmApi.listen();
        GithubApi.listen();

        // Do a request every once in a while
        setInterval(ServerActions.getModulesFromNpm, config['poll-interval']);

        // Fetch straight away so we have something to deliver to clients
        ServerActions.getModulesFromNpm();
    });
}

function getPageTitle(query) {
    if (!query) {
        return params.page.title;
    }

    return query + ' - ' + params.page.title;
}

function handleRequest(request, reply) {
    var reqParams = _.merge({}, params, {
        page: {
            title: getPageTitle(request.params.query || request.params.component)
        }
    });

    var liveReloadSrc = isDev ? ' localhost:35729' : '';
    var analyticsSrc = ' http://www.google-analytics.com https://www.google-analytics.com';

    reply(render(request, reqParams, tpl('default')))
        .header('X-UA-Compatible', 'IE=edge,chrome=1')
        .header('Cache-Control', 'public, must-revalidate, max-age=150')
        .header('Content-Security-Policy', [
            'script-src \'self\'' + liveReloadSrc + analyticsSrc,
            'frame-src \'none\'',
            'object-src \'none\''
        ].join(';'));
}

server.route({
    method: 'GET',
    path: '/',
    handler: handleRequest
});

server.route({
    method: 'GET',
    path: '/search/{query}',
    handler: handleRequest
});

server.route({
    method: 'GET',
    path: '/component/{component}',
    handler: handleRequest
});

server.route({
    method: 'GET',
    path: '/api/components',
    config: {
        handler: controllers.components.componentsList,
        cache: { expiresIn: config['poll-interval'], privacy: 'public' }
    }
});

server.route({
    method: 'GET',
    path: '/api/components/{component}',
    config: {
        handler: controllers.components.componentInfo
    }
});

server.route({
    method: 'GET',
    path: '/{param*}',
    config: {
        handler: {
            directory: {
                path: 'public',
                lookupCompressed: true
            }
        },
        cache: { expiresIn: 3600 * 1000, privacy: 'public' }
    }
});

server.start(function() {
    console.log('Server running at:', server.info.uri);

    startNpmModulesPolling();
});<|endoftext|>


<commit_before>var http    = require('http');
var pkg     = require('./package');
var through = require('through');
var trumpet = require('trumpet')();

var elements = [],
    json     = [];

function push (buf) {
  var data = buf.toString().trim();
  if (data !== '') {
    var imgIndex = data.indexOf('&');
    if (imgIndex > -1) {
      data = data.substr(0, imgIndex) + "'";
    }
    elements.push(data);
  }
};

parseResults = function (cb) {
  trumpet.selectAll('.fs *', function(el) {
    el.createReadStream().pipe(el.createWriteStream({outer: true}));
  });

  trumpet.selectAll('.fd *', function(el) {
    el.createReadStream().pipe(el.createWriteStream({outer: true}));
  });

  trumpet.selectAll('.fd', function (row) {
    row.createReadStream().pipe(through(push));
  });

  trumpet.selectAll('.fs', function (row) {
    row.createReadStream().pipe(through(push));
  });

  trumpet.selectAll('.fh', function (row) {
    row.createReadStream().pipe(through(push));
  });

  trumpet.selectAll('.fa', function (row) {
    row.createReadStream().pipe(through(push));
  });

  trumpet.once('end', function () {
    for (var i = 0; i < elements.length; i+=4) {
      json.push({
        status: elements[i],
        home:   elements[i+1],
        result: elements[i+2],
        away:   elements[i+3]
      });
    };

    cb(json);
  });

  http.get(pkg.feed, function(res) {
    var res = res.pipe(trumpet);
  });
}

module.exports = parseResults;<commit_msg>remove duplicated var<commit_after>var http    = require('http');
var pkg     = require('./package');
var through = require('through');
var trumpet = require('trumpet')();

var elements = [],
    json     = [];

function push (buf) {
  var data = buf.toString().trim();
  if (data !== '') {
    var imgIndex = data.indexOf('&');
    if (imgIndex > -1) {
      data = data.substr(0, imgIndex) + "'";
    }
    elements.push(data);
  }
};

parseResults = function (cb) {
  trumpet.selectAll('.fs *', function(el) {
    el.createReadStream().pipe(el.createWriteStream({outer: true}));
  });

  trumpet.selectAll('.fd *', function(el) {
    el.createReadStream().pipe(el.createWriteStream({outer: true}));
  });

  trumpet.selectAll('.fd', function (row) {
    row.createReadStream().pipe(through(push));
  });

  trumpet.selectAll('.fs', function (row) {
    row.createReadStream().pipe(through(push));
  });

  trumpet.selectAll('.fh', function (row) {
    row.createReadStream().pipe(through(push));
  });

  trumpet.selectAll('.fa', function (row) {
    row.createReadStream().pipe(through(push));
  });

  trumpet.once('end', function () {
    for (var i = 0; i < elements.length; i+=4) {
      json.push({
        status: elements[i],
        home:   elements[i+1],
        result: elements[i+2],
        away:   elements[i+3]
      });
    };

    cb(json);
  });

  http.get(pkg.feed, function(res) {
    res.pipe(trumpet);
  });
}

module.exports = parseResults;
<|endoftext|>


<commit_before>/*jshint node:true*/

'use strict';

var path = require('path');
var fs = require('fs');
var MergeTrees = require('broccoli-merge-trees');
var BabelTranspiler = require('broccoli-babel-transpiler');
var Concat = require('broccoli-concat');
var Funnel = require('broccoli-funnel');
var resolve = require('resolve');
var VersionChecker = require('ember-cli-version-checker');

module.exports = {
  name: 'Ember CLI Mocha',

  overrideTestCommandFilter: function() {
    var TestCommand = this.project.require('ember-cli/lib/commands/test');

    TestCommand.prototype.buildTestPageQueryString = function(options) {
      var params = [];

      if (options.filter) {
        params.push('grep=' + options.filter);

        if (options.invert) {
           params.push('invert=1');
        }
      }

      if (options.query) {
        params.push(options.query);
      }

      return params.join('&');
    };

    TestCommand.prototype.availableOptions.push({
      name: 'invert',
      type: Boolean,
      default: false,
      description: 'Invert the filter specified by the --filter argument',
      aliases: ['i']
    });
  },

  _getDependencyTrees: function() {
    if (this._dependencyTrees) {
      return this._dependencyTrees;
    }

    var emberTestHelpersPath = path.dirname(resolve.sync('ember-test-helpers', { basedir: this._emberMochaLibPath }));
    var klassyPath = path.dirname(resolve.sync('klassy', { basedir: emberTestHelpersPath }));

    this._dependencyTrees = [
      this.treeGenerator(this._emberMochaLibPath),
      this.treeGenerator(emberTestHelpersPath),
      this.treeGenerator(klassyPath)
    ];

    return this._dependencyTrees;
  },

  init: function() {
    this._super.init && this._super.init.apply(this, arguments);

    this.overrideTestCommandFilter();

    var checker = new VersionChecker(this);
    var dep = checker.for('ember-cli', 'npm');

    this._shouldImportEmberMocha = !dep.gt('2.2.0-alpha');
    this._emberMochaLibPath = path.dirname(resolve.sync('ember-mocha'));

    this.setTestGenerator();
  },

  postBuild: function () {
    this.checkPackages();
  },

  checkPackages: function () {
    var packages = Object.keys(this.project.addonPackages);
    if (packages.indexOf('ember-cli-qunit') !== -1) {
      console.warn('\nIt looks like you are using "ember-cli-qunit" which can cause issues with "ember-cli-mocha", please remove this package.\n');
      process.exit(1);
    }
    if (packages.indexOf('ember-cli-htmlbars-inline-precompile') < 0) {
      console.warn('\nIt looks like you\'re not on ember-cli 1.13, which includes ember-cli-htmlbars-inline-precompile by default. Please run: ember install ember-cli-htmlbars-inline-precompile.\n');
      process.exit(1);
    }
  },

  blueprintsPath: function() {
    return path.join(__dirname, 'blueprints');
  },

  treeForVendor: function(tree) {
    var mochaPath = path.dirname(resolve.sync('mocha'));
    // var mochaTree = this.treeGenerator(mochaPath);
    var mochaTree = new Funnel(mochaPath, {
      files: ['mocha.js', 'mocha.css'],
      destDir: '/mocha',
    });

    var chaiPath = path.dirname(resolve.sync('chai'));
    // var chaiTree = this.treeGenerator(chaiPath);
    var chaiTree = new Funnel(chaiPath, {
      files: ['chai.js'],
      destDir: '/chai',
    });

    var emberMochaBuildSupportPath = path.join(this._emberMochaLibPath, '..', 'build-support');

    var mochaSetupTree = new Funnel(emberMochaBuildSupportPath, {
      files: ['mocha-setup.js'],
      destDir: '/ember-mocha'
    });

    var trees = [
      tree,
      mochaTree,
      chaiTree,
      mochaSetupTree
    ];

    if (this._shouldImportEmberMocha) {
      // support for Ember CLI < 2.2.0-beta.1
      var depTree = new MergeTrees(this._getDependencyTrees());

      var transpiled = new BabelTranspiler(depTree, {
        loose: true,
        moduleIds: true,
        modules: 'amdStrict'
      });

      var concattedTree = new Concat(transpiled, {
        inputFiles: ['**/*.js'],
        outputFile: '/ember-mocha/ember-mocha.js',
        annotation: 'Concat: Ember Mocha'
      });

      trees.push(concattedTree);
    }

    return new MergeTrees(trees, {
      annotation: 'ember-cli-mocha: treeForVendor'
    });
  },

  treeForAddonTestSupport: function() {
    // for Ember CLI >= 2.2.0-beta.1
    return new MergeTrees(this._getDependencyTrees());
  },

  included: function included(app, parentAddon) {
    var target = (parentAddon || app);
    this._super.included.call(this, target);

    this.options = target.options || {};

    if (app.tests) {
      var fileAssets = [
        'vendor/mocha/mocha.js',
        'vendor/mocha/mocha.css',
        'vendor/chai/chai.js',
        'vendor/ember-mocha/mocha-setup.js',
        app.bowerDirectory + '/ember-mocha-adapter/adapter.js',
        'vendor/ember-cli-mocha/test-loader.js'
      ];

      if (this._shouldImportEmberMocha) {
        // support for Ember CLI < 2.2.0-beta.1
        fileAssets.push('vendor/ember-mocha/ember-mocha.js');
      }

      var addonOptions = app.options['ember-cli-mocha'] || {};
      if (addonOptions && !addonOptions.disableContainerStyles) {
        fileAssets.push('vendor/ember-cli-mocha/test-container-styles.css');
      }

      app.import(app.bowerDirectory + '/ember-cli-shims/test-shims.js', {
        type: 'test'
      });

      fileAssets.forEach(function(file){
        app.import(file, {
          type: 'test'
        });
      });
    }
    this.jshintrc = app.options.jshintrc;
  },

  contentFor: function(type) {
    if (type === 'test-body') {
      return this._readTemplate('test-body');
    }
  },

  _readTemplate: function(name) {
    return fs.readFileSync(path.join(__dirname, 'templates', name + '.html'));
  },

  setTestGenerator: function() {
    this.project.generateTestFile = function(moduleName, tests) {
      var output = "describe('" + moduleName + "', function() {\n";

      tests.forEach(function(test) {
        output += "  it('" + test.name + "', function() {\n";
        if (test.passed) {
          output +=
            "    // precompiled test passed\n";
        } else {
          output +=
            "    // precompiled test failed\n" +
            "    var error = new chai.AssertionError('" + test.errorMessage + "');\n" +
            "    error.stack = undefined;\n" +
            "    throw error;\n";
        }
        output +=   "  });\n";
      });

      output += "});\n";

      return output;
    };
  }
};
<commit_msg>Remove unused/obsolete "jshintrc" property<commit_after>/*jshint node:true*/

'use strict';

var path = require('path');
var fs = require('fs');
var MergeTrees = require('broccoli-merge-trees');
var BabelTranspiler = require('broccoli-babel-transpiler');
var Concat = require('broccoli-concat');
var Funnel = require('broccoli-funnel');
var resolve = require('resolve');
var VersionChecker = require('ember-cli-version-checker');

module.exports = {
  name: 'Ember CLI Mocha',

  overrideTestCommandFilter: function() {
    var TestCommand = this.project.require('ember-cli/lib/commands/test');

    TestCommand.prototype.buildTestPageQueryString = function(options) {
      var params = [];

      if (options.filter) {
        params.push('grep=' + options.filter);

        if (options.invert) {
           params.push('invert=1');
        }
      }

      if (options.query) {
        params.push(options.query);
      }

      return params.join('&');
    };

    TestCommand.prototype.availableOptions.push({
      name: 'invert',
      type: Boolean,
      default: false,
      description: 'Invert the filter specified by the --filter argument',
      aliases: ['i']
    });
  },

  _getDependencyTrees: function() {
    if (this._dependencyTrees) {
      return this._dependencyTrees;
    }

    var emberTestHelpersPath = path.dirname(resolve.sync('ember-test-helpers', { basedir: this._emberMochaLibPath }));
    var klassyPath = path.dirname(resolve.sync('klassy', { basedir: emberTestHelpersPath }));

    this._dependencyTrees = [
      this.treeGenerator(this._emberMochaLibPath),
      this.treeGenerator(emberTestHelpersPath),
      this.treeGenerator(klassyPath)
    ];

    return this._dependencyTrees;
  },

  init: function() {
    this._super.init && this._super.init.apply(this, arguments);

    this.overrideTestCommandFilter();

    var checker = new VersionChecker(this);
    var dep = checker.for('ember-cli', 'npm');

    this._shouldImportEmberMocha = !dep.gt('2.2.0-alpha');
    this._emberMochaLibPath = path.dirname(resolve.sync('ember-mocha'));

    this.setTestGenerator();
  },

  postBuild: function () {
    this.checkPackages();
  },

  checkPackages: function () {
    var packages = Object.keys(this.project.addonPackages);
    if (packages.indexOf('ember-cli-qunit') !== -1) {
      console.warn('\nIt looks like you are using "ember-cli-qunit" which can cause issues with "ember-cli-mocha", please remove this package.\n');
      process.exit(1);
    }
    if (packages.indexOf('ember-cli-htmlbars-inline-precompile') < 0) {
      console.warn('\nIt looks like you\'re not on ember-cli 1.13, which includes ember-cli-htmlbars-inline-precompile by default. Please run: ember install ember-cli-htmlbars-inline-precompile.\n');
      process.exit(1);
    }
  },

  blueprintsPath: function() {
    return path.join(__dirname, 'blueprints');
  },

  treeForVendor: function(tree) {
    var mochaPath = path.dirname(resolve.sync('mocha'));
    // var mochaTree = this.treeGenerator(mochaPath);
    var mochaTree = new Funnel(mochaPath, {
      files: ['mocha.js', 'mocha.css'],
      destDir: '/mocha',
    });

    var chaiPath = path.dirname(resolve.sync('chai'));
    // var chaiTree = this.treeGenerator(chaiPath);
    var chaiTree = new Funnel(chaiPath, {
      files: ['chai.js'],
      destDir: '/chai',
    });

    var emberMochaBuildSupportPath = path.join(this._emberMochaLibPath, '..', 'build-support');

    var mochaSetupTree = new Funnel(emberMochaBuildSupportPath, {
      files: ['mocha-setup.js'],
      destDir: '/ember-mocha'
    });

    var trees = [
      tree,
      mochaTree,
      chaiTree,
      mochaSetupTree
    ];

    if (this._shouldImportEmberMocha) {
      // support for Ember CLI < 2.2.0-beta.1
      var depTree = new MergeTrees(this._getDependencyTrees());

      var transpiled = new BabelTranspiler(depTree, {
        loose: true,
        moduleIds: true,
        modules: 'amdStrict'
      });

      var concattedTree = new Concat(transpiled, {
        inputFiles: ['**/*.js'],
        outputFile: '/ember-mocha/ember-mocha.js',
        annotation: 'Concat: Ember Mocha'
      });

      trees.push(concattedTree);
    }

    return new MergeTrees(trees, {
      annotation: 'ember-cli-mocha: treeForVendor'
    });
  },

  treeForAddonTestSupport: function() {
    // for Ember CLI >= 2.2.0-beta.1
    return new MergeTrees(this._getDependencyTrees());
  },

  included: function included(app, parentAddon) {
    var target = (parentAddon || app);
    this._super.included.call(this, target);

    this.options = target.options || {};

    if (app.tests) {
      var fileAssets = [
        'vendor/mocha/mocha.js',
        'vendor/mocha/mocha.css',
        'vendor/chai/chai.js',
        'vendor/ember-mocha/mocha-setup.js',
        app.bowerDirectory + '/ember-mocha-adapter/adapter.js',
        'vendor/ember-cli-mocha/test-loader.js'
      ];

      if (this._shouldImportEmberMocha) {
        // support for Ember CLI < 2.2.0-beta.1
        fileAssets.push('vendor/ember-mocha/ember-mocha.js');
      }

      var addonOptions = app.options['ember-cli-mocha'] || {};
      if (addonOptions && !addonOptions.disableContainerStyles) {
        fileAssets.push('vendor/ember-cli-mocha/test-container-styles.css');
      }

      app.import(app.bowerDirectory + '/ember-cli-shims/test-shims.js', {
        type: 'test'
      });

      fileAssets.forEach(function(file){
        app.import(file, {
          type: 'test'
        });
      });
    }
  },

  contentFor: function(type) {
    if (type === 'test-body') {
      return this._readTemplate('test-body');
    }
  },

  _readTemplate: function(name) {
    return fs.readFileSync(path.join(__dirname, 'templates', name + '.html'));
  },

  setTestGenerator: function() {
    this.project.generateTestFile = function(moduleName, tests) {
      var output = "describe('" + moduleName + "', function() {\n";

      tests.forEach(function(test) {
        output += "  it('" + test.name + "', function() {\n";
        if (test.passed) {
          output +=
            "    // precompiled test passed\n";
        } else {
          output +=
            "    // precompiled test failed\n" +
            "    var error = new chai.AssertionError('" + test.errorMessage + "');\n" +
            "    error.stack = undefined;\n" +
            "    throw error;\n";
        }
        output +=   "  });\n";
      });

      output += "});\n";

      return output;
    };
  }
};
<|endoftext|>


<commit_before>var path = require('path')
var jstransformer = require('jstransformer')
var toTransformer = require('inputformat-to-jstransformer')
var extend = require('extend')
var async = require('async')
var clone = require('clone')
var minimatch = require('minimatch')

var transformers = {}

/**
* Get the transformer from the given name.
*
* @return The JSTransformer; null if it doesn't exist.
*/
function getTransformer(name) {
  if (name in transformers) {
    return transformers[name]
  }
  var transformer = toTransformer(name)
  transformers[name] = transformer ? jstransformer(transformer) : false
  return transformers[name]
}

module.exports = function (opts) {
  // Prepare the options.
  opts = opts || {}
  opts.layoutPattern = opts.layoutPattern || 'layouts/**'
  opts.pattern = opts.pattern || '**'
  opts.engineLocals = opts.engineLocals || {}
  opts.engineOptions = opts.engineOptions || {}
  var defaultLayout = opts.defaultLayout

  // Execute the plugin.
  return function (files, metalsmith, done) {
    // Retrieve all layouts.
    var templates = {}
    var filesKeys = Object.keys(files)
    var layouts = minimatch.match(filesKeys, opts.layoutPattern, {matchBase: true})

    /**
     * Compile the given layout and store it in templates.
     */
    function compileLayout(layout, done) {
      // Find which JSTransformer to compile with.
      var transform = path.extname(layout).substring(1)
      transform = getTransformer(transform)
      if (transform) {
        // Retrieve the options for the JSTransformer.
        var thefilename = path.join(metalsmith._directory, metalsmith._source, layout)
        var options = extend({}, opts.engineOptions[transform.name], files[layout], {
          filename: thefilename,
          root: metalsmith.source()
        })

        // Compile the content.
        var content = files[layout].contents.toString()
        transform.compileAsync(content, options).then(function (results) {
          // Wire up the template for the layout.
          templates[layout] = results
          templates[layout].transformName = transform.name

          // Set the layout as the default layout, if desired.
          if (files[layout].defaultLayout) {
            defaultLayout = layout
          }

          // Finished compiling the layout into a template.
          done()
        }, function (err) {
          done(err)
        })
      } else {
        done('The layout ' + layout + ' has an unsupported transform of ' + transform + '.')
      }
    }

    /**
     * Delete the given file from the files array.
     */
    function deleteFile(file, done) {
      if (file in files) {
        delete files[file]
      }
      done()
    }

    /**
     * Render the given file in its layout templates.
     */
    function renderContent(file, done) {
      // Only render content, skip rendering layouts.
      if (!(file in layouts)) {
        var layoutName = files[file].layout || defaultLayout
        while (layoutName && templates[layoutName]) {
          // Build the options/locals.
          var thefilename = path.join(metalsmith._directory, metalsmith._source, layoutName)
          var transformName = templates[layoutName].transformName
          var locals = extend({}, metalsmith.metadata(), opts.engineLocals[transformName], files[layoutName], files[file], {
            contents: files[file].contents.toString(),
            filename: thefilename,
            root: metalsmith.source()
          })

          // Render the content using the template function and options.
          try {
            files[file].contents = templates[layoutName].fn(locals)
          } catch (err) {
            return done(err)
          }

          // Allow for recursive explicit layouts.
          layoutName = files[layoutName].layout
        }
      }
      done()
    }

    /**
     * Process the given file. Call done() when done processing.
     */
    function processFile(file, done) {
      /**
       * Process the given extension on the file.
       */
      function processExtension(extension, done) {
        // Retrieve the transformer.
        var transformer = getTransformer(extension)

        // Process the extension until the transformation is done.
        if (transformer && !files[file].jstransformerDone) {
          // Construct the options.
          var engineOpts = opts.engineOptions[transformer.name]
          var options = extend({}, metalsmith.metadata(), engineOpts, files[file], {
            filename: metalsmith.source() + '/' + file,
            root: metalsmith.source()
          })
          // Construct the locals.
          var engineLocals = opts.engineLocals[transformer.name]
          var locals = extend({}, metalsmith.metadata(), engineLocals, files[file], {
            filename: metalsmith.source() + '/' + file,
            root: metalsmith.source()
          })

          // Get the transformer to render the contents.
          transformer.renderAsync(files[file].contents.toString(), options, locals).then(function (result) {
            // Allow providing the default output format.
            files[file].jstransformerOutputFormat = transformer.outputFormat
            // Remove an extension from the end.
            files[file].jstransformerFilePath.pop()
            files[file].contents = new Buffer(result.body)
            done()
          }, function (err) {
            files[file].jstransformerDone = true
            done(err)
          })
        } else {
          // The transformer isn't supported, skip the rest.
          files[file].jstransformerDone = true
          done()
        }
      }

      // Prepare the extension processing.
      var extensions = file.split('.')
      files[file].jstransformerFilePath = clone(extensions)
      extensions.reverse().pop()
      // Loop through the transformer series.
      async.mapSeries(extensions, processExtension, done)
    }

    /**
     * Rename the given file to its desired new name.
     */
    function renameFile(file, done) {
      var filename = file
      // Check if there is a potential filepath change.
      if (files[file].jstransformerFilePath) {
        // See if we should add the default output format.
        if (files[file].jstransformerFilePath.length === 1 && files[file].jstransformerOutputFormat) {
          files[file].jstransformerFilePath.push(files[file].jstransformerOutputFormat)
        }
        filename = files[file].jstransformerFilePath.join('.')
      }

      // See if we are to now rename the file.
      if (filename !== file) {
        files[filename] = files[file]
        delete files[file]
      }

      done()
    }

    /**
     * Delete auxiliary metadata from the given file if exist.
     */
    function deleteAuxiliaryMetadata(file, done) {
      delete files[file].jstransformerOutputFormat
      delete files[file].jstransformerFilePath
      delete files[file].jstransformerDone
      done()
    }

    // TODO: Clean up async function chain tree.
    // Compile all layouts.
    async.map(layouts, compileLayout, function (err) {
      if (err) {
        done(err)
      } else {
        // Render all individual content.
        try {
          var contenAtFiles = minimatch.match(filesKeys, opts.pattern, {matchBase: true});
        } catch (err) {
          done(err);
        }

        async.map(contentFiles, processFile, function (err) {
          if (err) {
            done(err)
          } else {
            // Render the content within the layouts.
            async.map(contentFiles, renderContent, function (err) {
              if (err) {
                done(err)
              } else {
                // Delete the layout data.
                async.map(layouts, deleteFile, function (err) {
                  if (err) {
                    done(err)
                  } else {
                    // Now rename all the files.
                    async.map(Object.keys(files), renameFile, function (err) {
                      if (err) {
                        done(err)
                      } else {
                        // Now delete auxiliary metadata from files.
                        async.map(Object.keys(files), deleteAuxiliaryMetadata, done)
                      }
                    })
                  }
                })
              }
            })
          }
        })
      }
    })
  }
}
<commit_msg>fix typo<commit_after>var path = require('path')
var jstransformer = require('jstransformer')
var toTransformer = require('inputformat-to-jstransformer')
var extend = require('extend')
var async = require('async')
var clone = require('clone')
var minimatch = require('minimatch')

var transformers = {}

/**
* Get the transformer from the given name.
*
* @return The JSTransformer; null if it doesn't exist.
*/
function getTransformer(name) {
  if (name in transformers) {
    return transformers[name]
  }
  var transformer = toTransformer(name)
  transformers[name] = transformer ? jstransformer(transformer) : false
  return transformers[name]
}

module.exports = function (opts) {
  // Prepare the options.
  opts = opts || {}
  opts.layoutPattern = opts.layoutPattern || 'layouts/**'
  opts.pattern = opts.pattern || '**'
  opts.engineLocals = opts.engineLocals || {}
  opts.engineOptions = opts.engineOptions || {}
  var defaultLayout = opts.defaultLayout

  // Execute the plugin.
  return function (files, metalsmith, done) {
    // Retrieve all layouts.
    var templates = {}
    var filesKeys = Object.keys(files)
    var layouts = minimatch.match(filesKeys, opts.layoutPattern, {matchBase: true})

    /**
     * Compile the given layout and store it in templates.
     */
    function compileLayout(layout, done) {
      // Find which JSTransformer to compile with.
      var transform = path.extname(layout).substring(1)
      transform = getTransformer(transform)
      if (transform) {
        // Retrieve the options for the JSTransformer.
        var thefilename = path.join(metalsmith._directory, metalsmith._source, layout)
        var options = extend({}, opts.engineOptions[transform.name], files[layout], {
          filename: thefilename,
          root: metalsmith.source()
        })

        // Compile the content.
        var content = files[layout].contents.toString()
        transform.compileAsync(content, options).then(function (results) {
          // Wire up the template for the layout.
          templates[layout] = results
          templates[layout].transformName = transform.name

          // Set the layout as the default layout, if desired.
          if (files[layout].defaultLayout) {
            defaultLayout = layout
          }

          // Finished compiling the layout into a template.
          done()
        }, function (err) {
          done(err)
        })
      } else {
        done('The layout ' + layout + ' has an unsupported transform of ' + transform + '.')
      }
    }

    /**
     * Delete the given file from the files array.
     */
    function deleteFile(file, done) {
      if (file in files) {
        delete files[file]
      }
      done()
    }

    /**
     * Render the given file in its layout templates.
     */
    function renderContent(file, done) {
      // Only render content, skip rendering layouts.
      if (!(file in layouts)) {
        var layoutName = files[file].layout || defaultLayout
        while (layoutName && templates[layoutName]) {
          // Build the options/locals.
          var thefilename = path.join(metalsmith._directory, metalsmith._source, layoutName)
          var transformName = templates[layoutName].transformName
          var locals = extend({}, metalsmith.metadata(), opts.engineLocals[transformName], files[layoutName], files[file], {
            contents: files[file].contents.toString(),
            filename: thefilename,
            root: metalsmith.source()
          })

          // Render the content using the template function and options.
          try {
            files[file].contents = templates[layoutName].fn(locals)
          } catch (err) {
            return done(err)
          }

          // Allow for recursive explicit layouts.
          layoutName = files[layoutName].layout
        }
      }
      done()
    }

    /**
     * Process the given file. Call done() when done processing.
     */
    function processFile(file, done) {
      /**
       * Process the given extension on the file.
       */
      function processExtension(extension, done) {
        // Retrieve the transformer.
        var transformer = getTransformer(extension)

        // Process the extension until the transformation is done.
        if (transformer && !files[file].jstransformerDone) {
          // Construct the options.
          var engineOpts = opts.engineOptions[transformer.name]
          var options = extend({}, metalsmith.metadata(), engineOpts, files[file], {
            filename: metalsmith.source() + '/' + file,
            root: metalsmith.source()
          })
          // Construct the locals.
          var engineLocals = opts.engineLocals[transformer.name]
          var locals = extend({}, metalsmith.metadata(), engineLocals, files[file], {
            filename: metalsmith.source() + '/' + file,
            root: metalsmith.source()
          })

          // Get the transformer to render the contents.
          transformer.renderAsync(files[file].contents.toString(), options, locals).then(function (result) {
            // Allow providing the default output format.
            files[file].jstransformerOutputFormat = transformer.outputFormat
            // Remove an extension from the end.
            files[file].jstransformerFilePath.pop()
            files[file].contents = new Buffer(result.body)
            done()
          }, function (err) {
            files[file].jstransformerDone = true
            done(err)
          })
        } else {
          // The transformer isn't supported, skip the rest.
          files[file].jstransformerDone = true
          done()
        }
      }

      // Prepare the extension processing.
      var extensions = file.split('.')
      files[file].jstransformerFilePath = clone(extensions)
      extensions.reverse().pop()
      // Loop through the transformer series.
      async.mapSeries(extensions, processExtension, done)
    }

    /**
     * Rename the given file to its desired new name.
     */
    function renameFile(file, done) {
      var filename = file
      // Check if there is a potential filepath change.
      if (files[file].jstransformerFilePath) {
        // See if we should add the default output format.
        if (files[file].jstransformerFilePath.length === 1 && files[file].jstransformerOutputFormat) {
          files[file].jstransformerFilePath.push(files[file].jstransformerOutputFormat)
        }
        filename = files[file].jstransformerFilePath.join('.')
      }

      // See if we are to now rename the file.
      if (filename !== file) {
        files[filename] = files[file]
        delete files[file]
      }

      done()
    }

    /**
     * Delete auxiliary metadata from the given file if exist.
     */
    function deleteAuxiliaryMetadata(file, done) {
      delete files[file].jstransformerOutputFormat
      delete files[file].jstransformerFilePath
      delete files[file].jstransformerDone
      done()
    }

    // TODO: Clean up async function chain tree.
    // Compile all layouts.
    async.map(layouts, compileLayout, function (err) {
      if (err) {
        done(err)
      } else {
        // Render all individual content.
        try {
          var contentFiles = minimatch.match(filesKeys, opts.pattern, {matchBase: true});
        } catch (err) {
          done(err);
        }

        async.map(contentFiles, processFile, function (err) {
          if (err) {
            done(err)
          } else {
            // Render the content within the layouts.
            async.map(contentFiles, renderContent, function (err) {
              if (err) {
                done(err)
              } else {
                // Delete the layout data.
                async.map(layouts, deleteFile, function (err) {
                  if (err) {
                    done(err)
                  } else {
                    // Now rename all the files.
                    async.map(Object.keys(files), renameFile, function (err) {
                      if (err) {
                        done(err)
                      } else {
                        // Now delete auxiliary metadata from files.
                        async.map(Object.keys(files), deleteAuxiliaryMetadata, done)
                      }
                    })
                  }
                })
              }
            })
          }
        })
      }
    })
  }
}
<|endoftext|>


<commit_before>/*global JSONPath, getJSON, exports*/
/*jslint vars:true, todo:true*/
(function (undef) {'use strict';

/**
* @param {boolean} config.errorOnEqualPriority
*/
function JSONPathTransformer (config) {
    if (!(this instanceof JSONPathTransformer)) {
        return new JSONPathTransformer(config);
    }
    this.config = config;
    // Todo: if no templates, allow query (e.g., something like '$' without apply-templates but like XQuery)
    var map = {};
    this.templates.forEach(function (template) {
        if (map[template.name]) {
            throw "Templates must all have different names.";
        }
        map[template.name] = true;
    });
    map = null;
}
JSONPathTransformer.prototype.getDefaultPriority = function (path) {
    if (typeof path === 'string') {
        path = JSONPath.toPathArray(path);
    }
    // Todo: Path specificity
    // Let's also, unlike XSLT, give higher priority to absolute fixed paths over recursive descent and priority to longer paths and lower to wildcard terminal points

};
JSONPathTransformer.prototype.transform = function () {
    var config = this.config;
    var matched = this.templates.sort(function (a, b) {
        // Root tests
        if (a.path === '$') {
            return -1;
        }
        if (b.path === '$') {
            return 1;
        }

        var aPriority = typeof a.priority === 'number' ? a.priority : this.getDefaultPriority(a.path);
        var bPriority = typeof b.priority === 'number' ? b.priority : this.getDefaultPriority(a.path);

        if (aPriority === bPriority && this.config.errorOnEqualPriority) {
            throw "You have configured JSONPathTransformer to throw errors on finding templates of equal priority and these have been found.";
        }

        return (aPriority > bPriority) ? -1 : 1; // We want equal conditions to go in favor of the later (b)
    }).some(function (templateObj) {
        var path = templateObj.path;
        var json = config.json;
        var values = JSONPath({json: json, path: path, resultType: 'value', wrap: false, callback: function (parent, property, value, path) {

        }});
        if (values) {
            templateObj.template(values, path, json);
        }
        return true;
    });

    if (!matched) { // Should not get here with default template rules in place
        throw "No template rules matched";
    }
};
JSONPathTransformer.DefaultTemplateRules = [
    // Todo: Apply default template rules

];

function JTLT (config) {
    if (!(this instanceof JTLT)) {
        return new JTLT(config);
    }
    this.templates = config.templates;
    this.config = config || {};
    this.setDefaults();
    var that = this;
    if (this.config.ajaxData) {
        getJSON(this.config.ajaxData, function (json) {
            that.config.data = json;
            that.autoStart();
        });
        return this;
    }
    this.autoStart();
}
JTLT.prototype.autoStart = function () {
    if (this.config.autostart !== false) {
        return this.config.success(this.transform());
    }
};
JTLT.prototype.setDefaults = function () {
    this.config.engine = this.config.engine || JSONPathTransformer;
    return this;
};
JTLT.prototype.transform = function () {
    if (this.config.data === undef) {
        if (this.config.ajaxData) {
            throw "You must wait for the 'ajaxData' source to be retrieved.";
        }
        throw "You must supply a 'data' or 'ajaxData' property";
    }

    var engineObj = this.config.engine({templates: this.templates, json: this.config.data});
    engineObj.transform();
};

if (typeof exports !== 'undefined') {
    exports.JTLT = JTLT;
    exports.JSONPathTransformer = JSONPathTransformer;
}
else {
    window.JTLT = JTLT;
    window.JSONPathTransformer = JSONPathTransformer;
}

}());<commit_msg>document and further work on skeleton<commit_after>/*global JSONPath, getJSON, exports*/
/*jslint vars:true, todo:true*/
(function (undef) {'use strict';

/**
* @param {boolean} config.errorOnEqualPriority
*/
function JSONPathTransformer (config) {
    if (!(this instanceof JSONPathTransformer)) {
        return new JSONPathTransformer(config);
    }
    this.config = config;
    // Todo: if no templates, allow query (e.g., something like '$' without apply-templates but like XQuery)
    var map = {};
    this.templates.forEach(function (template) {
        if (map[template.name]) {
            throw "Templates must all have different names.";
        }
        map[template.name] = true;
    });
    map = null;
    this.transform();
}
JSONPathTransformer.prototype.getDefaultPriority = function (path) {
    if (typeof path === 'string') {
        path = JSONPath.toPathArray(path);
    }
    // Todo: Path specificity
    // Let's also, unlike XSLT, give higher priority to absolute fixed paths over recursive descent and priority to longer paths and lower to wildcard terminal points

    // -.5 = *, @string() (etc.)
    // -.25 = Namespace (not relevant without Jamilih)
    // 0 = single name (i.e., $..someName)
    // .5 = ., .., [], [()], [(?)]

};
JSONPathTransformer.prototype.transform = function () {
    var config = this.config;
    var matched = this.templates.sort(function (a, b) {
        // Root tests
        if (a.path === '$') {
            return -1;
        }
        if (b.path === '$') {
            return 1;
        }

        var aPriority = typeof a.priority === 'number' ? a.priority : this.getDefaultPriority(a.path);
        var bPriority = typeof b.priority === 'number' ? b.priority : this.getDefaultPriority(a.path);

        if (aPriority === bPriority && this.config.errorOnEqualPriority) {
            throw "You have configured JSONPathTransformer to throw errors on finding templates of equal priority and these have been found.";
        }

        return (aPriority > bPriority) ? -1 : 1; // We want equal conditions to go in favor of the later (b)
    }).some(function (templateObj) {
        var path = templateObj.path;
        var json = config.data;
        var values = JSONPath({json: json, path: path, resultType: 'value', wrap: false, callback: function (parent, property, value, path) {

        }});
        if (values) {
            templateObj.template(values, path, json);
        }
        return true;
    });

    if (!matched) { // Should not get here with default template rules in place
        throw "No template rules matched";
    }
};
JSONPathTransformer.DefaultTemplateRules = [
    // Todo: Apply default template rules

];

/**
* For templates/queries, one may choose among config.query, config.template, or config.templates, but one must be present and of valid type. For the source json, one must use either a valid config.ajaxData or config.data parameter.
* @param {function} config.success A callback supplied with a single argument that is the result of this instance's transform() method.
* @param {array} [config.templates] An array of template objects
* @param {object|function} [config.template] A function assumed to be a root template or a single, complete template object
* @param {function} [config.query] A function assumed to be a root template
* @param {object} [config.data] A JSON object
* @param {string} [config.ajaxData] URL of a JSON file to retrieve for evaluation
* @param {boolean} [config.errorOnEqualPriority=false]
* @param {boolean} [config.autostart=true] Whether to begin transform() immediately.
* @param {function} [config.engine=JSONPathTransformer] Will be based the same config as passed to this instance. Defaults to a transforming function based on JSONPath and with its own set of priorities for processing templates.
* @returns {JTLT} A JTLT instance object
*/
function JTLT (config) {
    if (!(this instanceof JTLT)) {
        return new JTLT(config);
    }

    this.setDefaults(config);
    var that = this;
    if (this.config.ajaxData) {
        getJSON(this.config.ajaxData, function (json) {
            that.config.data = json;
            that._autoStart();
        });
        return this;
    }
    this._autoStart();
}
JTLT.prototype._autoStart = function () {
    if (this.config.autostart !== false || this.ready) {
        this.config.success(this.transform());
    }
};
JTLT.prototype.setDefaults = function () {
    var query = config.query ? config.query : (typeof config.templates === 'function' ? config.templates : (typeof config.template === 'function' ? config.template : null));
    this.templates = query ? [{name: 'root', path: '$', template: query}] || config.templates || [config.template];
    this.config.errorOnEqualPriority = config.errorOnEqualPriority || false;
    this.config = config || {};
    this.config.engine = this.config.engine || JSONPathTransformer;
    return this;
};
/**
* @returns {any}
*/
JTLT.prototype.transform = function () {
    if (this.config.data === undef) {
        if (this.config.ajaxData) {
            this.ready = true;
            return;
        }
        throw "You must supply a 'data' or 'ajaxData' property";
    }
    if (typeof this.config.success !== 'function') {
        throw "You must supply a 'success' callback";
    }

    return this.config.engine({templates: this.templates, json: this.config.data});
};

if (typeof exports !== 'undefined') {
    exports.JTLT = JTLT;
    exports.JSONPathTransformer = JSONPathTransformer;
}
else {
    window.JTLT = JTLT;
    window.JSONPathTransformer = JSONPathTransformer;
}

}());<|endoftext|>


<commit_before>/*
 * index.js :: include for the binarypack modules
 *
 * (C) 2013 Jarrett Cruger -- MIT
 *
 */

var fs = require('fs');

module.exports = require('binarypack');

//
// Expose source of browser code to be loaded by primus
//
module.exports.browser = fs.readFileSync('./vendor/binarypack.js', 'utf-8');

<commit_msg>[fix] label more clearly as browser source<commit_after>/*
 * index.js :: include for the binarypack modules
 *
 * (C) 2013 Jarrett Cruger -- MIT
 *
 */

var fs = require('fs');

module.exports = require('binarypack');

//
// Expose source of browser code to be loaded by primus
//
module.exports.BrowserSource = fs.readFileSync('./vendor/binarypack.js', 'utf-8');

<|endoftext|>


<commit_before>var express = require('express');
var cors = require('cors');
var app = express();
var pg = require('pg');
var url = require('url');
var nodemailer = require("nodemailer");

app.set('port', (process.env.PORT || 5000));
app.use(cors());
app.use(express.static(__dirname + '/public'));

// views is directory for all template files
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

app.get('/', function(request, response) {
  response.render('pages/index');
});

app.get('/db', function (request, response) {
  pg.connect(process.env.DATABASE_URL, function(err, client, done) {
    client.query('SELECT * FROM test_table', function(err, result) {
      done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.render('pages/showdata', {results: result.rows} ); }
    });
  });
});

app.get('/getAllUser', function (request, response) {
  pg.connect(process.env.DATABASE_URL, function(err, client, done) {
    client.query('SELECT * FROM userdata', function(err, result) {
      done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.send(result); }
    });
  });
});

app.get('/login',function(request,response){

	var query1 = url.parse(request.url, true);
	var name = query1.query.uname;
	var pass = query1.query.pwd;

	pg.connect(process.env.DATABASE_URL, function(err, client, done) {

  	  client.query('SELECT product_id FROM userdata WHERE email = \'' + name +'\'  and password = \''+pass +'\' ', function(err, result) {
  	  	done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.send(result); }
    });
  });
});

app.get('/check',function(request,response){

	var query1 = url.parse(request.url, true);
	var name = query1.query.uname;

	pg.connect(process.env.DATABASE_URL, function(err, client, done) {

  	  client.query('SELECT email FROM userdata WHERE email = \'' + name +'\' ', function(err, result) {
  	  	done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.send(result); }
    });
  });
});

app.get('/sensordata', function (request, response) {
  var query1 = url.parse(request.url, true);
	var name = query1.query.pid;

  pg.connect(process.env.DATABASE_URL, function(err, client, done) {
    client.query(' SELECT * FROM test_table WHERE product_id = \''+name +'\' ', function(err, result) {
      done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.send(result); }
    });
  });
});

app.get('/register',function(request,response){

	var query1 = url.parse(request.url, true);
	var name = query1.query.name;
	var email = (query1.query.uname).trim();
	var phone = query1.query.phone;
	var location = query1.query.loc;
	var pass = query1.query.pwd;
	var prodid = query1.query.pid;

	pg.connect(process.env.DATABASE_URL, function(err, client, done) {

  	  client.query(' Insert into userdata (name, email, phone, location, password, product_id) values (   \'' + name +'\' , \''+ email + ' \' , \' '+phone+'\' , \''+ location+'\' , \''+pass+'\' , \''+prodid+ '\'   ) ', function(err, result) {
      done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.send(result); }
    });
  });
});

//for sending email
app.get('/forgotPassword', function(request, response) {

	var query1 = url.parse(request.url, true);
	var name = query1.query.uname;

/*
  var n = name.length;
  var newstr ="";
  var count = 0;

    for(count = 0; count < n; count++)
    {

    	if(count == 0 || count%2 == 0)
        {
    		var a = name.charCodeAt(count)+1;
        }
        else
        {
        	var a = name.charCodeAt(count)-1;
        }
        var b = String.fromCharCode(a);
        newstr += b;

    }
    name = newstr;
    */

	pg.connect(process.env.DATABASE_URL, function(err, client, done) {

  	  client.query(' SELECT email FROM userdata WHERE email = \''+name +'\' ', function(err, result) {
  	  	done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.render('pages/resetPassword', {results: result.rows} );
       }
    });
  });
});

//for replacing password in database
app.get('/updatepassword', function(request, response) {

  var query1 = url.parse(request.url, true);
  var name = query1.query.uname;
  var pass = query1.query.pass;

  pg.connect(process.env.DATABASE_URL, function(err, client, done) {

      client.query('UPDATE userdata SET password = \'' + pass +'\' WHERE email = \'' + name + '\' ', function(err, result) {
        done();
      if (err)
       { console.error(err); response.send("Error " + err); }
    });
  });
});

// Inserting Sensor Data via GET
// SANJOTH'S WORK STARTS HERE
// https://sens-agriculture.herokuapp.com/insertData?pid=p1337&temp=23&humid=70&ph=30&co=111&uv=11
app.get('/insertData', function (request, response) {
var query1 = url.parse(request.url, true);
  var product_id = query1.query.pid;
  var temprature = query1.query.temp;
  var humidity = query1.query.humid;
  var powerOfHyd = query1.query.ph;
  var co_leve = query1.query.co;
  var light = query1.query.uv;

   pg.connect(process.env.DATABASE_URL, function(err, client, done) {
    client.query('INSERT INTO test_table (product_id, temprature, humidity, ph, co_leve, light) VALUES ( \'' + product_id +'\' , \''+ temprature + ' \' , \' '+humidity+'\' , \''+ powerOfHyd+'\' , \''+co_leve+'\' , \''+light+ '\')', function(err, result) {
      done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.send(result); }
    });
  });
});

/* Inserting Sensor Data via POST
app.post('/insertData', function (request, response) {

   pg.connect(process.env.DATABASE_URL, function(err, client, done) {
    client.query(' // Query // ', function(err, result) {
      done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.send(result); }
    });
  });
});
*/

app.get('/resetSuccess', function(request, response) {
  response.render('pages/resetSuccess');
});

app.get('/loginForm', function(request, response) {
  response.render('pages/loginForm');
});

app.get('/signUp', function(request, response) {
  response.render('pages/signUp');
});

app.get('/visual.ejs', function(request, response) {
  response.render('pages/visual');
});

app.get('/progress', function(request, response) {
  response.render('pages/progress');
});

//for sending mail to in forgot password-case
app.get('/nodemail', function (request, response) {

  var query1 = url.parse(request.url, true);
  var f_email = query1.query.f_email;

  var transporter = nodemailer.createTransport({
    service: 'gmail',
   auth: {
     user: 'sensagriculture@gmail.com',
     pass: '1234@asdf'
   }
 });

 var mailOptions = {
   from: 'agriculture@gmail.com',
   to: f_email,
   subject: 'Link to reset your password',
   text: 'Dear User, \n \n Please go to to the link below to reset your password: \n https://sens-agriculture.herokuapp.com/forgotPassword?uname='+f_email+'\n\n Thank you. \n\n Regards,\n Team SenS'
 };

 transporter.sendMail(mailOptions, function(error, info){
   if (error) {
     console.log(error);
   } else {
     console.log('Email sent: ' + info.response);
   }
 });
});

app.get('/showdata', function(request, response) {
  response.render('pages/showdata');
});

app.listen(app.get('port'), function() {
  console.log('Node app is running on port', app.get('port'));
});
<commit_msg>bug removal<commit_after>var express = require('express');
var cors = require('cors');
var app = express();
var pg = require('pg');
var url = require('url');
var nodemailer = require("nodemailer");

app.set('port', (process.env.PORT || 5000));
app.use(cors());
app.use(express.static(__dirname + '/public'));

// views is directory for all template files
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

app.get('/', function(request, response) {
  response.render('pages/index');
});

app.get('/db', function (request, response) {
  pg.connect(process.env.DATABASE_URL, function(err, client, done) {
    client.query('SELECT * FROM test_table', function(err, result) {
      done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.render('pages/showdata', {results: result.rows} ); }
    });
  });
});

app.get('/getAllUser', function (request, response) {
  pg.connect(process.env.DATABASE_URL, function(err, client, done) {
    client.query('SELECT * FROM userdata', function(err, result) {
      done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.send(result); }
    });
  });
});

app.get('/login',function(request,response){

	var query1 = url.parse(request.url, true);
	var name = query1.query.uname;
	var pass = query1.query.pwd;

	pg.connect(process.env.DATABASE_URL, function(err, client, done) {

  	  client.query('SELECT product_id FROM userdata WHERE email = \'' + name +'\'  and password = \''+pass +'\' ', function(err, result) {
  	  	done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.send(result); }
    });
  });
});

app.get('/check',function(request,response){

	var query1 = url.parse(request.url, true);
	var name = query1.query.uname;

	pg.connect(process.env.DATABASE_URL, function(err, client, done) {

  	  client.query('SELECT email FROM userdata WHERE email = \'' + name +'\' ', function(err, result) {
  	  	done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.send(result); }
    });
  });
});

app.get('/sensordata', function (request, response) {
  var query1 = url.parse(request.url, true);
	var name = query1.query.pid;

  pg.connect(process.env.DATABASE_URL, function(err, client, done) {
    client.query(' SELECT * FROM test_table WHERE product_id = \''+name +'\' ', function(err, result) {
      done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.send(result); }
    });
  });
});

app.get('/register',function(request,response){

	var query1 = url.parse(request.url, true);
	var name = query1.query.name;
	var email = (query1.query.uname).trim();
	var phone = query1.query.phone;
	var location = query1.query.loc;
	var pass = query1.query.pwd;
	var prodid = query1.query.pid;

	pg.connect(process.env.DATABASE_URL, function(err, client, done) {

  	  client.query(' Insert into userdata (name, email, phone, location, password, product_id) values (   \'' + name +'\' , \''+ email + ' \' , \' '+phone+'\' , \''+ location+'\' , \''+pass+'\' , \''+prodid+ '\'   ) ', function(err, result) {
      done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.send(result); }
    });
  });
});

//for sending email
app.get('/forgotPassword', function(request, response) {

	var query1 = url.parse(request.url, true);
	var name = query1.query.uname;

  var n = name.length;
  var newstr ="";
  var count;
  var a;

    for(count = 0; count < n; count++)
    {

    	if(count == 0 || count%2 == 0)
        {
    		a = name.charCodeAt(count)+1;
        }
        else
        {
        a = name.charCodeAt(count)-1;
        }
        var b = String.fromCharCode(a);
        newstr += b;

    }
    var name1 = newstr;

	pg.connect(process.env.DATABASE_URL, function(err, client, done) {

  	  client.query(' SELECT email FROM userdata WHERE email = \''+name1+'\' ', function(err, result) {
  	  	done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.render('pages/resetPassword', {results: result.rows} );
       }
    });
  });
});

//for replacing password in database
app.get('/updatepassword', function(request, response) {

  var query1 = url.parse(request.url, true);
  var name = query1.query.uname;
  var pass = query1.query.pass;

  pg.connect(process.env.DATABASE_URL, function(err, client, done) {

      client.query('UPDATE userdata SET password = \'' + pass +'\' WHERE email = \'' + name + '\' ', function(err, result) {
        done();
      if (err)
       { console.error(err); response.send("Error " + err); }
    });
  });
});

// Inserting Sensor Data via GET
// SANJOTH'S WORK STARTS HERE
// https://sens-agriculture.herokuapp.com/insertData?pid=p1337&temp=23&humid=70&ph=30&co=111&uv=11
app.get('/insertData', function (request, response) {
var query1 = url.parse(request.url, true);
  var product_id = query1.query.pid;
  var temprature = query1.query.temp;
  var humidity = query1.query.humid;
  var powerOfHyd = query1.query.ph;
  var co_leve = query1.query.co;
  var light = query1.query.uv;

   pg.connect(process.env.DATABASE_URL, function(err, client, done) {
    client.query('INSERT INTO test_table (product_id, temprature, humidity, ph, co_leve, light) VALUES ( \'' + product_id +'\' , \''+ temprature + ' \' , \' '+humidity+'\' , \''+ powerOfHyd+'\' , \''+co_leve+'\' , \''+light+ '\')', function(err, result) {
      done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.send(result); }
    });
  });
});

/* Inserting Sensor Data via POST
app.post('/insertData', function (request, response) {

   pg.connect(process.env.DATABASE_URL, function(err, client, done) {
    client.query(' // Query // ', function(err, result) {
      done();
      if (err)
       { console.error(err); response.send("Error " + err); }
      else
       { response.send(result); }
    });
  });
});
*/

app.get('/resetSuccess', function(request, response) {
  response.render('pages/resetSuccess');
});

app.get('/loginForm', function(request, response) {
  response.render('pages/loginForm');
});

app.get('/signUp', function(request, response) {
  response.render('pages/signUp');
});

app.get('/visual.ejs', function(request, response) {
  response.render('pages/visual');
});

app.get('/progress', function(request, response) {
  response.render('pages/progress');
});

//for sending mail to in forgot password-case
app.get('/nodemail', function (request, response) {

  var query1 = url.parse(request.url, true);
  var f_email = query1.query.f_email;

  var transporter = nodemailer.createTransport({
    service: 'gmail',
   auth: {
     user: 'sensagriculture@gmail.com',
     pass: '1234@asdf'
   }
 });

 var mailOptions = {
   from: 'agriculture@gmail.com',
   to: f_email,
   subject: 'Link to reset your password',
   text: 'Dear User, \n \n Please go to to the link below to reset your password: \n https://sens-agriculture.herokuapp.com/forgotPassword?uname='+f_email+'\n\n Thank you. \n\n Regards,\n Team SenS'
 };

 transporter.sendMail(mailOptions, function(error, info){
   if (error) {
     console.log(error);
   } else {
     console.log('Email sent: ' + info.response);
   }
 });
});

app.get('/showdata', function(request, response) {
  response.render('pages/showdata');
});

app.listen(app.get('port'), function() {
  console.log('Node app is running on port', app.get('port'));
});
<|endoftext|>


<commit_before>var fs = require("fs");
var crypto = require("crypto");
var path = require("path");
var async = require("async");
var webpackDevServer = require("webpack-dev-server");
var webpack = require("webpack");
var SingleEntryDependency = require("webpack/lib/dependencies/SingleEntryDependency");

function Plugin(/* config.port */karmaPort, /* config.hostname */hostname, /* config.webpackPort */port, /* config.webpack */webpackOptions, /* config.webpackServer */webpackServerOptions, /* config.basePath */basePath, fileList) {
	if(!port) port = karmaPort + 1;
	if(!hostname) hostname = "localhost";
	if(!webpackOptions) webpackOptions = {};
	if(!webpackOptions.output) webpackOptions.output = {};
	if(!webpackServerOptions) webpackServerOptions = {};

	this.files = [];
	this.basePath = basePath;
	this.waiting = [];
	this.fileList = fileList;

	webpackOptions.output.path = "/";
	webpackOptions.output.filename = "_js/[name]";
	webpackOptions.output.chunkFilename = "_js/[id].chunk.js";
	webpackOptions.output.publicPath = "http://" + hostname + ":" + port + "/";

	var compiler = webpack(webpackOptions);
	compiler.plugin("compilation", function(compilation, params) {
		compilation.dependencyFactories.set(SingleEntryDependency, params.normalModuleFactory);
	});
	compiler.plugin("done", function(stats) {
		this.excludeRemovedTests(stats);

		// If karma is already in preprocessing phase, no need to trigger karma run.
		if(!this.karmaWaitsForPreprocessing) {
			// If file required in tests is changed, webpack compilation is done silently for karma.
			// Fix this by emulating test file change.
			this.notifyKarmaAboutChanges(stats);
		}

		if(this.waiting) {
			var w = this.waiting;
			this.waiting = null;
			w.forEach(function(cb) {
				cb();
			});
		}
	}.bind(this));
	compiler.plugin("invalid", function() {
		if(!this.waiting) this.waiting = [];
	}.bind(this));
	compiler.plugin("make", this.make.bind(this));
	var server = this.server = new webpackDevServer(compiler, webpackServerOptions);
	server.listen(port, hostname);
}

Plugin.prototype.notifyKarmaAboutChanges = function(stats) {
	// Find recently recompiled files.
	var changedAssets = stats.toJson().assets.filter(function (asset) {
		return asset.emitted;
	}).map(function(asset) {
		return asset.name;
	});

	// Pick files watched by karma among them.
	var changedTests = this.files.filter(function (file) {
		var assetName = "_js/" + path.relative(this.basePath, file).replace(/\\/g, "/");
		return changedAssets.indexOf(assetName) !== -1;
	}.bind(this));

	// Make karma to run preprocessors on changed tests.
	changedTests.forEach(function(changedTestFile) {
		this.fileList.buckets.forEach(function(bucket) {
			bucket.forEach(function(watchedFile) {
				if (watchedFile.originalPath === changedTestFile) {
					this.changeKarmaFile(watchedFile);
				}
			}.bind(this));
		}.bind(this));
	}.bind(this));
};

Plugin.prototype.excludeRemovedTests = function(stats) {
	if(stats.compilation.errors.length === 0) return;
	stats.compilation.errors.forEach(function(error) {
		var missingFile = error.error.path;
		this.files = this.files.filter(function (file) {
			return missingFile !== file;
		});
	}.bind(this))
};

Plugin.prototype.addFile = function(entry) {
	if(this.files.indexOf(entry) >= 0) return;
	this.files.push(entry);
	if(!this.waiting) this.waiting = [];
	this.server.invalidate();
};

Plugin.prototype.changeKarmaFile = function(watchedFile) {
	// Hack: utimes
	//
	// Karma v0.12 will do fs.stat to compare it with watchedFile.mtime.
	// https://github.com/karma-runner/karma/blob/v0.12.16/lib/file_list.js#L362
	// Not doing utimes() causes karma to ignore changeFile event.
	fs.utimesSync(watchedFile.originalPath, new Date(), new Date());
	this.fileList.changeFile(watchedFile.originalPath);
};

Plugin.prototype.make = function(compilation, callback) {
	async.forEach(this.files.slice(), function(file, callback) {
		compilation.addEntry("", new SingleEntryDependency(file), path.relative(this.basePath, file).replace(/\\/g, "/"), callback);
	}.bind(this), callback);
};

Plugin.prototype.readFile = function(file, callback) {
	var server = this.server;
	function doRead() {
		server.middleware.fileSystem.readFile("/_js/"+file.replace(/\\/g, "/"), callback);
	}
	if(!this.waiting) this.waiting = [];
	this.waiting.push(doRead);
}

var sha1 = function(data) {
  var hash = crypto.createHash('sha1');
  hash.update(data);
  return hash.digest('hex');
};

function createPreprocesor(/* config.basePath */basePath, webpackPlugin, logger, config) {
	var log = logger.create("preprocessor.webpack");
	return function(content, file, done) {
		webpackPlugin.karmaWaitsForPreprocessing = true;
		webpackPlugin.addFile(file.path);
		webpackPlugin.readFile(path.relative(basePath, file.path), function(err, content) {
			webpackPlugin.karmaWaitsForPreprocessing = false;
			// Hack: file.sha
			//
			// Karma v0.12 assumes preprocessing is idempotent - always returns the same result on the same input.
			// That's not true with karma-webpack. Not setting file.sha causes browser to use a cached file.
			file.sha = sha1(content);
			done(err, content && content.toString("utf-8"));
		});
	};
}

module.exports = {
	"webpackPlugin": ["type", Plugin],
	"preprocessor:webpack": ["factory", createPreprocesor]
};
<commit_msg>more fixes for autoWatch #10<commit_after>var fs = require("fs");
var crypto = require("crypto");
var path = require("path");
var async = require("async");
var webpackDevServer = require("webpack-dev-server");
var webpack = require("webpack");
var SingleEntryDependency = require("webpack/lib/dependencies/SingleEntryDependency");

function Plugin(/* config.port */karmaPort, /* config.hostname */hostname, /* config.webpackPort */port, /* config.webpack */webpackOptions, /* config.webpackServer */webpackServerOptions, /* config.basePath */basePath, fileList) {
	if(!port) port = karmaPort + 1;
	if(!hostname) hostname = "localhost";
	if(!webpackOptions) webpackOptions = {};
	if(!webpackOptions.output) webpackOptions.output = {};
	if(!webpackServerOptions) webpackServerOptions = {};

	this.files = [];
	this.basePath = basePath;
	this.waiting = [];
	this.fileList = fileList;

	webpackOptions.output.path = "/";
	webpackOptions.output.filename = "_js/[name]";
	webpackOptions.output.chunkFilename = "_js/[id].chunk.js";
	webpackOptions.output.publicPath = "http://" + hostname + ":" + port + "/";

	var compiler = webpack(webpackOptions);
	compiler.plugin("compilation", function(compilation, params) {
		compilation.dependencyFactories.set(SingleEntryDependency, params.normalModuleFactory);
	});
	compiler.plugin("done", function(stats) {
		var compilation = stats.compilation;
		stats = stats.toJson();

		if(!this.waiting || this.waiting.length === 0) {
			// If file required in tests is changed, webpack compilation is done silently for karma.
			// Fix this by emulating test file change.
			this.notifyKarmaAboutChanges(stats);
		}

		if(this.waiting && stats.assets.length > 0) {
			var w = this.waiting;
			this.waiting = null;
			w.forEach(function(cb) {
				cb();
			});
		}
	}.bind(this));
	compiler.plugin("invalid", function() {
		if(!this.waiting) this.waiting = [];
	}.bind(this));
	compiler.plugin("make", this.make.bind(this));
	var server = this.server = new webpackDevServer(compiler, webpackServerOptions);
	server.listen(port, hostname);
}

Plugin.prototype.notifyKarmaAboutChanges = function(stats) {
	// Find recently recompiled files.
	var changedAssets = stats.assets.filter(function (asset) {
		return asset.emitted;
	}).map(function(asset) {
		return asset.name;
	});

	// Pick files watched by karma among them.
	var changedTests = this.files.filter(function (file) {
		var assetName = "_js/" + path.relative(this.basePath, file).replace(/\\/g, "/");
		return changedAssets.indexOf(assetName) !== -1;
	}.bind(this));

	// Make karma to run preprocessors on changed tests.
	changedTests.forEach(function(changedTestFile) {
		this.fileList.buckets.forEach(function(bucket) {
			bucket.forEach(function(watchedFile) {
				if (watchedFile.originalPath === changedTestFile) {
					this.changeKarmaFile(watchedFile);
				}
			}.bind(this));
		}.bind(this));
	}.bind(this));
};

Plugin.prototype.addFile = function(entry) {
	if(this.files.indexOf(entry) >= 0) return;
	this.files.push(entry);
};

Plugin.prototype.changeKarmaFile = function(watchedFile) {
	// Add and remove triggers a rebuild for karma
	this.fileList.removeFile(watchedFile.originalPath);
	this.fileList.addFile(watchedFile.originalPath);
};

Plugin.prototype.make = function(compilation, callback) {
	async.forEach(this.files.slice(), function(file, callback) {
		var dep = new SingleEntryDependency(file);
		compilation.addEntry("", dep, path.relative(this.basePath, file).replace(/\\/g, "/"), function() {
			// If the module fails because of an File not found error, remove the test file
			if(dep.module.error && dep.module.error.error && dep.module.error.error.code === "ENOENT") {
				this.files = this.files.filter(function(f) {
					return file !== f;
				});
				this.server.invalidate();
			}
			callback();
		}.bind(this));
	}.bind(this), callback);
};

Plugin.prototype.readFile = function(file, callback) {
	var server = this.server;
	function doRead() {
		server.middleware.fileSystem.readFile("/_js/"+file.replace(/\\/g, "/"), callback);
	}
	if(!this.waiting)
		doRead();
	else
		// Retry to read once a build is finished
		// do it on process.nextTick to catch changes while building
		this.waiting.push(process.nextTick.bind(process, this.readFile.bind(this, file, callback)));
}

var sha1 = function(data) {
	var hash = crypto.createHash('sha1');
	hash.update(data);
	return hash.digest('hex');
};

function createPreprocesor(/* config.basePath */basePath, webpackPlugin, logger, config) {
	var log = logger.create("preprocessor.webpack");
	return function(content, file, done) {
		webpackPlugin.karmaWaitsForPreprocessing = true;

		webpackPlugin.addFile(file.path);

		// recompile
		webpackPlugin.server.invalidate()

		// read blocks until bundle is done
		webpackPlugin.readFile(path.relative(basePath, file.path), function(err, content) {
			webpackPlugin.karmaWaitsForPreprocessing = false;
			// Hack: file.sha
			//
			// Karma v0.12 assumes preprocessing is idempotent - always returns the same result on the same input.
			// That's not true with karma-webpack. Not setting file.sha causes browser to use a cached file.
			file.sha = sha1(content);
			done(err, content && content.toString("utf-8"));
		});
	};
}

module.exports = {
	"webpackPlugin": ["type", Plugin],
	"preprocessor:webpack": ["factory", createPreprocesor]
};
<|endoftext|>


<commit_before>'use strict'

const assert = require('assert')
const methods = require('methods')
const compose = require('koa-compose')
const pathToRegexp = require('path-to-regexp')

//
// router({ prefix: '/path', ...setting }, _ => { })
//
module.exports = function router (options, init) {
  return new Router(options, init)._routes()
}

class Layer {
  constructor (router, path, array) {
    assert(array.every(x => typeof x === 'function'))

    this.router = router
    this.middleware = undefined
    this.array = array
    this.keys = []
    this.regexp = pathToRegexp(path, this.keys, router._options)
    this.recompile()
  }

  recompile () {
    let arr = this.keys.filter(key => this.router._params.has(key.name))
                       .map(key => this.router._params.get(key.name))
                       .concat(this.array)
    this.middleware = arr.length === 1 ? arr[0] : compose(arr)
  }
}

class Router {
  constructor (options, fn) {
    if (typeof options === 'function') {
      fn = options
      options = null
    }

    options = Object.assign({
      sensitive: false,
      strict: false,
      end: true
    }, options)

    this._options = options
    this._params = new Map()
    this._map = new Map()
    this._all = []
    this._stack = []
    this._prefix = undefined

    let prefix = options.prefix
    if (prefix) {
      assert(typeof prefix === 'string', 'prefix should be a string')
      assert(prefix.slice(-1) !== '/', 'prefix should not end with "/"')

      this._prefix = new Layer(this, `${prefix}/:rest*`, [])
      this._prefix.keys.pop()
    }

    for (let method of methods) {
      this[method] = function (path) {
        let layer = new Layer(this, path, Array.from(arguments).slice(1))

        let METHOD = method.toUpperCase()
        if (METHOD === 'GET') {
          if (!this._map.has('HEAD')) {
            this._map.set('HEAD', [].concat(this._all))
          }
          this._map.get('HEAD').push(layer)
        }
        if (!this._map.has(METHOD)) {
          this._map.set(METHOD, [].concat(this._all))
        }
        this._map.get(METHOD).push(layer)
        this._stack.push(layer)

        return this
      }
    }

    fn(this)
  }

  all (path) {
    let layer = new Layer(this, path, Array.from(arguments).slice(1).map(
      obj => typeof obj === 'function' ? obj : this._convertObjectToMiddleware(obj)
    ))

    this._map.forEach(value => value.push(layer))
    this._all.push(layer)
    this._stack.push(layer)

    return this
  }

  param (name) {
    let arr = Array.from(arguments).slice(1)

    assert(typeof name === 'string')
    assert(!this._params.has(name))
    assert(arr.every(x => typeof x === 'function'))

    let mw = arr.length === 1 ? arr[0] : compose(arr)

    let symbol = Symbol()

    this._params.set(name, (ctx, next) => {
      if (ctx[symbol] || ctx.params[name] == null) {
        return next()
      }
      ctx[symbol] = true
      return mw(ctx, next)
    })

    this._stack.forEach(layer => {
      if (layer.keys.some(key => key.name === name)) {
        layer.recompile()
      }
    })

    if (this._prefix) {
      if (this._prefix.keys.some(key => key.name === name)) {
        this._prefix.recompile()
      }
    }

    return this
  }

  _routes () {
    if (!this._prefix) {
      return (ctx, next) => {
        return this._lookup(ctx, next, ctx.path)
      }
    }

    return (ctx, next) => {
      let res = this._prefix.regexp.exec(ctx.path)
      if (res == null) {
        return next()
      }
      this._setParams(ctx, this._prefix.keys, res)

      let path = res[res.length - 1] || '/'
      if (path[0] !== '/') {
        path = '/' + path
      }

      let mw = this._prefix.middleware
      if (mw) {
        return mw(ctx, () => {
          try {
            return Promise.resolve(this._lookup(ctx, next, path))
          } catch (e) {
            return Promise.reject(e)
          }
        })
      }

      return this._lookup(ctx, next, path)
    }
  }

  _lookup (ctx, next, path) {
    let method = ctx.method
    let group = this._map.has(method) ? this._map.get(method) : this._all
    let index = -1
    let dispatch = i => {
      if (i <= index) {
        throw new Error('next() called multiple times')
      }
      while (i < group.length) {
        let layer = group[i]
        let res = layer.regexp.exec(path)
        if (res == null) {
          i += 1
        } else {
          index = i
          this._setParams(ctx, layer.keys, res)
          let mw = layer.middleware
          return mw(ctx, () => {
            try {
              return Promise.resolve(dispatch(i + 1))
            } catch (e) {
              return Promise.reject(e)
            }
          })
        }
      }
      index = i
      return next()
    }
    return dispatch(0)
  }

  _convertObjectToMiddleware (obj) {
    let map = new Map()
    for (let key of Object.keys(obj)) {
      let mw = obj[key]
      if (Array.isArray(mw)) {
        mw = compose(mw)
      }
      if (typeof mw !== 'function') {
        throw new Error(mw + ' is not array or function (middleware)')
      }
      if (methods.indexOf(key.toLowerCase()) < 0) {
        throw new Error(`invalid method "${key}"`)
      }
      map.set(key.toUpperCase(), mw)
    }
    if (map.has('GET') && !map.has('HEAD')) {
      map.set('HEAD', map.get('GET'))
    }
    if (!map.has('OPTIONS')) {
      map.set('OPTIONS', (ctx, next) => {
        ctx.status = 200
        ctx.set('Allow', allowed)
      })
    }
    let allowed = Array.from(map.keys()).join(', ')
    return (ctx, next) => {
      let method = ctx.method
      if (map.has(method)) {
        return map.get(method)(ctx, next)
      }
      ctx.status = 405
      ctx.set('Allow', allowed)
    }
  }

  _setParams (ctx, keys, result) {
    ctx.params = ctx.params || {}

    for (let j = 0; j < keys.length; j++) {
      let param = result[j + 1]
      if (param) {
        ctx.params[keys[j].name] = this._safeDecodeURIComponent(param)
      }
    }
  }

  _safeDecodeURIComponent (str) {
    try {
      return decodeURIComponent(str)
    } catch (e) {
      return str
    }
  }
}
<commit_msg>set default value of prefix as null<commit_after>'use strict'

const assert = require('assert')
const methods = require('methods')
const compose = require('koa-compose')
const pathToRegexp = require('path-to-regexp')

//
// router({ prefix: '/path', ...setting }, _ => { })
//
module.exports = function router (options, init) {
  return new Router(options, init)._routes()
}

class Layer {
  constructor (router, path, array) {
    assert(array.every(x => typeof x === 'function'))

    this.router = router
    this.middleware = undefined
    this.array = array
    this.keys = []
    this.regexp = pathToRegexp(path, this.keys, router._options)
    this.recompile()
  }

  recompile () {
    let arr = this.keys.filter(key => this.router._params.has(key.name))
                       .map(key => this.router._params.get(key.name))
                       .concat(this.array)
    this.middleware = arr.length === 1 ? arr[0] : compose(arr)
  }
}

class Router {
  constructor (options, fn) {
    if (typeof options === 'function') {
      fn = options
      options = null
    }

    options = Object.assign({
      prefix: null,
      sensitive: false,
      strict: false,
      end: true
    }, options)

    this._options = options
    this._params = new Map()
    this._map = new Map()
    this._all = []
    this._stack = []
    this._prefix = null

    let prefix = options.prefix
    if (prefix) {
      assert(typeof prefix === 'string', 'prefix should be a string')
      assert(prefix.slice(-1) !== '/', 'prefix should not end with "/"')

      this._prefix = new Layer(this, `${prefix}/:rest*`, [])
      this._prefix.keys.pop()
    }

    for (let method of methods) {
      this[method] = function (path) {
        let layer = new Layer(this, path, Array.from(arguments).slice(1))

        let METHOD = method.toUpperCase()
        if (METHOD === 'GET') {
          if (!this._map.has('HEAD')) {
            this._map.set('HEAD', [].concat(this._all))
          }
          this._map.get('HEAD').push(layer)
        }
        if (!this._map.has(METHOD)) {
          this._map.set(METHOD, [].concat(this._all))
        }
        this._map.get(METHOD).push(layer)
        this._stack.push(layer)

        return this
      }
    }

    fn(this)
  }

  all (path) {
    let layer = new Layer(this, path, Array.from(arguments).slice(1).map(
      obj => typeof obj === 'function' ? obj : this._convertObjectToMiddleware(obj)
    ))

    this._map.forEach(value => value.push(layer))
    this._all.push(layer)
    this._stack.push(layer)

    return this
  }

  param (name) {
    let arr = Array.from(arguments).slice(1)

    assert(typeof name === 'string')
    assert(!this._params.has(name))
    assert(arr.every(x => typeof x === 'function'))

    let mw = arr.length === 1 ? arr[0] : compose(arr)

    let symbol = Symbol()

    this._params.set(name, (ctx, next) => {
      if (ctx[symbol] || ctx.params[name] == null) {
        return next()
      }
      ctx[symbol] = true
      return mw(ctx, next)
    })

    this._stack.forEach(layer => {
      if (layer.keys.some(key => key.name === name)) {
        layer.recompile()
      }
    })

    if (this._prefix) {
      if (this._prefix.keys.some(key => key.name === name)) {
        this._prefix.recompile()
      }
    }

    return this
  }

  _routes () {
    if (!this._prefix) {
      return (ctx, next) => {
        return this._lookup(ctx, next, ctx.path)
      }
    }

    return (ctx, next) => {
      let res = this._prefix.regexp.exec(ctx.path)
      if (res == null) {
        return next()
      }
      this._setParams(ctx, this._prefix.keys, res)

      let path = res[res.length - 1] || '/'
      if (path[0] !== '/') {
        path = '/' + path
      }

      let mw = this._prefix.middleware
      if (mw) {
        return mw(ctx, () => {
          try {
            return Promise.resolve(this._lookup(ctx, next, path))
          } catch (e) {
            return Promise.reject(e)
          }
        })
      }

      return this._lookup(ctx, next, path)
    }
  }

  _lookup (ctx, next, path) {
    let method = ctx.method
    let group = this._map.has(method) ? this._map.get(method) : this._all
    let index = -1
    let dispatch = i => {
      if (i <= index) {
        throw new Error('next() called multiple times')
      }
      while (i < group.length) {
        let layer = group[i]
        let res = layer.regexp.exec(path)
        if (res == null) {
          i += 1
        } else {
          index = i
          this._setParams(ctx, layer.keys, res)
          let mw = layer.middleware
          return mw(ctx, () => {
            try {
              return Promise.resolve(dispatch(i + 1))
            } catch (e) {
              return Promise.reject(e)
            }
          })
        }
      }
      index = i
      return next()
    }
    return dispatch(0)
  }

  _convertObjectToMiddleware (obj) {
    let map = new Map()
    for (let key of Object.keys(obj)) {
      let mw = obj[key]
      if (Array.isArray(mw)) {
        mw = compose(mw)
      }
      if (typeof mw !== 'function') {
        throw new Error(mw + ' is not array or function (middleware)')
      }
      if (methods.indexOf(key.toLowerCase()) < 0) {
        throw new Error(`invalid method "${key}"`)
      }
      map.set(key.toUpperCase(), mw)
    }
    if (map.has('GET') && !map.has('HEAD')) {
      map.set('HEAD', map.get('GET'))
    }
    if (!map.has('OPTIONS')) {
      map.set('OPTIONS', (ctx, next) => {
        ctx.status = 200
        ctx.set('Allow', allowed)
      })
    }
    let allowed = Array.from(map.keys()).join(', ')
    return (ctx, next) => {
      let method = ctx.method
      if (map.has(method)) {
        return map.get(method)(ctx, next)
      }
      ctx.status = 405
      ctx.set('Allow', allowed)
    }
  }

  _setParams (ctx, keys, result) {
    ctx.params = ctx.params || {}

    for (let j = 0; j < keys.length; j++) {
      let param = result[j + 1]
      if (param) {
        ctx.params[keys[j].name] = this._safeDecodeURIComponent(param)
      }
    }
  }

  _safeDecodeURIComponent (str) {
    try {
      return decodeURIComponent(str)
    } catch (e) {
      return str
    }
  }
}
<|endoftext|>