From b08de105ef1f83cb4d4a6aed87835abe71a247b6 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Fri, 1 May 2020 08:21:08 +0200 Subject: [PATCH] Major cleanup to `blitz new` dependency update + graceful failure (Closes #202, #284) Co-Authored-By: Adam Markon (patch) --- README.md | 1 + examples/store/cypress/fixtures/example.json | 2 +- packages/cli/jest.config.js | 2 +- packages/cli/package.json | 4 +- packages/cli/src/commands/new.ts | 15 +- packages/cli/src/generators/app.ts | 81 ++++---- packages/cli/src/utils/fallbackable.ts | 4 + .../cli/src/utils/fetch-latest-version-for.ts | 31 ++++ .../src/utils/get-blitz-dependency-version.ts | 19 ++ packages/cli/src/utils/get-latest-version.ts | 53 ++++-- packages/cli/src/utils/npm-fetch.ts | 36 ++-- .../cli/src/utils/replace-blitz-dependency.ts | 7 - .../cli/src/utils/replace-dependencies.ts | 16 -- packages/cli/test/commands/db.test.ts | 18 +- packages/cli/test/commands/new.test.ts | 76 +++++++- packages/server/src/log.ts | 25 ++- yarn.lock | 173 ++++++++++++++++++ 17 files changed, 452 insertions(+), 111 deletions(-) create mode 100644 packages/cli/src/utils/fallbackable.ts create mode 100644 packages/cli/src/utils/fetch-latest-version-for.ts create mode 100644 packages/cli/src/utils/get-blitz-dependency-version.ts delete mode 100644 packages/cli/src/utils/replace-blitz-dependency.ts delete mode 100644 packages/cli/src/utils/replace-dependencies.ts diff --git a/README.md b/README.md index 1bfefdebdc..0d094b892f 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,7 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e + This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! diff --git a/examples/store/cypress/fixtures/example.json b/examples/store/cypress/fixtures/example.json index da18d9352a..02e4254378 100644 --- a/examples/store/cypress/fixtures/example.json +++ b/examples/store/cypress/fixtures/example.json @@ -2,4 +2,4 @@ "name": "Using fixtures to represent data", "email": "hello@cypress.io", "body": "Fixtures are a great way to mock data for responses to routes" -} \ No newline at end of file +} diff --git a/packages/cli/jest.config.js b/packages/cli/jest.config.js index 720e349447..340aa00bf3 100644 --- a/packages/cli/jest.config.js +++ b/packages/cli/jest.config.js @@ -6,7 +6,7 @@ module.exports = { // collectCoverage: !!`Boolean(process.env.CI)`, collectCoverageFrom: ['src/**/*.ts'], coveragePathIgnorePatterns: ['/templates/'], - modulePathIgnorePatterns: ['tmp', 'lib'], + modulePathIgnorePatterns: ['/tmp', '/lib'], testPathIgnorePatterns: ['src/commands/test.ts'], // TODO enable threshold // coverageThreshold: { diff --git a/packages/cli/package.json b/packages/cli/package.json index f1482d6129..d892694eb7 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -41,6 +41,7 @@ "fs-extra": "^9.0.0", "fs-readdir-recursive": "^1.1.0", "globby": "^11.0.0", + "got": "^11.0.2", "has-yarn": "^2.1.0", "hasbin": "^1.2.3", "mem-fs": "^1.1.3", @@ -59,7 +60,8 @@ "@oclif/dev-cli": "^1.22.2", "@oclif/test": "^1.2.5", "@prisma/cli": "2.0.0-beta.3", - "@types/pluralize": "^0.0.29" + "@types/pluralize": "^0.0.29", + "nock": "13.0.0-beta.3" }, "oclif": { "commands": "./lib/src/commands", diff --git a/packages/cli/src/commands/new.ts b/packages/cli/src/commands/new.ts index 8e5d99dbce..c5b256af02 100644 --- a/packages/cli/src/commands/new.ts +++ b/packages/cli/src/commands/new.ts @@ -4,6 +4,7 @@ import Command from '../command' import AppGenerator from '../generators/app' import chalk from 'chalk' import hasbin from 'hasbin' +import {log} from '@blitzjs/server' const debug = require('debug')('blitz:new') import PromptAbortedError from '../errors/prompt-aborted' @@ -11,6 +12,7 @@ import PromptAbortedError from '../errors/prompt-aborted' export interface Flags { ts: boolean yarn: boolean + 'skip-install': boolean } export default class New extends Command { @@ -35,6 +37,12 @@ export default class New extends Command { default: hasbin.sync('yarn'), allowNo: true, }), + 'skip-install': flags.boolean({ + description: 'Skip package installation', + hidden: true, + default: false, + allowNo: true, + }), 'dry-run': flags.boolean({description: 'show what files will be created without writing them to disk'}), } @@ -54,14 +62,13 @@ export default class New extends Command { useTs: !flags.js, yarn: flags.yarn, version: this.config.version, + skipInstall: flags['skip-install'], }) - const themeColor = '6700AB' - try { - this.log('\n' + chalk.hex(themeColor).bold('Hang tight while we set up your new Blitz app!') + '\n') + this.log('\n' + log.withBrand('Hang tight while we set up your new Blitz app!') + '\n') await generator.run() - this.log('\n' + chalk.hex(themeColor).bold('Your new Blitz app is ready! Next steps:') + '\n') + this.log('\n' + log.withBrand('Your new Blitz app is ready! Next steps:') + '\n') this.log(chalk.yellow(` 1. cd ${args.name}`)) this.log(chalk.yellow(` 2. blitz start`)) this.log(chalk.yellow(` 3. You create new pages by placing components inside app/pages/\n`)) diff --git a/packages/cli/src/generators/app.ts b/packages/cli/src/generators/app.ts index 16f12eb6fb..2aef9a67f5 100644 --- a/packages/cli/src/generators/app.ts +++ b/packages/cli/src/generators/app.ts @@ -4,17 +4,16 @@ import chalk from 'chalk' import username from 'username' import {readJSONSync, writeJson} from 'fs-extra' import {join} from 'path' -import {replaceDependencies} from '../utils/replace-dependencies' -import {replaceBlitzDependency} from '../utils/replace-blitz-dependency' +import {fetchLatestVersionsFor} from '../utils/fetch-latest-version-for' import {log} from '@blitzjs/server' - -const themeColor = '6700AB' +import {getBlitzDependencyVersion} from '../utils/get-blitz-dependency-version' export interface AppGeneratorOptions extends GeneratorOptions { appName: string useTs: boolean yarn: boolean version: string + skipInstall: boolean } class AppGenerator extends Generator { @@ -39,48 +38,62 @@ class AppGenerator extends Generator { async postWrite() { const pkgJsonLocation = join(this.destinationPath(), 'package.json') const pkg = readJSONSync(pkgJsonLocation) - const pkgDependencies = Object.keys(pkg.dependencies) - const pkgDevDependencies = Object.keys(pkg.devDependencies) console.log('') // New line needed - const spinner = log.spinner(log.withBranded('Retrieving the freshest of dependencies')).start() - - const dependenciesArray = await Promise.all([ - replaceDependencies(pkg, pkgDependencies, 'dependencies'), - replaceDependencies(pkg, pkgDevDependencies, 'devDependencies'), + const spinner = log.spinner(log.withBrand('Retrieving the freshest of dependencies')).start() + + const [ + {value: newDependencies, isFallback: dependenciesUsedFallback}, + {value: newDevDependencies, isFallback: devDependenciesUsedFallback}, + {value: blitzDependencyVersion, isFallback: blitzUsedFallback}, + ] = await Promise.all([ + fetchLatestVersionsFor(pkg.dependencies), + fetchLatestVersionsFor(pkg.devDependencies), + getBlitzDependencyVersion(this.options.version), ]) - for (let i = 0; i < dependenciesArray.length; i++) { - const {key, dependencies} = dependenciesArray[i] - pkg[key] = replaceBlitzDependency(dependencies, this.options.version) - } + pkg.dependencies = newDependencies + pkg.devDependencies = newDevDependencies + pkg.dependencies.blitz = blitzDependencyVersion - await writeJson(pkgJsonLocation, pkg, {spaces: 2}) + const fallbackUsed = dependenciesUsedFallback || devDependenciesUsedFallback || blitzUsedFallback - spinner.succeed() + await writeJson(pkgJsonLocation, pkg, {spaces: 2}) - console.log(chalk.hex(themeColor).bold('\nInstalling those dependencies...')) - console.log('Scary warning messages during this part are unfortunately normal.\n') + if (!fallbackUsed && !this.options.skipInstall) { + spinner.succeed() + log.branded('\nInstalling those dependencies...') + console.log('Scary warning messages during this part are unfortunately normal.\n') - const result = spawn.sync(this.options.yarn ? 'yarn' : 'npm', ['install'], {stdio: 'inherit'}) - if (result.status !== 0) { - throw new Error() - } + const result = spawn.sync(this.options.yarn ? 'yarn' : 'npm', ['install'], {stdio: 'inherit'}) + if (result.status !== 0) { + throw new Error() + } - console.log(chalk.hex(themeColor).bold('\nDependencies successfully installed.')) + log.branded('\nDependencies successfully installed.') - const runLocalNodeCLI = (command: string) => { - if (this.options.yarn) { - return spawn.sync('yarn', ['run', ...command.split(' ')]) - } else { - return spawn.sync('npx', command.split(' ')) + const runLocalNodeCLI = (command: string) => { + if (this.options.yarn) { + return spawn.sync('yarn', ['run', ...command.split(' ')]) + } else { + return spawn.sync('npx', command.split(' ')) + } } - } - // Ensure the generated files are formatted with the installed prettier version - const prettierResult = runLocalNodeCLI('prettier --loglevel silent --write .') - if (prettierResult.status !== 0) { - throw new Error('Failed running prettier') + // Ensure the generated files are formatted with the installed prettier version + const prettierResult = runLocalNodeCLI('prettier --loglevel silent --write .') + if (prettierResult.status !== 0) { + throw new Error('Failed running prettier') + } + } else { + console.log('') // New line needed + spinner.fail( + chalk.red.bold( + `We had some trouble connecting to the network, so we'll skip installing your dependencies right now. Make sure to run ${ + this.options.yarn ? "'yarn'" : "'npm install'" + } once you're connected again.`, + ), + ) } // TODO: someone please clean up this ugly code :D diff --git a/packages/cli/src/utils/fallbackable.ts b/packages/cli/src/utils/fallbackable.ts new file mode 100644 index 0000000000..e0bb23d476 --- /dev/null +++ b/packages/cli/src/utils/fallbackable.ts @@ -0,0 +1,4 @@ +export interface Fallbackable { + value: T + isFallback: boolean +} diff --git a/packages/cli/src/utils/fetch-latest-version-for.ts b/packages/cli/src/utils/fetch-latest-version-for.ts new file mode 100644 index 0000000000..1837cacc25 --- /dev/null +++ b/packages/cli/src/utils/fetch-latest-version-for.ts @@ -0,0 +1,31 @@ +import {getLatestVersion} from './get-latest-version' +import {Fallbackable} from './fallbackable' + +export const fetchLatestVersionsFor = async >( + dependencies: T, +): Promise> => { + const entries = Object.entries(dependencies) + + let fallbackUsed = false + + const updated = await Promise.all( + entries.map(async ([dep, version]) => { + if (version.match(/\d.x/)) { + const {value: latestVersion, isFallback} = await getLatestVersion(dep, version) + + if (isFallback) { + fallbackUsed = true + } + + return [dep, latestVersion] + } else { + return [dep, version] + } + }), + ) + + return { + isFallback: fallbackUsed, + value: Object.fromEntries(updated), + } +} diff --git a/packages/cli/src/utils/get-blitz-dependency-version.ts b/packages/cli/src/utils/get-blitz-dependency-version.ts new file mode 100644 index 0000000000..e0a96ee071 --- /dev/null +++ b/packages/cli/src/utils/get-blitz-dependency-version.ts @@ -0,0 +1,19 @@ +import {fetchDistTags} from './npm-fetch' +import {Fallbackable} from './fallbackable' +import {logFailedVersionFetch} from './get-latest-version' + +export const getBlitzDependencyVersion = async (cliVersion: string): Promise> => { + try { + const {latest, canary} = await fetchDistTags('blitz') + + if (cliVersion.includes('canary')) { + return {value: canary, isFallback: false} + } + + return {value: latest, isFallback: false} + } catch (error) { + const fallback = 'latest' + logFailedVersionFetch('blitz', fallback) + return {value: fallback, isFallback: true} + } +} diff --git a/packages/cli/src/utils/get-latest-version.ts b/packages/cli/src/utils/get-latest-version.ts index 1d8886f8a7..db96ea6b8d 100644 --- a/packages/cli/src/utils/get-latest-version.ts +++ b/packages/cli/src/utils/get-latest-version.ts @@ -1,24 +1,45 @@ import {fetchAllVersions, fetchLatestDistVersion} from './npm-fetch' +import {log} from '@blitzjs/server' +import {Fallbackable} from './fallbackable' +import chalk from 'chalk' -export const getLatestVersion = async (dependency: string, templateVersion: string) => { +export const logFailedVersionFetch = (dependency: string, fallback: string) => { + log.clearLine( + log.withWarning( + `Failed to fetch latest version of '${chalk.bold(dependency)}', falling back to '${chalk.bold( + fallback, + )}'.\n`, + ), + ) +} + +export const getLatestVersion = async ( + dependency: string, + templateVersion: string = '', +): Promise> => { const major = templateVersion.replace('.x', '') - const allVersions = await fetchAllVersions(dependency) - const latestDistVersion = await fetchLatestDistVersion(dependency) - if (!allVersions || !latestDistVersion) { - return templateVersion - } + try { + const [allVersions, latestDistVersion] = await Promise.all([ + fetchAllVersions(dependency), + fetchLatestDistVersion(dependency), + ]) - const latestVersion = Object.keys(allVersions) - .filter((version) => version.startsWith(major)) - .sort((a, b) => a.localeCompare(b, undefined, {numeric: true})) - .reverse()[0] + const latestVersion = Object.keys(allVersions) + .filter((version) => version.startsWith(major)) + .sort((a, b) => a.localeCompare(b, undefined, {numeric: true})) + .reverse()[0] - // If the latest tagged version matches our pinned major, use that, otherwise use the - // latest untagged which does - if (latestDistVersion.startsWith(major)) { - return latestDistVersion - } else { - return latestVersion + // If the latest tagged version matches our pinned major, use that, otherwise use the + // latest untagged which does + if (latestDistVersion.startsWith(major)) { + return {value: latestDistVersion, isFallback: false} + } else { + return {value: latestVersion, isFallback: false} + } + } catch (error) { + const fallback = templateVersion + logFailedVersionFetch(dependency, fallback) + return {value: fallback, isFallback: false} } } diff --git a/packages/cli/src/utils/npm-fetch.ts b/packages/cli/src/utils/npm-fetch.ts index 1d822c1407..0aefc7e046 100644 --- a/packages/cli/src/utils/npm-fetch.ts +++ b/packages/cli/src/utils/npm-fetch.ts @@ -1,21 +1,27 @@ -import fetch from 'node-fetch' +import got from 'got' + +type PackageInformation = any +type NpmDepResponse = {versions: Record} export const fetchAllVersions = async (dependency: string) => { - const res = await fetch(`https://registry.npmjs.org/${dependency}`) - if (res.ok) { - const json = await res.json() - return json.versions as string[] - } else { - return - } + const res = await got(`https://registry.npmjs.org/${dependency}`, { + retry: {limit: 3}, + responseType: 'json', + }).json() + return Object.keys(res.versions) +} + +type NpmDistTagsResponse = {latest: string; canary: string} + +export const fetchDistTags = async (dependency: string) => { + const res = await got(`https://registry.npmjs.org/-/package/${dependency}/dist-tags`, { + retry: {limit: 3}, + responseType: 'json', + }).json() + return res } export const fetchLatestDistVersion = async (dependency: string) => { - const res = await fetch(`https://registry.npmjs.org/-/package/${dependency}/dist-tags`) - if (res.ok) { - const json = await res.json() - return json.latest as string - } else { - return - } + const res = await fetchDistTags(dependency) + return res.latest } diff --git a/packages/cli/src/utils/replace-blitz-dependency.ts b/packages/cli/src/utils/replace-blitz-dependency.ts deleted file mode 100644 index 1a04fff2bd..0000000000 --- a/packages/cli/src/utils/replace-blitz-dependency.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const replaceBlitzDependency = (depends: Record, cliVersion: string) => { - if (depends.blitz) { - depends.blitz = cliVersion.includes('canary') ? 'canary' : 'latest' - } - - return depends -} diff --git a/packages/cli/src/utils/replace-dependencies.ts b/packages/cli/src/utils/replace-dependencies.ts deleted file mode 100644 index 9625cd93a1..0000000000 --- a/packages/cli/src/utils/replace-dependencies.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {getLatestVersion} from '../utils/get-latest-version' - -export const replaceDependencies = async (pkg: any, dependencies: string[], key: string) => { - const latestVersions = await Promise.all( - dependencies.map(async (dependency) => { - const templateVersion = pkg[key][dependency] - if (templateVersion.match(/\d.x/)) { - return await getLatestVersion(dependency, templateVersion) - } else { - return templateVersion - } - }), - ) - - return {key, dependencies: dependencies.reduce((o, k, i) => ({...o, [k]: latestVersions[i]}), {})} -} diff --git a/packages/cli/test/commands/db.test.ts b/packages/cli/test/commands/db.test.ts index a3d62030b3..5777375467 100644 --- a/packages/cli/test/commands/db.test.ts +++ b/packages/cli/test/commands/db.test.ts @@ -38,9 +38,7 @@ describe('Db command', () => { jest.clearAllMocks() }) - it('runs db migrate', async () => { - await DbCmd.run(['migrate']) - + function expectDbMigrateOutcome() { expect(spawn).toBeCalledWith(...migrateSaveParams) expect(spawn.mock.calls.length).toBe(3) @@ -48,18 +46,16 @@ describe('Db command', () => { //expect(onSpy).toHaveBeenCalledWith(0); expect(spawn).toBeCalledWith(...migrateUpParams) + } + + it('runs db migrate', async () => { + await DbCmd.run(['migrate']) + expectDbMigrateOutcome() }) it('runs db migrate (alias)', async () => { await DbCmd.run(['m']) - - expect(spawn).toBeCalledWith(...migrateSaveParams) - expect(spawn.mock.calls.length).toBe(3) - - // following expection is not working - //expect(onSpy).toHaveBeenCalledWith(0); - - expect(spawn).toBeCalledWith(...migrateUpParams) + expectDbMigrateOutcome() }) it('runs db introspect', async () => { diff --git a/packages/cli/test/commands/new.test.ts b/packages/cli/test/commands/new.test.ts index ae54da6d6b..4338303350 100644 --- a/packages/cli/test/commands/new.test.ts +++ b/packages/cli/test/commands/new.test.ts @@ -1,3 +1,75 @@ -jest.mock('fs') +import NewCmd from '../../src/commands/new' +import * as fs from 'fs' +import * as path from 'path' +import * as os from 'os' +import fetch from 'node-fetch' +import nock from 'nock' -test('Mock inquirer.js and test the command', () => {}) +jest.setTimeout(60 * 1000) +const blitzCliPackageJson = require('../../package.json') + +async function getBlitzDistTags() { + const response = await fetch('https://registry.npmjs.org/-/package/blitz/dist-tags') + return await response.json() +} + +describe('`new` command', () => { + describe('when scaffolding new project', () => { + jest.setTimeout(60 * 1000) + + async function whileStayingInCWD(task: () => PromiseLike) { + const oldCWD = process.cwd() + await task() + process.chdir(oldCWD) + } + + async function withNewApp(test: (dirName: string, packageJson: any) => Promise | void) { + function makeTempDir() { + const tmpDirPath = path.join(os.tmpdir(), 'blitzjs-test-') + + return fs.mkdtempSync(tmpDirPath) + } + + const tempDir = makeTempDir() + + await whileStayingInCWD(() => NewCmd.run([tempDir, '--skip-install'])) + + const packageJsonFile = fs.readFileSync(path.join(tempDir, 'package.json'), { + encoding: 'utf8', + flag: 'r', + }) + const packageJson = JSON.parse(packageJsonFile) + + await test(tempDir, packageJson) + + fs.rmdirSync(tempDir, {recursive: true}) + } + + it('pins Blitz to the current version', async () => + await withNewApp(async (_, packageJson) => { + const { + dependencies: {blitz: blitzVersion}, + } = packageJson + + const {latest, canary} = await getBlitzDistTags() + if (blitzCliPackageJson.version.includes('canary')) { + expect(blitzVersion).toEqual(canary) + } else { + expect(blitzVersion).toEqual(latest) + } + })) + + describe('with network trouble', () => { + it('uses template versions', async () => { + nock('https://registry.npmjs.org').get(/.*/).reply(500).persist() + + await withNewApp(async (_, packageJson) => { + const {dependencies} = packageJson + expect(dependencies.blitz).toBe('latest') + }) + + nock.restore() + }) + }) + }) +}) diff --git a/packages/server/src/log.ts b/packages/server/src/log.ts index 4b0ec09a92..d4f70b7984 100644 --- a/packages/server/src/log.ts +++ b/packages/server/src/log.ts @@ -2,12 +2,20 @@ import chalk from 'chalk' import ora from 'ora' import readline from 'readline' -const brandColor = '6700AB' +// const blitzTrueBrandColor = '6700AB' +const blitzBrightBrandColor = '8a3df0' -const withBranded = (str: string) => { +// Using brigh brand color so it's better for dark terminals +const brandColor = blitzBrightBrandColor + +const withBrand = (str: string) => { return chalk.hex(brandColor).bold(str) } +const withWarning = (str: string) => { + return `⚠️ ${chalk.yellow(str)}` +} + const withCaret = (str: string) => { return `${chalk.gray('>')} ${str}` } @@ -40,6 +48,15 @@ const clearLine = (msg?: string) => { msg && process.stdout.write(msg) } +/** + * Logs a red error message to stderr. + * + * @param {string} msg + */ +const warning = (msg: string) => { + console.log(withCaret(withWarning(msg))) +} + /** * Logs a red error message to stderr. * @@ -97,13 +114,15 @@ const variable = (val: any) => { } export const log = { - withBranded, + withBrand, + withWarning, withCaret, withCheck, withX, branded, clearLine, error, + warning, meta, progress, spinner, diff --git a/yarn.lock b/yarn.lock index f44c3cea2f..c94b4c241b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2490,6 +2490,18 @@ resolved "https://registry.yarnpkg.com/@scarf/scarf/-/scarf-1.0.4.tgz#d7c09e7d38428123df18a8d83a4bb5d09517d952" integrity sha512-lkhjzeYyYAG4VvdrjvbZCOYzXH5vCwfzYj9xJ4zHDgyYIOzObZwcsbW6W1q5Z4tywrb14oG/tfsFAMMQPCTFqw== +"@sindresorhus/is@^2.1.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-2.1.1.tgz#ceff6a28a5b4867c2dd4a1ba513de278ccbe8bb1" + integrity sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg== + +"@szmarczak/http-timer@^4.0.0": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" + integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ== + dependencies: + defer-to-connect "^2.0.0" + "@testing-library/dom@^7.1.0": version "7.2.2" resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.2.2.tgz#30ab09cca132fe49b2ca61ccd9ed785c5f0a6fc5" @@ -2568,6 +2580,16 @@ resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.29.tgz#7cd933c902c4fc83046517a1bef973886d00bdb6" integrity sha512-kmVtnxTuUuhCET669irqQmPAez4KFnFVKvpleVRyfC3g+SHD1hIkFZcWLim9BVcwUBLO59o8VZE4yGCmTif8Yw== +"@types/cacheable-request@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" + integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "*" + "@types/node" "*" + "@types/responselike" "*" + "@types/chai-jquery@1.1.40": version "1.1.40" resolved "https://registry.yarnpkg.com/@types/chai-jquery/-/chai-jquery-1.1.40.tgz#445bedcbbb2ae4e3027f46fa2c1733c43481ffa1" @@ -2696,6 +2718,11 @@ "@types/node" "*" "@types/vinyl" "*" +"@types/http-cache-semantics@*": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" + integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A== + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" @@ -2755,6 +2782,13 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= +"@types/keyv@*": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7" + integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw== + dependencies: + "@types/node" "*" + "@types/lodash@*": version "4.14.150" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.150.tgz#649fe44684c3f1fcb6164d943c5a61977e8cf0bd" @@ -2920,6 +2954,13 @@ dependencies: "@types/node" "*" +"@types/responselike@*", "@types/responselike@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" + integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + dependencies: + "@types/node" "*" + "@types/semver@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.1.0.tgz#c8c630d4c18cd326beff77404887596f96408408" @@ -4397,6 +4438,24 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +cacheable-lookup@^4.1.1: + version "4.2.2" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-4.2.2.tgz#7fee1d25d9902382a6b8966c164349977168ed4f" + integrity sha512-06EWjs5/UO+gl6RHW7UAajeMZ+5E+HvHLQtaKcpjJLE5S/3+pX28VClFXM+LCwFRcmODURMnO94bZ+lFy5YvRg== + +cacheable-request@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58" + integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^2.0.0" + cachedir@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" @@ -4842,6 +4901,13 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + clone-stats@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" @@ -5780,6 +5846,13 @@ decompress-response@^3.2.0: dependencies: mimic-response "^1.0.0" +decompress-response@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-5.0.0.tgz#7849396e80e3d1eba8cb2f75ef4930f76461cb0f" + integrity sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw== + dependencies: + mimic-response "^2.0.0" + dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" @@ -5807,6 +5880,11 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" +defer-to-connect@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.0.tgz#83d6b199db041593ac84d781b5222308ccf4c2c1" + integrity sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg== + define-properties@^1.1.2, define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -7662,6 +7740,24 @@ globrex@^0.1.1: resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== +got@^11.0.2: + version "11.0.2" + resolved "https://registry.yarnpkg.com/got/-/got-11.0.2.tgz#55613d6a1b7040ff9c26cb075defea39eed58d7a" + integrity sha512-zOanxiJs1LaBAiKsV43UUw/oRlyRNtJFeuATahfi4c3MTremj09eAeJBSJ7GR2oEMhrLLRSJpz8fQaojVDijjw== + dependencies: + "@sindresorhus/is" "^2.1.0" + "@szmarczak/http-timer" "^4.0.0" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^4.1.1" + cacheable-request "^7.0.1" + decompress-response "^5.0.0" + get-stream "^5.0.0" + http2-wrapper "^1.0.0-beta.4.4" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + got@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" @@ -7918,6 +8014,11 @@ http-cache-semantics@^3.8.1: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + http-call@^5.1.2: version "5.3.0" resolved "https://registry.yarnpkg.com/http-call/-/http-call-5.3.0.tgz#4ded815b13f423de176eb0942d69c43b25b148db" @@ -7947,6 +8048,14 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +http2-wrapper@^1.0.0-beta.4.4: + version "1.0.0-beta.4.4" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.0-beta.4.4.tgz#6e1c71b5ddff3037ce16053b20d1044b1e8c0df5" + integrity sha512-CHpjljc2VeZQ1Lk02dwAfOq0k7uY+MSmt9or0zQiyPr++BIngUKIDRoy/MfX0jVZbpG/GjGVZK3K9ac5pBS//A== + dependencies: + quick-lru "^5.0.0" + resolve-alpn "^1.0.0" + https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" @@ -9181,6 +9290,11 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -9264,6 +9378,13 @@ junk@^3.1.0: resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1" integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ== +keyv@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.0.tgz#2d1dab694926b2d427e4c74804a10850be44c12f" + integrity sha512-U7ioE8AimvRVLfw4LffyOIRhL2xVgmE8T22L6i0BucSnBUyv4w+I7VN/zVZwRKHOI6ZRUcdMdWHQ8KSUvGpEog== + dependencies: + json-buffer "3.0.1" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -9742,6 +9863,11 @@ lowercase-keys@^1.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + lru-cache@^4.0.1: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" @@ -10059,6 +10185,11 @@ mimic-response@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== +mimic-response@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" + integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== + min-indent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.0.tgz#cfc45c37e9ec0d8f0a0ec3dd4ef7f7c3abe39256" @@ -10404,6 +10535,16 @@ no-case@^2.2.0: dependencies: lower-case "^1.1.1" +nock@13.0.0-beta.3: + version "13.0.0-beta.3" + resolved "https://registry.yarnpkg.com/nock/-/nock-13.0.0-beta.3.tgz#01ecff90403249d20e495ba906e7bd8b11f50273" + integrity sha512-Ms4WP389EUndlAVjGomWZ5U/gSGuWnhJDu35uMUxiDrMBpSdx1+l0VhVnuNFa33s3gQkYkq/uEUJtRR2qzjEOw== + dependencies: + debug "^4.1.0" + json-stringify-safe "^5.0.1" + lodash.set "^4.3.2" + propagate "^2.0.0" + node-emoji@^1.8.1: version "1.10.0" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" @@ -10562,6 +10703,11 @@ normalize-url@^3.0.0, normalize-url@^3.3.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== +normalize-url@^4.1.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" + integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== + normalize.css@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-8.0.1.tgz#9b98a208738b9cc2634caacbc42d131c97487bf3" @@ -10953,6 +11099,11 @@ p-cancelable@^0.3.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== +p-cancelable@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e" + integrity sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg== + p-defer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" @@ -12318,6 +12469,11 @@ prop-types@15.7.2, prop-types@^15.7.2: object-assign "^4.1.1" react-is "^16.8.1" +propagate@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45" + integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag== + proto-list@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" @@ -12480,6 +12636,11 @@ quick-lru@^1.0.0: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= +quick-lru@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.0.tgz#1602f339bde554c4dace47880227ec9c2869f2e8" + integrity sha512-WjAKQ9ORzvqjLijJXiXWqc3Gcs1ivoxCj6KJmEjoWBE6OtHwuaDLSAUqGHALUiid7A1KqGqsSHZs8prxF5xxAQ== + ramda@0.26.1: version "0.26.1" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" @@ -13053,6 +13214,11 @@ reserved-words@^0.1.2: resolved "https://registry.yarnpkg.com/reserved-words/-/reserved-words-0.1.2.tgz#00a0940f98cd501aeaaac316411d9adc52b31ab1" integrity sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE= +resolve-alpn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.0.0.tgz#745ad60b3d6aff4b4a48e01b8c0bdc70959e0e8c" + integrity sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA== + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -13144,6 +13310,13 @@ resolve@1.x, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.11.1, dependencies: path-parse "^1.0.6" +responselike@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" + integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw== + dependencies: + lowercase-keys "^2.0.0" + restore-cursor@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"