<commit_before>var SourceMapConsumer = require('source-map').SourceMapConsumer;
var path = require('path');
var fs = require('fs');

// Only install once if called multiple times
var alreadyInstalled = false;

// If true, the caches are reset before a stack trace formatting operation
var emptyCacheBetweenOperations = false;

// Maps a file path to a string containing the file contents
var fileContentsCache = {};

// Maps a file path to a source map for that file
var sourceMapCache = {};

function isInBrowser() {
  return typeof window !== 'undefined';
}

function retrieveFile(path) {
  if (path in fileContentsCache) {
    return fileContentsCache[path];
  }

  try {
    // Use SJAX if we are in the browser
    if (isInBrowser()) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET', path, false);
      xhr.send(null);
      var contents = xhr.readyState === 4 ? xhr.responseText : null;
    }

    // Otherwise, use the filesystem
    else {
      var contents = fs.readFileSync(path, 'utf8');
    }
  } catch (e) {
    var contents = null;
  }

  return fileContentsCache[path] = contents;
}

// Support URLs relative to a directory, but be careful about a protocol prefix
// in case we are in the browser (i.e. directories may start with "http://")
function supportRelativeURL(file, url) {
  if (!file) return url;
  var dir = path.dirname(file);
  var match = /^\w+:\/\/[^\/]*/.exec(dir);
  var protocol = match ? match[0] : '';
  return protocol + path.resolve(dir.slice(protocol.length), url);
}

function retrieveSourceMapURL(source) {
  var fileData;

  if (isInBrowser()) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', source, false);
    xhr.send(null);
    fileData = xhr.readyState === 4 ? xhr.responseText : null;

    // Support providing a sourceMappingURL via the SourceMap header
    var sourceMapHeader = xhr.getResponseHeader("SourceMap") ||
                          xhr.getResponseHeader("X-SourceMap");
    if (sourceMapHeader) {
      return sourceMapHeader;
    }
  }

  // Get the URL of the source map
  fileData = retrieveFile(source);
  var match = /\/\/[#@]\s*sourceMappingURL=(.*)\s*$/m.exec(fileData);
  if (!match) return null;
  return match[1];
};

// Can be overridden by the retrieveSourceMap option to install. Takes a
// generated source filename; returns a {map, optional url} object, or null if
// there is no source map.  The map field may be either a string or the parsed
// JSON object (ie, it must be a valid argument to the SourceMapConsumer
// constructor).
function retrieveSourceMap(source) {
  var sourceMappingURL = retrieveSourceMapURL(source);
  if (!sourceMappingURL) return null;

  // Read the contents of the source map
  var sourceMapData;
  var dataUrlPrefix = "data:application/json;base64,";
  if (sourceMappingURL.slice(0, dataUrlPrefix.length).toLowerCase() == dataUrlPrefix) {
    // Support source map URL as a data url
    sourceMapData = new Buffer(sourceMappingURL.slice(dataUrlPrefix.length), "base64").toString();
    sourceMappingURL = null;
  } else {
    // Support source map URLs relative to the source URL
    sourceMappingURL = supportRelativeURL(source, sourceMappingURL);
    sourceMapData = retrieveFile(sourceMappingURL, 'utf8');
  }

  if (!sourceMapData) {
    return null;
  }

  return {
    url: sourceMappingURL,
    map: sourceMapData
  };
}

function mapSourcePosition(position) {
  var sourceMap = sourceMapCache[position.source];
  if (!sourceMap) {
    // Call the (overrideable) retrieveSourceMap function to get the source map.
    var urlAndMap = retrieveSourceMap(position.source);
    if (urlAndMap) {
      sourceMap = sourceMapCache[position.source] = {
        url: urlAndMap.url,
        map: new SourceMapConsumer(urlAndMap.map)
      };

      // Load all sources stored inline with the source map into the file cache
      // to pretend like they are already loaded. They may not exist on disk.
      if (sourceMap.map.sourcesContent) {
        sourceMap.map.sources.forEach(function(source, i) {
          var contents = sourceMap.map.sourcesContent[i];
          if (contents) {
            var url = supportRelativeURL(sourceMap.url, source);
            fileContentsCache[url] = contents;
          }
        });
      }
    }
  }

  // Resolve the source URL relative to the URL of the source map
  if (sourceMap) {
    var originalPosition = sourceMap.map.originalPositionFor(position);

    // Only return the original position if a matching line was found. If no
    // matching line is found then we return position instead, which will cause
    // the stack trace to print the path and line for the compiled file. It is
    // better to give a precise location in the compiled file than a vague
    // location in the original file.
    if (originalPosition.source !== null) {
      originalPosition.source = supportRelativeURL(
        sourceMap.url, originalPosition.source);
      return originalPosition;
    }
  }

  return position;
}

// Parses code generated by FormatEvalOrigin(), a function inside V8:
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js
function mapEvalOrigin(origin) {
  // Most eval() calls are in this format
  var match = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(origin);
  if (match) {
    var position = mapSourcePosition({
      source: match[2],
      line: match[3],
      column: match[4] - 1
    });
    return 'eval at ' + match[1] + ' (' + position.source + ':' +
      position.line + ':' + (position.column + 1) + ')';
  }

  // Parse nested eval() calls using recursion
  match = /^eval at ([^(]+) \((.+)\)$/.exec(origin);
  if (match) {
    return 'eval at ' + match[1] + ' (' + mapEvalOrigin(match[2]) + ')';
  }

  // Make sure we still return useful information if we didn't find anything
  return origin;
}

// This is copied almost verbatim from the V8 source code at
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js. The
// implementation of wrapCallSite() used to just forward to the actual source
// code of CallSite.prototype.toString but unfortunately a new release of V8
// did something to the prototype chain and broke the shim. The only fix I
// could find was copy/paste.
function CallSiteToString() {
  var fileName;
  var fileLocation = "";
  if (this.isNative()) {
    fileLocation = "native";
  } else {
    fileName = this.getScriptNameOrSourceURL();
    if (!fileName && this.isEval()) {
      fileLocation = this.getEvalOrigin();
      fileLocation += ", ";  // Expecting source position to follow.
    }

    if (fileName) {
      fileLocation += fileName;
    } else {
      // Source code does not originate from a file and is not native, but we
      // can still get the source position inside the source string, e.g. in
      // an eval string.
      fileLocation += "<anonymous>";
    }
    var lineNumber = this.getLineNumber();
    if (lineNumber != null) {
      fileLocation += ":" + lineNumber;
      var columnNumber = this.getColumnNumber();
      if (columnNumber) {
        fileLocation += ":" + columnNumber;
      }
    }
  }

  var line = "";
  var functionName = this.getFunctionName();
  var addSuffix = true;
  var isConstructor = this.isConstructor();
  var isMethodCall = !(this.isToplevel() || isConstructor);
  if (isMethodCall) {
    var typeName = this.getTypeName();
    var methodName = this.getMethodName();
    if (functionName) {
      if (typeName && functionName.indexOf(typeName) != 0) {
        line += typeName + ".";
      }
      line += functionName;
      if (methodName && functionName.indexOf("." + methodName) != functionName.length - methodName.length - 1) {
        line += " [as " + methodName + "]";
      }
    } else {
      line += typeName + "." + (methodName || "<anonymous>");
    }
  } else if (isConstructor) {
    line += "new " + (functionName || "<anonymous>");
  } else if (functionName) {
    line += functionName;
  } else {
    line += fileLocation;
    addSuffix = false;
  }
  if (addSuffix) {
    line += " (" + fileLocation + ")";
  }
  return line;
}

function cloneCallSite(frame) {
  var object = {};
  Object.getOwnPropertyNames(Object.getPrototypeOf(frame)).forEach(function(name) {
    object[name] = /^(?:is|get)/.test(name) ? function() { return frame[name].call(frame); } : frame[name];
  });
  object.toString = CallSiteToString;
  return object;
}

function wrapCallSite(frame) {
  // Most call sites will return the source file from getFileName(), but code
  // passed to eval() ending in "//# sourceURL=..." will return the source file
  // from getScriptNameOrSourceURL() instead
  var source = frame.getFileName() || frame.getScriptNameOrSourceURL();
  if (source) {
    var position = mapSourcePosition({
      source: source,
      line: frame.getLineNumber(),
      column: frame.getColumnNumber() - 1
    });
    frame = cloneCallSite(frame);
    frame.getFileName = function() { return position.source; };
    frame.getLineNumber = function() { return position.line; };
    frame.getColumnNumber = function() { return position.column + 1; };
    frame.getScriptNameOrSourceURL = function() { return position.source; };
    return frame;
  }

  // Code called using eval() needs special handling
  var origin = frame.isEval() && frame.getEvalOrigin();
  if (origin) {
    origin = mapEvalOrigin(origin);
    frame = cloneCallSite(frame);
    frame.getEvalOrigin = function() { return origin; };
    return frame;
  }

  // If we get here then we were unable to change the source position
  return frame;
}

// This function is part of the V8 stack trace API, for more info see:
// http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
function prepareStackTrace(error, stack) {
  if (emptyCacheBetweenOperations) {
    fileContentsCache = {};
    sourceMapCache = {};
  }
  return error + stack.map(function(frame) {
    return '\n    at ' + wrapCallSite(frame);
  }).join('');
}

// Generate position and snippet of original source with pointer
function getErrorSource(error) {
  var match = /\n    at [^(]+ \((.*):(\d+):(\d+)\)/.exec(error.stack);
  if (match) {
    var source = match[1];
    var line = +match[2];
    var column = +match[3];

    // Support the inline sourceContents inside the source map
    var contents = fileContentsCache[source];

    // Support files on disk
    if (!contents && fs.existsSync(source)) {
      contents = fs.readFileSync(source, 'utf8');
    }

    // Format the line from the original source code like node does
    if (contents) {
      var code = contents.split(/(?:\r\n|\r|\n)/)[line - 1];
      if (code) {
        return '\n' + source + ':' + line + '\n' + code + '\n' +
          new Array(column).join(' ') + '^';
      }
    }
  }
  return null;
}

// Mimic node's stack trace printing when an exception escapes the process
function handleUncaughtExceptions(error) {
  if (!error || !error.stack) {
    console.log('Uncaught exception:', error);
  } else {
    var source = getErrorSource(error);
    if (source !== null) console.log(source);
    console.log(error.stack);
  }
  process.exit(1);
}

exports.wrapCallSite = wrapCallSite;
exports.getErrorSource = getErrorSource;
exports.mapSourcePosition = mapSourcePosition;
exports.retrieveSourceMap = retrieveSourceMap;

exports.install = function(options) {
  if (!alreadyInstalled) {
    alreadyInstalled = true;
    Error.prepareStackTrace = prepareStackTrace;

    // Configure options
    options = options || {};
    var installHandler = 'handleUncaughtExceptions' in options ?
      options.handleUncaughtExceptions : true;
    emptyCacheBetweenOperations = 'emptyCacheBetweenOperations' in options ?
      options.emptyCacheBetweenOperations : false;

    // Allow sources to be found by methods other than reading the files
    // directly from disk.
    if (options.retrieveFile)
      retrieveFile = options.retrieveFile;

    // Allow source maps to be found by methods other than reading the files
    // directly from disk.
    if (options.retrieveSourceMap)
      retrieveSourceMap = options.retrieveSourceMap;

    // Provide the option to not install the uncaught exception handler. This is
    // to support other uncaught exception handlers (in test frameworks, for
    // example). If this handler is not installed and there are no other uncaught
    // exception handlers, uncaught exceptions will be caught by node's built-in
    // exception handler and the process will still be terminated. However, the
    // generated JavaScript code will be shown above the stack trace instead of
    // the original source code.
    if (installHandler && !isInBrowser()) {
      process.on('uncaughtException', handleUncaughtExceptions);
    }
  }
};
<commit_msg>Making use of console.error<commit_after>var SourceMapConsumer = require('source-map').SourceMapConsumer;
var path = require('path');
var fs = require('fs');

// Only install once if called multiple times
var alreadyInstalled = false;

// If true, the caches are reset before a stack trace formatting operation
var emptyCacheBetweenOperations = false;

// Maps a file path to a string containing the file contents
var fileContentsCache = {};

// Maps a file path to a source map for that file
var sourceMapCache = {};

function isInBrowser() {
  return typeof window !== 'undefined';
}

function retrieveFile(path) {
  if (path in fileContentsCache) {
    return fileContentsCache[path];
  }

  try {
    // Use SJAX if we are in the browser
    if (isInBrowser()) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET', path, false);
      xhr.send(null);
      var contents = xhr.readyState === 4 ? xhr.responseText : null;
    }

    // Otherwise, use the filesystem
    else {
      var contents = fs.readFileSync(path, 'utf8');
    }
  } catch (e) {
    var contents = null;
  }

  return fileContentsCache[path] = contents;
}

// Support URLs relative to a directory, but be careful about a protocol prefix
// in case we are in the browser (i.e. directories may start with "http://")
function supportRelativeURL(file, url) {
  if (!file) return url;
  var dir = path.dirname(file);
  var match = /^\w+:\/\/[^\/]*/.exec(dir);
  var protocol = match ? match[0] : '';
  return protocol + path.resolve(dir.slice(protocol.length), url);
}

function retrieveSourceMapURL(source) {
  var fileData;

  if (isInBrowser()) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', source, false);
    xhr.send(null);
    fileData = xhr.readyState === 4 ? xhr.responseText : null;

    // Support providing a sourceMappingURL via the SourceMap header
    var sourceMapHeader = xhr.getResponseHeader("SourceMap") ||
                          xhr.getResponseHeader("X-SourceMap");
    if (sourceMapHeader) {
      return sourceMapHeader;
    }
  }

  // Get the URL of the source map
  fileData = retrieveFile(source);
  var match = /\/\/[#@]\s*sourceMappingURL=(.*)\s*$/m.exec(fileData);
  if (!match) return null;
  return match[1];
};

// Can be overridden by the retrieveSourceMap option to install. Takes a
// generated source filename; returns a {map, optional url} object, or null if
// there is no source map.  The map field may be either a string or the parsed
// JSON object (ie, it must be a valid argument to the SourceMapConsumer
// constructor).
function retrieveSourceMap(source) {
  var sourceMappingURL = retrieveSourceMapURL(source);
  if (!sourceMappingURL) return null;

  // Read the contents of the source map
  var sourceMapData;
  var dataUrlPrefix = "data:application/json;base64,";
  if (sourceMappingURL.slice(0, dataUrlPrefix.length).toLowerCase() == dataUrlPrefix) {
    // Support source map URL as a data url
    sourceMapData = new Buffer(sourceMappingURL.slice(dataUrlPrefix.length), "base64").toString();
    sourceMappingURL = null;
  } else {
    // Support source map URLs relative to the source URL
    sourceMappingURL = supportRelativeURL(source, sourceMappingURL);
    sourceMapData = retrieveFile(sourceMappingURL, 'utf8');
  }

  if (!sourceMapData) {
    return null;
  }

  return {
    url: sourceMappingURL,
    map: sourceMapData
  };
}

function mapSourcePosition(position) {
  var sourceMap = sourceMapCache[position.source];
  if (!sourceMap) {
    // Call the (overrideable) retrieveSourceMap function to get the source map.
    var urlAndMap = retrieveSourceMap(position.source);
    if (urlAndMap) {
      sourceMap = sourceMapCache[position.source] = {
        url: urlAndMap.url,
        map: new SourceMapConsumer(urlAndMap.map)
      };

      // Load all sources stored inline with the source map into the file cache
      // to pretend like they are already loaded. They may not exist on disk.
      if (sourceMap.map.sourcesContent) {
        sourceMap.map.sources.forEach(function(source, i) {
          var contents = sourceMap.map.sourcesContent[i];
          if (contents) {
            var url = supportRelativeURL(sourceMap.url, source);
            fileContentsCache[url] = contents;
          }
        });
      }
    }
  }

  // Resolve the source URL relative to the URL of the source map
  if (sourceMap) {
    var originalPosition = sourceMap.map.originalPositionFor(position);

    // Only return the original position if a matching line was found. If no
    // matching line is found then we return position instead, which will cause
    // the stack trace to print the path and line for the compiled file. It is
    // better to give a precise location in the compiled file than a vague
    // location in the original file.
    if (originalPosition.source !== null) {
      originalPosition.source = supportRelativeURL(
        sourceMap.url, originalPosition.source);
      return originalPosition;
    }
  }

  return position;
}

// Parses code generated by FormatEvalOrigin(), a function inside V8:
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js
function mapEvalOrigin(origin) {
  // Most eval() calls are in this format
  var match = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(origin);
  if (match) {
    var position = mapSourcePosition({
      source: match[2],
      line: match[3],
      column: match[4] - 1
    });
    return 'eval at ' + match[1] + ' (' + position.source + ':' +
      position.line + ':' + (position.column + 1) + ')';
  }

  // Parse nested eval() calls using recursion
  match = /^eval at ([^(]+) \((.+)\)$/.exec(origin);
  if (match) {
    return 'eval at ' + match[1] + ' (' + mapEvalOrigin(match[2]) + ')';
  }

  // Make sure we still return useful information if we didn't find anything
  return origin;
}

// This is copied almost verbatim from the V8 source code at
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js. The
// implementation of wrapCallSite() used to just forward to the actual source
// code of CallSite.prototype.toString but unfortunately a new release of V8
// did something to the prototype chain and broke the shim. The only fix I
// could find was copy/paste.
function CallSiteToString() {
  var fileName;
  var fileLocation = "";
  if (this.isNative()) {
    fileLocation = "native";
  } else {
    fileName = this.getScriptNameOrSourceURL();
    if (!fileName && this.isEval()) {
      fileLocation = this.getEvalOrigin();
      fileLocation += ", ";  // Expecting source position to follow.
    }

    if (fileName) {
      fileLocation += fileName;
    } else {
      // Source code does not originate from a file and is not native, but we
      // can still get the source position inside the source string, e.g. in
      // an eval string.
      fileLocation += "<anonymous>";
    }
    var lineNumber = this.getLineNumber();
    if (lineNumber != null) {
      fileLocation += ":" + lineNumber;
      var columnNumber = this.getColumnNumber();
      if (columnNumber) {
        fileLocation += ":" + columnNumber;
      }
    }
  }

  var line = "";
  var functionName = this.getFunctionName();
  var addSuffix = true;
  var isConstructor = this.isConstructor();
  var isMethodCall = !(this.isToplevel() || isConstructor);
  if (isMethodCall) {
    var typeName = this.getTypeName();
    var methodName = this.getMethodName();
    if (functionName) {
      if (typeName && functionName.indexOf(typeName) != 0) {
        line += typeName + ".";
      }
      line += functionName;
      if (methodName && functionName.indexOf("." + methodName) != functionName.length - methodName.length - 1) {
        line += " [as " + methodName + "]";
      }
    } else {
      line += typeName + "." + (methodName || "<anonymous>");
    }
  } else if (isConstructor) {
    line += "new " + (functionName || "<anonymous>");
  } else if (functionName) {
    line += functionName;
  } else {
    line += fileLocation;
    addSuffix = false;
  }
  if (addSuffix) {
    line += " (" + fileLocation + ")";
  }
  return line;
}

function cloneCallSite(frame) {
  var object = {};
  Object.getOwnPropertyNames(Object.getPrototypeOf(frame)).forEach(function(name) {
    object[name] = /^(?:is|get)/.test(name) ? function() { return frame[name].call(frame); } : frame[name];
  });
  object.toString = CallSiteToString;
  return object;
}

function wrapCallSite(frame) {
  // Most call sites will return the source file from getFileName(), but code
  // passed to eval() ending in "//# sourceURL=..." will return the source file
  // from getScriptNameOrSourceURL() instead
  var source = frame.getFileName() || frame.getScriptNameOrSourceURL();
  if (source) {
    var position = mapSourcePosition({
      source: source,
      line: frame.getLineNumber(),
      column: frame.getColumnNumber() - 1
    });
    frame = cloneCallSite(frame);
    frame.getFileName = function() { return position.source; };
    frame.getLineNumber = function() { return position.line; };
    frame.getColumnNumber = function() { return position.column + 1; };
    frame.getScriptNameOrSourceURL = function() { return position.source; };
    return frame;
  }

  // Code called using eval() needs special handling
  var origin = frame.isEval() && frame.getEvalOrigin();
  if (origin) {
    origin = mapEvalOrigin(origin);
    frame = cloneCallSite(frame);
    frame.getEvalOrigin = function() { return origin; };
    return frame;
  }

  // If we get here then we were unable to change the source position
  return frame;
}

// This function is part of the V8 stack trace API, for more info see:
// http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
function prepareStackTrace(error, stack) {
  if (emptyCacheBetweenOperations) {
    fileContentsCache = {};
    sourceMapCache = {};
  }
  return error + stack.map(function(frame) {
    return '\n    at ' + wrapCallSite(frame);
  }).join('');
}

// Generate position and snippet of original source with pointer
function getErrorSource(error) {
  var match = /\n    at [^(]+ \((.*):(\d+):(\d+)\)/.exec(error.stack);
  if (match) {
    var source = match[1];
    var line = +match[2];
    var column = +match[3];

    // Support the inline sourceContents inside the source map
    var contents = fileContentsCache[source];

    // Support files on disk
    if (!contents && fs.existsSync(source)) {
      contents = fs.readFileSync(source, 'utf8');
    }

    // Format the line from the original source code like node does
    if (contents) {
      var code = contents.split(/(?:\r\n|\r|\n)/)[line - 1];
      if (code) {
        return '\n' + source + ':' + line + '\n' + code + '\n' +
          new Array(column).join(' ') + '^';
      }
    }
  }
  return null;
}

// Mimic node's stack trace printing when an exception escapes the process
function handleUncaughtExceptions(error) {
  if (!error || !error.stack) {
    console.error('Uncaught exception:', error);
  } else {
    var source = getErrorSource(error);
    if (source !== null) console.error(source);
    console.error(error.stack);
  }
  process.exit(1);
}

exports.wrapCallSite = wrapCallSite;
exports.getErrorSource = getErrorSource;
exports.mapSourcePosition = mapSourcePosition;
exports.retrieveSourceMap = retrieveSourceMap;

exports.install = function(options) {
  if (!alreadyInstalled) {
    alreadyInstalled = true;
    Error.prepareStackTrace = prepareStackTrace;

    // Configure options
    options = options || {};
    var installHandler = 'handleUncaughtExceptions' in options ?
      options.handleUncaughtExceptions : true;
    emptyCacheBetweenOperations = 'emptyCacheBetweenOperations' in options ?
      options.emptyCacheBetweenOperations : false;

    // Allow sources to be found by methods other than reading the files
    // directly from disk.
    if (options.retrieveFile)
      retrieveFile = options.retrieveFile;

    // Allow source maps to be found by methods other than reading the files
    // directly from disk.
    if (options.retrieveSourceMap)
      retrieveSourceMap = options.retrieveSourceMap;

    // Provide the option to not install the uncaught exception handler. This is
    // to support other uncaught exception handlers (in test frameworks, for
    // example). If this handler is not installed and there are no other uncaught
    // exception handlers, uncaught exceptions will be caught by node's built-in
    // exception handler and the process will still be terminated. However, the
    // generated JavaScript code will be shown above the stack trace instead of
    // the original source code.
    if (installHandler && !isInBrowser()) {
      process.on('uncaughtException', handleUncaughtExceptions);
    }
  }
};
<|endoftext|>


<commit_before>
/*!
 * connect-mongo
 * Copyright(c) 2011 Casey Banner <kcbanner@gmail.com>
 * MIT Licensed
 */

/**
 * Module dependencies
 */

var Store = require('connect').session.Store;
var mongo = require('mongodb');

/**
 * One day in seconds.
 */

var oneDay = 86400;

/**
 * Default options
 */

var defaultOptions = {host: '127.0.0.1', port: 27017, collection: 'sessions'};

/**
 * Initialize MongoStore with the given `options`.
 * Calls `callback` when db connection is ready (mainly for testing purposes).
 *
 * @param {Object} options
 * @param {Function} callback
 * @api public
 */

var MongoStore = module.exports = function MongoStore(options, callback) {
  options = options || {};
  Store.call(this, options);

  if(!options.db) {
    throw new Error('Required MongoStore option `db` missing');
  }

  var self = this;
  var getCollection = function(callback) {
    self.db.collection(options.collection || defaultOptions.collection, function(err, collection) {
      if (err) {
        throw new Error('Error getting collection: ' + options.collection || defaultOptions.collection);
      }

      self.collection = collection;
      callback && callback();
    });
  };

  this.db = new mongo.Db(options.db || defaultOptions.db, new mongo.Server(options.host || defaultOptions.host,
                                                                           options.port || defaultOptions.port, {}));
  this.db.open(function(err) {
    if (err) {
      throw new Error('Error connecting to db');
    }

    if (options.username && options.password) {
      db.authenticate(options.username, options.password, function () {
        getCollection(callback);
      });
    } else {
      getCollection(callback);
    }
  });
};

/**
 * Inherit from `Store`.
 */

MongoStore.prototype.__proto__ = Store.prototype;

/**
 * Attempt to fetch session by the given `sid`.
 *
 * @param {String} sid
 * @param {Function} fn
 * @api public
 */
MongoStore.prototype.get = function(sid, callback) {
  this.collection.findOne({_id: sid}, function(err, session) {
    try {
      if (session) {
        callback(err, JSON.parse(session.session));
      } else {
        return callback();
      }
    } catch (err) {
      callback(err);
    }
  });
};

/**
 * Commit the given `sess` object associated with the given `sid`.
 *
 * @param {String} sid
 * @param {Session} sess
 * @param {Function} fn
 * @api public
 */

MongoStore.prototype.set = function(sid, session, callback) {
  try {
    var s = {_id: sid, session: JSON.stringify(session)};

    this.collection.update({_id: sid}, s, {upsert: true}, function(err, data) {
      callback && callback(err, JSON.parse(data.session));
    });
  } catch (err) {
    callback && callback(err);
  }
};

/**
 * Destroy the session associated with the given `sid`.
 *
 * @param {String} sid
 * @api public
 */

MongoStore.prototype.destroy = function(sid, callback) {
  this.collection.remove({_id: sid}, callback);
};

/**
 * Fetch number of sessions.
 *
 * @param {Function} fn
 * @api public
 */

MongoStore.prototype.length = function(callback) {
  this.collection.count({}, callback);
};

/**
 * Clear all sessions.
 *
 * @param {Function} fn
 * @api public
 */

MongoStore.prototype.clear = function(callback) {
  this.collection.drop(callback);
};<commit_msg>* Cleanup.<commit_after>
/*!
 * connect-mongo
 * Copyright(c) 2011 Casey Banner <kcbanner@gmail.com>
 * MIT Licensed
 */

/**
 * Module dependencies
 */

var Store = require('connect').session.Store;
var mongo = require('mongodb');

/**
 * Default options
 */

var defaultOptions = {host: '127.0.0.1', port: 27017, collection: 'sessions'};

/**
 * Initialize MongoStore with the given `options`.
 * Calls `callback` when db connection is ready (mainly for testing purposes).
 *
 * @param {Object} options
 * @param {Function} callback
 * @api public
 */

var MongoStore = module.exports = function MongoStore(options, callback) {
  options = options || {};
  Store.call(this, options);

  if(!options.db) {
    throw new Error('Required MongoStore option `db` missing');
  }

  var self = this;
  var getCollection = function(callback) {
    self.db.collection(options.collection || defaultOptions.collection, function(err, collection) {
      if (err) {
        throw new Error('Error getting collection: ' + options.collection || defaultOptions.collection);
      }

      self.collection = collection;
      callback && callback();
    });
  };

  this.db = new mongo.Db(options.db || defaultOptions.db, new mongo.Server(options.host || defaultOptions.host,
                                                                           options.port || defaultOptions.port, {}));
  this.db.open(function(err) {
    if (err) {
      throw new Error('Error connecting to db');
    }

    if (options.username && options.password) {
      db.authenticate(options.username, options.password, function () {
        getCollection(callback);
      });
    } else {
      getCollection(callback);
    }
  });
};

/**
 * Inherit from `Store`.
 */

MongoStore.prototype.__proto__ = Store.prototype;

/**
 * Attempt to fetch session by the given `sid`.
 *
 * @param {String} sid
 * @param {Function} fn
 * @api public
 */
MongoStore.prototype.get = function(sid, callback) {
  this.collection.findOne({_id: sid}, function(err, session) {
    try {
      if (session) {
        callback(err, JSON.parse(session.session));
      } else {
        return callback();
      }
    } catch (err) {
      callback(err);
    }
  });
};

/**
 * Commit the given `sess` object associated with the given `sid`.
 *
 * @param {String} sid
 * @param {Session} sess
 * @param {Function} fn
 * @api public
 */

MongoStore.prototype.set = function(sid, session, callback) {
  try {
    var s = {_id: sid, session: JSON.stringify(session)};
    this.collection.update({_id: sid}, s, {upsert: true}, function(err, data) {
      callback && callback(err, JSON.parse(data.session));
    });
  } catch (err) {
    callback && callback(err);
  }
};

/**
 * Destroy the session associated with the given `sid`.
 *
 * @param {String} sid
 * @api public
 */

MongoStore.prototype.destroy = function(sid, callback) {
  this.collection.remove({_id: sid}, callback);
};

/**
 * Fetch number of sessions.
 *
 * @param {Function} fn
 * @api public
 */

MongoStore.prototype.length = function(callback) {
  this.collection.count({}, callback);
};

/**
 * Clear all sessions.
 *
 * @param {Function} fn
 * @api public
 */

MongoStore.prototype.clear = function(callback) {
  this.collection.drop(callback);
};<|endoftext|>


<commit_before>/* jshint camelcase: false */

/**
 * Module dependencies
 */
var _ = require('lodash');
var crypto = require('crypto');
var mongo = require('mongodb');
var util = require('util');
var debug = require('debug')('connect-mongo');
var deprecate = require('depd')('connect-mongo');

var MongoClient = mongo.MongoClient;
var Db = mongo.Db;

/**
 * Default options
 */
var defaultOptions = {
  // Legacy strategy default options
  host: '127.0.0.1',
  port: 27017,
  autoReconnect: true,
  ssl: false,
  w: 1,

  // Global options
  collection: 'sessions',
  stringify: true,
  hash: false,
  ttl:  60 * 60 * 24 * 14, // 14 days
  ttlAutoIndex: true
};

var defaultHashOptions = {
  salt: 'connect-mongo',
  algorithm: 'sha1'
};

var defaultSerializationOptions = {
  serialize: function (session) {
    // Copy each property of the session to a new object
    var obj = {};
    for (var prop in session) {
      if (prop === 'cookie') {

      // Convert the cookie instance to an object, if possible
      // This gets rid of the duplicate object under session.cookie.data property

        obj.cookie = session.cookie.toJSON ? session.cookie.toJSON() : session.cookie;
      } else {
        obj[prop] = session[prop];
      }
    }

    return obj;
  },
  unserialize: _.identity
};

var stringifySerializationOptions = {
  serialize: JSON.stringify,
  unserialize: JSON.parse
};

module.exports = function(connect) {
  var Store = connect.Store || connect.session.Store;

  /**
   * Initialize MongoStore with the given `options`.
   *
   * @param {Object} options
   * @api public
   */

  function MongoStore(options) {

    /* Deprecated options */

    if ('auto_reconnect' in options) {
      deprecate('auto_reconnect option is deprecated. Use autoReconnect instead');
      options.autoReconnect = options.auto_reconnect;
    }

    if ('mongoose_connection' in options) {
      deprecate('mongoose_connection option is deprecated. Use mongooseConnection instead');
      options.mongooseConnection = options.mongoose_connection;
    }

    if ('defaultExpirationTime' in options) {
      deprecate('defaultExpirationTime option is deprecated. Use ttl instead');
      options.ttl = options.defaultExpirationTime / 1000;
    }

    /* Options */

    options = _.defaults(options || {}, defaultOptions);

    if (options.hash) {
      options.hash = _.defaults(options.hash, defaultHashOptions);
    }

    if (!options.stringify || options.serialize || options.unserialize) {
      options = _.defaults(options, defaultSerializationOptions);
    } else {
      options = _.assign(options, stringifySerializationOptions);
    }

    this.options =  options;

    Store.call(this, options);

    var self = this;

    function changeState(newState) {
      debug('switched to state: %s', newState);
      self.state = newState;
      self.emit(newState);
    }

    function connectionReady(err) {
      if (err) {
          debug('not able to connect to the database');
          changeState('disconnected');
          throw err;
      }

      self.collection = self.db.collection(options.collection);

      if (!self.options.ttlAutoIndex) return changeState('connected');

      self.collection.ensureIndex({ expires: 1 }, { expireAfterSeconds: 0 }, function (err) {
        if (err) throw err;
        changeState('connected');
      });
    }

    function buildUrlFromOptions() {
      if(!options.db || typeof options.db !== 'string') {
        throw new Error('Required MongoStore option `db` missing');
      }

      options.url = 'mongodb://';

      if (options.username) {
        options.url += options.username + ':' + (options.password || '') + '@';
      }

      options.url += options.host + ':' + options.port + '/' + options.db;

      if (options.ssl) options.url += '?ssl=true';

      if (!options.mongoOptions) {
        options.mongoOptions = {
          server: { auto_reconnect: options.autoReconnect },
          db: { w: options.w }
        };
      }
    }

    function initWithUrl() {
      MongoClient.connect(options.url, options.mongoOptions || {}, function(err, db) {
        if (!err) self.db = db;
        connectionReady(err);
      });
    }

    function initWithMongooseConnection() {
      if (options.mongooseConnection.readyState === 1) {
        self.db = options.mongooseConnection.db;
        process.nextTick(connectionReady);
      } else {
        options.mongooseConnection.once('open', function() {
          self.db = options.mongooseConnection.db;
          connectionReady();
        });
      }
    }

    function initWithNativeDb() {
      self.db = options.db;

      if (options.db.openCalled) {
        options.db.collection(options.collection, connectionReady);
      } else {
        options.db.open(connectionReady);
      }
    }

    this.getCollection = function (done) {
      switch (self.state) {
        case 'connected':
          done(null, self.collection);
          break;
        case 'connecting':
          self.once('connected', function () {
            done(null, self.collection);
          });
          break;
        case 'disconnected':
          done(new Error('Not connected'));
          break;
      }
    };

    this.getSessionId = function (sid) {
      if (options.hash) {
        return crypto.createHash(options.hash.algorithm).update(options.hash.salt + sid).digest('hex');
      } else {
        return sid;
      }
    };

    changeState('init');

    if (options.url) {
      debug('use strategy: `url`');
      initWithUrl();
    } else if (options.mongooseConnection) {
      debug('use strategy: `mongoose_connection`');
      initWithMongooseConnection();
    } else if (options.db && options.db instanceof Db) {
      debug('use strategy: `native_db`');
      initWithNativeDb();
    } else {
      debug('use strategy: `legacy`');
      buildUrlFromOptions();
      initWithUrl();
    }

    changeState('connecting');

  }

  /**
   * Inherit from `Store`.
   */
   util.inherits(MongoStore, Store);

  /**
   * Attempt to fetch session by the given `sid`.
   *
   * @param {String} sid
   * @param {Function} callback
   * @api public
   */

  MongoStore.prototype.get = function(sid, callback) {
    if (!callback) callback = _.noop;
    sid = this.getSessionId(sid);

    var self = this;
    this.getCollection(function(err, collection) {
      if (err) return callback(err);
      collection.findOne({_id: sid}, function(err, session) {
        if (err) {
          debug('not able to execute `find` query for session: ' + sid);
          return callback(err);
        }

        if (session) {
          if (!session.expires || Date.now() < session.expires) {
            var s;
            try {
              s = self.options.unserialize(session.session);
            } catch (err) {
              debug('unable to deserialize session');
              callback(err);
            }
            callback(null, s);
          } else {
            self.destroy(sid, callback);
          }
        } else {
          callback();
        }
      });
    });
  };

  /**
   * Commit the given `sess` object associated with the given `sid`.
   *
   * @param {String} sid
   * @param {Session} sess
   * @param {Function} callback
   * @api public
   */

  MongoStore.prototype.set = function(sid, session, callback) {
    if (!callback) callback = _.noop;
    sid = this.getSessionId(sid);

    var s;

    try {
      s = {_id: sid, session: this.options.serialize(session)};
    } catch (err) {
      debug('unable to serialize session');
      callback(err);
    }

    if (session && session.cookie && session.cookie.expires) {
      s.expires = new Date(session.cookie.expires);
    } else {
      // If there's no expiration date specified, it is
      // browser-session cookie or there is no cookie at all,
      // as per the connect docs.
      //
      // So we set the expiration to two-weeks from now
      // - as is common practice in the industry (e.g Django) -
      // or the default specified in the options.
      s.expires = new Date(Date.now() + this.options.ttl * 1000);
    }

    this.getCollection(function(err, collection) {
      if (err) return callback(err);
      collection.update({_id: sid}, s, {upsert: true, safe: true}, function(err) {
        if (err) debug('not able to set/update session: ' + sid);
        callback(err);
      });
    });
  };

  /**
   * Destroy the session associated with the given `sid`.
   *
   * @param {String} sid
   * @param {Function} callback
   * @api public
   */

  MongoStore.prototype.destroy = function(sid, callback) {
    if (!callback) callback = _.noop;
    sid = this.getSessionId(sid);

    this.getCollection(function(err, collection) {
      if (err) return callback(err);
      collection.remove({_id: sid}, function(err) {
        if (err) debug('not able to destroy session: ' + sid);
        callback(err);
      });
    });
  };

  /**
   * Fetch number of sessions.
   *
   * @param {Function} callback
   * @api public
   */

  MongoStore.prototype.length = function(callback) {
    if (!callback) callback = _.noop;
    this.getCollection(function(err, collection) {
      if (err) return callback(err);
      collection.count({}, function(err, count) {
        if (err) debug('not able to count sessions');
        callback(err, count);
      });
    });
  };

  /**
   * Clear all sessions.
   *
   * @param {Function} callback
   * @api public
   */

  MongoStore.prototype.clear = function(callback) {
    if (!callback) callback = _.noop;
    this.getCollection(function(err, collection) {
      if (err) return callback(err);
      collection.drop(function(err) {
        if (err) debug('not able to clear sessions');
        callback(err);
      });
    });
  };

  return MongoStore;
};
<commit_msg>Check expiration in query<commit_after>/* jshint camelcase: false */

/**
 * Module dependencies
 */
var _ = require('lodash');
var crypto = require('crypto');
var mongo = require('mongodb');
var util = require('util');
var debug = require('debug')('connect-mongo');
var deprecate = require('depd')('connect-mongo');

var MongoClient = mongo.MongoClient;
var Db = mongo.Db;

/**
 * Default options
 */
var defaultOptions = {
  // Legacy strategy default options
  host: '127.0.0.1',
  port: 27017,
  autoReconnect: true,
  ssl: false,
  w: 1,

  // Global options
  collection: 'sessions',
  stringify: true,
  hash: false,
  ttl:  60 * 60 * 24 * 14, // 14 days
  ttlAutoIndex: true
};

var defaultHashOptions = {
  salt: 'connect-mongo',
  algorithm: 'sha1'
};

var defaultSerializationOptions = {
  serialize: function (session) {
    // Copy each property of the session to a new object
    var obj = {};
    for (var prop in session) {
      if (prop === 'cookie') {

      // Convert the cookie instance to an object, if possible
      // This gets rid of the duplicate object under session.cookie.data property

        obj.cookie = session.cookie.toJSON ? session.cookie.toJSON() : session.cookie;
      } else {
        obj[prop] = session[prop];
      }
    }

    return obj;
  },
  unserialize: _.identity
};

var stringifySerializationOptions = {
  serialize: JSON.stringify,
  unserialize: JSON.parse
};

module.exports = function(connect) {
  var Store = connect.Store || connect.session.Store;

  /**
   * Initialize MongoStore with the given `options`.
   *
   * @param {Object} options
   * @api public
   */

  function MongoStore(options) {

    /* Deprecated options */

    if ('auto_reconnect' in options) {
      deprecate('auto_reconnect option is deprecated. Use autoReconnect instead');
      options.autoReconnect = options.auto_reconnect;
    }

    if ('mongoose_connection' in options) {
      deprecate('mongoose_connection option is deprecated. Use mongooseConnection instead');
      options.mongooseConnection = options.mongoose_connection;
    }

    if ('defaultExpirationTime' in options) {
      deprecate('defaultExpirationTime option is deprecated. Use ttl instead');
      options.ttl = options.defaultExpirationTime / 1000;
    }

    /* Options */

    options = _.defaults(options || {}, defaultOptions);

    if (options.hash) {
      options.hash = _.defaults(options.hash, defaultHashOptions);
    }

    if (!options.stringify || options.serialize || options.unserialize) {
      options = _.defaults(options, defaultSerializationOptions);
    } else {
      options = _.assign(options, stringifySerializationOptions);
    }

    this.options =  options;

    Store.call(this, options);

    var self = this;

    function changeState(newState) {
      debug('switched to state: %s', newState);
      self.state = newState;
      self.emit(newState);
    }

    function connectionReady(err) {
      if (err) {
          debug('not able to connect to the database');
          changeState('disconnected');
          throw err;
      }

      self.collection = self.db.collection(options.collection);

      if (!self.options.ttlAutoIndex) return changeState('connected');

      self.collection.ensureIndex({ expires: 1 }, { expireAfterSeconds: 0 }, function (err) {
        if (err) throw err;
        changeState('connected');
      });
    }

    function buildUrlFromOptions() {
      if(!options.db || typeof options.db !== 'string') {
        throw new Error('Required MongoStore option `db` missing');
      }

      options.url = 'mongodb://';

      if (options.username) {
        options.url += options.username + ':' + (options.password || '') + '@';
      }

      options.url += options.host + ':' + options.port + '/' + options.db;

      if (options.ssl) options.url += '?ssl=true';

      if (!options.mongoOptions) {
        options.mongoOptions = {
          server: { auto_reconnect: options.autoReconnect },
          db: { w: options.w }
        };
      }
    }

    function initWithUrl() {
      MongoClient.connect(options.url, options.mongoOptions || {}, function(err, db) {
        if (!err) self.db = db;
        connectionReady(err);
      });
    }

    function initWithMongooseConnection() {
      if (options.mongooseConnection.readyState === 1) {
        self.db = options.mongooseConnection.db;
        process.nextTick(connectionReady);
      } else {
        options.mongooseConnection.once('open', function() {
          self.db = options.mongooseConnection.db;
          connectionReady();
        });
      }
    }

    function initWithNativeDb() {
      self.db = options.db;

      if (options.db.openCalled) {
        options.db.collection(options.collection, connectionReady);
      } else {
        options.db.open(connectionReady);
      }
    }

    this.getCollection = function (done) {
      switch (self.state) {
        case 'connected':
          done(null, self.collection);
          break;
        case 'connecting':
          self.once('connected', function () {
            done(null, self.collection);
          });
          break;
        case 'disconnected':
          done(new Error('Not connected'));
          break;
      }
    };

    this.getSessionId = function (sid) {
      if (options.hash) {
        return crypto.createHash(options.hash.algorithm).update(options.hash.salt + sid).digest('hex');
      } else {
        return sid;
      }
    };

    changeState('init');

    if (options.url) {
      debug('use strategy: `url`');
      initWithUrl();
    } else if (options.mongooseConnection) {
      debug('use strategy: `mongoose_connection`');
      initWithMongooseConnection();
    } else if (options.db && options.db instanceof Db) {
      debug('use strategy: `native_db`');
      initWithNativeDb();
    } else {
      debug('use strategy: `legacy`');
      buildUrlFromOptions();
      initWithUrl();
    }

    changeState('connecting');

  }

  /**
   * Inherit from `Store`.
   */
   util.inherits(MongoStore, Store);

  /**
   * Attempt to fetch session by the given `sid`.
   *
   * @param {String} sid
   * @param {Function} callback
   * @api public
   */

  MongoStore.prototype.get = function(sid, callback) {
    if (!callback) callback = _.noop;
    sid = this.getSessionId(sid);

    var self = this;

    var query = {
      _id: sid,
      $or: [
        { expires: { $exists: false } },
        { expires: { $gt: new Date() } }
      ]
    };

    this.getCollection(function(err, collection) {
      if (err) return callback(err);
      collection.findOne(query, function(err, session) {
        if (err) {
          debug('not able to execute `find` query for session: ' + sid);
          return callback(err);
        }

        if (session) {
          var s;
          try {
            s = self.options.unserialize(session.session);
          } catch (err) {
            debug('unable to deserialize session');
            callback(err);
          }
          callback(null, s);
        } else {
          callback();
        }
      });
    });
  };

  /**
   * Commit the given `sess` object associated with the given `sid`.
   *
   * @param {String} sid
   * @param {Session} sess
   * @param {Function} callback
   * @api public
   */

  MongoStore.prototype.set = function(sid, session, callback) {
    if (!callback) callback = _.noop;
    sid = this.getSessionId(sid);

    var s;

    try {
      s = {_id: sid, session: this.options.serialize(session)};
    } catch (err) {
      debug('unable to serialize session');
      callback(err);
    }

    if (session && session.cookie && session.cookie.expires) {
      s.expires = new Date(session.cookie.expires);
    } else {
      // If there's no expiration date specified, it is
      // browser-session cookie or there is no cookie at all,
      // as per the connect docs.
      //
      // So we set the expiration to two-weeks from now
      // - as is common practice in the industry (e.g Django) -
      // or the default specified in the options.
      s.expires = new Date(Date.now() + this.options.ttl * 1000);
    }

    this.getCollection(function(err, collection) {
      if (err) return callback(err);
      collection.update({_id: sid}, s, {upsert: true, safe: true}, function(err) {
        if (err) debug('not able to set/update session: ' + sid);
        callback(err);
      });
    });
  };

  /**
   * Destroy the session associated with the given `sid`.
   *
   * @param {String} sid
   * @param {Function} callback
   * @api public
   */

  MongoStore.prototype.destroy = function(sid, callback) {
    if (!callback) callback = _.noop;
    sid = this.getSessionId(sid);

    this.getCollection(function(err, collection) {
      if (err) return callback(err);
      collection.remove({_id: sid}, function(err) {
        if (err) debug('not able to destroy session: ' + sid);
        callback(err);
      });
    });
  };

  /**
   * Fetch number of sessions.
   *
   * @param {Function} callback
   * @api public
   */

  MongoStore.prototype.length = function(callback) {
    if (!callback) callback = _.noop;
    this.getCollection(function(err, collection) {
      if (err) return callback(err);
      collection.count({}, function(err, count) {
        if (err) debug('not able to count sessions');
        callback(err, count);
      });
    });
  };

  /**
   * Clear all sessions.
   *
   * @param {Function} callback
   * @api public
   */

  MongoStore.prototype.clear = function(callback) {
    if (!callback) callback = _.noop;
    this.getCollection(function(err, collection) {
      if (err) return callback(err);
      collection.drop(function(err) {
        if (err) debug('not able to clear sessions');
        callback(err);
      });
    });
  };

  return MongoStore;
};
<|endoftext|>


<commit_before>var fs = require('fs');
var debug = require('debug')('keystone:core:importer');
var path = require('path');

/**
 * Returns a function that looks in a specified path relative to the current
 * directory, and returns all .js modules it (recursively).
 *
 * ####Example:
 *
 *     var importRoutes = keystone.importer(__dirname);
 *
 *     var routes = {
 *         site: importRoutes('./site'),
 *         api: importRoutes('./api')
 *     };
 *
 * @param {String} rel__dirname
 * @api public
 */

function dispatchImporter (rel__dirname) {

	function importer (from) {
		debug('importing ', from);
		var imported = {};
		var joinPath = function () {
			return '.' + path.sep + path.join.apply(path, arguments);
		};

		var fsPath = joinPath(path.relative(process.cwd(), rel__dirname), from);
		fs.readdirSync(fsPath).forEach(function (name) {
			var info = fs.statSync(path.join(fsPath, name));
			debug('recur');
			if (info.isDirectory()) {
				imported[name] = importer(joinPath(from, name));
			} else {
				// only import files that we can `require`
				var ext = path.extname(name);
				var base = path.basename(name, ext);
				if (require.extensions[ext]) {
					imported[base] = require(path.join(rel__dirname, from, name));
				} else {
					debug('cannot require ', ext);
				}
			}
		});

		return imported;
	}

	return importer;
}

module.exports = dispatchImporter;
<commit_msg>Update importer.js<commit_after>var fs = require('fs');
var debug = require('debug')('keystone:core:importer');
var path = require('path');

/**
 * Returns a function that looks in a specified path relative to the current
 * directory, and returns all .js modules in it (recursively).
 *
 * ####Example:
 *
 *     var importRoutes = keystone.importer(__dirname);
 *
 *     var routes = {
 *         site: importRoutes('./site'),
 *         api: importRoutes('./api')
 *     };
 *
 * @param {String} rel__dirname
 * @api public
 */

function dispatchImporter (rel__dirname) {

	function importer (from) {
		debug('importing ', from);
		var imported = {};
		var joinPath = function () {
			return '.' + path.sep + path.join.apply(path, arguments);
		};

		var fsPath = joinPath(path.relative(process.cwd(), rel__dirname), from);
		fs.readdirSync(fsPath).forEach(function (name) {
			var info = fs.statSync(path.join(fsPath, name));
			debug('recur');
			if (info.isDirectory()) {
				imported[name] = importer(joinPath(from, name));
			} else {
				// only import files that we can `require`
				var ext = path.extname(name);
				var base = path.basename(name, ext);
				if (require.extensions[ext]) {
					imported[base] = require(path.join(rel__dirname, from, name));
				} else {
					debug('cannot require ', ext);
				}
			}
		});

		return imported;
	}

	return importer;
}

module.exports = dispatchImporter;
<|endoftext|>


<commit_before>/**
 * Created by nathandunn on 6/10/17.
 */
import {AnnotationCommand, request, SelectionState} from "substance";

class MarkupApp {

    constructor() {
        this.words = [];
    }

    render(data, callback) {

        // let words = ['organism','unc-5','elegans','epidermal'];
        // alert('rendering with dat: ' + JSON.stringify(data));
        // alert('rendering with words: ' + data.length);

        let cmd = new ToggleStrongCommand();
        let documentSession = window.app.state.documentSession;
        let selectionState = documentSession.getSelectionState();
        let nodes = window.doc.getNodes();

        document.getElementById('message').innerHTML = "Running markup...";
        // n.startsWith('article') // article junk
        // || n.startsWith('ext-link') // what we are tring to create
        // n.startsWith('body') // this is just the intro
        // || n.startsWith('heading') // this is the heading for each paragraph
        let numErrors = 0;
        let totalWordsFound = 0;
        let wordsFound = [];
        let totalWordHits = 0;

        for (let n in nodes) {
            // console.log(n);
            if (n.startsWith('paragraph')
            ) {
                let p = window.doc.get(n);
                // just find the first one
                for (let w in data) {
                    let wordHits = 0;
                    let word = data[w];
                    let found = 0;
                    var reWord = word.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
                    var re = new RegExp("\\W" + reWord + "\\W", "g");
                    var hits;
                    while (hits = re.exec(p.content)) {

                        let sel = documentSession.createSelection({
                            type: 'property',
                            path: [p.id, 'content'],
                            startOffset: hits.index + 1,
                            endOffset: hits.index + 1 + word.length
                        });
                        selectionState.setSelection(sel);
                        let cmdState = cmd.getCommandState({
                            selectionState: selectionState,
                            documentSession: documentSession
                        });
                        if (cmdState.mode == "create") {
                            cmd.execute({
                                commandState: {
                                    mode: 'create'
                                },
                                documentSession: documentSession,
                                selectionState: documentSession.getSelectionState()
                            });
                            console.log('Found ' + word);

                        } else {
                            console.log("Annotated words: " + p.content.substring(selectionState.getAnnotationsForType(cmd.getAnnotationType())[0].startOffset, selectionState.getAnnotationsForType(cmd.getAnnotationType())[0].endOffset));
                            if (cmdState.mode == "delete") {
                                console.log('Error trying to annotate: ' + word + ' because it is already linked.');
                            } else if (cmdState.mode == "expand") {
                                console.log('Error trying to annotate: ' + word + ' because part of the word is already linked.');
                            } else if (cmdState.mode == "truncate") {
                                console.log('Error trying to annotate: ' + word + ' because it is part of the linked word.');
                            }
                            ++numErrors;
                        }

                        //found = p.content.indexOf(word,found+1);
                        ++wordHits;
                    }
                    if (wordHits > 0) {
                        ++totalWordsFound;
                        totalWordHits += wordHits;
                        wordsFound[word] = wordHits;
                        document.getElementById('message').innerHTML = "Searching: found " + totalWordsFound + " words, hits: " + totalWordHits;
                    }
                }
            }
        }
        let finalMessage = "Total words " + totalWordsFound + " Total links: " + totalWordHits;
        // finalMessage += "
";
        finalMessage += "
";
        for (let word in wordsFound) {
            finalMessage += "
" + word + " (" + wordsFound[word] + ")
";
        }

        // finalMessage += "
";
        document.getElementById('message').innerHTML = finalMessage;
        console.log('total found: ' + totalWordsFound);
        console.log('total errors: ' + numErrors);

        if (callback) callback();
    }

    getWords(callback) {
        let serverURL = window.location.protocol + '//' + window.location.hostname + ':8080/keyWordSet/sampleKeyWordSet';
        console.log('server URL: ' + serverURL);
        request('GET', serverURL, null, function (err, data) {
            if (err) {
                console.error(err);
                this.setState({
                    error: new Error('Loading failed')
                });
                return
            }
            if (data) {
                this.words = [];
                for (let d in data) {
                    this.words.push(data[d].value);
                }
                console.log('finished processing with words: ' + this.words.length);
                // this.render(this.words, cb);
                if (callback) callback(this.words);

                return this.words;
            }
        });
    }

}

class ToggleStrongCommand extends AnnotationCommand {

    // type = 'bold';
    // tagName = 'bold';

    constructor() {
        // super({name: 'bold', nodeType: 'bold'})
        super({name: 'markup', nodeType: 'ext-link'})
    }
}

// ToggleStrongCommand.define({
//     attributes: { type: 'object', default: {} }
// });

// export default ToggleStrongCommand

export default MarkupApp
<commit_msg>inline display hopefullly<commit_after>/**
 * Created by nathandunn on 6/10/17.
 */
import {AnnotationCommand, request, SelectionState} from "substance";

class MarkupApp {

    constructor() {
        this.words = [];
    }

    render(data, callback) {

        // let words = ['organism','unc-5','elegans','epidermal'];
        // alert('rendering with dat: ' + JSON.stringify(data));
        // alert('rendering with words: ' + data.length);

        let cmd = new ToggleStrongCommand();
        let documentSession = window.app.state.documentSession;
        let selectionState = documentSession.getSelectionState();
        let nodes = window.doc.getNodes();

        document.getElementById('message').innerHTML = "Running markup...";
        // n.startsWith('article') // article junk
        // || n.startsWith('ext-link') // what we are tring to create
        // n.startsWith('body') // this is just the intro
        // || n.startsWith('heading') // this is the heading for each paragraph
        let numErrors = 0;
        let totalWordsFound = 0;
        let wordsFound = [];
        let totalWordHits = 0;

        for (let n in nodes) {
            // console.log(n);
            if (n.startsWith('paragraph')
            ) {
                let p = window.doc.get(n);
                // just find the first one
                for (let w in data) {
                    let wordHits = 0;
                    let word = data[w];
                    let found = 0;
                    var reWord = word.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
                    var re = new RegExp("\\W" + reWord + "\\W", "g");
                    var hits;
                    while (hits = re.exec(p.content)) {

                        let sel = documentSession.createSelection({
                            type: 'property',
                            path: [p.id, 'content'],
                            startOffset: hits.index + 1,
                            endOffset: hits.index + 1 + word.length
                        });
                        selectionState.setSelection(sel);
                        let cmdState = cmd.getCommandState({
                            selectionState: selectionState,
                            documentSession: documentSession
                        });
                        if (cmdState.mode == "create") {
                            cmd.execute({
                                commandState: {
                                    mode: 'create'
                                },
                                documentSession: documentSession,
                                selectionState: documentSession.getSelectionState()
                            });
                            console.log('Found ' + word);

                        } else {
                            console.log("Annotated words: " + p.content.substring(selectionState.getAnnotationsForType(cmd.getAnnotationType())[0].startOffset, selectionState.getAnnotationsForType(cmd.getAnnotationType())[0].endOffset));
                            if (cmdState.mode == "delete") {
                                console.log('Error trying to annotate: ' + word + ' because it is already linked.');
                            } else if (cmdState.mode == "expand") {
                                console.log('Error trying to annotate: ' + word + ' because part of the word is already linked.');
                            } else if (cmdState.mode == "truncate") {
                                console.log('Error trying to annotate: ' + word + ' because it is part of the linked word.');
                            }
                            ++numErrors;
                        }

                        //found = p.content.indexOf(word,found+1);
                        ++wordHits;
                    }
                    if (wordHits > 0) {
                        ++totalWordsFound;
                        totalWordHits += wordHits;
                        wordsFound[word] = wordHits;
                        document.getElementById('message').innerHTML = "Searching: found " + totalWordsFound + " words, hits: " + totalWordHits;
                    }
                }
            }
        }
        let finalMessage = "Total words " + totalWordsFound + " Total links: " + totalWordHits;
        // finalMessage += "
";
        finalMessage += "
";
        for (let word in wordsFound) {
            finalMessage += "
" + word + " (" + wordsFound[word] + ");
";
            if(wordsFound[word]>1){
                finalMessage += " (" + wordsFound[word] + ")";
            }
            finalMessage += ";
 ";
        }

        // finalMessage += "
";
        document.getElementById('message').innerHTML = finalMessage;
        console.log('total found: ' + totalWordsFound);
        console.log('total errors: ' + numErrors);

        if (callback) callback();
    }

    getWords(callback) {
        let serverURL = window.location.protocol + '//' + window.location.hostname + ':8080/keyWordSet/sampleKeyWordSet';
        console.log('server URL: ' + serverURL);
        request('GET', serverURL, null, function (err, data) {
            if (err) {
                console.error(err);
                this.setState({
                    error: new Error('Loading failed')
                });
                return
            }
            if (data) {
                this.words = [];
                for (let d in data) {
                    this.words.push(data[d].value);
                }
                console.log('finished processing with words: ' + this.words.length);
                // this.render(this.words, cb);
                if (callback) callback(this.words);

                return this.words;
            }
        });
    }

}

class ToggleStrongCommand extends AnnotationCommand {

    // type = 'bold';
    // tagName = 'bold';

    constructor() {
        // super({name: 'bold', nodeType: 'bold'})
        super({name: 'markup', nodeType: 'ext-link'})
    }
}

// ToggleStrongCommand.define({
//     attributes: { type: 'object', default: {} }
// });

// export default ToggleStrongCommand

export default MarkupApp
<|endoftext|>


<commit_before>// Though "Dialog" looks like an object, it isn't really an object.  Instead
// it's just namespace for protecting global symbols.

function Dialog(url, action, init) {
    if (typeof init == "undefined") {
        init = window;  // pass this window object by default
    }
    if (document.all) { // here we hope that Mozilla will never support document.all
        var value =
            showModalDialog(url, init,
            //window.open(url, '_blank',
            "resizable: no; help: no; status: no; scroll: no");
        if (action) {
            action(value);
        }
    } else {
        return Dialog._geckoOpenModal(url, action, init);
    }
};

Dialog._parentEvent = function(ev) {
    if (Dialog._modal && !Dialog._modal.closed) {
        setTimeout("Dialog._modal.focus()", 1);
        // we get here in Mozilla only, anyway, so we can safely use
        // the DOM version.
        ev.preventDefault();
        ev.stopPropagation();
    }
};

// should be a function, the return handler of the currently opened dialog.
Dialog._return = null;

// constant, the currently opened dialog
Dialog._modal = null;

// the dialog will read it's args from this variable
Dialog._arguments = null;

Dialog._geckoOpenModal = function(url, action, init) {

    if(url.lastIndexOf("insert_image.php") != -1) {
        var x = 730;
        var y = 540;
    } else if (url.lastIndexOf("link.php") != -1) {
        var x = 700;
        var y = 460;
    } else if (url.lastIndexOf("dlg_ins_smile.php") != -1) {
        var x = 330;
        var y = 360;
    } else if (url.lastIndexOf("dlg_ins_char.php") != -1) {
        var x = 450;
        var y = 270;
    } else if (url.lastIndexOf("select_color.html") != -1) {
        var x = 238;
        var y = 188;
    } else if (url.lastIndexOf("insert_table.php") != -1) {
        var x = 410;
        var y = 240;
    } else {
        var x = 10;
        var y = 10;
    }

    var lx = (screen.width - x) / 2;
    var tx = (screen.height - y) / 2;
    var dlg = window.open(url, "ha_dialog", "toolbar=no,menubar=no,personalbar=no, width="+ x +",height="+ y +",scrollbars=no,resizable=no, left="+ lx +", top="+ tx +"");
    Dialog._modal = dlg;
    Dialog._arguments = init;

    // capture some window's events
    function capwin(w) {
        w.addEventListener("click", Dialog._parentEvent, true);
        w.addEventListener("mousedown", Dialog._parentEvent, true);
        w.addEventListener("focus", Dialog._parentEvent, true);
    };
    // release the captured events
    function relwin(w) {
        w.removeEventListener("focus", Dialog._parentEvent, true);
        w.removeEventListener("mousedown", Dialog._parentEvent, true);
        w.removeEventListener("click", Dialog._parentEvent, true);
    };
    capwin(window);
    // capture other frames
    for (var i = 0; i < window.frames.length; capwin(window.frames[i++]));
    // make up a function to be called when the Dialog ends.
    Dialog._return = function (val) {
        if (val && action) {
            action(val);
        }
        relwin(window);
        // capture other frames
        for (var i = 0; i < window.frames.length; relwin(window.frames[i++]));
        Dialog._modal = null;
    };
};
<commit_msg>Some fixes of students dialog's placement on the screen and a little fix for event handling<commit_after>// $Id$
// Though "Dialog" looks like an object, it isn't really an object.  Instead
// it's just namespace for protecting global symbols.

function Dialog(url, action, init) {
    if (typeof init == "undefined") {
        init = window;  // pass this window object by default
    }
    if (document.all) { // here we hope that Mozilla will never support document.all
        var value =
            showModalDialog(url, init,
            //window.open(url, '_blank',
            "resizable: no; help: no; status: no; scroll: no");
        if (action) {
            action(value);
        }
    } else {
        return Dialog._geckoOpenModal(url, action, init);
    }
};

Dialog._parentEvent = function(ev) {
    if (Dialog._modal && !Dialog._modal.closed) {
        // we get here in Mozilla only, anyway, so we can safely use
        // the DOM version.
        ev.preventDefault();
        ev.stopPropagation();
    }
};

// should be a function, the return handler of the currently opened dialog.
Dialog._return = null;

// constant, the currently opened dialog
Dialog._modal = null;

// the dialog will read it's args from this variable
Dialog._arguments = null;

Dialog._geckoOpenModal = function(url, action, init) {

    if(url.lastIndexOf("insert_image.php") != -1) {
        var x = 730;
        var y = 540;
    } else if (url.lastIndexOf("link.php") != -1) {
        var x = 700;
        var y = 460;
    } else if (url.lastIndexOf("dlg_ins_smile.php") != -1) {
        var x = 330;
        var y = 360;
    } else if (url.lastIndexOf("dlg_ins_char.php") != -1) {
        var x = 450;
        var y = 270;
    } else if (url.lastIndexOf("select_color.html") != -1) {
        var x = 238;
        var y = 188;
    } else if (url.lastIndexOf("insert_table.php") != -1) {
        var x = 410;
        var y = 240;
    } else if (url.lastIndexOf("link_std.php") != -1) {
        var x = 420;
        var y = 210;
    } else if (url.lastIndexOf("insert_image_std.php") != -1) {
        var x = 450;
        var y = 230;
    } else {
        var x = 10;
        var y = 10;
    }

    var lx = (screen.width - x) / 2;
    var tx = (screen.height - y) / 2;
    var dlg = window.open(url, "ha_dialog", "toolbar=no,menubar=no,personalbar=no, width="+ x +",height="+ y +",scrollbars=no,resizable=no, left="+ lx +", top="+ tx +"");
    Dialog._modal = dlg;
    Dialog._arguments = init;

    // capture some window's events
    function capwin(w) {
        w.addEventListener("click", Dialog._parentEvent, true);
        w.addEventListener("mousedown", Dialog._parentEvent, true);
        w.addEventListener("focus", Dialog._parentEvent, true);
    };
    // release the captured events
    function relwin(w) {
        w.removeEventListener("focus", Dialog._parentEvent, true);
        w.removeEventListener("mousedown", Dialog._parentEvent, true);
        w.removeEventListener("click", Dialog._parentEvent, true);
    };
    capwin(window);
    // capture other frames
    //for (var i = 0; i < window.frames.length; capwin(window.frames[i++]));
    // make up a function to be called when the Dialog ends.
    Dialog._return = function (val) {
        if (val && action) {
            action(val);
        }
        relwin(window);
        // capture other frames
        //for (var i = 0; i < window.frames.length; relwin(window.frames[i++]));
        Dialog._modal = null;
    };
};
<|endoftext|>