mirror of
https://github.com/verdaccio/verdaccio.git
synced 2025-02-17 23:45:29 -05:00
test: add some unit test for local-storage
This commit is contained in:
parent
724e372246
commit
d0e97cf076
9 changed files with 530 additions and 189 deletions
|
@ -16,7 +16,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/file-locking": "^0.0.5",
|
||||
"@verdaccio/local-storage": "^0.0.11",
|
||||
"@verdaccio/local-storage": "^0.0.14",
|
||||
"@verdaccio/streams": "^0.0.2",
|
||||
"@verdaccio/types": "^0.0.8",
|
||||
"JSONStream": "^1.1.1",
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
/* eslint prefer-rest-params: 0 */
|
||||
|
||||
import assert from 'assert';
|
||||
import Crypto from 'crypto';
|
||||
import assert from 'assert';
|
||||
import fs from 'fs';
|
||||
import Path from 'path';
|
||||
import Stream from 'stream';
|
||||
|
@ -12,6 +12,10 @@ import _ from 'lodash';
|
|||
// $FlowFixMe
|
||||
import async from 'async';
|
||||
import * as Utils from './utils';
|
||||
import {
|
||||
generatePackageTemplate, normalizePackage, generateRevision, cleanUpReadme,
|
||||
fileExist, noSuchFile, resourceNotAvailable, DEFAULT_REVISION, pkgFileName,
|
||||
} from './storage-utils';
|
||||
|
||||
import LocalDatabase from '@verdaccio/local-storage';
|
||||
import {UploadTarball, ReadTarball} from '@verdaccio/streams';
|
||||
|
@ -30,33 +34,12 @@ import type {
|
|||
ILocalData,
|
||||
} from '@verdaccio/local-storage';
|
||||
|
||||
const pkgFileName = 'package.json';
|
||||
const fileExist = 'EEXISTS';
|
||||
const noSuchFile = 'ENOENT';
|
||||
const resourceNotAvailable = 'EAGAIN';
|
||||
|
||||
const generatePackageTemplate = function(name: string): Package {
|
||||
return {
|
||||
// standard things
|
||||
'name': name,
|
||||
'versions': {},
|
||||
'dist-tags': {},
|
||||
'time': {},
|
||||
'_distfiles': {},
|
||||
'_attachments': {},
|
||||
'_uplinks': {},
|
||||
};
|
||||
};
|
||||
|
||||
const DEFAULT_REVISION: string = `0-0000000000000000`;
|
||||
|
||||
/**
|
||||
* Implements Storage interface (same for storage.js, local-storage.js, up-storage.js).
|
||||
*/
|
||||
class Storage implements IStorage {
|
||||
class LocalStorage implements IStorage {
|
||||
|
||||
config: Config;
|
||||
utils: Utils;
|
||||
localData: ILocalData;
|
||||
logger: Logger;
|
||||
|
||||
|
@ -66,7 +49,7 @@ class Storage implements IStorage {
|
|||
this.config = config;
|
||||
}
|
||||
|
||||
addPackage(name: string, info: Package, callback: Callback) {
|
||||
addPackage(name: string, pkg: Package, callback: Callback) {
|
||||
const storage: ILocalFS = this._getLocalStorage(name);
|
||||
|
||||
if (_.isNil(storage)) {
|
||||
|
@ -74,15 +57,15 @@ class Storage implements IStorage {
|
|||
}
|
||||
|
||||
storage.createJSON(pkgFileName, generatePackageTemplate(name), (err) => {
|
||||
if (err && err.code === fileExist) {
|
||||
if (_.isNull(err) === false && err.code === fileExist) {
|
||||
return callback( Utils.ErrorCode.get409());
|
||||
}
|
||||
|
||||
const latest = Utils.getLatestVersion(info);
|
||||
|
||||
if (_.isNil(latest) === false && info.versions[latest]) {
|
||||
return callback(null, info.versions[latest]);
|
||||
const latest = Utils.getLatestVersion(pkg);
|
||||
if (_.isNil(latest) === false && pkg.versions[latest]) {
|
||||
return callback(null, pkg.versions[latest]);
|
||||
}
|
||||
|
||||
return callback();
|
||||
});
|
||||
}
|
||||
|
@ -95,6 +78,7 @@ class Storage implements IStorage {
|
|||
*/
|
||||
removePackage(name: string, callback: Callback) {
|
||||
let storage: ILocalFS = this._getLocalStorage(name);
|
||||
|
||||
if (_.isNil(storage)) {
|
||||
return callback( Utils.ErrorCode.get404());
|
||||
}
|
||||
|
@ -107,9 +91,10 @@ class Storage implements IStorage {
|
|||
return callback(err);
|
||||
}
|
||||
}
|
||||
this._normalizePackage(data);
|
||||
|
||||
let removeFailed = this.localData.remove(name);
|
||||
data = normalizePackage(data);
|
||||
|
||||
const removeFailed = this.localData.remove(name);
|
||||
|
||||
if (removeFailed) {
|
||||
// This will happen when database is locked
|
||||
|
@ -127,26 +112,6 @@ class Storage implements IStorage {
|
|||
});
|
||||
}
|
||||
|
||||
_deleteAttachments(storage: ILocalFS, attachments: string[], callback: Callback): void {
|
||||
const unlinkNext = function(cb) {
|
||||
if (_.isEmpty(attachments)) {
|
||||
return cb();
|
||||
}
|
||||
|
||||
const attachment = attachments.shift();
|
||||
storage.deleteJSON(attachment, function() {
|
||||
unlinkNext(cb);
|
||||
});
|
||||
};
|
||||
|
||||
unlinkNext(function() {
|
||||
// try to unlink the directory, but ignore errors because it can fail
|
||||
storage.removePackage(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronize remote package info with the local one
|
||||
* @param {*} name
|
||||
|
@ -162,11 +127,11 @@ class Storage implements IStorage {
|
|||
let change = false;
|
||||
for (let versionId in packageInfo.versions) {
|
||||
if (_.isNil(packageLocalJson.versions[versionId])) {
|
||||
const version = packageInfo.versions[versionId];
|
||||
let version = packageInfo.versions[versionId];
|
||||
|
||||
// we don't keep readmes for package versions,
|
||||
// only one readme per package
|
||||
delete version.readme;
|
||||
version = cleanUpReadme(version);
|
||||
|
||||
change = true;
|
||||
packageLocalJson.versions[versionId] = version;
|
||||
|
@ -192,12 +157,14 @@ class Storage implements IStorage {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let tag in packageInfo['dist-tags']) {
|
||||
if (!packageLocalJson['dist-tags'][tag] || packageLocalJson['dist-tags'][tag] !== packageInfo['dist-tags'][tag]) {
|
||||
change = true;
|
||||
packageLocalJson['dist-tags'][tag] = packageInfo['dist-tags'][tag];
|
||||
}
|
||||
}
|
||||
|
||||
for (let up in packageInfo._uplinks) {
|
||||
if (Object.prototype.hasOwnProperty.call(packageInfo._uplinks, up)) {
|
||||
const need_change = !Utils.is_object(packageLocalJson._uplinks[up])
|
||||
|
@ -232,27 +199,6 @@ class Storage implements IStorage {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the dist file remains as the same protocol
|
||||
* @param {Object} hash metadata
|
||||
* @param {String} upLinkKey registry key
|
||||
* @private
|
||||
*/
|
||||
_updateUplinkToRemoteProtocol(hash: DistFile, upLinkKey: string): void {
|
||||
// if we got this information from a known registry,
|
||||
// use the same protocol for the tarball
|
||||
//
|
||||
// see https://github.com/rlidwka/sinopia/issues/166
|
||||
const tarballUrl: any = UrlNode.parse(hash.url);
|
||||
const uplinkUrl: any = UrlNode.parse(this.config.uplinks[upLinkKey].url);
|
||||
|
||||
if (uplinkUrl.host === tarballUrl.host) {
|
||||
tarballUrl.protocol = uplinkUrl.protocol;
|
||||
hash.registry = upLinkKey;
|
||||
hash.url = UrlNode.format(tarballUrl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new version to a previous local package.
|
||||
* @param {*} name
|
||||
|
@ -269,7 +215,7 @@ class Storage implements IStorage {
|
|||
data.readme = metadata.readme;
|
||||
|
||||
// TODO: lodash remove
|
||||
delete metadata.readme;
|
||||
metadata = cleanUpReadme(metadata);
|
||||
|
||||
if (data.versions[version] != null) {
|
||||
return cb( Utils.ErrorCode.get409() );
|
||||
|
@ -344,6 +290,7 @@ class Storage implements IStorage {
|
|||
_getVersionNotFound() {
|
||||
return Utils.ErrorCode.get404('this version doesn\'t exist');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return file no available
|
||||
* @return {String}
|
||||
|
@ -357,32 +304,36 @@ class Storage implements IStorage {
|
|||
* Update the package metadata, tags and attachments (tarballs).
|
||||
* Note: Currently supports unpublishing only.
|
||||
* @param {*} name
|
||||
* @param {*} metadata
|
||||
* @param {*} pkg
|
||||
* @param {*} revision
|
||||
* @param {*} callback
|
||||
* @return {Function}
|
||||
*/
|
||||
changePackage(name: string,
|
||||
metadata: Package,
|
||||
pkg: Package,
|
||||
revision?: string, callback: Callback) {
|
||||
if (!Utils.is_object(metadata.versions) || !Utils.is_object(metadata['dist-tags'])) {
|
||||
if (!Utils.is_object(pkg.versions) || !Utils.is_object(pkg['dist-tags'])) {
|
||||
return callback( Utils.ErrorCode.get422());
|
||||
}
|
||||
|
||||
this._updatePackage(name, (data, cb) => {
|
||||
for (let ver in data.versions) {
|
||||
if (_.isNil(metadata.versions[ver])) {
|
||||
this.logger.info( {name: name, version: ver},
|
||||
'unpublishing @{name}@@{version}');
|
||||
delete data.versions[ver];
|
||||
for (let file in data._attachments) {
|
||||
if (data._attachments[file].version === ver) {
|
||||
delete data._attachments[file].version;
|
||||
this._updatePackage(name, (jsonData, cb) => {
|
||||
for (let ver in jsonData.versions) {
|
||||
|
||||
if (_.isNil(pkg.versions[ver])) {
|
||||
this.logger.info( {name: name, version: ver}, 'unpublishing @{name}@@{version}');
|
||||
|
||||
delete jsonData.versions[ver];
|
||||
|
||||
for (let file in jsonData._attachments) {
|
||||
if (jsonData._attachments[file].version === ver) {
|
||||
delete jsonData._attachments[file].version;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
data['dist-tags'] = metadata['dist-tags'];
|
||||
|
||||
jsonData['dist-tags'] = pkg['dist-tags'];
|
||||
cb();
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
|
@ -391,7 +342,6 @@ class Storage implements IStorage {
|
|||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a tarball.
|
||||
* @param {*} name
|
||||
|
@ -697,8 +647,8 @@ class Storage implements IStorage {
|
|||
return callback(this._internalError(err, pkgFileName, 'error reading'));
|
||||
}
|
||||
}
|
||||
this._normalizePackage(result);
|
||||
callback(err, result);
|
||||
|
||||
callback(err, normalizePackage(result));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -772,28 +722,6 @@ class Storage implements IStorage {
|
|||
}, on_end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise package properties, tags, revision id.
|
||||
* @param {Object} pkg package reference.
|
||||
*/
|
||||
_normalizePackage(pkg: Package) {
|
||||
const pkgProperties = ['versions', 'dist-tags', '_distfiles', '_attachments', '_uplinks', 'time'];
|
||||
|
||||
pkgProperties.forEach((key) => {
|
||||
if (_.isNil(Utils.is_object(pkg[key]))) {
|
||||
pkg[key] = {};
|
||||
}
|
||||
});
|
||||
|
||||
if (_.isString(pkg._rev) === false) {
|
||||
pkg._rev = DEFAULT_REVISION;
|
||||
}
|
||||
// normalize dist-tags
|
||||
Utils.normalize_dist_tags(pkg);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve either a previous created local package or a boilerplate.
|
||||
* @param {*} name
|
||||
|
@ -810,23 +738,18 @@ class Storage implements IStorage {
|
|||
// TODO: race condition
|
||||
if (_.isNil(err) === false) {
|
||||
if (err.code === noSuchFile) {
|
||||
// if package doesn't exist, we create it here
|
||||
data = generatePackageTemplate(name);
|
||||
} else {
|
||||
return callback(this._internalError(err, pkgFileName, 'error reading'));
|
||||
}
|
||||
}
|
||||
|
||||
this._normalizePackage(data);
|
||||
callback(null, data);
|
||||
callback(null, normalizePackage(data));
|
||||
});
|
||||
}
|
||||
|
||||
_createNewPackage(name: string, callback: Callback): Callback {
|
||||
const data = generatePackageTemplate(name);
|
||||
|
||||
this._normalizePackage(data);
|
||||
return callback(null, data);
|
||||
return callback(null, normalizePackage(generatePackageTemplate(name)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -837,8 +760,7 @@ class Storage implements IStorage {
|
|||
* @return {Object} Error instance
|
||||
*/
|
||||
_internalError(err: string, file: string, message: string) {
|
||||
this.logger.error( {err: err, file: file},
|
||||
message + ' @{file}: @{!err.message}' );
|
||||
this.logger.error( {err: err, file: file}, `${message} @{file}: @{!err.message}` );
|
||||
|
||||
return Utils.ErrorCode.get500();
|
||||
}
|
||||
|
@ -854,29 +776,29 @@ class Storage implements IStorage {
|
|||
6. callback(err?)
|
||||
* @param {*} name package name
|
||||
* @param {*} updateFn function(package, cb) - update function
|
||||
* @param {*} _callback callback that gets invoked after it's all updated
|
||||
* @param {*} callback callback that gets invoked after it's all updated
|
||||
* @return {Function}
|
||||
*/
|
||||
_updatePackage(name: string, updateFn: Callback, _callback: Callback) {
|
||||
_updatePackage(name: string, updateFn: Callback, callback: Callback) {
|
||||
const storage: ILocalFS = this._getLocalStorage(name);
|
||||
|
||||
if (!storage) {
|
||||
return _callback( Utils.ErrorCode.get404() );
|
||||
return callback( Utils.ErrorCode.get404() );
|
||||
}
|
||||
|
||||
storage.lockAndReadJSON(pkgFileName, (err, json) => {
|
||||
let locked = false;
|
||||
|
||||
// callback that cleans up lock first
|
||||
const callback = function(err: Error) {
|
||||
const lockCallback = function(err: Error) {
|
||||
let _args = arguments;
|
||||
if (locked) {
|
||||
storage.unlockJSON(pkgFileName, function() {
|
||||
// ignore any error from the unlock
|
||||
_callback.apply(err, _args);
|
||||
callback.apply(err, _args);
|
||||
});
|
||||
} else {
|
||||
_callback(..._args);
|
||||
callback(..._args);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -886,20 +808,21 @@ class Storage implements IStorage {
|
|||
|
||||
if (err) {
|
||||
if (err.code === resourceNotAvailable) {
|
||||
return callback( Utils.ErrorCode.get503() );
|
||||
return lockCallback( Utils.ErrorCode.get503() );
|
||||
} else if (err.code === noSuchFile) {
|
||||
return callback( Utils.ErrorCode.get404() );
|
||||
return lockCallback( Utils.ErrorCode.get404() );
|
||||
} else {
|
||||
return callback(err);
|
||||
return lockCallback(err);
|
||||
}
|
||||
}
|
||||
|
||||
this._normalizePackage(json);
|
||||
json = normalizePackage(json);
|
||||
|
||||
updateFn(json, (err) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return lockCallback(err);
|
||||
}
|
||||
this._writePackage(name, json, callback);
|
||||
this._writePackage(name, json, lockCallback);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -913,11 +836,11 @@ class Storage implements IStorage {
|
|||
*/
|
||||
_writePackage(name: string, json: Package, callback: Callback) {
|
||||
// calculate revision a la couchdb
|
||||
if (typeof(json._rev) !== 'string') {
|
||||
if (_.isString(json._rev) === false) {
|
||||
json._rev = DEFAULT_REVISION;
|
||||
}
|
||||
|
||||
json._rev = this._generateRevision(json._rev);
|
||||
json._rev = generateRevision(json._rev);
|
||||
|
||||
let storage: ILocalFS = this._getLocalStorage(name);
|
||||
if (_.isNil(storage)) {
|
||||
|
@ -926,11 +849,46 @@ class Storage implements IStorage {
|
|||
storage.writeJSON(pkgFileName, json, callback);
|
||||
}
|
||||
|
||||
_generateRevision(rev: string): string {
|
||||
const _rev = rev.split('-');
|
||||
_deleteAttachments(storage: ILocalFS, attachments: string[], callback: Callback): void {
|
||||
const unlinkNext = function(cb) {
|
||||
if (_.isEmpty(attachments)) {
|
||||
return cb();
|
||||
}
|
||||
|
||||
return ((+_rev[0] || 0) + 1) + '-' + Crypto.pseudoRandomBytes(8).toString('hex');
|
||||
const attachment = attachments.shift();
|
||||
storage.deleteJSON(attachment, function() {
|
||||
unlinkNext(cb);
|
||||
});
|
||||
};
|
||||
|
||||
unlinkNext(function() {
|
||||
// try to unlink the directory, but ignore errors because it can fail
|
||||
storage.removePackage(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the dist file remains as the same protocol
|
||||
* @param {Object} hash metadata
|
||||
* @param {String} upLinkKey registry key
|
||||
* @private
|
||||
*/
|
||||
_updateUplinkToRemoteProtocol(hash: DistFile, upLinkKey: string): void {
|
||||
// if we got this information from a known registry,
|
||||
// use the same protocol for the tarball
|
||||
//
|
||||
// see https://github.com/rlidwka/sinopia/issues/166
|
||||
const tarballUrl: any = UrlNode.parse(hash.url);
|
||||
const uplinkUrl: any = UrlNode.parse(this.config.uplinks[upLinkKey].url);
|
||||
|
||||
if (uplinkUrl.host === tarballUrl.host) {
|
||||
tarballUrl.protocol = uplinkUrl.protocol;
|
||||
hash.registry = upLinkKey;
|
||||
hash.url = UrlNode.format(tarballUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Storage;
|
||||
module.exports = LocalStorage;
|
||||
|
|
84
src/lib/storage-utils.js
Normal file
84
src/lib/storage-utils.js
Normal file
|
@ -0,0 +1,84 @@
|
|||
// @flow
|
||||
|
||||
import _ from 'lodash';
|
||||
import crypto from 'crypto';
|
||||
import * as Utils from './utils';
|
||||
|
||||
import type {
|
||||
Package, Version
|
||||
} from '@verdaccio/types';
|
||||
|
||||
const pkgFileName = 'package.json';
|
||||
const fileExist: string = 'EEXISTS';
|
||||
const noSuchFile: string = 'ENOENT';
|
||||
const resourceNotAvailable: string = 'EAGAIN';
|
||||
const DEFAULT_REVISION: string = `0-0000000000000000`;
|
||||
|
||||
const generatePackageTemplate = function(name: string): Package {
|
||||
return {
|
||||
// standard things
|
||||
'name': name,
|
||||
'versions': {},
|
||||
'dist-tags': {},
|
||||
'time': {},
|
||||
'_distfiles': {},
|
||||
'_attachments': {},
|
||||
'_uplinks': {},
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Normalise package properties, tags, revision id.
|
||||
* @param {Object} pkg package reference.
|
||||
*/
|
||||
function normalizePackage(pkg: Package) {
|
||||
const pkgProperties = [
|
||||
'versions',
|
||||
'dist-tags',
|
||||
'_distfiles',
|
||||
'_attachments',
|
||||
'_uplinks',
|
||||
'time'];
|
||||
|
||||
pkgProperties.forEach((key) => {
|
||||
if (_.isNil(Utils.is_object(pkg[key]))) {
|
||||
pkg[key] = {};
|
||||
}
|
||||
});
|
||||
|
||||
if (_.isString(pkg._rev) === false) {
|
||||
pkg._rev = DEFAULT_REVISION;
|
||||
}
|
||||
|
||||
// normalize dist-tags
|
||||
Utils.normalize_dist_tags(pkg);
|
||||
|
||||
return pkg;
|
||||
}
|
||||
|
||||
function generateRevision(rev: string): string {
|
||||
const _rev = rev.split('-');
|
||||
|
||||
return ((+_rev[0] || 0) + 1) + '-' + crypto.pseudoRandomBytes(8).toString('hex');
|
||||
}
|
||||
|
||||
function cleanUpReadme(version: Version): Version {
|
||||
if(_.isNil(version) === false) {
|
||||
delete version.readme;
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
export {
|
||||
generatePackageTemplate,
|
||||
normalizePackage,
|
||||
generateRevision,
|
||||
cleanUpReadme,
|
||||
DEFAULT_REVISION,
|
||||
fileExist,
|
||||
noSuchFile,
|
||||
pkgFileName,
|
||||
resourceNotAvailable,
|
||||
};
|
||||
|
179
test/unit/local-storage.spec.js
Normal file
179
test/unit/local-storage.spec.js
Normal file
|
@ -0,0 +1,179 @@
|
|||
// @flow
|
||||
import rimRaf from 'rimraf';
|
||||
import LocalStorage from '../../src/lib/local-storage';
|
||||
import AppConfig from '../../src/lib/config';
|
||||
import configExample from './partials/config';
|
||||
import Logger, {setup} from '../../src/lib/logger';
|
||||
import {readFile} from '../functional/lib/test.utils';
|
||||
|
||||
const readMetadata = (fileName: string = 'metadata') => readFile(`../../unit/partials/${fileName}`);
|
||||
|
||||
import type {IStorage} from '@verdaccio/types';
|
||||
|
||||
setup([]);
|
||||
|
||||
describe('LocalStorage', () => {
|
||||
let storage: IStorage;
|
||||
const pkgName: string = 'npm_test';
|
||||
|
||||
beforeAll(function () {
|
||||
storage = new LocalStorage(new AppConfig(configExample), Logger.logger);
|
||||
});
|
||||
|
||||
test('should be defined', () => {
|
||||
expect(storage).toBeDefined();
|
||||
});
|
||||
|
||||
describe('LocalStorage::addPackage', () => {
|
||||
test('should add a package', (done) => {
|
||||
const metadata = JSON.parse(readMetadata());
|
||||
const pkgStoragePath: string = storage._getLocalStorage(pkgName);
|
||||
rimRaf(pkgStoragePath.path, (err) => {
|
||||
expect(err).toBeNull();
|
||||
storage.addPackage(pkgName, metadata, (err, data) => {
|
||||
expect(data.version).toMatch(/1.0.0/);
|
||||
expect(data.dist.tarball).toMatch(/npm_test-1.0.0.tgz/);
|
||||
expect(data.name).toMatch(pkgName);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('should fails on add a package', (done) => {
|
||||
const metadata = JSON.parse(readMetadata());
|
||||
|
||||
storage.addPackage(pkgName, metadata, (err, data) => {
|
||||
expect(err).not.toBeNull();
|
||||
expect(err.statusCode).toEqual(409);
|
||||
// expect(err.status).toMatch(/this package is already present/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('LocalStorage::addVersion', () => {
|
||||
test('should add new version without tag', (done) => {
|
||||
const metadata = JSON.parse(readMetadata('metadata-add-version'));
|
||||
|
||||
storage.addVersion(pkgName, '1.0.1', metadata, null, (err, data) => {
|
||||
expect(err).toBeNull();
|
||||
expect(data).toBeUndefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should fails on add a duplicated version without tag', (done) => {
|
||||
const metadata = JSON.parse(readMetadata('metadata-add-version'));
|
||||
|
||||
storage.addVersion(pkgName, '1.0.1', metadata, null, (err, data) => {
|
||||
expect(err).not.toBeNull();
|
||||
expect(err.statusCode).toEqual(409);
|
||||
expect(err.message).toMatch(/this package is already present/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should add new second version without tag', (done) => {
|
||||
const metadata = JSON.parse(readMetadata('metadata-add-version'));
|
||||
|
||||
storage.addVersion(pkgName, '1.0.2', metadata, 'beta', (err, data) => {
|
||||
expect(err).toBeNull();
|
||||
expect(data).toBeUndefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('LocalStorage::changePackage', () => {
|
||||
test('should unpublish a version', (done) => {
|
||||
const metadata = JSON.parse(readMetadata('metadata-unpublish'));
|
||||
const rev: string = metadata['_rev'];
|
||||
|
||||
storage.changePackage(pkgName, metadata, rev, (err) => {
|
||||
expect(err).toBeUndefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('LocalStorage::addTarball', () => {
|
||||
test('should add a new tarball', (done) => {
|
||||
const tarballData = JSON.parse(readMetadata('addTarball'));
|
||||
const stream = storage.addTarball(pkgName, `${pkgName}-add-tarball-1.0.4.tgz`);
|
||||
stream.on('error', function(err) {
|
||||
expect(err).toBeNull();
|
||||
done();
|
||||
});
|
||||
stream.on('success', function() {
|
||||
done();
|
||||
});
|
||||
|
||||
stream.end(new Buffer(tarballData.data, 'base64'));
|
||||
stream.done();
|
||||
});
|
||||
|
||||
test('should fails on add a new tarball on missing package', (done) => {
|
||||
const tarballData = JSON.parse(readMetadata('addTarball'));
|
||||
const stream = storage.addTarball('unexsiting-package', `${pkgName}-add-tarball-1.0.4.tgz`);
|
||||
stream.on('error', function(err) {
|
||||
expect(err).not.toBeNull();
|
||||
expect(err.statusCode).toEqual(404);
|
||||
expect(err.message).toMatch(/no such package available/);
|
||||
done();
|
||||
});
|
||||
|
||||
stream.on('success', function() {
|
||||
done();
|
||||
});
|
||||
|
||||
stream.end(new Buffer(tarballData.data, 'base64'));
|
||||
stream.done();
|
||||
});
|
||||
|
||||
test('should fails on use invalid package name on add a new tarball', (done) => {
|
||||
const stream = storage.addTarball(pkgName, `${pkgName}-fails-add-tarball-1.0.4.tgz`);
|
||||
stream.on('error', function(err) {
|
||||
expect(err).not.toBeNull();
|
||||
expect(err.statusCode).toEqual(422);
|
||||
expect(err.message).toMatch(/refusing to accept zero-length file/);
|
||||
done();
|
||||
});
|
||||
|
||||
stream.done();
|
||||
});
|
||||
|
||||
test('should fails on abort on add a new tarball', (done) => {
|
||||
const stream = storage.addTarball('package.json', `${pkgName}-fails-add-tarball-1.0.4.tgz`);
|
||||
stream.abort();
|
||||
stream.on('error', function(err) {
|
||||
expect(err).not.toBeNull();
|
||||
expect(err.statusCode).toEqual(403);
|
||||
expect(err.message).toMatch(/can't use this filename/);
|
||||
done();
|
||||
});
|
||||
|
||||
stream.done();
|
||||
});
|
||||
});
|
||||
|
||||
// describe('LocalStorage::removePackage', () => {
|
||||
// test('should remove completely package', (done) => {
|
||||
// storage.removePackage(pkgName, (err, data) => {
|
||||
// expect(err).toBeNull();
|
||||
// expect(data).toBeUndefined();
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// test('should fails with package not found', (done) => {
|
||||
// const pkgName: string = 'npm_test_fake';
|
||||
// storage.removePackage(pkgName, (err, data) => {
|
||||
// expect(err).not.toBeNull();
|
||||
// expect(err.message).toMatch(/no such package available/);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
});
|
5
test/unit/partials/addTarball
Normal file
5
test/unit/partials/addTarball
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"content_type": "application\/octet-stream",
|
||||
"data": "H4sIAAAAAAAAE+2SPU\/DMBCGM+dXnDx0QsHOR5G6AgMzI4XKcg7qltiW7ZYi1P+OHRcqoWxEQkh5lpPf93x3\/jBcbPkLXpoUi43TKhsZSum8rmFIj9RNCRmrStY0ZVXNq4wy1lwxyOjYgwyxc57bMMpv66SzwHf8J3zkAETxDskiRNOtPDq\/2mjPyUW09mid1Cq6rKBFndQWnbDS+JOTxI7LfiVVi4fwkb5SDQZBCYkuuLFfUGOXmPvEirqgJIjHU\/b+5seGZKR+AxVQrDUsya212i5AaYgGOINCPktslwRmM8CD9MDObbb4\/qZtG8s9PPYK3\/m1tufDvEqByvW3cnd\/TfJj\/tcvNTExMTEun6rWVXoACAAA",
|
||||
"length": 279
|
||||
}
|
50
test/unit/partials/metadata
Normal file
50
test/unit/partials/metadata
Normal file
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"_id": "npm_test",
|
||||
"name": "npm_test",
|
||||
"description": "",
|
||||
"dist-tags": {
|
||||
"latest": "1.0.0"
|
||||
},
|
||||
"versions": {
|
||||
"1.0.0": {
|
||||
"name": "npm_test",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"test": "^1.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [
|
||||
|
||||
],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"readme": "ERROR: No README data found!",
|
||||
"_id": "npm_test@1.0.0",
|
||||
"_npmVersion": "5.5.1",
|
||||
"_nodeVersion": "9.3.0",
|
||||
"_npmUser": {
|
||||
|
||||
},
|
||||
"dist": {
|
||||
"integrity": "sha512-tfzM1OFjWwg2d2Wke\/DV6icjeTZUVOZYLkbf8wmONRSAgMovL\/F+zyI24OhTtWyOXd1Kbj2YUMBvLpmpAjv8zg==",
|
||||
"shasum": "3e4e6bd5097b295e520b947c9be3259a9509a673",
|
||||
"tarball": "http:\/\/localhost:4873\/npm_test\/-\/npm_test-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"_attachments": {
|
||||
"npm_test-1.0.0.tgz": {
|
||||
"content_type": "application\/octet-stream",
|
||||
"data": "H4sIAAAAAAAAE+2ST08CMRDFOe+nmPTAyawt7ELCVT149ihqmu4gI9I2bUGM4bvbbhGM4eYmxmR\/l6bvtW+mf6xUK\/mMlzaP5Ys3etAxnPNJVcE5PVHV0RPjkairsZiK0YALUU+mMOBdN3KOjQ\/SxVZ+m5PPAsfxn\/BRADAt18hmwDxpY0k+BfSBXSRni86T0ckUJS95Vhv0ypENByeLa0ntjHSDu\/iPvpZajIJWhD66qRwcC6Xlj6KsYm7U94cN2+sfe7KRS34LabuMCaiWBubsxjnjZqANJAO8RUULwmbOYDgE3FEAcSqzwvc345oUd\/\/QKnITlsadzvNKCrVv7+X27ooV++Kv36qnp6enSz4B8bhKUwAIAAA=",
|
||||
"length": 281
|
||||
}
|
||||
}
|
||||
}
|
32
test/unit/partials/metadata-add-version
Normal file
32
test/unit/partials/metadata-add-version
Normal file
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "npm_test",
|
||||
"version": "1.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"test": "^1.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [
|
||||
|
||||
],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"readme": "ERROR: No README data found!",
|
||||
"_id": "npm_test@1.0.1",
|
||||
"_npmVersion": "5.5.1",
|
||||
"_nodeVersion": "9.3.0",
|
||||
"_npmUser": {
|
||||
|
||||
},
|
||||
"dist": {
|
||||
"integrity": "sha512-zVEqt1JUCOPsash9q4wMkJEDPD+QCx95TRhQII+JnoS31uBUKoZxhzvvUJCcLVy2CQG4QdwXARU7dYWPnrwhGg==",
|
||||
"shasum": "b7088c30970489637f8b4e6795e8cf2b699d7569",
|
||||
"tarball": "http:\/\/localhost:4873\/npm_test\/-\/npm_test-1.0.1.tgz"
|
||||
}
|
||||
}
|
46
test/unit/partials/metadata-unpublish
Normal file
46
test/unit/partials/metadata-unpublish
Normal file
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"name": "npm_test",
|
||||
"versions": {
|
||||
"1.0.1": {
|
||||
"name": "npm_test",
|
||||
"version": "1.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"test": "^1.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [
|
||||
|
||||
],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"_id": "npm_test@1.0.0",
|
||||
"_npmVersion": "5.5.1",
|
||||
"_nodeVersion": "9.3.0",
|
||||
"_npmUser": {
|
||||
|
||||
},
|
||||
"dist": {
|
||||
"integrity": "sha512-tfzM1OFjWwg2d2Wke\/DV6icjeTZUVOZYLkbf8wmONRSAgMovL\/F+zyI24OhTtWyOXd1Kbj2YUMBvLpmpAjv8zg==",
|
||||
"shasum": "3e4e6bd5097b295e520b947c9be3259a9509a673",
|
||||
"tarball": "http:\/\/localhost:4873\/npm_test\/-\/npm_test-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dist-tags": {
|
||||
"latest": "1.0.1"
|
||||
},
|
||||
"time": {
|
||||
"modified": "2017-12-17T14:15:10.760Z",
|
||||
"created": "2017-12-17T11:39:33.140Z",
|
||||
"1.0.1": "2017-12-17T11:39:33.140Z"
|
||||
},
|
||||
"_rev": "9-1c8dae9336a8dc70",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
83
yarn.lock
83
yarn.lock
|
@ -56,8 +56,8 @@
|
|||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@types/node@*":
|
||||
version "8.0.57"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-8.0.57.tgz#e5d8b4dc112763e35cfc51988f4f38da3c486d99"
|
||||
version "8.5.1"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-8.5.1.tgz#4ec3020bcdfe2abffeef9ba3fbf26fca097514b5"
|
||||
|
||||
"@verdaccio/file-locking@^0.0.5":
|
||||
version "0.0.5"
|
||||
|
@ -66,14 +66,14 @@
|
|||
lockfile "1.0.3"
|
||||
lodash "4.17.4"
|
||||
|
||||
"@verdaccio/local-storage@^0.0.11":
|
||||
version "0.0.11"
|
||||
resolved "https://registry.npmjs.org/@verdaccio/local-storage/-/local-storage-0.0.11.tgz#3a121f6f08a7cfed1d778c5db26d095542c74cad"
|
||||
"@verdaccio/local-storage@^0.0.14":
|
||||
version "0.0.14"
|
||||
resolved "https://registry.npmjs.org/@verdaccio/local-storage/-/local-storage-0.0.14.tgz#bd9d7084a33336111448801fd266f2dbc8bbe6dc"
|
||||
dependencies:
|
||||
"@verdaccio/file-locking" "^0.0.5"
|
||||
"@verdaccio/streams" "^0.0.2"
|
||||
async "2.5.0"
|
||||
http-errors "1.4.0"
|
||||
http-errors "1.6.2"
|
||||
lodash "4.17.4"
|
||||
mkdirp "0.5.1"
|
||||
|
||||
|
@ -149,8 +149,8 @@ ajv@^4.9.1:
|
|||
json-stable-stringify "^1.0.1"
|
||||
|
||||
ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5, ajv@^5.2.0, ajv@^5.2.3:
|
||||
version "5.5.1"
|
||||
resolved "https://registry.npmjs.org/ajv/-/ajv-5.5.1.tgz#b38bb8876d9e86bee994956a04e721e88b248eb2"
|
||||
version "5.5.2"
|
||||
resolved "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
|
||||
dependencies:
|
||||
co "^4.6.0"
|
||||
fast-deep-equal "^1.0.0"
|
||||
|
@ -376,11 +376,11 @@ autoprefixer@^6.3.1:
|
|||
postcss-value-parser "^3.2.3"
|
||||
|
||||
autoprefixer@^7.1.2:
|
||||
version "7.2.2"
|
||||
resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.2.tgz#082293b964be00602efacc59aa4aa7df5158bb6e"
|
||||
version "7.2.3"
|
||||
resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.3.tgz#c2841e38b7940c2d0a9bbffd72c75f33637854f8"
|
||||
dependencies:
|
||||
browserslist "^2.10.0"
|
||||
caniuse-lite "^1.0.30000780"
|
||||
caniuse-lite "^1.0.30000783"
|
||||
normalize-range "^0.1.2"
|
||||
num2fraction "^1.2.2"
|
||||
postcss "^6.0.14"
|
||||
|
@ -1456,12 +1456,12 @@ caniuse-api@^1.5.2:
|
|||
lodash.uniq "^4.5.0"
|
||||
|
||||
caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
|
||||
version "1.0.30000780"
|
||||
resolved "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000780.tgz#8d1977561d00ff0f0ed2b6b66140328ab4504c0a"
|
||||
version "1.0.30000783"
|
||||
resolved "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000783.tgz#16b30d47266a4f515cc69ae0316b670c9603cdbe"
|
||||
|
||||
caniuse-lite@^1.0.30000780:
|
||||
version "1.0.30000780"
|
||||
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000780.tgz#1f9095f2efd4940e0ba6c5992ab7a9b64cc35ba4"
|
||||
caniuse-lite@^1.0.30000780, caniuse-lite@^1.0.30000783:
|
||||
version "1.0.30000783"
|
||||
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000783.tgz#9b5499fb1b503d2345d12aa6b8612852f4276ffd"
|
||||
|
||||
caseless@~0.11.0:
|
||||
version "0.11.0"
|
||||
|
@ -1937,8 +1937,8 @@ core-js@^1.0.0:
|
|||
resolved "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
|
||||
|
||||
core-js@^2.4.0, core-js@^2.5.0:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b"
|
||||
version "2.5.3"
|
||||
resolved "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e"
|
||||
|
||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
|
@ -2524,10 +2524,10 @@ enzyme@^3.2.0:
|
|||
rst-selector-parser "^2.2.3"
|
||||
|
||||
errno@^0.1.3, errno@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d"
|
||||
version "0.1.6"
|
||||
resolved "https://registry.npmjs.org/errno/-/errno-0.1.6.tgz#c386ce8a6283f14fc09563b71560908c9bf53026"
|
||||
dependencies:
|
||||
prr "~0.0.0"
|
||||
prr "~1.0.1"
|
||||
|
||||
error-ex@^1.2.0, error-ex@^1.3.1:
|
||||
version "1.3.1"
|
||||
|
@ -2699,8 +2699,8 @@ eslint-plugin-import@2.8.0:
|
|||
read-pkg-up "^2.0.0"
|
||||
|
||||
eslint-plugin-jest@^21.2.0:
|
||||
version "21.4.2"
|
||||
resolved "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-21.4.2.tgz#0e8ec03687259169cef46656827a0a0715e8a8d4"
|
||||
version "21.5.0"
|
||||
resolved "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-21.5.0.tgz#c7a3bd2ee9d1c832b4e31dec89f6ad93e08d4853"
|
||||
|
||||
eslint-plugin-react@7.5.1:
|
||||
version "7.5.1"
|
||||
|
@ -3660,13 +3660,6 @@ http-deceiver@^1.2.7:
|
|||
version "1.2.7"
|
||||
resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
|
||||
|
||||
http-errors@1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.4.0.tgz#6c0242dea6b3df7afda153c71089b31c6e82aabf"
|
||||
dependencies:
|
||||
inherits "2.0.1"
|
||||
statuses ">= 1.2.1 < 2"
|
||||
|
||||
http-errors@1.6.2, http-errors@^1.4.0, http-errors@~1.6.2:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736"
|
||||
|
@ -4032,10 +4025,8 @@ is-regexp@^1.0.0:
|
|||
resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
|
||||
|
||||
is-resolvable@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62"
|
||||
dependencies:
|
||||
tryit "^1.0.1"
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz#acca1cd36dbe44b974b924321555a70ba03b1cf4"
|
||||
|
||||
is-stream@^1.0.1, is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
|
@ -5030,8 +5021,8 @@ modify-values@^1.0.0:
|
|||
resolved "https://registry.npmjs.org/modify-values/-/modify-values-1.0.0.tgz#e2b6cdeb9ce19f99317a53722f3dbf5df5eaaab2"
|
||||
|
||||
moment@^2.10.6:
|
||||
version "2.19.3"
|
||||
resolved "https://registry.npmjs.org/moment/-/moment-2.19.3.tgz#bdb99d270d6d7fda78cc0fbace855e27fe7da69f"
|
||||
version "2.20.0"
|
||||
resolved "https://registry.npmjs.org/moment/-/moment-2.20.0.tgz#53396358994dd3a551e966a66af715ecb6c30ad0"
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
|
@ -6042,9 +6033,9 @@ proxy-addr@~2.0.2:
|
|||
forwarded "~0.1.2"
|
||||
ipaddr.js "1.5.2"
|
||||
|
||||
prr@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a"
|
||||
prr@~1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
|
||||
|
||||
pseudomap@^1.0.2:
|
||||
version "1.0.2"
|
||||
|
@ -7024,7 +7015,7 @@ state-toggle@^1.0.0:
|
|||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.0.tgz#d20f9a616bb4f0c3b98b91922d25b640aa2bc425"
|
||||
|
||||
"statuses@>= 1.2.1 < 2", "statuses@>= 1.3.1 < 2":
|
||||
"statuses@>= 1.3.1 < 2":
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087"
|
||||
|
||||
|
@ -7424,10 +7415,6 @@ trough@^1.0.0:
|
|||
dependencies:
|
||||
glob "^6.0.4"
|
||||
|
||||
tryit@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb"
|
||||
|
||||
tty-browserify@0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
|
||||
|
@ -7468,8 +7455,8 @@ ua-parser-js@^0.7.9:
|
|||
resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
|
||||
|
||||
uglify-js@3.2.x:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.2.1.tgz#d6427fd45a25fefc5d196689c0c772a6915e10fe"
|
||||
version "3.2.2"
|
||||
resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.2.2.tgz#870e4b34ed733d179284f9998efd3293f7fd73f6"
|
||||
dependencies:
|
||||
commander "~2.12.1"
|
||||
source-map "~0.6.1"
|
||||
|
@ -7563,8 +7550,8 @@ unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1:
|
|||
resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.1.tgz#3ccbdc53679eed6ecf3777dd7f5e3229c1b6aa3c"
|
||||
|
||||
unist-util-visit@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.2.0.tgz#9dc78d1f95cd242e865f7f93f327d3296bb9a718"
|
||||
version "1.3.0"
|
||||
resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.3.0.tgz#41ca7c82981fd1ce6c762aac397fc24e35711444"
|
||||
dependencies:
|
||||
unist-util-is "^2.1.1"
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue