mirror of
https://github.com/verdaccio/verdaccio.git
synced 2025-01-06 22:40:26 -05:00
chore(flow): update flow definitions for proxy
This commit is contained in:
parent
7e06ccc8ac
commit
f7414e9bb2
6 changed files with 82 additions and 40 deletions
|
@ -51,7 +51,7 @@
|
||||||
"@commitlint/cli": "^6.1.0",
|
"@commitlint/cli": "^6.1.0",
|
||||||
"@commitlint/config-conventional": "^6.1.0",
|
"@commitlint/config-conventional": "^6.1.0",
|
||||||
"@commitlint/travis-cli": "^6.1.0",
|
"@commitlint/travis-cli": "^6.1.0",
|
||||||
"@verdaccio/types": "0.3.0",
|
"@verdaccio/types": "0.3.1",
|
||||||
"axios": "0.17.1",
|
"axios": "0.17.1",
|
||||||
"babel-cli": "6.26.0",
|
"babel-cli": "6.26.0",
|
||||||
"babel-core": "6.26.0",
|
"babel-core": "6.26.0",
|
||||||
|
|
|
@ -570,7 +570,8 @@ class Storage implements IStorageHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err || !upLinkResponse) {
|
if (err || !upLinkResponse) {
|
||||||
return cb(null, [err || Error(500, 'no data')]);
|
// $FlowFixMe
|
||||||
|
return cb(null, [err || Error('no data')]);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -597,6 +598,7 @@ class Storage implements IStorageHandler {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Storage._mergeVersions(packageInfo, upLinkResponse, self.config);
|
Storage._mergeVersions(packageInfo, upLinkResponse, self.config);
|
||||||
|
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
self.logger.error({
|
self.logger.error({
|
||||||
sub: 'out',
|
sub: 'out',
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
import zlib from 'zlib';
|
import zlib from 'zlib';
|
||||||
import JSONStream from 'JSONStream';
|
import JSONStream from 'JSONStream';
|
||||||
import createError from 'http-errors';
|
import createError from 'http-errors';
|
||||||
|
@ -8,7 +10,17 @@ import URL from 'url';
|
||||||
import {parseInterval, is_object, ErrorCode} from './utils';
|
import {parseInterval, is_object, ErrorCode} from './utils';
|
||||||
import {ReadTarball} from '@verdaccio/streams';
|
import {ReadTarball} from '@verdaccio/streams';
|
||||||
|
|
||||||
const Logger = require('./logger');
|
import type {
|
||||||
|
IProxy,
|
||||||
|
Config,
|
||||||
|
Callback,
|
||||||
|
Logger,
|
||||||
|
} from '@verdaccio/types';
|
||||||
|
|
||||||
|
import type {IUploadTarball} from '@verdaccio/streams';
|
||||||
|
|
||||||
|
|
||||||
|
const LoggerApi = require('./logger');
|
||||||
|
|
||||||
const encode = function(thing) {
|
const encode = function(thing) {
|
||||||
return encodeURIComponent(thing).replace(/^%40/, '@');
|
return encodeURIComponent(thing).replace(/^%40/, '@');
|
||||||
|
@ -33,23 +45,37 @@ const setConfig = (config, key, def) => {
|
||||||
* Implements Storage interface
|
* Implements Storage interface
|
||||||
* (same for storage.js, local-storage.js, up-storage.js)
|
* (same for storage.js, local-storage.js, up-storage.js)
|
||||||
*/
|
*/
|
||||||
class ProxyStorage {
|
class ProxyStorage implements IProxy {
|
||||||
|
config: Config;
|
||||||
|
failed_requests: number;
|
||||||
|
userAgent: string;
|
||||||
|
ca: string | void;
|
||||||
|
logger: Logger;
|
||||||
|
server_id: string;
|
||||||
|
url: any;
|
||||||
|
maxage: string;
|
||||||
|
timeout: string;
|
||||||
|
max_fails: number;
|
||||||
|
fail_timeout: number;
|
||||||
|
upname: string;
|
||||||
|
proxy: string;
|
||||||
|
last_request_time: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param {*} config
|
* @param {*} config
|
||||||
* @param {*} mainConfig
|
* @param {*} mainConfig
|
||||||
*/
|
*/
|
||||||
constructor(config, mainConfig) {
|
constructor(config: UpLinkConf, mainConfig: Config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.failed_requests = 0;
|
this.failed_requests = 0;
|
||||||
this.userAgent = mainConfig.user_agent;
|
this.userAgent = mainConfig.user_agent;
|
||||||
this.ca = config.ca;
|
this.ca = config.ca;
|
||||||
this.logger = Logger.logger.child({sub: 'out'});
|
this.logger = LoggerApi.logger.child({sub: 'out'});
|
||||||
this.server_id = mainConfig.server_id;
|
this.server_id = mainConfig.server_id;
|
||||||
|
|
||||||
this.url = URL.parse(this.config.url);
|
this.url = URL.parse(this.config.url);
|
||||||
|
// $FlowFixMe
|
||||||
this._setupProxy(this.url.hostname, config, mainConfig, this.url.protocol === 'https:');
|
this._setupProxy(this.url.hostname, config, mainConfig, this.url.protocol === 'https:');
|
||||||
|
|
||||||
this.config.url = this.config.url.replace(/\/$/, '');
|
this.config.url = this.config.url.replace(/\/$/, '');
|
||||||
|
@ -74,7 +100,7 @@ class ProxyStorage {
|
||||||
* @param {*} cb
|
* @param {*} cb
|
||||||
* @return {Request}
|
* @return {Request}
|
||||||
*/
|
*/
|
||||||
request(options, cb) {
|
request(options: any, cb: Callback) {
|
||||||
let json;
|
let json;
|
||||||
|
|
||||||
if (this._statusCheck() === false) {
|
if (this._statusCheck() === false) {
|
||||||
|
@ -84,9 +110,10 @@ class ProxyStorage {
|
||||||
if (_.isFunction(cb)) {
|
if (_.isFunction(cb)) {
|
||||||
cb(ErrorCode.get500('uplink is offline'));
|
cb(ErrorCode.get500('uplink is offline'));
|
||||||
}
|
}
|
||||||
|
// $FlowFixMe
|
||||||
streamRead.emit('error', createError('uplink is offline'));
|
streamRead.emit('error', createError('uplink is offline'));
|
||||||
});
|
});
|
||||||
|
// $FlowFixMe
|
||||||
streamRead._read = function() {};
|
streamRead._read = function() {};
|
||||||
// preventing 'Uncaught, unspecified "error" event'
|
// preventing 'Uncaught, unspecified "error" event'
|
||||||
streamRead.on('error', function() {});
|
streamRead.on('error', function() {});
|
||||||
|
@ -116,7 +143,7 @@ class ProxyStorage {
|
||||||
let requestCallback = cb ? (function(err, res, body) {
|
let requestCallback = cb ? (function(err, res, body) {
|
||||||
let error;
|
let error;
|
||||||
const responseLength = err ? 0 : body.length;
|
const responseLength = err ? 0 : body.length;
|
||||||
|
// $FlowFixMe
|
||||||
processBody(err, body);
|
processBody(err, body);
|
||||||
logActivity();
|
logActivity();
|
||||||
cb(err, res, body);
|
cb(err, res, body);
|
||||||
|
@ -132,6 +159,7 @@ class ProxyStorage {
|
||||||
|
|
||||||
if (options.json && res.statusCode < 300) {
|
if (options.json && res.statusCode < 300) {
|
||||||
try {
|
try {
|
||||||
|
// $FlowFixMe
|
||||||
body = JSON.parse(body.toString('utf8'));
|
body = JSON.parse(body.toString('utf8'));
|
||||||
} catch(_err) {
|
} catch(_err) {
|
||||||
body = {};
|
body = {};
|
||||||
|
@ -216,7 +244,7 @@ class ProxyStorage {
|
||||||
* @return {Object}
|
* @return {Object}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_setHeaders(options) {
|
_setHeaders(options: any) {
|
||||||
const headers = options.headers || {};
|
const headers = options.headers || {};
|
||||||
const accept = 'Accept';
|
const accept = 'Accept';
|
||||||
const acceptEncoding = 'Accept-Encoding';
|
const acceptEncoding = 'Accept-Encoding';
|
||||||
|
@ -236,7 +264,7 @@ class ProxyStorage {
|
||||||
* @return {Object}
|
* @return {Object}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_setAuth(headers) {
|
_setAuth(headers: any) {
|
||||||
|
|
||||||
if (_.isNil(this.config.auth) || headers['authorization']) {
|
if (_.isNil(this.config.auth) || headers['authorization']) {
|
||||||
return headers;
|
return headers;
|
||||||
|
@ -248,7 +276,7 @@ class ProxyStorage {
|
||||||
|
|
||||||
// get NPM_TOKEN http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules
|
// get NPM_TOKEN http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules
|
||||||
// or get other variable export in env
|
// or get other variable export in env
|
||||||
let token = process.env.NPM_TOKEN;
|
let token: any = process.env.NPM_TOKEN;
|
||||||
if (this.config.auth.token) {
|
if (this.config.auth.token) {
|
||||||
token = this.config.auth.token;
|
token = this.config.auth.token;
|
||||||
} else if (this.config.auth.token_env) {
|
} else if (this.config.auth.token_env) {
|
||||||
|
@ -270,7 +298,7 @@ class ProxyStorage {
|
||||||
* @throws {Error}
|
* @throws {Error}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_throwErrorAuth(message) {
|
_throwErrorAuth(message: string) {
|
||||||
this.logger.error(message);
|
this.logger.error(message);
|
||||||
throw new Error(message);
|
throw new Error(message);
|
||||||
}
|
}
|
||||||
|
@ -282,7 +310,7 @@ class ProxyStorage {
|
||||||
* @param {string} token
|
* @param {string} token
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_setHeaderAuthorization(headers, type, token) {
|
_setHeaderAuthorization(headers: any, type: string, token: string) {
|
||||||
if (type !== 'bearer' && type !== 'basic') {
|
if (type !== 'bearer' && type !== 'basic') {
|
||||||
this._throwErrorAuth(`Auth type '${type}' not allowed`);
|
this._throwErrorAuth(`Auth type '${type}' not allowed`);
|
||||||
}
|
}
|
||||||
|
@ -310,7 +338,7 @@ class ProxyStorage {
|
||||||
* @param {Object} headers
|
* @param {Object} headers
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_overrideWithUplinkConfigHeaders(headers) {
|
_overrideWithUplinkConfigHeaders(headers: any) {
|
||||||
// add/override headers specified in the config
|
// add/override headers specified in the config
|
||||||
for (let key in this.config.headers) {
|
for (let key in this.config.headers) {
|
||||||
if (Object.prototype.hasOwnProperty.call(this.config.headers, key)) {
|
if (Object.prototype.hasOwnProperty.call(this.config.headers, key)) {
|
||||||
|
@ -320,12 +348,14 @@ class ProxyStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether can fetch from the provided URL.
|
* Determine whether can fetch from the provided URL
|
||||||
* @param {*} url
|
* @param {*} url
|
||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
isUplinkValid(url) {
|
isUplinkValid(url: string) {
|
||||||
|
// $FlowFixMe
|
||||||
url = URL.parse(url);
|
url = URL.parse(url);
|
||||||
|
// $FlowFixMe
|
||||||
return url.protocol === this.url.protocol && url.host === this.url.host && url.path.indexOf(this.url.path) === 0;
|
return url.protocol === this.url.protocol && url.host === this.url.host && url.path.indexOf(this.url.path) === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +365,7 @@ class ProxyStorage {
|
||||||
* @param {*} options request options, eg: eTag.
|
* @param {*} options request options, eg: eTag.
|
||||||
* @param {*} callback
|
* @param {*} callback
|
||||||
*/
|
*/
|
||||||
getRemoteMetadata(name, options, callback) {
|
getRemoteMetadata(name: string, options: any, callback: Callback) {
|
||||||
const headers = {};
|
const headers = {};
|
||||||
if (_.isNil(options.etag) === false) {
|
if (_.isNil(options.etag) === false) {
|
||||||
headers['If-None-Match'] = options.etag;
|
headers['If-None-Match'] = options.etag;
|
||||||
|
@ -355,7 +385,9 @@ class ProxyStorage {
|
||||||
return callback( ErrorCode.get404('package doesn\'t exist on uplink'));
|
return callback( ErrorCode.get404('package doesn\'t exist on uplink'));
|
||||||
}
|
}
|
||||||
if (!(res.statusCode >= 200 && res.statusCode < 300)) {
|
if (!(res.statusCode >= 200 && res.statusCode < 300)) {
|
||||||
|
// $FlowFixMe
|
||||||
const error = createError(`bad status code: ${res.statusCode}`);
|
const error = createError(`bad status code: ${res.statusCode}`);
|
||||||
|
// $FlowFixMe
|
||||||
error.remoteStatus = res.statusCode;
|
error.remoteStatus = res.statusCode;
|
||||||
return callback(error);
|
return callback(error);
|
||||||
}
|
}
|
||||||
|
@ -368,7 +400,7 @@ class ProxyStorage {
|
||||||
* @param {String} url
|
* @param {String} url
|
||||||
* @return {Stream}
|
* @return {Stream}
|
||||||
*/
|
*/
|
||||||
fetchTarball(url) {
|
fetchTarball(url: string) {
|
||||||
const stream = new ReadTarball({});
|
const stream = new ReadTarball({});
|
||||||
let current_length = 0;
|
let current_length = 0;
|
||||||
let expected_length;
|
let expected_length;
|
||||||
|
@ -382,11 +414,12 @@ class ProxyStorage {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
readStream.on('response', function(res) {
|
readStream.on('response', function(res: any) {
|
||||||
if (res.statusCode === 404) {
|
if (res.statusCode === 404) {
|
||||||
return stream.emit('error', ErrorCode.get404('file doesn\'t exist on uplink'));
|
return stream.emit('error', ErrorCode.get404('file doesn\'t exist on uplink'));
|
||||||
}
|
}
|
||||||
if (!(res.statusCode >= 200 && res.statusCode < 300)) {
|
if (!(res.statusCode >= 200 && res.statusCode < 300)) {
|
||||||
|
// $FlowFixMe
|
||||||
return stream.emit('error', createError('bad uplink status code: ' + res.statusCode));
|
return stream.emit('error', createError('bad uplink status code: ' + res.statusCode));
|
||||||
}
|
}
|
||||||
if (res.headers['content-length']) {
|
if (res.headers['content-length']) {
|
||||||
|
@ -408,6 +441,7 @@ class ProxyStorage {
|
||||||
current_length += data.length;
|
current_length += data.length;
|
||||||
}
|
}
|
||||||
if (expected_length && current_length != expected_length) {
|
if (expected_length && current_length != expected_length) {
|
||||||
|
// $FlowFixMe
|
||||||
stream.emit('error', createError('content length mismatch'));
|
stream.emit('error', createError('content length mismatch'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -419,9 +453,9 @@ class ProxyStorage {
|
||||||
* @param {*} options request options
|
* @param {*} options request options
|
||||||
* @return {Stream}
|
* @return {Stream}
|
||||||
*/
|
*/
|
||||||
search(options) {
|
search(options: any) {
|
||||||
const transformStream = new Stream.PassThrough({objectMode: true});
|
const transformStream: IUploadTarball = new Stream.PassThrough({objectMode: true});
|
||||||
const requestStream = this.request({
|
const requestStream: IUploadTarball = this.request({
|
||||||
uri: options.req.url,
|
uri: options.req.url,
|
||||||
req: options.req,
|
req: options.req,
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -437,6 +471,7 @@ class ProxyStorage {
|
||||||
|
|
||||||
requestStream.on('response', (res) => {
|
requestStream.on('response', (res) => {
|
||||||
if (!String(res.statusCode).match(/^2\d\d$/)) {
|
if (!String(res.statusCode).match(/^2\d\d$/)) {
|
||||||
|
// $FlowFixMe
|
||||||
return transformStream.emit('error', createError(`bad status code ${res.statusCode} from uplink`));
|
return transformStream.emit('error', createError(`bad status code ${res.statusCode} from uplink`));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,7 +506,7 @@ class ProxyStorage {
|
||||||
* @param {*} req the http request
|
* @param {*} req the http request
|
||||||
* @param {*} headers the request headers
|
* @param {*} headers the request headers
|
||||||
*/
|
*/
|
||||||
_addProxyHeaders(req, headers) {
|
_addProxyHeaders(req: any, headers: any) {
|
||||||
if (req) {
|
if (req) {
|
||||||
// Only submit X-Forwarded-For field if we don't have a proxy selected
|
// Only submit X-Forwarded-For field if we don't have a proxy selected
|
||||||
// in the config file.
|
// in the config file.
|
||||||
|
@ -502,7 +537,7 @@ class ProxyStorage {
|
||||||
* @param {*} alive
|
* @param {*} alive
|
||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
_statusCheck(alive) {
|
_statusCheck(alive?: boolean) {
|
||||||
if (arguments.length === 0) {
|
if (arguments.length === 0) {
|
||||||
return this._ifRequestFailure() === false;
|
return this._ifRequestFailure() === false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -541,9 +576,9 @@ class ProxyStorage {
|
||||||
* @param {*} mainconfig
|
* @param {*} mainconfig
|
||||||
* @param {*} isHTTPS
|
* @param {*} isHTTPS
|
||||||
*/
|
*/
|
||||||
_setupProxy(hostname, config, mainconfig, isHTTPS) {
|
_setupProxy(hostname: string, config: UpLinkConf, mainconfig: Config, isHTTPS: boolean) {
|
||||||
let noProxyList;
|
let noProxyList;
|
||||||
let proxy_key = isHTTPS ? 'https_proxy' : 'http_proxy';
|
let proxy_key: string = isHTTPS ? 'https_proxy' : 'http_proxy';
|
||||||
|
|
||||||
// get http_proxy and no_proxy configs
|
// get http_proxy and no_proxy configs
|
||||||
if (proxy_key in config) {
|
if (proxy_key in config) {
|
||||||
|
@ -552,6 +587,7 @@ class ProxyStorage {
|
||||||
this.proxy = mainconfig[proxy_key];
|
this.proxy = mainconfig[proxy_key];
|
||||||
}
|
}
|
||||||
if ('no_proxy' in config) {
|
if ('no_proxy' in config) {
|
||||||
|
// $FlowFixMe
|
||||||
noProxyList = config.no_proxy;
|
noProxyList = config.no_proxy;
|
||||||
} else if ('no_proxy' in mainconfig) {
|
} else if ('no_proxy' in mainconfig) {
|
||||||
noProxyList = mainconfig.no_proxy;
|
noProxyList = mainconfig.no_proxy;
|
||||||
|
@ -561,17 +597,22 @@ class ProxyStorage {
|
||||||
if (hostname[0] !== '.') {
|
if (hostname[0] !== '.') {
|
||||||
hostname = '.' + hostname;
|
hostname = '.' + hostname;
|
||||||
}
|
}
|
||||||
|
// $FlowFixMe
|
||||||
if (_.isString(noProxyList) && noProxyList.length) {
|
if (_.isString(noProxyList) && noProxyList.length) {
|
||||||
|
// $FlowFixMe
|
||||||
noProxyList = noProxyList.split(',');
|
noProxyList = noProxyList.split(',');
|
||||||
}
|
}
|
||||||
if (_.isArray(noProxyList)) {
|
if (_.isArray(noProxyList)) {
|
||||||
|
// $FlowFixMe
|
||||||
for (let i = 0; i < noProxyList.length; i++) {
|
for (let i = 0; i < noProxyList.length; i++) {
|
||||||
|
// $FlowFixMe
|
||||||
let noProxyItem = noProxyList[i];
|
let noProxyItem = noProxyList[i];
|
||||||
if (noProxyItem[0] !== '.') noProxyItem = '.' + noProxyItem;
|
if (noProxyItem[0] !== '.') noProxyItem = '.' + noProxyItem;
|
||||||
if (hostname.lastIndexOf(noProxyItem) === hostname.length - noProxyItem.length) {
|
if (hostname.lastIndexOf(noProxyItem) === hostname.length - noProxyItem.length) {
|
||||||
if (this.proxy) {
|
if (this.proxy) {
|
||||||
this.logger.debug({url: this.url.href, rule: noProxyItem},
|
this.logger.debug({url: this.url.href, rule: noProxyItem},
|
||||||
'not using proxy for @{url}, excluded by @{rule} rule');
|
'not using proxy for @{url}, excluded by @{rule} rule');
|
||||||
|
// $FlowFixMe
|
||||||
this.proxy = false;
|
this.proxy = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import assert from 'assert';
|
|
||||||
|
|
||||||
export default function(server, express) {
|
export default function(server, express) {
|
||||||
|
|
||||||
describe('test for unexpected client hangs', () => {
|
describe('test for unexpected client hangs', () => {
|
||||||
let on_tarball;
|
let handleResponseTarball;
|
||||||
|
|
||||||
beforeAll(function() {
|
beforeAll(function() {
|
||||||
express.get('/testexp-racycrash', function(request, response) {
|
express.get('/testexp-racycrash', function(request, response) {
|
||||||
|
@ -23,16 +21,17 @@ export default function(server, express) {
|
||||||
});
|
});
|
||||||
|
|
||||||
express.get('/testexp-racycrash/-/test.tar.gz', function(request, response) {
|
express.get('/testexp-racycrash/-/test.tar.gz', function(request, response) {
|
||||||
on_tarball(response);
|
handleResponseTarball(response);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not crash on error if client disconnects', callback => {
|
test('should not crash on error if client disconnects', callback => {
|
||||||
on_tarball = function(res) {
|
handleResponseTarball = function(res) {
|
||||||
res.header('content-length', 1e6);
|
res.header('content-length', 1e6);
|
||||||
res.write('test test test\n');
|
res.write('test test test');
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
res.write('test test test\n');
|
res.write('-');
|
||||||
|
// destroy the connection
|
||||||
res.socket.destroy();
|
res.socket.destroy();
|
||||||
cb();
|
cb();
|
||||||
}, 200);
|
}, 200);
|
||||||
|
@ -40,7 +39,7 @@ export default function(server, express) {
|
||||||
|
|
||||||
server.request({uri: '/testexp-racycrash/-/test.tar.gz'})
|
server.request({uri: '/testexp-racycrash/-/test.tar.gz'})
|
||||||
.then(function(body) {
|
.then(function(body) {
|
||||||
assert.equal(body, 'test test test\n');
|
expect(body).toEqual('test test test');
|
||||||
});
|
});
|
||||||
|
|
||||||
function cb() {
|
function cb() {
|
||||||
|
@ -54,7 +53,7 @@ export default function(server, express) {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not store tarball', () => {
|
test('should not store tarball', () => {
|
||||||
on_tarball = function(res) {
|
handleResponseTarball = function(res) {
|
||||||
res.socket.destroy();
|
res.socket.destroy();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ describe('UpStorge', () => {
|
||||||
const uplinkDefault = {
|
const uplinkDefault = {
|
||||||
url: 'https://registry.npmjs.org/'
|
url: 'https://registry.npmjs.org/'
|
||||||
};
|
};
|
||||||
let generateProxy = (config = uplinkDefault) => {
|
let generateProxy = (config: UpLinkConf = uplinkDefault) => {
|
||||||
const appConfig: Config = new AppConfig(configExample);
|
const appConfig: Config = new AppConfig(configExample);
|
||||||
|
|
||||||
return new ProxyStorage(config, appConfig);
|
return new ProxyStorage(config, appConfig);
|
||||||
|
|
BIN
yarn.lock
BIN
yarn.lock
Binary file not shown.
Loading…
Reference in a new issue