diff --git a/src/api/endpoint/api/publish.ts b/src/api/endpoint/api/publish.ts index 4191df1cb..0a5ee1a9b 100644 --- a/src/api/endpoint/api/publish.ts +++ b/src/api/endpoint/api/publish.ts @@ -14,7 +14,7 @@ import { IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandl import { logger } from '../../../lib/logger'; import {isPublishablePackage} from "../../../lib/storage-utils"; -export default function publish(router: Router, auth: IAuth, storage: IStorageHandler, config: Config) { +export default function publish(router: Router, auth: IAuth, storage: IStorageHandler, config: Config): void { const can = allow(auth); /** @@ -101,9 +101,9 @@ export default function publish(router: Router, auth: IAuth, storage: IStorageHa /** * Publish a package */ -export function publishPackage(storage: IStorageHandler, config: Config, auth: IAuth) { +export function publishPackage(storage: IStorageHandler, config: Config, auth: IAuth): any { const starApi = star(storage); - return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { + return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void { const packageName = req.params.package; logger.debug({packageName} , `publishing or updating a new version for @{packageName}`); @@ -111,7 +111,7 @@ export function publishPackage(storage: IStorageHandler, config: Config, auth: I /** * Write tarball of stream data from package clients. */ - const createTarball = function(filename: string, data, cb: Callback) { + const createTarball = function(filename: string, data, cb: Callback): void { const stream = storage.addTarball(packageName, filename); stream.on('error', function(err) { cb(err); @@ -128,18 +128,18 @@ export function publishPackage(storage: IStorageHandler, config: Config, auth: I /** * Add new package version in storage */ - const createVersion = function(version: string, metadata: Version, cb: Callback) { + const createVersion = function(version: string, metadata: Version, cb: Callback): void { storage.addVersion(packageName, version, metadata, null, cb); }; /** * Add new tags in storage */ - const addTags = function(tags: MergeTags, cb: Callback) { + const addTags = function(tags: MergeTags, cb: Callback): void { storage.mergeTags(packageName, tags, cb); }; - const afterChange = function(error, okMessage, metadata) { + const afterChange = function(error, okMessage, metadata): void { const metadataCopy: Package = { ...metadata }; const { _attachments, versions } = metadataCopy; @@ -218,7 +218,7 @@ export function publishPackage(storage: IStorageHandler, config: Config, auth: I logger.debug({packageName} , `updating a new version for @{packageName}`); // we check unpublish permissions, an update is basically remove versions const remote = req.remote_user; - auth.allow_unpublish({packageName}, remote, (error, allowed) => { + auth.allow_unpublish({packageName}, remote, (error) => { if (error) { logger.debug({packageName} , `not allowed to unpublish a version for @{packageName}`); return next(error); @@ -245,7 +245,7 @@ export function publishPackage(storage: IStorageHandler, config: Config, auth: I * un-publish a package */ export function unPublishPackage(storage: IStorageHandler) { - return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { + return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void { const packageName = req.params.package; logger.debug({packageName} , `unpublishing @{packageName}`); @@ -263,7 +263,7 @@ export function unPublishPackage(storage: IStorageHandler) { * Delete tarball */ export function removeTarball(storage: IStorageHandler) { - return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { + return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void { const packageName = req.params.package; const {filename, revision} = req.params; @@ -283,7 +283,7 @@ export function removeTarball(storage: IStorageHandler) { * Adds a new version */ export function addVersion(storage: IStorageHandler) { - return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { + return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void { const { version, tag } = req.params; const packageName = req.params.package; diff --git a/src/lib/config-path.ts b/src/lib/config-path.ts index f401e50eb..2d1cc8f2c 100644 --- a/src/lib/config-path.ts +++ b/src/lib/config-path.ts @@ -1,8 +1,3 @@ -/** - * @prettier - * @flow - */ - import fs from 'fs'; import _ from 'lodash'; import Path from 'path'; @@ -16,18 +11,24 @@ const CONFIG_FILE = 'config.yaml'; const XDG = 'xdg'; const WIN = 'win'; const WIN32 = 'win32'; +// eslint-disable-next-line const pkgJSON = require('../../package.json'); +export type SetupDirectory = { + path: string; + type: string +}; + /** * Find and get the first config file that match. * @return {String} the config file path */ -function findConfigFile(configPath: any) { +function findConfigFile(configPath: string): string { if (_.isNil(configPath) === false) { return Path.resolve(configPath); } - const configPaths = getConfigPaths(); + const configPaths: SetupDirectory[] = getConfigPaths(); if (_.isEmpty(configPaths)) { throw new Error('no configuration files can be processed'); @@ -41,7 +42,7 @@ function findConfigFile(configPath: any) { return createConfigFile(_.head(configPaths)).path; } -function createConfigFile(configLocation: any) { +function createConfigFile(configLocation: any): SetupDirectory { createConfigFolder(configLocation); const defaultConfig = updateStorageLinks(configLocation, readDefaultConfig()); @@ -51,16 +52,16 @@ function createConfigFile(configLocation: any) { return configLocation; } -function readDefaultConfig() { +function readDefaultConfig(): string { return fs.readFileSync(require.resolve('../../conf/default.yaml'), CHARACTER_ENCODING.UTF8); } -function createConfigFolder(configLocation) { +function createConfigFolder(configLocation): void { mkdirp.sync(Path.dirname(configLocation.path)); logger.info({ file: configLocation.path }, 'Creating default config file in @{file}'); } -function updateStorageLinks(configLocation, defaultConfig) { +function updateStorageLinks(configLocation, defaultConfig): string { if (configLocation.type !== XDG) { return defaultConfig; } @@ -77,13 +78,19 @@ function updateStorageLinks(configLocation, defaultConfig) { } } -function getConfigPaths() { - return [getXDGDirectory(), getWindowsDirectory(), getRelativeDefaultDirectory(), getOldDirectory()].filter( - path => !!path - ); +function getConfigPaths(): SetupDirectory[] { + const listPaths: SetupDirectory[] = [getXDGDirectory(), getWindowsDirectory(), getRelativeDefaultDirectory(), getOldDirectory()].reduce( + function(acc, currentValue: any): SetupDirectory[] { + if (_.isUndefined(currentValue) === false) { + acc.push(currentValue); + } + return acc; + }, [] as SetupDirectory[]); + + return listPaths; } -const getXDGDirectory = () => { +const getXDGDirectory = (): SetupDirectory | void => { const XDGConfig = getXDGHome() || (process.env.HOME && Path.join(process.env.HOME, '.config')); if (XDGConfig && folderExists(XDGConfig)) { @@ -94,9 +101,9 @@ const getXDGDirectory = () => { } }; -const getXDGHome = () => process.env.XDG_CONFIG_HOME; +const getXDGHome = (): string | void => process.env.XDG_CONFIG_HOME; -const getWindowsDirectory = () => { +const getWindowsDirectory = (): SetupDirectory | void => { if (process.platform === WIN32 && process.env.APPDATA && folderExists(process.env.APPDATA)) { return { path: Path.resolve(Path.join(process.env.APPDATA, pkgJSON.name, CONFIG_FILE)), @@ -105,14 +112,14 @@ const getWindowsDirectory = () => { } }; -const getRelativeDefaultDirectory = () => { +const getRelativeDefaultDirectory = (): SetupDirectory => { return { path: Path.resolve(Path.join('.', pkgJSON.name, CONFIG_FILE)), type: 'def', }; }; -const getOldDirectory = () => { +const getOldDirectory = (): SetupDirectory => { return { path: Path.resolve(Path.join('.', CONFIG_FILE)), type: 'old', diff --git a/src/lib/crypto-utils.ts b/src/lib/crypto-utils.ts index 11df4ecef..de522de42 100644 --- a/src/lib/crypto-utils.ts +++ b/src/lib/crypto-utils.ts @@ -1,4 +1,4 @@ -import { createDecipher, createCipher, createHash, pseudoRandomBytes } from 'crypto'; +import { createDecipher, createCipher, createHash, pseudoRandomBytes, Hash } from 'crypto'; import jwt from 'jsonwebtoken'; import { JWTSignOptions, RemoteUser } from '@verdaccio/types'; @@ -16,7 +16,7 @@ export function aesEncrypt(buf: Buffer, secret: string): Buffer { return Buffer.concat([b1, b2]); } -export function aesDecrypt(buf: Buffer, secret: string) { +export function aesDecrypt(buf: Buffer, secret: string): Buffer { try { // deprecated (it will be migrated in Verdaccio 5), it is a breaking change // https://nodejs.org/api/crypto.html#crypto_crypto_createdecipher_algorithm_password_options @@ -30,7 +30,7 @@ export function aesDecrypt(buf: Buffer, secret: string) { } } -export function createTarballHash() { +export function createTarballHash(): Hash { return createHash(defaultTarballHashAlgorithm); } @@ -47,12 +47,12 @@ export function stringToMD5(data: Buffer | string): string { .digest('hex'); } -export function generateRandomHexString(length: number = 8) { +export function generateRandomHexString(length = 8): string { return pseudoRandomBytes(length).toString('hex'); } export async function signPayload(payload: RemoteUser, secretOrPrivateKey: string, options: JWTSignOptions): Promise { - return new Promise(function(resolve, reject) { + return new Promise(function(resolve, reject): Promise { return jwt.sign( payload, secretOrPrivateKey, @@ -65,6 +65,6 @@ export async function signPayload(payload: RemoteUser, secretOrPrivateKey: strin }); } -export function verifyPayload(token: string, secretOrPrivateKey: string) { +export function verifyPayload(token: string, secretOrPrivateKey: string): RemoteUser { return jwt.verify(token, secretOrPrivateKey); } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index b05418008..179c2ec84 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -38,8 +38,11 @@ import { } from '@verdaccio/commons-api'; import { IncomingHttpHeaders } from 'http2'; -const Logger = require('./logger'); -const pkginfo = require('pkginfo')(module); // eslint-disable-line no-unused-vars +import { logger } from './logger'; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +// eslint-disable-next-line @typescript-eslint/no-var-requires +require('pkginfo')(module); const pkgVersion = module.exports.version; const pkgName = module.exports.name; @@ -287,7 +290,7 @@ export function semverSort(listVersions: string[]): string[] { listVersions .filter(function(x): boolean { if (!semver.parse(x, true)) { - Logger.logger.warn({ ver: x }, 'ignoring bad version @{ver}'); + logger.warn({ ver: x }, 'ignoring bad version @{ver}'); return false; } return true; @@ -525,7 +528,7 @@ export function parseReadme(packageName: string, readme: string): string | void } // logs readme not found error - Logger.logger.error({ packageName }, '@{packageName}: No readme found'); + logger.error({ packageName }, '@{packageName}: No readme found'); return sanitizyReadme('ERROR: No README data found!'); } @@ -606,15 +609,15 @@ export function pad(str, max): string { * @param {Number} charNum * @returns {String} */ -export function mask(str: string, charNum = 3) { +export function mask(str: string, charNum = 3): string { return `${str.substr(0, charNum)}...${str.substr(-charNum)}`; } -export function encodeScopedUri(packageName) { +export function encodeScopedUri(packageName): string { return packageName.replace(/\//g, '%2f'); } -export function hasDiffOneKey(versions) { +export function hasDiffOneKey(versions): boolean { return Object.keys(versions).length !== 1; } diff --git a/test/e2e/.eslintrc b/test/e2e/.eslintrc new file mode 100644 index 000000000..cbfb89d2f --- /dev/null +++ b/test/e2e/.eslintrc @@ -0,0 +1,6 @@ +{ + "rules": { + "@typescript-eslint/no-var-requires": 0, + "@typescript-eslint/explicit-member-accessibility": 0 + } +} diff --git a/test/functional/fixtures/plugins/middlewares.es6.js b/test/functional/fixtures/plugins/middlewares.es6.js index e6893e6d1..0d17e46a3 100644 --- a/test/functional/fixtures/plugins/middlewares.es6.js +++ b/test/functional/fixtures/plugins/middlewares.es6.js @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/explicit-member-accessibility */ + /** * Original plugin in ES6 * @@ -34,9 +36,10 @@ class PluginES6 { constructor(config, stuff) { this._config = config; + this._logger = stuff.logger; } - register_middlewares(app, auth, storage) { + register_middlewares(app, /* auth, storage */) { const message = this._config.message; diff --git a/test/functional/fixtures/plugins/middlewares.js b/test/functional/fixtures/plugins/middlewares.js index 8a6f11500..cdeee39ce 100644 --- a/test/functional/fixtures/plugins/middlewares.js +++ b/test/functional/fixtures/plugins/middlewares.js @@ -1,11 +1,12 @@ -function Plugin(config, stuff) { +function Plugin(config, pluginOptions) { const self = Object.create(Plugin.prototype); self._config = config; + self._logger = pluginOptions.logger; return self; } -Plugin.prototype.register_middlewares = function (app, auth, storage) { +Plugin.prototype.register_middlewares = function (app) { const {message} = this._config; app.get('/test/route', function (req, res, next) { @@ -13,7 +14,6 @@ Plugin.prototype.register_middlewares = function (app, auth, storage) { return next({ ok: message }) }); - -} +}; module.exports = Plugin; diff --git a/test/functional/fixtures/plugins/middlewares.uplink.js b/test/functional/fixtures/plugins/middlewares.uplink.js index ff8d3a4ad..24381eaf9 100644 --- a/test/functional/fixtures/plugins/middlewares.uplink.js +++ b/test/functional/fixtures/plugins/middlewares.uplink.js @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ const nock = require('nock'); function Plugin(config) { @@ -6,13 +7,14 @@ function Plugin(config) { return self; } -Plugin.prototype.register_middlewares = function (app, auth, storage) { +Plugin.prototype.register_middlewares = function (app) { app.get('/test-uplink-timeout-*', function (req, res, next) { // https://github.com/nock/nock#readme nock('http://localhost:55552') .get(req.path) - // 31s is greater than the default 30s connection timeout + // note: we use 50s due hardware reasons small threshold is not enough to make fails + // 50s is greater than the default 30s connection timeout .socketDelay(50000) // http-status 200 OK .reply(200); diff --git a/test/functional/lib/simple_server.ts b/test/functional/lib/simple_server.ts index 3daf6b266..2fc91d38b 100644 --- a/test/functional/lib/simple_server.ts +++ b/test/functional/lib/simple_server.ts @@ -1,24 +1,36 @@ import express from 'express'; import bodyParser from 'body-parser'; +/** + * Simple Server + * + * A emtpy express server with the objetive to emumate any external API. + * + * eg: test/functional/tags/tags.ts + * + * express.get('/testexp_tags', function(req, res) { + let f = readTags().toString().replace(/__NAME__/g, 'testexp_tags'); + res.send(JSON.parse(f)); + }); + * + * or at test/functional/package/gzip.ts + */ export default class ExpressServer { - app: any; - server: any; + private app: any; + private server: any; - constructor() { + public constructor() { this.app = express(); } - start(port: number): Promise { + public start(port: number): Promise { return new Promise((resolve) => { this.app.use(bodyParser.json()); this.app.use(bodyParser.urlencoded({ extended: true })); - this.server = this.app.listen(port, () => { - resolve(this); - }); + this.server = this.app.listen(port, () => resolve(this)); }); } } diff --git a/test/functional/pre-setup.js b/test/functional/pre-setup.js index 8be36bcba..19decbf84 100644 --- a/test/functional/pre-setup.js +++ b/test/functional/pre-setup.js @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ + require('@babel/register')({ extensions: [".ts", ".js"] }); diff --git a/test/functional/readme/readme.ts b/test/functional/readme/readme.ts index 61cfbdeaa..7619182a9 100644 --- a/test/functional/readme/readme.ts +++ b/test/functional/readme/readme.ts @@ -1,5 +1,8 @@ import {DEFAULT_NO_README, HTTP_STATUS} from '../../../src/lib/constants'; +import pkgReadmeJSON from './pkg-readme.json'; +import pkgNoReadmeJSON from './pkg-no-readme.json'; + export default function (server, server2) { describe('should test readme', () => { @@ -8,9 +11,9 @@ export default function (server, server2) { const README_MESSAGE = 'this is a readme'; beforeAll(async function() { - await server.putPackage('readme-test', require('./pkg-readme.json')) + await server.putPackage('readme-test', pkgReadmeJSON) .status(HTTP_STATUS.CREATED); - await server.putPackage(README_PKG2, require('./pkg-no-readme.json')) + await server.putPackage(README_PKG2, pkgNoReadmeJSON) .status(HTTP_STATUS.CREATED); }); diff --git a/test/functional/search/simple.search.ts b/test/functional/search/simple.search.ts index 51cd250d9..0ddfb09d3 100644 --- a/test/functional/search/simple.search.ts +++ b/test/functional/search/simple.search.ts @@ -1,6 +1,5 @@ import {API_MESSAGE, HTTP_STATUS} from '../../../src/lib/constants'; - -const pkgExample = require('./search.json'); +import pkgExample from './search.json'; export default function(server, server2, express) { diff --git a/test/functional/tags/dist-tags-merge.ts b/test/functional/tags/dist-tags-merge.ts index ebd34291f..45c58b2c7 100644 --- a/test/functional/tags/dist-tags-merge.ts +++ b/test/functional/tags/dist-tags-merge.ts @@ -2,9 +2,7 @@ import {generateSha} from '../lib/test.utils'; import {API_MESSAGE, HTTP_STATUS} from '../../../src/lib/constants'; import {DOMAIN_SERVERS, PORT_SERVER_1, PORT_SERVER_2, PORT_SERVER_3} from '../config.functional'; import {DIST_TAGS} from '../../../src/lib/constants'; - - -const pkgExample = require('./dist-tags-merge.json'); +import pkgExample from './dist-tags-merge.json'; export default function(server, server2, server3) { diff --git a/test/functional/test-environment.js b/test/functional/test-environment.js index fdbfc6eb6..4f37edfd8 100644 --- a/test/functional/test-environment.js +++ b/test/functional/test-environment.js @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ + require('@babel/register')({ extensions: [".ts", ".js"] }); diff --git a/test/lib/helper/register.js b/test/lib/helper/register.js index c38e35351..0c0f6e597 100644 --- a/test/lib/helper/register.js +++ b/test/lib/helper/register.js @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ + require('@babel/register')({ sourceMap: 'inline', }); diff --git a/test/lib/server.ts b/test/lib/server.ts index a79f7e24a..79e21494d 100644 --- a/test/lib/server.ts +++ b/test/lib/server.ts @@ -148,19 +148,20 @@ export default class Server implements IServerBridge { }).send(JSON.stringify(version)); } - public putTarballIncomplete(name: string, filename: string, data: any, size: number, cb: Function): Promise { + public putTarballIncomplete(pkgName: string, filename: string, data: any, headerContentSize: number): Promise { let promise = this.request({ - uri: `/${encodeURIComponent(name)}/-/${encodeURIComponent(filename)}/whatever`, + uri: `/${encodeURIComponent(pkgName)}/-/${encodeURIComponent(filename)}/whatever`, method: 'PUT', headers: { [HEADERS.CONTENT_TYPE]: HEADERS.OCTET_STREAM, - [HEADERS.CONTENT_LENGTH]: size, + [HEADERS.CONTENT_LENGTH]: headerContentSize, }, timeout: 1000, }); promise.request(function(req) { req.write(data); + // it auto abort the request setTimeout(function() { req.req.abort(); }, 20); diff --git a/test/lib/server_process.ts b/test/lib/server_process.ts index a58fa00f7..6e264558b 100644 --- a/test/lib/server_process.ts +++ b/test/lib/server_process.ts @@ -8,18 +8,18 @@ import {IVerdaccioConfig, IServerBridge, IServerProcess} from '../types'; export default class VerdaccioProcess implements IServerProcess { - bridge: IServerBridge; - config: IVerdaccioConfig; - childFork: any; - isDebug: boolean; - silence: boolean; - cleanStore: boolean; + private bridge: IServerBridge; + private config: IVerdaccioConfig; + private childFork: any; + private isDebug: boolean; + private silence: boolean; + private cleanStore: boolean; public constructor(config: IVerdaccioConfig, bridge: IServerBridge, - silence: boolean = true, - isDebug: boolean = false, - cleanStore: boolean = true) { + silence = true, + isDebug = false, + cleanStore = true) { this.config = config; this.bridge = bridge; this.silence = silence; @@ -27,7 +27,7 @@ export default class VerdaccioProcess implements IServerProcess { this.cleanStore = cleanStore; } - public init(verdaccioPath: string = '../../bin/verdaccio'): Promise { + public init(verdaccioPath = '../../bin/verdaccio'): Promise { return new Promise((resolve, reject) => { if(this.cleanStore) { rimRaf(this.config.storagePath, (err) => { diff --git a/test/lib/utils-test.ts b/test/lib/utils-test.ts index 1345087c7..bb532c223 100644 --- a/test/lib/utils-test.ts +++ b/test/lib/utils-test.ts @@ -3,7 +3,7 @@ import { Version } from "@verdaccio/types"; export function generateNewVersion( pkgName: string, version: string, - shashum: string = '238e7641e59508dc9c20eb4ad37a8aa57ab777b4'): Version { + shashum = '238e7641e59508dc9c20eb4ad37a8aa57ab777b4'): Version { // $FlowFixMe return { "name": pkgName, diff --git a/test/lib/verdaccio-server.ts b/test/lib/verdaccio-server.ts index d1d8930ac..c4ea6e1ce 100644 --- a/test/lib/verdaccio-server.ts +++ b/test/lib/verdaccio-server.ts @@ -7,7 +7,7 @@ export class VerdaccioConfig implements IVerdaccioConfig { public domainPath: string; public port: number; - constructor(storagePath: string, configPath: string, domainPath: string, port: number) { + public constructor(storagePath: string, configPath: string, domainPath: string, port: number) { this.storagePath = storagePath; this.configPath = configPath; this.domainPath = domainPath; diff --git a/test/types-test/.eslintrc b/test/types-test/.eslintrc new file mode 100644 index 000000000..6f5f938c4 --- /dev/null +++ b/test/types-test/.eslintrc @@ -0,0 +1,5 @@ +{ + "rules": { + "@typescript-eslint/explicit-member-accessibility": 0 + } +} diff --git a/test/types-test/README.md b/test/types-test/README.md new file mode 100644 index 000000000..e131b4a15 --- /dev/null +++ b/test/types-test/README.md @@ -0,0 +1,7 @@ +# Types smoke test + +This folder is intended to check whether any type update might break plugin implementations + +## Contribute + +- Add more scenarios, middleware, plugins, filters etc. \ No newline at end of file diff --git a/test/flow/plugins/auth/example.auth.plugin.js b/test/types-test/plugins/auth/example.auth.plugin.ts similarity index 60% rename from test/flow/plugins/auth/example.auth.plugin.js rename to test/types-test/plugins/auth/example.auth.plugin.ts index 6d92587aa..b846da6d3 100644 --- a/test/flow/plugins/auth/example.auth.plugin.js +++ b/test/types-test/plugins/auth/example.auth.plugin.ts @@ -1,42 +1,37 @@ -/** - * @prettier - */ - -// @flow - // this file is not aim to be tested, just to check flow definitions import Config from '../../../../src/lib/config'; -import LoggerApi from '../../../../src/lib/logger'; +import { logger } from '../../../../src/lib/logger'; +import { Callback } from '@verdaccio/types'; import { Config as AppConfig, PackageAccess, IPluginAuth, RemoteUser, Logger, PluginOptions } from '@verdaccio/types'; -class ExampleAuthPlugin implements IPluginAuth { +class ExampleAuthPlugin implements IPluginAuth<{}> { config: AppConfig; logger: Logger; - constructor(config: AppConfig, options: PluginOptions) { + constructor(config: AppConfig, options: PluginOptions<{}>) { this.config = config; this.logger = options.logger; } - adduser(user: string, password: string, cb: verdaccio$Callback): void { + adduser(user: string, password: string, cb: Callback): void { cb(); } - changePassword(username, password, newPassword, cb: verdaccio$Callback): void { + changePassword(username, password, newPassword, cb: Callback): void { cb(); } - authenticate(user: string, password: string, cb: verdaccio$Callback): void { + authenticate(user: string, password: string, cb: Callback): void { cb(); } - allow_access(user: RemoteUser, pkg: PackageAccess, cb: verdaccio$Callback): void { + allow_access(user: RemoteUser, pkg: PackageAccess, cb: Callback): void { cb(); } - allow_publish(user: RemoteUser, pkg: PackageAccess, cb: verdaccio$Callback): void { + allow_publish(user: RemoteUser, pkg: PackageAccess, cb: Callback): void { cb(); } } @@ -45,32 +40,32 @@ type SubTypePackageAccess = PackageAccess & { sub?: boolean; }; -class ExampleAuthCustomPlugin implements IPluginAuth { +class ExampleAuthCustomPlugin implements IPluginAuth<{}> { config: AppConfig; logger: Logger; - constructor(config: AppConfig, options: PluginOptions) { + constructor(config: AppConfig, options: PluginOptions<{}>) { this.config = config; this.logger = options.logger; } - adduser(user: string, password: string, cb: verdaccio$Callback): void { + adduser(user: string, password: string, cb: Callback): void { cb(); } - changePassword(username, password, newPassword, cb: verdaccio$Callback): void { + changePassword(username, password, newPassword, cb: Callback): void { cb(); } - authenticate(user: string, password: string, cb: verdaccio$Callback): void { + authenticate(user: string, password: string, cb: Callback): void { cb(); } - allow_access(user: RemoteUser, pkg: SubTypePackageAccess, cb: verdaccio$Callback): void { + allow_access(user: RemoteUser, pkg: SubTypePackageAccess, cb: Callback): void { cb(); } - allow_publish(user: RemoteUser, pkg: SubTypePackageAccess, cb: verdaccio$Callback): void { + allow_publish(user: RemoteUser, pkg: SubTypePackageAccess, cb: Callback): void { cb(); } } @@ -80,9 +75,9 @@ const config1: AppConfig = new Config({ self_path: '/home/sotrage', }); -const options: PluginOptions = { +const options: PluginOptions<{}> = { config: config1, - logger: LoggerApi.logger.child(), + logger: logger.child(), }; const auth = new ExampleAuthPlugin(config1, options); diff --git a/test/flow/plugins/middleware/example.middleware.plugin.js b/test/types-test/plugins/middleware/example.middleware.plugin.ts similarity index 65% rename from test/flow/plugins/middleware/example.middleware.plugin.js rename to test/types-test/plugins/middleware/example.middleware.plugin.ts index 4d8c41f88..075107e74 100644 --- a/test/flow/plugins/middleware/example.middleware.plugin.js +++ b/test/types-test/plugins/middleware/example.middleware.plugin.ts @@ -1,11 +1,13 @@ -// @flow +// this file is not aim to be tested, just to check typescript definitions +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable no-unused-vars */ -// this file is not aim to be tested, just to check flow definitions import Config from '../../../../src/lib/config'; import {generatePackageTemplate} from '../../../../src/lib/storage-utils'; import {readFile} from '../../../functional/lib/test.utils'; +import { Package } from '@verdaccio/types'; -const readMetadata = (fileName: string = 'metadata') => readFile(`../../unit/partials/${fileName}`); +const readMetadata = (fileName: string): Package => JSON.parse(readFile(`../../unit/partials/${fileName}`).toString()) as Package; import { Config as AppConfig, @@ -15,9 +17,10 @@ import { IBasicAuth, } from '@verdaccio/types'; import { IUploadTarball, IReadTarball } from '@verdaccio/streams'; +import { generateVersion } from "../../../unit/__helper/utils"; -export default class ExampleMiddlewarePlugin implements IPluginMiddleware { - register_middlewares(app: any, auth: IBasicAuth, storage: IStorageManager): void { +export default class ExampleMiddlewarePlugin implements IPluginMiddleware<{}> { + register_middlewares(app: any, auth: IBasicAuth<{}>, storage: IStorageManager<{}>): void { const remoteUser: RemoteUser = { groups: [], real_groups: [], @@ -29,13 +32,12 @@ export default class ExampleMiddlewarePlugin implements IPluginMiddleware { auth.aesEncrypt(new Buffer('pass')); // storage storage.addPackage('name', generatePackageTemplate('test'), () => {}); - storage.addVersion('name', 'version', readMetadata(), 'tag', () => {}); + storage.addVersion('name', 'version', generateVersion('name', '1.0.0'), 'tag', () => {}); storage.mergeTags('name', {'latest': '1.0.0'}, () => {}); - storage.changePackage('name', readMetadata(), 'revision', () => {}); + storage.changePackage('name', readMetadata('metadata'), 'revision', () => {}); storage.removePackage('name', () => {}); storage.mergeTags('name', {'latest': '1.0.0'}, () => {}); storage.removeTarball('name', 'filename', 'revision', () => {}); - /* eslint no-unused-vars: 0 */ const config1: AppConfig = new Config({ storage: './storage', self_path: '/home/sotrage' @@ -43,8 +45,7 @@ export default class ExampleMiddlewarePlugin implements IPluginMiddleware { const add: IUploadTarball = storage.addTarball('name', 'filename'); storage.getTarball('name', 'filename'); const read: IReadTarball = storage.getTarball('name', 'filename'); - const search: IReadTarball = storage.search('test'); - /* eslint no-unused-vars: 0 */ + const search: IReadTarball = storage.search('test', {}); } } diff --git a/test/flow/plugins/partials/config.example.js b/test/types-test/plugins/partials/config.example.js similarity index 100% rename from test/flow/plugins/partials/config.example.js rename to test/types-test/plugins/partials/config.example.js diff --git a/test/flow/plugins/storage/example.storage.plugin.js b/test/types-test/plugins/storage/example.storage.plugin.js similarity index 100% rename from test/flow/plugins/storage/example.storage.plugin.js rename to test/types-test/plugins/storage/example.storage.plugin.js diff --git a/test/types-test/plugins/storage/example.storage.plugin.ts b/test/types-test/plugins/storage/example.storage.plugin.ts new file mode 100644 index 000000000..09c34e559 --- /dev/null +++ b/test/types-test/plugins/storage/example.storage.plugin.ts @@ -0,0 +1,171 @@ +// this file is not aim to be tested, just to check typescript definitions + +import { + Callback, + Config as AppConfig, + Logger, + Package, + Token, + TokenFilter, + IUploadTarball, IReadTarball +} from '@verdaccio/types'; + +import { + IPluginStorage, + IPackageStorageManager, + IPackageStorage +} from '@verdaccio/types'; +import { UploadTarball, ReadTarball} from '@verdaccio/streams'; + +import Config from '../../../../src/lib/config'; +import {logger} from '../../../../src/lib/logger'; +import {generatePackageTemplate} from '../../../../src/lib/storage-utils'; + +class PackageStorage implements IPackageStorageManager { + path: string; + logger: Logger; + + constructor(path: string, logger: Logger) { + this.path = path; + this.logger = logger; + } + + updatePackage(name: string, updateHandler: Callback, + onWrite: Callback, + transformPackage: Function, + onEnd: Callback) { + onEnd(); + } + + deletePackage(fileName: string, callback: Callback) { + callback(); + } + + removePackage(callback: Callback): void { + callback(); + } + + createPackage(name: string, value: Package, cb: Callback) { + cb(); + } + + savePackage(name: string, value: Package, cb: Callback) { + cb(); + } + + readPackage(name: string, cb: Callback) { + cb(); + } + + writeTarball(name): IUploadTarball { + this.logger.debug({name}, 'some name @name'); + const uploadStream = new UploadTarball({}); + uploadStream.on('close', () => {}); + if (uploadStream.abort) { + uploadStream.abort(); + } + + if (uploadStream.done) { + uploadStream.done(); + } + + return uploadStream; + } + + readTarball(name): IReadTarball { + this.logger.debug({name}, 'some name @name'); + const readTarballStream: IReadTarball = new ReadTarball({}); + + if (readTarballStream.abort) { + readTarballStream.abort(); + } + + return readTarballStream; + } +} + +class ExampleStoragePlugin implements IPluginStorage<{}> { + logger: Logger; + config: AppConfig; + + constructor(config: AppConfig, logger: Logger) { + this.config = config; + this.logger = logger; + } + + saveToken(token: Token): Promise { + return Promise.resolve(token) + } + deleteToken(user: string, tokenKey: string): Promise{ + return Promise.resolve([user, tokenKey]); + } + + readTokens(filter: TokenFilter): Promise { + const token: Token = { + user: filter.user, + key: '12312', + token: '12321', + readonly: false, + created: '123232' + } + + return Promise.resolve([token, token]); + } + + getSecret(): Promise { + return Promise.resolve(); + } + + setSecret(secret: string): Promise { + return Promise.resolve(secret); + } + + add(name: string, cb: Callback) { + cb(); + } + + remove(name: string, cb: Callback) { + cb(); + } + + get(cb: Callback) { + cb(); + } + + getPackageStorage(packageInfo: string): IPackageStorage { + return new PackageStorage(packageInfo, this.logger); + } + + search(onPackage: Callback, onEnd: Callback, validateName: any): void { + onPackage(onEnd(validateName())); + } +} + +export default ExampleStoragePlugin; + +const config1: AppConfig = new Config({ + storage: './storage', + self_path: '/home/sotrage' +}); + + +const storage = new ExampleStoragePlugin(config1, logger.child()); + +storage.add('test', () => {}); +storage.remove('test', () => {}); +storage.getSecret().then(() => {}); +storage.setSecret('newSecret').then(() => {}); +storage.search(() => {}, () => {}, 'validateName'); +storage.get(() => {}); + +const storageManager: IPackageStorage = storage.getPackageStorage('test'); + +if (storageManager) { + storageManager.createPackage('test', generatePackageTemplate('test'), () => {}); + storageManager.savePackage('fileName', generatePackageTemplate('test'), () => {}); + storageManager.updatePackage('pkgFileName', () =>{}, () => {}, () => {}, () => {}); + storageManager.deletePackage('test', () => {}); + storageManager.removePackage(() => {}); + storageManager.readPackage('test', () => {}); + storageManager.writeTarball('test'); +} diff --git a/test/types/index.ts b/test/types/index.ts index 030ec2b71..b17677c4b 100644 --- a/test/types/index.ts +++ b/test/types/index.ts @@ -15,11 +15,6 @@ export interface IRequestPromise { } export interface IServerProcess { - bridge: IServerBridge; - config: IVerdaccioConfig; - childFork: any; - isDebug: boolean; - silence: boolean; init(): Promise; stop(): void; } diff --git a/test/unit/__helper/api.ts b/test/unit/__helper/api.ts index 337c27d69..bf5710bc1 100644 --- a/test/unit/__helper/api.ts +++ b/test/unit/__helper/api.ts @@ -19,8 +19,7 @@ export function putPackage( request: any, pkgName: string, publishMetadata: Package, - token?: string, - httpStatus: number = HTTP_STATUS.CREATED): Promise { + token?: string): Promise { return new Promise((resolve) => { let put = request.put(pkgName) .set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON) diff --git a/test/unit/__helper/utils.ts b/test/unit/__helper/utils.ts index bd3b0e9d4..9968671c4 100644 --- a/test/unit/__helper/utils.ts +++ b/test/unit/__helper/utils.ts @@ -1,6 +1,6 @@ import { Package } from "@verdaccio/types"; -export function generateAttachment(pkgName, version) { +export function generateAttachment() { return { "content_type": "application\/octet-stream", "data": "H4sIAAAAAAAAE+2W32vbMBDH85y\/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo\/\/79KPeQsnIw5KUDX\/9IOvurLuz\/DHSjK\/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1aW8eML+Vv10m9oF\/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0ScCdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI\/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yoEHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS\/pLQe+D+FIv\/agIWI6GX66kFuIhT+1gDjrp\/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0\/jWiAK8OcMjt8MW3OlfQppcuhhQ6k+2OgkK2Q8DssFPi\/IHpU9fz3\/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6\/f88f\/Pu47zomiPk2Lv\/dOv8h+P\/34\/D\/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=", @@ -54,7 +54,7 @@ export function generatePackageBody(pkgName: string, _versions: string[] = ['1.0 }, {}); const attachtment = _versions.reduce((cat, version) => { - cat[`${pkgName}-${version}.tgz`] = generateAttachment(pkgName, version); + cat[`${pkgName}-${version}.tgz`] = generateAttachment(); return cat; }, {}); @@ -106,8 +106,8 @@ export function generateStarMedatada(pkgName: string, users): any { } } -export function generatePackageMetadata(pkgName: string, version: string = '1.0.0'): Package { - // @ts-ignore +export function generatePackageMetadata(pkgName: string, version = '1.0.0'): Package { + // @ts-ignore return { "_id": pkgName, "name": pkgName, diff --git a/test/unit/modules/access/pkg.access.spec.ts b/test/unit/modules/access/pkg.access.spec.ts index a7207b3c9..b60fe98ee 100644 --- a/test/unit/modules/access/pkg.access.spec.ts +++ b/test/unit/modules/access/pkg.access.spec.ts @@ -101,7 +101,7 @@ describe('api with no limited access configuration', () => { .set(HEADERS.CONTENT_TYPE, HEADERS.JSON_CHARSET) .expect(HEADERS.CONTENT_TYPE, /json/) .expect(HTTP_STATUS.OK) - .end(function(err, res) { + .end(function(err) { if (err) { return done(err); } diff --git a/test/unit/modules/api/api.spec.ts b/test/unit/modules/api/api.spec.ts index fa631a555..8d2639f2a 100644 --- a/test/unit/modules/api/api.spec.ts +++ b/test/unit/modules/api/api.spec.ts @@ -405,7 +405,7 @@ describe('endpoint unit test', () => { .set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET) .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET) .expect(HTTP_STATUS.NOT_FOUND) - .end(function(err, res) { + .end(function(err) { if (err) { return done(err); } @@ -437,7 +437,7 @@ describe('endpoint unit test', () => { .set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET) .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET) .expect(HTTP_STATUS.NOT_FOUND) - .end(function(err, res) { + .end(function(err) { if (err) { return done(err); } @@ -716,7 +716,7 @@ describe('endpoint unit test', () => { } const deletePayload = generatePackageUnpublish(pkgName, ['2.0.0']); - const [err2, res2] = await putPackage(request(app), generateUnPublishURI(pkgName), deletePayload, token, HTTP_STATUS.FORBIDDEN); + const [err2, res2] = await putPackage(request(app), generateUnPublishURI(pkgName), deletePayload, token); expect(err2).not.toBeNull(); expect(res2.body.error).toMatch(/user jota_unpublish_fail is not allowed to unpublish package non-unpublish/); diff --git a/test/unit/modules/api/partials/plugin/filter.js b/test/unit/modules/api/partials/plugin/filter.ts similarity index 88% rename from test/unit/modules/api/partials/plugin/filter.js rename to test/unit/modules/api/partials/plugin/filter.ts index 994554f55..a3caa169c 100644 --- a/test/unit/modules/api/partials/plugin/filter.js +++ b/test/unit/modules/api/partials/plugin/filter.ts @@ -1,9 +1,10 @@ class FilterPlugin { - constructor(config) { + private _config; + public constructor(config) { this._config = config; } - filter_metadata(pkg) { + public filter_metadata(pkg) { return new Promise((resolve, reject) => { // We use this to test what happens when a filter rejects if(pkg.name === 'trigger-filter-failure') { diff --git a/test/unit/modules/api/publish.spec.ts b/test/unit/modules/api/publish.spec.ts index 00725e749..2bad6835e 100644 --- a/test/unit/modules/api/publish.spec.ts +++ b/test/unit/modules/api/publish.spec.ts @@ -270,7 +270,7 @@ describe('Publish endpoints - publish package', () => { test('should star a package', () => { const storage = { changePackage: jest.fn(), - getPackage({ name, req, callback }) { + getPackage({ callback }) { callback(null, { users: {}, }); diff --git a/test/unit/modules/api/token.spec.ts b/test/unit/modules/api/token.spec.ts index dcb361cd1..9800cec0b 100644 --- a/test/unit/modules/api/token.spec.ts +++ b/test/unit/modules/api/token.spec.ts @@ -162,7 +162,7 @@ describe('endpoint unit test', () => { .set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token)) .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET) .expect(HTTP_STATUS.OK) - .end(function(err, resp) { + .end(function(err) { if (err) { return done(err); } diff --git a/test/unit/modules/cli/cli.spec.ts b/test/unit/modules/cli/cli.spec.ts index f3929d1ee..d46e9b558 100644 --- a/test/unit/modules/cli/cli.spec.ts +++ b/test/unit/modules/cli/cli.spec.ts @@ -6,8 +6,7 @@ import config from '../../partials/config'; import {DEFAULT_DOMAIN, DEFAULT_PORT, DEFAULT_PROTOCOL} from '../../../../src/lib/constants'; import {getListListenAddresses} from '../../../../src/lib/cli/utils'; import {parseConfigFile} from '../../../../src/lib/utils'; - -const logger = require('../../../../src/lib/logger'); +import { logger } from '../../../../src/lib/logger'; jest.mock('../../../../src/lib/logger', () => ({ setup: jest.fn(), @@ -132,8 +131,8 @@ describe('startServer via API', () => { // @ts-ignore global.process = { ...realProcess, exit: exitMock }; await startServer(conf, address, store, version, serverName, () => { - expect(logger.logger.fatal).toHaveBeenCalled(); - expect(logger.logger.fatal).toHaveBeenCalledTimes(2); + expect(logger.fatal).toHaveBeenCalled(); + expect(logger.fatal).toHaveBeenCalledTimes(2); done(); }); expect(exitMock).toHaveBeenCalledWith(2); diff --git a/test/unit/modules/notifications/request.spec.ts b/test/unit/modules/notifications/request.spec.ts index 8b3ce8579..f4d05e991 100644 --- a/test/unit/modules/notifications/request.spec.ts +++ b/test/unit/modules/notifications/request.spec.ts @@ -1,4 +1,5 @@ import { HTTP_STATUS, API_ERROR } from '../../../../src/lib/constants'; +/* eslint-disable @typescript-eslint/no-var-requires */ /** * Mocks Logger Service diff --git a/test/unit/modules/plugin/partials/test-plugin-storage/.eslintrc b/test/unit/modules/plugin/partials/test-plugin-storage/.eslintrc new file mode 100644 index 000000000..a521e4fe8 --- /dev/null +++ b/test/unit/modules/plugin/partials/test-plugin-storage/.eslintrc @@ -0,0 +1,5 @@ +{ + "rules": { + "@typescript-eslint/no-empty-function": 0 + } +} diff --git a/test/unit/modules/plugin/partials/test-plugin-storage/invalid-plugin-sanity/index.js b/test/unit/modules/plugin/partials/test-plugin-storage/invalid-plugin-sanity/index.js index 18feb62a9..bf345d0f2 100644 --- a/test/unit/modules/plugin/partials/test-plugin-storage/invalid-plugin-sanity/index.js +++ b/test/unit/modules/plugin/partials/test-plugin-storage/invalid-plugin-sanity/index.js @@ -1,6 +1,7 @@ function ValidVerdaccioPlugin() { return { // not valid method + // eslint-disable-next-line @typescript-eslint/no-empty-function authenticate__: function(){} } } diff --git a/test/unit/modules/plugin/partials/test-plugin-storage/verdaccio-es6-plugin/dummy.js b/test/unit/modules/plugin/partials/test-plugin-storage/verdaccio-es6-plugin/dummy.js index 3c641b39e..e002568cc 100644 --- a/test/unit/modules/plugin/partials/test-plugin-storage/verdaccio-es6-plugin/dummy.js +++ b/test/unit/modules/plugin/partials/test-plugin-storage/verdaccio-es6-plugin/dummy.js @@ -1,3 +1,5 @@ +// this is how a Babel.js transpiled plugin looks like + "use strict"; Object.defineProperty(exports, "__esModule", { @@ -19,10 +21,10 @@ var Dummy = function () { _createClass(Dummy, [{ key: "getPackageStorage", - value: function getPackageStorage(packageInfo, packagePath) {} + value: function getPackageStorage() {} }]); return Dummy; }(); -exports.default = Dummy; \ No newline at end of file +exports.default = Dummy; diff --git a/test/unit/modules/plugin/partials/test-plugin-storage/verdaccio-es6-plugin/index.js b/test/unit/modules/plugin/partials/test-plugin-storage/verdaccio-es6-plugin/index.js index 9294c94d4..a01985c72 100644 --- a/test/unit/modules/plugin/partials/test-plugin-storage/verdaccio-es6-plugin/index.js +++ b/test/unit/modules/plugin/partials/test-plugin-storage/verdaccio-es6-plugin/index.js @@ -1,4 +1,5 @@ 'use strict'; +/* eslint-disable @typescript-eslint/no-var-requires */ Object.defineProperty(exports, "__esModule", { value: true diff --git a/test/unit/modules/storage/local-storage.spec.ts b/test/unit/modules/storage/local-storage.spec.ts index 2fd9690c2..f25e79414 100644 --- a/test/unit/modules/storage/local-storage.spec.ts +++ b/test/unit/modules/storage/local-storage.spec.ts @@ -10,7 +10,7 @@ import {readFile} from '../../../functional/lib/test.utils'; import {generatePackageTemplate} from '../../../../src/lib/storage-utils'; import {generateNewVersion} from '../../../lib/utils-test'; -const readMetadata = (fileName: string = 'metadata') => readFile(`../../unit/partials/${fileName}`).toString(); +const readMetadata = (fileName = 'metadata') => readFile(`../../unit/partials/${fileName}`).toString(); import {Config, MergeTags, Package} from '@verdaccio/types'; import {IStorage} from '../../../../types'; @@ -216,7 +216,7 @@ describe('LocalStorage', () => { await addPackageToStore(pkgName, generatePackageTemplate(pkgName)); await addNewVersion(pkgName, version); - storage.addVersion(pkgName, version, generateNewVersion(pkgName, version), '', (err, data) => { + storage.addVersion(pkgName, version, generateNewVersion(pkgName, version), '', err => { expect(err).not.toBeNull(); expect(err.statusCode).toEqual(HTTP_STATUS.CONFLICT); expect(err.message).toMatch(API_ERROR.PACKAGE_EXIST); @@ -231,7 +231,7 @@ describe('LocalStorage', () => { const tarballName = `${pkgName}-${version}.tgz`; await addTarballToStore(pkgName, tarballName); - storage.addVersion(pkgName, version, generateNewVersion(pkgName, version, 'fake'), '', (err, data) => { + storage.addVersion(pkgName, version, generateNewVersion(pkgName, version, 'fake'), '', err => { expect(err).not.toBeNull(); expect(err.statusCode).toEqual(HTTP_STATUS.BAD_REQUEST); expect(err.message).toMatch(/shasum error/); @@ -503,7 +503,7 @@ describe('LocalStorage', () => { test('should fails with package not found', (done) => { const pkgName = 'npm_test_fake'; - storage.removePackage(pkgName, (err, data) => { + storage.removePackage(pkgName, err => { expect(err).not.toBeNull(); expect(err.message).toMatch(/no such package available/); done(); @@ -511,7 +511,7 @@ describe('LocalStorage', () => { }); test('should fails with @scoped package not found', (done) => { - storage.removePackage(pkgNameScoped, (err, data) => { + storage.removePackage(pkgNameScoped, err => { expect(err).not.toBeNull(); expect(err.message).toMatch(API_ERROR.NO_PACKAGE); done(); diff --git a/test/unit/modules/storage/storage-utils.spec.ts b/test/unit/modules/storage/storage-utils.spec.ts index be60aedb2..9ae672b0a 100644 --- a/test/unit/modules/storage/storage-utils.spec.ts +++ b/test/unit/modules/storage/storage-utils.spec.ts @@ -4,7 +4,7 @@ import {readFile} from "../../../functional/lib/test.utils"; import {Package} from '@verdaccio/types'; -const readMetadata = (fileName: string = 'metadata') => readFile(`../../unit/partials/${fileName}`); +const readMetadata = (fileName = 'metadata') => readFile(`../../unit/partials/${fileName}`); describe('Storage Utils', () => { describe('normalizePackage', () => { diff --git a/test/unit/modules/storage/store.spec.ts b/test/unit/modules/storage/store.spec.ts index 3743f3cde..6c6447ca9 100644 --- a/test/unit/modules/storage/store.spec.ts +++ b/test/unit/modules/storage/store.spec.ts @@ -60,7 +60,7 @@ describe('StorageTest', () => { const storage: IStorageHandler = await generateStorage(); // @ts-ignore - storage._syncUplinksMetadata('jquery', null, {}, (err, metadata, errors) => { + storage._syncUplinksMetadata('jquery', null, {}, (err, metadata) => { expect(err).toBeNull(); expect(metadata).toBeDefined(); expect(metadata).toBeInstanceOf(Object); diff --git a/test/unit/modules/uplinks/up-storage.spec.ts b/test/unit/modules/uplinks/up-storage.spec.ts index 1497968f8..5af4b122c 100644 --- a/test/unit/modules/uplinks/up-storage.spec.ts +++ b/test/unit/modules/uplinks/up-storage.spec.ts @@ -156,7 +156,7 @@ describe('UpStorge', () => { describe('valid use cases', () => { const validateUpLink = ( url: string, - tarBallUrl: string = `${url}/artifactory/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz`) => { + tarBallUrl = `${url}/artifactory/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz`) => { const uplinkConf = { url }; const proxy: IProxy = generateProxy(uplinkConf); diff --git a/test/unit/modules/utils/utils.spec.ts b/test/unit/modules/utils/utils.spec.ts index b2c3e941f..e1b3fccd8 100644 --- a/test/unit/modules/utils/utils.spec.ts +++ b/test/unit/modules/utils/utils.spec.ts @@ -20,7 +20,7 @@ import { DIST_TAGS, DEFAULT_USER } from '../../../../src/lib/constants'; import { logger, setup } from '../../../../src/lib/logger'; import { readFile } from '../../../functional/lib/test.utils'; -const readmeFile = (fileName: string = 'markdown.md') => +const readmeFile = (fileName = 'markdown.md') => readFile(`../../unit/partials/readme/${fileName}`); setup([]); diff --git a/test/unit/partials/config/index.js b/test/unit/partials/config/index.js index 8863a9f1b..5edf37675 100644 --- a/test/unit/partials/config/index.js +++ b/test/unit/partials/config/index.js @@ -1,12 +1,15 @@ import _ from 'lodash'; import path from 'path'; + import {parseConfigFile} from '../../../../src/lib/utils'; - +/** + * Override the default.yaml configuration file with any new config provided. + */ export default (options, url = 'default.yaml') => { const locationFile = path.join(__dirname, `../config/yaml/${url}`); const config = parseConfigFile(locationFile); - + return _.assign({}, _.cloneDeep(config), options); } diff --git a/test/unit/partials/config/json/README.md b/test/unit/partials/config/json/README.md new file mode 100644 index 000000000..a8e393aa1 --- /dev/null +++ b/test/unit/partials/config/json/README.md @@ -0,0 +1,7 @@ +# JSON Configurations + +This folder host all sort of JSON configurations for testing. **It should not include many scenarios, since we use `yaml` for testing. JSON files on this folder aims to verify a verdaccio JSON config file works properly. + +## Contribute + +- Don't add new scenarios unless is discussed with the core team. diff --git a/test/unit/partials/config/yaml/README.md b/test/unit/partials/config/yaml/README.md new file mode 100644 index 000000000..d643e410e --- /dev/null +++ b/test/unit/partials/config/yaml/README.md @@ -0,0 +1,16 @@ +# Yaml Configurations + +This folder host all sort of configurations for testing. We use `yaml` instead json configuration files for different reasons, maintenability, avoid polute with non use data and contributors can easily understand them. + +The files on this folder should be small as possible, **there is a custom config file for all tests (`default.yaml`)** and the following configuration aims to override those part are need it for the test. + +## Contribute + +- Each topic ideally should have his **own folder** if many scenarios might be part of the test. **eg: profile, security** + - Include different scenarios inside of the folder with enough context to indenty the use case. +- Foder or file, should be **named** as the test that used them. *eg: `api.spec.yaml` -> `api.spec.ts`* +- **Don't use the same config file in multiple test**, it increase maintenance complexity. +- Try to **include only the props are require for the test**: +- Comment the config files, don't be shy, add as much context you think is need it for future contributors. + +> Note: Some configurations might be not aligned with this rules, but in the future all files should be follow them for consistency. diff --git a/test/unit/partials/config/yaml/token.spec.yaml b/test/unit/partials/config/yaml/token.spec.yaml index df8bdde76..87ddb880a 100644 --- a/test/unit/partials/config/yaml/token.spec.yaml +++ b/test/unit/partials/config/yaml/token.spec.yaml @@ -7,6 +7,7 @@ security: jwt: sign: expiresIn: 5m + # to avoid invalid verification token, more info on JWT page notBefore: 0 packages: '@token/*': @@ -18,5 +19,5 @@ packages: logs: - { type: stdout, format: pretty, level: trace } experiments: - ## Enable token for testing + ## enable token for testing token: true diff --git a/tsconfig.json b/tsconfig.json index da919fb00..2a10c0a5b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ "noImplicitAny": false, "strict": true, "strictNullChecks": true, + "resolveJsonModule": true, "outDir": "lib", "allowSyntheticDefaultImports": true, "esModuleInterop": true, diff --git a/types/index.ts b/types/index.ts index 24d80746e..01ed49fca 100644 --- a/types/index.ts +++ b/types/index.ts @@ -187,7 +187,7 @@ export interface IStorageHandler extends IStorageManager, ITokenActions init(config: Config, filters: IPluginFilters): Promise; saveToken(token: Token): Promise; deleteToken(user: string, tokenKey: string): Promise; - readTokens(filter: TokenFilter): Promise>; + readTokens(filter: TokenFilter): Promise; _syncUplinksMetadata(name: string, packageInfo: Package, options: any, callback: Callback): void; _updateVersionsHiddenUpLink(versions: Versions, upLink: IProxy): void; }