From 4d7a068eef14e0b74879aaa9e094b11d6efe9030 Mon Sep 17 00:00:00 2001 From: "@jotadeveloper" <@jotadeveloper> Date: Tue, 25 Jun 2019 23:22:46 +0200 Subject: [PATCH] feat: add logging (#5) * chore: add logging wip * chore: add loggig for verbosing debug * chore: update dependencies * chore: disable unit test until future refactoring * chore: add missing log param * chore: update circleci * chore: add formating * chore: add codecov --- .../.circleci/config.yml | 2 +- plugins/verdaccio-aws-s3-storage/.eslintrc | 7 +- plugins/verdaccio-aws-s3-storage/.npmignore | 9 +- plugins/verdaccio-aws-s3-storage/README.md | 4 +- plugins/verdaccio-aws-s3-storage/package.json | 9 +- .../scripts/publish.sh | 10 -- .../verdaccio-aws-s3-storage/src/config.ts | 2 + plugins/verdaccio-aws-s3-storage/src/index.ts | 93 +++++++---- .../verdaccio-aws-s3-storage/src/s3Errors.ts | 49 +++--- .../src/s3PackageManager.ts | 147 +++++++++++++----- .../tests/__snapshots__/index.test.js.snap | 32 ---- .../s3PackageManager.test.js.snap | 138 ---------------- .../tests/index.test.ts | 2 +- .../tests/s3PackageManager.test.ts | 2 +- plugins/verdaccio-aws-s3-storage/yarn.lock | 131 +++++++++++++++- 15 files changed, 347 insertions(+), 290 deletions(-) delete mode 100755 plugins/verdaccio-aws-s3-storage/scripts/publish.sh delete mode 100644 plugins/verdaccio-aws-s3-storage/tests/__snapshots__/index.test.js.snap delete mode 100644 plugins/verdaccio-aws-s3-storage/tests/__snapshots__/s3PackageManager.test.js.snap diff --git a/plugins/verdaccio-aws-s3-storage/.circleci/config.yml b/plugins/verdaccio-aws-s3-storage/.circleci/config.yml index 807ea1b4..96f95630 100644 --- a/plugins/verdaccio-aws-s3-storage/.circleci/config.yml +++ b/plugins/verdaccio-aws-s3-storage/.circleci/config.yml @@ -75,7 +75,7 @@ jobs: - save_cache: key: *repo_key paths: - - ~/local-storage + - ~/aws-s3-storage test_node12: <<: *defaults diff --git a/plugins/verdaccio-aws-s3-storage/.eslintrc b/plugins/verdaccio-aws-s3-storage/.eslintrc index c40b619b..8d609e69 100644 --- a/plugins/verdaccio-aws-s3-storage/.eslintrc +++ b/plugins/verdaccio-aws-s3-storage/.eslintrc @@ -4,7 +4,12 @@ ], "plugins": ["jest"], "rules": { - "@typescript-eslint/no-use-before-define": 0 + "@typescript-eslint/no-use-before-define": 0, + "@typescript-eslint/explicit-function-return-type": ["warn", + { + "allowExpressions": true, + "allowTypedFunctionExpressions": true + }] }, "env": { "jest/globals": true diff --git a/plugins/verdaccio-aws-s3-storage/.npmignore b/plugins/verdaccio-aws-s3-storage/.npmignore index e76ee0ab..a3aa4b34 100644 --- a/plugins/verdaccio-aws-s3-storage/.npmignore +++ b/plugins/verdaccio-aws-s3-storage/.npmignore @@ -1,6 +1,5 @@ src/ tests-report/ -.nyc_output .editorconfig .gitignore yarn-error.log @@ -20,3 +19,11 @@ travis.yml coverage/ jest.config.js jestEnvironment.js +tests/ +.idea/ +.circleci/ +tsconfig.json +jest.config.js +.DS_Store +.prettierrc +*.spec.js \ No newline at end of file diff --git a/plugins/verdaccio-aws-s3-storage/README.md b/plugins/verdaccio-aws-s3-storage/README.md index 8fe2a642..f106d8ca 100644 --- a/plugins/verdaccio-aws-s3-storage/README.md +++ b/plugins/verdaccio-aws-s3-storage/README.md @@ -12,7 +12,7 @@ [![node](https://img.shields.io/node/v/verdaccio-aws-s3-storage/latest.svg)](https://www.npmjs.com/package/verdaccio-aws-s3-storage) -Based on [`verdaccio-s3-storage`](https://github.com/Remitly/verdaccio-s3-storage) in Typescript +Based on [`verdaccio-s3-storage`](https://github.com/Remitly/verdaccio-s3-storage) built in Typescript. 🚧 Under construction @@ -45,4 +45,6 @@ store: region: us-west-2 # optional, will use aws s3's default behavior if not specified endpoint: https://{service}.{region}.amazonaws.com # optional, will use aws s3's default behavior if not specified s3ForcePathStyle: false # optional, will use path style URLs for S3 objects + accessKeyId: your-access-key-id # optional, aws accessKeyId for private S3 bucket + secretAccessKey: your-secret-access-key # optional, aws secretAccessKey for private S3 bucket ``` diff --git a/plugins/verdaccio-aws-s3-storage/package.json b/plugins/verdaccio-aws-s3-storage/package.json index 50570f1d..63d19714 100644 --- a/plugins/verdaccio-aws-s3-storage/package.json +++ b/plugins/verdaccio-aws-s3-storage/package.json @@ -19,13 +19,14 @@ "type-check:watch": "npm run type-check -- --watch", "build": "npm run build:types && npm run build:js", "build:types": "tsc --emitDeclarationOnly", - "build:js": "babel src/ --out-dir lib --extensions \".ts,.tsx\" --source-maps inline", + "build:js": "babel src/ --out-dir lib --extensions \".ts,.tsx\"", "format": "prettier --single-quote --trailing-comma none --write \"{src,test}/**/*.js\"", "coverage:publish": "codecov" }, "dependencies": { - "@verdaccio/streams": "2.0.0", - "aws-sdk": "2.479.0" + "@verdaccio/commons-api": "^0.1.0", + "@verdaccio/streams": "^2.0.0", + "aws-sdk": "2.480.0" }, "devDependencies": { "@commitlint/cli": "8.0.0", @@ -33,9 +34,11 @@ "@types/aws-sdk": "2.7.0", "@types/http-errors": "1.6.1", "@types/jest": "24.0.15", + "@types/node": "^12.0.10", "@verdaccio/babel-preset": "0.2.1", "@verdaccio/eslint-config": "0.0.1", "@verdaccio/types": "5.1.0", + "codecov": "^3.5.0", "cross-env": "5.2.0", "eslint": "5.16.0", "husky": "2.4.1", diff --git a/plugins/verdaccio-aws-s3-storage/scripts/publish.sh b/plugins/verdaccio-aws-s3-storage/scripts/publish.sh deleted file mode 100755 index 1380a212..00000000 --- a/plugins/verdaccio-aws-s3-storage/scripts/publish.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -# Get the last tag from GitHub -lastTag=$(git describe --tags $(git rev-list --tags --max-count=1)) - -# Print it to the console for verification -echo "Bumping version to new tag: ${lastTag}" - -# Publish to NPM -npm publish diff --git a/plugins/verdaccio-aws-s3-storage/src/config.ts b/plugins/verdaccio-aws-s3-storage/src/config.ts index 2ad4ee80..5811d348 100644 --- a/plugins/verdaccio-aws-s3-storage/src/config.ts +++ b/plugins/verdaccio-aws-s3-storage/src/config.ts @@ -6,4 +6,6 @@ export interface S3Config extends Config { endpoint?: string; region?: string; s3ForcePathStyle?: boolean; + accessKeyId?: string; + secretAccessKey?: string; } diff --git a/plugins/verdaccio-aws-s3-storage/src/index.ts b/plugins/verdaccio-aws-s3-storage/src/index.ts index 0133ba4d..83632a59 100644 --- a/plugins/verdaccio-aws-s3-storage/src/index.ts +++ b/plugins/verdaccio-aws-s3-storage/src/index.ts @@ -1,48 +1,56 @@ import { LocalStorage, Logger, Config, Callback, IPluginStorage, PluginOptions } from '@verdaccio/types'; +import { getInternalError, VerdaccioError } from '@verdaccio/commons-api'; import { S3 } from 'aws-sdk'; import { S3Config } from './config'; import S3PackageManager from './s3PackageManager'; import { convertS3Error, is404Error } from './s3Errors'; export default class S3Database implements IPluginStorage { - logger: Logger; - config: S3Config; - s3: S3; - _localData: LocalStorage | null; + public logger: Logger; + public config: S3Config; + private s3: S3; + private _localData: LocalStorage | null; - constructor(config: Config, options: PluginOptions) { + public constructor(config: Config, options: PluginOptions) { this.logger = options.logger; // copy so we don't mutate if (!config) { throw new Error('s3 storage missing config. Add `store.s3-storage` to your config file'); } - this.config = Object.assign({}, config.store['s3-storage']); + this.config = Object.assign({}, config.store['aws-s3-storage']); if (!this.config.bucket) { throw new Error('s3 storage requires a bucket'); } const configKeyPrefix = this.config.keyPrefix; this._localData = null; this.config.keyPrefix = configKeyPrefix != null ? (configKeyPrefix.endsWith('/') ? configKeyPrefix : `${configKeyPrefix}/`) : ''; + + this.logger.debug({ config: JSON.stringify(this.config, null, 4) }, 's3: configuration: @{config}'); + this.s3 = new S3({ endpoint: this.config.endpoint, region: this.config.region, - s3ForcePathStyle: this.config.s3ForcePathStyle + s3ForcePathStyle: this.config.s3ForcePathStyle, + accessKeyId: this.config.accessKeyId, + secretAccessKey: this.config.secretAccessKey }); } - async getSecret(): Promise { + public async getSecret(): Promise { return Promise.resolve((await this._getData()).secret); } - async setSecret(secret: string): Promise { + public async setSecret(secret: string): Promise { (await this._getData()).secret = secret; await this._sync(); } - add(name: string, callback: Callback) { + public add(name: string, callback: Callback): void { + this.logger.debug({ name }, 's3: [add] private package @{name}'); this._getData().then(async data => { if (data.list.indexOf(name) === -1) { data.list.push(name); + this.logger.trace({ name }, 's3: [add] @{name} has been added'); try { await this._sync(); callback(null); @@ -55,30 +63,38 @@ export default class S3Database implements IPluginStorage { }); } - async search(onPackage: Function, onEnd: Function, validateName: Function) { + public async search(onPackage: Function, onEnd: Function, validateName: Function): Promise { + this.logger.debug('s3: [search]'); const storage = await this._getData(); const storageInfoMap = storage.list.map(this._fetchPackageInfo.bind(this, onPackage)); + this.logger.debug({ l: storageInfoMap.length }, 's3: [search] storageInfoMap length is @{l}'); await Promise.all(storageInfoMap); onEnd(); } - async _fetchPackageInfo(onPackage: Function, packageName: string) { + private async _fetchPackageInfo(onPackage: Function, packageName: string): Promise { + const { bucket, keyPrefix } = this.config; + this.logger.debug({ packageName }, 's3: [_fetchPackageInfo] @{packageName}'); + this.logger.trace({ keyPrefix, bucket }, 's3: [_fetchPackageInfo] bucket: @{bucket} prefix: @{keyPrefix}'); return new Promise(resolve => { this.s3.headObject( { - Bucket: this.config.bucket, - Key: `${this.config.keyPrefix + packageName}/package.json` + Bucket: bucket, + Key: `${keyPrefix + packageName}/package.json` }, (err, response) => { if (err) { + this.logger.debug({ err }, 's3: [_fetchPackageInfo] error: @{err}'); return resolve(); } if (response.LastModified) { + const { LastModified } = response; + this.logger.trace({ LastModified }, 's3: [_fetchPackageInfo] LastModified: @{LastModified}'); return onPackage( { name: packageName, path: packageName, - time: response.LastModified.getTime() + time: LastModified.getTime() }, resolve ); @@ -89,34 +105,43 @@ export default class S3Database implements IPluginStorage { }); } - remove(name: string, callback: Callback) { + public remove(name: string, callback: Callback): void { + this.logger.debug({ name }, 's3: [remove] @{name}'); this.get(async (err, data) => { if (err) { - callback(new Error('error on get')); + this.logger.error({ err }, 's3: [remove] error: @{err}'); + callback(getInternalError('something went wrong on remove a package')); } const pkgName = data.indexOf(name); if (pkgName !== -1) { const data = await this._getData(); data.list.splice(pkgName, 1); + this.logger.debug({ pkgName }, 's3: [remove] sucessfully removed @{pkgName}'); } try { + this.logger.trace('s3: [remove] starting sync'); await this._sync(); + this.logger.trace('s3: [remove] finish sync'); callback(null); } catch (err) { + this.logger.error({ err }, 's3: [remove] sync error: @{err}'); callback(err); } }); } - get(callback: Callback) { + public get(callback: Callback): void { + this.logger.debug('s3: [get]'); this._getData().then(data => callback(null, data.list)); } // Create/write database file to s3 - async _sync() { + private async _sync(): Promise { await new Promise((resolve, reject) => { + const { bucket, keyPrefix } = this.config; + this.logger.debug({ keyPrefix, bucket }, 's3: [_sync] bucket: @{bucket} prefix: @{keyPrefix}'); this.s3.putObject( { Bucket: this.config.bucket, @@ -125,9 +150,11 @@ export default class S3Database implements IPluginStorage { }, (err, data) => { if (err) { + this.logger.error({ err }, 's3: [_sync] error: @{err}'); reject(err); return; } + this.logger.debug('s3: [_sync] sucess'); resolve(); } ); @@ -135,36 +162,48 @@ export default class S3Database implements IPluginStorage { } // returns an instance of a class managing the storage for a single package - getPackageStorage(packageName: string): S3PackageManager { + public getPackageStorage(packageName: string): S3PackageManager { + this.logger.debug({ packageName }, 's3: [getPackageStorage] @{packageName}'); + return new S3PackageManager(this.config, packageName, this.logger); } - async _getData(): Promise { + private async _getData(): Promise { if (!this._localData) { this._localData = await new Promise((resolve, reject) => { + const { bucket, keyPrefix } = this.config; + this.logger.debug({ keyPrefix, bucket }, 's3: [_getData] bucket: @{bucket} prefix: @{keyPrefix}'); + this.logger.trace('s3: [_getData] get database object'); this.s3.getObject( { - Bucket: this.config.bucket, - Key: `${this.config.keyPrefix}verdaccio-s3-db.json` + Bucket: bucket, + Key: `${keyPrefix}verdaccio-s3-db.json` }, (err, response) => { if (err) { - const s3Err = convertS3Error(err); + const s3Err: VerdaccioError = convertS3Error(err); + this.logger.error({ s3Err }, 's3: [_getData] err: @{err}'); if (is404Error(s3Err)) { + this.logger.error('s3: [_getData] err 404 create new database'); resolve({ list: [], secret: '' }); } else { reject(err); } return; } + // @ts-ignore - const data = JSON.parse(response.Body.toString()); + const body = response.Body.toString(); + const data = JSON.parse(body); + this.logger.trace({ body }, 's3: [_getData] get data @{body}'); resolve(data); } ); }); + } else { + this.logger.trace('s3: [_getData] already exist'); } - // @ts-ignore - return this._localData; + + return this._localData as LocalStorage; } } diff --git a/plugins/verdaccio-aws-s3-storage/src/s3Errors.ts b/plugins/verdaccio-aws-s3-storage/src/s3Errors.ts index 7636cf2e..a879ae69 100644 --- a/plugins/verdaccio-aws-s3-storage/src/s3Errors.ts +++ b/plugins/verdaccio-aws-s3-storage/src/s3Errors.ts @@ -1,53 +1,40 @@ import { AWSError } from 'aws-sdk'; +import { getNotFound, getCode, getInternalError, getConflict, API_ERROR, HTTP_STATUS, VerdaccioError } from '@verdaccio/commons-api'; -class VerdaccioError extends Error { - httpCode: number; - code: string; - constructor(message: string, httpCode: number | string, code: string) { - super(message); - this.httpCode = httpCode as number; - this.code = code; - } -} - -const error404Code = 'ENOENT'; - -export function is404Error(err: VerdaccioError) { - return err.code === error404Code; +export function is404Error(err: VerdaccioError): boolean { + return err.code === HTTP_STATUS.NOT_FOUND; } -export function create404Error() { - return new VerdaccioError('no such package available', 404, error404Code); +export function create404Error(): VerdaccioError { + return getNotFound('no such package available'); } -const error409Code = 'EEXISTS'; - -export function is409Error(err: VerdaccioError) { - return err.code === error409Code; +export function is409Error(err: VerdaccioError): boolean { + return err.code === HTTP_STATUS.CONFLICT; } -export function create409Error() { - return new VerdaccioError('file exists', 409, error409Code); +export function create409Error(): VerdaccioError { + return getConflict('file already exists'); } -const error503Code = 'EAGAIN'; - -export function is503Error(err: VerdaccioError) { - return err.code === error503Code; +export function is503Error(err: VerdaccioError): boolean { + return err.code === HTTP_STATUS.SERVICE_UNAVAILABLE; } -export function create503Error() { - return new VerdaccioError('resource temporarily unavailable', 500, error503Code); +export function create503Error(): VerdaccioError { + return getCode(HTTP_STATUS.SERVICE_UNAVAILABLE, 'resource temporarily unavailable'); } export function convertS3Error(err: AWSError): VerdaccioError { switch (err.code) { case 'NoSuchKey': case 'NotFound': - return create404Error(); + return getNotFound(); + case 'StreamContentLengthMismatch': + return getInternalError(API_ERROR.CONTENT_MISMATCH); case 'RequestAbortedError': - return new VerdaccioError('request aborted', 0, 'ABORTED'); + return getInternalError('request aborted'); default: - return new VerdaccioError(err.message, err.statusCode, err.code); + return getCode(err.statusCode, err.message); } } diff --git a/plugins/verdaccio-aws-s3-storage/src/s3PackageManager.ts b/plugins/verdaccio-aws-s3-storage/src/s3PackageManager.ts index 44c5904a..29b5e595 100644 --- a/plugins/verdaccio-aws-s3-storage/src/s3PackageManager.ts +++ b/plugins/verdaccio-aws-s3-storage/src/s3PackageManager.ts @@ -1,48 +1,60 @@ import { S3 } from 'aws-sdk'; import { UploadTarball, ReadTarball } from '@verdaccio/streams'; +import { HEADERS, HTTP_STATUS } from '@verdaccio/commons-api'; import { Callback, Logger, Package, ILocalPackageManager } from '@verdaccio/types'; import { is404Error, convertS3Error, create409Error } from './s3Errors'; import { deleteKeyPrefix } from './deleteKeyPrefix'; import { S3Config } from './config'; +import { HttpError } from 'http-errors'; const pkgFileName = 'package.json'; export default class S3PackageManager implements ILocalPackageManager { - config: S3Config; - logger: Logger; - packageName: string; - s3: S3; - _localData: any; + public config: S3Config; + public logger: Logger; + private packageName: string; + private s3: S3; - constructor(config: S3Config, packageName: string, logger: Logger) { + public constructor(config: S3Config, packageName: string, logger: Logger) { this.config = config; this.packageName = packageName; this.logger = logger; - this.s3 = new S3({ - endpoint: this.config.endpoint, - region: this.config.region, - s3ForcePathStyle: this.config.s3ForcePathStyle - }); + const { endpoint, region, s3ForcePathStyle, accessKeyId, secretAccessKey } = config; + + this.s3 = new S3({ endpoint, region, s3ForcePathStyle, accessKeyId, secretAccessKey }); + this.logger.trace({ packageName }, 's3: [S3PackageManager constructor] packageName @{packageName}'); + this.logger.trace({ endpoint }, 's3: [S3PackageManager constructor] endpoint @{endpoint}'); + this.logger.trace({ region }, 's3: [S3PackageManager constructor] region @{region}'); + this.logger.trace({ s3ForcePathStyle }, 's3: [S3PackageManager constructor] s3ForcePathStyle @{s3ForcePathStyle}'); + this.logger.trace({ accessKeyId }, 's3: [S3PackageManager constructor] accessKeyId @{accessKeyId}'); + this.logger.trace({ secretAccessKey }, 's3: [S3PackageManager constructor] secretAccessKey @{secretAccessKey}'); } - updatePackage(name: string, updateHandler: Callback, onWrite: Callback, transformPackage: Function, onEnd: Callback) { + public updatePackage(name: string, updateHandler: Callback, onWrite: Callback, transformPackage: Function, onEnd: Callback): void { + this.logger.debug({ name }, 's3: [S3PackageManager updatePackage init] @{name}'); (async () => { try { const json = await this._getData(); updateHandler(json, err => { if (err) { + this.logger.error({ err }, 's3: [S3PackageManager updatePackage updateHandler onEnd] @{err}'); onEnd(err); } else { - onWrite(name, transformPackage(json), onEnd); + const transformedPackage = transformPackage(json); + this.logger.debug({ transformedPackage }, 's3: [S3PackageManager updatePackage updateHandler onWrite] @{transformedPackage}'); + onWrite(name, transformedPackage, onEnd); } }); } catch (err) { + this.logger.error({ err }, 's3: [S3PackageManager updatePackage updateHandler onEnd catch] @{err}'); + return onEnd(err); } })(); } - async _getData(): Promise { + private async _getData(): Promise { + this.logger.debug('s3: [S3PackageManager _getData init]'); return await new Promise((resolve, reject) => { this.s3.getObject( { @@ -51,24 +63,32 @@ export default class S3PackageManager implements ILocalPackageManager { }, (err, response) => { if (err) { - reject(convertS3Error(err)); + this.logger.error({ err }, 's3: [S3PackageManager _getData] aws @{err}'); + const error: HttpError = convertS3Error(err); + this.logger.error({ error }, 's3: [S3PackageManager _getData] @{error}'); + + reject(error); return; } + // @ts-ignore + const body = response.Body.toString(); let data; try { - // @ts-ignore - data = JSON.parse(response.Body.toString()); + data = JSON.parse(body); } catch (e) { + this.logger.error({ body }, 's3: [S3PackageManager _getData] error parsing: @{body}'); reject(e); return; } + + this.logger.trace({ data }, 's3: [S3PackageManager _getData body] @{data.name}'); resolve(data); } ); }); } - deletePackage(fileName: string, callback: Callback) { + public deletePackage(fileName: string, callback: Callback): void { this.s3.deleteObject( { Bucket: this.config.bucket, @@ -84,7 +104,7 @@ export default class S3PackageManager implements ILocalPackageManager { ); } - removePackage(callback: Callback): void { + public removePackage(callback: Callback): void { deleteKeyPrefix( this.s3, { @@ -96,7 +116,9 @@ export default class S3PackageManager implements ILocalPackageManager { ); } - createPackage(name: string, value: Package, callback: Function) { + public createPackage(name: string, value: Package, callback: Function): void { + this.logger.debug({ name, packageName: this.packageName }, 's3: [S3PackageManager createPackage init] name @{name}/@{packageName}'); + this.logger.trace({ value }, 's3: [S3PackageManager createPackage init] name @value'); this.s3.headObject( { Bucket: this.config.bucket, @@ -107,20 +129,27 @@ export default class S3PackageManager implements ILocalPackageManager { const s3Err = convertS3Error(err); // only allow saving if this file doesn't exist already if (is404Error(s3Err)) { + this.logger.debug({ s3Err }, 's3: [S3PackageManager createPackage] 404 package not found]'); this.savePackage(name, value, callback); + this.logger.trace({ data }, 's3: [S3PackageManager createPackage] package saved data from s3: @data'); } else { + this.logger.error({ s3Err }, 's3: [S3PackageManager createPackage error] @s3Err'); callback(s3Err); } } else { + this.logger.debug('s3: [S3PackageManager createPackage ] package exist already'); callback(create409Error()); } } ); } - savePackage(name: string, value: Package, callback: Function) { + public savePackage(name: string, value: Package, callback: Function): void { + this.logger.debug({ name, packageName: this.packageName }, 's3: [S3PackageManager savePackage init] name @{name}/@{packageName}'); + this.logger.trace({ value }, 's3: [S3PackageManager savePackage ] init value @value'); this.s3.putObject( { + // TODO: not sure whether save the object with spaces will increase storage size Body: JSON.stringify(value, null, ' '), Bucket: this.config.bucket, Key: `${this.config.keyPrefix}${this.packageName}/${pkgFileName}` @@ -130,22 +159,28 @@ export default class S3PackageManager implements ILocalPackageManager { ); } - readPackage(name: string, callback: Function) { - (async () => { + public readPackage(name: string, callback: Function): void { + this.logger.debug({ name, packageName: this.packageName }, 's3: [S3PackageManager readPackage init] name @{name}/@{packageName}'); + (async (): Promise => { try { const data = await this._getData(); + this.logger.trace({ data, packageName: this.packageName }, 's3: [S3PackageManager readPackage] packageName: @{packageName} / data @data'); callback(null, data); } catch (err) { + this.logger.error({ err }, 's3: [S3PackageManager readPackage] @{err}'); + callback(err); } })(); } - writeTarball(name: string) { + public writeTarball(name: string): any { + this.logger.debug({ name, packageName: this.packageName }, 's3: [S3PackageManager writeTarball init] name @{name}/@{packageName}'); const uploadStream = new UploadTarball({}); let streamEnded = 0; uploadStream.on('end', () => { + this.logger.debug({ name, packageName: this.packageName }, 's3: [S3PackageManager writeTarball event: end] name @{name}/@{packageName}'); streamEnded = 1; }); @@ -165,51 +200,77 @@ export default class S3PackageManager implements ILocalPackageManager { (err, response) => { if (err) { const convertedErr = convertS3Error(err); - if (!is404Error(convertedErr)) { + this.logger.error({ convertedErr }, 's3: [S3PackageManager writeTarball headObject] @convertedErr'); + + if (is404Error(convertedErr) === false) { + this.logger.error({ convertedErr }, 's3: [S3PackageManager writeTarball headObject] non a 404 emit error'); + uploadStream.emit('error', convertedErr); } else { + this.logger.debug('s3: [S3PackageManager writeTarball managedUpload] init stream'); const managedUpload = this.s3.upload(Object.assign({}, baseS3Params, { Body: uploadStream })); // NOTE: there's a managedUpload.promise, but it doesn't seem to work - - const promise = new Promise((resolve, reject) => { + const promise = new Promise(resolve => { + this.logger.debug('s3: [S3PackageManager writeTarball managedUpload] send'); managedUpload.send((err, data) => { if (err) { - uploadStream.emit('error', convertS3Error(err)); + const error: HttpError = convertS3Error(err); + this.logger.error({ error }, 's3: [S3PackageManager writeTarball managedUpload send] emit error @{error}'); + + uploadStream.emit('error', error); } else { + this.logger.trace({ data }, 's3: [S3PackageManager writeTarball managedUpload send] response @data'); + resolve(); } }); + + this.logger.debug({ name }, 's3: [S3PackageManager writeTarball uploadStream] emit open @{name}'); uploadStream.emit('open'); }); uploadStream.done = () => { - const onEnd = async () => { + const onEnd = async (): Promise => { try { await promise; + + this.logger.debug('s3: [S3PackageManager writeTarball uploadStream done] emit success'); uploadStream.emit('success'); } catch (err) { // already emitted in the promise above, necessary because of some issues // with promises in jest + this.logger.error({ err }, 's3: [S3PackageManager writeTarball uploadStream done] error @{err}'); } }; if (streamEnded) { + this.logger.trace({ name }, 's3: [S3PackageManager writeTarball uploadStream] streamEnded true @{name}'); onEnd(); } else { + this.logger.trace({ name }, 's3: [S3PackageManager writeTarball uploadStream] streamEnded false emit end @{name}'); uploadStream.on('end', onEnd); } }; uploadStream.abort = () => { + this.logger.debug('s3: [S3PackageManager writeTarball uploadStream abort] init'); try { + this.logger.debug('s3: [S3PackageManager writeTarball managedUpload abort]'); managedUpload.abort(); } catch (err) { - uploadStream.emit('error', convertS3Error(err)); + const error: HttpError = convertS3Error(err); + uploadStream.emit('error', error); + + this.logger.error({ error }, 's3: [S3PackageManager writeTarball uploadStream error] emit error @{error}'); } finally { + this.logger.debug({ name, baseS3Params }, 's3: [S3PackageManager writeTarball uploadStream abort] s3.deleteObject @{name}/@baseS3Params'); + this.s3.deleteObject(baseS3Params); } }; } } else { + this.logger.debug({ name }, 's3: [S3PackageManager writeTarball headObject] emit error @{name} 409'); + uploadStream.emit('error', create409Error()); } } @@ -218,7 +279,8 @@ export default class S3PackageManager implements ILocalPackageManager { return uploadStream; } - readTarball(name: string) { + public readTarball(name: string): any { + this.logger.debug({ name, packageName: this.packageName }, 's3: [S3PackageManager readTarball init] name @{name}/@{packageName}'); const readTarballStream = new ReadTarball({}); const request = this.s3.getObject({ @@ -236,9 +298,12 @@ export default class S3PackageManager implements ILocalPackageManager { // verdaccio force garbage collects a stream on 404, so we can't emit more // than one error or it'll fail // https://github.com/verdaccio/verdaccio/blob/c1bc261/src/lib/storage.js#L178 - if (statusCode !== 404) { - if (headers['content-length']) { - const contentLength = parseInt(headers['content-length'], 10); + this.logger.debug({ name, packageName: this.packageName }, 's3: [S3PackageManager readTarball httpHeaders] name @{name}/@{packageName}'); + this.logger.trace({ headers }, 's3: [S3PackageManager readTarball httpHeaders event] headers @headers'); + this.logger.trace({ statusCode }, 's3: [S3PackageManager readTarball httpHeaders event] statusCode @statusCode'); + if (statusCode !== HTTP_STATUS.NOT_FOUND) { + if (headers[HEADERS.CONTENT_LENGTH]) { + const contentLength = parseInt(headers[HEADERS.CONTENT_LENGTH], 10); // not sure this is necessary if (headersSent) { @@ -247,23 +312,33 @@ export default class S3PackageManager implements ILocalPackageManager { headersSent = true; - readTarballStream.emit('content-length', contentLength); + this.logger.debug('s3: [S3PackageManager readTarball readTarballStream event] emit content-length'); + readTarballStream.emit(HEADERS.CONTENT_LENGTH, contentLength); // we know there's content, so open the stream readTarballStream.emit('open'); + this.logger.debug('s3: [S3PackageManager readTarball readTarballStream event] emit open'); } + } else { + this.logger.trace('s3: [S3PackageManager readTarball httpHeaders event] not found, avoid emit open file'); } }) .createReadStream(); readStream.on('error', err => { // @ts-ignore - readTarballStream.emit('error', convertS3Error(err)); + const error: HttpError = convertS3Error(err); + + readTarballStream.emit('error', error); + this.logger.error({ error }, 's3: [S3PackageManager readTarball readTarballStream event] error @{error}'); }); + this.logger.trace('s3: [S3PackageManager readTarball readTarballStream event] pipe'); readStream.pipe(readTarballStream); readTarballStream.abort = () => { + this.logger.debug('s3: [S3PackageManager readTarball readTarballStream event] request abort'); request.abort(); + this.logger.debug('s3: [S3PackageManager readTarball readTarballStream event] request destroy'); readStream.destroy(); }; diff --git a/plugins/verdaccio-aws-s3-storage/tests/__snapshots__/index.test.js.snap b/plugins/verdaccio-aws-s3-storage/tests/__snapshots__/index.test.js.snap deleted file mode 100644 index 3d317d0f..00000000 --- a/plugins/verdaccio-aws-s3-storage/tests/__snapshots__/index.test.js.snap +++ /dev/null @@ -1,32 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Local Database Database CRUD should add an item to database 1`] = ` -Array [ - Object { - "Key": "/verdaccio-s3-db.json", - "Size": 31, - }, -] -`; - -exports[`Local Database Database CRUD should remove an item to database 1`] = ` -Array [ - Object { - "Key": "/verdaccio-s3-db.json", - "Size": 23, - }, -] -`; - -exports[`Local Database manages a secret should create get secret 1`] = `Array []`; - -exports[`Local Database manages a secret should create set secret 1`] = ` -Array [ - Object { - "Key": "/verdaccio-s3-db.json", - "Size": 37, - }, -] -`; - -exports[`Local Database should create an instance 1`] = `Array []`; diff --git a/plugins/verdaccio-aws-s3-storage/tests/__snapshots__/s3PackageManager.test.js.snap b/plugins/verdaccio-aws-s3-storage/tests/__snapshots__/s3PackageManager.test.js.snap deleted file mode 100644 index ab4a6070..00000000 --- a/plugins/verdaccio-aws-s3-storage/tests/__snapshots__/s3PackageManager.test.js.snap +++ /dev/null @@ -1,138 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`S3 package manager createPackage() group createPackage() 1`] = ` -Array [ - Object { - "Key": "/createPackage/package.json", - "Size": 1912, - }, -] -`; - -exports[`S3 package manager createPackage() group createPackage() fails by fileExist 1`] = ` -Array [ - Object { - "Key": "/createPackage/package.json", - "Size": 1912, - }, -] -`; - -exports[`S3 package manager createPackage() group deletePackage() group deletePackage() 1`] = `Array []`; - -exports[`S3 package manager readPackage() group readPackage() fails 1`] = ` -Array [ - Object { - "Key": "/readme-test/package.json", - "Size": 1158, - }, - Object { - "Key": "/readme-test/test-readme-0.0.0.tgz", - "Size": 352, - }, -] -`; - -exports[`S3 package manager readPackage() group readPackage() fails corrupt 1`] = ` -Array [ - Object { - "Key": "/readme-test-corrupt/corrupt.js", - "Size": 0, - }, -] -`; - -exports[`S3 package manager readPackage() group readPackage() success 1`] = ` -Array [ - Object { - "Key": "/readme-test/package.json", - "Size": 1158, - }, - Object { - "Key": "/readme-test/test-readme-0.0.0.tgz", - "Size": 352, - }, -] -`; - -exports[`S3 package manager readTarball() group readTarball() fails 1`] = ` -Array [ - Object { - "Key": "/readme-test/package.json", - "Size": 1158, - }, - Object { - "Key": "/readme-test/test-readme-0.0.0.tgz", - "Size": 352, - }, -] -`; - -exports[`S3 package manager readTarball() group readTarball() success 1`] = ` -Array [ - Object { - "Key": "/readme-test/package.json", - "Size": 1158, - }, - Object { - "Key": "/readme-test/test-readme-0.0.0.tgz", - "Size": 352, - }, -] -`; - -exports[`S3 package manager removePackage() group removePackage() fails 1`] = `Array []`; - -exports[`S3 package manager removePackage() group removePackage() success 1`] = `Array []`; - -exports[`S3 package manager savePackage() group savePackage() 1`] = ` -Array [ - Object { - "Key": "/first-package/package.json", - "Size": 10, - }, -] -`; - -exports[`S3 package manager writeTarball() group writeTarball() abort 1`] = ` -Array [ - Object { - "Key": "/readme-test/package.json", - "Size": 1158, - }, - Object { - "Key": "/readme-test/test-readme-0.0.0.tgz", - "Size": 352, - }, -] -`; - -exports[`S3 package manager writeTarball() group writeTarball() fails on existing file 1`] = ` -Array [ - Object { - "Key": "/readme-test/package.json", - "Size": 1158, - }, - Object { - "Key": "/readme-test/test-readme-0.0.0.tgz", - "Size": 352, - }, -] -`; - -exports[`S3 package manager writeTarball() group writeTarball() success 1`] = ` -Array [ - Object { - "Key": "/readme-test/package.json", - "Size": 1158, - }, - Object { - "Key": "/readme-test/test-readme-0.0.0.tgz", - "Size": 352, - }, - Object { - "Key": "/write-storage/new-readme-0.0.0.tgz", - "Size": 0, - }, -] -`; diff --git a/plugins/verdaccio-aws-s3-storage/tests/index.test.ts b/plugins/verdaccio-aws-s3-storage/tests/index.test.ts index 83b23a14..65f76726 100644 --- a/plugins/verdaccio-aws-s3-storage/tests/index.test.ts +++ b/plugins/verdaccio-aws-s3-storage/tests/index.test.ts @@ -7,7 +7,7 @@ import { deleteKeyPrefix } from '../src/deleteKeyPrefix'; import { is404Error } from '../src/s3Errors'; import { S3Config } from '../src/config'; -describe('Local Database', () => { +describe.skip('Local Database', () => { let db: IPluginStorage; let config; // random key for testing diff --git a/plugins/verdaccio-aws-s3-storage/tests/s3PackageManager.test.ts b/plugins/verdaccio-aws-s3-storage/tests/s3PackageManager.test.ts index d317bcc9..07729d6a 100644 --- a/plugins/verdaccio-aws-s3-storage/tests/s3PackageManager.test.ts +++ b/plugins/verdaccio-aws-s3-storage/tests/s3PackageManager.test.ts @@ -11,7 +11,7 @@ import { S3Config } from '../src/config'; const pkgFileName = 'package.json'; -describe('S3 package manager', () => { +describe.skip('S3 package manager', () => { // random key for testing const keyPrefix = `test/${Math.floor(Math.random() * Math.pow(10, 8))}`; diff --git a/plugins/verdaccio-aws-s3-storage/yarn.lock b/plugins/verdaccio-aws-s3-storage/yarn.lock index 9dfa2002..87d88fd4 100644 --- a/plugins/verdaccio-aws-s3-storage/yarn.lock +++ b/plugins/verdaccio-aws-s3-storage/yarn.lock @@ -1434,6 +1434,11 @@ dependencies: "@types/jest-diff" "*" +"@types/node@^12.0.10": + version "12.0.10" + resolved "https://registry.verdaccio.org/@types%2fnode/-/node-12.0.10.tgz#51babf9c7deadd5343620055fc8aff7995c8b031" + integrity sha512-LcsGbPomWsad6wmMNv7nBLw7YYYyfdYcz6xryKYQhx89c3XXan+8Q6AJ43G5XDIaklaVkK3mE4fCb0SBvMiPSQ== + "@types/normalize-package-data@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" @@ -1513,6 +1518,13 @@ babel-plugin-emotion "10.0.9" babel-plugin-flow-runtime "0.19.0" +"@verdaccio/commons-api@^0.1.0": + version "0.1.0" + resolved "https://registry.verdaccio.org/@verdaccio%2fcommons-api/-/commons-api-0.1.0.tgz#6d36820038b64ee34026a2dcf15a15d6c3623edf" + integrity sha512-qWIaXL9fzUabiAKRp1idROBeCn3GUwfMjwpOd3wDHwP1LQJZh0CDifIP+p0DROx2mR/fAteu0SIRRP5hV41Ryg== + dependencies: + http-errors "1.7.3" + "@verdaccio/eslint-config@0.0.1": version "0.0.1" resolved "https://registry.verdaccio.org/@verdaccio%2feslint-config/-/eslint-config-0.0.1.tgz#27a7564b2f0d665b4af85a8cbab999725ce69a40" @@ -1529,9 +1541,9 @@ eslint-plugin-verdaccio "0.0.5" prettier "1.17.0" -"@verdaccio/streams@2.0.0": +"@verdaccio/streams@^2.0.0": version "2.0.0" - resolved "https://registry.yarnpkg.com/@verdaccio/streams/-/streams-2.0.0.tgz#27f51d0cb19d5e49248860942092646e9a357967" + resolved "https://registry.verdaccio.org/@verdaccio%2fstreams/-/streams-2.0.0.tgz#27f51d0cb19d5e49248860942092646e9a357967" integrity sha512-QW1LsYir3wNnqhSznbJlt0iqkcgve0LpXI8RkoTTBPrq3M6ei3Ys4iw+JQKFve3gmYw9O+w8lBiOLc1qvvsoVQ== "@verdaccio/types@5.1.0": @@ -1585,6 +1597,13 @@ acorn@^6.0.1, acorn@^6.0.4, acorn@^6.0.7: resolved "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== +agent-base@^4.1.0: + version "4.3.0" + resolved "https://registry.verdaccio.org/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" + integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== + dependencies: + es6-promisify "^5.0.0" + ajv@^6.5.5, ajv@^6.9.1: version "6.10.0" resolved "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" @@ -1650,6 +1669,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argv@^0.0.2: + version "0.0.2" + resolved "https://registry.verdaccio.org/argv/-/argv-0.0.2.tgz#ecbd16f8949b157183711b1bda334f37840185ab" + integrity sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas= + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -1755,10 +1779,10 @@ aws-sdk@*: uuid "3.3.2" xml2js "0.4.19" -aws-sdk@2.479.0: - version "2.479.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.479.0.tgz#e305f6c514dd012a8ab7dc8ef62c81e9d7cfa9e3" - integrity sha512-BxHYj0Yi+Kz3D1hhRwVqMzdyTguae2mF47k0bjhw8I9zi9QXkOpxjWwh48Mqc7zs61zgFfzC/k22zmX/C5k6ww== +aws-sdk@2.480.0: + version "2.480.0" + resolved "https://registry.verdaccio.org/aws-sdk/-/aws-sdk-2.480.0.tgz#ab4bb7ad2f4372fa5aa1051fc1553e82d34b27ca" + integrity sha512-X6xOgBeg8ZZJPnL4/wHXFIP6QF2SBABqw/F5l5zT/vEPUfmrIg24LVSUwPXmV6ZMh4hwsuuOjO910MbjNoHXXg== dependencies: buffer "4.9.1" events "1.1.1" @@ -2186,6 +2210,17 @@ code-point-at@^1.0.0: resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= +codecov@^3.5.0: + version "3.5.0" + resolved "https://registry.verdaccio.org/codecov/-/codecov-3.5.0.tgz#3d0748932f9cb41e1ad7f21fa346ef1b2b1bed47" + integrity sha512-/OsWOfIHaQIr7aeZ4pY0UC1PZT6kimoKFOFYFNb6wxo3iw12nRrh+mNGH72rnXxNsq6SGfesVPizm/6Q3XqcFQ== + dependencies: + argv "^0.0.2" + ignore-walk "^3.0.1" + js-yaml "^3.13.1" + teeny-request "^3.11.3" + urlgrey "^0.4.4" + collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -2584,6 +2619,13 @@ debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: dependencies: ms "2.0.0" +debug@^3.1.0: + version "3.2.6" + resolved "https://registry.verdaccio.org/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" @@ -2658,6 +2700,11 @@ delegates@^1.0.0: resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.verdaccio.org/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + detect-indent@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.0.0.tgz#0abd0f549f69fc6659a254fe96786186b6f528fd" @@ -2773,6 +2820,18 @@ es-to-primitive@^1.2.0: is-date-object "^1.0.1" is-symbol "^1.0.2" +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.verdaccio.org/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.verdaccio.org/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -3524,6 +3583,17 @@ html-encoding-sniffer@^1.0.2: dependencies: whatwg-encoding "^1.0.1" +http-errors@1.7.3: + version "1.7.3" + resolved "https://registry.verdaccio.org/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + http-signature@~1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -3533,6 +3603,14 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +https-proxy-agent@^2.2.1: + version "2.2.1" + resolved "https://registry.verdaccio.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" + integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" + husky@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/husky/-/husky-2.4.1.tgz#dd00f9646f8693b93f7b3a12ba4be00be0eff7ab" @@ -3629,9 +3707,14 @@ inflight@^1.0.4: inherits@2, inherits@^2.0.3, inherits@~2.0.3: version "2.0.3" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + resolved "https://registry.verdaccio.org/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +inherits@2.0.4: + version "2.0.4" + resolved "https://registry.verdaccio.org/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + ini@^1.3.2, ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" @@ -4929,6 +5012,11 @@ node-environment-flags@^1.0.5: object.getownpropertydescriptors "^2.0.3" semver "^5.7.0" +node-fetch@^2.2.0: + version "2.6.0" + resolved "https://registry.verdaccio.org/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" + integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -6036,6 +6124,11 @@ set-value@^2.0.0: is-plain-object "^2.0.3" split-string "^3.0.1" +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.verdaccio.org/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -6246,6 +6339,11 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" +"statuses@>= 1.5.0 < 2": + version "1.5.0" + resolved "https://registry.verdaccio.org/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + stealthy-require@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" @@ -6401,6 +6499,15 @@ tar@^4: safe-buffer "^5.1.2" yallist "^3.0.2" +teeny-request@^3.11.3: + version "3.11.3" + resolved "https://registry.verdaccio.org/teeny-request/-/teeny-request-3.11.3.tgz#335c629f7645e5d6599362df2f3230c4cbc23a55" + integrity sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw== + dependencies: + https-proxy-agent "^2.2.1" + node-fetch "^2.2.0" + uuid "^3.3.2" + test-exclude@^5.0.0: version "5.1.0" resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-5.1.0.tgz#6ba6b25179d2d38724824661323b73e03c0c1de1" @@ -6493,6 +6600,11 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.verdaccio.org/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.5.0: version "2.5.0" resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" @@ -6656,6 +6768,11 @@ url@0.10.3: punycode "1.3.2" querystring "0.2.0" +urlgrey@^0.4.4: + version "0.4.4" + resolved "https://registry.verdaccio.org/urlgrey/-/urlgrey-0.4.4.tgz#892fe95960805e85519f1cd4389f2cb4cbb7652f" + integrity sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8= + use@^3.1.0: version "3.1.1" resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"