mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-30 22:34:10 -05:00
refactor: config file using flow
This commit is contained in:
parent
3917b19976
commit
dd3a937ac9
11 changed files with 113 additions and 65 deletions
|
@ -52,7 +52,7 @@
|
|||
"devDependencies": {
|
||||
"@commitlint/cli": "6.1.3",
|
||||
"@commitlint/config-conventional": "6.1.3",
|
||||
"@verdaccio/types": "3.0.0",
|
||||
"@verdaccio/types": "3.0.1",
|
||||
"babel-cli": "6.26.0",
|
||||
"babel-core": "6.26.0",
|
||||
"babel-eslint": "8.2.2",
|
||||
|
|
|
@ -15,13 +15,13 @@ import type {$ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler,
|
|||
import type {Config as IConfig} from '@verdaccio/types';
|
||||
import {ErrorCode} from '../lib/utils';
|
||||
import {API_ERROR, HTTP_STATUS} from '../lib/constants';
|
||||
import AppConfig from '../lib/config';
|
||||
|
||||
const LoggerApp = require('../lib/logger');
|
||||
const Config = require('../lib/config');
|
||||
const Middleware = require('./middleware');
|
||||
const Cats = require('../lib/status-cats');
|
||||
|
||||
const defineAPI = function(config: Config, storage: IStorageHandler) {
|
||||
const defineAPI = function(config: IConfig, storage: IStorageHandler) {
|
||||
const auth: IAuth = new Auth(config);
|
||||
const app: $Application = express();
|
||||
// run in production mode by default, just in case
|
||||
|
@ -103,7 +103,7 @@ const defineAPI = function(config: Config, storage: IStorageHandler) {
|
|||
|
||||
export default async function(configHash: any) {
|
||||
LoggerApp.setup(configHash.logs);
|
||||
const config: IConfig = new Config(configHash);
|
||||
const config: IConfig = new AppConfig(configHash);
|
||||
const storage: IStorageHandler = new Storage(config);
|
||||
// waits until init calls have been intialized
|
||||
await storage.init(config);
|
||||
|
|
|
@ -9,6 +9,7 @@ import type {Config, Logger, Callback} from '@verdaccio/types';
|
|||
import type {$Response, NextFunction} from 'express';
|
||||
import type {$RequestExtend, JWTPayload} from '../../types';
|
||||
import {API_ERROR, ROLES} from './constants';
|
||||
import {getMatchedPackagesSpec} from './config-utils';
|
||||
|
||||
|
||||
const LoggerApi = require('./logger');
|
||||
|
@ -146,7 +147,7 @@ class Auth {
|
|||
allow_access(packageName: string, user: string, callback: Callback) {
|
||||
let plugins = this.plugins.slice(0);
|
||||
// $FlowFixMe
|
||||
let pkg = Object.assign({name: packageName}, this.config.getMatchedPackagesSpec(packageName));
|
||||
let pkg = Object.assign({name: packageName}, getMatchedPackagesSpec(packageName, this.config.packages));
|
||||
|
||||
(function next() {
|
||||
const plugin = plugins.shift();
|
||||
|
@ -175,7 +176,7 @@ class Auth {
|
|||
allow_publish(packageName: string, user: string, callback: Callback) {
|
||||
let plugins = this.plugins.slice(0);
|
||||
// $FlowFixMe
|
||||
let pkg = Object.assign({name: packageName}, this.config.getMatchedPackagesSpec(packageName));
|
||||
let pkg = Object.assign({name: packageName}, getMatchedPackagesSpec(packageName, this.config.packages));
|
||||
|
||||
(function next() {
|
||||
const plugin = plugins.shift();
|
||||
|
|
9
src/lib/bootstrap.js
vendored
9
src/lib/bootstrap.js
vendored
|
@ -64,9 +64,12 @@ export function getListListenAddresses(argListen: string, configListen: mixed) {
|
|||
* @param {String} pkgVersion
|
||||
* @param {String} pkgName
|
||||
*/
|
||||
function startVerdaccio(config: any, cliListen: string,
|
||||
configPath: string, pkgVersion: string,
|
||||
pkgName: string, callback: Callback) {
|
||||
function startVerdaccio(config: any,
|
||||
cliListen: string,
|
||||
configPath: string,
|
||||
pkgVersion: string,
|
||||
pkgName: string,
|
||||
callback: Callback) {
|
||||
if (isObject(config) === false) {
|
||||
throw new Error('config file must be an object');
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
// @flow
|
||||
|
||||
import _ from 'lodash';
|
||||
import minimatch from 'minimatch';
|
||||
import assert from 'assert';
|
||||
import minimatch from 'minimatch';
|
||||
|
||||
import {ErrorCode} from './utils';
|
||||
|
||||
import type {PackageList} from '@verdaccio/types';
|
||||
import type {MatchedPackage} from '../../types';
|
||||
const BLACKLIST = {
|
||||
all: true,
|
||||
anonymous: true,
|
||||
|
@ -38,17 +40,6 @@ export function normalizeUserlist(oldFormat: any, newFormat: any) {
|
|||
return _.flatten(result);
|
||||
}
|
||||
|
||||
export function getMatchedPackagesSpec(packages: any, pkg: any) {
|
||||
for (let i in packages) {
|
||||
// $FlowFixMe
|
||||
if (minimatch.makeRe(i).exec(pkg)) {
|
||||
return packages[i];
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
export function uplinkSanityCheck(uplinks: any, users: any = BLACKLIST) {
|
||||
const newUplinks = _.clone(uplinks);
|
||||
let newUsers = _.clone(users);
|
||||
|
@ -88,8 +79,36 @@ export function sanityCheckUplinksProps(configUpLinks: any) {
|
|||
return uplinks;
|
||||
}
|
||||
|
||||
export function normalisePackageAccess(packages: any): any {
|
||||
const normalizedPkgs: any = {...packages};
|
||||
/**
|
||||
* Check whether an uplink can proxy
|
||||
*/
|
||||
export function hasProxyTo(pkg: string, upLink: string, packages: PackageList): boolean {
|
||||
const matchedPkg: MatchedPackage = (getMatchedPackagesSpec(pkg, packages): MatchedPackage);
|
||||
const proxyList = typeof matchedPkg !== 'undefined' ? matchedPkg.proxy : [];
|
||||
if (proxyList) {
|
||||
return proxyList.reduce((prev, curr) => {
|
||||
if (upLink === curr) {
|
||||
return true;
|
||||
}
|
||||
return prev;
|
||||
}, false);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getMatchedPackagesSpec(pkg: string, packages: PackageList): MatchedPackage {
|
||||
for (let i in packages) {
|
||||
// $FlowFixMe
|
||||
if (minimatch.makeRe(i).exec(pkg)) {
|
||||
return packages[i];
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
export function normalisePackageAccess(packages: PackageList): PackageList {
|
||||
const normalizedPkgs: PackageList = {...packages};
|
||||
// add a default rule for all packages to make writing plugins easier
|
||||
if (_.isNil(normalizedPkgs['**'])) {
|
||||
normalizedPkgs['**'] = {};
|
||||
|
|
|
@ -1,12 +1,25 @@
|
|||
// @flow
|
||||
|
||||
import _ from 'lodash';
|
||||
import assert from 'assert';
|
||||
import minimatch from 'minimatch';
|
||||
|
||||
import {generateRandomHexString} from './crypto-utils';
|
||||
import {normalisePackageAccess, sanityCheckUplinksProps, uplinkSanityCheck} from './config-utils';
|
||||
import {
|
||||
getMatchedPackagesSpec,
|
||||
normalisePackageAccess,
|
||||
sanityCheckUplinksProps,
|
||||
uplinkSanityCheck} from './config-utils';
|
||||
import {getUserAgent, isObject} from './utils';
|
||||
import {APP_ERROR} from './constants';
|
||||
|
||||
import type {
|
||||
PackageList,
|
||||
Config as AppConfig,
|
||||
Logger,
|
||||
} from '@verdaccio/types';
|
||||
|
||||
import type {MatchedPackage, StartUpConfig} from '../../types';
|
||||
|
||||
const LoggerApi = require('./logger');
|
||||
const strategicConfigProps = ['uplinks', 'packages'];
|
||||
const allowedEnvConfig = ['http_proxy', 'https_proxy', 'no_proxy'];
|
||||
|
@ -14,10 +27,24 @@ const allowedEnvConfig = ['http_proxy', 'https_proxy', 'no_proxy'];
|
|||
/**
|
||||
* Coordinates the application configuration
|
||||
*/
|
||||
class Config {
|
||||
constructor(config) {
|
||||
class Config implements AppConfig {
|
||||
logger: Logger;
|
||||
user_agent: string;
|
||||
secret: string;
|
||||
uplinks: any;
|
||||
packages: PackageList;
|
||||
users: any;
|
||||
server_id: string;
|
||||
self_path: string;
|
||||
storage: string | void;
|
||||
$key: any;
|
||||
$value: any;
|
||||
|
||||
constructor(config: StartUpConfig) {
|
||||
const self = this;
|
||||
this.logger = LoggerApi.logger;
|
||||
this.self_path = config.self_path;
|
||||
this.storage = config.storage;
|
||||
|
||||
for (let configProp in config) {
|
||||
if (self[configProp] == null) {
|
||||
|
@ -44,7 +71,7 @@ class Config {
|
|||
this.uplinks = sanityCheckUplinksProps(uplinkSanityCheck(this.uplinks));
|
||||
|
||||
if (_.isNil(this.users) === false) {
|
||||
this.logger.warn(`[users]: property on configuration file
|
||||
this.logger.warn(`[users]: property on configuration file
|
||||
is not longer supported, property being ignored`);
|
||||
}
|
||||
|
||||
|
@ -63,42 +90,18 @@ class Config {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether an uplink can proxy
|
||||
* @param {String} pkg package anem
|
||||
* @param {*} upLink
|
||||
* @return {Boolean}
|
||||
*/
|
||||
hasProxyTo(pkg, upLink) {
|
||||
return (this.getMatchedPackagesSpec(pkg).proxy || []).reduce(function(prev, curr) {
|
||||
if (upLink === curr) {
|
||||
return true;
|
||||
}
|
||||
return prev;
|
||||
}, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for package spec
|
||||
* @param {String} pkg package name
|
||||
* @return {Object}
|
||||
*/
|
||||
getMatchedPackagesSpec(pkg) {
|
||||
for (let i in this.packages) {
|
||||
if (minimatch.makeRe(i).exec(pkg)) {
|
||||
return this.packages[i];
|
||||
}
|
||||
}
|
||||
return {};
|
||||
getMatchedPackagesSpec(pkg: string): MatchedPackage {
|
||||
return getMatchedPackagesSpec(pkg, this.packages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store or create whether recieve a secret key
|
||||
* @param {String} secret
|
||||
* @return {String}
|
||||
*/
|
||||
checkSecretKey(secret) {
|
||||
if (_.isString(secret) && secret !== '') {
|
||||
checkSecretKey(secret: string): string {
|
||||
if (_.isString(secret) && _.isEmpty(secret) === false) {
|
||||
this.secret = secret;
|
||||
return secret;
|
||||
}
|
||||
|
@ -109,4 +112,4 @@ class Config {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports = Config;
|
||||
export default Config;
|
||||
|
|
|
@ -26,6 +26,7 @@ Callback,
|
|||
Logger,
|
||||
} from '@verdaccio/types';
|
||||
import type {IReadTarball, IUploadTarball} from '@verdaccio/streams';
|
||||
import {hasProxyTo} from './config-utils';
|
||||
|
||||
const LoggerApi = require('../lib/logger');
|
||||
|
||||
|
@ -412,9 +413,9 @@ class Storage implements IStorageHandler {
|
|||
packageInfo = generatePackageTemplate(name);
|
||||
}
|
||||
|
||||
for (let up in this.uplinks) {
|
||||
if (this.config.hasProxyTo(name, up)) {
|
||||
upLinks.push(this.uplinks[up]);
|
||||
for (let uplink in this.uplinks) {
|
||||
if (hasProxyTo(name, uplink, this.config.packages)) {
|
||||
upLinks.push(this.uplinks[uplink]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ describe('Config Utilities', () => {
|
|||
return path.join(__dirname, `../partials/config/yaml/${name}.yaml`);
|
||||
};
|
||||
|
||||
describe('getMatchedPackagesSpec', () => {
|
||||
describe('normalisePackageAccess', () => {
|
||||
test('should test basic conversion', ()=> {
|
||||
const {packages} = parseConfigFile(parsePartial('pkgs-basic'));
|
||||
const access = normalisePackageAccess(packages);
|
||||
|
@ -58,8 +58,14 @@ describe('Config Utilities', () => {
|
|||
const react = access['react-*'];
|
||||
|
||||
expect(react).toBeDefined();
|
||||
expect(react.access).toBeDefined();
|
||||
// $FlowFixMe
|
||||
expect(react.access[0]).toBe(ROLES.$ALL);
|
||||
expect(react.publish).toBeDefined();
|
||||
// $FlowFixMe);
|
||||
expect(react.publish[0]).toBe('admin');
|
||||
expect(react.proxy).toBeDefined();
|
||||
// $FlowFixMe
|
||||
expect(react.proxy[0]).toBe('uplink2');
|
||||
expect(react.storage).toBeDefined();
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
|
||||
import assert from 'assert';
|
||||
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');
|
||||
let Config = require('../../../src/lib/config');
|
||||
|
||||
|
||||
require('../../../src/lib/logger').setup([]);
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import type {
|
|||
MergeTags,
|
||||
Config,
|
||||
Logger,
|
||||
PackageAccess,
|
||||
Package} from '@verdaccio/types';
|
||||
import type {
|
||||
IUploadTarball,
|
||||
|
@ -95,6 +96,20 @@ export interface IStorageHandler {
|
|||
_updateVersionsHiddenUpLink(versions: Versions, upLink: IProxy): void;
|
||||
}
|
||||
|
||||
// export interface ConfigHandler {
|
||||
// checkSecretKey(token: string): string;
|
||||
// hasProxyTo(pkg: string, upLink: string): boolean;
|
||||
// getMatchedPackagesSpec(storage: string): verdaccio$PackageAccess | void;
|
||||
// [key: string]: number;
|
||||
// }
|
||||
|
||||
export type StartUpConfig = {
|
||||
storage: string;
|
||||
self_path: string;
|
||||
}
|
||||
|
||||
export type MatchedPackage = PackageAccess | void;
|
||||
|
||||
export interface IStorage {
|
||||
config: Config;
|
||||
localData: ILocalData;
|
||||
|
|
BIN
yarn.lock
BIN
yarn.lock
Binary file not shown.
Loading…
Reference in a new issue