From 199c98314d31c6915e36130dd14741ce88c9f8f1 Mon Sep 17 00:00:00 2001 From: "Juan Picado @jotadeveloper" Date: Sat, 24 Feb 2018 20:19:06 +0100 Subject: [PATCH] refactor: add types to new files pluging-loader and auth --- .flowconfig | 1 + flow-typed/npm/js-yaml_vx.x.x.js | 255 +++++++++++++++++++++++++++++++ package.json | 2 +- src/api/endpoint/api/publish.js | 2 +- src/api/web/middleware.js | 2 +- src/lib/auth.js | 46 +++--- src/lib/config.js | 2 +- src/lib/local-storage.js | 10 +- src/lib/logger.js | 2 +- src/lib/plugin-loader.js | 18 +-- src/lib/storage-utils.js | 2 +- src/lib/storage.js | 2 +- src/lib/up-storage.js | 12 +- src/lib/utils.js | 152 +++++++++--------- test/unit/st_merge.spec.js | 8 +- yarn.lock | 6 +- 16 files changed, 386 insertions(+), 136 deletions(-) create mode 100644 flow-typed/npm/js-yaml_vx.x.x.js diff --git a/.flowconfig b/.flowconfig index ae1cda594..20e1cebe6 100644 --- a/.flowconfig +++ b/.flowconfig @@ -22,3 +22,4 @@ node_modules/@verdaccio/types/lib/ [options] suppress_comment= \\(.\\|\n\\)*\\$FlowFixMe +module.ignore_non_literal_requires=true diff --git a/flow-typed/npm/js-yaml_vx.x.x.js b/flow-typed/npm/js-yaml_vx.x.x.js new file mode 100644 index 000000000..ede09ca55 --- /dev/null +++ b/flow-typed/npm/js-yaml_vx.x.x.js @@ -0,0 +1,255 @@ +// flow-typed signature: 10998829754884cf0b6f5fe169611a08 +// flow-typed version: <>/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'>; +} diff --git a/package.json b/package.json index d3eb181e0..d0754cd1c 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "@commitlint/cli": "6.1.0", "@commitlint/config-conventional": "6.1.0", "@commitlint/travis-cli": "6.1.0", - "@verdaccio/types": "1.0.1", + "@verdaccio/types": "1.0.3", "axios": "0.17.1", "babel-cli": "6.26.0", "babel-core": "6.26.0", diff --git a/src/api/endpoint/api/publish.js b/src/api/endpoint/api/publish.js index c4ed89bc2..894e1adb6 100644 --- a/src/api/endpoint/api/publish.js +++ b/src/api/endpoint/api/publish.js @@ -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 return next( createError[404]('npm star|unstar calls are not implemented') ); } diff --git a/src/api/web/middleware.js b/src/api/web/middleware.js index ecfc392ad..3210997ab 100644 --- a/src/api/web/middleware.js +++ b/src/api/web/middleware.js @@ -65,7 +65,7 @@ module.exports.encodeScopePackage = function(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') ); } next(); diff --git a/src/lib/auth.js b/src/lib/auth.js index d9e9b0e98..bfca1725f 100644 --- a/src/lib/auth.js +++ b/src/lib/auth.js @@ -1,3 +1,5 @@ +// @flow + import {loadPlugin} from '../lib/plugin-loader'; import Crypto from 'crypto'; import jwt from 'jsonwebtoken'; @@ -5,6 +7,9 @@ import {ErrorCode} from './utils'; const Error = require('http-errors'); 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'); /** @@ -117,16 +122,13 @@ class Auth { /** * 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 pkg = Object.assign({name: package_name}, - this.config.getMatchedPackagesSpec(package_name)) + // $FlowFixMe + let pkg = Object.assign({name: packageName}, this.config.getMatchedPackagesSpec(packageName)); - ;(function next() { + (function next() { let p = plugins.shift(); if (typeof(p.allow_access) !== 'function') { @@ -150,16 +152,13 @@ class Auth { /** * 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 pkg = Object.assign({name: package_name}, - this.config.getMatchedPackagesSpec(package_name)) + // $FlowFixMe + let pkg = Object.assign({name: packageName}, this.config.getMatchedPackagesSpec(packageName)); - ;(function next() { + (function next() { let p = plugins.shift(); if (typeof(p.allow_publish) !== 'function') { @@ -181,7 +180,7 @@ class Auth { basic_middleware() { let self = this; let credentials; - return function(req, res, _next) { + return function(req: $RequestExtend, res: $Response, _next: NextFunction) { req.pause(); const next = function(err) { @@ -251,7 +250,7 @@ class Auth { */ bearer_middleware() { let self = this; - return function(req, res, _next) { + return function(req: $RequestExtend, res: $Response, _next: NextFunction) { req.pause(); const next = function(_err) { req.resume(); @@ -290,6 +289,7 @@ class Auth { } req.remote_user = authenticatedUser(user.u, user.g); + // $FlowFixMe req.remote_user.token = token; next(); }; @@ -300,7 +300,7 @@ class Auth { * @return {Function} */ jwtMiddleware() { - return (req, res, _next) => { + return (req: $RequestExtend, res: $Response, _next: NextFunction) => { if (req.remote_user !== null && req.remote_user.name !== undefined) return _next(); req.pause(); @@ -365,10 +365,8 @@ class Auth { /** * Encrypt a string. - * @param {String} buf - * @return {Buffer} */ - aes_encrypt(buf) { + aes_encrypt(buf: Buffer) { const c = Crypto.createCipher('aes192', this.secret); const b1 = c.update(buf); const b2 = c.final(); @@ -377,10 +375,8 @@ class Auth { /** * Dencrypt a string. - * @param {String} buf - * @return {Buffer} */ - aes_decrypt(buf) { + aes_decrypt(buf: Buffer ) { try { const c = Crypto.createDecipher('aes192', this.secret); const b1 = c.update(buf); @@ -407,11 +403,9 @@ function buildAnonymousUser() { /** * Authenticate an user. - * @param {*} name - * @param {*} groups * @return {Object} { name: xx, groups: [], real_groups: [] } */ -function authenticatedUser(name, groups) { +function authenticatedUser(name: string, groups: Array) { let _groups = (groups || []).concat(['$all', '$authenticated', '@all', '@authenticated', 'all']); return { name: name, diff --git a/src/lib/config.js b/src/lib/config.js index 0120e5737..aa97d54cc 100644 --- a/src/lib/config.js +++ b/src/lib/config.js @@ -75,7 +75,7 @@ class Config { // sanity check for strategic config properties ['users', 'uplinks', 'packages'].forEach(function(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 for (let i in self.users) { diff --git a/src/lib/local-storage.js b/src/lib/local-storage.js index f526c407f..e4333a60e 100644 --- a/src/lib/local-storage.js +++ b/src/lib/local-storage.js @@ -191,7 +191,7 @@ class LocalStorage implements IStorage { for (let up in packageInfo._uplinks) { 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].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 (Utils.is_object(metadata.dist) && _.isString(metadata.dist.tarball)) { + if (Utils.isObject(metadata.dist) && _.isString(metadata.dist.tarball)) { 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 (data._attachments[tarball].shasum != metadata.dist.shasum) { @@ -339,7 +339,7 @@ class LocalStorage implements IStorage { changePackage(name: string, pkg: Package, 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()); } @@ -604,7 +604,7 @@ class LocalStorage implements IStorage { } const listVersions: Array = Object.keys(data.versions); - const versions: Array = Utils.semver_sort(listVersions); + const versions: Array = Utils.semverSort(listVersions); const latest: string = data['dist-tags'] && data['dist-tags'].latest ? data['dist-tags'].latest : versions.pop(); if (data.versions[latest]) { diff --git a/src/lib/logger.js b/src/lib/logger.js index 242c6bbaf..35bf3df08 100644 --- a/src/lib/logger.js +++ b/src/lib/logger.js @@ -157,7 +157,7 @@ function print(type, msg, obj, colors) { let _ref = name.split('.'); for (let _i = 0; _i < _ref.length; _i++) { let id = _ref[_i]; - if (Utils.is_object(str) || Array.isArray(str)) { + if (Utils.isObject(str) || Array.isArray(str)) { str = str[id]; } else { str = undefined; diff --git a/src/lib/plugin-loader.js b/src/lib/plugin-loader.js index 99cda76e2..49e489173 100644 --- a/src/lib/plugin-loader.js +++ b/src/lib/plugin-loader.js @@ -1,14 +1,16 @@ +// @flow import Path from 'path'; import _ from 'lodash'; import logger from './logger'; +import type {Config} from '@verdaccio/types'; /** * Requires a module. * @param {*} path the module's path * @return {Object} */ -function tryLoad(path) { +function tryLoad(path: string) { try { return require(path); } 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 * and sinopia-ldap. All verdaccio prefix will have preferences. * @param {*} config a reference of the configuration settings - * @param {*} plugin_configs + * @param {*} pluginConfigs * @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 */ -function loadPlugin(config, plugin_configs, params, sanity_check) { - let plugins = Object.keys(plugin_configs || {}).map(function(p) { +function loadPlugin(config: Config, pluginConfigs: any, params: any, sanityCheck: Function) { + return Object.keys(pluginConfigs || {}).map(function(p) { let plugin; // try local plugins first @@ -78,18 +80,16 @@ function loadPlugin(config, plugin_configs, params, sanity_check) { } /* 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 */ - if (plugin === null || !sanity_check(plugin)) { + if (plugin === null || !sanityCheck(plugin)) { logger.logger.error({content: p}, '@{content} 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}'); return plugin; }); - - return plugins; } export {loadPlugin}; diff --git a/src/lib/storage-utils.js b/src/lib/storage-utils.js index a231848ac..2ee7e867e 100644 --- a/src/lib/storage-utils.js +++ b/src/lib/storage-utils.js @@ -42,7 +42,7 @@ function normalizePackage(pkg: Package) { 'time']; pkgProperties.forEach((key) => { - if (_.isNil(Utils.is_object(pkg[key]))) { + if (_.isNil(Utils.isObject(pkg[key]))) { pkg[key] = {}; } }); diff --git a/src/lib/storage.js b/src/lib/storage.js index 6a9c5213e..1db295e4b 100644 --- a/src/lib/storage.js +++ b/src/lib/storage.js @@ -555,7 +555,7 @@ class Storage implements IStorageHandler { const _options = Object.assign({}, options); let upLinkMeta = packageInfo._uplinks[upLink.upname]; - if (Utils.is_object(upLinkMeta)) { + if (Utils.isObject(upLinkMeta)) { const fetched = upLinkMeta.fetched; diff --git a/src/lib/up-storage.js b/src/lib/up-storage.js index 0b9ca89e1..18869f6ce 100644 --- a/src/lib/up-storage.js +++ b/src/lib/up-storage.js @@ -7,7 +7,7 @@ import _ from 'lodash'; import request from 'request'; import Stream from 'stream'; import URL from 'url'; -import {parseInterval, is_object, ErrorCode} from './utils'; +import {parseInterval, isObject, ErrorCode} from './utils'; import {ReadTarball} from '@verdaccio/streams'; import type { @@ -51,8 +51,8 @@ class ProxyStorage implements IProxy { logger: Logger; server_id: string; url: any; - maxage: string; - timeout: string; + maxage: number; + timeout: number; max_fails: number; fail_timeout: number; upname: string; @@ -133,7 +133,7 @@ class ProxyStorage implements IProxy { uri: uri, }, 'making request: \'@{method} @{uri}\''); - if (is_object(options.json)) { + if (isObject(options.json)) { json = JSON.stringify(options.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)) { error = body.error; } @@ -467,7 +467,7 @@ class ProxyStorage implements IProxy { }); let parsePackage = (pkg) => { - if (is_object(pkg)) { + if (isObject(pkg)) { transformStream.emit('data', pkg); } }; diff --git a/src/lib/utils.js b/src/lib/utils.js index 8dc53fa80..d546a45b6 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -1,3 +1,5 @@ +// @flow + import {generateGravatarUrl} from '../utils/user'; import assert from 'assert'; import semver from 'semver'; @@ -6,15 +8,16 @@ import URL from 'url'; import fs from 'fs'; import _ from 'lodash'; import createError from 'http-errors'; +import type {Package, Config} from '@verdaccio/types'; +import type {$Request} from 'express'; const Logger = require('./logger'); /** * Validate a package. - * @param {*} name * @return {Boolean} whether the package is valid or not */ -function validate_package(name) { +function validate_package(name: any): boolean { name = name.split('/', 2); if (name.length === 1) { // normal package @@ -32,7 +35,7 @@ function validate_package(name) { * @param {*} name the package name * @return {Boolean} whether is valid or not */ -function validate_name(name) { +function validate_name(name: string): boolean { if (_.isString(name) === false) { return false; } @@ -54,7 +57,7 @@ function validate_name(name) { * @param {*} obj the element * @return {Boolean} */ -function isObject(obj) { +function isObject(obj: any): boolean { return _.isObject(obj) && _.isNull(obj) === false && _.isArray(obj) === false; } @@ -65,7 +68,7 @@ function isObject(obj) { * @param {*} name * @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.equal(object.name, name); @@ -82,12 +85,9 @@ function validate_metadata(object, name) { /** * Create base url for registry. - * @param {String} protocol - * @param {String} host - * @param {String} prefix * @return {String} base registry url */ -function combineBaseUrl(protocol, host, prefix) { +function combineBaseUrl(protocol: string, host: string, prefix?: string): string { let result = `${protocol}://${host}`; if (prefix) { @@ -108,7 +108,7 @@ function combineBaseUrl(protocol, host, prefix) { * @param {*} config * @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. * @param {*} _url @@ -118,6 +118,7 @@ function filter_tarball_urls(pkg, req, config) { if (!req.headers.host) { return _url; } + // $FlowFixMe const filename = URL.parse(_url).pathname.replace(/^.*\//, ''); const base = combineBaseUrl(getWebProtocol(req), req.headers.host, config.url_prefix); @@ -142,7 +143,7 @@ function filter_tarball_urls(pkg, req, config) { * @param {*} tag * @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 (data['dist-tags'][tag] !== version) { 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. - * @param {*} object - * @param {*} version * @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 - if (object.versions[version] != null) { - return object.versions[version]; + if (pkg.versions[version] != null) { + return pkg.versions[version]; } + try { version = semver.parse(version, true); - for (let k in object.versions) { - if (version.compare(semver.parse(k, true)) === 0) { - return object.versions[k]; + for (let versionItem in pkg.versions) { + // $FlowFixMe + if (version.compare(semver.parse(versionItem, true)) === 0) { + return pkg.versions[versionItem]; } } } catch (err) { @@ -196,7 +197,7 @@ function get_version(object, version) { * @param {*} urlAddress the internet address definition * @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? // @@ -225,12 +226,10 @@ function parse_address(urlAddress) { /** * Function filters out bad semver versions and sorts the array. - * @param {*} array * @return {Array} sorted Array */ -function semverSort(array) { - return array - .filter(function(x) { +function semverSort(listVersions: Array) { + return listVersions.filter(function(x) { if (!semver.parse(x, true)) { Logger.logger.warn( {ver: x}, 'ignoring bad version @{ver}' ); return false; @@ -245,32 +244,33 @@ function semverSort(array) { * Flatten arrays of tags. * @param {*} data */ -function normalize_dist_tags(data) { +function normalize_dist_tags(pkg: Package) { let sorted; - if (!data['dist-tags'].latest) { + if (!pkg['dist-tags'].latest) { // 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) { - data['dist-tags'].latest = sorted.pop(); + pkg['dist-tags'].latest = sorted.pop(); } } - for (let tag in data['dist-tags']) { - if (_.isArray(data['dist-tags'][tag])) { - if (data['dist-tags'][tag].length) { + for (let tag in pkg['dist-tags']) { + if (_.isArray(pkg['dist-tags'][tag])) { + if (pkg['dist-tags'][tag].length) { // sort array - sorted = semverSort(data['dist-tags'][tag]); + // $FlowFixMe + sorted = semverSort(pkg['dist-tags'][tag]); if (sorted.length) { // use highest version based on semver sort - data['dist-tags'][tag] = sorted.pop(); + pkg['dist-tags'][tag] = sorted.pop(); } } else { - delete data['dist-tags'][tag]; + delete pkg['dist-tags'][tag]; } - } else if (_.isString(data['dist-tags'][tag] )) { - if (!semver.parse(data['dist-tags'][tag], true)) { + } else if (_.isString(pkg['dist-tags'][tag] )) { + if (!semver.parse(pkg['dist-tags'][tag], true)) { // 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 * @return {Number} */ -function parseInterval(interval) { +function parseInterval(interval: any) { if (typeof(interval) === 'number') { return interval * 1000; } @@ -318,46 +318,46 @@ function parseInterval(interval) { * @param {*} req * @return {String} */ -function getWebProtocol(req) { +function getWebProtocol(req: $Request) { return req.get('X-Forwarded-Proto') || req.protocol; } -const getLatestVersion = function(pkgInfo) { +const getLatestVersion = function(pkgInfo: Package) { return pkgInfo['dist-tags'].latest; }; const ErrorCode = { - get409: (message = 'this package is already present') => { + get409: (message: string = 'this package is already present') => { return createError(409, message); }, - get422: (customMessage) => { + get422: (customMessage?: string) => { return createError(422, customMessage || 'bad data'); }, - get400: (customMessage) => { + get400: (customMessage?: string) => { return createError(400, customMessage); }, - get500: (customMessage) => { + get500: (customMessage?: string) => { 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); }, get503: () => { return createError(500, 'resource temporarily unavailable'); }, - get404: (customMessage) => { + get404: (customMessage?: string) => { 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. * @param {String} path * @return {Boolean} */ -function folder_exists(path) { +function folder_exists(path: string) { try { const stat = fs.statSync(path); return stat.isDirectory(); @@ -371,7 +371,7 @@ function folder_exists(path) { * @param {String} path * @return {Boolean} */ -function fileExists(path) { +function fileExists(path: string) { try { const stat = fs.statSync(path); return stat.isFile(); @@ -380,7 +380,7 @@ function fileExists(path) { } } -function sortByName(packages) { +function sortByName(packages: Array) { return packages.sort(function(a, b) { if (a.name < b.name) { return -1; @@ -390,11 +390,11 @@ function sortByName(packages) { }); } -function addScope(scope, packageName) { +function addScope(scope: string, packageName: string) { return `@${scope}/${packageName}`; } -function deleteProperties(propertiesToDelete, packageInfo) { +function deleteProperties(propertiesToDelete: Array, packageInfo: Package) { _.forEach(propertiesToDelete, (property) => { delete packageInfo[property]; }); @@ -402,7 +402,7 @@ function deleteProperties(propertiesToDelete, packageInfo) { return packageInfo; } -function addGravatarSupport(info) { +function addGravatarSupport(info: any) { if (_.isString(_.get(info, 'latest.author.email'))) { info.latest.author.avatar = generateGravatarUrl(info.latest.author.email); } else { @@ -426,25 +426,27 @@ function addGravatarSupport(info) { return info; } -module.exports.addGravatarSupport = addGravatarSupport; -module.exports.deleteProperties = deleteProperties; -module.exports.addScope = addScope; -module.exports.sortByName = sortByName; -module.exports.folder_exists = folder_exists; -module.exports.file_exists = fileExists; -module.exports.parseInterval = parseInterval; -module.exports.semver_sort = semverSort; -module.exports.parse_address = parse_address; -module.exports.get_version = get_version; -module.exports.normalize_dist_tags = normalize_dist_tags; -module.exports.tag_version = tag_version; -module.exports.combineBaseUrl = combineBaseUrl; -module.exports.filter_tarball_urls = filter_tarball_urls; -module.exports.validate_metadata = validate_metadata; -module.exports.is_object = isObject; -module.exports.validate_name = validate_name; -module.exports.validate_package = validate_package; -module.exports.getWebProtocol = getWebProtocol; -module.exports.getLatestVersion = getLatestVersion; -module.exports.ErrorCode = ErrorCode; -module.exports.parseConfigFile = parseConfigFile; +export { + addGravatarSupport, + deleteProperties, + addScope, + sortByName, + folder_exists, + fileExists, + parseInterval, + semverSort, + parse_address, + get_version, + normalize_dist_tags, + tag_version, + combineBaseUrl, + filter_tarball_urls, + validate_metadata, + isObject, + validate_name, + validate_package, + getWebProtocol, + getLatestVersion, + ErrorCode, + parseConfigFile, +}; diff --git a/test/unit/st_merge.spec.js b/test/unit/st_merge.spec.js index 7f1a8465d..7e8fd37c8 100644 --- a/test/unit/st_merge.spec.js +++ b/test/unit/st_merge.spec.js @@ -1,7 +1,5 @@ -'use strict'; - 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'; 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.3-b', '1.2.3c', diff --git a/yarn.lock b/yarn.lock index 54e10f734..a79a813c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -214,9 +214,9 @@ version "1.0.0" resolved "https://registry.npmjs.org/@verdaccio/streams/-/streams-1.0.0.tgz#d5d24c6747208728b9fd16b908e3932c3fb1f864" -"@verdaccio/types@1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@verdaccio/types/-/types-1.0.1.tgz#0d072ab36d734096ac432a219cf2b13f502e6b60" +"@verdaccio/types@1.0.3": + version "1.0.3" + resolved "https://registry.npmjs.org/@verdaccio/types/-/types-1.0.3.tgz#886998a6ed010b688ad221bb4686091db3ec78f0" JSONStream@^1.0.4, JSONStream@^1.1.1: version "1.3.2"