refactor: add types to new files

pluging-loader and auth
This commit is contained in:
Juan Picado @jotadeveloper 2018-02-24 20:19:06 +01:00
parent afd1b6e2dd
commit 199c98314d
No known key found for this signature in database
GPG Key ID: 18AC54485952D158
16 changed files with 386 additions and 136 deletions

View File

@ -22,3 +22,4 @@ node_modules/@verdaccio/types/lib/
[options] [options]
suppress_comment= \\(.\\|\n\\)*\\$FlowFixMe suppress_comment= \\(.\\|\n\\)*\\$FlowFixMe
module.ignore_non_literal_requires=true

255
flow-typed/npm/js-yaml_vx.x.x.js vendored Normal file
View File

@ -0,0 +1,255 @@
// flow-typed signature: 10998829754884cf0b6f5fe169611a08
// flow-typed version: <<STUB>>/js-yaml_v3.10.0/flow_v0.64.0
/**
* This is an autogenerated libdef stub for:
*
* 'js-yaml'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'js-yaml' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'js-yaml/bin/js-yaml' {
declare module.exports: any;
}
declare module 'js-yaml/dist/js-yaml' {
declare module.exports: any;
}
declare module 'js-yaml/dist/js-yaml.min' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/common' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/dumper' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/exception' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/loader' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/mark' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/schema' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/schema/core' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/schema/default_full' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/schema/default_safe' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/schema/failsafe' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/schema/json' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/binary' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/bool' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/float' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/int' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/js/function' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/js/regexp' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/js/undefined' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/map' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/merge' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/null' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/omap' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/pairs' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/seq' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/set' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/str' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/timestamp' {
declare module.exports: any;
}
// Filename aliases
declare module 'js-yaml/bin/js-yaml.js' {
declare module.exports: $Exports<'js-yaml/bin/js-yaml'>;
}
declare module 'js-yaml/dist/js-yaml.js' {
declare module.exports: $Exports<'js-yaml/dist/js-yaml'>;
}
declare module 'js-yaml/dist/js-yaml.min.js' {
declare module.exports: $Exports<'js-yaml/dist/js-yaml.min'>;
}
declare module 'js-yaml/index' {
declare module.exports: $Exports<'js-yaml'>;
}
declare module 'js-yaml/index.js' {
declare module.exports: $Exports<'js-yaml'>;
}
declare module 'js-yaml/lib/js-yaml.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml'>;
}
declare module 'js-yaml/lib/js-yaml/common.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/common'>;
}
declare module 'js-yaml/lib/js-yaml/dumper.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/dumper'>;
}
declare module 'js-yaml/lib/js-yaml/exception.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/exception'>;
}
declare module 'js-yaml/lib/js-yaml/loader.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/loader'>;
}
declare module 'js-yaml/lib/js-yaml/mark.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/mark'>;
}
declare module 'js-yaml/lib/js-yaml/schema.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/schema'>;
}
declare module 'js-yaml/lib/js-yaml/schema/core.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/schema/core'>;
}
declare module 'js-yaml/lib/js-yaml/schema/default_full.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/schema/default_full'>;
}
declare module 'js-yaml/lib/js-yaml/schema/default_safe.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/schema/default_safe'>;
}
declare module 'js-yaml/lib/js-yaml/schema/failsafe.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/schema/failsafe'>;
}
declare module 'js-yaml/lib/js-yaml/schema/json.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/schema/json'>;
}
declare module 'js-yaml/lib/js-yaml/type.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type'>;
}
declare module 'js-yaml/lib/js-yaml/type/binary.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/binary'>;
}
declare module 'js-yaml/lib/js-yaml/type/bool.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/bool'>;
}
declare module 'js-yaml/lib/js-yaml/type/float.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/float'>;
}
declare module 'js-yaml/lib/js-yaml/type/int.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/int'>;
}
declare module 'js-yaml/lib/js-yaml/type/js/function.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/js/function'>;
}
declare module 'js-yaml/lib/js-yaml/type/js/regexp.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/js/regexp'>;
}
declare module 'js-yaml/lib/js-yaml/type/js/undefined.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/js/undefined'>;
}
declare module 'js-yaml/lib/js-yaml/type/map.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/map'>;
}
declare module 'js-yaml/lib/js-yaml/type/merge.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/merge'>;
}
declare module 'js-yaml/lib/js-yaml/type/null.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/null'>;
}
declare module 'js-yaml/lib/js-yaml/type/omap.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/omap'>;
}
declare module 'js-yaml/lib/js-yaml/type/pairs.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/pairs'>;
}
declare module 'js-yaml/lib/js-yaml/type/seq.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/seq'>;
}
declare module 'js-yaml/lib/js-yaml/type/set.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/set'>;
}
declare module 'js-yaml/lib/js-yaml/type/str.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/str'>;
}
declare module 'js-yaml/lib/js-yaml/type/timestamp.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/timestamp'>;
}

View File

@ -52,7 +52,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": "1.0.1", "@verdaccio/types": "1.0.3",
"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",

View File

@ -96,7 +96,7 @@ module.exports = function(router, auth, storage, config) {
}); });
}; };
if (Object.keys(req.body).length === 1 && Utils.is_object(req.body.users)) { if (Object.keys(req.body).length === 1 && Utils.isObject(req.body.users)) {
// 501 status is more meaningful, but npm doesn't show error message for 5xx // 501 status is more meaningful, but npm doesn't show error message for 5xx
return next( createError[404]('npm star|unstar calls are not implemented') ); return next( createError[404]('npm star|unstar calls are not implemented') );
} }

View File

@ -65,7 +65,7 @@ module.exports.encodeScopePackage = function(req, res, next) {
}; };
module.exports.expect_json = function expect_json(req, res, next) { module.exports.expect_json = function expect_json(req, res, next) {
if (!utils.is_object(req.body)) { if (!utils.isObject(req.body)) {
return next( createError[400]('can\'t parse incoming json') ); return next( createError[400]('can\'t parse incoming json') );
} }
next(); next();

View File

@ -1,3 +1,5 @@
// @flow
import {loadPlugin} from '../lib/plugin-loader'; import {loadPlugin} from '../lib/plugin-loader';
import Crypto from 'crypto'; import Crypto from 'crypto';
import jwt from 'jsonwebtoken'; import jwt from 'jsonwebtoken';
@ -5,6 +7,9 @@ import {ErrorCode} from './utils';
const Error = require('http-errors'); const Error = require('http-errors');
import type {Config, Logger, Callback} from '@verdaccio/types'; import type {Config, Logger, Callback} from '@verdaccio/types';
import type {$Request, $Response, NextFunction} from 'express';
type $RequestExtend = $Request & {remote_user: any}
const LoggerApi = require('./logger'); const LoggerApi = require('./logger');
/** /**
@ -117,16 +122,13 @@ class Auth {
/** /**
* Allow user to access a package. * Allow user to access a package.
* @param {*} package_name
* @param {*} user
* @param {*} callback
*/ */
allow_access(package_name, user, callback) { allow_access(packageName: string, user: string, callback: Callback) {
let plugins = this.plugins.slice(0); let plugins = this.plugins.slice(0);
let pkg = Object.assign({name: package_name}, // $FlowFixMe
this.config.getMatchedPackagesSpec(package_name)) let pkg = Object.assign({name: packageName}, this.config.getMatchedPackagesSpec(packageName));
;(function next() { (function next() {
let p = plugins.shift(); let p = plugins.shift();
if (typeof(p.allow_access) !== 'function') { if (typeof(p.allow_access) !== 'function') {
@ -150,16 +152,13 @@ class Auth {
/** /**
* Allow user to publish a package. * Allow user to publish a package.
* @param {*} package_name
* @param {*} user
* @param {*} callback
*/ */
allow_publish(package_name, user, callback) { allow_publish(packageName: string, user: string, callback: Callback) {
let plugins = this.plugins.slice(0); let plugins = this.plugins.slice(0);
let pkg = Object.assign({name: package_name}, // $FlowFixMe
this.config.getMatchedPackagesSpec(package_name)) let pkg = Object.assign({name: packageName}, this.config.getMatchedPackagesSpec(packageName));
;(function next() { (function next() {
let p = plugins.shift(); let p = plugins.shift();
if (typeof(p.allow_publish) !== 'function') { if (typeof(p.allow_publish) !== 'function') {
@ -181,7 +180,7 @@ class Auth {
basic_middleware() { basic_middleware() {
let self = this; let self = this;
let credentials; let credentials;
return function(req, res, _next) { return function(req: $RequestExtend, res: $Response, _next: NextFunction) {
req.pause(); req.pause();
const next = function(err) { const next = function(err) {
@ -251,7 +250,7 @@ class Auth {
*/ */
bearer_middleware() { bearer_middleware() {
let self = this; let self = this;
return function(req, res, _next) { return function(req: $RequestExtend, res: $Response, _next: NextFunction) {
req.pause(); req.pause();
const next = function(_err) { const next = function(_err) {
req.resume(); req.resume();
@ -290,6 +289,7 @@ class Auth {
} }
req.remote_user = authenticatedUser(user.u, user.g); req.remote_user = authenticatedUser(user.u, user.g);
// $FlowFixMe
req.remote_user.token = token; req.remote_user.token = token;
next(); next();
}; };
@ -300,7 +300,7 @@ class Auth {
* @return {Function} * @return {Function}
*/ */
jwtMiddleware() { jwtMiddleware() {
return (req, res, _next) => { return (req: $RequestExtend, res: $Response, _next: NextFunction) => {
if (req.remote_user !== null && req.remote_user.name !== undefined) return _next(); if (req.remote_user !== null && req.remote_user.name !== undefined) return _next();
req.pause(); req.pause();
@ -365,10 +365,8 @@ class Auth {
/** /**
* Encrypt a string. * Encrypt a string.
* @param {String} buf
* @return {Buffer}
*/ */
aes_encrypt(buf) { aes_encrypt(buf: Buffer) {
const c = Crypto.createCipher('aes192', this.secret); const c = Crypto.createCipher('aes192', this.secret);
const b1 = c.update(buf); const b1 = c.update(buf);
const b2 = c.final(); const b2 = c.final();
@ -377,10 +375,8 @@ class Auth {
/** /**
* Dencrypt a string. * Dencrypt a string.
* @param {String} buf
* @return {Buffer}
*/ */
aes_decrypt(buf) { aes_decrypt(buf: Buffer ) {
try { try {
const c = Crypto.createDecipher('aes192', this.secret); const c = Crypto.createDecipher('aes192', this.secret);
const b1 = c.update(buf); const b1 = c.update(buf);
@ -407,11 +403,9 @@ function buildAnonymousUser() {
/** /**
* Authenticate an user. * Authenticate an user.
* @param {*} name
* @param {*} groups
* @return {Object} { name: xx, groups: [], real_groups: [] } * @return {Object} { name: xx, groups: [], real_groups: [] }
*/ */
function authenticatedUser(name, groups) { function authenticatedUser(name: string, groups: Array<any>) {
let _groups = (groups || []).concat(['$all', '$authenticated', '@all', '@authenticated', 'all']); let _groups = (groups || []).concat(['$all', '$authenticated', '@all', '@authenticated', 'all']);
return { return {
name: name, name: name,

View File

@ -75,7 +75,7 @@ class Config {
// sanity check for strategic config properties // sanity check for strategic config properties
['users', 'uplinks', 'packages'].forEach(function(x) { ['users', 'uplinks', 'packages'].forEach(function(x) {
if (self[x] == null) self[x] = {}; if (self[x] == null) self[x] = {};
assert(Utils.is_object(self[x]), `CONFIG: bad "${x}" value (object expected)`); assert(Utils.isObject(self[x]), `CONFIG: bad "${x}" value (object expected)`);
}); });
// sanity check for users // sanity check for users
for (let i in self.users) { for (let i in self.users) {

View File

@ -191,7 +191,7 @@ class LocalStorage implements IStorage {
for (let up in packageInfo._uplinks) { for (let up in packageInfo._uplinks) {
if (Object.prototype.hasOwnProperty.call(packageInfo._uplinks, up)) { if (Object.prototype.hasOwnProperty.call(packageInfo._uplinks, up)) {
const need_change = !Utils.is_object(packageLocalJson._uplinks[up]) const need_change = !Utils.isObject(packageLocalJson._uplinks[up])
|| packageInfo._uplinks[up].etag !== packageLocalJson._uplinks[up].etag || packageInfo._uplinks[up].etag !== packageLocalJson._uplinks[up].etag
|| packageInfo._uplinks[up].fetched !== packageLocalJson._uplinks[up].fetched; || packageInfo._uplinks[up].fetched !== packageLocalJson._uplinks[up].fetched;
@ -248,10 +248,10 @@ class LocalStorage implements IStorage {
} }
// if uploaded tarball has a different shasum, it's very likely that we have some kind of error // if uploaded tarball has a different shasum, it's very likely that we have some kind of error
if (Utils.is_object(metadata.dist) && _.isString(metadata.dist.tarball)) { if (Utils.isObject(metadata.dist) && _.isString(metadata.dist.tarball)) {
let tarball = metadata.dist.tarball.replace(/.*\//, ''); let tarball = metadata.dist.tarball.replace(/.*\//, '');
if (Utils.is_object(data._attachments[tarball])) { if (Utils.isObject(data._attachments[tarball])) {
if (_.isNil(data._attachments[tarball].shasum) === false && _.isNil(metadata.dist.shasum) === false) { if (_.isNil(data._attachments[tarball].shasum) === false && _.isNil(metadata.dist.shasum) === false) {
if (data._attachments[tarball].shasum != metadata.dist.shasum) { if (data._attachments[tarball].shasum != metadata.dist.shasum) {
@ -339,7 +339,7 @@ class LocalStorage implements IStorage {
changePackage(name: string, changePackage(name: string,
pkg: Package, pkg: Package,
revision?: string, callback: Callback) { revision?: string, callback: Callback) {
if (!Utils.is_object(pkg.versions) || !Utils.is_object(pkg['dist-tags'])) { if (!Utils.isObject(pkg.versions) || !Utils.isObject(pkg['dist-tags'])) {
return callback( Utils.ErrorCode.get422()); return callback( Utils.ErrorCode.get422());
} }
@ -604,7 +604,7 @@ class LocalStorage implements IStorage {
} }
const listVersions: Array<string> = Object.keys(data.versions); const listVersions: Array<string> = Object.keys(data.versions);
const versions: Array<string> = Utils.semver_sort(listVersions); const versions: Array<string> = Utils.semverSort(listVersions);
const latest: string = data['dist-tags'] && data['dist-tags'].latest ? data['dist-tags'].latest : versions.pop(); const latest: string = data['dist-tags'] && data['dist-tags'].latest ? data['dist-tags'].latest : versions.pop();
if (data.versions[latest]) { if (data.versions[latest]) {

View File

@ -157,7 +157,7 @@ function print(type, msg, obj, colors) {
let _ref = name.split('.'); let _ref = name.split('.');
for (let _i = 0; _i < _ref.length; _i++) { for (let _i = 0; _i < _ref.length; _i++) {
let id = _ref[_i]; let id = _ref[_i];
if (Utils.is_object(str) || Array.isArray(str)) { if (Utils.isObject(str) || Array.isArray(str)) {
str = str[id]; str = str[id];
} else { } else {
str = undefined; str = undefined;

View File

@ -1,14 +1,16 @@
// @flow
import Path from 'path'; import Path from 'path';
import _ from 'lodash'; import _ from 'lodash';
import logger from './logger'; import logger from './logger';
import type {Config} from '@verdaccio/types';
/** /**
* Requires a module. * Requires a module.
* @param {*} path the module's path * @param {*} path the module's path
* @return {Object} * @return {Object}
*/ */
function tryLoad(path) { function tryLoad(path: string) {
try { try {
return require(path); return require(path);
} catch(err) { } catch(err) {
@ -37,13 +39,13 @@ function mergeConfig(appConfig, pluginConfig) {
* - A seccond attempt from node_modules, in case to have multiple match as for instance verdaccio-ldap * - A seccond attempt from node_modules, in case to have multiple match as for instance verdaccio-ldap
* and sinopia-ldap. All verdaccio prefix will have preferences. * and sinopia-ldap. All verdaccio prefix will have preferences.
* @param {*} config a reference of the configuration settings * @param {*} config a reference of the configuration settings
* @param {*} plugin_configs * @param {*} pluginConfigs
* @param {*} params a set of params to initialise the plugin * @param {*} params a set of params to initialise the plugin
* @param {*} sanity_check callback that check the shape that should fulfill the plugin * @param {*} sanityCheck callback that check the shape that should fulfill the plugin
* @return {Array} list of plugins * @return {Array} list of plugins
*/ */
function loadPlugin(config, plugin_configs, params, sanity_check) { function loadPlugin(config: Config, pluginConfigs: any, params: any, sanityCheck: Function) {
let plugins = Object.keys(plugin_configs || {}).map(function(p) { return Object.keys(pluginConfigs || {}).map(function(p) {
let plugin; let plugin;
// try local plugins first // try local plugins first
@ -78,18 +80,16 @@ function loadPlugin(config, plugin_configs, params, sanity_check) {
} }
/* eslint new-cap:off */ /* eslint new-cap:off */
plugin = isES6(plugin) ? new plugin.default(mergeConfig(config, plugin_configs[p]), params) : plugin(plugin_configs[p], params); plugin = isES6(plugin) ? new plugin.default(mergeConfig(config, pluginConfigs[p]), params) : plugin(pluginConfigs[p], params);
/* eslint new-cap:off */ /* eslint new-cap:off */
if (plugin === null || !sanity_check(plugin)) { if (plugin === null || !sanityCheck(plugin)) {
logger.logger.error({content: p}, '@{content} doesn\'t look like a valid plugin'); logger.logger.error({content: p}, '@{content} doesn\'t look like a valid plugin');
throw Error('"' + p + '" doesn\'t look like a valid plugin'); throw Error('"' + p + '" doesn\'t look like a valid plugin');
} }
logger.logger.warn({content: p}, 'Plugin successfully loaded: @{content}'); logger.logger.warn({content: p}, 'Plugin successfully loaded: @{content}');
return plugin; return plugin;
}); });
return plugins;
} }
export {loadPlugin}; export {loadPlugin};

View File

@ -42,7 +42,7 @@ function normalizePackage(pkg: Package) {
'time']; 'time'];
pkgProperties.forEach((key) => { pkgProperties.forEach((key) => {
if (_.isNil(Utils.is_object(pkg[key]))) { if (_.isNil(Utils.isObject(pkg[key]))) {
pkg[key] = {}; pkg[key] = {};
} }
}); });

View File

@ -555,7 +555,7 @@ class Storage implements IStorageHandler {
const _options = Object.assign({}, options); const _options = Object.assign({}, options);
let upLinkMeta = packageInfo._uplinks[upLink.upname]; let upLinkMeta = packageInfo._uplinks[upLink.upname];
if (Utils.is_object(upLinkMeta)) { if (Utils.isObject(upLinkMeta)) {
const fetched = upLinkMeta.fetched; const fetched = upLinkMeta.fetched;

View File

@ -7,7 +7,7 @@ import _ from 'lodash';
import request from 'request'; import request from 'request';
import Stream from 'stream'; import Stream from 'stream';
import URL from 'url'; import URL from 'url';
import {parseInterval, is_object, ErrorCode} from './utils'; import {parseInterval, isObject, ErrorCode} from './utils';
import {ReadTarball} from '@verdaccio/streams'; import {ReadTarball} from '@verdaccio/streams';
import type { import type {
@ -51,8 +51,8 @@ class ProxyStorage implements IProxy {
logger: Logger; logger: Logger;
server_id: string; server_id: string;
url: any; url: any;
maxage: string; maxage: number;
timeout: string; timeout: number;
max_fails: number; max_fails: number;
fail_timeout: number; fail_timeout: number;
upname: string; upname: string;
@ -133,7 +133,7 @@ class ProxyStorage implements IProxy {
uri: uri, uri: uri,
}, 'making request: \'@{method} @{uri}\''); }, 'making request: \'@{method} @{uri}\'');
if (is_object(options.json)) { if (isObject(options.json)) {
json = JSON.stringify(options.json); json = JSON.stringify(options.json);
headers['Content-Type'] = headers['Content-Type'] || 'application/json'; headers['Content-Type'] = headers['Content-Type'] || 'application/json';
} }
@ -167,7 +167,7 @@ class ProxyStorage implements IProxy {
} }
} }
if (!err && is_object(body)) { if (!err && isObject(body)) {
if (_.isString(body.error)) { if (_.isString(body.error)) {
error = body.error; error = body.error;
} }
@ -467,7 +467,7 @@ class ProxyStorage implements IProxy {
}); });
let parsePackage = (pkg) => { let parsePackage = (pkg) => {
if (is_object(pkg)) { if (isObject(pkg)) {
transformStream.emit('data', pkg); transformStream.emit('data', pkg);
} }
}; };

View File

@ -1,3 +1,5 @@
// @flow
import {generateGravatarUrl} from '../utils/user'; import {generateGravatarUrl} from '../utils/user';
import assert from 'assert'; import assert from 'assert';
import semver from 'semver'; import semver from 'semver';
@ -6,15 +8,16 @@ import URL from 'url';
import fs from 'fs'; import fs from 'fs';
import _ from 'lodash'; import _ from 'lodash';
import createError from 'http-errors'; import createError from 'http-errors';
import type {Package, Config} from '@verdaccio/types';
import type {$Request} from 'express';
const Logger = require('./logger'); const Logger = require('./logger');
/** /**
* Validate a package. * Validate a package.
* @param {*} name
* @return {Boolean} whether the package is valid or not * @return {Boolean} whether the package is valid or not
*/ */
function validate_package(name) { function validate_package(name: any): boolean {
name = name.split('/', 2); name = name.split('/', 2);
if (name.length === 1) { if (name.length === 1) {
// normal package // normal package
@ -32,7 +35,7 @@ function validate_package(name) {
* @param {*} name the package name * @param {*} name the package name
* @return {Boolean} whether is valid or not * @return {Boolean} whether is valid or not
*/ */
function validate_name(name) { function validate_name(name: string): boolean {
if (_.isString(name) === false) { if (_.isString(name) === false) {
return false; return false;
} }
@ -54,7 +57,7 @@ function validate_name(name) {
* @param {*} obj the element * @param {*} obj the element
* @return {Boolean} * @return {Boolean}
*/ */
function isObject(obj) { function isObject(obj: any): boolean {
return _.isObject(obj) && _.isNull(obj) === false && _.isArray(obj) === false; return _.isObject(obj) && _.isNull(obj) === false && _.isArray(obj) === false;
} }
@ -65,7 +68,7 @@ function isObject(obj) {
* @param {*} name * @param {*} name
* @return {Object} the object with additional properties as dist-tags ad versions * @return {Object} the object with additional properties as dist-tags ad versions
*/ */
function validate_metadata(object, name) { function validate_metadata(object: Package, name: string) {
assert(isObject(object), 'not a json object'); assert(isObject(object), 'not a json object');
assert.equal(object.name, name); assert.equal(object.name, name);
@ -82,12 +85,9 @@ function validate_metadata(object, name) {
/** /**
* Create base url for registry. * Create base url for registry.
* @param {String} protocol
* @param {String} host
* @param {String} prefix
* @return {String} base registry url * @return {String} base registry url
*/ */
function combineBaseUrl(protocol, host, prefix) { function combineBaseUrl(protocol: string, host: string, prefix?: string): string {
let result = `${protocol}://${host}`; let result = `${protocol}://${host}`;
if (prefix) { if (prefix) {
@ -108,7 +108,7 @@ function combineBaseUrl(protocol, host, prefix) {
* @param {*} config * @param {*} config
* @return {String} a filtered package * @return {String} a filtered package
*/ */
function filter_tarball_urls(pkg, req, config) { function filter_tarball_urls(pkg: Package, req: $Request, config: Config) {
/** /**
* Filter a tarball url. * Filter a tarball url.
* @param {*} _url * @param {*} _url
@ -118,6 +118,7 @@ function filter_tarball_urls(pkg, req, config) {
if (!req.headers.host) { if (!req.headers.host) {
return _url; return _url;
} }
// $FlowFixMe
const filename = URL.parse(_url).pathname.replace(/^.*\//, ''); const filename = URL.parse(_url).pathname.replace(/^.*\//, '');
const base = combineBaseUrl(getWebProtocol(req), req.headers.host, config.url_prefix); const base = combineBaseUrl(getWebProtocol(req), req.headers.host, config.url_prefix);
@ -142,7 +143,7 @@ function filter_tarball_urls(pkg, req, config) {
* @param {*} tag * @param {*} tag
* @return {Boolean} whether a package has been tagged * @return {Boolean} whether a package has been tagged
*/ */
function tag_version(data, version, tag) { function tag_version(data: Package, version: string, tag: string) {
if (_.isEmpty(tag) === false) { if (_.isEmpty(tag) === false) {
if (data['dist-tags'][tag] !== version) { if (data['dist-tags'][tag] !== version) {
if (semver.parse(version, true)) { if (semver.parse(version, true)) {
@ -161,20 +162,20 @@ function tag_version(data, version, tag) {
/** /**
* Gets version from a package object taking into account semver weirdness. * Gets version from a package object taking into account semver weirdness.
* @param {*} object
* @param {*} version
* @return {String} return the semantic version of a package * @return {String} return the semantic version of a package
*/ */
function get_version(object, version) { function get_version(pkg: Package, version: any) {
// this condition must allow cast // this condition must allow cast
if (object.versions[version] != null) { if (pkg.versions[version] != null) {
return object.versions[version]; return pkg.versions[version];
} }
try { try {
version = semver.parse(version, true); version = semver.parse(version, true);
for (let k in object.versions) { for (let versionItem in pkg.versions) {
if (version.compare(semver.parse(k, true)) === 0) { // $FlowFixMe
return object.versions[k]; if (version.compare(semver.parse(versionItem, true)) === 0) {
return pkg.versions[versionItem];
} }
} }
} catch (err) { } catch (err) {
@ -196,7 +197,7 @@ function get_version(object, version) {
* @param {*} urlAddress the internet address definition * @param {*} urlAddress the internet address definition
* @return {Object|Null} literal object that represent the address parsed * @return {Object|Null} literal object that represent the address parsed
*/ */
function parse_address(urlAddress) { function parse_address(urlAddress: any) {
// //
// TODO: refactor it to something more reasonable? // TODO: refactor it to something more reasonable?
// //
@ -225,12 +226,10 @@ function parse_address(urlAddress) {
/** /**
* Function filters out bad semver versions and sorts the array. * Function filters out bad semver versions and sorts the array.
* @param {*} array
* @return {Array} sorted Array * @return {Array} sorted Array
*/ */
function semverSort(array) { function semverSort(listVersions: Array<string>) {
return array return listVersions.filter(function(x) {
.filter(function(x) {
if (!semver.parse(x, true)) { if (!semver.parse(x, true)) {
Logger.logger.warn( {ver: x}, 'ignoring bad version @{ver}' ); Logger.logger.warn( {ver: x}, 'ignoring bad version @{ver}' );
return false; return false;
@ -245,32 +244,33 @@ function semverSort(array) {
* Flatten arrays of tags. * Flatten arrays of tags.
* @param {*} data * @param {*} data
*/ */
function normalize_dist_tags(data) { function normalize_dist_tags(pkg: Package) {
let sorted; let sorted;
if (!data['dist-tags'].latest) { if (!pkg['dist-tags'].latest) {
// overwrite latest with highest known version based on semver sort // overwrite latest with highest known version based on semver sort
sorted = semverSort(Object.keys(data.versions)); sorted = semverSort(Object.keys(pkg.versions));
if (sorted && sorted.length) { if (sorted && sorted.length) {
data['dist-tags'].latest = sorted.pop(); pkg['dist-tags'].latest = sorted.pop();
} }
} }
for (let tag in data['dist-tags']) { for (let tag in pkg['dist-tags']) {
if (_.isArray(data['dist-tags'][tag])) { if (_.isArray(pkg['dist-tags'][tag])) {
if (data['dist-tags'][tag].length) { if (pkg['dist-tags'][tag].length) {
// sort array // sort array
sorted = semverSort(data['dist-tags'][tag]); // $FlowFixMe
sorted = semverSort(pkg['dist-tags'][tag]);
if (sorted.length) { if (sorted.length) {
// use highest version based on semver sort // use highest version based on semver sort
data['dist-tags'][tag] = sorted.pop(); pkg['dist-tags'][tag] = sorted.pop();
} }
} else { } else {
delete data['dist-tags'][tag]; delete pkg['dist-tags'][tag];
} }
} else if (_.isString(data['dist-tags'][tag] )) { } else if (_.isString(pkg['dist-tags'][tag] )) {
if (!semver.parse(data['dist-tags'][tag], true)) { if (!semver.parse(pkg['dist-tags'][tag], true)) {
// if the version is invalid, delete the dist-tag entry // if the version is invalid, delete the dist-tag entry
delete data['dist-tags'][tag]; delete pkg['dist-tags'][tag];
} }
} }
} }
@ -293,7 +293,7 @@ const parseIntervalTable = {
* @param {*} interval * @param {*} interval
* @return {Number} * @return {Number}
*/ */
function parseInterval(interval) { function parseInterval(interval: any) {
if (typeof(interval) === 'number') { if (typeof(interval) === 'number') {
return interval * 1000; return interval * 1000;
} }
@ -318,46 +318,46 @@ function parseInterval(interval) {
* @param {*} req * @param {*} req
* @return {String} * @return {String}
*/ */
function getWebProtocol(req) { function getWebProtocol(req: $Request) {
return req.get('X-Forwarded-Proto') || req.protocol; return req.get('X-Forwarded-Proto') || req.protocol;
} }
const getLatestVersion = function(pkgInfo) { const getLatestVersion = function(pkgInfo: Package) {
return pkgInfo['dist-tags'].latest; return pkgInfo['dist-tags'].latest;
}; };
const ErrorCode = { const ErrorCode = {
get409: (message = 'this package is already present') => { get409: (message: string = 'this package is already present') => {
return createError(409, message); return createError(409, message);
}, },
get422: (customMessage) => { get422: (customMessage?: string) => {
return createError(422, customMessage || 'bad data'); return createError(422, customMessage || 'bad data');
}, },
get400: (customMessage) => { get400: (customMessage?: string) => {
return createError(400, customMessage); return createError(400, customMessage);
}, },
get500: (customMessage) => { get500: (customMessage?: string) => {
return customMessage ? createError(500, customMessage) : createError(500); return customMessage ? createError(500, customMessage) : createError(500);
}, },
get403: (message = 'can\'t use this filename') => { get403: (message: string = 'can\'t use this filename') => {
return createError(403, message); return createError(403, message);
}, },
get503: () => { get503: () => {
return createError(500, 'resource temporarily unavailable'); return createError(500, 'resource temporarily unavailable');
}, },
get404: (customMessage) => { get404: (customMessage?: string) => {
return createError(404, customMessage || 'no such package available'); return createError(404, customMessage || 'no such package available');
}, },
}; };
const parseConfigFile = (config_path) => YAML.safeLoad(fs.readFileSync(config_path, 'utf8')); const parseConfigFile = (configPath: string) => YAML.safeLoad(fs.readFileSync(configPath, 'utf8'));
/** /**
* Check whether the path already exist. * Check whether the path already exist.
* @param {String} path * @param {String} path
* @return {Boolean} * @return {Boolean}
*/ */
function folder_exists(path) { function folder_exists(path: string) {
try { try {
const stat = fs.statSync(path); const stat = fs.statSync(path);
return stat.isDirectory(); return stat.isDirectory();
@ -371,7 +371,7 @@ function folder_exists(path) {
* @param {String} path * @param {String} path
* @return {Boolean} * @return {Boolean}
*/ */
function fileExists(path) { function fileExists(path: string) {
try { try {
const stat = fs.statSync(path); const stat = fs.statSync(path);
return stat.isFile(); return stat.isFile();
@ -380,7 +380,7 @@ function fileExists(path) {
} }
} }
function sortByName(packages) { function sortByName(packages: Array<any>) {
return packages.sort(function(a, b) { return packages.sort(function(a, b) {
if (a.name < b.name) { if (a.name < b.name) {
return -1; return -1;
@ -390,11 +390,11 @@ function sortByName(packages) {
}); });
} }
function addScope(scope, packageName) { function addScope(scope: string, packageName: string) {
return `@${scope}/${packageName}`; return `@${scope}/${packageName}`;
} }
function deleteProperties(propertiesToDelete, packageInfo) { function deleteProperties(propertiesToDelete: Array<string>, packageInfo: Package) {
_.forEach(propertiesToDelete, (property) => { _.forEach(propertiesToDelete, (property) => {
delete packageInfo[property]; delete packageInfo[property];
}); });
@ -402,7 +402,7 @@ function deleteProperties(propertiesToDelete, packageInfo) {
return packageInfo; return packageInfo;
} }
function addGravatarSupport(info) { function addGravatarSupport(info: any) {
if (_.isString(_.get(info, 'latest.author.email'))) { if (_.isString(_.get(info, 'latest.author.email'))) {
info.latest.author.avatar = generateGravatarUrl(info.latest.author.email); info.latest.author.avatar = generateGravatarUrl(info.latest.author.email);
} else { } else {
@ -426,25 +426,27 @@ function addGravatarSupport(info) {
return info; return info;
} }
module.exports.addGravatarSupport = addGravatarSupport; export {
module.exports.deleteProperties = deleteProperties; addGravatarSupport,
module.exports.addScope = addScope; deleteProperties,
module.exports.sortByName = sortByName; addScope,
module.exports.folder_exists = folder_exists; sortByName,
module.exports.file_exists = fileExists; folder_exists,
module.exports.parseInterval = parseInterval; fileExists,
module.exports.semver_sort = semverSort; parseInterval,
module.exports.parse_address = parse_address; semverSort,
module.exports.get_version = get_version; parse_address,
module.exports.normalize_dist_tags = normalize_dist_tags; get_version,
module.exports.tag_version = tag_version; normalize_dist_tags,
module.exports.combineBaseUrl = combineBaseUrl; tag_version,
module.exports.filter_tarball_urls = filter_tarball_urls; combineBaseUrl,
module.exports.validate_metadata = validate_metadata; filter_tarball_urls,
module.exports.is_object = isObject; validate_metadata,
module.exports.validate_name = validate_name; isObject,
module.exports.validate_package = validate_package; validate_name,
module.exports.getWebProtocol = getWebProtocol; validate_package,
module.exports.getLatestVersion = getLatestVersion; getWebProtocol,
module.exports.ErrorCode = ErrorCode; getLatestVersion,
module.exports.parseConfigFile = parseConfigFile; ErrorCode,
parseConfigFile,
};

View File

@ -1,7 +1,5 @@
'use strict';
let assert = require('assert'); let assert = require('assert');
let semver_sort = require('../../src/lib/utils').semver_sort; let semverSort = require('../../src/lib/utils').semverSort;
import Storage from '../../src/lib/storage'; import Storage from '../../src/lib/storage';
require('../../src/lib/logger').setup([]); require('../../src/lib/logger').setup([]);
@ -57,9 +55,9 @@ describe('Storage._merge_versions versions', () => {
}); });
test('semver_sort', () => { test('semverSort', () => {
assert.deepEqual(semver_sort(['1.2.3', '1.2', '1.2.3a', '1.2.3c', '1.2.3-b']), assert.deepEqual(semverSort(['1.2.3', '1.2', '1.2.3a', '1.2.3c', '1.2.3-b']),
['1.2.3a', ['1.2.3a',
'1.2.3-b', '1.2.3-b',
'1.2.3c', '1.2.3c',

View File

@ -214,9 +214,9 @@
version "1.0.0" version "1.0.0"
resolved "https://registry.npmjs.org/@verdaccio/streams/-/streams-1.0.0.tgz#d5d24c6747208728b9fd16b908e3932c3fb1f864" resolved "https://registry.npmjs.org/@verdaccio/streams/-/streams-1.0.0.tgz#d5d24c6747208728b9fd16b908e3932c3fb1f864"
"@verdaccio/types@1.0.1": "@verdaccio/types@1.0.3":
version "1.0.1" version "1.0.3"
resolved "https://registry.npmjs.org/@verdaccio/types/-/types-1.0.1.tgz#0d072ab36d734096ac432a219cf2b13f502e6b60" resolved "https://registry.npmjs.org/@verdaccio/types/-/types-1.0.3.tgz#886998a6ed010b688ad221bb4686091db3ec78f0"
JSONStream@^1.0.4, JSONStream@^1.1.1: JSONStream@^1.0.4, JSONStream@^1.1.1:
version "1.3.2" version "1.3.2"