diff --git a/.circleci/config.yml b/.circleci/config.yml index be51bc8bd..4b719e9ba 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,31 +2,94 @@ # # Check https://circleci.com/docs/2.0/language-javascript/ for more details # +aliases: + # Workflow filters + - &filter-not-release-or-master + tags: + ignore: /^v[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)$/ + branches: + ignore: + - master + - &filter-only-master + branches: + only: master + version: 2 jobs: build: docker: - # specify the version you desire here - - image: circleci/node:7.10 - + - image: circleci/node:8 working_directory: ~/repo - steps: - checkout - - # Download and cache dependencies - restore_cache: keys: - - v1-dependencies-{{ checksum "package.json" }} + - dependency-cache-{{ checksum "yarn.lock" }} # fallback to using the latest cache if no exact match is found - - v1-dependencies- + - dependency-cache- + - run: + name: yarn install + command: 'yarn install --pure-lockfile --no-progress' + - save_cache: + paths: + - node_modules + key: dependency-cache-{{ checksum "yarn.lock" }} + - run: yarn lint-repo - - run: yarn install + check-repo-update: + docker: + - image: circleci/node:8 + working_directory: ~/repo + steps: + - checkout + - restore_cache: + keys: + - dependency-cache-{{ checksum "yarn.lock" }} + - dependency-cache- + - run: + name: yarn install + command: 'yarn install --pure-lockfile --no-progress' + - save_cache: + paths: + - node_modules + key: dependency-cache-{{ checksum "yarn.lock" }} + - run: + name: check-repo-update + command: node ./scripts/check-repo-update.js + lint-updated-plugins: + docker: + - image: circleci/node:8 + working_directory: ~/repo + steps: + - checkout + - restore_cache: + keys: + - dependency-cache-{{ checksum "yarn.lock" }} + - dependency-cache- + - run: + name: yarn install + command: 'yarn install --pure-lockfile --no-progress' - save_cache: paths: - node_modules - key: v1-dependencies-{{ checksum "package.json" }} - - # run tests! - - run: yarn lint \ No newline at end of file + key: dependency-cache-{{ checksum "yarn.lock" }} + - run: + name: lint-updated-plugins + command: node ./scripts/lint-repo-update.js + +workflows: + version: 2 + build-master: + jobs: + - build: + filters: *filter-only-master + + build-branches-and-prs: + jobs: + - check-repo-update: + filters: *filter-not-release-or-master + - lint-updated-plugins: + filters: *filter-not-release-or-master + # - build: + # filters: *filter-not-release-or-master diff --git a/.circleci/run-build-locally.sh b/.circleci/run-build-locally.sh new file mode 100755 index 000000000..cfca71c55 --- /dev/null +++ b/.circleci/run-build-locally.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +BASEDIR=$(dirname "$0") + +CURRENT_COMMIT_HASH=$(git log -n 1 | grep -Po "(?<=commit )[0-9a-z]{40}") +CURRENT_BRANCH=$(git status | grep -Po "(?<=On branch ).+") + +COMMIT_HASH=${2:-${CURRENT_COMMIT_HASH}} +BRANCH=${1:-${CURRENT_BRANCH}} + +echo "Branch: ${BRANCH} commit: ${COMMIT_HASH}" + +curl --user ${CIRCLE_TOKEN}: \ + --request POST \ + --form revision=${CURRENT_COMMIT_HASH}\ + --form config=${BASEDIR}/config.yml \ + --form notify=false \ + https://circleci.com/api/v1.1/project/github/grafana/grafana-plugin-repository/tree/${CURRENT_BRANCH} diff --git a/.gitignore b/.gitignore index b512c09d4..76efb07fd 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -node_modules \ No newline at end of file +node_modules +.vscode diff --git a/package.json b/package.json index 1574b57b0..461b54d8c 100644 --- a/package.json +++ b/package.json @@ -6,11 +6,17 @@ "author": "Daniel Lee ", "license": "MIT", "scripts": { - "lint": "grunt" + "lint": "grunt", + "lint-repo": "./scripts/lint-repo.js", + "lint-repo-update": "./scripts/lint-repo-update.js", + "test-ci-build": "./.circleci/run-build-locally.sh" }, "devDependencies": { + "chalk": "^2.4.2", "grunt": "^1.0.1", - "request": "^2.83.0", + "lodash": "^4.17.11", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", "semver": "^5.4.1" } } diff --git a/repo.json b/repo.json index 57e39c039..2629d6539 100644 --- a/repo.json +++ b/repo.json @@ -2664,7 +2664,7 @@ "commit": "d34709e5ee7bddcdd93cbf8dbf31ce8b9e02d056", "url": "https://github.com/michaeldmoore/michaeldmoore-multistat-panel" } - ], + ] }, { "id": "scadavis-synoptic-panel", diff --git a/scripts/check-plugins.js b/scripts/check-plugins.js new file mode 100755 index 000000000..f61c66c5a --- /dev/null +++ b/scripts/check-plugins.js @@ -0,0 +1,23 @@ +#!/usr/bin/env node +const fs = require('fs'); +const path = require('path'); +const chalk = require('chalk'); + +// const prettyjson = require('prettyjson'); + +// const repo = require('../repo.json'); +const repoPath = path.join(__dirname, '../repo.json'); +let repo = fs.readFileSync(repoPath); +try { + repo = JSON.parse(repo); +} catch (parseError) { + console.error(chalk.red('Error parsing repo.json')) + console.error(parseError); + process.exit(1); +} + +// console.log(prettyjson.render(repo)); +// console.log(repo); +const plugins = repo.plugins.map(plugin => plugin.id); +// console.log(plugins); +console.log(repo.plugins[1]); diff --git a/scripts/check-repo-update.js b/scripts/check-repo-update.js new file mode 100755 index 000000000..69d99e233 --- /dev/null +++ b/scripts/check-repo-update.js @@ -0,0 +1,24 @@ +#!/usr/bin/env node +const request = require('request-promise-native'); +const { diffPluginsRepo } = require('./diffPluginsRepo'); +const { checkSemver } = require('./checkSemver'); + +const repoMasterUrl = 'https://raw.githubusercontent.com/grafana/grafana-plugin-repository/master/repo.json'; +const repoCurrent = require('../repo.json'); + +function main() { + return request(repoMasterUrl).then(body => { + const repoMaster = JSON.parse(body); + const diff = diffPluginsRepo(repoCurrent, repoMaster); + return { diff, repoMaster }; + }).then(result => { + const { diff, repoMaster } = result; + console.log(JSON.stringify(diff, null, 2)); + return checkSemver(diff, repoMaster); + }).catch(error => { + console.error(error); + process.exit(1); + }); +} + +main(); diff --git a/scripts/checkSemver.js b/scripts/checkSemver.js new file mode 100644 index 000000000..b7a486c80 --- /dev/null +++ b/scripts/checkSemver.js @@ -0,0 +1,34 @@ +const _ = require('lodash'); +const semver = require('semver'); + +/** + * Checks whether plugin updates follow semver or not. + * @param {*} diff + * @param {*} base + */ +function checkSemver(diff, base) { + _.forEach(diff.diff, (pluginUpdate, pluginId) => { + _.forEach(pluginUpdate.versions, versionObj => { + const updateVersion = versionObj.version; + if (!semver.valid(updateVersion)) { + throw new Error(`Invalid version: ${updateVersion} (plugin: ${pluginId})`); + } + const basePlugin = _.find(base.plugins, { 'id': pluginId }); + if (basePlugin) { + + const baseVersions = basePlugin.versions; + _.forEach(baseVersions, baseVersionObj => { + const baseVersion = baseVersionObj.version; + if (semver.lt(updateVersion, baseVersion)) { + throw new Error(`Updated version should be greater than previous: ${updateVersion} < ${baseVersion} (plugin: ${pluginId})`); + } + }); + } + }); + }); + return true; +} + +module.exports = { + checkSemver +}; diff --git a/scripts/diffPluginsRepo.js b/scripts/diffPluginsRepo.js new file mode 100644 index 000000000..0e6fdd376 --- /dev/null +++ b/scripts/diffPluginsRepo.js @@ -0,0 +1,78 @@ +const _ = require('lodash'); + +/** + * Returns plugins repo diff with additional metadata. + * @param {Object} update updated repo + * @param {Object} base base repo + * @return {Object} Diff object + */ +function diffPluginsRepo(update, base) { + let diff = {}; + let diffMeta = {}; + + const pluginsBase = _.keyBy(base.plugins, 'id'); + const pluginsUpdate = _.keyBy(update.plugins, 'id'); + + _.forEach(pluginsUpdate, (pluginUpdate, id) => { + const pluginBase = pluginsBase[id]; + + // New plugin added + if (!pluginBase) { + diff[id] = pluginUpdate; + diffMeta[id] = { newPlugin: true }; + return; + } + + // Plugin version added + if (!_.isEqual(pluginUpdate, pluginBase)) { + diff[id] = {}; + diffMeta[id] = { updatedPlugin: true }; + + // Check if metadata was changed + _.forOwn(pluginUpdate, (value, key) => { + if (value !== pluginBase[key] && key !== 'versions') { + diffMeta[id].metadataUpdated = true; + diff[key] = value; + } + }); + + let versionsDiff = _.xorWith(pluginUpdate.versions, pluginBase.versions, _.isEqual); + if (versionsDiff && versionsDiff.length) { + diff[id].versions = []; + // Check if version was changed + versionsDiff.forEach(versionObj => { + const changedVersion = _.find(pluginBase.versions, { 'version': versionObj.version }); + if (changedVersion) { + diffMeta[id].versionChanged = true; + const versionChange = _.find(pluginUpdate.versions, { 'version': versionObj.version }); + if (versionChange && !_.find(diff[id].versions, { 'version': versionChange.version })) { + diff[id].versions.push(versionChange); + _.forOwn(changedVersion, (value, key) => { + if (value !== versionObj[key]) { + if (diffMeta[id].versionChanges && diffMeta[id].versionChanges[versionObj.version]) { + diffMeta[id].versionChanges[versionObj.version].push(key); + } else { + diffMeta[id].versionChanges = { + [versionObj.version]: [key] + }; + } + } + }); + } + } else { + diff[id].versions.push(versionObj); + diffMeta[id].versionAdded = true; + } + }); + } + } + }); + return { + diff: diff, + meta: diffMeta + }; +} + +module.exports = { + diffPluginsRepo +}; diff --git a/scripts/github/github.js b/scripts/github/github.js new file mode 100644 index 000000000..7a90d63f9 --- /dev/null +++ b/scripts/github/github.js @@ -0,0 +1,97 @@ +const request = require('request-promise-native'); +const { GITHUB_API_TOKEN } = process.env; + +function getFileContent(owner, repo, path, commit) { + let endpoint = `/repos/${owner}/${repo}/contents/${path}`; + if (commit) { + endpoint += `?ref=${commit}`; + } + return apiRequest(endpoint).then(result => { + if (result && result.content) { + const encoding = result.encoding || 'base64'; + const content = Buffer.from(result.content, encoding).toString(); + return content; + } + }); +} + +function fetchFile({base, commit, path, prefix}) { + // try to match base as a github repo url + const matches = new RegExp('^https?://github[.]com/([^/]+)/([^/]+)(?:/tree/([^/]+))?(.*)$').exec(base); + + // couldn't match the base + if (!matches) { + throw new Error('Could not extract repo and owner from url'); + } + + // build github contents api url + const owner = matches[1]; + const repo = matches[2]; + const baseRef = matches[3]; + const basePath = matches[4]; + + let filePath = basePath; + if (prefix) { + filePath += '/' + prefix; + } + filePath += '/' + path; + if (filePath[0] === '/') { + filePath = filePath.slice(1); + } + + if (!commit && baseRef) { + commit = baseRef; + } + + return getFileContent(owner, repo, filePath, commit); +} + +async function fetchJson({base, commit, path, prefix}) { + const content = await fetchFile({base, commit, path, prefix}); + try { + const json = JSON.parse(content); + return json; + } catch(parseErr) { + return Promise.reject(parseErr); + } +} + +async function fetchPluginJson(url, commit) { + let json; + + for (const prefix of ['dist', '', 'src']) { + try { + json = await fetchJson({ base: url, commit, path: 'plugin.json', prefix }); + return { json, prefix }; + } catch(err) { + // Skip errors for first two prefixes + if (prefix === 'src') { + throw new Error(err.message); + } + } + } + + throw new Error('Could not find plugin.json'); +} + +function apiRequest(endpoint) { + const githubApiUrl = 'https://api.github.com'; + const url = `${githubApiUrl}${endpoint}`; + const options = { + uri: url, + headers: { + 'User-Agent': 'NodeJS' + }, + json: true + }; + if (GITHUB_API_TOKEN) { + options.headers['Authorization'] = `token ${GITHUB_API_TOKEN}`; + } + return request(options); +} + +module.exports = { + getFileContent, + fetchPluginJson, + request: apiRequest, +}; diff --git a/scripts/lint-plugin.js b/scripts/lint-plugin.js new file mode 100755 index 000000000..099cfc0b6 --- /dev/null +++ b/scripts/lint-plugin.js @@ -0,0 +1,27 @@ +#!/usr/bin/env node +const chalk = require('chalk'); +const { lintPlugin } = require('./lintPlugin'); + +const pluginUrl = process.argv[2]; +const commit = process.argv[3]; + +console.log(`${pluginUrl} : ${commit}`); + +return lintPlugin(pluginUrl, commit).then(result => { + // console.debug(result); + if (result && result.statusCode > 0) { + console.error(chalk.yellow(result.status)); + result.warnings.forEach(err => console.error(chalk.yellow(err))); + } else { + console.log(chalk.green(result.status)); + } +}).catch(error => { + if (error && error.status === 'Error') { + console.error(chalk.red(error.status)); + error.errors.forEach(err => console.error(chalk.red(err))); + error.warnings.forEach(err => console.error(chalk.yellow(err))); + process.exit(1); + } else { + console.error(error.message || error); + } +}); diff --git a/scripts/lint-repo-update.js b/scripts/lint-repo-update.js new file mode 100755 index 000000000..ee70e984b --- /dev/null +++ b/scripts/lint-repo-update.js @@ -0,0 +1,81 @@ +#!/usr/bin/env node +const _ = require('lodash'); +const chalk = require('chalk'); +const request = require('request-promise-native'); +const { diffPluginsRepo } = require('./diffPluginsRepo'); +const { lintPlugin } = require('./lintPlugin'); + +const repoMasterUrl = 'https://raw.githubusercontent.com/grafana/grafana-plugin-repository/master/repo.json'; +const repoCurrent = require('../repo.json'); + +async function main() { + return request(repoMasterUrl).then(body => { + const repoMaster = JSON.parse(body); + try { + const diff = diffPluginsRepo(repoCurrent, repoMaster); + return diff; + } catch(diffError) { + console.log(diffError); + process.exit(1); + } + }).then(result => { + const diff = result; + return lintRepoUpdate(diff); + }).catch(error => { + console.error(error.message ? chalk.red(error.message) : error); + process.exit(1); + }); +} + +function lintRepoUpdate(diff) { + let success = true; + let promises = []; + _.forEach(diff.diff, (pluginUpdate, pluginId) => { + _.forEach(pluginUpdate.versions, async versionObj => { + const url = versionObj.url.trim(); + const commit = versionObj.commit.trim(); + const version = versionObj.version; + + const lintPromise = lintPlugin(url, commit, version).then(result => { + console.log(`Linting ${chalk.blue(pluginId)} version ${chalk.blue(versionObj.version)}`); + console.log(`${url} : ${commit}`); + if (result && result.statusCode > 0) { + console.error(chalk.yellow(result.status)); + result.warnings.forEach(err => console.error(chalk.yellow(err))); + } else { + console.log(chalk.green(result.status)); + } + console.log(''); + return; + }).catch(error => { + console.log(`Linting ${chalk.blue(pluginId)} version ${chalk.blue(versionObj.version)}`); + console.log(`${url} : ${commit}`); + if (error && error.status === 'Error') { + console.error(chalk.red(error.status)); + error.errors.forEach(err => console.error(chalk.red(err))); + error.warnings.forEach(err => console.error(chalk.yellow(err))); + } else { + console.error(error); + } + console.log(''); + success = false; + return; + }); + promises.push(lintPromise); + }); + }); + + if (promises.length === 0) { + console.log('No plugins to lint'); + } + + return Promise.all(promises).then(() => { + if (success) { + return success; + } else { + return Promise.reject(new Error('Failed linting plugins update')); + } + }); +} + +main().catch(console.error); diff --git a/scripts/lint-repo.js b/scripts/lint-repo.js new file mode 100755 index 000000000..53281d6c4 --- /dev/null +++ b/scripts/lint-repo.js @@ -0,0 +1,94 @@ +#!/usr/bin/env node +const fs = require('fs'); +const path = require('path'); +const _ = require('lodash'); +const semver = require('semver'); +const chalk = require('chalk'); +const { lintPlugin } = require('./lintPlugin'); + +async function main() { + let pluginsRepo; + try { + pluginsRepo = getRepo(); + } catch(err) { + console.error(chalk.red('Error processing repo.json')) + console.error(err); + process.exit(1); + } + const plugins = pluginsRepo.plugins; + if (!(plugins && plugins.length)) { + console.log(chalk.yellow('Warning: repo.json is empty')); + } + + let okLints = 0; + let failedLints = 0; + let warningLints = 0; + + for (const plugin of plugins) { + let version; + + if (!(plugin.versions && plugin.versions.length)) { + console.log(chalk.yellow(`Warning: plugin ${plugin.id} has no versions`)); + continue; + } + + if (plugin.versions.length === 1) { + version = plugin.versions[0]; + } else { + // use the top or bottom commit which has the highest version + // can't sort with semver as lots of plugins don't follow it + const topVersion = plugin.versions[0]; + const bottomVersion = plugin.versions[plugin.versions.length - 1]; + version = semver.gte(topVersion.version, bottomVersion.version) ? topVersion : bottomVersion; + } + + let commit = version.commit; + let url = version.url; + + // console.log(`Linting plugin ${chalk.blue(plugin.id)}`); + console.log(`Linting ${chalk.blue(plugin.id)} version ${chalk.blue(version.version)}`); + try { + const lintResult = await lintPlugin(url, commit, version.version); + if (lintResult) { + if (lintResult && lintResult.statusCode > 0) { + console.error(chalk.yellow(lintResult.status)); + lintResult.warnings.forEach(err => console.error(chalk.yellow(err))); + warningLints++; + } else { + console.log(chalk.green(lintResult.status)); + okLints++; + } + } + console.log(''); + } catch(error) { + console.log(`${url} : ${commit}`); + if (error && error.status === 'Error') { + console.error(chalk.red(error.status)); + error.errors.forEach(err => console.error(chalk.red(err))); + error.warnings.forEach(err => console.error(chalk.yellow(err))); + } else { + console.error(error); + } + failedLints++; + console.log(''); + } + } + + console.log(chalk.green('Status:')); + console.log(`${chalk.green('OK')}: ${okLints}`); + console.log(`${chalk.yellow('Warnings')}: ${warningLints}`); + console.log(`${chalk.red('Failed')}: ${failedLints}`); + + if (failedLints > 0) { + process.exit(1); + } +} + +function getRepo() { + const repoPath = path.join(__dirname, '../repo.json'); + let repo = fs.readFileSync(repoPath); + repo = JSON.parse(repo); + return repo; +} + +main(); diff --git a/scripts/lintPlugin.js b/scripts/lintPlugin.js new file mode 100644 index 000000000..d89b9b543 --- /dev/null +++ b/scripts/lintPlugin.js @@ -0,0 +1,76 @@ +const request = require('request-promise-native'); +const { fetchPluginJson } = require('./github/github'); + +async function lintPlugin(pluginUrl, commit, version) { + const postData = { + url: pluginUrl, + commit: commit + }; + + const apiResponse = await request.post({url:'https://grafana.com/api/plugins/lint', form: postData}); + // console.debug(apiResponse); + const linterResult = JSON.parse(apiResponse); + + const result = { + status: 'OK', + statusCode: 0, + errors: [], + warnings: [], + }; + + if (!linterResult.valid) { + if (linterResult.lintErrors && linterResult.lintErrors.length) { + const htmlTagsErrorPattern = /The .* file contains HTML tags/; + linterResult.lintErrors.forEach(err => { + // Do not fail on "The README.md file contains HTML tags" error + if (htmlTagsErrorPattern.test(err)) { + result.status = 'Warning' + result.statusCode = 1; + result.warnings.push(err); + } else { + result.status = 'Error' + result.statusCode = 2; + result.errors.push(err); + } + }); + } else { + result.status = 'Error' + result.statusCode = 2; + } + } + + // Try to fetch plugin.json and make some additional checks + try { + const pluginJsonResponse = await fetchPluginJson(pluginUrl, commit); + const pluginJson = pluginJsonResponse.json; + // console.log(pluginJson); + if (pluginJsonResponse.prefix === 'src') { + result.warnings.push(`It seems, plugin isn't built properly: plugin.json found in src/ only`); + if (result.statusCode === 0) { + result.status = 'Warning' + result.statusCode = 1; + } + } + + const pluginJsonVersion = pluginJson.info.version; + if (version && (!pluginJsonVersion || pluginJsonVersion !== version)) { + result.warnings.push(`Version in repo.json (${version}) doesn't match plugin.json (${pluginJsonVersion})`); + if (result.statusCode === 0) { + result.status = 'Warning' + result.statusCode = 1; + } + } + } catch(err) { + console.log(`Warning: failed fetching plugin.json. This may be caused by private repo without proper access rights.`); + } + + if (result.statusCode < 2) { + return result; + } else { + return Promise.reject(result); + } +} + +module.exports = { + lintPlugin +}; diff --git a/yarn.lock b/yarn.lock index 267033f6d..c67cf8c3a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6,14 +6,15 @@ abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" -ajv@^5.1.0: - version "5.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" +ajv@^6.5.5: + version "6.9.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.9.1.tgz#a4d3683d74abc5670e75f0b16520f70a20ea8dc1" + integrity sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA== dependencies: - co "^4.6.0" - fast-deep-equal "^1.0.0" + fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" ansi-regex@^2.0.0: version "2.1.1" @@ -23,6 +24,13 @@ ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + argparse@^1.0.2: version "1.0.9" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" @@ -53,9 +61,10 @@ aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" -aws4@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" +aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== balanced-match@^1.0.0: version "1.0.0" @@ -67,18 +76,6 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -boom@4.x.x: - version "4.3.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" - dependencies: - hoek "4.x.x" - -boom@5.x.x: - version "5.2.0" - resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" - dependencies: - hoek "4.x.x" - brace-expansion@^1.1.7: version "1.1.8" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" @@ -105,6 +102,15 @@ caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + chalk@~1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -115,21 +121,30 @@ chalk@~1.1.1: strip-ansi "^3.0.0" supports-color "^2.0.0" -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - coffee-script@~1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.10.0.tgz#12938bcf9be1948fa006f92e0c4c9e81705108c0" +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + colors@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" + integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== dependencies: delayed-stream "~1.0.0" @@ -141,12 +156,6 @@ core-util-is@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" -cryptiles@3.x.x: - version "3.1.2" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" - dependencies: - boom "5.x.x" - currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -186,7 +195,7 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -escape-string-regexp@^1.0.2: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -202,9 +211,10 @@ exit@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" -extend@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== extsprintf@1.3.0: version "1.3.0" @@ -214,9 +224,10 @@ extsprintf@^1.2.0: version "1.4.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" -fast-deep-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= fast-json-stable-stringify@^2.0.0: version "2.0.0" @@ -239,12 +250,13 @@ forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" -form-data@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== dependencies: asynckit "^0.4.0" - combined-stream "^1.0.5" + combined-stream "^1.0.6" mime-types "^2.1.12" fs.realpath@^1.0.0: @@ -357,11 +369,12 @@ har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" -har-validator@~5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" +har-validator@~5.1.0: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== dependencies: - ajv "^5.1.0" + ajv "^6.5.5" har-schema "^2.0.0" has-ansi@^2.0.0: @@ -370,18 +383,10 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" -hawk@~6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" - dependencies: - boom "4.x.x" - cryptiles "3.x.x" - hoek "4.x.x" - sntp "2.x.x" - -hoek@4.x.x: - version "4.2.0" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= hooker@~0.2.3: version "0.2.3" @@ -463,9 +468,10 @@ jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" -json-schema-traverse@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema@0.2.3: version "0.2.3" @@ -494,6 +500,11 @@ load-json-file@^1.0.0: pinkie-promise "^2.0.0" strip-bom "^2.0.0" +lodash@^4.17.11: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + lodash@~3.10.1: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" @@ -532,12 +543,24 @@ mime-db@~1.30.0: version "1.30.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" -mime-types@^2.1.12, mime-types@~2.1.17: +mime-db@~1.38.0: + version "1.38.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad" + integrity sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg== + +mime-types@^2.1.12: version "2.1.17" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" dependencies: mime-db "~1.30.0" +mime-types@~2.1.19: + version "2.1.22" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.22.tgz#fe6b355a190926ab7698c9a0556a11199b2199bd" + integrity sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog== + dependencies: + mime-db "~1.38.0" + "minimatch@2 || 3", minimatch@^3.0.2, minimatch@~3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -567,9 +590,10 @@ number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" -oauth-sign@~0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== object-assign@^4.0.1: version "4.1.1" @@ -623,13 +647,24 @@ pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" +psl@^1.1.24, psl@^1.1.28: + version "1.1.31" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" + integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== + punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" -qs@~6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== read-pkg-up@^1.0.1: version "1.0.1" @@ -659,32 +694,47 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request@^2.83.0: - version "2.83.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" +request-promise-core@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.2.tgz#339f6aababcafdb31c799ff158700336301d3346" + integrity sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag== + dependencies: + lodash "^4.17.11" + +request-promise-native@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.7.tgz#a49868a624bdea5069f1251d0a836e0d89aa2c59" + integrity sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w== + dependencies: + request-promise-core "1.1.2" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + +request@^2.88.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== dependencies: aws-sign2 "~0.7.0" - aws4 "^1.6.0" + aws4 "^1.8.0" caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.1" + combined-stream "~1.0.6" + extend "~3.0.2" forever-agent "~0.6.1" - form-data "~2.3.1" - har-validator "~5.0.3" - hawk "~6.0.2" + form-data "~2.3.2" + har-validator "~5.1.0" http-signature "~1.2.0" is-typedarray "~1.0.0" isstream "~0.1.2" json-stringify-safe "~5.0.1" - mime-types "~2.1.17" - oauth-sign "~0.8.2" + mime-types "~2.1.19" + oauth-sign "~0.9.0" performance-now "^2.1.0" - qs "~6.5.1" - safe-buffer "^5.1.1" - stringstream "~0.0.5" - tough-cookie "~2.3.3" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" tunnel-agent "^0.6.0" - uuid "^3.1.0" + uuid "^3.3.2" resolve@~1.1.0: version "1.1.7" @@ -694,10 +744,15 @@ rimraf@~2.2.8: version "2.2.8" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" -safe-buffer@^5.0.1, safe-buffer@^5.1.1: +safe-buffer@^5.0.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" +safe-buffer@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + "semver@2 || 3 || 4 || 5", semver@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" @@ -706,12 +761,6 @@ signal-exit@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" -sntp@2.x.x: - version "2.1.0" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" - dependencies: - hoek "4.x.x" - spdx-correct@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" @@ -744,9 +793,10 @@ sshpk@^1.7.0: jsbn "~0.1.0" tweetnacl "~0.14.0" -stringstream@~0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" +stealthy-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= strip-ansi@^3.0.0: version "3.0.1" @@ -770,10 +820,27 @@ supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -tough-cookie@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +tough-cookie@^2.3.3: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== dependencies: + psl "^1.1.24" punycode "^1.4.1" trim-newlines@^1.0.0: @@ -794,9 +861,17 @@ underscore.string@~3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.2.3.tgz#806992633665d5e5fcb4db1fb3a862eb68e9e6da" -uuid@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +uuid@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== validate-npm-package-license@^3.0.1: version "3.0.1"