<commit_before>var tsort         = require('tsort'),
	AliasResolver = require('./aliases'),
	UA            = require('./UA'),
	sources       = require('./sources');

// Polyfill String.prototype.startsWith
if (!String.prototype.startsWith) {
	require('../polyfills/String.prototype.startsWith/polyfill');
}

// Load additional useragent features: primarily to use: agent.satisfies to
// test a browser version against a semver string
require('useragent/features');

"use strict";

var polyfillSourceFolder = path.join(__dirname, '../polyfills');

var sources = {},
	configuredAliases = {};

fs.readdirSync(polyfillSourceFolder).forEach(function (polyfillName) {

	var polyfillPath = path.join(polyfillSourceFolder, polyfillName),
		configPath   = path.join(polyfillPath, 'config.json');

	if (!fs.existsSync(polyfillPath) || !fs.existsSync(configPath)) {
		return;
	}

	var config = require(configPath),
		polyfillSourcePath = path.join(polyfillPath, 'polyfill.js'),
		detectSourcePath = path.join(polyfillPath, 'detect.js'),
		fileContents = fs.readFileSync(polyfillSourcePath, 'utf8'),
		polyfillInfo = {
			file: fileContents,
			minifile: uglify.minify(fileContents, {fromString: true}).code,
			config: config
		};

	if (fs.existsSync(detectSourcePath)) {
		var featureGate = fs.readFileSync(detectSourcePath);
		var gatedFile = "if (!(" + featureGate + ")) {" + fileContents + "}";

		// Verify the generated feature gate is valid javascript
		try {
			new Function(gatedFile);
		} catch(e) {
			console.error("Error generating feature gate for polyfill: " + polyfillName);
			console.error("Invalid Syntax in feature gate: '" + e.message + "'");
			console.error("The detect.js file must be a valid expression that can be inserted as the condition of an if statement");
			process.exit(1);
		}

		polyfillInfo.gatedFile = gatedFile;
		polyfillInfo.miniGatedFile = uglify.minify(gatedFile, {fromString: true}).code;
	}

	sources[polyfillName] = polyfillInfo;

	// Store alias names in a map for efficient lookup, mapping aliases to
	// polyfillNames.  An alias can map to many polyfill names. So a group
	// of polyfills can be aliased under the same name.  This is why an
	// array is created and used for the value in the map.
	config.aliases = config.aliases || [];
	config.aliases.forEach(function(aliasName) {
		if (configuredAliases[aliasName]) {
			configuredAliases[aliasName].push(polyfillName);
		} else {
			configuredAliases[aliasName] = [ polyfillName ];
		}
	});
});

// Alias resolvers are functions that receive a polyfill name as an argument, and return an array of polyfill names or a falsy value to indicate that the resolver has no alias for the supplied polyfill name.  Resolvers act in sequence, so the second resolver will be called on the list of polyfills resulting from the first resolver.  The final resolver must return only canonical names.
(function initAliasResolvers() {

	// Map pre-configured aliases
	AliasResolver.addResolver(function aliasFromConfig(polyfillIdentifierName) {
		return configuredAliases[polyfillIdentifierName] || undefined;

	// Expand a polyfill name i.e. Element.prototype becomes Element.prototype.* etc
	}).addResolver(function expandNamespacedPolyfills(polyfillIdentifierName) {

		// Append a dot separator to the polyfill name before testing 'startsWith' if it does not already end with a dot.
		var polyfillIdentifierNameAsNamespace = polyfillIdentifierName.replace(/(\.)?$/, '') + '.';

		var expandedPolyfillNames = Object.keys(sources).filter(function(canonicalSourceName) {
			return canonicalSourceName.startsWith(polyfillIdentifierNameAsNamespace);
		});

		if (expandedPolyfillNames.length === 0) {
			return undefined;
		}

		if (polyfillIdentifierName in sources) {
			expandedPolyfillNames.push(polyfillIdentifierName);
		}

		return expandedPolyfillNames;

	// Add all the dependencies of a polyfill by resolving the polyfill to itself plus all its dependencies
	}).addResolver(function addDependencies(polyfillIdentifierName) {
		if (sources[polyfillIdentifierName] && sources[polyfillIdentifierName].config.dependencies) {
			var list = [polyfillIdentifierName];
			sources[polyfillIdentifierName].config.dependencies.forEach(function(dep) {
				var subdeps = addDependencies(dep);
				list = subdeps ? list.concat(subdeps) : list.concat(dep);
			})
			return list;
		}
	});
}());

function getAllPolyfills() {
	return Object.keys(sources);
}

/**
 * Given a list of features that should be polyfilled in 'options.features' (with flags i.e. `[{ name: <featurename>, flags: [<flaglist>] }, {...}]`), determine which have a configuration valid for the given options.uaString, and return a list of canonical (unaliased) features (with flags) and polyfill variants.
 *
 * @return array, canonicalised features filtered for UA
 */
function getPolyfills(options) {
	var ua = new UA(options.uaString);

	function chooseVariant(feature) {
		if (feature.polyfillVariant !== undefined) return;
		var polyfill = sources.getPolyfill(feature.name);
		if (polyfill) {
			Object.keys(polyfill.variants).forEach(function(variantName) {
				var v = polyfill.variants[variantName];
				console.log(feature.name, variantName, v.browsers[ua.getFamily()], ua.getVersion(), ua.satisfies(v.browsers[ua.getFamily()]));
				if (v.browsers && v.browsers[ua.getFamily()] && ua.satisfies(v.browsers[ua.getFamily()])) {
					feature.polyfillVariant = variantName;
					return false;
				}
			});
			if (!feature.polyfillVariant && feature.flags.indexOf('always') !== -1 && polyfill.variants['default']) {
				feature.polyfillVariant = 'default';
			}
			if (feature.polyfillVariant) {
				var deps = getDependencies(feature);
				if (deps) deps.forEach(chooseVariant);
				return;
			}
		}
		feature.polyfillVariant = null;
	}

	function getDependencies(feature) {
		var polyfill = sources.getPolyfill(feature.name);
		var deps = [];
		if (feature.polyfillVariant && polyfill.variants[feature.polyfillVariant].dependencies) {
			polyfill.variants[feature.polyfillVariant].dependencies.forEach(function(dep) {
				if (!features[dep]) {
					features[dep] = {name: dep, flags:feature.flags, aliasOf: [feature.name]};
				}
				features[dep].aliasOf.push(feature.name);
				deps.push(features[dep]);
			});
		}
		return deps;
	}

	var aliasResolver = new AliasResolver([
		function expandNamespacedPolyfills(feature) {

			// Append a dot separator to the polyfill name before testing 'startsWith' if it does not already end with a dot.
			var namespace = feature.name.replace(/(\.)?$/, '') + '.';
			var expandedFeatureNames = sources.listPolyfills().filter(function(canonicalFeatureName) {
				return canonicalFeatureName.startsWith(namespace);
			});

			if (expandedFeatureNames.length === 0) {
				return feature;
			}

			if (sources.polyfillExists(feature.name)) {
				expandedFeatureNames.push(feature.name);
			}

			return expandedFeatureNames;
		},
		function aliasFromConfig(feature) {
			return sources.getConfigAliases(feature.name) || feature;
		}
	]);

	var features = aliasResolver.resolve(options.features).reduce(function(obj, val) {
		obj[val.name] = val;
		return obj;
	}, {});

	Object.keys(features).forEach(function(featureName) {
		chooseVariant(features[featureName]);
	});

	return Object.keys(features).map(function(key) { return features[key]; });
}

function getPolyfillString(options) {
	var ua = new UA(options.uaString),
		currentPolyfills = {},
		explainerComment;

	if (ua.meetsBaseline()) {
		if (options.minify) {
			explainerComment = ['Rerun without minification for verbose metadata'];
		} else  {
			explainerComment = [
				'For detailed credits and licence information see http://github.com/financial-times/polyfill-service.',
				'',
				'Detected: ' + ua.getFamily() + '/' + ua.getVersion(),
				''
			]
		}
	} else {
		explainerComment = ['Unsupported UA detected: ' + ua.getFamily() + '/' + ua.getVersion()];
		if (ua.getBaseline()) {
			explainerComment.push('Version range for polyfill support in this family is: ' + ua.getBaseline());
		}
		options.features = [];
	}

	var features = getPolyfills(options);
	var warnings = {unknown:[], nopolyfill:[]};
	var graph = tsort();

	// Convert to object to make it easier to pick polyfills out in graph order
	features = features.reduce(function(obj, val) {
		obj[val.name] = val;
		return obj;
	}, {});

	Object.keys(features).forEach(function(featureName) {
		var feature = features[featureName];

		if (!sources.getPolyfill(featureName)) {
			warnings.unknown.push(' - '+featureName);
		} else if (!feature.polyfillVariant) {
			warnings.nopolyfill.push(' - '+featureName);
		} else {

			graph.add(featureName);
			var polyfill = sources.getPolyfill(featureName).variants[feature.polyfillVariant];
			var srcKey = (options.minify ? 'min':'raw') + (polyfill.shouldGate ? 'Gated':'') + 'Source';

			feature.polyfillOutput = polyfill[srcKey];

			if (polyfill.dependencies) {
				for (var i = 0; i < polyfill.dependencies.length; i++) {
					graph.add(polyfill.dependencies[i], featureName);
				}
			}
			feature.comment = '- ' + featureName + (feature.polyfillVariant !== 'default' ? '-'+feature.polyfillVariant:'') + ', License: ' + (polyfill.license || 'CC0')  + ' ' + ((feature.aliasOf && feature.aliasOf.length) ? ' (required by "' + feature.aliasOf.join('", "') + '")' : '');
		}
	});

	// Using the graph order, build the completed polyfill bundle
	var builtPolyfillString = '';
	graph.sort().forEach(function(featureName) {
		builtPolyfillString += features[featureName].polyfillOutput || '';
		if (!options.minify && features[featureName].comment) explainerComment.push(features[featureName].comment);
	});

	if (warnings.unknown.length && !options.minify) {
		explainerComment = explainerComment.concat(
			'',
			'These features were not recognised:',
			warnings.unknown
		);
	}

	if (warnings.nopolyfill.length && !options.minify) {
		explainerComment = explainerComment.concat(
			'',
			'These features have no polyfill suitable for '+ua.getFamily() + '/' + ua.getVersion() + ':',
			warnings.nopolyfill
		);
	}

	return '/* ' + explainerComment.join('\n * ') + ' */\n\n' + builtPolyfillString;
}

module.exports = {
	getPolyfills: getPolyfills,
	getAllPolyfills: getAllPolyfills,
	getPolyfillString: getPolyfillString,
	normalizeUserAgent: UA.normalize
};
<commit_msg>Fix bad rebase<commit_after>var tsort         = require('tsort'),
	AliasResolver = require('./aliases'),
	UA            = require('./UA'),
	sources       = require('./sources');

// Polyfill String.prototype.startsWith
if (!String.prototype.startsWith) {
	require('../polyfills/String.prototype.startsWith/polyfill');
}

// Load additional useragent features: primarily to use: agent.satisfies to
// test a browser version against a semver string
require('useragent/features');

"use strict";

function getAllPolyfills() {
	return Object.keys(sources);
}

/**
 * Given a list of features that should be polyfilled in 'options.features' (with flags i.e. `[{ name: <featurename>, flags: [<flaglist>] }, {...}]`), determine which have a configuration valid for the given options.uaString, and return a list of canonical (unaliased) features (with flags) and polyfill variants.
 *
 * @return array, canonicalised features filtered for UA
 */
function getPolyfills(options) {
	var ua = new UA(options.uaString);

	function chooseVariant(feature) {
		if (feature.polyfillVariant !== undefined) return;
		var polyfill = sources.getPolyfill(feature.name);
		if (polyfill) {
			Object.keys(polyfill.variants).forEach(function(variantName) {
				var v = polyfill.variants[variantName];
				console.log(feature.name, variantName, v.browsers[ua.getFamily()], ua.getVersion(), ua.satisfies(v.browsers[ua.getFamily()]));
				if (v.browsers && v.browsers[ua.getFamily()] && ua.satisfies(v.browsers[ua.getFamily()])) {
					feature.polyfillVariant = variantName;
					return false;
				}
			});
			if (!feature.polyfillVariant && feature.flags.indexOf('always') !== -1 && polyfill.variants['default']) {
				feature.polyfillVariant = 'default';
			}
			if (feature.polyfillVariant) {
				var deps = getDependencies(feature);
				if (deps) deps.forEach(chooseVariant);
				return;
			}
		}
		feature.polyfillVariant = null;
	}

	function getDependencies(feature) {
		var polyfill = sources.getPolyfill(feature.name);
		var deps = [];
		if (feature.polyfillVariant && polyfill.variants[feature.polyfillVariant].dependencies) {
			polyfill.variants[feature.polyfillVariant].dependencies.forEach(function(dep) {
				if (!features[dep]) {
					features[dep] = {name: dep, flags:feature.flags, aliasOf: [feature.name]};
				}
				features[dep].aliasOf.push(feature.name);
				deps.push(features[dep]);
			});
		}
		return deps;
	}

	var aliasResolver = new AliasResolver([
		function expandNamespacedPolyfills(feature) {

			// Append a dot separator to the polyfill name before testing 'startsWith' if it does not already end with a dot.
			var namespace = feature.name.replace(/(\.)?$/, '') + '.';
			var expandedFeatureNames = sources.listPolyfills().filter(function(canonicalFeatureName) {
				return canonicalFeatureName.startsWith(namespace);
			});

			if (expandedFeatureNames.length === 0) {
				return feature;
			}

			if (sources.polyfillExists(feature.name)) {
				expandedFeatureNames.push(feature.name);
			}

			return expandedFeatureNames;
		},
		function aliasFromConfig(feature) {
			return sources.getConfigAliases(feature.name) || feature;
		}
	]);

	var features = aliasResolver.resolve(options.features).reduce(function(obj, val) {
		obj[val.name] = val;
		return obj;
	}, {});

	Object.keys(features).forEach(function(featureName) {
		chooseVariant(features[featureName]);
	});

	return Object.keys(features).map(function(key) { return features[key]; });
}

function getPolyfillString(options) {
	var ua = new UA(options.uaString),
		currentPolyfills = {},
		explainerComment;

	if (ua.meetsBaseline()) {
		if (options.minify) {
			explainerComment = ['Rerun without minification for verbose metadata'];
		} else  {
			explainerComment = [
				'For detailed credits and licence information see http://github.com/financial-times/polyfill-service.',
				'',
				'Detected: ' + ua.getFamily() + '/' + ua.getVersion(),
				''
			]
		}
	} else {
		explainerComment = ['Unsupported UA detected: ' + ua.getFamily() + '/' + ua.getVersion()];
		if (ua.getBaseline()) {
			explainerComment.push('Version range for polyfill support in this family is: ' + ua.getBaseline());
		}
		options.features = [];
	}

	var features = getPolyfills(options);
	var warnings = {unknown:[], nopolyfill:[]};
	var graph = tsort();

	// Convert to object to make it easier to pick polyfills out in graph order
	features = features.reduce(function(obj, val) {
		obj[val.name] = val;
		return obj;
	}, {});

	Object.keys(features).forEach(function(featureName) {
		var feature = features[featureName];

		if (!sources.getPolyfill(featureName)) {
			warnings.unknown.push(' - '+featureName);
		} else if (!feature.polyfillVariant) {
			warnings.nopolyfill.push(' - '+featureName);
		} else {

			graph.add(featureName);
			var polyfill = sources.getPolyfill(featureName).variants[feature.polyfillVariant];
			var srcKey = (options.minify ? 'min':'raw') + (polyfill.shouldGate ? 'Gated':'') + 'Source';

			feature.polyfillOutput = polyfill[srcKey];

			if (polyfill.dependencies) {
				for (var i = 0; i < polyfill.dependencies.length; i++) {
					graph.add(polyfill.dependencies[i], featureName);
				}
			}
			feature.comment = '- ' + featureName + (feature.polyfillVariant !== 'default' ? '-'+feature.polyfillVariant:'') + ', License: ' + (polyfill.license || 'CC0')  + ' ' + ((feature.aliasOf && feature.aliasOf.length) ? ' (required by "' + feature.aliasOf.join('", "') + '")' : '');
		}
	});

	// Using the graph order, build the completed polyfill bundle
	var builtPolyfillString = '';
	graph.sort().forEach(function(featureName) {
		builtPolyfillString += features[featureName].polyfillOutput || '';
		if (!options.minify && features[featureName].comment) explainerComment.push(features[featureName].comment);
	});

	if (warnings.unknown.length && !options.minify) {
		explainerComment = explainerComment.concat(
			'',
			'These features were not recognised:',
			warnings.unknown
		);
	}

	if (warnings.nopolyfill.length && !options.minify) {
		explainerComment = explainerComment.concat(
			'',
			'These features have no polyfill suitable for '+ua.getFamily() + '/' + ua.getVersion() + ':',
			warnings.nopolyfill
		);
	}

	return '/* ' + explainerComment.join('\n * ') + ' */\n\n' + builtPolyfillString;
}

module.exports = {
	getPolyfills: getPolyfills,
	getAllPolyfills: getAllPolyfills,
	getPolyfillString: getPolyfillString,
	normalizeUserAgent: UA.normalize
};
<|endoftext|>


<commit_before>var jsdom = require("jsdom"), http = require("http");

var filters = {
	credlist: /^[a-z0-9\-\._]+@[a-z0-9\-\.]+\.[a-z]{2,4}[ \t;,:\|]+\S+/,
	hacknotif: /(h[a4]ck[e3]d|[p0]wn[e3]d|d[e3]f[a4]c[e3]d) by/,
	leakedby: /leaked (by|from)/,
	visacc: /[ \t:="']+4[0-9]{12}(?:[0-9]{3})?/,
	mastercc: /\s+5[1-5][0-9]{14}\s+/,
	mysqlpwddump: /[\s\|,;']+[a-z0-9\-\._]+@[a-z0-9\-\.]+\.[a-z]{2,4}[\s\|,;:']+/,
	apikey: /(api|private)[-_]key[ "']*=[ ="']*\w+/,
	cvereference: /CVE\-20[0-1]{1}[0-9]{1}\-[0-9]{4}/
}, fmp = Object.keys(filters);

var htrq = function (url, cb) {
	http.get(url, function (s) {
		var data = Buffer(0);

		s.on("data", function (c) {
			data = Buffer.concat([data, c]);
		}), s.on("end", function () {
			cb(data)
		})
	})
}

var items = {}, initd, i = 0;

var queue = []; var Q = false;

var queueIterator = function () {
	if (!queue.length) return setTimeout(queueIterator, 500)

	var item = queue.shift();

	htrq("http://pastebin.com/raw.php?i=" + item, function (data) {
		console.log("Obtaining:", item, "(Queue: " + queue.length + ")");

		var ds = data.toString();

		fmp.forEach(function (f) {
			if(filters[f].test(ds)) {
				console.log("Found a match:", f, item);
				fs.writeFileSync("./track/" + f + "." + Date.now(), data);
			}
		})

		setTimeout(queueIterator, 3500 + (Math.random() * 3000));
	})
}

var _next = function () {
	console.log("Updating..", ++i);
	jsdom.env(
		"http://pastebin.com/archive", ["http://code.jquery.com/jquery.js"],
		function(errors, window) {
			var $ = window.$;
			var _items = {};

			$("table tr").each(function(i, k){
				k = $(k);

				if ( k.attr("class") ) return;

				var as = k.find("a");

				_items[as[0].getAttribute("href").slice(1)] = as[1].getAttribute("href").split("/").pop();
			});

			Object.keys(_items).filter(function (v) {
				return !items[v]
			}).forEach(function (v) {
				console.log("Queued:", v);

				queue.push(v);

				items[v] = _items[v];
			})

			setTimeout(_next, 15000)
		}
	);
}

_next();
queueIterator();

process.on("uncaughtException", new Function);<commit_msg>Fix, console log<commit_after>var jsdom = require("jsdom"), http = require("http"), fs = require("fs");

var filters = {
	credlist: /^[a-z0-9\-\._]+@[a-z0-9\-\.]+\.[a-z]{2,4}[ \t;,:\|]+\S+/,
	hacknotif: /(h[a4]ck[e3]d|[p0]wn[e3]d|d[e3]f[a4]c[e3]d) by/,
	leakedby: /leaked (by|from)/,
	visacc: /[ \t:="']+4[0-9]{12}(?:[0-9]{3})?/,
	mastercc: /\s+5[1-5][0-9]{14}\s+/,
	mysqlpwddump: /[\s\|,;']+[a-z0-9\-\._]+@[a-z0-9\-\.]+\.[a-z]{2,4}[\s\|,;:']+/,
	apikey: /(api|private)[-_]key[ "']*=[ ="']*\w+/,
	cvereference: /CVE\-20[0-1]{1}[0-9]{1}\-[0-9]{4}/
}, fmp = Object.keys(filters);

var htrq = function (url, cb) {
	http.get(url, function (s) {
		var data = Buffer(0);

		s.on("data", function (c) {
			data = Buffer.concat([data, c]);
		}), s.on("end", function () {
			cb(data)
		})
	})
}

var items = {}, initd, i = 0;

var queue = []; var Q = false;

var queueIterator = function () {
	if (!queue.length) return setTimeout(queueIterator, 500)

	var item = queue.shift();

	htrq("http://pastebin.com/raw.php?i=" + item, function (data) {
		console.log("Obtaining:", item, "(Queue: " + queue.length + ")");

		var ds = data.toString();

		fmp.forEach(function (f) {
			if(filters[f].test(ds)) {
				console.log("Found a match:", f, item);
				fs.writeFileSync("./track/" + f + "." + Date.now(), data);
			}
		})

		setTimeout(queueIterator, 3500 + (Math.random() * 3000));
	})
}

var _next = function () {
	console.log("Updating..", ++i);
	jsdom.env(
		"http://pastebin.com/archive", ["http://code.jquery.com/jquery.js"],
		function(errors, window) {
			var $ = window.$;
			var _items = {};

			$("table tr").each(function(i, k){
				k = $(k);

				if ( k.attr("class") ) return;

				var as = k.find("a");

				_items[as[0].getAttribute("href").slice(1)] = as[1].getAttribute("href").split("/").pop();
			});

			Object.keys(_items).filter(function (v) {
				return !items[v]
			}).forEach(function (v) {
				console.log("Queued:", v);

				queue.push(v);

				items[v] = _items[v];
			})

			setTimeout(_next, 15000)
		}
	);
}

_next();
queueIterator();

process.on("uncaughtException", function (e) {
	console.log(e)
});<|endoftext|>


<commit_before>var StubGenerator = require('./stub-generator');
var CachingBrowserify = require('./caching-browserify');
var mergeTrees = require('broccoli-merge-trees');

module.exports = {
  name: 'ember-browserify',

  included: function(app){
    var enableSourcemaps = app.options.sourcemaps && app.options.sourcemaps.enabled && app.options.sourcemaps.extensions.indexOf('js') > -1;

    this.app = app;

    this.options = {
      root: this.app.project.root,
      browserifyOptions: app.project.config(app.env).browserify || {},
      enableSourcemap: enableSourcemaps,
      fullPaths: app.env !== 'production'
    };

    app.import('browserify/browserify.js');
    if (app.importWhitelistFilters) {
      app.importWhitelistFilters.push(function(moduleName){
        return moduleName.slice(0,4) === 'npm:';
      });
    }
  },

  postprocessTree: function(type, tree){
    if (type !== 'js'){ return tree; }
    return mergeTrees([
      tree,
      new CachingBrowserify(new StubGenerator(tree), this.options)
    ]);
  }
};
<commit_msg>support dependencies in the test tree<commit_after>var StubGenerator = require('./stub-generator');
var CachingBrowserify = require('./caching-browserify');
var mergeTrees = require('broccoli-merge-trees');

module.exports = {
  name: 'ember-browserify',

  included: function(app){
    var enableSourcemaps = app.options.sourcemaps && app.options.sourcemaps.enabled && app.options.sourcemaps.extensions.indexOf('js') > -1;

    this.app = app;

    this.options = {
      root: this.app.project.root,
      browserifyOptions: app.project.config(app.env).browserify || {},
      enableSourcemap: enableSourcemaps,
      fullPaths: app.env !== 'production'
    };

    app.import('browserify/browserify.js');
    if (app.tests) {
      app.import('browserify-tests/browserify.js');
    }

    if (app.importWhitelistFilters) {
      app.importWhitelistFilters.push(function(moduleName){
        return moduleName.slice(0,4) === 'npm:';
      });
    }
  },

  postprocessTree: function(type, tree){
    var outputFile, options;
    if (type === 'js'){
      outputFile = 'browserify/browserify.js';
    } else if (type === 'test'){
      outputFile = 'browserify-tests/browserify.js';
    }

    if (outputFile) {
      options = Object.create(this.options);
      options.outputFile = outputFile;
      tree = mergeTrees([
        tree,
        new CachingBrowserify(new StubGenerator(tree), options)
      ]);
    }
    return tree;
  }
};
<|endoftext|>


<commit_before>// Dependencies
const gitSource = require("git-source")
    , packageJson = require("package-json")
    , ul = require("ul")
    , gry = require("gry")
    , tmp = require("tmp")
    , oArgv = require("oargv")
    , rJson = require("r-json")
    , mkdirp = require("mkdirp")
    , oneByOne = require("one-by-one")
    , sameTime = require("same-time")
    , ExecLimiter = require("exec-limiter")
    , deffy = require("deffy")
    , path = require("path")
    ;

// Constants
const DEFAULT_PACK = {
    repository: {}
  , scripts: {}
  , dependencies: {}
};

// Create the exec limiter
var el = new ExecLimiter(deffy(+process.env.GPM_PROCESS_COUT_LIMIT, 100));

/**
 * Gpm
 * Creates a new `Gpm` instance.
 *
 * @name Gpm
 * @function
 * @param {String|Object} package The git url, the npm package name or a package.json-like object.
 * @param {Object} options An object containing the following fields:
 *
 *  - `url_type` (String): A value interpreted by `git-url-parse` (default: `"ssh"`).
 *  - `dest` (String): The destination path (defaults to `process.cwd()`).
 *  - `auto` (Boolean): If `true`, a new directory will be created in the destination directory (default: `true`).
 *  - `is_dev` (Boolean): If `true`, the dev dependencies will be installed as well (default: `false`).
 *  - `depth` (Number): The dependency tree depth (the other dependencies being installed via `npm`). Default is `Infinity`.
 *
 * @return {Gpm} The `Gpm` instance.
 */
function Gpm(package, options) {

    options = ul.merge(options, {
        url_type: "ssh"
      , dest: process.cwd()
      , auto: true
      , is_dev: false
      , depth: Infinity
    });

    this.package = package;
    this.path = options.dest;
    this.auto = options.auto;
    this.url_type = options.url_type;
    this.is_dev = options.is_dev;
    this.depth = options.depth;
}

/**
 * getPack
 * Gets the module `package.json` object.
 *
 * @name getPack
 * @function
 * @param {Function} callback The callback function.
 */
Gpm.prototype.getPack = function (callback) {
    var self = this
      , parsed = self.url_parsed
      ;

    if (!self.is_git) {
        PackageJson(self.input, "latest", function (err, res) {
            if (self.input === "cli-box")
            if (err) { return callback(err); }
            self.pack = ul.merge(res, DEFAULT_PACK);
            callback(null, res);
        });
    } else {
        var repo = new gry(tmp.dirSync().name);
        repo.exec(oArgv({
            _: [self.input, "."]
          , depth: "1"
        }, "clone"), function (err) {
            if (err) { return callback(err); }
            rJson(repo.cwd + "/package.json", function (err, pack) {
                if (err) { return callback(err); }
                self.pack = ul.merge(pack, DEFAULT_PACK);
                callback(null, pack);
            });
        });
    }
};

/**
 * getGitUrl
 * Gets the git url of the package.
 *
 * @name getGitUrl
 * @function
 * @param {Function} callback The callback function.
 */
Gpm.prototype.getGitUrl = function (callback) {
    var self = this
      , err = null
      , url = null
      ;

    if (self.is_git) {
        return callback(null, self.input);
    }

    if (self.pack) {

        if (typeof self.pack.repository.url !== "string") {
            err = Error("The package does not contain any repository url.");
        }

        if (!err) {
            parsedUrl = GitUrlParse(self.pack.repository.url)
            url = parsedUrl.toString(self.url_type)
        }

        return callback(null, url);
    }

    self.getPack(function (err, pack) {
        if (err) {return callback(err); }
        self.getGitUrl(callback);
    });
};

/**
 * getPath
 * Gets the path to the repository.
 *
 * @name getPath
 * @function
 * @return {String} The path to the repository.
 */
Gpm.prototype.getPath = function () {
    return path.join(this.path, this.auto ? this.pack.name : "");
};

/**
 * runTask
 * Runs a script from `scripts` (`package.json`).
 *
 * @name runTask
 * @function
 * @param {String} task What npm task to run.
 * @param {Function} callback The callback function.
 */
Gpm.prototype.runTask = function (task, callback) {
    var self = this;
    if (typeof self.pack.scripts[task] !== "string") {
        return callback();
    }
    el.add(oArgv({ _: [task] }, "npm run"), { cwd: self.repoPath }, callback);
};

/**
 * exec
 * Executes a command in the repository.
 *
 * @name exec
 * @function
 * @param {String} command The command to execute.
 * @param {Function} callback The callback function.
 */
Gpm.prototype.exec = function (command, callback) {
    el.add(command, { cwd: this.repoPath }, callback);
};

/**
 * getDependencies
 * Returns the requested dependencies for installation
 *
 * @name getDependencies
 * @function
 * @return {Array} A list with the dependencies whose installation was required
 */
Gpm.prototype.getDependencies = function() {
  // A single dependency was requested
  if (typeof this.package === 'string') {
    return [this.package];
  }

  // A package.json was requested
  var dependencies = Object.keys(this.package.dependencies || {});
  if (this.is_dev) {
    dependencies = dependencies.concat(Object.keys(this.package.devDependencies || {}));
  }
  return dependencies;
};

/**
 * install
 * Installs the input package(s).
 *
 * @name install
 * @function
 * @param {Function} callback The callback function.
 * @param {Function} progress The progress function.
 */
Gpm.prototype.install = function(callback, progress) {
    var self = this;

    oneByOne(self.getDependencies().map(function(package) {
        return function(next) {
            self.name = package;
            self.installCurrent(next, progress);
        };
    }), callback);
};

/**
 * installCurrent
 * Installs the current package dependencies.
 *
 * @name installCurrent
 * @function
 * @param {Function} callback The callback function.
 * @param {Function} progress The progress function.
 */
Gpm.prototype.installCurrent = function (callback, progress) {
    var self = this;

    self.url_parsed = GitUrlParse(self.name);
    if (self.url_parsed.protocol !== "file") {
        self.input = self.url_parsed.toString(self.url_type);
        self.is_git = true;
    } else {
        self.input = self.name;
        self.is_git = false;
    }

    progress("Installing " + self.input);
    oneByOne([
        self.getPack.bind(self)
      , function (cb) {
            self.repoPath = self.getPath();
            cb(null, self.repoPath);
        }
      , function (cb, path) {
            mkdirp(path, cb);
        }
      , self.getGitUrl.bind(self)
      , function (cb, gitUrl) {
            progress("Clonning " + gitUrl);
            self.repo = new gry(self.repoPath);
            self.repo.exec(oArgv({
                _: [gitUrl, "."]
            }, "clone"), cb);
        }
      , self.runTask.bind(self, "preinstall")
      , function (cb) {
            // And here the recursive-magic is happening
            var dep = function (obj) {
                    return Object.keys(obj).map(function (name) {
                        return function (cb) {
                            if (self.depth === 1) {
                                return self.exec(oArgv({
                                    production: self.is_dev || undefined
                                  , _: "i"
                                }, "npm"), cb);
                            }
                            var cDep = new Gpm(name, {
                                dest: path.join(self.repoPath, "node_modules")
                              , url_type: self.url_type
                              , auto: self.auto
                              , is_dev: self.is_dev
                              , depth: self.depth - 1
                            });
                            cDep.install(cb, progress);
                        };
                    });
                }
              , deps = dep(self.pack.dependencies)
              ;

            if (self.dev_install) {
                deps = deps.concat(dep(self.pack.devDependencies));
            }

            if (!deps.length) {
                return cb();
            }

            sameTime(deps, cb);
        }
      , self.runTask.bind(self, "install")
      , self.runTask.bind(self, "postinstall")
    ], callback);
};

module.exports = Gpm;
<commit_msg>Use ES2015 classes<commit_after>"use strict";

// Dependencies
const gitSource = require("git-source")
    , packageJson = require("package-json")
    , ul = require("ul")
    , gry = require("gry")
    , tmp = require("tmp")
    , oArgv = require("oargv")
    , rJson = require("r-json")
    , mkdirp = require("mkdirp")
    , oneByOne = require("one-by-one")
    , sameTime = require("same-time")
    , ExecLimiter = require("exec-limiter")
    , deffy = require("deffy")
    , path = require("path")
    ;

// Constants
const DEFAULT_PACK = {
    repository: {}
  , scripts: {}
  , dependencies: {}
};

// Create the exec limiter
const el = new ExecLimiter(deffy(+process.env.GPM_PROCESS_COUT_LIMIT, 100));

class Gpm {
    /**
     * Gpm
     * Creates a new `Gpm` instance.
     *
     * @name Gpm
     * @function
     * @param {String|Object} package The git url, the npm package name or a package.json-like object.
     * @param {Object} options An object containing the following fields:
     *
     *  - `url_type` (String): A value interpreted by `git-url-parse` (default: `"ssh"`).
     *  - `dest` (String): The destination path (defaults to `process.cwd()`).
     *  - `auto` (Boolean): If `true`, a new directory will be created in the destination directory (default: `true`).
     *  - `is_dev` (Boolean): If `true`, the dev dependencies will be installed as well (default: `false`).
     *  - `depth` (Number): The dependency tree depth (the other dependencies being installed via `npm`). Default is `Infinity`.
     *
     * @return {Gpm} The `Gpm` instance.
     */
    constructor (package, options) {
        options = ul.merge(options, {
            url_type: "ssh"
          , dest: process.cwd()
          , auto: true
          , is_dev: false
          , depth: Infinity
        });

        this.package = package;
        this.path = options.dest;
        this.auto = options.auto;
        this.url_type = options.url_type;
        this.is_dev = options.is_dev;
        this.depth = options.depth;
    }

    /**
     * getPack
     * Gets the module `package.json` object.
     *
     * @name getPack
     * @function
     * @param {Function} callback The callback function.
     */
    getPack (callback) {
        var self = this
          , parsed = self.url_parsed
          ;

        if (!self.is_git) {
            PackageJson(self.input, "latest", function (err, res) {
                if (self.input === "cli-box")
                if (err) { return callback(err); }
                self.pack = ul.merge(res, DEFAULT_PACK);
                callback(null, res);
            });
        } else {
            var repo = new gry(tmp.dirSync().name);
            repo.exec(oArgv({
                _: [self.input, "."]
              , depth: "1"
            }, "clone"), function (err) {
                if (err) { return callback(err); }
                rJson(repo.cwd + "/package.json", function (err, pack) {
                    if (err) { return callback(err); }
                    self.pack = ul.merge(pack, DEFAULT_PACK);
                    callback(null, pack);
                });
            });
        }
    }

    /**
     * getGitUrl
     * Gets the git url of the package.
     *
     * @name getGitUrl
     * @function
     * @param {Function} callback The callback function.
     */
    getGitUrl (callback) {
        var self = this
          , err = null
          , url = null
          ;

        if (self.is_git) {
            return callback(null, self.input);
        }

        if (self.pack) {

            if (typeof self.pack.repository.url !== "string") {
                err = Error("The package does not contain any repository url.");
            }

            if (!err) {
                parsedUrl = GitUrlParse(self.pack.repository.url)
                url = parsedUrl.toString(self.url_type)
            }

            return callback(null, url);
        }

        self.getPack(function (err, pack) {
            if (err) {return callback(err); }
            self.getGitUrl(callback);
        });
    }

    /**
     * getPath
     * Gets the path to the repository.
     *
     * @name getPath
     * @function
     * @return {String} The path to the repository.
     */
    getPath () {
        return path.join(this.path, this.auto ? this.pack.name : "");
    }

    /**
     * runTask
     * Runs a script from `scripts` (`package.json`).
     *
     * @name runTask
     * @function
     * @param {String} task What npm task to run.
     * @param {Function} callback The callback function.
     */
    runTask (task, callback) {
        var self = this;
        if (typeof self.pack.scripts[task] !== "string") {
            return callback();
        }
        el.add(oArgv({ _: [task] }, "npm run"), { cwd: self.repoPath }, callback);
    }

    /**
     * exec
     * Executes a command in the repository.
     *
     * @name exec
     * @function
     * @param {String} command The command to execute.
     * @param {Function} callback The callback function.
     */
    exec (command, callback) {
        el.add(command, { cwd: this.repoPath }, callback);
    }

    /**
     * getDependencies
     * Returns the requested dependencies for installation
     *
     * @name getDependencies
     * @function
     * @return {Array} A list with the dependencies whose installation was required
     */
    getDependencies() {
      // A single dependency was requested
      if (typeof this.package === 'string') {
        return [this.package];
      }

      // A package.json was requested
      var dependencies = Object.keys(this.package.dependencies || {});
      if (this.is_dev) {
        dependencies = dependencies.concat(Object.keys(this.package.devDependencies || {}));
      }
      return dependencies;
    }

    /**
     * install
     * Installs the input package(s).
     *
     * @name install
     * @function
     * @param {Function} callback The callback function.
     * @param {Function} progress The progress function.
     */
    install(callback, progress) {
        var self = this;

        oneByOne(self.getDependencies().map(function(package) {
            return function(next) {
                self.name = package;
                self.installCurrent(next, progress);
            };
        }), callback);
    }

    /**
     * installCurrent
     * Installs the current package dependencies.
     *
     * @name installCurrent
     * @function
     * @param {Function} callback The callback function.
     * @param {Function} progress The progress function.
     */
    installCurrent (callback, progress) {
        var self = this;

        self.url_parsed = GitUrlParse(self.name);
        if (self.url_parsed.protocol !== "file") {
            self.input = self.url_parsed.toString(self.url_type);
            self.is_git = true;
        } else {
            self.input = self.name;
            self.is_git = false;
        }

        progress("Installing " + self.input);
        oneByOne([
            self.getPack.bind(self)
          , function (cb) {
                self.repoPath = self.getPath();
                cb(null, self.repoPath);
            }
          , function (cb, path) {
                mkdirp(path, cb);
            }
          , self.getGitUrl.bind(self)
          , function (cb, gitUrl) {
                progress("Clonning " + gitUrl);
                self.repo = new gry(self.repoPath);
                self.repo.exec(oArgv({
                    _: [gitUrl, "."]
                }, "clone"), cb);
            }
          , self.runTask.bind(self, "preinstall")
          , function (cb) {
                // And here the recursive-magic is happening
                var dep = function (obj) {
                        return Object.keys(obj).map(function (name) {
                            return function (cb) {
                                if (self.depth === 1) {
                                    return self.exec(oArgv({
                                        production: self.is_dev || undefined
                                      , _: "i"
                                    }, "npm"), cb);
                                }
                                var cDep = new Gpm(name, {
                                    dest: path.join(self.repoPath, "node_modules")
                                  , url_type: self.url_type
                                  , auto: self.auto
                                  , is_dev: self.is_dev
                                  , depth: self.depth - 1
                                });
                                cDep.install(cb, progress);
                            };
                        });
                    }
                  , deps = dep(self.pack.dependencies)
                  ;

                if (self.dev_install) {
                    deps = deps.concat(dep(self.pack.devDependencies));
                }

                if (!deps.length) {
                    return cb();
                }

                sameTime(deps, cb);
            }
          , self.runTask.bind(self, "install")
          , self.runTask.bind(self, "postinstall")
        ], callback);
    }
}

module.exports = Gpm;
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */
var fs = require('fs')
  , path = require('path')
  , Server = require('./server');

/**
 * Create an OAuth 2.0 server.
 *
 * @return {Server}
 * @api public
 */
function createServer() {
  var server = new Server();
  return server;
}

// expose createServer() as the module
exports = module.exports = createServer;

/**
 * Export `.createServer()`.
 */
exports.createServer = createServer;

/**
 * Export middleware.
 */
exports.errorHandler = require('./middleware/errorHandler');

/**
 * Auto-load bundled grants.
 */
exports.grant = {};

fs.readdirSync(__dirname + '/grant').forEach(function(filename) {
  if (/\.js$/.test(filename)) {
    var name = path.basename(filename, '.js');
    var load = function () { return require('./grant/' + name); };
    exports.grant.__defineGetter__(name, load);
  }
});

// alias grants
exports.grant.authorizationCode = exports.grant.code;
exports.grant.implicit = exports.grant.token;

/**
 * Auto-load bundled exchanges.
 */
exports.exchange = {};

fs.readdirSync(__dirname + '/exchange').forEach(function(filename) {
  if (/\.js$/.test(filename)) {
    var name = path.basename(filename, '.js');
    var load = function () { return require('./exchange/' + name); };
    exports.exchange.__defineGetter__(name, load);
  }
});

// alias exchanges
exports.exchange.code = exports.exchange.authorizationCode;

/**
 * Export errors.
 */
exports.OAuth2Error = require('./errors/oauth2error');
exports.AuthorizationError = require('./errors/authorizationerror');
exports.BadRequestError = require('./errors/badrequesterror');
exports.ForbiddenError = require('./errors/forbiddenerror');
exports.TokenError = require('./errors/tokenerror');
<commit_msg>Don't expose HTTP errors.<commit_after>/**
 * Module dependencies.
 */
var fs = require('fs')
  , path = require('path')
  , Server = require('./server');

/**
 * Create an OAuth 2.0 server.
 *
 * @return {Server}
 * @api public
 */
function createServer() {
  var server = new Server();
  return server;
}

// expose createServer() as the module
exports = module.exports = createServer;

/**
 * Export `.createServer()`.
 */
exports.createServer = createServer;

/**
 * Export middleware.
 */
exports.errorHandler = require('./middleware/errorHandler');

/**
 * Auto-load bundled grants.
 */
exports.grant = {};

fs.readdirSync(__dirname + '/grant').forEach(function(filename) {
  if (/\.js$/.test(filename)) {
    var name = path.basename(filename, '.js');
    var load = function () { return require('./grant/' + name); };
    exports.grant.__defineGetter__(name, load);
  }
});

// alias grants
exports.grant.authorizationCode = exports.grant.code;
exports.grant.implicit = exports.grant.token;

/**
 * Auto-load bundled exchanges.
 */
exports.exchange = {};

fs.readdirSync(__dirname + '/exchange').forEach(function(filename) {
  if (/\.js$/.test(filename)) {
    var name = path.basename(filename, '.js');
    var load = function () { return require('./exchange/' + name); };
    exports.exchange.__defineGetter__(name, load);
  }
});

// alias exchanges
exports.exchange.code = exports.exchange.authorizationCode;

/**
 * Export errors.
 */
exports.OAuth2Error = require('./errors/oauth2error');
exports.AuthorizationError = require('./errors/authorizationerror');
exports.TokenError = require('./errors/tokenerror');
<|endoftext|>


<commit_before>/**
 * Dependencies
 */

var Path = require('path'),
    _ = require('lodash'),
    utils = require('./utils'),
    mocha = require('mocha'),
    EventEmitter = require('events').EventEmitter;

/**
 * Test Runner
 *
 * @param {Object} options
 * @api public
 */

module.exports = function(options) {

  if(!options.adapter) throw new Error('Must supply an adapter');
  if(!options.interfaces) throw new Error('Must supply a list of supported interfaces');
  if(!Array.isArray(options.interfaces)) throw new Error('Must supply a list of supported interfaces');

  this.adapter = options.adapter;
  this.config = options.config || {};
  this.interfaces = options.interfaces;

  // Attach config to adapter
  this.adapter.config = this.config;

  // Globalize Adapter
  global.Adapter = this.adapter;

  // Build an array of files to test
  var filter = '\\.(' + ['js'].join('|') + ')$';

  var files = [];

  this.interfaces.forEach(function(interface) {
    var interfacePath = Path.resolve(__dirname,'../interfaces/' + interface);
    files = files.concat(utils.fileLookup(interfacePath, filter, true));
  });

  // Build a Mocha Runner
  var test = new mocha();

  // Build a global event emitter to keep track of what models we need to clean up
  global.Events = new EventEmitter();

  // Add cleanup to files
  files.push(Path.resolve(__dirname, './cleanup'));

  // Allow Adapter to be a global without warning about a leak
  test.globals([Adapter, Events]);
  test.files = files;

  test.run(function(err) {
    process.exit();
  });
};

/**
 * File Loader
 *
 * @param {String} path
 * @param {Boolean} recursive
 * @return {Array}
 */

// function lookupFiles(path, recursive) {
//   var files = [];

//   if (!fs.existsSync(path)) path += '.js';

//   // Check if path is a file or directory
//   var stat = fs.statSync(path);
//   if (stat.isFile()) return path;

//   fs.readdirSync(path).forEach(function(file) {
//     file = Path.join(path, file);

//     // If file is directory recursivly call function again
//     var stat = fs.statSync(file);
//     if (stat.isDirectory()) {
//       if (recursive) files = files.concat(lookupFiles(file, recursive));
//       return;
//     }

//     var re = new RegExp('\\.(' + ['js'].join('|') + ')$');

//     if (!stat.isFile() || !re.test(file) || Path.basename(file)[0] == '.') return;
//     files.push(file);
//   });

//   return files;
// }
<commit_msg>pass arg to process.exit<commit_after>/**
 * Dependencies
 */

var Path = require('path'),
    _ = require('lodash'),
    utils = require('./utils'),
    mocha = require('mocha'),
    EventEmitter = require('events').EventEmitter;

/**
 * Test Runner
 *
 * @param {Object} options
 * @api public
 */

module.exports = function(options) {

  if(!options.adapter) throw new Error('Must supply an adapter');
  if(!options.interfaces) throw new Error('Must supply a list of supported interfaces');
  if(!Array.isArray(options.interfaces)) throw new Error('Must supply a list of supported interfaces');

  this.adapter = options.adapter;
  this.config = options.config || {};
  this.interfaces = options.interfaces;

  // Attach config to adapter
  this.adapter.config = this.config;

  // Globalize Adapter
  global.Adapter = this.adapter;

  // Build an array of files to test
  var filter = '\\.(' + ['js'].join('|') + ')$';

  var files = [];

  this.interfaces.forEach(function(interface) {
    var interfacePath = Path.resolve(__dirname,'../interfaces/' + interface);
    files = files.concat(utils.fileLookup(interfacePath, filter, true));
  });

  // Build a Mocha Runner
  var test = new mocha();

  // Build a global event emitter to keep track of what models we need to clean up
  global.Events = new EventEmitter();

  // Add cleanup to files
  files.push(Path.resolve(__dirname, './cleanup'));

  // Allow Adapter to be a global without warning about a leak
  test.globals([Adapter, Events]);
  test.files = files;

  test.run(function(err) {
    process.exit(1);
  });
};

/**
 * File Loader
 *
 * @param {String} path
 * @param {Boolean} recursive
 * @return {Array}
 */

// function lookupFiles(path, recursive) {
//   var files = [];

//   if (!fs.existsSync(path)) path += '.js';

//   // Check if path is a file or directory
//   var stat = fs.statSync(path);
//   if (stat.isFile()) return path;

//   fs.readdirSync(path).forEach(function(file) {
//     file = Path.join(path, file);

//     // If file is directory recursivly call function again
//     var stat = fs.statSync(file);
//     if (stat.isDirectory()) {
//       if (recursive) files = files.concat(lookupFiles(file, recursive));
//       return;
//     }

//     var re = new RegExp('\\.(' + ['js'].join('|') + ')$');

//     if (!stat.isFile() || !re.test(file) || Path.basename(file)[0] == '.') return;
//     files.push(file);
//   });

//   return files;
// }
<|endoftext|>


<commit_before>'use strict';

var multimatch = require('multimatch'),
    findup = require('findup-sync'),
    path = require('path');

var parentDir = path.dirname(module.parent.filename);

module.exports = function(options) {

    var defaultOptions = {
            prefix: 'gulp',
            pattern: null,
            replaceExpr: null,
            scope: ['dependencies', 'devDependencies', 'peerDependencies'],
            config: findup('package.json', {cwd: parentDir}),
            requireFn: require,
            camelize: true,
            lazy: true,
            rename: {}
        },
        container = {},
        names;

    options = parseOptions(options, defaultOptions);

    names = options.scope.reduce(function(result, prop) {
        return result.concat(Object.keys(options.config[prop] || {}));
    }, []);

    multimatch(names, options.pattern).forEach(function(name) {
        var requireName;
        if(options.rename[name]) {
            requireName = options.rename[name];
        }
        else {
            requireName = name.replace(options.replaceExp, '');
            requireName = options.camelize ? camelize(requireName) : requireName;
        }
        if (options.lazy) {
            Object.defineProperty(container, requireName, {
                get: function() {
                    return options.requireFn(name);
                }
            });
        }
        else {
            container[requireName] = options.requireFn(name);
        }
    });

    return container;

};

function parseOptions(options, defaultOptions) {
    options = isType('String', options) ? { prefix: options } : (isType('Object', options) ? options : {});
    options.prefix = isType('String', options.prefix) ? options.prefix : defaultOptions.prefix;
    options.pattern = isType('String', options.pattern, true) ? arrayify(options.pattern) : [options.prefix + '-*', options.prefix + '.*'];
    options.replaceExp = isType('RegExp', options.replaceExp) ? options.replaceExp : new RegExp('^' + options.prefix + '(-|\\.)');
    options.scope = isType('String', options.scope, true) ? arrayify(options.scope) : defaultOptions.scope;
    options.config = isType('String', options.config) || isType('Object', options.config) ? options.config : defaultOptions.config;
    options.requireFn = isType('Function', options.requireFn) ? options.requireFn : defaultOptions.requireFn;
    options.camelize = isType('Boolean', options.camelize) ? options.camelize : defaultOptions.camelize;
    options.lazy = isType('Boolean', options.lazy) ? options.lazy : defaultOptions.lazy;
    options.rename = isType('Object', options.rename) ? options.rename : defaultOptions.rename;
    if (isType('String', options.config)) {
        options.config = require(options.config);
    }
    if (!isType('Object', options.config)) {
        throw new Error('Could not find dependencies. Do you have a package.json file in your project?');
    }
    options.pattern.push('!auto-plug');
    return options;
}

function arrayify(object) {
    return Object.prototype.toString.call(object) === '[object Array]' ? object : [object];
}

function camelize(str) {
    return str.replace(/-(\w)/g, function(m, p1) {
        return p1.toUpperCase();
    });
}

function isType(type, object, allowArrayOfSameType) {
    var testType = function(obj) {
        return Object.prototype.toString.call(obj) === '[object ' + type + ']';
    };
    if (allowArrayOfSameType && Object.prototype.toString.call(object) === '[object Array]') {
        return object.every(testType);
    }
    return testType(object);
}

// Necessary to get the current `module.parent` and resolve paths correctly.
delete require.cache[__filename];

<commit_msg>add some comments an beautify<commit_after>'use strict';

var multimatch = require('multimatch'),
    findup = require('findup-sync'),
    path = require('path');

/**
 * parent module's directory to find package.json
 * @type {String}
 */
var parentDir = path.dirname(module.parent.filename);
// necessary to get the current `module.parent` and resolve paths correctly.
delete require.cache[__filename];

/**
 * export main function
 * @param  {mixed}  options  custom options object or options.prefix string
 * @return {Object}          object containing requires
 */
module.exports = function(options) {

    var defaultOptions = {
            prefix: 'gulp',
            pattern: null,
            replaceExpr: null,
            scope: ['dependencies', 'devDependencies', 'peerDependencies'],
            config: findup('package.json', {cwd: parentDir}),
            requireFn: require,
            camelize: true,
            lazy: true,
            rename: {}
        },
        container = {},
        names;

    options = parseOptions(options, defaultOptions);

    names = options.scope.reduce(function(result, prop) {
        return result.concat(Object.keys(options.config[prop] || {}));
    }, []);

    multimatch(names, options.pattern).forEach(function(name) {
        var requireName;
        if (options.rename[name]) {
            requireName = options.rename[name];
        }
        else {
            requireName = name.replace(options.replaceExp, '');
            requireName = options.camelize ? camelize(requireName) : requireName;
        }
        if (options.lazy) {
            Object.defineProperty(container, requireName, {
                get: function() {
                    return options.requireFn(name);
                }
            });
        }
        else {
            container[requireName] = options.requireFn(name);
        }
    });

    return container;

};

/**
 * creates a valid options object from custom options and default options
 * @param  {mixed}  options        custom options object or options.prefix string
 * @param  {Object} defaultOptions default options object
 * @return {Object}                merged and validated options object
 */
function parseOptions(options, defaultOptions) {
    options = isType('String', options) ?
        { prefix: options } : (isType('Object', options) ? options : {});
    options.prefix = isType('String', options.prefix) ?
        options.prefix : defaultOptions.prefix;
    options.pattern = isType('String', options.pattern, true) ?
        arrayify(options.pattern) : [options.prefix + '-*', options.prefix + '.*'];
    options.replaceExp = isType('RegExp', options.replaceExp) ?
        options.replaceExp : new RegExp('^' + options.prefix + '(-|\\.)');
    options.scope = isType('String', options.scope, true) ?
        arrayify(options.scope) : defaultOptions.scope;
    options.config = (isType('String', options.config) || isType('Object', options.config)) ?
        options.config : defaultOptions.config;
    options.requireFn = isType('Function', options.requireFn) ?
        options.requireFn : defaultOptions.requireFn;
    options.camelize = isType('Boolean', options.camelize) ?
        options.camelize : defaultOptions.camelize;
    options.lazy = isType('Boolean', options.lazy) ?
        options.lazy : defaultOptions.lazy;
    options.rename = isType('Object', options.rename) ?
        options.rename : defaultOptions.rename;
    if (isType('String', options.config)) {
        options.config = require(options.config);
    }
    if (!isType('Object', options.config)) {
        throw new Error('Could not find dependencies. Do you have a package.json file in your project?');
    }
    options.pattern.push('!auto-plug');
    return options;
}

/**
 * if item is no array, put it in an array
 * @param  {mixed} item
 * @return {Array}
 */
function arrayify(item) {
    return Object.prototype.toString.call(item) === '[object Array]' ? item : [item];
}

/**
 * transform string to camelcase
 * @param  {String} str
 * @return {String}
 */
function camelize(str) {
    return str.replace(/-(\w)/g, function(m, p1) {
        return p1.toUpperCase();
    });
}

/**
 * test if an item is an object of given type or an array of same type (if allowArrayOfType is true)
 * @param  {String}  type
 * @param  {mixed}   item
 * @param  {Boolean} allowArrayOfType
 * @return {Boolean}                   result
 */
function isType(type, item, allowArrayOfType) {
    var testType = function(obj) {
        return Object.prototype.toString.call(obj) === '[object ' + type + ']';
    };
    if (allowArrayOfType && Object.prototype.toString.call(item) === '[object Array]') {
        return item.every(testType);
    }
    return testType(item);
}
<|endoftext|>


<commit_before>"use strict";

var DEFAULT_TILE_SIZE = 256,
    DEBUG = !!process.env.DEBUG;

var assert = require("assert");

var async = require("async"),
    d3 = require("d3"),
    request = require("request"),
    Canvas = require("canvas"),
    Image = Canvas.Image,
    SphericalMercator = require("sphericalmercator");

var TILE_SIZE,
    merc,
    validate;

var debug = {
  log: function() {
    if (DEBUG) {
      console.log.apply(null, arguments);
    }
  },
  time: function() {
    if (DEBUG) {
      console.time.apply(null, arguments);
    }
  },
  timeEnd: function() {
    if (DEBUG) {
      console.timeEnd.apply(null, arguments);
    }
  }
};

module.exports = exports = function(options) {
  TILE_SIZE = options.tileSize || DEFAULT_TILE_SIZE;
  validate = options.validate.bind(stitch) || stitch.validate;

  merc = new SphericalMercator({ size: TILE_SIZE });

  return stitch;
};

/**
 * Stitch tiles into a single image.
 *
 * @param {string} providerTemplate Provider URL template.
 * @param {Object} view Extent(s) and zoom.
 * @param {Function} callback (Error, Canvas) callback.
 */
var stitch = function(providerTemplate, view, callback) {
  var tiles = getTilesForView(view);
  var urls = makeUrls(providerTemplate, tiles);
  var tasks = makeTasks(urls);

  var rows = tiles.length,
      cols = tiles[0].length;

  debug.time("fetching tiles");

  async.parallel(tasks, function(err, results) {
    debug.timeEnd("fetching tiles");

    if (err) {
      return callback(err);
    }

    debug.time("stitching");

    var canvas = new Canvas(rows * TILE_SIZE, cols * TILE_SIZE),
        ctx = canvas.getContext("2d");

    if (view.backgroundColor) {
      ctx.fillStyle = view.backgroundColor;
      ctx.fillRect(0, 0, canvas.width, canvas.height);
    }

    var x = 0,
        y = 0;
    results.forEach(function(img, i) {
      if (img) {
        ctx.drawImage(img, x, y, TILE_SIZE, TILE_SIZE);
      }

      if (i % cols === cols - 1) {
        x += TILE_SIZE;
        y = 0;
      } else {
        y += TILE_SIZE;
      }
    });

    debug.timeEnd("stitching");

    return callback(null, canvas);
  });
};

var getTiles = function(zoom, range) {
  return d3.range(range.minX, range.maxX + 1).map(function(x) {
    // tileRange.*Y is backward because our y coordinates start at the top
    return d3.range(range.maxY, range.minY + 1).map(function(y) {
      return {
        zoom: zoom,
        x: x,
        y: y
      };
    });
  });
};

var getTilesForView = stitch.getTilesForView = function(view) {
  var tiles = view.extents.map(function(extent) {
    return getTiles(view.zoom, merc.xyz(extent, view.zoom));
  });

  return Array.prototype.concat.apply([], tiles);
};

/**
 * Determine an appropriate zoom level given an extent and desired dimensions.
 */
var getView = stitch.getView = function(extent, width, height) {
  var zoom = 2,
      bbox;

  // this extent crosses the antimeridian
  if (extent[0] > extent[2]) {
    // split the extent into 2 pieces
    var left = [extent[0], extent[1], 180, extent[3]];
    var right = [-180, extent[1], extent[2], extent[3]];

    // calculate widths
    var leftWidth = (left[2] - left[0]) / ((left[2] - left[0]) + (right[2] - right[0])) * width;
    var rightWidth = (right[2] - right[0]) / ((left[2] - left[0]) + (right[2] - right[0])) * width;

    // recursively calculate views for each piece
    var leftView = getView(left, leftWidth, height);
    var rightView = getView(right, rightWidth, height);

    // zooms should match
    assert.equal(leftView.zoom, rightView.zoom, "left and right zooms should match");

    return {
      extents: [left, right],
      zoom: leftView.zoom
    };
  }

  var bounds = [[extent[0], extent[1]], [extent[2], extent[3]]];

  // loop until the pixel delta is larger than the desired width and height
  do {
    zoom++;
    bbox = [merc.px(bounds[0], zoom), merc.px(bounds[1], zoom)];
  } while (zoom <= 20 && bbox[1][0] - bbox[0][0] < width || bbox[1][1] - bbox[0][1] < height);

  return {
    extents: [extent], // return the original extent, otherwise it ends up on tile boundaries
    zoom: zoom
  };
};

var getDimensionsForView = stitch.getDimensionsForView = function(view) {
  var bbox = [merc.px([view.extent[0], view.extent[1]], view.zoom),
              merc.px([view.extent[2], view.extent[3]], view.zoom)];

  return {
    width: bbox[1][0] - bbox[0][0],
    height: bbox[1][1] - bbox[0][1]
  };
};

stitch.validate = function(err, res, callback) {
  if (err) {
    return callback(err);
  }

  if (res.statusCode === 200) {
    return callback();
  }

  return callback(new Error("Request returned non-200 status code: " + res.statusCode));
};

var makeTasks = function(urls) {
  return urls.map(function(url) {
    return function(callback) {
      debug.time(url);

      request({
        url: url,
        encoding: null
      }, function(err, res, body) {
        debug.timeEnd(url);

        // validate the response
        return validate(err, res, function(err) {
          if (err) {
            return callback(err);
          }

          if (res.statusCode === 200) {
            var img = new Image();
            img.src = body;

            return callback(null, img);
          }

          // successful (per validate()), but no image data available
          return callback();
        });
      });
    };
  });
};

var makeUrls = function(providerUrl, tiles) {
  return tiles.reduce(function(a, b) {
    return a.concat(b);
  }, []).map(function(x) {
    return providerUrl
           .replace(/\{z\}/i, x.zoom)
           .replace(/\{x\}/i, x.x)
           .replace(/\{y\}/i, x.y);
  });
};

/**
 * Crop a stitched set of tiles to the desired view, scaling as necessary.
 *
 * @param {Canvas} canvas Source canvas (width and height will be a multiple of
 * TILE_SIZE).
 * @param {Object} view Extent and zoom.
 * @param {Number} width Target width.
 * @param {Number} height Target height.
 */
var crop = stitch.crop = function(canvas, view, width, height) {
  var target = new Canvas(width, height),
      targetCtx = target.getContext("2d");

  var nw,
      se,
      sourceWidth,
      sourceHeight;

  if (view.extents.length === 2) {
    // extent crosses the antimeridian

    console.log(view.extents[0][0], view.extents[0][1]);
    console.log(view.extents[1][2], view.extents[1][3]);

    nw = merc.px([view.extents[0][0], view.extents[0][1]], view.zoom);
    se = merc.px([view.extents[1][2], view.extents[1][3]], view.zoom);

    // complicated way of determining the x-value for 180º
    var am = merc.px([180, view.extents[0][1]], view.zoom);

    sourceWidth = (am[0] - nw[0]) + se[0];
    sourceHeight = se[1] - nw[1];
  } else {
    var extent = view.extents[0];

    nw = merc.px([extent[0], extent[1]], view.zoom);
    se = merc.px([extent[2], extent[3]], view.zoom);

    sourceWidth = se[0] - nw[0];
    sourceHeight = se[1] - nw[1];
  }

  var startX = nw[0] % TILE_SIZE,
      startY = nw[1] % TILE_SIZE;

  debug.log("width: %d, height: %d", width, height);
  debug.log("canvas.width: %d, canvas.height: %d", canvas.width, canvas.height);
  debug.log("sourceWidth: %d, sourceHeight: %d", sourceWidth, sourceHeight);
  targetCtx.drawImage(canvas, startX, startY, sourceWidth, sourceHeight,
                              0, 0, width, height);

  return target;
};

var cropToCenter = stitch.cropToCenter = function(canvas, width, height) {
  var target = new Canvas(width, height),
      targetCtx = target.getContext("2d");

  var xOffset = (canvas.width - width) / 2,
      yOffset = (canvas.height - height) / 2;

  targetCtx.drawImage(canvas, -xOffset, -yOffset);

  return target;
};

var resize = stitch.resize = function(canvas, width, height) {
  var target = new Canvas(width, height),
      targetCtx = target.getContext("2d");

  var aspectRatio = canvas.width / canvas.height,
      targetWidth = Math.max(width, height * aspectRatio),
      targetHeight = Math.max(height, width / aspectRatio),
      xOffset = (targetWidth - width) / 2,
      yOffset = (targetHeight - height) / 2;

  // TODO use ImageMagick to the same effect w/ better results when scaling
  // see http://www.imagemagick.org/script/command-line-options.php?#crop
  targetCtx.drawImage(canvas,
                      0, 0, canvas.width, canvas.height,
                      -xOffset, -yOffset, targetWidth, targetHeight);

  return target;
};
<commit_msg>Fail when too many tiles would be fetched<commit_after>"use strict";

var DEFAULT_TILE_SIZE = 256,
    DEBUG = !!process.env.DEBUG;

var assert = require("assert");

var async = require("async"),
    d3 = require("d3"),
    request = require("request"),
    Canvas = require("canvas"),
    Image = Canvas.Image,
    SphericalMercator = require("sphericalmercator");

var TILE_SIZE,
    merc,
    validate;

var debug = {
  log: function() {
    if (DEBUG) {
      console.log.apply(null, arguments);
    }
  },
  time: function() {
    if (DEBUG) {
      console.time.apply(null, arguments);
    }
  },
  timeEnd: function() {
    if (DEBUG) {
      console.timeEnd.apply(null, arguments);
    }
  }
};

module.exports = exports = function(options) {
  TILE_SIZE = options.tileSize || DEFAULT_TILE_SIZE;
  validate = options.validate.bind(stitch) || stitch.validate;

  merc = new SphericalMercator({ size: TILE_SIZE });

  return stitch;
};

/**
 * Stitch tiles into a single image.
 *
 * @param {string} providerTemplate Provider URL template.
 * @param {Object} view Extent(s) and zoom.
 * @param {Function} callback (Error, Canvas) callback.
 */
var stitch = function(providerTemplate, view, callback) {
  var tiles = getTilesForView(view);
  var urls = makeUrls(providerTemplate, tiles);
  var tasks = makeTasks(urls);

  var rows = tiles.length,
      cols = tiles[0].length;

  // > 25x25
  if (rows * cols > 625) {
    return callback(new Error("Too many tiles to fetch: " + rows * cols));
  }

  debug.time("fetching tiles");

  async.parallel(tasks, function(err, results) {
    debug.timeEnd("fetching tiles");

    if (err) {
      return callback(err);
    }

    debug.time("stitching");

    var canvas = new Canvas(rows * TILE_SIZE, cols * TILE_SIZE),
        ctx = canvas.getContext("2d");

    if (view.backgroundColor) {
      ctx.fillStyle = view.backgroundColor;
      ctx.fillRect(0, 0, canvas.width, canvas.height);
    }

    var x = 0,
        y = 0;
    results.forEach(function(img, i) {
      if (img) {
        ctx.drawImage(img, x, y, TILE_SIZE, TILE_SIZE);
      }

      if (i % cols === cols - 1) {
        x += TILE_SIZE;
        y = 0;
      } else {
        y += TILE_SIZE;
      }
    });

    debug.timeEnd("stitching");

    return callback(null, canvas);
  });
};

var getTiles = function(zoom, range) {
  return d3.range(range.minX, range.maxX + 1).map(function(x) {
    // tileRange.*Y is backward because our y coordinates start at the top
    return d3.range(range.maxY, range.minY + 1).map(function(y) {
      return {
        zoom: zoom,
        x: x,
        y: y
      };
    });
  });
};

var getTilesForView = stitch.getTilesForView = function(view) {
  var tiles = view.extents.map(function(extent) {
    return getTiles(view.zoom, merc.xyz(extent, view.zoom));
  });

  return Array.prototype.concat.apply([], tiles);
};

/**
 * Determine an appropriate zoom level given an extent and desired dimensions.
 */
var getView = stitch.getView = function(extent, width, height) {
  var zoom = 2,
      bbox;

  // this extent crosses the antimeridian
  if (extent[0] > extent[2]) {
    // split the extent into 2 pieces
    var left = [extent[0], extent[1], 180, extent[3]];
    var right = [-180, extent[1], extent[2], extent[3]];

    // calculate widths
    var leftWidth = (left[2] - left[0]) / ((left[2] - left[0]) + (right[2] - right[0])) * width;
    var rightWidth = (right[2] - right[0]) / ((left[2] - left[0]) + (right[2] - right[0])) * width;

    // recursively calculate views for each piece
    var leftView = getView(left, leftWidth, height);
    var rightView = getView(right, rightWidth, height);

    // zooms should match
    assert.equal(leftView.zoom, rightView.zoom, "left and right zooms should match");

    return {
      extents: [left, right],
      zoom: leftView.zoom
    };
  }

  var bounds = [[extent[0], extent[1]], [extent[2], extent[3]]];

  // loop until the pixel delta is larger than the desired width and height
  do {
    zoom++;
    bbox = [merc.px(bounds[0], zoom), merc.px(bounds[1], zoom)];
  } while (zoom <= 20 && bbox[1][0] - bbox[0][0] < width || bbox[1][1] - bbox[0][1] < height);

  return {
    extents: [extent], // return the original extent, otherwise it ends up on tile boundaries
    zoom: zoom
  };
};

var getDimensionsForView = stitch.getDimensionsForView = function(view) {
  var bbox = [merc.px([view.extent[0], view.extent[1]], view.zoom),
              merc.px([view.extent[2], view.extent[3]], view.zoom)];

  return {
    width: bbox[1][0] - bbox[0][0],
    height: bbox[1][1] - bbox[0][1]
  };
};

stitch.validate = function(err, res, callback) {
  if (err) {
    return callback(err);
  }

  if (res.statusCode === 200) {
    return callback();
  }

  return callback(new Error("Request returned non-200 status code: " + res.statusCode));
};

var makeTasks = function(urls) {
  return urls.map(function(url) {
    return function(callback) {
      debug.time(url);

      request({
        url: url,
        encoding: null
      }, function(err, res, body) {
        debug.timeEnd(url);

        // validate the response
        return validate(err, res, function(err) {
          if (err) {
            return callback(err);
          }

          if (res.statusCode === 200) {
            var img = new Image();
            img.src = body;

            return callback(null, img);
          }

          // successful (per validate()), but no image data available
          return callback();
        });
      });
    };
  });
};

var makeUrls = function(providerUrl, tiles) {
  return tiles.reduce(function(a, b) {
    return a.concat(b);
  }, []).map(function(x) {
    return providerUrl
           .replace(/\{z\}/i, x.zoom)
           .replace(/\{x\}/i, x.x)
           .replace(/\{y\}/i, x.y);
  });
};

/**
 * Crop a stitched set of tiles to the desired view, scaling as necessary.
 *
 * @param {Canvas} canvas Source canvas (width and height will be a multiple of
 * TILE_SIZE).
 * @param {Object} view Extent and zoom.
 * @param {Number} width Target width.
 * @param {Number} height Target height.
 */
var crop = stitch.crop = function(canvas, view, width, height) {
  var target = new Canvas(width, height),
      targetCtx = target.getContext("2d");

  var nw,
      se,
      sourceWidth,
      sourceHeight;

  if (view.extents.length === 2) {
    // extent crosses the antimeridian

    console.log(view.extents[0][0], view.extents[0][1]);
    console.log(view.extents[1][2], view.extents[1][3]);

    nw = merc.px([view.extents[0][0], view.extents[0][1]], view.zoom);
    se = merc.px([view.extents[1][2], view.extents[1][3]], view.zoom);

    // complicated way of determining the x-value for 180º
    var am = merc.px([180, view.extents[0][1]], view.zoom);

    sourceWidth = (am[0] - nw[0]) + se[0];
    sourceHeight = se[1] - nw[1];
  } else {
    var extent = view.extents[0];

    nw = merc.px([extent[0], extent[1]], view.zoom);
    se = merc.px([extent[2], extent[3]], view.zoom);

    sourceWidth = se[0] - nw[0];
    sourceHeight = se[1] - nw[1];
  }

  var startX = nw[0] % TILE_SIZE,
      startY = nw[1] % TILE_SIZE;

  debug.log("width: %d, height: %d", width, height);
  debug.log("canvas.width: %d, canvas.height: %d", canvas.width, canvas.height);
  debug.log("sourceWidth: %d, sourceHeight: %d", sourceWidth, sourceHeight);
  targetCtx.drawImage(canvas, startX, startY, sourceWidth, sourceHeight,
                              0, 0, width, height);

  return target;
};

var cropToCenter = stitch.cropToCenter = function(canvas, width, height) {
  var target = new Canvas(width, height),
      targetCtx = target.getContext("2d");

  var xOffset = (canvas.width - width) / 2,
      yOffset = (canvas.height - height) / 2;

  targetCtx.drawImage(canvas, -xOffset, -yOffset);

  return target;
};

var resize = stitch.resize = function(canvas, width, height) {
  var target = new Canvas(width, height),
      targetCtx = target.getContext("2d");

  var aspectRatio = canvas.width / canvas.height,
      targetWidth = Math.max(width, height * aspectRatio),
      targetHeight = Math.max(height, width / aspectRatio),
      xOffset = (targetWidth - width) / 2,
      yOffset = (targetHeight - height) / 2;

  // TODO use ImageMagick to the same effect w/ better results when scaling
  // see http://www.imagemagick.org/script/command-line-options.php?#crop
  targetCtx.drawImage(canvas,
                      0, 0, canvas.width, canvas.height,
                      -xOffset, -yOffset, targetWidth, targetHeight);

  return target;
};
<|endoftext|>


<commit_before>var EventEmitter = require('events').EventEmitter;
var util = require('util');
var Client = require(__dirname+'/client');
var defaults =  require(__dirname + '/defaults');

//external genericPool module
var genericPool = require('generic-pool');

//cache of existing client pools
var pools = {};

var PG = function(clientConstructor) {
  EventEmitter.call(this);
  this.Client = clientConstructor;
  this.Connection = require(__dirname + '/connection');
  this.defaults = defaults;
};

util.inherits(PG, EventEmitter);

PG.prototype.end = function() {
  Object.keys(pools).forEach(function(name) {
    var pool = pools[name];
    pool.drain(function() {
      pool.destroyAllNow();
    });
  })
}

PG.prototype.connect = function(config, callback) {
  var self = this;
  var c = config;
  var cb = callback;
  //allow for no config to be passed
  if(typeof c === 'function') {
    cb = c;
    c = defaults;
  }

  //get unique pool name even if object was used as config
  var poolName = typeof(c) === 'string' ? c : c.user+c.host+c.port+c.database;
  var pool = pools[poolName];

  if(pool) return pool.acquire(cb);

  var pool = pools[poolName] = genericPool.Pool({
    name: poolName,
    create: function(callback) {
      var client = new self.Client(c);
      client.connect();

      var connectError = function(err) {
        client.removeListener('connect', connectSuccess);
        callback(err, null);
      };

      var connectSuccess = function() {
        client.removeListener('error', connectError);

        //handle connected client background errors by emitting event
        //via the pg object and then removing errored client from the pool
        client.on('error', function(e) {
          self.emit('error', e, client);
          pool.destroy(client);
        });
        callback(null, client);
      };

      client.once('connect', connectSuccess);
      client.once('error', connectError);
      client.on('drain', function() {
        pool.release(client);
      });
    },
    destroy: function(client) {
      client.end();
    },
    max: defaults.poolSize,
    idleTimeoutMillis: defaults.poolIdleTimeout,
    reapIntervalMillis: defaults.reapIntervalMillis
  });
  return pool.acquire(cb);
}

// cancel the query runned by the given client
PG.prototype.cancel = function(config, client, query) {
  var c = config;
  //allow for no config to be passed
  if(typeof c === 'function')
    c = defaults;
  var cancellingClient = new this.Client(c);
  cancellingClient.cancel(client, query);
}

module.exports = new PG(Client);

//lazy require native module...the native module may not have installed
module.exports.__defineGetter__("native", function() {
  delete module.exports.native;
  return (module.exports.native = new PG(require(__dirname + '/native')));
})
<commit_msg>use client#connect callback in pg.connect connection error handling<commit_after>var EventEmitter = require('events').EventEmitter;
var util = require('util');
var Client = require(__dirname+'/client');
var defaults =  require(__dirname + '/defaults');

//external genericPool module
var genericPool = require('generic-pool');

//cache of existing client pools
var pools = {};

var PG = function(clientConstructor) {
  EventEmitter.call(this);
  this.Client = clientConstructor;
  this.Connection = require(__dirname + '/connection');
  this.defaults = defaults;
};

util.inherits(PG, EventEmitter);

PG.prototype.end = function() {
  Object.keys(pools).forEach(function(name) {
    var pool = pools[name];
    pool.drain(function() {
      pool.destroyAllNow();
    });
  })
}

PG.prototype.connect = function(config, callback) {
  var self = this;
  var c = config;
  var cb = callback;
  //allow for no config to be passed
  if(typeof c === 'function') {
    cb = c;
    c = defaults;
  }

  //get unique pool name even if object was used as config
  var poolName = typeof(c) === 'string' ? c : c.user+c.host+c.port+c.database;
  var pool = pools[poolName];

  if(pool) return pool.acquire(cb);

  var pool = pools[poolName] = genericPool.Pool({
    name: poolName,
    create: function(callback) {
      var client = new self.Client(c);
      client.connect(function(err) {
        if(err) return callback(err);

        //handle connected client background errors by emitting event
        //via the pg object and then removing errored client from the pool
        client.on('error', function(e) {
          self.emit('error', e, client);
          pool.destroy(client);
        });

        callback(null, client);
      });

      client.on('drain', function() {
        pool.release(client);
      });
    },
    destroy: function(client) {
      client.end();
    },
    max: defaults.poolSize,
    idleTimeoutMillis: defaults.poolIdleTimeout,
    reapIntervalMillis: defaults.reapIntervalMillis
  });
  return pool.acquire(cb);
}

// cancel the query runned by the given client
PG.prototype.cancel = function(config, client, query) {
  var c = config;
  //allow for no config to be passed
  if(typeof c === 'function')
    c = defaults;
  var cancellingClient = new this.Client(c);
  cancellingClient.cancel(client, query);
}

module.exports = new PG(Client);

//lazy require native module...the native module may not have installed
module.exports.__defineGetter__("native", function() {
  delete module.exports.native;
  return (module.exports.native = new PG(require(__dirname + '/native')));
})
<|endoftext|>


<commit_before>/*
 * Load cJSON files recursively.
 */

var path = require('path'),
    util = require('util'),
    cjson = require('cjson');

function i(data) {
    return util.inspect(data, 99, false);
}

/*
 * Recursively go through the given data-structure and sort out any
 * `#include`-statements.
 */
function includeRecursively(obj, currentFile, loadedFiles) {
    //console.warn("→ includeRecursively(" + i(obj) + ", " + currentFile + ", " + loadedFiles + ")");

    if (Array.isArray(obj)) {
        return obj.map(function (element) {
            return includeRecursively(element, currentFile, loadedFiles);
        });
    } else if (typeof obj === 'object' && obj !== null) {
        // If there's any data to mix in, we do that.
        if (obj['#include'] !== undefined) {
            Array.isArray(obj['#include']) ? obj['#include'] : [obj['#include']].reverse().forEach(function (include) {
                // Figure out the target filename.
                var dirname = path.dirname(currentFile),
                    newFilename = path.resolve(dirname, include);
                obj = cjson.extend(
                    true,
                    loadFile(newFilename, loadedFiles),
                    obj
                );
            });
            delete obj['#include'];
        }
        Object.keys(obj).forEach(function (key) {
            obj[key] = includeRecursively(obj[key], currentFile, loadedFiles);
        });
    }
    return obj;
}

/*
 * Load `filename` and then have `includeRecursively` go through the file and
 * resolve any nested include-statements.
 *
 * Also checks if the given file has been loaded previously (to identify include-loops).
 */
function loadFile(filename, loadedFiles) {
    //console.warn("→ loadFile(" + filename + ", " + loadedFiles + ")");

    var fullname = path.normalize(filename),
        base = cjson.load(fullname);

    // Have we loaded this file before?
    if (loadedFiles.indexOf(fullname) !== -1) {
        throw new Error("Loop in loaded files: \n\t→ " + loadedFiles.join("\n\t→ "));
    }

    // We've also loaded this file
    var newLoadedFiles = [].concat(loadedFiles, [fullname]);

    base = includeRecursively(base, fullname, newLoadedFiles);

    return base;
}

function load(filename) {
    return loadFile(path.resolve(filename), []);
}

module.exports.load = load;
<commit_msg>Fixed stupid bug that broke {"#include": <array>}<commit_after>/*
 * Load cJSON files recursively.
 */

var path = require('path'),
    util = require('util'),
    cjson = require('cjson');

function i(data) {
    return util.inspect(data, 99, false);
}

/*
 * Recursively go through the given data-structure and sort out any
 * `#include`-statements.
 */
function includeRecursively(obj, currentFile, loadedFiles) {
    //console.warn("→ includeRecursively(" + i(obj) + ", " + currentFile + ", " + loadedFiles + ")");

    if (Array.isArray(obj)) {
        return obj.map(function (element) {
            return includeRecursively(element, currentFile, loadedFiles);
        });
    } else if (typeof obj === 'object' && obj !== null) {
        // If there's any data to mix in, we do that.
        if (obj['#include'] !== undefined) {
            (Array.isArray(obj['#include']) ? obj['#include'].reverse() : [obj['#include']]).forEach(function (include) {
                // Figure out the target filename.
                var dirname = path.dirname(currentFile),
                    newFilename = path.resolve(dirname, include);
                obj = cjson.extend(
                    true,
                    loadFile(newFilename, loadedFiles),
                    obj
                );
            });
            delete obj['#include'];
        }
        Object.keys(obj).forEach(function (key) {
            obj[key] = includeRecursively(obj[key], currentFile, loadedFiles);
        });
    }
    return obj;
}

/*
 * Load `filename` and then have `includeRecursively` go through the file and
 * resolve any nested include-statements.
 *
 * Also checks if the given file has been loaded previously (to identify include-loops).
 */
function loadFile(filename, loadedFiles) {
    //console.warn("→ loadFile(" + filename + ", " + loadedFiles + ")");

    var fullname = path.normalize(filename),
        base = cjson.load(fullname);

    // Have we loaded this file before?
    if (loadedFiles.indexOf(fullname) !== -1) {
        throw new Error("Loop in loaded files: \n\t→ " + loadedFiles.join("\n\t→ "));
    }

    // We've also loaded this file
    var newLoadedFiles = [].concat(loadedFiles, [fullname]);

    base = includeRecursively(base, fullname, newLoadedFiles);

    return base;
}

function load(filename) {
    return loadFile(path.resolve(filename), []);
}

module.exports.load = load;
<|endoftext|>


<commit_before><commit_msg>Add update to NameActions to accept a patient object rather than an id<commit_after><|endoftext|>