From b991588764f01e89e84d2916defba37280420a44 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Wed, 9 Dec 2020 18:41:08 +0000 Subject: [PATCH] ui: Update UI README (#9346) --- ui/package.json | 3 +- ui/packages/consul-ui/README.md | 129 ++++++++++++++++++++++------- ui/packages/consul-ui/package.json | 7 +- ui/yarn.lock | 107 ++++++++++++++++++++++-- 4 files changed, 206 insertions(+), 40 deletions(-) diff --git a/ui/package.json b/ui/package.json index d14647a40..541a1a657 100644 --- a/ui/package.json +++ b/ui/package.json @@ -12,6 +12,7 @@ "doc:toc": "doctoc README.md" }, "devDependencies": { - "doctoc": "^1.4.0" + "doctoc": "^1.4.0", + "npm-run-all": "^4.1.5" } } diff --git a/ui/packages/consul-ui/README.md b/ui/packages/consul-ui/README.md index 3636d9197..56e402295 100644 --- a/ui/packages/consul-ui/README.md +++ b/ui/packages/consul-ui/README.md @@ -1,5 +1,21 @@ # consul-ui + + + + +- [Prerequisites](#prerequisites) +- [Installation](#installation) +- [Yarn Commands](#yarn-commands) +- [Running / Development](#running--development) + - [Browser 'Environment' Variables](#browser-environment-variables) + - [Code Generators](#code-generators) + - [Running Tests](#running-tests) + - [Linting](#linting) + - [Building](#building) + - [Running Tests in Parallel](#running-tests-in-parallel) + + ## Prerequisites @@ -7,6 +23,7 @@ You will need the following things properly installed on your computer. * [Git](https://git-scm.com/) * [Node.js](https://nodejs.org/) (with npm) + * [yarn](https://yarnpkg.com) * [Ember CLI](https://ember-cli.com/) * [Google Chrome](https://google.com/chrome/) @@ -14,10 +31,38 @@ You will need the following things properly installed on your computer. ## Installation * `git clone https://github.com/hashicorp/consul.git` this repository -* `cd ui-v2` -* `yarn install` +* `cd ui/packages/consul-ui` +* `make start` or `yarn && yarn start` -All tooling scripts below primarily use `make` which in turn call node package scripts. + +## Yarn Commands + +Most used tooling scripts below primarily use `make` which will `yarn install` +and in turn call node package scripts. + +List of available project commands. `yarn run ` + +| Command | Description | +| ------- | ----------- | +| build:staging | Builds the UI in staging mode (ready for PR preview site). | +| build:ci | Builds the UI for CI. | +| build | Builds the UI for production. | +| lint | Runs all lint commands. | +| lint:hbs | Lints `hbs` template files. | +| lint:js | Lints `js` files. | +| format | Runs all auto-formatters. | +| format:js | Auto-formats `js` files using Prettier. | +| format:sass | Auto-formats `scss` files using Prettier. | +| start | Runs the development app on a local server using the mock API. | +| start:consul | Runs the development app local server using a real consul instance as the backend. | +| start:staging | Runs the staging app local server. | +| test | Runs the ember tests in a headless browser. | +| test:view | Runs the ember tests in a non-headless browser. | +| test:oss | Runs only the OSS ember tests in a headless browser. | +| test:oss:view | Runs only the OSS ember tests in a non-headless browser. | +| test:coverage:view | Runs only the test specified for coverage in a non-headless browser. | +| test:node | Runs tests that can't be run in ember using node. | +| doc:toc | Automatically generates a table of contents for this README file. | ## Running / Development @@ -28,52 +73,75 @@ consul. * `make start` or `yarn start` to start the ember app * Visit your app at [http://localhost:4200](http://localhost:4200). -To enable ACLs using the mock API, use Web Inspector to set a cookie as follows: +You can also run the UI against a normal Consul installation. +* `consul server -dev` to start consul listening on http://localhost:8500 +* `make start-consul` to start the ember app proxying to `consul` (this will +respect the `CONSUL_HTTP_ADDR` environment variable to locate the Consul +installation. +* Visit your app at [http://localhost:4200](http://localhost:4200). + +Example: + +```bash +CONSUL_HTTP_ADDR=http://10.0.0.1:8500 make start-consul ``` + + +### Browser 'Environment' Variables + +In order to configure different configurations of Consul you can use Web +Inspector in your browser to set various cookie which to emulate different +configurations whislt using the mock API. + +For example: to enable ACLs, use Web Inspector to set a cookie as follows: + +```bash CONSUL_ACLS_ENABLE=1 ``` This will enable the ACLs login page, to which you can login with any ACL token/secret. -You can also use a number of other cookie key/values to set various things whilst -developing the UI, such as (but not limited to): +| Variable | Default Value | Description | +| -------- | ------------- | ----------- | +| `CONSUL_ACLS_ENABLE` | false | Enable/disable ACLs support. | +| `CONSUL_ACLS_LEGACY` | false | Enable/disable legacy ACLs support. | +| `CONSUL_NSPACES_ENABLE` | false | Enable/disable Namespace support. | +| `CONSUL_SSO_ENABLE` | false | Enable/disable SSO support. | +| `CONSUL_OIDC_PROVIDER_URL` | undefined | Provide a OIDC provider URL for SSO. | +| `CONSUL_LATENCY` | 0 | Add a latency to network requests (milliseconds) | +| `CONSUL_METRICS_POLL_INTERVAL` | 10000 | Change the interval between requests to the metrics provider (milliseconds) | +| `CONSUL_SERVICE_COUNT` | (random) | Configure the number of services that the API returns. | +| `CONSUL_NODE_COUNT` | (random) | Configure the number of nodes that the API returns. | +| `CONSUL_KV_COUNT` | (random) | Configure the number of KV entires that the API returns. | +| `CONSUL_INTENTION_COUNT` | (random) | Configure the number of intentions that the API returns. | +| `CONSUL_POLICY_COUNT` | (random) | Configure the number of policies that the API returns. | +| `CONSUL_ROLE_COUNT` | (random) | Configure the number of roles that the API returns. | +| `CONSUL_NSPACE_COUNT` | (random) | Configure the number of namespaces that the API returns. | +| `CONSUL_UPSTREAM_COUNT` | (random) | Configure the number of upstreams that the API returns. | +| `CONSUL_EXPOSED_COUNT` | (random) | Configure the number of exposed paths that the API returns. | +| `CONSUL_CHECK_COUNT` | (random) | Configure the number of health checks that the API returns. | +| `CONSUL_OIDC_PROVIDER_COUNT` | (random) | Configure the number of OIDC providers that the API returns. | -``` -CONSUL_SERVICE_COUNT=1000 -CONSUL_NODE_CODE=1000 -// etc etc -``` - -See `./node_modules/@hashicorp/consul-api-double` for more details. - -If you wish to run the UI code against a running consul instance, uncomment the `proxy` -line in `.ember-cli` to point ember-cli to your consul instance. - -You can also run the UI against a normal Consul installation. - -`make start-consul` or `yarn run start:consul` will use the `CONSUL_HTTP_ADDR` -environment variable to locate the Consul installation. If that it not set -`start-consul` will use `http://localhost:8500`. - -Example usage: - -``` -CONSUL_HTTP_ADDR=http://10.0.0.1:8500 make start-consul -``` +See `./mock-api` for more details. ### Code Generators -Make use of the many generators for code, try `ember help generate` for more details +Many classes used in the UI can be generated with ember generators, try `ember help generate` for more details ### Running Tests -Please note: You do not need to run `make start-api`/`yarn run start:api` to run the tests, but the same mock consul API is used. +Tests use the mock api (see ./mock-api for details) * `make test` or `yarn run test` * `make test-view` or `yarn run test:view` to view the tests running in Chrome +OSS only tests can also be run using: + +* `make test-oss` or `yarn run test:oss` +* `make test-oss-view` or `yarn run test:oss:view` to view the tests running in Chrome + ### Linting `make lint` currently runs linting on the majority of js files and hbs files (using `ember-template-lint`). @@ -88,6 +156,7 @@ See `.eslintrc.js` and `.eslintignore` for specific configuration. Static files are built into ./dist #### Running Tests in Parallel + Alternatively, `ember-exam` can be used to split the tests across multiple browser instances for faster results. Most options are the same as `ember test`. To see a full list of options, run `ember exam --help`. **Note:** The `EMBER_EXAM_PARALLEL` environment variable must be set to override the default `parallel` value of `1` browser instance in [testem.js](./testem.js). diff --git a/ui/packages/consul-ui/package.json b/ui/packages/consul-ui/package.json index cfb074357..50756f19c 100644 --- a/ui/packages/consul-ui/package.json +++ b/ui/packages/consul-ui/package.json @@ -12,11 +12,14 @@ "build": "ember build --environment=production", "build:staging": "ember build --environment staging", "build:ci": "ember build --environment test", - "lint:dev:js": "eslint -c .dev.eslintrc.js --fix ./*.js ./.*.js app config lib server tests", + "doc:toc": "doctoc README.md", + "lint": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*", "lint:hbs": "ember-template-lint .", "lint:js": "eslint .", + "_lint:dev:js": "eslint -c .dev.eslintrc.js --fix ./*.js ./.*.js app config lib server tests", + "format": "npm-run-all format:*", "format:js": "prettier --write \"{app,config,lib,server,vendor,tests}/**/*.js\" ./*.js ./.*.js", - "format:css": "prettier --write \"app/styles/**/*.*\"", + "format:sass": "prettier --write \"app/styles/**/*.*.scss\"", "start": "ember serve --port=${EMBER_SERVE_PORT:-4200} --live-reload-port=${EMBER_LIVE_RELOAD_PORT:-7020}", "start:staging": "ember serve --port=${EMBER_SERVE_PORT:-4200} --live-reload-port=${EMBER_LIVE_RELOAD_PORT:-7020} --environment staging", "start:consul": "ember serve --proxy=${CONSUL_HTTP_ADDR:-http://localhost:8500} --port=${EMBER_SERVE_PORT:-4200} --live-reload-port=${EMBER_LIVE_RELOAD_PORT:-7020}", diff --git a/ui/yarn.lock b/ui/yarn.lock index 84ab08da9..84409b5a4 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -6581,7 +6581,7 @@ cross-spawn@7.0.1: shebang-command "^2.0.0" which "^2.0.1" -cross-spawn@^6.0.0: +cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -10425,6 +10425,11 @@ homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" +hosted-git-info@^2.1.4: + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + hosted-git-info@^3.0.6: version "3.0.7" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.7.tgz#a30727385ea85acfcee94e0aad9e368c792e036c" @@ -11857,6 +11862,16 @@ livereload-js@^2.3.0: resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.4.0.tgz#447c31cf1ea9ab52fc20db615c5ddf678f78009c" integrity sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw== +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + loader-runner@^2.3.0, loader-runner@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" @@ -12389,6 +12404,11 @@ memory-streams@^0.1.3: dependencies: readable-stream "~1.0.2" +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -12887,6 +12907,16 @@ nopt@^3.0.6: dependencies: abbrev "1" +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -12927,6 +12957,21 @@ npm-package-arg@^8.0.1: semver "^7.0.0" validate-npm-package-name "^3.0.0" +npm-run-all@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" + integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== + dependencies: + ansi-styles "^3.2.1" + chalk "^2.4.1" + cross-spawn "^6.0.5" + memorystream "^0.3.1" + minimatch "^3.0.4" + pidtree "^0.3.0" + read-pkg "^3.0.0" + shell-quote "^1.6.1" + string.prototype.padend "^3.0.0" + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -13573,6 +13618,11 @@ picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== +pidtree@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" + integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== + pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" @@ -14295,6 +14345,15 @@ reactcss@^1.2.0: dependencies: lodash "^4.0.1" +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" @@ -15032,16 +15091,16 @@ semver-regex@^2.0.0: resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338" integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + semver@7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -15166,7 +15225,7 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@1.7.2: +shell-quote@1.7.2, shell-quote@^1.6.1: version "1.7.2" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== @@ -15474,6 +15533,32 @@ spawn-args@^0.2.0: resolved "https://registry.yarnpkg.com/spawn-args/-/spawn-args-0.2.0.tgz#fb7d0bd1d70fd4316bd9e3dec389e65f9d6361bb" integrity sha1-+30L0dcP1DFr2ePew4nmX51jYbs= +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.7" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" + integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -16862,6 +16947,14 @@ v8-compile-cache@^2.1.1: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + validate-npm-package-name@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e"