Skip to content

Commit

Permalink
[bin] unify configuration; getPkgs available programmatically
Browse files Browse the repository at this point in the history
  • Loading branch information
doublerebel committed Apr 4, 2016
1 parent 41a8fcc commit 2af31e1
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 93 deletions.
114 changes: 31 additions & 83 deletions bin/cmd.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ var defaultConfig = require('../config/default'),
snpm = require('../lib'),
url = require('url'),
fs = require('fs'),
path = require('path'),
getPkgs = require('npm-registry-packages');
path = require('path')
util = require('util');

process.title = 'smart-private-npm';

Expand Down Expand Up @@ -39,128 +39,76 @@ if (argv.help) {
// TODO: Replace with diagnostic
var winston = require('winston');

var log = new winston.Logger({
var config = argv.config ? require(path.resolve(process.cwd(), argv.config)) : {};

var log = config.log = config.log || new winston.Logger({
transports: [
new (winston.transports.Console)({ level: argv.loglevel, colorize: true })
]
});

var config = argv.config ? require(path.resolve(process.cwd(), argv.config)) : {};

config.ip = argv.i;

//
// TODO: A better way of merging the defaults with the cli flags
// taking precendence
//
config.private = argv.private || config.private || defaultConfig.private;

config.public = argv.public || config.public || defaultConfig.public;

config.http = config.http || defaultConfig.http;

config.https = config.https || null;

config.exclude = argv.exclude || config.exclude || defaultConfig.exclude;

config.rewrites = config.rewrites || require('../config/rewrites');

config.transparent = argv.transparent || config.transparent || false;


if (argv.config) {
log.verbose('config => %s', argv.config);
}
log.verbose('private registry => %s', config.private);
log.verbose('public registry => %s', config.public);
log.verbose('http => %s', ''+config.http);
log.verbose('https => '+(config.https ? config.https : 'null'));
log.verbose('excludes =>', config.exclude);
log.verbose('transparent =>', config.transparent);
log.verbose('ignore-private =>', config.ip);


if (typeof config.public === "string") {
config.public = url.parse(config.public);
}
if (typeof config.private === "string") {
config.private = url.parse(config.private);
}

var proxyOpts = {
rewrites: config.rewrites,
var snpmOpts = {
rewrites: null,
proxy: {
npm: config.public,
npm: null,
policy: {
npm: config.private,
npm: null,
private: {},
blacklist: {},
transparent: config.transparent
transparent: false
},
log: log
log: null
},
http: config.http,
https: config.https,
log: log
http: null,
https: null,
log: null
};

if (config.blacklist) {
proxyOpts.proxy.policy.blacklist = config.blacklist;
}
snpmOpts = util._extend(snpmOpts, defaultConfig, config, argv);
delete snpmOpts.config;

if (config.whitelist) {
proxyOpts.proxy.policy.whitelist = config.whitelist;
if (argv.config) {
log.verbose('config => %s', argv.config);
}

if (config.ip === true) {
log.verbose('private registry => %s', snpmOpts.proxy.policy.npm);
log.verbose('public registry => %s', snpmOpts.npm);
log.verbose('http => %s', ''+snpmOpts.http);
log.verbose('https => '+(snpmOpts.https ? snpmOpts.https : 'null'));
log.verbose('excludes =>', snpmOpts.exclude);
log.verbose('transparent =>', snpmOpts.proxy.transparent);
log.verbose('ignore-private =>', snpmOpts.ip);

if (snpmOpts.ip === true) {
getPkgs = function(a, cb) {
process.nextTick(function() {
cb(null, []);
});
};
}

getPkgs(config.private.href, function(err, pkgs) {
snpm.getPkgs(snpmOpts, function(err, privatePkgs) {
if (err) {
if (err.code && err.code === 'ECONNREFUSED') {
log.error('Error loading private packages', err.message);
log.error('Is your private registry running and accessible at [%s]?', config.private);
log.error('Is your private registry running and accessible at [%s]?', snpmOpts.proxy.policy.npm);
} else {
log.error('Error loading private packages', { err: err });
}

return process.exit(1);
}

if (!config.filter) {
pkgs = pkgs.filter(function(f) {
return (!(~config.exclude.indexOf(f)));
});
}

var privatePkgs = {},
len = pkgs.length;

if (!config.ip) {
for (var i=0; i<len; i++) {
var pkg = pkgs[i];
privatePkgs[pkg] = 1;
}

config.exclude.forEach(function(e) {
log.verbose('excluding package: '+e);
if (privatePkgs.hasOwnProperty(e)) {
delete privatePkgs[e];
}
});

log.verbose('loaded private packages', privatePkgs);
} else {
log.verbose('ignoring packages from private registry');
}

proxyOpts.proxy.policy.private = privatePkgs;
snpm.createServer(proxyOpts, function(err, servers) {
snpmOpts.proxy.policy.private = privatePkgs;
snpm.createServer(snpmOpts, function(err, servers) {
if (err) {
log.error('error starting private npm', { err: err });
log.error('servers: %j', Object.keys(servers));
Expand Down
26 changes: 17 additions & 9 deletions config/default.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
//
// Default rewrites for routes
//
exports.rewrites = require('./rewrites');

//
// Default CouchDB documents to exclude
//
Expand All @@ -9,15 +14,18 @@ exports.exclude = [
'error: forbidden',
];

//
// Private npm registry url
//
exports.private = 'http://localhost:5984';

//
// Public npm registry url
//
exports.public = 'https://registry.nodejitsu.com';
exports.proxy = {
//
// Public npm registry url
//
npm: 'https://registry.nodejitsu.com',
policy: {
//
// Private npm registry url
//
npm: 'http://localhost:5984'
}
};

//
// Function to filter excluded documents
Expand Down
52 changes: 51 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
*/

var createServers = require('create-servers'),
director = require('director');
director = require('director'),
getPkgs = require('npm-registry-packages');

var patterns = {
packageAnd: /\/([_\.\(\)!\\ %@&a-zA-Z0-9-]+)\/.*/,
Expand Down Expand Up @@ -178,3 +179,52 @@ exports.createRouter = function createRouter(options, callback) {
router.proxy = proxy;
return router;
};

//
// ### function getPkgs (options, callback)
// #### @options {Object} Options for starting the proxy
// #### - log {function} Logging function to use.
// #### - exclude {Array} Default CouchDB documents to exclude.
// #### - filter {function} Filter function for CouchDB documente exclusion.
// #### - ip {boolean} Whether to ignore packages from private registry.
//
exports.getPkgs = function(config, cb) {
url = config.private || config.proxy.policy.npm;
if (url.href) url = url.href;

getPkgs(url, function(err, pkgs) {
if (err) {
return cb(err);
}

if (!config.filter) {
pkgs = pkgs.filter(function(f) {
return (!(~config.exclude.indexOf(f)));
});
}

var privatePkgs = {},
len = pkgs.length,
log = config.log;

if (!config.ip) {
for (var i=0; i<len; i++) {
var pkg = pkgs[i];
privatePkgs[pkg] = 1;
}

config.exclude.forEach(function(e) {
log.info('[getPkgs] excluding package: '+e);
if (privatePkgs.hasOwnProperty(e)) {
delete privatePkgs[e];
}
});

log.info('[getPkgs] loaded private packages', privatePkgs);
} else {
log.info('[getPkgs] ignoring packages from private registry');
}

cb(null, privatePkgs);
});
};

0 comments on commit 2af31e1

Please sign in to comment.