diff --git a/.eslintignore b/.eslintignore
index 7840d0e66..2cea1dff6 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -14,3 +14,4 @@ Dockerfile
*.scss
*.png
*.jpg
+test/unit/partials/
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7fbaebbd9..49160c30c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -66,6 +66,42 @@ All notable changes to this project will be documented in this file. See [standa
* replaced lunr by lunr-mutable ([#915](https://github.com/verdaccio/verdaccio/issues/915)) ([1602840](https://github.com/verdaccio/verdaccio/commit/1602840))
* verdaccio update notification on CLI ([#988](https://github.com/verdaccio/verdaccio/issues/988)) ([#998](https://github.com/verdaccio/verdaccio/issues/998)) ([bc04703](https://github.com/verdaccio/verdaccio/commit/bc04703))
+
+## [3.11.1](https://github.com/verdaccio/verdaccio/compare/v3.11.0...v3.11.1) (2019-01-31)
+
+
+### Bug Fixes
+
+* don’t make change if `time` fields match ([#1167](https://github.com/verdaccio/verdaccio/issues/1167)) ([e62ef8d](https://github.com/verdaccio/verdaccio/commit/e62ef8d))
+* don’t packages that have no uplinks after reading ([#1204](https://github.com/verdaccio/verdaccio/issues/1204)) ([95686be](https://github.com/verdaccio/verdaccio/commit/95686be))
+
+
+
+
+# [3.11.0](https://github.com/verdaccio/verdaccio/compare/v3.10.2...v3.11.0) (2019-01-27)
+
+
+### Features
+
+* introduce server keepAliveTimeout into config files ([a359055](https://github.com/verdaccio/verdaccio/commit/a359055))
+
+
+
+
+## [3.10.2](https://github.com/verdaccio/verdaccio/compare/v3.10.1...v3.10.2) (2019-01-22)
+
+
+### Bug Fixes
+
+* add logic to catch clause ([#1183](https://github.com/verdaccio/verdaccio/issues/1183)) ([056d396](https://github.com/verdaccio/verdaccio/commit/056d396))
+* adds _id to normalise metadata ([#1194](https://github.com/verdaccio/verdaccio/issues/1194)) ([e2fa581](https://github.com/verdaccio/verdaccio/commit/e2fa581))
+* remove some unneeded checks ([#1182](https://github.com/verdaccio/verdaccio/issues/1182)) ([ab56d75](https://github.com/verdaccio/verdaccio/commit/ab56d75))
+* remove unused object ([#1185](https://github.com/verdaccio/verdaccio/issues/1185)) ([e9b3907](https://github.com/verdaccio/verdaccio/commit/e9b3907))
+* remove unused parameters from processBody method invocation ([#1184](https://github.com/verdaccio/verdaccio/issues/1184)) ([064f7cf](https://github.com/verdaccio/verdaccio/commit/064f7cf))
+* remove use of comma separator ([#1186](https://github.com/verdaccio/verdaccio/issues/1186)) ([f20fefa](https://github.com/verdaccio/verdaccio/commit/f20fefa))
+* remove useless assignment to local variable emailCopy ([#1181](https://github.com/verdaccio/verdaccio/issues/1181)) ([13b8347](https://github.com/verdaccio/verdaccio/commit/13b8347))
+
+
## [3.10.1](https://github.com/verdaccio/verdaccio/compare/v3.10.0...v3.10.1) (2018-12-20)
@@ -1165,4 +1201,4 @@ in [#108](https://github.com/verdaccio/verdaccio/pull/108)
## 22 May 2013, version 0.0.0
- first commits
-
\ No newline at end of file
+
diff --git a/conf/default.yaml b/conf/default.yaml
index 782a03f6c..4b721a700 100644
--- a/conf/default.yaml
+++ b/conf/default.yaml
@@ -61,6 +61,12 @@ packages:
# if package is not available locally, proxy requests to 'npmjs' registry
proxy: npmjs
+# You can specify HTTP/1.1 server keep alive timeout in seconds for incomming connections.
+# A value of 0 makes the http server behave similarly to Node.js versions prior to 8.0.0, which did not have a keep-alive timeout.
+# WORKAROUND: Through given configuration you can workaround following issue https://github.com/verdaccio/verdaccio/issues/301. Set to 0 in case 60 is not enought.
+server:
+ keepAliveTimeout: 60
+
# To use `npm audit` uncomment the following section
middlewares:
audit:
diff --git a/src/lib/bootstrap.js b/src/lib/bootstrap.js
index 31b5dfe34..24d23bc26 100644
--- a/src/lib/bootstrap.js
+++ b/src/lib/bootstrap.js
@@ -48,7 +48,10 @@ function startVerdaccio(config: any, cliListen: string, configPath: string, pkgV
// http
webServer = http.createServer(app);
}
-
+ if (config.server && config.server.keepAliveTimeout) {
+ // $FlowFixMe library definition for node is not up to date (doesn't contain recent 8.0 changes)
+ webServer.keepAliveTimeout = config.server.keepAliveTimeout;
+ }
unlinkAddressPath(addr);
callback(webServer, addr, pkgName, pkgVersion);
diff --git a/src/lib/local-storage.js b/src/lib/local-storage.js
index 276bb4e36..e3d4c467f 100644
--- a/src/lib/local-storage.js
+++ b/src/lib/local-storage.js
@@ -169,7 +169,7 @@ class LocalStorage implements IStorage {
}
}
- if ('time' in packageInfo) {
+ if ('time' in packageInfo && !_.isEqual(packageLocalJson.time, packageInfo.time)) {
packageLocalJson.time = packageInfo.time;
change = true;
}
diff --git a/src/lib/storage-utils.js b/src/lib/storage-utils.js
index 5db683b1a..3676078e1 100644
--- a/src/lib/storage-utils.js
+++ b/src/lib/storage-utils.js
@@ -45,6 +45,10 @@ export function normalizePackage(pkg: Package) {
pkg._rev = STORAGE.DEFAULT_REVISION;
}
+ if (_.isString(pkg._id) === false) {
+ pkg._id = pkg.name;
+ }
+
// normalize dist-tags
normalizeDistTags(pkg);
@@ -93,7 +97,7 @@ export function normalizeContributors(contributors: Array): Array {
const pkgNameScoped = `@scope/${pkgName}-scope`;
const tarballName: string = `${pkgName}-add-tarball-1.0.4.tgz`;
const tarballName2: string = `${pkgName}-add-tarball-1.0.5.tgz`;
+
+ const getStorage = (LocalStorageClass = LocalStorage) => {
+ const config: Config = new AppConfig(configExample);
+ config.self_path = path.join('../partials/store');
+ return new LocalStorageClass(config, Logger.logger);
+ }
+
const getPackageMetadataFromStore = (pkgName: string) => {
return new Promise((resolve) => {
storage.getPackageMetadata(pkgName, (err, data ) => {
@@ -76,10 +83,7 @@ describe('LocalStorage', () => {
};
beforeAll(() => {
- const config: Config = new AppConfig(configExample);
- config.self_path = path.join('../partials/store');
-
- storage = new LocalStorage(config, Logger.logger);
+ storage = getStorage();
});
test('should be defined', () => {
@@ -249,16 +253,27 @@ describe('LocalStorage', () => {
});
describe('LocalStorage::updateVersions', () => {
- test('should update versions from external source', async (done) => {
- const metadata = JSON.parse(readMetadata('metadata-update-versions-tags'));
- const pkgName = 'add-update-versions-test-1';
- const version = '1.0.2';
- await addPackageToStore(pkgName, generatePackageTemplate(pkgName));
- await addNewVersion(pkgName, '1.0.1');
- await addNewVersion(pkgName, version);
+ const metadata = JSON.parse(readMetadata('metadata-update-versions-tags'));
+ const pkgName = 'add-update-versions-test-1';
+ const version = '1.0.2';
+ let _storage;
+ beforeEach(done => {
+ class MockLocalStorage extends LocalStorage {}
+ // $FlowFixMe
+ MockLocalStorage.prototype._writePackage = jest.fn(LocalStorage.prototype._writePackage)
+ _storage = getStorage(MockLocalStorage);
+ rimRaf(path.join(configExample.storage, pkgName), async () => {
+ await addPackageToStore(pkgName, generatePackageTemplate(pkgName));
+ await addNewVersion(pkgName, '1.0.1');
+ await addNewVersion(pkgName, version);
+ done();
+ })
+ })
- storage.updateVersions(pkgName, metadata, (err, data) => {
+ test('should update versions from external source', async (done) => {
+ _storage.updateVersions(pkgName, metadata, (err, data) => {
expect(err).toBeNull();
+ expect(_storage._writePackage).toHaveBeenCalledTimes(1);
expect(data.versions['1.0.1']).toBeDefined();
expect(data.versions[version]).toBeDefined();
expect(data.versions['1.0.4']).toBeDefined();
@@ -273,6 +288,17 @@ describe('LocalStorage', () => {
done();
});
});
+
+ test('should not update if the metadata match', done => {
+ _storage.updateVersions(pkgName, metadata, e => {
+ expect(e).toBeNull()
+ _storage.updateVersions(pkgName, metadata, err => {
+ expect(err).toBeNull()
+ expect(_storage._writePackage).toHaveBeenCalledTimes(1);
+ done()
+ })
+ })
+ })
});
describe('LocalStorage::changePackage', () => {
diff --git a/test/unit/api/store.spec.js b/test/unit/api/store.spec.js
index 02c884e0f..9ea50ff48 100644
--- a/test/unit/api/store.spec.js
+++ b/test/unit/api/store.spec.js
@@ -2,6 +2,8 @@
import _ from 'lodash';
import path from 'path';
+import fs from 'fs';
+import rimraf from 'rimraf';
// $FlowFixMe
import configExample from '../partials/config/index';
import AppConfig from '../../../src/lib/config';
@@ -16,12 +18,12 @@ import {DOMAIN_SERVERS} from '../../functional/config.functional';
setup(configExample.logs);
+const storagePath = path.join(__dirname, '../partials/store/test-storage-store.spec');
const mockServerPort: number = 55548;
const generateStorage = async function(port = mockServerPort, configDefault = configExample) {
const storageConfig = _.clone(configDefault);
- const storage = path.join(__dirname, '../partials/store/test-storage-store.spec');
storageConfig.self_path = __dirname;
- storageConfig.storage = storage;
+ storageConfig.storage = storagePath;
storageConfig.uplinks = {
npmjs: {
url: `http://${DOMAIN_SERVERS}:${port}`
@@ -37,8 +39,11 @@ const generateStorage = async function(port = mockServerPort, configDefault = co
describe('StorageTest', () => {
let mockRegistry;
- beforeAll(async () => {
- mockRegistry = await mockServer(mockServerPort).init();
+ beforeAll(done => {
+ rimraf(storagePath, async () => {
+ mockRegistry = await mockServer(mockServerPort).init();
+ done()
+ })
});
afterAll(function(done) {
@@ -90,5 +95,21 @@ describe('StorageTest', () => {
done();
});
});
+
+ test('should not touch if the package exists and has no uplinks', async (done) => {
+ const storage: IStorageHandler = await generateStorage();
+ const metadataSource = path.join(__dirname, '../partials/metadata');
+ const metadataPath = path.join(storagePath, 'npm_test/package.json');
+ fs.mkdirSync(path.join(storagePath, 'npm_test'));
+ fs.writeFileSync(metadataPath, fs.readFileSync(metadataSource));
+ const metadata = JSON.parse(fs.readFileSync(metadataPath).toString());
+ // $FlowFixMe
+ storage.localStorage.updateVersions = jest.fn(storage.localStorage.updateVersions);
+ storage._syncUplinksMetadata('npm_test', metadata, {}, (err) => {
+ expect(err).toBeNull();
+ expect(storage.localStorage.updateVersions).not.toHaveBeenCalled();
+ done();
+ });
+ });
});
});
diff --git a/test/unit/partials/metadata-update-versions-tags b/test/unit/partials/metadata-update-versions-tags
index 4679888fc..9a10d432b 100644
--- a/test/unit/partials/metadata-update-versions-tags
+++ b/test/unit/partials/metadata-update-versions-tags
@@ -82,7 +82,13 @@
"beta": "1.0.2",
"next": "1.0.4"
},
- "time": {},
+ "time": {
+ "modified": "2019-01-29T03:20:04.000Z",
+ "created": "2019-01-29T03:20:00.000Z",
+ "1.0.1": "2019-01-29T03:20:01.000Z",
+ "1.0.2": "2019-01-29T03:20:02.000Z",
+ "1.0.4": "2019-01-29T03:20:04.000Z"
+ },
"_distfiles": {},
"_attachments": {},
"_uplinks": {},