From d1b3e6e3b5556594cd1d927bd274eeb345e7ee21 Mon Sep 17 00:00:00 2001 From: "Juan Picado @jotadeveloper" Date: Sun, 13 Oct 2019 10:27:01 +0200 Subject: [PATCH] build: e2e integration with puppeteer (#192) * build: add e2e testing scripts * build: add e2e testing scripts * chore: fix script * chore: fix script * chore: ignore e2e normal test * chore: fix node_latest_browser * chore: move lint to prepare * chore: fix lint * chore: add local theme * fix: e2e tests --- .circleci/config.yml | 36 +- jest/jest.config.js | 10 +- package.json | 13 +- test/e2e/.eslintrc | 11 + test/e2e/config/config-protected-e2e.yaml | 31 ++ test/e2e/config/config-scoped-e2e.yaml | 34 ++ test/e2e/e2e.spec.js | 193 ++++++++++ test/e2e/partials/pkg-protected.js | 50 +++ test/e2e/partials/pkg-scoped.js | 50 +++ test/e2e/plugins/theme.js | 6 + test/e2e/pre-setup.js | 4 + test/e2e/puppeteer_environment.js | 75 ++++ test/e2e/registry-launcher.ts | 60 +++ test/e2e/request.ts | 137 +++++++ test/e2e/server.ts | 265 +++++++++++++ test/e2e/setup.js | 17 + test/e2e/teardown.js | 13 + test/jest.config.e2e.js | 27 ++ yarn.lock | 438 ++++++++++++++++------ 19 files changed, 1328 insertions(+), 142 deletions(-) create mode 100644 test/e2e/.eslintrc create mode 100644 test/e2e/config/config-protected-e2e.yaml create mode 100644 test/e2e/config/config-scoped-e2e.yaml create mode 100644 test/e2e/e2e.spec.js create mode 100644 test/e2e/partials/pkg-protected.js create mode 100644 test/e2e/partials/pkg-scoped.js create mode 100644 test/e2e/plugins/theme.js create mode 100644 test/e2e/pre-setup.js create mode 100644 test/e2e/puppeteer_environment.js create mode 100644 test/e2e/registry-launcher.ts create mode 100644 test/e2e/request.ts create mode 100644 test/e2e/server.ts create mode 100644 test/e2e/setup.js create mode 100644 test/e2e/teardown.js create mode 100644 test/jest.config.e2e.js diff --git a/.circleci/config.yml b/.circleci/config.yml index a6ff13b..cbdf419 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,6 +5,9 @@ aliases: ~/ui-theme - &defaults working_directory: *repo_path + - &node_latest_browser + docker: + - image: circleci/node:latest-browsers - &node_latest_executor docker: - image: circleci/node:latest @@ -47,9 +50,12 @@ jobs: - run: name: Install dependencies command: yarn install --frozen-lockfile + - run: + name: Lint code + command: yarn lint - run: name: Build project - command: yarn run build + command: yarn build - save_cache: key: *yarn_cache_key paths: @@ -61,15 +67,6 @@ jobs: paths: - ./* - lint: - <<: *defaults - <<: *default_executor - steps: - - *restore_repo - - run: - name: Lint code - command: yarn lint - test_bundlesize: <<: *defaults <<: *default_executor @@ -92,6 +89,15 @@ jobs: paths: - coverage + test_e2e: + <<: *defaults + <<: *node_latest_browser + steps: + - *restore_repo + - run: + name: Test E2E Node (LTS) + command: yarn test:e2e + test_node_lts: <<: *defaults <<: *node_lts_executor @@ -138,10 +144,6 @@ workflows: jobs: - prepare: <<: *ignore_non_dev_branches - - lint: - requires: - - prepare - <<: *ignore_non_dev_branches - test_bundlesize: requires: - prepare @@ -154,15 +156,19 @@ workflows: requires: - prepare <<: *ignore_non_dev_branches + - test_e2e: + requires: + - prepare + <<: *ignore_non_dev_branches - coverage: requires: - test_node_latest <<: *ignore_non_dev_branches - publish_package: requires: - - lint - test_bundlesize - test_node_latest - test_node_lts + - test_e2e - coverage <<: *execute_on_release diff --git a/jest/jest.config.js b/jest/jest.config.js index 1658072..7b31e3b 100644 --- a/jest/jest.config.js +++ b/jest/jest.config.js @@ -11,7 +11,15 @@ module.exports = { rootDir: '..', setupFiles: ['/jest/setup.ts'], transformIgnorePatterns: ['/node_modules/(?!react-syntax-highlighter)'], - modulePathIgnorePatterns: ['/coverage', '/scripts', '/.circleci', '/tools', '/build', '/.vscode/'], + modulePathIgnorePatterns: [ + '/coverage', + '/scripts', + '/.circleci', + '/tools', + '/build', + '/.vscode/', + '/test/e2e/', + ], snapshotSerializers: ['enzyme-to-json/serializer', 'jest-emotion'], moduleNameMapper: { '\\.(s?css)$': '/node_modules/identity-obj-proxy', diff --git a/package.json b/package.json index b5b9636..fcffa35 100644 --- a/package.json +++ b/package.json @@ -28,10 +28,12 @@ "@types/react": "16.9.2", "@types/react-dom": "16.9.0", "@types/react-router-dom": "5.1.0", + "@types/request": "2.48.3", "@types/validator": "10.11.3", "@types/webpack-env": "1.14.0", "@typescript-eslint/parser": "2.3.2", "@verdaccio/babel-preset": "2.0.0", + "@verdaccio/commons-api": "8.1.2", "@verdaccio/eslint-config": "2.0.0", "@verdaccio/types": "8.1.0", "autosuggest-highlight": "3.1.1", @@ -82,13 +84,14 @@ "ora": "3.4.0", "prettier": "1.18.2", "prop-types": "15.7.2", - "puppeteer": "1.17.0", + "puppeteer": "1.8.0", "react": "16.10.0", "react-autosuggest": "9.4.3", "react-dom": "16.10.0", "react-emotion": "9.2.12", "react-hot-loader": "4.12.11", "react-router-dom": "5.1.2", + "request": "2.88.0", "resolve-url-loader": "3.1.0", "rimraf": "3.0.0", "source-map-loader": "0.2.4", @@ -105,9 +108,10 @@ "uglifyjs-webpack-plugin": "2.2.0", "url-loader": "2.1.0", "validator": "11.1.0", - "verdaccio": "4.2.2", - "verdaccio-auth-memory": "8.1.1", - "verdaccio-memory": "8.1.1", + "verdaccio": "4.3.3", + "verdaccio-auth-memory": "8.1.2", + "verdaccio-memory": "8.1.2", + "wait-on": "3.3.0", "webpack": "4.41.0", "webpack-bundle-analyzer": "3.5.2", "webpack-bundle-size-analyzer": "3.1.0", @@ -156,6 +160,7 @@ "test:clean": "npx jest --clearCache", "test:acceptance": "codeceptjs run --steps", "test:acceptance:server": "concurrently --kill-others \"npm run verdaccio:server\" \"npm run test:acceptance\"", + "test:e2e": "cross-env BABEL_ENV=test jest --config ./test/jest.config.e2e.js", "test": "cross-env NODE_ENV=test BABEL_ENV=test TZ=UTC jest --config ./jest/jest.config.js --maxWorkers 2 --passWithNoTests", "test:size": "bundlesize", "lint": "npm run lint:js && npm run lint:css && npm run lint:lockfile", diff --git a/test/e2e/.eslintrc b/test/e2e/.eslintrc new file mode 100644 index 0000000..ada2d5b --- /dev/null +++ b/test/e2e/.eslintrc @@ -0,0 +1,11 @@ +{ + "rules": { + "@typescript-eslint/no-var-requires": 0, + "@typescript-eslint/explicit-function-return-type": 0, + "@typescript-eslint/no-explicit-any": 0, + "@typescript-eslint/explicit-member-accessibility": 0, + "no-console": 0, + "new-cap": 0, + "max-len": 0 + } +} diff --git a/test/e2e/config/config-protected-e2e.yaml b/test/e2e/config/config-protected-e2e.yaml new file mode 100644 index 0000000..6d6a4c7 --- /dev/null +++ b/test/e2e/config/config-protected-e2e.yaml @@ -0,0 +1,31 @@ +web: + enable: true + title: verdaccio-server-protected-e2e + +store: + memory: + limit: 10 + +auth: + auth-memory: + users: + test: + name: test + password: test + +logs: + - { type: stdout, format: pretty, level: warn } + +packages: + 'protected-*': + access: $authenticated + publish: $authenticated + +theme: + ../plugins/theme: + prop: dummy + +listen: 0.0.0.0:55552 + +# expose internal methods +_debug: true diff --git a/test/e2e/config/config-scoped-e2e.yaml b/test/e2e/config/config-scoped-e2e.yaml new file mode 100644 index 0000000..fd0f891 --- /dev/null +++ b/test/e2e/config/config-scoped-e2e.yaml @@ -0,0 +1,34 @@ +web: + enable: true + title: verdaccio-server-e2e + +store: + memory: + limit: 10 + +auth: + auth-memory: + users: + test: + name: test + password: test + +logs: + - { type: stdout, format: pretty, level: warn } + +packages: + '@*/*': + access: $all + publish: $all + '**': + access: $all + publish: $authenticated + +theme: + ../plugins/theme: + prop: dummy + +listen: 0.0.0.0:55558 + +# expose internal methods +_debug: true diff --git a/test/e2e/e2e.spec.js b/test/e2e/e2e.spec.js new file mode 100644 index 0000000..4c2aa36 --- /dev/null +++ b/test/e2e/e2e.spec.js @@ -0,0 +1,193 @@ +const scopedPackageMetadata = require('./partials/pkg-scoped'); +const protectedPackageMetadata = require('./partials/pkg-protected'); + +describe('/ (Verdaccio Page)', () => { + let page; + // this might be increased based on the delays included in all test + jest.setTimeout(20000); + + const clickElement = async function(selector, options = { button: 'middle', delay: 100 }) { + const button = await page.$(selector); + await button.focus(); + await button.click(options); + }; + + const evaluateSignIn = async function() { + const text = await page.evaluate(() => document.querySelector('button[data-testid="header--button-login"]').textContent); + + expect(text).toMatch('Login'); + }; + + const getPackages = async function() { + return await page.$$('.package-list-items .package-link a'); + }; + + const logIn = async function() { + await clickElement('button[data-testid="header--button-login"]'); + await page.waitFor(500); + // we fill the sign in form + const signInDialog = await page.$('#login--form-container'); + const userInput = await signInDialog.$('#login--form-username'); + expect(userInput).not.toBeNull(); + const passInput = await signInDialog.$('#login--form-password'); + expect(passInput).not.toBeNull(); + await userInput.type('test', { delay: 100 }); + await passInput.type('test', { delay: 100 }); + await passInput.dispose(); + // click on log in + const loginButton = await page.$('#login--form-submit'); + expect(loginButton).toBeDefined(); + await loginButton.focus(); + await loginButton.click({ delay: 100 }); + await page.waitFor(500); + }; + + beforeAll(async () => { + page = await global.__BROWSER__.newPage(); + await page.goto('http://0.0.0.0:55558'); + page.on('console', msg => console.log('PAGE LOG:', msg.text())); + }); + + afterAll(async () => { + await page.close(); + }); + + test('should load without error', async () => { + const text = await page.evaluate(() => document.body.textContent); + + // FIXME: perhaps it is not the best approach + expect(text).toContain('Powered by'); + }); + + test('should match title with no packages published', async () => { + const text = await page.evaluate(() => document.querySelector('#help-card__title').textContent); + expect(text).toMatch('No Package Published Yet'); + }); + + test('should match title with first step', async () => { + const text = await page.evaluate(() => document.querySelector('#help-card').textContent); + expect(text).toContain('npm adduser --registry http://0.0.0.0:55558'); + }); + + test('should match title with second step', async () => { + const text = await page.evaluate(() => document.querySelector('#help-card').textContent); + expect(text).toContain('npm publish --registry http://0.0.0.0:55558'); + }); + + test('should match button Login to sign in', async () => { + await evaluateSignIn(); + }); + + test('should click on sign in button', async () => { + const signInButton = await page.$('button[data-testid="header--button-login"]'); + await signInButton.click(); + await page.waitFor(1000); + const signInDialog = await page.$('#login--form-container'); + + expect(signInDialog).not.toBeNull(); + }); + + test('should log in an user', async () => { + // we open the dialog + await logIn(); + // check whether user is logged + const buttonLogout = await page.$('#header--button-logout'); + expect(buttonLogout).toBeDefined(); + }); + + test('should logout an user', async () => { + // we assume the user is logged already + await clickElement('#header--button-account', { clickCount: 1, delay: 500 }); + await page.waitFor(1000); + await clickElement('#header--button-logout > span', { clickCount: 1, delay: 500 }); + await page.waitFor(1000); + await evaluateSignIn(); + }); + + test('should check registry info dialog', async () => { + const registryInfoButton = await page.$('#header--button-registryInfo'); + registryInfoButton.click(); + await page.waitFor(500); + + const registryInfoDialog = await page.$('#registryInfo--dialog-container'); + expect(registryInfoDialog).not.toBeNull(); + + const closeButton = await page.$('#registryInfo--dialog-close'); + closeButton.click(); + }); + + test('should publish a package', async () => { + await global.__SERVER__.putPackage(scopedPackageMetadata.name, scopedPackageMetadata); + await page.waitFor(1000); + await page.reload(); + await page.waitFor(1000); + const packagesList = await getPackages(); + expect(packagesList).toHaveLength(1); + }); + + test('should navigate to the package detail', async () => { + const packagesList = await getPackages(); + const firstPackage = packagesList[0]; + await firstPackage.click({ clickCount: 1, delay: 200 }); + await page.waitFor(1000); + const readmeText = await page.evaluate(() => document.querySelector('.markdown-body').textContent); + expect(readmeText).toMatch('test'); + }); + + test('should contains last sync information', async () => { + const versionList = await page.$$('.sidebar-info .detail-info'); + expect(versionList).toHaveLength(1); + }); + + test('should display dependencies tab', async () => { + const dependenciesTab = await page.$$('#dependencies-tab'); + expect(dependenciesTab).toHaveLength(1); + await dependenciesTab[0].click({ clickCount: 1, delay: 200 }); + await page.waitFor(1000); + const tags = await page.$$('.dep-tag'); + const tag = tags[0]; + const label = await page.evaluate(el => el.innerText, tag); + expect(label).toMatch('verdaccio@'); + }); + + test('should display version tab', async () => { + const versionsTab = await page.$$('#versions-tab'); + expect(versionsTab).toHaveLength(1); + await versionsTab[0].click({ clickCount: 1, delay: 200 }); + await page.waitFor(1000); + const versionItems = await page.$$('.version-item'); + expect(versionItems).toHaveLength(2); + }); + + test('should display uplinks tab', async () => { + const upLinksTab = await page.$$('#uplinks-tab'); + expect(upLinksTab).toHaveLength(1); + await upLinksTab[0].click({ clickCount: 1, delay: 200 }); + await page.waitFor(1000); + }); + + test('should display readme tab', async () => { + const readmeTab = await page.$$('#readme-tab'); + expect(readmeTab).toHaveLength(1); + await readmeTab[0].click({ clickCount: 1, delay: 200 }); + await page.waitFor(1000); + }); + + test('should publish a protected package', async () => { + await page.goto('http://0.0.0.0:55552'); + await page.waitFor(500); + await global.__SERVER_PROTECTED__.putPackage(protectedPackageMetadata.name, protectedPackageMetadata); + await page.waitFor(500); + await page.reload(); + await page.waitFor(500); + const text = await page.evaluate(() => document.querySelector('#help-card__title').textContent); + expect(text).toMatch('No Package Published Yet'); + }); + + test('should go to 404 page', async () => { + await page.goto('http://0.0.0.0:55552/-/web/detail/@verdaccio/not-found'); + await page.waitFor(500); + const text = await page.evaluate(() => document.querySelector('.not-found-text').textContent); + expect(text).toMatch("Sorry, we couldn't find it..."); + }); +}); diff --git a/test/e2e/partials/pkg-protected.js b/test/e2e/partials/pkg-protected.js new file mode 100644 index 0000000..46e8bf2 --- /dev/null +++ b/test/e2e/partials/pkg-protected.js @@ -0,0 +1,50 @@ +const json = { + _id: 'protected-pkg', + name: 'protected-pkg', + description: '', + 'dist-tags': { + latest: '5.0.5', + }, + versions: { + '5.0.5': { + name: 'protected-pkg', + version: '5.0.5', + description: '', + main: 'index.js', + scripts: { + test: 'echo "Error: no test specified" && exit 1', + }, + keywords: [], + author: { + name: 'User NPM', + email: 'user@domain.com', + }, + license: 'ISC', + dependencies: { + verdaccio: '^2.7.2', + }, + readme: '# test', + readmeFilename: 'README.md', + _id: 'protected-pkg@5.0.5', + _npmVersion: '5.5.1', + _nodeVersion: '8.7.0', + _npmUser: {}, + dist: { + integrity: 'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9cmE6dUBf+XoPoH4g==', + shasum: '2c03764f651a9f016ca0b7620421457b619151b9', + tarball: 'http://localhost:5555/protected-pkg/-/protected-pkg-5.0.5.tgz', + }, + }, + }, + readme: '# test', + _attachments: { + 'protected-pkg-5.0.5.tgz': { + 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=', + length: 512, + }, + }, +}; + +module.exports = json; diff --git a/test/e2e/partials/pkg-scoped.js b/test/e2e/partials/pkg-scoped.js new file mode 100644 index 0000000..099fc41 --- /dev/null +++ b/test/e2e/partials/pkg-scoped.js @@ -0,0 +1,50 @@ +const json = { + _id: '@scope/pk1-test', + name: '@scope/pk1-test', + description: '', + 'dist-tags': { + latest: '1.0.6', + }, + versions: { + '1.0.6': { + name: '@scope/pk1-test', + version: '1.0.6', + description: '', + main: 'index.js', + scripts: { + test: 'echo "Error: no test specified" && exit 1', + }, + keywords: [], + author: { + name: 'User NPM', + email: 'user@domain.com', + }, + license: 'ISC', + dependencies: { + verdaccio: '^2.7.2', + }, + readme: '# test', + readmeFilename: 'README.md', + _id: '@scope/pk1-test@1.0.6', + _npmVersion: '5.5.1', + _nodeVersion: '8.7.0', + _npmUser: {}, + dist: { + integrity: 'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9cmE6dUBf+XoPoH4g==', + shasum: '2c03764f651a9f016ca0b7620421457b619151b9', + tarball: 'http://localhost:5555/@scope/pk1-test/-/@scope/pk1-test-1.0.6.tgz', + }, + }, + }, + readme: '# test', + _attachments: { + '@scope/pk1-test-1.0.6.tgz': { + 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=', + length: 512, + }, + }, +}; + +module.exports = json; diff --git a/test/e2e/plugins/theme.js b/test/e2e/plugins/theme.js new file mode 100644 index 0000000..3f34b33 --- /dev/null +++ b/test/e2e/plugins/theme.js @@ -0,0 +1,6 @@ +const path = require('path'); + +module.exports = () => { + console.log('loading local theme'); + return path.join(__dirname, '../../../', 'static'); +}; diff --git a/test/e2e/pre-setup.js b/test/e2e/pre-setup.js new file mode 100644 index 0000000..fc9e894 --- /dev/null +++ b/test/e2e/pre-setup.js @@ -0,0 +1,4 @@ +require('@babel/register')({ + extensions: ['.ts', '.js'], +}); +module.exports = require('./setup'); diff --git a/test/e2e/puppeteer_environment.js b/test/e2e/puppeteer_environment.js new file mode 100644 index 0000000..e914c4c --- /dev/null +++ b/test/e2e/puppeteer_environment.js @@ -0,0 +1,75 @@ +const fs = require('fs'); +const os = require('os'); +const path = require('path'); + +const { yellow } = require('kleur'); +const NodeEnvironment = require('jest-environment-node'); +const puppeteer = require('puppeteer'); + +const VerdaccioProcess = require('./registry-launcher'); +const Server = require('./server'); + +const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup'); + +class VerdaccioConfig { + constructor(storagePath, configPath, domainPath, port) { + this.storagePath = storagePath; + this.configPath = configPath; + this.domainPath = domainPath; + this.port = port; + } +} + +class PuppeteerEnvironment extends NodeEnvironment { + constructor(config) { + super(config); + } + + async setup() { + const config1 = new VerdaccioConfig( + path.join(__dirname, './store-e2e'), + path.join(__dirname, './config/config-scoped-e2e.yaml'), + 'http://0.0.0.0:55558/', + 55558 + ); + const config2 = new VerdaccioConfig( + path.join(__dirname, './store-e2e'), + path.join(__dirname, './config/config-protected-e2e.yaml'), + 'http://0.0.0.0:55552/', + 55552 + ); + const server1 = new Server.default(config1.domainPath); + const server2 = new Server.default(config2.domainPath); + const process1 = new VerdaccioProcess.default(config1, server1); + const process2 = new VerdaccioProcess.default(config2, server2); + const fork = await process1.init('../../node_modules/.bin/verdaccio'); + const fork2 = await process2.init('../../node_modules/.bin/verdaccio'); + this.global.__VERDACCIO_E2E__ = fork[0]; + this.global.__VERDACCIO__PROTECTED_E2E__ = fork2[0]; + + console.log(yellow('Setup Test Environment.')); + await super.setup(); + const wsEndpoint = fs.readFileSync(path.join(DIR, 'wsEndpoint'), 'utf8'); + if (!wsEndpoint) { + throw new Error('wsEndpoint not found'); + } + this.global.__SERVER__ = server1; + this.global.__SERVER_PROTECTED__ = server2; + this.global.__BROWSER__ = await puppeteer.connect({ + browserWSEndpoint: wsEndpoint, + }); + } + + async teardown() { + console.log(yellow('Teardown Test Environment.')); + await super.teardown(); + this.global.__VERDACCIO_E2E__.stop(); + this.global.__VERDACCIO__PROTECTED_E2E__.stop(); + } + + runScript(script) { + return super.runScript(script); + } +} + +module.exports = PuppeteerEnvironment; diff --git a/test/e2e/registry-launcher.ts b/test/e2e/registry-launcher.ts new file mode 100644 index 0000000..d876100 --- /dev/null +++ b/test/e2e/registry-launcher.ts @@ -0,0 +1,60 @@ +import path from 'path'; +import { fork } from 'child_process'; + +import { HTTP_STATUS } from '@verdaccio/commons-api'; + +export const CREDENTIALS = { + user: 'foo', + password: 'test', +}; + +export default class VerdaccioProcess { + private bridge; + private config; + private childFork; + + public constructor(config, bridge) { + this.config = config; + this.bridge = bridge; + } + + public init(verdaccioPath) { + return new Promise((resolve, reject) => { + this._start(verdaccioPath, resolve, reject); + }); + } + + private _start(verdaccioPath: string, resolve: Function, reject: Function) { + const verdaccioRegisterWrap: string = path.join(__dirname, verdaccioPath); + const childOptions = { + silent: false, + }; + + const { configPath, port } = this.config; + this.childFork = fork(verdaccioRegisterWrap, ['-c', configPath, '-l', port as string], childOptions); + + this.childFork.on('message', msg => { + // verdaccio_started is a message that comes from verdaccio in debug mode that notify has been started + if ('verdaccio_started' in msg) { + this.bridge + .debug() + .status(HTTP_STATUS.OK) + .then(body => { + this.bridge + .auth(CREDENTIALS.user, CREDENTIALS.password) + .status(HTTP_STATUS.CREATED) + .body_ok(new RegExp(CREDENTIALS.user)) + .then(() => resolve([this, body.pid]), reject); + }, reject); + } + }); + + this.childFork.on('error', err => reject([err, this])); + this.childFork.on('disconnect', err => reject([err, this])); + this.childFork.on('exit', err => reject([err, this])); + } + + public stop(): void { + return this.childFork.kill('SIGINT'); + } +} diff --git a/test/e2e/request.ts b/test/e2e/request.ts new file mode 100644 index 0000000..4712d1a --- /dev/null +++ b/test/e2e/request.ts @@ -0,0 +1,137 @@ +import assert from 'assert'; + +import _ from 'lodash'; +import request from 'request'; + +const requestData = Symbol('smart_request_data'); + +export interface RequestPromise { + status(reason: any): any; + body_ok(reason: any): any; + body_error(reason: any): any; + request(reason: any): any; + response(reason: any): any; + send(reason: any): any; +} + +function injectResponse(smartObject: any, promise: Promise): Promise { + // $FlowFixMe + promise[requestData] = smartObject[requestData]; + return promise; +} + +export class PromiseAssert extends Promise implements RequestPromise { + public constructor(options: any) { + super(options); + } + + public status(expected: number) { + const selfData = this[requestData]; + + return injectResponse( + this, + this.then(function(body) { + try { + assert.equal(selfData.response.statusCode, expected); + } catch (err) { + selfData.error.message = err.message; + throw selfData.error; + } + return body; + }) + ); + } + + public body_ok(expected: any) { + const selfData = this[requestData]; + + return injectResponse( + this, + this.then(function(body) { + try { + if (_.isRegExp(expected)) { + assert(body.ok.match(expected), "'" + body.ok + "' doesn't match " + expected); + } else { + assert.equal(body.ok, expected); + } + assert.equal(body.error, null); + } catch (err) { + selfData.error.message = err.message; + throw selfData.error; + } + + return body; + }) + ); + } + + public body_error(expected: any) { + // $FlowFixMe + const selfData = this[requestData]; + + return injectResponse( + this, + this.then(function(body) { + try { + if (_.isRegExp(expected)) { + assert(body.error.match(expected), body.error + " doesn't match " + expected); + } else { + assert.equal(body.error, expected); + } + assert.equal(body.ok, null); + } catch (err) { + selfData.error.message = err.message; + throw selfData.error; + } + return body; + }) + ); + } + + public request(callback: any) { + callback(this[requestData].request); + return this; + } + + public response(cb: any) { + const selfData = this[requestData]; + + return injectResponse( + this, + this.then(function(body) { + cb(selfData.response); + return body; + }) + ); + } + + public send(data: any) { + this[requestData].request.end(data); + return this; + } +} + +function smartRequest(options: any): Promise { + const smartObject: any = {}; + + smartObject[requestData] = {}; + smartObject[requestData].error = Error(); + Error.captureStackTrace(smartObject[requestData].error, smartRequest); + + const promiseResult: Promise = new PromiseAssert(function(resolve, reject) { + // store request reference on symbol + smartObject[requestData].request = request(options, function(err, res, body) { + if (err) { + return reject(err); + } + + // store the response on symbol + smartObject[requestData].response = res; + resolve(body); + }); + }); + + return injectResponse(smartObject, promiseResult); +} + +export default smartRequest; diff --git a/test/e2e/server.ts b/test/e2e/server.ts new file mode 100644 index 0000000..2a75bd6 --- /dev/null +++ b/test/e2e/server.ts @@ -0,0 +1,265 @@ +import assert from 'assert'; + +import _ from 'lodash'; +import { HTTP_STATUS, HEADERS, API_MESSAGE } from '@verdaccio/commons-api'; + +import smartRequest, { RequestPromise } from './request'; +import { CREDENTIALS } from './registry-launcher'; + +declare class PromiseAssert extends Promise { + public constructor(options: any); +} + +const TARBALL = 'tarball-blahblah-file.name'; + +function getPackage(name, version = '0.0.0'): any { + return { + name, + version, + readme: 'this is a readme', + dist: { + shasum: 'fake', + tarball: `http://localhost:0000/${encodeURIComponent(name)}/-/${TARBALL}`, + }, + }; +} + +export interface ServerBridge { + url: string; + userAgent: string; + authstr: string; + request(options: any): typeof PromiseAssert; + auth(name: string, password: string): RequestPromise; + auth(name: string, password: string): RequestPromise; + logout(token: string): Promise; + getPackage(name: string): Promise; + putPackage(name: string, data: any): Promise; + putVersion(name: string, version: string, data: any): Promise; + getTarball(name: string, filename: string): Promise; + putTarball(name: string, filename: string, data: any): Promise; + removeTarball(name: string): Promise; + removeSingleTarball(name: string, filename: string): Promise; + addTag(name: string, tag: string, version: string): Promise; + putTarballIncomplete(name: string, filename: string, data: any, size: number, cb: Function): Promise; + addPackage(name: string): Promise; + whoami(): Promise; + ping(): Promise; + debug(): RequestPromise; +} + +const TOKEN_BASIC = 'Basic'; + +function buildToken(type: string, token: string): string { + return `${_.capitalize(type)} ${token}`; +} + +const buildAuthHeader = (user, pass): string => { + return buildToken(TOKEN_BASIC, new Buffer(`${user}:${pass}`).toString('base64')); +}; + +export default class Server implements ServerBridge { + public url: string; + public userAgent: string; + public authstr: string; + + public constructor(url: string) { + this.url = url.replace(/\/$/, ''); + this.userAgent = 'node/v8.1.2 linux x64'; + this.authstr = buildAuthHeader(CREDENTIALS.user, CREDENTIALS.password); + } + + public request(options: any): any { + assert(options.uri); + const headers = options.headers || {}; + + headers.accept = headers.accept || HEADERS.JSON; + headers['user-agent'] = headers['user-agent'] || this.userAgent; + headers.authorization = headers.authorization || this.authstr; + + return smartRequest({ + url: this.url + options.uri, + method: options.method || 'GET', + headers: headers, + encoding: options.encoding, + json: _.isNil(options.json) === false ? options.json : true, + }); + } + + public auth(name: string, password: string) { + // pragma: allowlist secret + this.authstr = buildAuthHeader(name, password); + return this.request({ + uri: `/-/user/org.couchdb.user:${encodeURIComponent(name)}/-rev/undefined`, + method: 'PUT', + json: { + name, + password, + email: `${CREDENTIALS.user}@example.com`, + _id: `org.couchdb.user:${name}`, + type: 'user', + roles: [], + date: new Date(), + }, + }); + } + + public logout(token: string) { + return this.request({ + uri: `/-/user/token/${encodeURIComponent(token)}`, + method: 'DELETE', + }); + } + + public getPackage(name: string) { + return this.request({ + uri: `/${encodeURIComponent(name)}`, + method: 'GET', + }); + } + + public putPackage(name: string, data) { + if (_.isObject(data) && !Buffer.isBuffer(data)) { + data = JSON.stringify(data); + } + + return this.request({ + uri: `/${encodeURIComponent(name)}`, + method: 'PUT', + headers: { + [HEADERS.CONTENT_TYPE]: HEADERS.JSON, + }, + }).send(data); + } + + public putVersion(name: string, version: string, data: any) { + if (_.isObject(data) && !Buffer.isBuffer(data)) { + data = JSON.stringify(data); + } + + return this.request({ + uri: `/${encodeURIComponent(name)}/${encodeURIComponent(version)}/-tag/latest`, + method: 'PUT', + headers: { + [HEADERS.CONTENT_TYPE]: HEADERS.JSON, + }, + }).send(data); + } + + public getTarball(name: string, filename: string) { + return this.request({ + uri: `/${encodeURIComponent(name)}/-/${encodeURIComponent(filename)}`, + method: 'GET', + encoding: null, + }); + } + + public putTarball(name: string, filename: string, data: any) { + return this.request({ + uri: `/${encodeURIComponent(name)}/-/${encodeURIComponent(filename)}/whatever`, + method: 'PUT', + headers: { + [HEADERS.CONTENT_TYPE]: HEADERS.OCTET_STREAM, + }, + }).send(data); + } + + public removeTarball(name: string) { + return this.request({ + uri: `/${encodeURIComponent(name)}/-rev/whatever`, + method: 'DELETE', + headers: { + [HEADERS.CONTENT_TYPE]: HEADERS.JSON_CHARSET, + }, + }); + } + + public removeSingleTarball(name: string, filename: string) { + return this.request({ + uri: `/${encodeURIComponent(name)}/-/${filename}/-rev/whatever`, + method: 'DELETE', + headers: { + [HEADERS.CONTENT_TYPE]: HEADERS.JSON_CHARSET, + }, + }); + } + + public addTag(name: string, tag: string, version: string) { + return this.request({ + uri: `/${encodeURIComponent(name)}/${encodeURIComponent(tag)}`, + method: 'PUT', + headers: { + [HEADERS.CONTENT_TYPE]: HEADERS.JSON, + }, + }).send(JSON.stringify(version)); + } + + public putTarballIncomplete(pkgName: string, filename: string, data: any, headerContentSize: number): Promise { + const promise = this.request({ + uri: `/${encodeURIComponent(pkgName)}/-/${encodeURIComponent(filename)}/whatever`, + method: 'PUT', + headers: { + [HEADERS.CONTENT_TYPE]: HEADERS.OCTET_STREAM, + [HEADERS.CONTENT_LENGTH]: headerContentSize, + }, + timeout: 1000, + }); + + promise.request(function(req) { + req.write(data); + // it auto abort the request + setTimeout(function() { + req.req.abort(); + }, 20); + }); + + return new Promise(function(resolve, reject) { + promise + .then(function() { + reject(Error('no error')); + }) + .catch(function(err) { + if (err.code === 'ECONNRESET') { + resolve(); + } else { + reject(err); + } + }); + }); + } + + public addPackage(name: string) { + return this.putPackage(name, getPackage(name)) + .status(HTTP_STATUS.CREATED) + .body_ok(API_MESSAGE.PKG_CREATED); + } + + public whoami() { + return this.request({ + uri: '/-/whoami', + }) + .status(HTTP_STATUS.OK) + .then(function(body) { + return body.username; + }); + } + + public ping() { + return this.request({ + uri: '/-/ping', + }) + .status(HTTP_STATUS.OK) + .then(function(body) { + return body; + }); + } + + public debug() { + return this.request({ + uri: '/-/_debug', + method: 'GET', + headers: { + [HEADERS.CONTENT_TYPE]: HEADERS.JSON, + }, + }); + } +} diff --git a/test/e2e/setup.js b/test/e2e/setup.js new file mode 100644 index 0000000..4554458 --- /dev/null +++ b/test/e2e/setup.js @@ -0,0 +1,17 @@ +const fs = require('fs'); +const os = require('os'); +const path = require('path'); + +const { green } = require('kleur'); +const puppeteer = require('puppeteer'); +const mkdirp = require('mkdirp'); + +const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup'); + +module.exports = async function() { + console.log(green('Setup Puppeteer')); + const browser = await puppeteer.launch({ headless: true, /* slowMo: 300 */ args: ['--no-sandbox'] }); + global.__BROWSER__ = browser; + mkdirp.sync(DIR); + fs.writeFileSync(path.join(DIR, 'wsEndpoint'), browser.wsEndpoint()); +}; diff --git a/test/e2e/teardown.js b/test/e2e/teardown.js new file mode 100644 index 0000000..ba76246 --- /dev/null +++ b/test/e2e/teardown.js @@ -0,0 +1,13 @@ +const os = require('os'); +const path = require('path'); + +const { green } = require('kleur'); +const rimraf = require('rimraf'); + +const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup'); + +module.exports = async function() { + console.log(green('Teardown Puppeteer')); + await global.__BROWSER__.close(); + rimraf.sync(DIR); +}; diff --git a/test/jest.config.e2e.js b/test/jest.config.e2e.js new file mode 100644 index 0000000..f0684ca --- /dev/null +++ b/test/jest.config.e2e.js @@ -0,0 +1,27 @@ +module.exports = { + name: 'verdaccio-e2e-jest', + verbose: true, + collectCoverage: false, + globalSetup: './e2e/pre-setup.js', + globalTeardown: './e2e/teardown.js', + testEnvironment: './e2e/puppeteer_environment.js', + testRegex: '(/e2e.*\\.spec)\\.js', + modulePathIgnorePatterns: [ + '/unit/partials/mock-store/.*/package.json', + '/functional/store/.*/package.json', + '/unit/partials/store/.*/package.json', + '/../coverage', + '/../docs', + '/../debug', + '/../scripts', + '/../.circleci', + '/../tools', + '/../wiki', + '/../systemd', + '/../flow-typed', + 'unit/partials/mock-store/.*/package.json', + 'functional/store/.*/package.json', + '/../build', + '/../.vscode/', + ], +}; diff --git a/yarn.lock b/yarn.lock index 534e100..45d1d13 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1176,6 +1176,38 @@ resolved "https://registry.verdaccio.org/@emotion%2futils/-/utils-0.8.2.tgz#576ff7fb1230185b619a75d258cbc98f0867a8dc" integrity sha512-rLu3wcBWH4P5q1CGoSSH/i9hrXs7SlbRLkoq9IGuoPYNGQvDJ3pt/wmOM+XgYjIDRMVIdkUWt0RsfzF50JfnCw== +"@hapi/address@2.x.x": + version "2.1.2" + resolved "https://registry.verdaccio.org/@hapi%2faddress/-/address-2.1.2.tgz#1c794cd6dbf2354d1eb1ef10e0303f573e1c7222" + integrity sha512-O4QDrx+JoGKZc6aN64L04vqa7e41tIiLU+OvKdcYaEMP97UttL0f9GIi9/0A4WAMx0uBd6SidDIhktZhgOcN8Q== + +"@hapi/bourne@1.x.x": + version "1.3.2" + resolved "https://registry.verdaccio.org/@hapi%2fbourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a" + integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== + +"@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0": + version "8.3.0" + resolved "https://registry.verdaccio.org/@hapi%2fhoek/-/hoek-8.3.0.tgz#2b9db1cd00f3891005c77b3a8d608b88a6d0aa4d" + integrity sha512-C0QL9bmgUXTSuf8nDeGrpMjtJG7tPUr8wG6/wxPbP62tGwCwQtdMSJYfESowmY4P3Hn593f+8OzNY5bckcu/LQ== + +"@hapi/joi@^15.0.3": + version "15.1.1" + resolved "https://registry.verdaccio.org/@hapi%2fjoi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7" + integrity sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ== + dependencies: + "@hapi/address" "2.x.x" + "@hapi/bourne" "1.x.x" + "@hapi/hoek" "8.x.x" + "@hapi/topo" "3.x.x" + +"@hapi/topo@3.x.x": + version "3.1.6" + resolved "https://registry.verdaccio.org/@hapi%2ftopo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29" + integrity sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ== + dependencies: + "@hapi/hoek" "^8.3.0" + "@jest/console@^24.7.1", "@jest/console@^24.9.0": version "24.9.0" resolved "https://registry.verdaccio.org/@jest%2fconsole/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" @@ -1541,6 +1573,11 @@ dependencies: "@babel/types" "^7.3.0" +"@types/caseless@*": + version "0.12.2" + resolved "https://registry.verdaccio.org/@types%2fcaseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8" + integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w== + "@types/cheerio@*": version "0.22.13" resolved "https://registry.verdaccio.org/@types%2fcheerio/-/cheerio-0.22.13.tgz#5eecda091a24514185dcba99eda77e62bf6523e6" @@ -1716,6 +1753,16 @@ "@types/prop-types" "*" csstype "^2.2.0" +"@types/request@2.48.3": + version "2.48.3" + resolved "https://registry.verdaccio.org/@types%2frequest/-/request-2.48.3.tgz#970b8ed2317568c390361d29c555a95e74bd6135" + integrity sha512-3Wo2jNYwqgXcIz/rrq18AdOZUQB8cQ34CXZo+LUwPJNpvRAL86+Kc2wwI8mqpz9Cr1V+enIox5v+WZhy/p3h8w== + dependencies: + "@types/caseless" "*" + "@types/node" "*" + "@types/tough-cookie" "*" + form-data "^2.5.0" + "@types/semver@^6.0.1": version "6.0.2" resolved "https://registry.verdaccio.org/@types%2fsemver/-/semver-6.0.2.tgz#5e8b09f0e4af53034b1d0fb9977a277847836205" @@ -1741,6 +1788,11 @@ "@types/react-dom" "*" "@types/testing-library__dom" "*" +"@types/tough-cookie@*": + version "2.3.5" + resolved "https://registry.verdaccio.org/@types%2ftough-cookie/-/tough-cookie-2.3.5.tgz#9da44ed75571999b65c37b60c9b2b88db54c585d" + integrity sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg== + "@types/unist@*", "@types/unist@^2.0.0": version "2.0.3" resolved "https://registry.verdaccio.org/@types%2funist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" @@ -1884,14 +1936,7 @@ babel-plugin-dynamic-import-node "2.3.0" babel-plugin-emotion "10.0.14" -"@verdaccio/commons-api@8.0.0": - version "8.0.0" - resolved "https://registry.verdaccio.org/@verdaccio%2fcommons-api/-/commons-api-8.0.0.tgz#b7f2480c73b33311932e59b2dec8c0cda3a1995c" - integrity sha512-s0HFftOhhhnWGVxMRwX1iq7lvFdn9uWmZziG65/XBOrLVw9C1YNsvxmuchIYD0/mms35gq5hm8Z8UqvgGjKo0w== - dependencies: - http-errors "1.7.3" - -"@verdaccio/commons-api@^8.1.1": +"@verdaccio/commons-api@8.1.2", "@verdaccio/commons-api@^8.1.2": version "8.1.2" resolved "https://registry.verdaccio.org/@verdaccio%2fcommons-api/-/commons-api-8.1.2.tgz#725b04dad6c09f6d9c3d6a9ca83fbb9d55f6dae1" integrity sha512-voJIpdikrSe6aWpRmGoyHGIB0mUgLyNe5oz+jBH81G0/8VsFiIEXye2WTJ4vmEGsZV3tsitMfJM0x+H+uFpE4Q== @@ -1922,45 +1967,36 @@ dependencies: lockfile "1.0.4" -"@verdaccio/file-locking@1.0.3": - version "1.0.3" - resolved "https://registry.verdaccio.org/@verdaccio%2ffile-locking/-/file-locking-1.0.3.tgz#8244380a4ee41e585ef38690f9dbcaa1aba6bdc4" - integrity sha512-+npFxBPq8c7oXHtroLGjcrninqtoQBPVeCfLG0BzrEe3ZM5bCcaz3nwQsXLBzhL/QP5z3zLiOgpsxddDN3UIyw== +"@verdaccio/file-locking@^8.1.2": + version "8.1.2" + resolved "https://registry.verdaccio.org/@verdaccio%2ffile-locking/-/file-locking-8.1.2.tgz#6f529a54ad2fa3558068e8c3e8241c6502ec6763" + integrity sha512-23fer5+B+Y254MzHoCvPiqDbB9QEzlDau7Gj/L2vQbFjjVnnBMv85PCokWDU7EguF2mvhjkZ5U4Zoo6bZ5PRKw== dependencies: lockfile "1.0.4" -"@verdaccio/local-storage@2.2.1": - version "2.2.1" - resolved "https://registry.verdaccio.org/@verdaccio%2flocal-storage/-/local-storage-2.2.1.tgz#ce8b9ab6c05d6ce2bccef5c7781abe8667eab778" - integrity sha512-lSM5Rc2dn8rtzo1P2kQz7TNlVgm12OQzOcocK9uwVgKS95sWqjxttLB9EMfsGsy0+qwfzw96AMBkOXn3f55m/Q== +"@verdaccio/local-storage@8.1.2": + version "8.1.2" + resolved "https://registry.verdaccio.org/@verdaccio%2flocal-storage/-/local-storage-8.1.2.tgz#27564856856808bb019ff0453745d25bea04074a" + integrity sha512-49j5nyB7+At3ho/eMBF6WB+Wz0H90MOzvzx8pS+J1rBoqY+nkyeR4iYG7I+kbWCcRjp7aDpwN5djGPyV8ZEsXw== dependencies: - "@verdaccio/file-locking" "1.0.3" - "@verdaccio/streams" "2.0.0" + "@verdaccio/commons-api" "^8.1.2" + "@verdaccio/file-locking" "^8.1.2" + "@verdaccio/streams" "^8.1.2" async "3.1.0" - http-errors "1.7.3" - lodash "4.17.11" + level "5.0.1" + lodash "4.17.15" mkdirp "0.5.1" -"@verdaccio/readme@8.0.0": - version "8.0.0" - resolved "https://registry.verdaccio.org/@verdaccio%2freadme/-/readme-8.0.0.tgz#36108dc48597f9ee380d42c965f08db91ed6e87a" - integrity sha512-wZCUR//UwdKbt3C308pFxsai6HJjVJ0lAedyVSWctK+3Dj/is10OsMrWoJZ0gJbacRET6S3rJF9WeS6dtntZcw== +"@verdaccio/readme@8.1.2": + version "8.1.2" + resolved "https://registry.verdaccio.org/@verdaccio%2freadme/-/readme-8.1.2.tgz#1022e7bced4c91f0712b66792528b00761ea8031" + integrity sha512-FVa5WQttsf8rLRK3IA/VZD9UWhHAdK/UEcKL0zP+EFqiXQTADYuIPgdLtSeC1w4LTUAUu2Qv05D2vimTAabFKA== dependencies: - dompurify "1.0.11" + dompurify "2.0.3" jsdom "15.1.1" - marked "0.6.2" + marked "0.7.0" -"@verdaccio/streams@2.0.0": - version "2.0.0" - resolved "https://registry.verdaccio.org/@verdaccio%2fstreams/-/streams-2.0.0.tgz#27f51d0cb19d5e49248860942092646e9a357967" - integrity sha512-QW1LsYir3wNnqhSznbJlt0iqkcgve0LpXI8RkoTTBPrq3M6ei3Ys4iw+JQKFve3gmYw9O+w8lBiOLc1qvvsoVQ== - -"@verdaccio/streams@8.0.0": - version "8.0.0" - resolved "https://registry.verdaccio.org/@verdaccio%2fstreams/-/streams-8.0.0.tgz#d8e1aa4121c288b2a305de4607d19d0df3f49e52" - integrity sha512-N1zCrQfbo8xWMUyYRFLUuA1Xn9cbbvOslIZ1P2jX+E4HyA/4fBwZi6mpsa79RuOmm1Vu2GI/yXADiO4x9F4j2Q== - -"@verdaccio/streams@^8.1.1": +"@verdaccio/streams@8.1.2", "@verdaccio/streams@^8.1.2": version "8.1.2" resolved "https://registry.verdaccio.org/@verdaccio%2fstreams/-/streams-8.1.2.tgz#0f74d967415b260b728b35caf05992fdb5bb5fe9" integrity sha512-mh7qeYFNNt7MtxPZXs8JLs5lwxob1mELNEc6aA3ZHhg90PCKM7v9fzylWZgbsn0XSzTKltosQ/dqYUQvDCd0Dg== @@ -1970,10 +2006,10 @@ resolved "https://registry.verdaccio.org/@verdaccio%2ftypes/-/types-8.1.0.tgz#298baa1c0bffd340022537a1d9b064b82b4ae497" integrity sha512-wc0SaH25ioT6xt4HtlFzvmNSjZXQOddJLDuI1VN4/8nHAIlrUdlQ0sGnmky4+bJOuTL3eqbaqx4nHMKep5+lDg== -"@verdaccio/ui-theme@0.2.3": - version "0.2.3" - resolved "https://registry.verdaccio.org/@verdaccio%2fui-theme/-/ui-theme-0.2.3.tgz#d25335be52bc15ad5c57cbff7607ddc8bf857833" - integrity sha512-rzn336VTjReOyxPdYapMDxgH+5PvxpT49GGdnHOcB7JEdDgl4Qa2mQIzRol/3GLahXMfOX+6uRY/ySBdlRo69A== +"@verdaccio/ui-theme@0.3.2": + version "0.3.2" + resolved "https://registry.verdaccio.org/@verdaccio%2fui-theme/-/ui-theme-0.3.2.tgz#6f4a27abb3781a9741473e55bff7af650dce118c" + integrity sha512-bxICDb2dgHXp6DOEx8f1IfU7PsgF1AuuDxa87MbvXqfE3CfMGB2TEwlPWNlX+VSScgWNh/yYSDrOIQ2SqwgAGg== "@webassemblyjs/ast@1.8.5": version "1.8.5" @@ -2154,6 +2190,31 @@ abbrev@1: resolved "https://registry.verdaccio.org/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abstract-leveldown@^6.1.1, abstract-leveldown@~6.2.1: + version "6.2.1" + resolved "https://registry.verdaccio.org/abstract-leveldown/-/abstract-leveldown-6.2.1.tgz#37b655151e13c3d9b20fa3a04ce63ccaa345fce4" + integrity sha512-zUgomHedGBCThDkUtc1bfilu2jEhRZ7Dk3RePhtMma/akw7UK2Upm2R5Dd8ynRBEt3uscwbWO0VQNx22/7RtWg== + dependencies: + level-concat-iterator "~2.0.0" + level-supports "~1.0.0" + xtend "~4.0.0" + +abstract-leveldown@~6.0.1: + version "6.0.3" + resolved "https://registry.verdaccio.org/abstract-leveldown/-/abstract-leveldown-6.0.3.tgz#b4b6159343c74b0c5197b2817854782d8f748c4a" + integrity sha512-jzewKKpZbaYUa6HTThnrl+GrJhzjEAeuc7hTVpZdzg7kupXZFoqQDFwyOwLNbmJKJlmzw8yiipMPkDiuKkT06Q== + dependencies: + level-concat-iterator "~2.0.0" + xtend "~4.0.0" + +abstract-leveldown@~6.1.1: + version "6.1.1" + resolved "https://registry.verdaccio.org/abstract-leveldown/-/abstract-leveldown-6.1.1.tgz#f44bad5862d71c7b418110d7698ac25bedf24396" + integrity sha512-7fK/KySVqzKIomdhkSWzX4YBQhzkzEMbWSiaB6mSN9e+ZdV3KEeKxia/8xQzCkATA5xnnukdP88cFR0D2FsFXw== + dependencies: + level-concat-iterator "~2.0.0" + xtend "~4.0.0" + accepts@^1.3.7, accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.verdaccio.org/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" @@ -3574,10 +3635,10 @@ commander@2.17.x: resolved "https://registry.verdaccio.org/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== -commander@2.20.0: - version "2.20.0" - resolved "https://registry.verdaccio.org/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" - integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== +commander@3.0.2: + version "3.0.2" + resolved "https://registry.verdaccio.org/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" + integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== commander@^2.11.0, commander@^2.14.1, commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@^2.8.1, commander@^2.9.0, commander@~2.20.0: version "2.20.1" @@ -4396,10 +4457,10 @@ dateformat@^3.0.0: resolved "https://registry.verdaccio.org/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== -dayjs@1.8.15: - version "1.8.15" - resolved "https://registry.verdaccio.org/dayjs/-/dayjs-1.8.15.tgz#7121bc04e6a7f2621ed6db566be4a8aaf8c3913e" - integrity sha512-HYHCI1nohG52B45vCQg8Re3hNDZbMroWPkhz50yaX7Lu0ATyjGsTdoYZBpjED9ar6chqTx2dmSmM8A51mojnAg== +dayjs@1.8.16: + version "1.8.16" + resolved "https://registry.verdaccio.org/dayjs/-/dayjs-1.8.16.tgz#2a3771de537255191b947957af2fd90012e71e64" + integrity sha512-XPmqzWz/EJiaRHjBqSJ2s6hE/BUoCIHKgdS2QPtTQtKcS9E4/Qn0WomoH1lXanWCzri+g7zPcuNV4aTZ8PMORQ== debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" @@ -4501,6 +4562,14 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" +deferred-leveldown@~5.3.0: + version "5.3.0" + resolved "https://registry.verdaccio.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz#27a997ad95408b61161aa69bd489b86c71b78058" + integrity sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw== + dependencies: + abstract-leveldown "~6.2.1" + inherits "^2.0.3" + define-properties@^1.1.2, define-properties@^1.1.3: version "1.1.3" resolved "https://registry.verdaccio.org/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -4769,10 +4838,10 @@ domhandler@^2.3.0: dependencies: domelementtype "1" -dompurify@1.0.11: - version "1.0.11" - resolved "https://registry.verdaccio.org/dompurify/-/dompurify-1.0.11.tgz#fe0f4a40d147f7cebbe31a50a1357539cfc1eb4d" - integrity sha512-XywCTXZtc/qCX3iprD1pIklRVk/uhl8BKpkTxr+ZyMVUzSUg7wkQXRBp/euJ5J5moa1QvfpvaPQVP71z1O59dQ== +dompurify@2.0.3: + version "2.0.3" + resolved "https://registry.verdaccio.org/dompurify/-/dompurify-2.0.3.tgz#5cc4965a487d54aedba6ba9634b137cfbd7eb50d" + integrity sha512-q006uOkD2JGSJgF0qBt7rVhUvUPBWCxpGayALmHvXx2iNlMfNVz7PDGeXEUjNGgIDjADz59VZCv6UE3U8XRWVw== domutils@1.5.1: version "1.5.1" @@ -4920,6 +4989,16 @@ encodeurl@~1.0.2: resolved "https://registry.verdaccio.org/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= +encoding-down@^6.2.0: + version "6.2.0" + resolved "https://registry.verdaccio.org/encoding-down/-/encoding-down-6.2.0.tgz#7ca52446dac6e0fd09ad3584a7359809ea1a4844" + integrity sha512-XlIoQMBMbU4aE01uSKpAix0sXBJWK8YPhuOdvKa1CroThZyUpj0zWzt+bbe7g1KWsdhNFFzHkQHSdDymVtpJ1w== + dependencies: + abstract-leveldown "^6.1.1" + inherits "^2.0.3" + level-codec "^9.0.0" + level-errors "^2.0.0" + end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.verdaccio.org/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -4946,10 +5025,10 @@ entities@^2.0.0: resolved "https://registry.verdaccio.org/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== -envinfo@7.3.1: - version "7.3.1" - resolved "https://registry.verdaccio.org/envinfo/-/envinfo-7.3.1.tgz#892e42f7bf858b3446d9414ad240dbaf8da52f09" - integrity sha512-GvXiDTqLYrORVSCuJCsWHPXF5BFvoWMQA9xX4YVjPT1jyS3aZEHUBwjzxU/6LTPF9ReHgVEbX7IEN5UvSXHw/A== +envinfo@7.4.0: + version "7.4.0" + resolved "https://registry.verdaccio.org/envinfo/-/envinfo-7.4.0.tgz#bef4ece9e717423aaf0c3584651430b735ad6630" + integrity sha512-FdDfnWnCVjxTTpWE3d6Jgh5JDIA3Cw7LCgpM/pI7kK1ORkjaqI2r6NqQ+ln2j0dfpgxY00AWieSvtkiZQKIItA== enzyme-adapter-react-16@1.14.0: version "1.14.0" @@ -5016,7 +5095,7 @@ err-code@^1.0.0: resolved "https://registry.verdaccio.org/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA= -errno@^0.1.3, errno@~0.1.7: +errno@^0.1.3, errno@~0.1.1, errno@~0.1.7: version "0.1.7" resolved "https://registry.verdaccio.org/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== @@ -5839,7 +5918,7 @@ forever-agent@~0.6.1: resolved "https://registry.verdaccio.org/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -form-data@^2.3.1: +form-data@^2.3.1, form-data@^2.5.0: version "2.5.1" resolved "https://registry.verdaccio.org/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== @@ -6333,10 +6412,10 @@ handle-thing@^2.0.0: resolved "https://registry.verdaccio.org/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754" integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ== -handlebars@4.1.2: - version "4.1.2" - resolved "https://registry.verdaccio.org/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67" - integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw== +handlebars@4.3.1: + version "4.3.1" + resolved "https://registry.verdaccio.org/handlebars/-/handlebars-4.3.1.tgz#6febc1890851f62a8932d495cc88d29390fa850d" + integrity sha512-c0HoNHzDiHpBt4Kqe99N8tdLPKAnGCQ73gYMPWtAYM4PwGnf7xl8PBUHJqh9ijlzt2uQKaSRxbXRt+rZ7M2/kA== dependencies: neo-async "^2.6.0" optimist "^0.6.1" @@ -6773,6 +6852,11 @@ iltorb@^2.4.3: prebuild-install "^5.3.0" which-pm-runs "^1.0.0" +immediate@~3.2.3: + version "3.2.3" + resolved "https://registry.verdaccio.org/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" + integrity sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw= + import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.verdaccio.org/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" @@ -6842,7 +6926,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.verdaccio.org/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -7302,7 +7386,7 @@ is-text-path@^2.0.0: dependencies: text-extensions "^2.0.0" -is-typedarray@~1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.verdaccio.org/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -8161,6 +8245,88 @@ left-pad@^1.3.0: resolved "https://registry.verdaccio.org/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== +level-codec@^9.0.0: + version "9.0.1" + resolved "https://registry.verdaccio.org/level-codec/-/level-codec-9.0.1.tgz#042f4aa85e56d4328ace368c950811ba802b7247" + integrity sha512-ajFP0kJ+nyq4i6kptSM+mAvJKLOg1X5FiFPtLG9M5gCEZyBmgDi3FkDrvlMkEzrUn1cWxtvVmrvoS4ASyO/q+Q== + +level-concat-iterator@~2.0.0: + version "2.0.1" + resolved "https://registry.verdaccio.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz#1d1009cf108340252cb38c51f9727311193e6263" + integrity sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw== + +level-errors@^2.0.0, level-errors@~2.0.0: + version "2.0.1" + resolved "https://registry.verdaccio.org/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8" + integrity sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw== + dependencies: + errno "~0.1.1" + +level-iterator-stream@~4.0.0: + version "4.0.2" + resolved "https://registry.verdaccio.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz#7ceba69b713b0d7e22fcc0d1f128ccdc8a24f79c" + integrity sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q== + dependencies: + inherits "^2.0.4" + readable-stream "^3.4.0" + xtend "^4.0.2" + +level-js@^4.0.0: + version "4.0.1" + resolved "https://registry.verdaccio.org/level-js/-/level-js-4.0.1.tgz#3bad57d8bb46ebba7b13bc7442b56f4b45c8a2e0" + integrity sha512-m5JRIyHZn5VnCCFeRegJkn5bQd3MJK5qZX12zg3Oivc8+BUIS2yFS6ANMMeHX2ieGxucNvEn6/ZnyjmZQLLUWw== + dependencies: + abstract-leveldown "~6.0.1" + immediate "~3.2.3" + inherits "^2.0.3" + ltgt "^2.1.2" + typedarray-to-buffer "~3.1.5" + +level-packager@^5.0.0: + version "5.0.3" + resolved "https://registry.verdaccio.org/level-packager/-/level-packager-5.0.3.tgz#e22bc9887663d0808ab092453d691bc319b7e5a2" + integrity sha512-Ut62o3nvUNCxYldM5+13+0sYow6ifKj2C26/0ToB7zKgdypF5wRKcVkcztQVwsQi+ZnrmDzhimp7FKP5Ynv6Rg== + dependencies: + encoding-down "^6.2.0" + levelup "^4.2.0" + +level-supports@~1.0.0: + version "1.0.0" + resolved "https://registry.verdaccio.org/level-supports/-/level-supports-1.0.0.tgz#376f3f2339c23be0ba2fe62b0fa0e3ac7d6d9988" + integrity sha512-01PKZumFhgysuHUbRz4c9DyA1egmcHJBAsZbm0Vf5agojC3uWOvAnhOD4swNUgHlfJBymXLi/xkBaEckeNRSvA== + dependencies: + xtend "^4.0.2" + +level@5.0.1: + version "5.0.1" + resolved "https://registry.verdaccio.org/level/-/level-5.0.1.tgz#8528cc1ee37ac413270129a1eab938c610be3ccb" + integrity sha512-wcak5OQeA4rURGacqS62R/xNHjCYnJSQDBOlm4KNUGJVE9bWv2B04TclqReYejN+oD65PzD4FsqeWoI5wNC5Lg== + dependencies: + level-js "^4.0.0" + level-packager "^5.0.0" + leveldown "^5.0.0" + opencollective-postinstall "^2.0.0" + +leveldown@^5.0.0: + version "5.3.0" + resolved "https://registry.verdaccio.org/leveldown/-/leveldown-5.3.0.tgz#cc228088b184901d52b54bd70518543bfb059406" + integrity sha512-PQXwTKMz55rYlg7984VbM7xpcqdiWgVKRms2fEgqVL7spd6+wK8NewScJOYIGpIG7/XxMOc0i+q/NX0WLJEcwA== + dependencies: + abstract-leveldown "~6.1.1" + napi-macros "~2.0.0" + node-gyp-build "~4.1.0" + +levelup@^4.2.0: + version "4.3.2" + resolved "https://registry.verdaccio.org/levelup/-/levelup-4.3.2.tgz#31c5b1b29f146d1d35d692e01a6da4d28fa55ebd" + integrity sha512-cRTjU4ktWo59wf13PHEiOayHC3n0dOh4i5+FHr4tv4MX9+l7mqETicNq3Aj07HKlLdk0z5muVoDL2RD+ovgiyA== + dependencies: + deferred-leveldown "~5.3.0" + level-errors "~2.0.0" + level-iterator-stream "~4.0.0" + level-supports "~1.0.0" + xtend "~4.0.0" + leven@^3.1.0: version "3.1.0" resolved "https://registry.verdaccio.org/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -8475,11 +8641,6 @@ lodash.uniq@^4.5.0: resolved "https://registry.verdaccio.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@4.17.11: - version "4.17.11" - resolved "https://registry.verdaccio.org/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" - integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== - lodash@4.17.14: version "4.17.14" resolved "https://registry.verdaccio.org/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" @@ -8565,6 +8726,11 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +ltgt@^2.1.2: + version "2.2.1" + resolved "https://registry.verdaccio.org/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" + integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU= + lunr-mutable-indexes@2.3.2: version "2.3.2" resolved "https://registry.verdaccio.org/lunr-mutable-indexes/-/lunr-mutable-indexes-2.3.2.tgz#864253489735d598c5140f3fb75c0a5c8be2e98c" @@ -8641,11 +8807,6 @@ markdown-table@^1.1.0: resolved "https://registry.verdaccio.org/markdown-table/-/markdown-table-1.1.3.tgz#9fcb69bcfdb8717bfd0398c6ec2d93036ef8de60" integrity sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q== -marked@0.6.2: - version "0.6.2" - resolved "https://registry.verdaccio.org/marked/-/marked-0.6.2.tgz#c574be8b545a8b48641456ca1dbe0e37b6dccc1a" - integrity sha512-LqxwVH3P/rqKX4EKGz7+c2G9r98WeM/SW34ybhgNGhUQNKtf1GmmSkJ6cDGJ/t6tiyae49qRkpyTw2B9HOrgUA== - marked@0.7.0: version "0.7.0" resolved "https://registry.verdaccio.org/marked/-/marked-0.7.0.tgz#b64201f051d271b1edc10a04d1ae9b74bb8e5c0e" @@ -9116,6 +9277,11 @@ napi-build-utils@^1.0.1: resolved "https://registry.verdaccio.org/napi-build-utils/-/napi-build-utils-1.0.1.tgz#1381a0f92c39d66bf19852e7873432fc2123e508" integrity sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA== +napi-macros@~2.0.0: + version "2.0.0" + resolved "https://registry.verdaccio.org/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" + integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.verdaccio.org/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -9216,6 +9382,11 @@ node-forge@0.9.0: resolved "https://registry.verdaccio.org/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ== +node-gyp-build@~4.1.0: + version "4.1.1" + resolved "https://registry.verdaccio.org/node-gyp-build/-/node-gyp-build-4.1.1.tgz#d7270b5d86717068d114cc57fff352f96d745feb" + integrity sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.verdaccio.org/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -9601,7 +9772,7 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -opencollective-postinstall@^2.0.2: +opencollective-postinstall@^2.0.0, opencollective-postinstall@^2.0.2: version "2.0.2" resolved "https://registry.verdaccio.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89" integrity sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw== @@ -10625,7 +10796,7 @@ process@^0.11.10: resolved "https://registry.verdaccio.org/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= -progress@^2.0.0, progress@^2.0.1: +progress@^2.0.0: version "2.0.3" resolved "https://registry.verdaccio.org/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== @@ -10764,19 +10935,19 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.verdaccio.org/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -puppeteer@1.17.0: - version "1.17.0" - resolved "https://registry.verdaccio.org/puppeteer/-/puppeteer-1.17.0.tgz#371957d227a2f450fa74b78e78a2dadb2be7f14f" - integrity sha512-3EXZSximCzxuVKpIHtyec8Wm2dWZn1fc5tQi34qWfiUgubEVYHjUvr0GOJojqf3mifI6oyKnCdrGxaOI+lWReA== +puppeteer@1.8.0: + version "1.8.0" + resolved "https://registry.verdaccio.org/puppeteer/-/puppeteer-1.8.0.tgz#9e8bbd2f5448cc19cac220efc0512837104877ad" + integrity sha512-wJ7Fxs03l4dy/ZXQACUKBBobIuJaS4NHq44q7/QinpAXFMwJMJFEIPjzoksVzUhZxQe+RXnjXH69mg13yMh0BA== dependencies: - debug "^4.1.0" + debug "^3.1.0" extract-zip "^1.6.6" https-proxy-agent "^2.2.1" mime "^2.0.3" - progress "^2.0.1" + progress "^2.0.0" proxy-from-env "^1.0.0" rimraf "^2.6.1" - ws "^6.1.0" + ws "^5.1.1" q@^1.1.2, q@^1.5.1: version "1.5.1" @@ -11107,7 +11278,7 @@ read-pkg@^5.1.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" -"readable-stream@2 || 3", readable-stream@^3.0.1, readable-stream@^3.0.2, readable-stream@^3.0.6, readable-stream@^3.1.1: +"readable-stream@2 || 3", readable-stream@^3.0.1, readable-stream@^3.0.2, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0: version "3.4.0" resolved "https://registry.verdaccio.org/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== @@ -11634,6 +11805,11 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" +rx@^4.1.0: + version "4.1.0" + resolved "https://registry.verdaccio.org/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" + integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I= + rxjs@^6.3.3, rxjs@^6.4.0, rxjs@^6.5.2: version "6.5.3" resolved "https://registry.verdaccio.org/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" @@ -13027,6 +13203,13 @@ type@^1.0.1: resolved "https://registry.verdaccio.org/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== +typedarray-to-buffer@~3.1.5: + version "3.1.5" + resolved "https://registry.verdaccio.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.verdaccio.org/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -13381,25 +13564,25 @@ vendors@^1.0.0: resolved "https://registry.verdaccio.org/vendors/-/vendors-1.0.3.tgz#a6467781abd366217c050f8202e7e50cc9eef8c0" integrity sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw== -verdaccio-audit@8.0.0: - version "8.0.0" - resolved "https://registry.verdaccio.org/verdaccio-audit/-/verdaccio-audit-8.0.0.tgz#61933cab21daa99a2de08c550d6c6d665f3226cd" - integrity sha512-80/0GEPulkwzi0qlQMHpe8tXeHEPQ+x78ZsUk3CkpNwCr+VlgzWxAzk6zI3ZUQ/gBBAidZ8We+TWNsdAPze8/w== +verdaccio-audit@8.1.4: + version "8.1.4" + resolved "https://registry.verdaccio.org/verdaccio-audit/-/verdaccio-audit-8.1.4.tgz#b2005927cbfe29229b01034e9d2d8bc635f12970" + integrity sha512-Ehg9XS1soO5xfbtut64MU+FutF42kay0tw1wwB84UaQJ7YgZ58ftgvLZcL3AuPlTzI9KHMCf6ZOdyt6/fNmsVw== dependencies: express "4.17.1" request "2.88.0" -verdaccio-auth-memory@8.1.1: - version "8.1.1" - resolved "https://registry.verdaccio.org/verdaccio-auth-memory/-/verdaccio-auth-memory-8.1.1.tgz#b3b40813eb15fd79aa8dd275b7a3d72db17e90c4" - integrity sha512-Az9UGS+2AGCSBcUAAVn/DCIeHYNgD0vuQVzL0aX7YtQf/pwUfTLpPGypu4hSsd/ISjJGNMN+ZuvCtHEr9xf6qg== +verdaccio-auth-memory@8.1.2: + version "8.1.2" + resolved "https://registry.verdaccio.org/verdaccio-auth-memory/-/verdaccio-auth-memory-8.1.2.tgz#3ed70d5c259cc7bc3e6338f11f71129cdd94cfb2" + integrity sha512-5ISuVsr1/7LWGf4VnDdh+WXAvVyeSldlleEiJG5lIS2THXyGMzKVSjHzN6TfWqvOKsx5QDmwY78Qmy4LnCLP1g== dependencies: - "@verdaccio/commons-api" "^8.1.1" + "@verdaccio/commons-api" "^8.1.2" -verdaccio-htpasswd@8.0.0: - version "8.0.0" - resolved "https://registry.verdaccio.org/verdaccio-htpasswd/-/verdaccio-htpasswd-8.0.0.tgz#7939fa13fe46e5154cda526cf0f18085c633e618" - integrity sha512-tZKw5X6TQhVPmyB1NrkdXqQEFIyLbE0WGGt1jFX3tfjjl9cglZLvbkVNkUFKeZcOv4GjJ4zHGXwmTG2ZHlWpEw== +verdaccio-htpasswd@8.1.2: + version "8.1.2" + resolved "https://registry.verdaccio.org/verdaccio-htpasswd/-/verdaccio-htpasswd-8.1.2.tgz#594c97eb33e260a699861411235cca3e018d14be" + integrity sha512-GZGnToJ80Cd3qYE2upNxcq6M35wlDCW+iqe9sCooqH0gLo+C3TUTJw54Y6zC1qtlnTV29Bhf07ODr1j5IS6dcA== dependencies: "@verdaccio/file-locking" "1.0.0" apache-md5 "1.1.2" @@ -13407,38 +13590,38 @@ verdaccio-htpasswd@8.0.0: http-errors "1.7.3" unix-crypt-td-js "1.0.0" -verdaccio-memory@8.1.1: - version "8.1.1" - resolved "https://registry.verdaccio.org/verdaccio-memory/-/verdaccio-memory-8.1.1.tgz#03cc0f03ff0049aa9f238aba102481d72fea797b" - integrity sha512-MLoj6Jt0bq8iC42dTJ866ID/d1dkIT0iu2AvEpI7wrOYKjT+ytHVVMM+RZE7GmlPyNetxm5aAu/aYpRzoRl2lw== +verdaccio-memory@8.1.2: + version "8.1.2" + resolved "https://registry.verdaccio.org/verdaccio-memory/-/verdaccio-memory-8.1.2.tgz#68e0f84936cd6e7bd503973680b930cbdac52c5d" + integrity sha512-fMVJOwfTVDVmHHk4r+/kNpoUeVIwR0zxqNUREm/cyO7JSXoCkI3TQHD/lnRSiEN6eoHY/JPOZQo42GygKlsi9g== dependencies: - "@verdaccio/commons-api" "^8.1.1" - "@verdaccio/streams" "^8.1.1" + "@verdaccio/commons-api" "^8.1.2" + "@verdaccio/streams" "^8.1.2" http-errors "1.7.3" memory-fs "0.4.1" -verdaccio@4.2.2: - version "4.2.2" - resolved "https://registry.verdaccio.org/verdaccio/-/verdaccio-4.2.2.tgz#80207e64920076d90a0f61a096aed7bae24578f1" - integrity sha512-8T0IcuerV/BjMh+SiIZi7pfx3icc3JQHmJ1LGzHZPPwLy2UD+bZkSKkPrqqWxDhckwPqRcOMG0Xa5yOa9rDGhQ== +verdaccio@4.3.3: + version "4.3.3" + resolved "https://registry.verdaccio.org/verdaccio/-/verdaccio-4.3.3.tgz#4a3e462dc88da9afed22b1a91aa47dc818b110af" + integrity sha512-XE86BmCRVh6qghyO+v9o4VyydvJ/A/AFQul6wzo/tRriQxuOLFdsmVvAd8tZNqE4FKSXowTqQtABmKYB2cBNZw== dependencies: - "@verdaccio/commons-api" "8.0.0" - "@verdaccio/local-storage" "2.2.1" - "@verdaccio/readme" "8.0.0" - "@verdaccio/streams" "8.0.0" - "@verdaccio/ui-theme" "0.2.3" + "@verdaccio/commons-api" "8.1.2" + "@verdaccio/local-storage" "8.1.2" + "@verdaccio/readme" "8.1.2" + "@verdaccio/streams" "8.1.2" + "@verdaccio/ui-theme" "0.3.2" JSONStream "1.3.5" async "3.1.0" body-parser "1.19.0" bunyan "1.8.12" - commander "2.20.0" + commander "3.0.2" compression "1.7.4" cookies "0.7.3" cors "2.8.5" - dayjs "1.8.15" - envinfo "7.3.1" + dayjs "1.8.16" + envinfo "7.4.0" express "4.17.1" - handlebars "4.1.2" + handlebars "4.3.1" http-errors "1.7.3" js-yaml "3.13.1" jsonwebtoken "8.5.1" @@ -13454,8 +13637,8 @@ verdaccio@4.2.2: pkginfo "0.4.1" request "2.87.0" semver "6.3.0" - verdaccio-audit "8.0.0" - verdaccio-htpasswd "8.0.0" + verdaccio-audit "8.1.4" + verdaccio-htpasswd "8.1.2" verror@1.10.0: version "1.10.0" @@ -13514,6 +13697,17 @@ wait-for-expect@^1.3.0: resolved "https://registry.verdaccio.org/wait-for-expect/-/wait-for-expect-1.3.0.tgz#65241ce355425f907f5d127bdb5e72c412ff830c" integrity sha512-8fJU7jiA96HfGPt+P/UilelSAZfhMBJ52YhKzlmZQvKEZU2EcD1GQ0yqGB6liLdHjYtYAoGVigYwdxr5rktvzA== +wait-on@3.3.0: + version "3.3.0" + resolved "https://registry.verdaccio.org/wait-on/-/wait-on-3.3.0.tgz#9940981d047a72a9544a97b8b5fca45b2170a082" + integrity sha512-97dEuUapx4+Y12aknWZn7D25kkjMk16PbWoYzpSdA8bYpVfS6hpl2a2pOWZ3c+Tyt3/i4/pglyZctG3J4V1hWQ== + dependencies: + "@hapi/joi" "^15.0.3" + core-js "^2.6.5" + minimist "^1.2.0" + request "^2.88.0" + rx "^4.1.0" + walker@^1.0.7, walker@~1.0.5: version "1.0.7" resolved "https://registry.verdaccio.org/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" @@ -13844,14 +14038,14 @@ write@1.0.3: dependencies: mkdirp "^0.5.1" -ws@^5.2.0: +ws@^5.1.1, ws@^5.2.0: version "5.2.2" resolved "https://registry.verdaccio.org/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== dependencies: async-limiter "~1.0.0" -ws@^6.0.0, ws@^6.1.0, ws@^6.2.1: +ws@^6.0.0, ws@^6.2.1: version "6.2.1" resolved "https://registry.verdaccio.org/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== @@ -13903,7 +14097,7 @@ xss@1.0.6: commander "^2.9.0" cssfilter "0.0.10" -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: +xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.verdaccio.org/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==