1
0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-11-08 23:25:51 +01:00

chore: fix unpublish issues, fix unit test

This commit is contained in:
Juan Picado @jotadeveloper 2019-02-24 23:20:25 +01:00
parent cab3596843
commit 9e17d2bc27
No known key found for this signature in database
GPG Key ID: 18AC54485952D158
30 changed files with 291 additions and 366 deletions

1
.gitignore vendored

@ -6,6 +6,7 @@ build/
### Test
test/unit/partials/store/test-*-storage/*
test/unit/partials/store/storage_default_storage/*
.verdaccio-db.json
.sinopia-db.json

@ -86,10 +86,10 @@
"husky": "0.15.0-rc.8",
"identity-obj-proxy": "3.0.0",
"in-publish": "2.0.0",
"jest": "23.6.0",
"jest-environment-jsdom": "23.4.0",
"jest-environment-jsdom-global": "1.1.0",
"jest-environment-node": "23.4.0",
"jest": "24.1.0",
"jest-environment-jsdom": "24.0.0",
"jest-environment-jsdom-global": "1.1.1",
"jest-environment-node": "24.0.0",
"lint-staged": "7.3.0",
"localstorage-memory": "1.0.2",
"mini-css-extract-plugin": "0.4.3",

@ -24,7 +24,7 @@ export default function publish(router: Router, auth: IAuth, storage: IStorageHa
router.put('/:package/:_rev?/:revision?', can('publish'), media(mime.getType('json')), expectJson, publishPackage(storage, config));
// un-publishing an entire package
router.delete('/:package/-rev/*', can('unpublish'), can('publish'), unPublishPackage(storage));
router.delete('/:package/-rev/*', can('unpublish'), unPublishPackage(storage));
// removing a tarball
router.delete('/:package/-/:filename/-rev/:revision', can('unpublish'), can('publish'), removeTarball(storage));

@ -106,7 +106,7 @@ const defineAPI = function(config: IConfig, storage: IStorageHandler) {
export default (async function(configHash: any) {
setup(configHash.logs);
const config: IConfig = new AppConfig(configHash);
const config: IConfig = new AppConfig(_.cloneDeep(configHash));
const storage: IStorageHandler = new Storage(config);
// waits until init calls have been initialized
await storage.init(config);

@ -60,6 +60,19 @@ export function allow_action(action: string) {
};
}
export function handleSpecialUnpublish() {
return function(user: RemoteUser, pkg: Package, callback: Callback) {
const action: string = 'unpublish';
const hasSupport: boolean = _.isNil(pkg[action]) === false ? pkg[action] : false;
if (hasSupport === false) {
return callback(null, undefined);
}
return allow_action(action)(user, pkg, callback);
};
}
export function getDefaultPlugins() {
return {
authenticate(user: string, password: string, cb: Callback) {
@ -72,7 +85,7 @@ export function getDefaultPlugins() {
allow_access: allow_action('access'),
allow_publish: allow_action('publish'),
allow_unpublish: allow_action('unpublish'),
allow_unpublish: handleSpecialUnpublish(),
};
}

@ -191,32 +191,32 @@ class Auth implements IAuth {
}
allow_unpublish({ packageName, packageVersion }: AuthPluginPackage, user: string, callback: Callback) {
const plugins = this.plugins.slice(0);
const self = this;
// $FlowFixMe
const pkg = Object.assign({ name: packageName, version: packageVersion }, getMatchedPackagesSpec(packageName, this.config.packages));
this.logger.trace({ packageName }, 'allow unpublish for @{packageName}');
(function next() {
const plugin = plugins.shift();
for (const plugin of this.plugins) {
if (_.isFunction(plugin.allow_unpublish) === false) {
return next();
continue;
} else {
plugin.allow_unpublish(user, pkg, (err, ok: boolean) => {
if (err) {
this.logger.trace({ packageName }, 'forbidden publish for @{packageName}, it will fallback on unpublish permissions');
return callback(err);
}
if (_.isNil(ok) === true) {
this.logger.trace({ packageName }, 'we bypass unpublish for @{packageName}, publish will handle the access');
return this.allow_publish(...arguments);
}
if (ok) {
this.logger.trace({ packageName }, 'allowed unpublish for @{packageName}');
return callback(null, ok);
}
});
}
plugin.allow_unpublish(user, pkg, (err, ok: boolean) => {
if (err) {
self.logger.trace({ packageName }, 'forbidden unpublish for @{packageName}');
return callback(err);
}
if (ok) {
self.logger.trace({ packageName }, 'allowed unpublish for @{packageName}');
return callback(null, ok);
}
next(); // cb(null, false) causes next plugin to roll
});
})();
}
}
/**

@ -123,8 +123,9 @@ export function normalisePackageAccess(packages: PackageList): PackageList {
delete normalizedPkgs[pkg].allow_publish;
normalizedPkgs[pkg].proxy = normalizeUserList(packages[pkg].proxy_access, packages[pkg].proxy);
delete normalizedPkgs[pkg].proxy_access;
// if unpublish is not defined, we set to false to fallback in publish access
// $FlowFixMe
normalizedPkgs[pkg].unpublish = normalizeUserList([], packages[pkg].unpublish);
normalizedPkgs[pkg].unpublish = _.isUndefined(packages[pkg].unpublish) ? false : normalizeUserList([], packages[pkg].unpublish);
}
}

@ -16,7 +16,7 @@ exports[`Publish endpoints - publish package should add a new package 1`] = `
],
"results": Array [
Object {
"isThrow": false,
"type": "return",
"value": undefined,
},
],
@ -40,7 +40,7 @@ exports[`Publish endpoints - publish package should change the existing package
],
"results": Array [
Object {
"isThrow": false,
"type": "return",
"value": undefined,
},
],

@ -14,7 +14,7 @@ exports[`Verdaccio update banner should print major update banner 1`] = `
],
"results": Array [
Object {
"isThrow": false,
"type": "return",
"value": undefined,
},
],
@ -35,7 +35,7 @@ exports[`Verdaccio update banner should print minor update banner 1`] = `
],
"results": Array [
Object {
"isThrow": false,
"type": "return",
"value": undefined,
},
],
@ -56,7 +56,7 @@ exports[`Verdaccio update banner should print patch update banner 1`] = `
],
"results": Array [
Object {
"isThrow": false,
"type": "return",
"value": undefined,
},
],
@ -75,7 +75,7 @@ exports[`Verdaccio update banner when default registry returns with error 1`] =
],
"results": Array [
Object {
"isThrow": false,
"type": "return",
"value": undefined,
},
],

@ -5,7 +5,6 @@ import _ from 'lodash';
import path from 'path';
import rimraf from 'rimraf';
import Config from '../../../src/lib/config';
import endPointAPI from '../../../src/api/index';
import {HEADERS, HTTP_STATUS, HEADER_TYPE} from '../../../src/lib/constants';
@ -27,7 +26,6 @@ const parseConfigurationJWTFile = () => {
const FORBIDDEN_VUE: string = 'authorization required to access package vue';
describe('endpoint user auth JWT unit test', () => {
let config;
let app;
let mockRegistry;
@ -36,21 +34,22 @@ describe('endpoint user auth JWT unit test', () => {
const mockServerPort = 55546;
rimraf(store, async () => {
const confS = parseConfigFile(parseConfigurationJWTFile());
const configForTest = _.clone(confS);
configForTest.storage = store;
configForTest.auth = {
htpasswd: {
file: './test-jwt-storage/.htpasswd'
const configForTest = _.assign({}, _.cloneDeep(confS), {
storage: store,
plinks: {
npmjs: {
url: `http://${DOMAIN_SERVERS}:${mockServerPort}`
}
},
self_path: store,
auth: {
htpasswd: {
file: './test-jwt-storage/.htpasswd'
}
}
};
configForTest.uplinks = {
npmjs: {
url: `http://${DOMAIN_SERVERS}:${mockServerPort}`
}
};
configForTest.self_path = store;
config = new Config(configForTest);
app = await endPointAPI(config);
});
app = await endPointAPI(configForTest);
mockRegistry = await mockServer(mockServerPort).init();
done();
});

@ -5,7 +5,6 @@ import rimraf from 'rimraf';
import { HEADERS, HTTP_STATUS } from '../../../src/lib/constants';
import configDefault from '../partials/config/config_access';
import Config from '../../../src/lib/config';
import endPointAPI from '../../../src/api/index';
import {mockServer} from './mock';
import {DOMAIN_SERVERS} from '../../functional/config.functional';
@ -13,7 +12,6 @@ import {DOMAIN_SERVERS} from '../../functional/config.functional';
require('../../../src/lib/logger').setup([]);
describe('api with no limited access configuration', () => {
let config;
let app;
let mockRegistry;
@ -21,20 +19,21 @@ describe('api with no limited access configuration', () => {
const mockServerPort = 55530;
const store = path.join(__dirname, './partials/store/access-storage');
rimraf(store, async () => {
const configForTest = _.clone(configDefault);
configForTest.auth = {
htpasswd: {
file: './access-storage/htpasswd-access-test'
const configForTest = _.assign({}, _.cloneDeep(configDefault), {
auth: {
htpasswd: {
file: './access-storage/htpasswd-access-test'
}
},
self_path: store,
uplinks: {
npmjs: {
url: `http://${DOMAIN_SERVERS}:${mockServerPort}`
}
}
};
configForTest.self_path = store;
configForTest.uplinks = {
npmjs: {
url: `http://${DOMAIN_SERVERS}:${mockServerPort}`
}
};
config = new Config(configForTest);
app = await endPointAPI(config);
});
app = await endPointAPI(configForTest);
mockRegistry = await mockServer(mockServerPort).init();
done();
});

@ -5,7 +5,6 @@ import _ from 'lodash';
import path from 'path';
import rimraf from 'rimraf';
import Config from '../../../src/lib/config';
import endPointAPI from '../../../src/api/index';
import {mockServer} from './mock';
import {parseConfigFile} from '../../../src/lib/utils';
@ -22,7 +21,6 @@ const parseConfigurationProfile = () => {
describe('endpoint user profile', () => {
let config;
let app;
let mockRegistry;
@ -31,16 +29,16 @@ describe('endpoint user profile', () => {
const mockServerPort = 55544;
rimraf(store, async () => {
const parsedConfig = parseConfigFile(parseConfigurationProfile());
const configForTest = _.clone(parsedConfig);
configForTest.storage = store;
configForTest.auth = {
htpasswd: {
file: './test-profile-storage/.htpasswd'
}
};
configForTest.self_path = store;
config = new Config(configForTest);
app = await endPointAPI(config);
const configForTest = _.assign({}, _.cloneDeep(parsedConfig), {
storage: store,
auth: {
htpasswd: {
file: './test-profile-storage/.htpasswd'
}
},
self_path: store
});
app = await endPointAPI(configForTest);
mockRegistry = await mockServer(mockServerPort).init();
done();
});

@ -5,39 +5,40 @@ import rimraf from 'rimraf';
import configDefault from '../partials/config/index';
import publishMetadata from '../partials/publish-api';
import Config from '../../../src/lib/config';
import endPointAPI from '../../../src/api/index';
import { HEADERS, API_ERROR, HTTP_STATUS, HEADER_TYPE, API_MESSAGE} from '../../../src/lib/constants';
import {HEADERS, API_ERROR, HTTP_STATUS, HEADER_TYPE, API_MESSAGE, TOKEN_BEARER} from '../../../src/lib/constants';
import {mockServer} from './mock';
import {DOMAIN_SERVERS} from '../../functional/config.functional';
import {buildToken} from '../../../src/lib/utils';
require('../../../src/lib/logger').setup([]);
const credentials = { name: 'jota', password: 'secretPass' };
describe('endpoint unit test', () => {
let config;
let app;
let mockRegistry;
beforeAll(function(done) {
const store = path.join(__dirname, '../partials/store/test-storage');
const store = path.join(__dirname, '../store/test-storage-api-spec');
const mockServerPort = 55549;
rimraf(store, async () => {
const configForTest = _.clone(configDefault);
configForTest.auth = {
htpasswd: {
file: './test-storage/.htpasswd'
const configForTest = configDefault({
auth: {
htpasswd: {
file: './test-storage-api-spec/.htpasswd'
}
},
storage: store,
self_path: store,
uplinks: {
npmjs: {
url: `http://${DOMAIN_SERVERS}:${mockServerPort}`
}
}
};
configForTest.uplinks = {
npmjs: {
url: `http://${DOMAIN_SERVERS}:${mockServerPort}`
}
};
configForTest.self_path = store;
config = new Config(configForTest);
app = await endPointAPI(config);
}, 'api.spec.yaml');
app = await endPointAPI(configForTest);
mockRegistry = await mockServer(mockServerPort).init();
done();
});
@ -157,7 +158,7 @@ describe('endpoint unit test', () => {
// we need it here, because token is required
request(app)
.get('/vue')
.set('authorization', `Bearer ${token}`)
.set('authorization', buildToken(TOKEN_BEARER, token))
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(HTTP_STATUS.OK)
.end(function(err, res) {
@ -171,7 +172,7 @@ describe('endpoint unit test', () => {
test('should test fails add a new user with missing name', (done) => {
const credentialsShort = _.clone(credentials);
const credentialsShort = _.cloneDeep(credentials);
delete credentialsShort.name;
request(app)
@ -192,7 +193,7 @@ describe('endpoint unit test', () => {
test('should test fails add a new user with missing password', (done) => {
const credentialsShort = _.clone(credentials);
const credentialsShort = _.cloneDeep(credentials);
delete credentialsShort.password;
request(app)
@ -213,7 +214,7 @@ describe('endpoint unit test', () => {
});
test('should test add a new user with login', (done) => {
const newCredentials = _.clone(credentials);
const newCredentials = _.cloneDeep(credentials);
newCredentials.name = 'jotaNew';
request(app)
@ -248,7 +249,7 @@ describe('endpoint unit test', () => {
test('should test fails add a new user with wrong password', (done) => {
const credentialsShort = _.clone(credentials);
const credentialsShort = _.cloneDeep(credentials);
credentialsShort.password = 'failPassword';
request(app)

@ -1,12 +1,10 @@
import request from 'supertest';
import _ from 'lodash';
import path from 'path';
import rimraf from 'rimraf';
import configDefault from '../partials/config/index';
import publishMetadata from '../partials/publish-api';
import forbiddenPlace from '../partials/forbidden-place';
import Config from '../../../src/lib/config';
import endPointAPI from '../../../src/api/index';
import { HEADERS, API_ERROR, HTTP_STATUS, HEADER_TYPE, DIST_TAGS} from '../../../src/lib/constants';
@ -18,7 +16,6 @@ require('../../../src/lib/logger').setup([]);
const credentials = { name: 'user-web', password: 'secretPass' };
describe('endpoint web unit test', () => {
let config;
let app;
let mockRegistry;
@ -26,21 +23,21 @@ describe('endpoint web unit test', () => {
const store = path.join(__dirname, '../store/test-storage-web');
const mockServerPort = 55544;
rimraf(store, async () => {
const configForTest = _.clone(configDefault);
configForTest.auth = {
htpasswd: {
file: './test-storage-web/.htpasswd'
}
};
configForTest.storage = path.join(__dirname, '../store/test-storage-web');
configForTest.uplinks = {
npmjs: {
url: `http://${DOMAIN_SERVERS}:${mockServerPort}`
}
};
configForTest.self_path = store;
config = new Config(configForTest);
app = await endPointAPI(config);
const configForTest = configDefault({
auth: {
htpasswd: {
file: './test-storage-web/.htpasswd'
}
},
storage: path.join(__dirname, '../store/test-storage-web'),
uplinks: {
npmjs: {
url: `http://${DOMAIN_SERVERS}:${mockServerPort}`
}
},
self_path: store
}, 'api.web.spec.yaml');
app = await endPointAPI(configForTest);
mockRegistry = await mockServer(mockServerPort).init();
done();
});
@ -52,7 +49,7 @@ describe('endpoint web unit test', () => {
});
describe('Registry WebUI endpoints', () => {
beforeAll(async function() {
beforeAll(async () => {
await request(app)
.put('/@scope%2fpk1-test')
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)

@ -22,7 +22,7 @@ import {parseConfigurationFile} from '../__helper';
import type {IAuth, } from '../../../types/index';
import type {Config, Security, RemoteUser} from '@verdaccio/types';
setup(configExample.logs);
setup([]);
describe('Auth utilities', () => {
const parseConfigurationSecurityFile = (name) => {
@ -31,7 +31,7 @@ describe('Auth utilities', () => {
function getConfig(configFileName: string, secret: string) {
const conf = parseConfigFile(parseConfigurationSecurityFile(configFileName));
const secConf= _.merge(configExample, conf);
const secConf= _.merge(configExample(), conf);
secConf.secret = secret;
const config: Config = new AppConfig(secConf);

@ -1,26 +1,31 @@
import _ from 'lodash';
// @flow
import Auth from '../../../src/lib/auth';
// $FlowFixMe
import configExample from '../partials/config/index';
import _configExample from '../partials/config/index';
// $FlowFixMe
import configPlugins from '../partials/config/plugin';
import _configPlugins from '../partials/config/plugin';
import AppConfig from '../../../src/lib/config';
import {setup} from '../../../src/lib/logger';
import type {IAuth} from '../../../types/index';
import type {Config} from '@verdaccio/types';
const authConfig = Object.assign({}, configExample);
// avoid noisy log output
authConfig.logs = [{type: 'stdout', format: 'pretty', level: 'error'}];
setup(configExample.logs);
setup([]);
describe('AuthTest', () => {
let configExample;
let configPlugins;
beforeEach(() => {
configExample = _configExample({
logs: [{type: 'stdout', format: 'pretty', level: 'error'}]
});
configPlugins = _.cloneDeep(_configPlugins);
});
test('should be defined', () => {
const config: Config = new AppConfig(authConfig);
const config: Config = new AppConfig(configExample);
const auth: IAuth = new Auth(config);
expect(auth).toBeDefined();

@ -18,7 +18,7 @@ describe('basic system test', () => {
beforeAll(async function(done) {
app.use(await endPointAPI(config));
app.use(await endPointAPI(config()));
server.listen(0, function() {
port = server.address().port;

@ -27,7 +27,7 @@ describe('startServer via API', () => {
const version = '1.0.0';
const port = '6000';
await startServer(_.clone(config), port, store, version, serverName,
await startServer(config(), port, store, version, serverName,
(webServer, addrs, pkgName, pkgVersion) => {
expect(webServer).toBeDefined();
expect(addrs).toBeDefined();
@ -49,7 +49,7 @@ describe('startServer via API', () => {
const address = 'https://www.domain.com:443';
const realProcess = process;
const conf = _.clone(config);
const conf = config();
conf.https = {};
// save process to catch exist
const exitMock = jest.fn();

@ -2,6 +2,7 @@
import rimRaf from 'rimraf';
import path from 'path';
import LocalStorage from '../../../src/lib/local-storage';
import AppConfig from '../../../src/lib/config';
// $FlowFixMe
@ -27,8 +28,10 @@ describe('LocalStorage', () => {
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');
const config: Config = new AppConfig(configExample({
self_path: path.join('../partials/store')
}));
return new LocalStorageClass(config, Logger.logger);
}
@ -262,7 +265,7 @@ describe('LocalStorage', () => {
// $FlowFixMe
MockLocalStorage.prototype._writePackage = jest.fn(LocalStorage.prototype._writePackage)
_storage = getStorage(MockLocalStorage);
rimRaf(path.join(configExample.storage, pkgName), async () => {
rimRaf(path.join(configExample().storage, pkgName), async () => {
await addPackageToStore(pkgName, generatePackageTemplate(pkgName));
await addNewVersion(pkgName, '1.0.1');
await addNewVersion(pkgName, version);

@ -1,8 +1,7 @@
import Search from '../../../src/lib/search';
import Config from '../../../src/lib/config';
import Storage from '../../../src/lib/storage';
let config_hash = require('../partials/config/index');
import buildConfig from '../partials/config/index';
require('../../../src/lib/logger').setup([]);
@ -33,7 +32,7 @@ let packages = [
describe('search', () => {
beforeAll(async function() {
let config = new Config(config_hash);
let config = new Config(buildConfig());
this.storage = new Storage(config);
await this.storage.init(config);
Search.configureStorage(this.storage);

@ -1,6 +1,5 @@
// @flow
import _ from 'lodash';
import path from 'path';
import fs from 'fs';
import rimraf from 'rimraf';
@ -16,19 +15,21 @@ import {API_ERROR, HTTP_STATUS} from '../../../src/lib/constants';
import {mockServer} from './mock';
import {DOMAIN_SERVERS} from '../../functional/config.functional';
setup(configExample.logs);
setup([]);
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);
storageConfig.self_path = __dirname;
storageConfig.storage = storagePath;
storageConfig.uplinks = {
npmjs: {
url: `http://${DOMAIN_SERVERS}:${port}`
const generateStorage = async function(port = mockServerPort) {
const storageConfig = configExample({
self_path: __dirname,
storage: storagePath,
uplinks: {
npmjs: {
url: `http://${DOMAIN_SERVERS}:${port}`
}
}
};
}, 'store.spec.yaml');
const config: Config = new AppConfig(storageConfig);
const store: IStorageHandler = new Storage(config);
await store.init(config);
@ -100,11 +101,14 @@ describe('StorageTest', () => {
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);
expect(metadata).toBeDefined();
console.log("M-->", metadata);
storage._syncUplinksMetadata('npm_test', metadata, {}, (err) => {
expect(err).toBeNull();
expect(storage.localStorage.updateVersions).not.toHaveBeenCalled();

@ -21,7 +21,7 @@ describe('UpStorge', () => {
url: `http://0.0.0.0:${mockServerPort}`
};
const generateProxy = (config: UpLinkConf = uplinkDefault) => {
const appConfig: Config = new AppConfig(configExample);
const appConfig: Config = new AppConfig(configExample());
return new ProxyStorage(config, appConfig);
};

@ -1,59 +1,12 @@
import _ from 'lodash';
import path from 'path';
import {parseConfigFile} from '../../../../src/lib/utils';
const config = {
storage: path.join(__dirname, '../store/test-storage'),
uplinks: {
'npmjs': {
'url': 'http://localhost:4873/'
}
},
packages: {
'@*/*': {
access: '$all',
publish: '$all',
proxy: 'npmjs'
},
'forbidden-place': {
access: 'nobody',
publish: '$all'
},
'react': {
access: '$all',
publish: '$all',
proxy: 'npmjs'
},
'corrupted-package': {
access: '$all',
publish: '$all',
proxy: 'npmjs'
},
'jquery': {
access: '$all',
publish: '$all',
proxy: 'npmjs'
},
'auth-package': {
access: '$authenticated',
publish: '$authenticated'
},
'vue': {
access: '$authenticated',
publish: '$authenticated',
proxy: 'npmjs'
},
'*': {
access: '$all',
publish: '$all'
},
},
logs: [
{type: 'stdout', format: 'pretty', level: 'warn'},
],
};
module.exports = config;
export default (options, url = 'default.yaml') => {
const locationFile = path.join(__dirname, `../config/yaml/${url}`);
const config = parseConfigFile(locationFile);
return _.assign({}, _.cloneDeep(config), options);
}

@ -1,8 +1,9 @@
import path from 'path';
import config from './index';
module.exports = {
...require('./index'),
...config(),
auth: {
[`${path.join(__dirname, '../plugin/authenticate')}`]: { }
}

@ -0,0 +1,31 @@
storage: ./storage_default_storage
uplinks:
npmjs:
url: http://localhost:4873/
packages:
'@*/*':
access: $all
publish: $all
unpublish: $all
proxy: npmjs
'auth-package':
access: $authenticated
publish: $authenticated
'forbidden-place':
access: nobody
publish: $all
'vue':
access: $authenticated
publish: $authenticated
proxy: npmjs
'jquery':
access: $all
publish: $all
proxy: npmjs
'*':
access: $all
publish: $all
unpublish: xxx
proxy: npmjs
logs:
- { type: stdout, format: pretty, level: error }

@ -0,0 +1,20 @@
storage: ./storage_default_storage
uplinks:
npmjs:
url: http://localhost:4873/
packages:
'@*/*':
access: $all
publish: $all
proxy: npmjs
unpublish: npmjs
'forbidden-place':
access: nobody
publish: $all
'*':
access: $all
publish: $all
unpublish: xxx
proxy: npmjs
logs:
- { type: stdout, format: pretty, level: warn }

@ -0,0 +1,38 @@
storage: ./storage_default_storage
uplinks:
npmjs:
url: http://localhost:4873/
packages:
'@*/*':
access: $all
publish: $all
proxy: npmjs
'forbidden-place':
access: nobody
publish: $all
'react':
access: $all
publish: $all
proxy: npmjs
'corrupted-package':
access: $all
publish: $all
proxy: npmjs
'jquery':
access: $all
publish: $all
proxy: npmjs
'auth-package':
access: $authenticated
publish: $authenticated
'vue':
access: $authenticated
publish: $authenticated
proxy: npmjs
'*':
access: $all
publish: $all
proxy: npmjs
logs:
- { type: stdout, format: pretty, level: warn }

@ -0,0 +1,22 @@
uplinks:
npmjs:
url: http://localhost:4873/
packages:
'@*/*':
access: $all
publish: $all
proxy: npmjs
'corrupted-package':
access: $all
publish: $all
proxy: npmjs
'jquery':
access: $all
publish: $all
proxy: npmjs
'*':
access: $all
publish: $all
proxy: npmjs
logs:
- { type: stdout, format: pretty, level: warn }

@ -1,163 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<NotFound /> component should load the component in default state 1`] = `
ShallowWrapper {
Symbol(enzyme.__root__): ShallowWrapper {
Symbol(enzyme.__root__): [Circular],
Symbol(enzyme.__unrendered__): <BrowserRouter>
<withRouter(WithTheme(WithWidth(NotFound))) />
</BrowserRouter>,
Symbol(enzyme.__renderer__): Object {
"batchedUpdates": [Function],
"getNode": [Function],
"render": [Function],
"simulateError": [Function],
"simulateEvent": [Function],
"unmount": [Function],
},
Symbol(enzyme.__node__): Object {
"instance": null,
"key": undefined,
"nodeType": "class",
"props": Object {
"children": <withRouter(WithTheme(WithWidth(NotFound))) />,
"history": Object {
"action": "POP",
"block": [Function],
"createHref": [Function],
"go": [Function],
"goBack": [Function],
"goForward": [Function],
"length": 1,
"listen": [Function],
"location": Object {
"hash": "",
"pathname": "/",
"search": "",
"state": undefined,
},
"push": [Function],
"replace": [Function],
},
},
"ref": null,
"rendered": Object {
"instance": null,
"key": undefined,
"nodeType": "function",
"props": Object {},
"ref": null,
"rendered": null,
"type": [Function],
},
"type": [Function],
},
Symbol(enzyme.__nodes__): Array [
Object {
"instance": null,
"key": undefined,
"nodeType": "class",
"props": Object {
"children": <withRouter(WithTheme(WithWidth(NotFound))) />,
"history": Object {
"action": "POP",
"block": [Function],
"createHref": [Function],
"go": [Function],
"goBack": [Function],
"goForward": [Function],
"length": 1,
"listen": [Function],
"location": Object {
"hash": "",
"pathname": "/",
"search": "",
"state": undefined,
},
"push": [Function],
"replace": [Function],
},
},
"ref": null,
"rendered": Object {
"instance": null,
"key": undefined,
"nodeType": "function",
"props": Object {},
"ref": null,
"rendered": null,
"type": [Function],
},
"type": [Function],
},
],
Symbol(enzyme.__options__): Object {
"adapter": ReactSixteenAdapter {
"options": Object {
"enableComponentDidUpdateOnSetState": true,
"lifecycles": Object {
"componentDidUpdate": Object {
"onSetState": true,
},
"getDerivedStateFromProps": true,
"getSnapshotBeforeUpdate": true,
"setState": Object {
"skipsComponentDidUpdateOnNullish": true,
},
},
},
},
"attachTo": undefined,
"hydrateIn": undefined,
},
},
Symbol(enzyme.__unrendered__): null,
Symbol(enzyme.__renderer__): Object {
"batchedUpdates": [Function],
"getNode": [Function],
"render": [Function],
"simulateError": [Function],
"simulateEvent": [Function],
"unmount": [Function],
},
Symbol(enzyme.__node__): Object {
"instance": null,
"key": undefined,
"nodeType": "function",
"props": Object {},
"ref": null,
"rendered": null,
"type": [Function],
},
Symbol(enzyme.__nodes__): Array [
Object {
"instance": null,
"key": undefined,
"nodeType": "function",
"props": Object {},
"ref": null,
"rendered": null,
"type": [Function],
},
],
Symbol(enzyme.__options__): Object {
"adapter": ReactSixteenAdapter {
"options": Object {
"enableComponentDidUpdateOnSetState": true,
"lifecycles": Object {
"componentDidUpdate": Object {
"onSetState": true,
},
"getDerivedStateFromProps": true,
"getSnapshotBeforeUpdate": true,
"setState": Object {
"skipsComponentDidUpdateOnNullish": true,
},
},
},
},
"attachTo": undefined,
"hydrateIn": undefined,
},
}
`;
exports[`<NotFound /> component should load the component in default state 1`] = `ShallowWrapper {}`;

BIN
yarn.lock

Binary file not shown.