Browse Source

More advanced features.

* fetch data from main registry if cache look up is failed
* save fetched data to npm's cache, in same was as npm does the job
pull/1/head
Harish.K 10 years ago
parent
commit
16aece8d5f
  1. 32
      app.js
  2. 3
      bin/www
  3. 15
      config.js
  4. 32
      test/utils.spec.js
  5. 30
      utils.js

32
app.js

@ -1,21 +1,16 @@
var express = require('express');
var fs = require('fs');
var config = require( __dirname + '/./config' );
var utils = require( __dirname + '/./utils');
var NPM_PATH = process.env.HOME + '/.npm';
var REGISTRY_NAME = 'registry.npmjs.org';
var LOCAL_REGISTRY = 'localhost:8080';
var NPM_PATH = config.NPM_PATH;
var REGISTRY_NAME = config.REGISTRY_NAME;
var fetchAndCacheMetadata = utils.fetchAndCacheMetadata;
var fetchAndCacheTarball = utils.fetchAndCacheTarball;
var patchData = utils.patchData;
var app = express();
function patchData( data ){
Object.keys(data.versions).forEach( function( v ){
var val = data.versions[v];
val.dist.tarball = val.dist.tarball.replace( REGISTRY_NAME, LOCAL_REGISTRY );
});
}
app.use( function(req, res, next ){
console.log(req.method, req.path );
next();
@ -24,7 +19,13 @@ app.use( function(req, res, next ){
app.get( '/:package', function( req, res ){
var packageName = req.params.package;
var cacheFile = [ NPM_PATH, REGISTRY_NAME, packageName, '.cache.json' ].join( '/' );
var cacheData = fs.readFileSync( cacheFile, 'utf-8' );
var cacheData;
if( !fs.existsSync( cacheFile ) ){
fetchAndCacheMetadata( packageName, cacheFile );
}
cacheData = fs.readFileSync( cacheFile, 'utf-8' );
cacheData = JSON.parse( cacheData );
patchData( cacheData );
@ -35,6 +36,11 @@ app.get( '/:package/-/:packageName-:version.tgz', function( req, res ){
var packageName = req.params.package;
var version = req.params.version.split('-').pop();
var packagePath = [ NPM_PATH , packageName, version, 'package.tgz'].join( '/' );
if( !fs.existsSync( packagePath ) ){
fetchAndCacheTarball( packageName, version, packagePath );
}
return fs.createReadStream( packagePath ).pipe( res );
});

3
bin/www

@ -5,7 +5,6 @@
*/
var app = require('../app');
var debug = require('debug')('npm-proxy:server');
var http = require('http');
/**
@ -86,5 +85,5 @@ function onListening() {
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
console.log('Listening on ' + bind);
}

15
config.js

@ -0,0 +1,15 @@
var defaultConfig = {
NPM_PATH : process.env.HOME + '/.npm',
REGISTRY_NAME : 'registry.npmjs.org',
LOCAL_REGISTRY : 'localhost:8080',
};
var config = {};
Object.keys( defaultConfig ).forEach( function(v){
config[v] = process.env[v] || defaultConfig[v];
});
module.exports = config;

32
test/utils.spec.js

@ -0,0 +1,32 @@
/* globals describe, it */
var utils = require( '../utils' );
var assert = require('assert');
var fs = require('fs');
var path = require('path');
var fetchAndCacheMetadata = utils.fetchAndCacheMetadata;
var fetchAndCacheTarball = utils.fetchAndCacheTarball;
/* TODO: write test */
// var patchData = utils.patchData;
describe( 'Utility functions ', function(){
it.skip( 'should fetchAndCacheMetadata', function( ){
var cacheFile = '/home/hari/.npm/registry.npmjs.org/lodash/.cache.json';
fetchAndCacheMetadata( 'lodash', cacheFile );
assert( fs.existsSync( cacheFile ) );
});
it( 'should fetchAndCacheTarball', function(){
var cacheFile = '/home/hari/.npm/lodash/4.2.1/package.tgz';
var packageJsonFile = path.dirname( cacheFile ) + '/package/package.json';
fetchAndCacheTarball( 'lodash', '4.2.1', cacheFile );
assert( fs.existsSync( cacheFile ) );
assert( fs.existsSync( packageJsonFile ) );
});
});

30
utils.js

@ -0,0 +1,30 @@
var execSync = require('child_process').execSync;
var path = require('path');
var config = require( __dirname + '/./config' );
var REGISTRY_NAME = config.REGISTRY_NAME;
var LOCAL_REGISTRY = config.LOCAL_REGISTRY;
exports.patchData = function ( data ){
Object.keys(data.versions).forEach( function( v ){
var val = data.versions[v];
val.dist.tarball = val.dist.tarball.replace( REGISTRY_NAME, LOCAL_REGISTRY );
});
};
exports.fetchAndCacheMetadata = function ( packageName, cacheFile ){
var packageCacheDir = path.dirname( cacheFile );
execSync( 'mkdir ' + packageCacheDir );
execSync( 'wget http://' + REGISTRY_NAME + '/' + packageName + ' -O ' + cacheFile );
};
exports.fetchAndCacheTarball = function ( packageName, version, tarballPath ){
var tarballUrl = 'http://' + REGISTRY_NAME + '/' + packageName + '/-/' + packageName + '-' + version + '.tgz';
var packageTarballDir = path.dirname( tarballPath );
execSync( 'mkdir -p ' + packageTarballDir );
execSync( 'wget ' + tarballUrl + ' -O ' + tarballPath );
execSync( 'cd ' + packageTarballDir + ';tar -xzf package.tgz package/package.json' );
};
Loading…
Cancel
Save