From 40a5db1f6b1ad17b5a593974b6db93015f50824c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sun, 21 Jul 2019 11:40:12 +0300 Subject: [PATCH 01/64] feat: use git stashes for gitWorkflow --- src/gitWorkflow.js | 249 ++++++------ src/runAll.js | 31 +- test/__mocks__/gitWorkflow.js | 16 +- test/__snapshots__/runAll.spec.js.snap | 132 +------ test/execGit.spec.js | 22 ++ test/gitStash.spec.js | 507 ------------------------- test/gitWorkflow.spec.js | 32 -- test/runAll.spec.js | 127 +------ 8 files changed, 175 insertions(+), 941 deletions(-) create mode 100644 test/execGit.spec.js delete mode 100644 test/gitStash.spec.js delete mode 100644 test/gitWorkflow.spec.js diff --git a/src/gitWorkflow.js b/src/gitWorkflow.js index 404d23cef..422712cb3 100644 --- a/src/gitWorkflow.js +++ b/src/gitWorkflow.js @@ -1,164 +1,133 @@ 'use strict' -const del = require('del') const debug = require('debug')('lint-staged:git') const execGit = require('./execGit') -let workingCopyTree = null -let indexTree = null -let formattedIndexTree = null - -async function writeTree(options) { - return execGit(['write-tree'], options) +const STASH_ORGINAL = 'lint-staged backup (original state)' +const STASH_MODIFICATIONS = 'lint-staged backup (modifications)' + +let unstagedDiff + +/** + * From `array` of strings find index number of string containing `test` string + * + * @param {Array} array - Array of strings + * @param {string} test - Test string + * @returns {number} - Index number + */ +const findIndex = (array, test) => array.findIndex(line => line.includes(test)) + +/** + * Get names of stashes + * + * @param {Object} [options] + * @returns {Promise} + */ +async function getStashes(options) { + const stashList = (await execGit(['stash', 'list'], options)).split('\n') + return { + original: `stash@{${findIndex(stashList, STASH_ORGINAL)}}`, + modifications: `stash@{${findIndex(stashList, STASH_MODIFICATIONS)}}` + } } -async function getDiffForTrees(tree1, tree2, options) { - debug(`Generating diff between trees ${tree1} and ${tree2}...`) - return execGit( - [ - 'diff-tree', - '--ignore-submodules', - '--binary', - '--no-color', - '--no-ext-diff', - '--unified=0', - tree1, - tree2 - ], +/** + * Create backup stashes, one of everything and one of only staged changes + * Leves stages files in index for running tasks + * + * @param {Object} [options] + * @returns {Promise} + */ +async function backupOriginalState(options) { + debug('Backing up original state...') + + // Get stash of entire original state, including unstaged changes + // Keep index so that tasks only work on those files + await execGit(['stash', 'save', '--include-untracked', '--keep-index', STASH_ORGINAL], options) + + // Since only staged files are now present, get a diff of unstaged changes + // by comparing current index against original stash, but in reverse + const { original } = await getStashes(options) + unstagedDiff = await execGit( + ['diff', '--unified=0', '--no-color', '--no-ext-diff', '-p', original, '-R'], options ) -} - -async function hasPartiallyStagedFiles(options) { - const stdout = await execGit(['status', '--porcelain'], options) - if (!stdout) return false - - const changedFiles = stdout.split('\n') - const partiallyStaged = changedFiles.filter(line => { - /** - * See https://git-scm.com/docs/git-status#_short_format - * The first letter of the line represents current index status, - * and second the working tree - */ - const [index, workingTree] = line - return index !== ' ' && workingTree !== ' ' && index !== '?' && workingTree !== '?' - }) - return partiallyStaged.length > 0 + debug('Done backing up original state!') } -// eslint-disable-next-line -async function gitStashSave(options) { - debug('Stashing files...') - // Save ref to the current index - indexTree = await writeTree(options) - // Add working copy changes to index - await execGit(['add', '.'], options) - // Save ref to the working copy index - workingCopyTree = await writeTree(options) - // Restore the current index - await execGit(['read-tree', indexTree], options) - // Remove all modifications - await execGit(['checkout-index', '-af'], options) - // await execGit(['clean', '-dfx'], options) - debug('Done stashing files!') - return [workingCopyTree, indexTree] -} +/** + * Resets everything and applies back unstaged and staged changes, + * possibly with modifications by tasks + * + * @param {Object} [options] + * @returns {Promise} + */ +async function applyModifications(options) { + debug('Applying modifications by tasks...') + + // Save index with possible modifications by tasks. + await execGit(['stash', 'save', STASH_MODIFICATIONS], options) + // Reset HEAD + await execGit(['reset'], options) + await execGit(['checkout', '.'], options) + + // Get diff of index against reseted HEAD, this includes all staged changes, + // with possible changes by tasks + const { modifications } = await getStashes(options) + const stagedDiff = await execGit( + ['diff', '--unified=0', '--no-color', '--no-ext-diff', 'HEAD', '-p', modifications], + options + ) -async function updateStash(options) { - formattedIndexTree = await writeTree(options) - return formattedIndexTree -} + await execGit(['apply', '-v', '--index', '--whitespace=nowarn', '--recount', '--unidiff-zero'], { + ...options, + input: `${stagedDiff}\n` + }) -async function applyPatchFor(tree1, tree2, options) { - const diff = await getDiffForTrees(tree1, tree2, options) - /** - * This is crucial for patch to work - * For some reason, git-apply requires that the patch ends with the newline symbol - * See http://git.661346.n2.nabble.com/Bug-in-Git-Gui-Creates-corrupt-patch-td2384251.html - * and https://stackoverflow.com/questions/13223868/how-to-stage-line-by-line-in-git-gui-although-no-newline-at-end-of-file-warnin - */ - // TODO: Figure out how to test this. For some reason tests were working but in the real env it was failing - if (diff) { - try { - /** - * Apply patch to index. We will apply it with --reject so it it will try apply hunk by hunk - * We're not interested in failied hunks since this mean that formatting conflicts with user changes - * and we prioritize user changes over formatter's - */ - await execGit( - ['apply', '-v', '--whitespace=nowarn', '--reject', '--recount', '--unidiff-zero'], - { - ...options, - input: `${diff}\n` // TODO: This should also work on Windows but test would be good - } - ) - } catch (err) { - debug('Could not apply patch to the stashed files cleanly') - debug(err) - debug('Patch content:') - debug(diff) - throw new Error('Could not apply patch to the stashed files cleanly.', err) - } + if (unstagedDiff) { + await execGit(['apply', '-v', '--whitespace=nowarn', '--recount', '--unidiff-zero'], { + ...options, + input: `${unstagedDiff}\n` + }) } -} -async function gitStashPop(options) { - if (workingCopyTree === null) { - throw new Error('Trying to restore from stash but could not find working copy stash.') - } + debug('Done applying modifications by tasks!') +} - debug('Restoring working copy') - // Restore the stashed files in the index - await execGit(['read-tree', workingCopyTree], options) - // and sync it to the working copy (i.e. update files on fs) - await execGit(['checkout-index', '-af'], options) - - // Then, restore the index after working copy is restored - if (indexTree !== null && formattedIndexTree === null) { - // Restore changes that were in index if there are no formatting changes - debug('Restoring index') - await execGit(['read-tree', indexTree], options) - } else { - /** - * There are formatting changes we want to restore in the index - * and in the working copy. So we start by restoring the index - * and after that we'll try to carry as many as possible changes - * to the working copy by applying the patch with --reject option. - */ - debug('Restoring index with formatting changes') - await execGit(['read-tree', formattedIndexTree], options) - try { - await applyPatchFor(indexTree, formattedIndexTree, options) - } catch (err) { - debug( - 'Found conflicts between formatters and local changes. Formatters changes will be ignored for conflicted hunks.' - ) - /** - * Clean up working directory from *.rej files that contain conflicted hanks. - * These hunks are coming from formatters so we'll just delete them since they are irrelevant. - */ - try { - const rejFiles = await del(['*.rej'], options) - debug('Deleted files and folders:\n', rejFiles.join('\n')) - } catch (delErr) { - debug('Error deleting *.rej files', delErr) - } - } - } - // Clean up references - workingCopyTree = null - indexTree = null - formattedIndexTree = null +/** + * Restore original HEAD state in case of errors + * + * @param {Object} [options] + * @returns {Promise} + */ +async function restoreOriginalState(options) { + debug('Restoring original state...') + const { original } = await getStashes(options) + await execGit(['reset', '--hard', 'HEAD'], options) + await execGit(['stash', 'apply', '--index', original], options) + debug('Done restoring original state!') +} - return null +/** + * Drop the created stashes after everything has run + * + * @param {Object} [options] + * @returns {Promise} + */ +async function dropBackupStashes(options) { + debug('Dropping backup stash...') + const { original, modifications } = await getStashes(options) + await execGit(['stash', 'drop', original], options) + await execGit(['stash', 'drop', modifications], options) + debug('Done dropping backup stash!') } module.exports = { execGit, - gitStashSave, - gitStashPop, - hasPartiallyStagedFiles, - updateStash + backupOriginalState, + applyModifications, + restoreOriginalState, + dropBackupStashes } diff --git a/src/runAll.js b/src/runAll.js index 5f4d652f0..82c85b1b9 100644 --- a/src/runAll.js +++ b/src/runAll.js @@ -105,33 +105,26 @@ https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-com return new Listr( [ { - title: 'Stashing changes...', - skip: async () => { - const hasPSF = await git.hasPartiallyStagedFiles({ cwd: gitDir }) - if (!hasPSF) { - return 'No partially staged files found...' - } - return false - }, - task: ctx => { - ctx.hasStash = true - return git.gitStashSave({ cwd: gitDir }) - } + title: 'Backing up...', + task: () => git.backupOriginalState({ cwd: gitDir }) }, { title: 'Running tasks...', task: () => new Listr(tasks, { ...listrOptions, concurrent: true, exitOnError: false }) }, { - title: 'Updating stash...', - enabled: ctx => ctx.hasStash, - skip: ctx => ctx.hasErrors && 'Skipping stash update since some tasks exited with errors', - task: () => git.updateStash({ cwd: gitDir }) + title: 'Applying modifications by tasks...', + skip: ctx => ctx.hasErrors, + task: () => git.applyModifications({ cwd: gitDir }) + }, + { + title: 'Restoring original state due to errors...', + enabled: ctx => ctx.hasErrors, + task: () => git.restoreOriginalState({ cwd: gitDir }) }, { - title: 'Restoring local changes...', - enabled: ctx => ctx.hasStash, - task: () => git.gitStashPop({ cwd: gitDir }) + title: 'Clearing backup...', + task: () => git.dropBackupStashes({ cwd: gitDir }) } ], listrOptions diff --git a/test/__mocks__/gitWorkflow.js b/test/__mocks__/gitWorkflow.js index dca093f73..6692f2577 100644 --- a/test/__mocks__/gitWorkflow.js +++ b/test/__mocks__/gitWorkflow.js @@ -1,11 +1,11 @@ -const hasPartiallyStagedFiles = jest.fn().mockImplementation(() => Promise.resolve(false)) -const gitStashSave = jest.fn().mockImplementation(() => Promise.resolve(null)) -const gitStashPop = jest.fn().mockImplementation(() => Promise.resolve(null)) -const updateStash = jest.fn().mockImplementation(() => Promise.resolve(null)) +const backupOriginalState = jest.fn().mockImplementation(() => Promise.resolve(null)) +const applyModifications = jest.fn().mockImplementation(() => Promise.resolve(null)) +const restoreOriginalState = jest.fn().mockImplementation(() => Promise.resolve(null)) +const dropBackupStashes = jest.fn().mockImplementation(() => Promise.resolve(null)) module.exports = { - gitStashSave, - gitStashPop, - updateStash, - hasPartiallyStagedFiles + backupOriginalState, + applyModifications, + restoreOriginalState, + dropBackupStashes } diff --git a/test/__snapshots__/runAll.spec.js.snap b/test/__snapshots__/runAll.spec.js.snap index 85a9f214e..4351a59f2 100644 --- a/test/__snapshots__/runAll.spec.js.snap +++ b/test/__snapshots__/runAll.spec.js.snap @@ -1,117 +1,26 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`runAll should not skip stashing and restoring if there are partially staged files 1`] = ` -" -LOG Stashing changes... [started] -LOG Stashing changes... [completed] -LOG Running tasks... [started] -LOG Running tasks for *.js [started] -LOG echo \\"sample\\" [started] -LOG echo \\"sample\\" [completed] -LOG Running tasks for *.js [completed] -LOG Running tasks... [completed] -LOG Updating stash... [started] -LOG Updating stash... [completed] -LOG Restoring local changes... [started] -LOG Restoring local changes... [completed]" -`; - exports[`runAll should not skip tasks if there are files 1`] = ` " -LOG Stashing changes... [started] -LOG Stashing changes... [skipped] -LOG → No partially staged files found... +LOG Backing up... [started] +LOG Backing up... [completed] LOG Running tasks... [started] LOG Running tasks for *.js [started] LOG echo \\"sample\\" [started] LOG echo \\"sample\\" [completed] LOG Running tasks for *.js [completed] -LOG Running tasks... [completed]" +LOG Running tasks... [completed] +LOG Applying modifications by tasks... [started] +LOG Applying modifications by tasks... [completed] +LOG Clearing backup... [started] +LOG Clearing backup... [completed]" `; -exports[`runAll should reject promise when error during getStagedFiles 1`] = `"Unable to get staged files!"`; - exports[`runAll should resolve the promise with no files 1`] = ` " LOG No staged files match any of provided globs." `; -exports[`runAll should skip linters and stash update but perform working copy restore if terminated 1`] = ` -" -LOG Stashing changes... [started] -LOG Stashing changes... [completed] -LOG Running tasks... [started] -LOG Running tasks for *.js [started] -LOG echo \\"sample\\" [started] -LOG echo \\"sample\\" [failed] -LOG → -LOG Running tasks for *.js [failed] -LOG → -LOG Running tasks... [failed] -LOG Updating stash... [started] -LOG Updating stash... [skipped] -LOG → Skipping stash update since some tasks exited with errors -LOG Restoring local changes... [started] -LOG Restoring local changes... [completed] -LOG { - name: 'ListrError', - errors: [ - { - privateMsg: '\\\\n\\\\n\\\\n‼ echo \\"sample\\" was terminated with SIGINT', - context: {hasStash: true, hasErrors: true} - } - ], - context: {hasStash: true, hasErrors: true} -}" -`; - -exports[`runAll should skip stashing and restoring if there are no partially staged files 1`] = ` -" -LOG Stashing changes... [started] -LOG Stashing changes... [skipped] -LOG → No partially staged files found... -LOG Running tasks... [started] -LOG Running tasks for *.js [started] -LOG echo \\"sample\\" [started] -LOG echo \\"sample\\" [completed] -LOG Running tasks for *.js [completed] -LOG Running tasks... [completed]" -`; - -exports[`runAll should skip stashing changes if no lint-staged files are changed 1`] = ` -" -LOG No staged files match any of provided globs." -`; - -exports[`runAll should skip updating stash if there are errors during linting 1`] = ` -" -LOG Stashing changes... [started] -LOG Stashing changes... [completed] -LOG Running tasks... [started] -LOG Running tasks for *.js [started] -LOG echo \\"sample\\" [started] -LOG echo \\"sample\\" [failed] -LOG → -LOG Running tasks for *.js [failed] -LOG → -LOG Running tasks... [failed] -LOG Updating stash... [started] -LOG Updating stash... [skipped] -LOG → Skipping stash update since some tasks exited with errors -LOG Restoring local changes... [started] -LOG Restoring local changes... [completed] -LOG { - name: 'ListrError', - errors: [ - { - privateMsg: '\\\\n\\\\n\\\\n× echo \\"sample\\" found some errors. Please fix them and try committing again.\\\\n\\\\nLinter finished with error', - context: {hasStash: true, hasErrors: true} - } - ], - context: {hasStash: true, hasErrors: true} -}" -`; - exports[`runAll should use an injected logger 1`] = ` " LOG No staged files match any of provided globs." @@ -122,25 +31,16 @@ exports[`runAll should warn if the argument length is longer than what the platf WARN ‼ lint-staged generated an argument string of 999999 characters, and commands might not run correctly on your platform. It is recommended to use functions as linters and split your command based on the number of staged files. For more info, please visit: https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-commands -LOG Stashing changes... [started] -LOG Stashing changes... [skipped] -LOG → No partially staged files found... +LOG Backing up... [started] +LOG Backing up... [completed] LOG Running tasks... [started] LOG Running tasks for *.js [started] LOG echo \\"sample\\" [started] -LOG echo \\"sample\\" [failed] -LOG → -LOG Running tasks for *.js [failed] -LOG → -LOG Running tasks... [failed] -LOG { - name: 'ListrError', - errors: [ - { - privateMsg: '\\\\n\\\\n\\\\n× echo \\"sample\\" found some errors. Please fix them and try committing again.\\\\n\\\\nLinter finished with error', - context: {hasErrors: true} - } - ], - context: {hasErrors: true} -}" +LOG echo \\"sample\\" [completed] +LOG Running tasks for *.js [completed] +LOG Running tasks... [completed] +LOG Applying modifications by tasks... [started] +LOG Applying modifications by tasks... [completed] +LOG Clearing backup... [started] +LOG Clearing backup... [completed]" `; diff --git a/test/execGit.spec.js b/test/execGit.spec.js new file mode 100644 index 000000000..5499ceb19 --- /dev/null +++ b/test/execGit.spec.js @@ -0,0 +1,22 @@ +/* eslint no-underscore-dangle: 0 */ + +import path from 'path' +import tmp from 'tmp' +import execa from 'execa' +import execGit from '../src/execGit' + +tmp.setGracefulCleanup() + +describe('execGit', () => { + it('should execute git in process.cwd if working copy is not specified', async () => { + const cwd = process.cwd() + await execGit(['init', 'param']) + expect(execa).toHaveBeenCalledWith('git', ['init', 'param'], { cwd }) + }) + + it('should execute git in a given working copy', async () => { + const cwd = path.join(process.cwd(), 'test', '__fixtures__') + await execGit(['init', 'param'], { cwd }) + expect(execa).toHaveBeenCalledWith('git', ['init', 'param'], { cwd }) + }) +}) diff --git a/test/gitStash.spec.js b/test/gitStash.spec.js deleted file mode 100644 index 27c95f295..000000000 --- a/test/gitStash.spec.js +++ /dev/null @@ -1,507 +0,0 @@ -const execa = require('execa') -const path = require('path') -const tmp = require('tmp') -const gitflow = require('../src/gitWorkflow') -const fs = require('fs-extra') - -tmp.setGracefulCleanup() -jest.unmock('execa') - -let wcDir -let wcDirPath -let gitOpts -const initialContent = `module.exports = { - test: 'test2' -} -` - -async function gitStatus(opts = gitOpts) { - return gitflow.execGit(['status', '--porcelain'], opts) -} - -async function readFile(filepath, dir = wcDirPath) { - const content = await fs.readFile(path.join(dir, filepath), { encoding: 'utf-8' }) - return content.replace(/\r\n/g, '\n') -} - -describe('git', () => { - beforeEach(async () => { - wcDir = tmp.dirSync({ unsafeCleanup: true }) - wcDirPath = wcDir.name - gitOpts = { - cwd: wcDirPath - } - - // Init repository - await gitflow.execGit('init', gitOpts) - // Create JS file - await fs.writeFile( - path.join(wcDirPath, 'test.js'), - `module.exports = { - test: 'test', - - foo: 'bar' -} -` - ) - await fs.writeFile( - path.join(wcDirPath, 'test.css'), - `.test { - border: 1px solid green; -} -` - ) - await gitflow.execGit(['config', 'user.name', '"test"'], gitOpts) - await gitflow.execGit(['config', 'user.email', '"test@test.com"'], gitOpts) - // Track all files - await gitflow.execGit(['add', '.'], gitOpts) - // Create inital commit - await gitflow.execGit(['commit', '-m', '"Initial commit"'], gitOpts) - // Update one of the files - await fs.writeFile(path.join(wcDirPath, 'test.css'), '.test { border: red; }') - // Update one of the files - await fs.writeFile(path.join(wcDirPath, 'test.js'), initialContent) - }) - - afterEach(() => { - wcDir.removeCallback() - }) - - describe('hasPartiallyStagedFiles', () => { - it('should return false if files are not staged', async () => { - const res = await gitflow.hasPartiallyStagedFiles(gitOpts) - expect(res).toEqual(false) - }) - - it('should return false if there are no modified files exist', async () => { - await gitflow.execGit(['checkout', '.'], gitOpts) - const res = await gitflow.hasPartiallyStagedFiles(gitOpts) - expect(res).toEqual(false) - }) - - it('should return false if changes are already in the index', async () => { - await gitflow.execGit(['checkout', 'test.css'], gitOpts) - await gitflow.execGit(['add', 'test.js'], gitOpts) - const res = await gitflow.hasPartiallyStagedFiles(gitOpts) - expect(res).toEqual(false) - }) - - it('should return false if there are untracked files', async () => { - const touch = process.platform === 'win32' ? 'echo.>' : 'touch' - await execa(touch, ['untracked.file'], gitOpts) - const res = await gitflow.hasPartiallyStagedFiles(gitOpts) - expect(res).toEqual(false) - }) - - it('should return true if files are modified and in the index', async () => { - await gitflow.execGit(['checkout', 'test.css'], gitOpts) - await gitflow.execGit(['add', 'test.js'], gitOpts) - await fs.writeFile(path.join(wcDirPath, 'test.js'), '') - const res = await gitflow.hasPartiallyStagedFiles(gitOpts) - expect(res).toEqual(true) - }) - }) - - describe('gitStashSave/gitStashPop', () => { - it('should stash and restore WC state without a commit', async () => { - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css - M test.js" -`) - - // Add test.js to index - await gitflow.execGit(['add', 'test.js'], gitOpts) - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css -M test.js" -`) - - // Stashing files - await gitflow.gitStashSave(gitOpts) - expect(await gitStatus()).toMatchInlineSnapshot(`"M test.js"`) - - // Restoring state - await gitflow.gitStashPop(gitOpts) - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css -M test.js" -`) - }) - - it('should not re-create deleted files as untracked files', async () => { - // Delete test.js - await gitflow.execGit(['checkout', 'test.js'], gitOpts) - await gitflow.execGit(['rm', 'test.js'], gitOpts) - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css -D test.js" -`) - - // Stashing files - await gitflow.gitStashSave(gitOpts) - expect(await gitStatus()).toMatchInlineSnapshot(`"D test.js"`) - - // Restoring state - await gitflow.gitStashPop(gitOpts) - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css -D test.js" -`) - }) - - it('should handle renamed files', async () => { - // Delete test.js - await gitflow.execGit(['checkout', 'test.js'], gitOpts) - await gitflow.execGit(['mv', 'test.js', 'test-renamed.js'], gitOpts) - expect(await gitStatus()).toMatchInlineSnapshot(` -"R test.js -> test-renamed.js - M test.css" -`) - - // Stashing files - await gitflow.gitStashSave(gitOpts) - expect(await gitStatus()).toMatchInlineSnapshot(`"R test.js -> test-renamed.js"`) - - // Restoring state - await gitflow.gitStashPop(gitOpts) - expect(await gitStatus()).toMatchInlineSnapshot(` -"R test.js -> test-renamed.js - M test.css" -`) - }) - - it('should handle rename and reset (both deleted and untracked) files', async () => { - // Delete test.js - await gitflow.execGit(['checkout', 'test.js'], gitOpts) - await gitflow.execGit(['mv', 'test.js', 'test-renamed.js'], gitOpts) - await gitflow.execGit(['reset', '.'], gitOpts) - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css - D test.js -?? test-renamed.js" -`) - - // Stashing files - await gitflow.gitStashSave(gitOpts) - expect(await gitStatus()).toMatchInlineSnapshot(`"?? test-renamed.js"`) - - // Restoring state - await gitflow.gitStashPop(gitOpts) - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css -?? test-renamed.js" -`) - }) - - it('should drop hooks fixes when aborted', async () => { - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css - M test.js" -`) - - // Add test.js to index - await gitflow.execGit(['add', 'test.js'], gitOpts) - // Save diff for the reference - const initialIndex = await gitflow.execGit(['diff', '--cached'], gitOpts) - - // Expect test.js is in index - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css -M test.js" -`) - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(initialIndex) - - // Stashing state - await gitflow.gitStashSave(gitOpts) - - // Only index should remain - expect(await gitStatus()).toMatchInlineSnapshot(`"M test.js"`) - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(initialIndex) - - // Do additional edits (imitate eslint --fix) - const eslintContent = `module.exports = { - test: 'test2', - test: 'test2', - test: 'test2', - test: 'test2', -};` - await fs.writeFile(path.join(wcDirPath, 'test.js'), eslintContent) - - // Expect both indexed and modified state on one file - expect(await gitStatus()).toMatchInlineSnapshot(`"MM test.js"`) - // and index isn't modified - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(initialIndex) - - // Restoring state - await gitflow.gitStashPop(gitOpts) - // Expect stashed files to be back - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css -M test.js" -`) - // and modification are gone - expect(await readFile('test.js')).toEqual(initialContent) - // Expect no modifications in index - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(initialIndex) - }) - - it('should drop hooks fixes and revert to user modifications when aborted', async () => { - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css - M test.js" -`) - - // Add test.js to index - await gitflow.execGit(['add', 'test.js'], gitOpts) - // Save diff for the reference - const initialIndex = await gitflow.execGit(['diff', '--cached'], gitOpts) - - // User does additional edits - const userContent = `module.exports = { - test: 'test2', - test: 'test3', -}` - await fs.writeFile(path.join(wcDirPath, 'test.js'), userContent) - - // Expect test.js is in both index and modified - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css -MM test.js" -`) - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(initialIndex) - - // Stashing state - await gitflow.gitStashSave(gitOpts) - - // Only index should remain - expect(await gitStatus()).toMatchInlineSnapshot(`"M test.js"`) - - // Do additional edits (imitate eslint --fix) - await fs.writeFile( - path.join(wcDirPath, 'test.js'), - `module.exports = { - test: 'test2', -};` - ) - - // Expect both indexed and modified state on one file - expect(await gitStatus()).toMatchInlineSnapshot(`"MM test.js"`) - // and index isn't modified - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(initialIndex) - - // Restoring state - await gitflow.gitStashPop(gitOpts) - - // Expect stashed files to be back - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css -MM test.js" -`) - // and content is back to user modifications - expect(await readFile('test.js')).toEqual(userContent) - // Expect no modifications in index - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(initialIndex) - }) - - it('should add hooks fixes to index when not aborted', async () => { - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css - M test.js" -`) - - // Add test.js to index - await gitflow.execGit(['add', 'test.js'], gitOpts) - // Save diff for the reference - const initialIndex = await gitflow.execGit(['diff', '--cached'], gitOpts) - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css -M test.js" -`) - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(initialIndex) - - // Stashing state - await gitflow.gitStashSave(gitOpts) - - // Only index should remain - expect(await gitStatus()).toMatchInlineSnapshot(`"M test.js"`) - - // Do additional edits (imitate eslint --fix) - const newContent = `module.exports = { - test: "test2", -};` - await fs.writeFile(path.join(wcDirPath, 'test.js'), newContent) - // and add to index - await gitflow.execGit(['add', 'test.js'], gitOpts) - await gitflow.updateStash(gitOpts) - const newIndex = await gitflow.execGit(['diff', '--cached'], gitOpts) - - // Expect only index changes - expect(await gitStatus()).toMatchInlineSnapshot(`"M test.js"`) - // and index is modified - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).not.toEqual(initialIndex) - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(newIndex) - - // Restoring state - await gitflow.gitStashPop(gitOpts) - - // Expect stashed files to be back - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css -M test.js" -`) - // and content keeps linter modifications - expect(await readFile('test.js')).toEqual(newContent) - // Expect modifications in index - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(newIndex) - }) - - it('should add hooks fixes to index and keep user modifications when not aborted', async () => { - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css - M test.js" -`) - - // Add test.js to index - await gitflow.execGit(['add', 'test.js'], gitOpts) - // Save diff for the reference - const initialIndex = await gitflow.execGit(['diff', '--cached'], gitOpts) - - // User does additional edits - const userContent = `module.exports = { - test: 'test2', - test: 'test3' -}` - await fs.writeFile(path.join(wcDirPath, 'test.js'), userContent) - - // Expect test.js is in both index and modified - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css -MM test.js" -`) - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(initialIndex) - - // Stashing state - await gitflow.gitStashSave(gitOpts) - - // Only index should remain - expect(await gitStatus()).toMatchInlineSnapshot(`"M test.js"`) - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(initialIndex) - - // Do additional edits (imitate eslint --fix) - await fs.writeFile( - path.join(wcDirPath, 'test.js'), - `module.exports = { - test: "test2" -};` - ) - // and add to index - await gitflow.execGit(['add', 'test.js'], gitOpts) - await gitflow.updateStash(gitOpts) - const newIndex = await gitflow.execGit(['diff', '--cached'], gitOpts) - - // Expect index is modified - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).not.toEqual(initialIndex) - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(newIndex) - - // Restoring state - await gitflow.gitStashPop(gitOpts) - - // Expect stashed files to be back - expect(await gitStatus()).toMatchInlineSnapshot(` -" M test.css -MM test.js" -`) - // and content is back to user modifications - expect(await readFile('test.js')).toEqual(userContent) - // Expect formatting changes in the index - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(newIndex) - }) - - it('should add hooks fixes to index and working copy on partially staged files', async () => { - // Start with a clean state - await gitflow.execGit(['checkout', '--', '.'], gitOpts) - - // Do additional edits and stage them - await fs.writeFile( - path.join(wcDirPath, 'test.js'), - `module.exports = { - test: 'test', - - - - - - - foo: ' - baz - ' -}` - ) - await gitflow.execGit(['add', 'test.js'], gitOpts) - - // Do additional edits without adding to index - await fs.writeFile( - path.join(wcDirPath, 'test.js'), - `module.exports = { - test: 'edited', - - - - - - - foo: ' - baz - ' -}` - ) - - expect(await gitStatus()).toMatchInlineSnapshot(`"MM test.js"`) - // Save diff for the reference - const initialIndex = await gitflow.execGit(['diff', '--cached'], gitOpts) - - // Stashing state - await gitflow.gitStashSave(gitOpts) - - // Only index should remain - expect(await gitStatus()).toMatchInlineSnapshot(`"M test.js"`) - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(initialIndex) - - // Imitate running prettier on the version from the index - await fs.writeFile( - path.join(wcDirPath, 'test.js'), - `module.exports = { - test: "test", - - - - - - - foo: "baz" -};` - ) - await gitflow.execGit(['add', 'test.js'], gitOpts) - await gitflow.updateStash(gitOpts) - const indexAfterEslint = await gitflow.execGit(['diff', '--cached'], gitOpts) - - // Restoring state - await gitflow.gitStashPop(gitOpts) - - // Expect stashed files to be back - expect(await gitStatus()).toMatchInlineSnapshot(`"MM test.js"`) - // and all lint-staged modifications to be gone - expect(await gitflow.execGit(['diff', '--cached'], gitOpts)).toEqual(indexAfterEslint) - expect(await readFile('test.js')).toEqual(`module.exports = { - test: 'edited', - - - - - - - foo: "baz" -};`) - }) - }) -}) diff --git a/test/gitWorkflow.spec.js b/test/gitWorkflow.spec.js deleted file mode 100644 index 2ba98bcb6..000000000 --- a/test/gitWorkflow.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint no-underscore-dangle: 0 */ - -import path from 'path' -import tmp from 'tmp' -import execa from 'execa' -import { execGit, gitStashPop } from '../src/gitWorkflow' - -tmp.setGracefulCleanup() - -describe('gitWorkflow', () => { - describe('execGit', () => { - it('should execute git in process.cwd if working copy is not specified', async () => { - const cwd = process.cwd() - await execGit(['init', 'param']) - expect(execa).toHaveBeenCalledWith('git', ['init', 'param'], { cwd }) - }) - - it('should execute git in a given working copy', async () => { - const cwd = path.join(process.cwd(), 'test', '__fixtures__') - await execGit(['init', 'param'], { cwd }) - expect(execa).toHaveBeenCalledWith('git', ['init', 'param'], { cwd }) - }) - }) - - describe('gitStashPop', () => { - it('should throw when workingTree is null', () => { - expect(gitStashPop()).rejects.toThrowErrorMatchingInlineSnapshot( - `"Trying to restore from stash but could not find working copy stash."` - ) - }) - }) -}) diff --git a/test/runAll.spec.js b/test/runAll.spec.js index 696e6c7fd..34e137be9 100644 --- a/test/runAll.spec.js +++ b/test/runAll.spec.js @@ -1,11 +1,9 @@ import makeConsoleMock from 'consolemock' -import execa from 'execa' import normalize from 'normalize-path' import resolveGitDir from '../src/resolveGitDir' import getStagedFiles from '../src/getStagedFiles' import runAll from '../src/runAll' -import { hasPartiallyStagedFiles, gitStashSave, gitStashPop, updateStash } from '../src/gitWorkflow' jest.mock('../src/resolveGitDir') jest.mock('../src/getStagedFiles') @@ -23,9 +21,6 @@ describe('runAll', () => { afterEach(() => { console.clearHistory() - gitStashSave.mockClear() - gitStashPop.mockClear() - updateStash.mockClear() }) afterAll(() => { @@ -53,69 +48,7 @@ describe('runAll', () => { expect(console.printHistory()).toMatchSnapshot() }) - it('should use an injected logger', async () => { - expect.assertions(1) - const logger = makeConsoleMock() - await runAll({ config: { '*.js': ['echo "sample"'] }, debug: true }, logger) - expect(logger.printHistory()).toMatchSnapshot() - }) - - it('should not skip tasks if there are files', async () => { - expect.assertions(1) - getStagedFiles.mockImplementationOnce(async () => ['sample.js']) - await runAll({ config: { '*.js': ['echo "sample"'] } }) - expect(console.printHistory()).toMatchSnapshot() - }) - - it('should not skip stashing and restoring if there are partially staged files', async () => { - expect.assertions(4) - hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(true)) - getStagedFiles.mockImplementationOnce(async () => ['sample.js']) - await runAll({ config: { '*.js': ['echo "sample"'] } }) - expect(gitStashSave).toHaveBeenCalledTimes(1) - expect(updateStash).toHaveBeenCalledTimes(1) - expect(gitStashPop).toHaveBeenCalledTimes(1) - expect(console.printHistory()).toMatchSnapshot() - }) - - it('should skip stashing and restoring if there are no partially staged files', async () => { - expect.assertions(4) - hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(false)) - getStagedFiles.mockImplementationOnce(async () => ['sample.js']) - await runAll({ config: { '*.js': ['echo "sample"'] } }) - expect(gitStashSave).toHaveBeenCalledTimes(0) - expect(updateStash).toHaveBeenCalledTimes(0) - expect(gitStashPop).toHaveBeenCalledTimes(0) - expect(console.printHistory()).toMatchSnapshot() - }) - - it('should skip updating stash if there are errors during linting', async () => { - expect.assertions(4) - hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(true)) - getStagedFiles.mockImplementationOnce(async () => ['sample.js']) - execa.mockImplementation(() => - Promise.resolve({ - stdout: '', - stderr: 'Linter finished with error', - code: 1, - failed: true, - cmd: 'mock cmd' - }) - ) - - try { - await runAll({ config: { '*.js': ['echo "sample"'] } }) - } catch (err) { - console.log(err) - } - expect(console.printHistory()).toMatchSnapshot() - expect(gitStashSave).toHaveBeenCalledTimes(1) - expect(updateStash).toHaveBeenCalledTimes(0) - expect(gitStashPop).toHaveBeenCalledTimes(1) - }) - it('should warn if the argument length is longer than what the platform can handle', async () => { - hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(false)) getStagedFiles.mockImplementationOnce(async () => new Array(100000).fill('sample.js')) try { @@ -126,61 +59,17 @@ describe('runAll', () => { expect(console.printHistory()).toMatchSnapshot() }) - it('should skip linters and stash update but perform working copy restore if terminated', async () => { - expect.assertions(4) - hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(true)) - getStagedFiles.mockImplementationOnce(async () => ['sample.js']) - execa.mockImplementation(() => - Promise.resolve({ - stdout: '', - stderr: '', - code: 0, - failed: false, - killed: true, - signal: 'SIGINT', - cmd: 'mock cmd' - }) - ) - - try { - await runAll({ config: { '*.js': ['echo "sample"'] } }) - } catch (err) { - console.log(err) - } - expect(console.printHistory()).toMatchSnapshot() - expect(gitStashSave).toHaveBeenCalledTimes(1) - expect(updateStash).toHaveBeenCalledTimes(0) - expect(gitStashPop).toHaveBeenCalledTimes(1) - }) - - it('should reject promise when error during getStagedFiles', async () => { + it('should use an injected logger', async () => { expect.assertions(1) - getStagedFiles.mockImplementationOnce(async () => null) - await expect(runAll({})).rejects.toThrowErrorMatchingSnapshot() + const logger = makeConsoleMock() + await runAll({ config: { '*.js': ['echo "sample"'] }, debug: true }, logger) + expect(logger.printHistory()).toMatchSnapshot() }) - it('should skip stashing changes if no lint-staged files are changed', async () => { - expect.assertions(4) - hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(true)) - getStagedFiles.mockImplementationOnce(async () => ['sample.java']) - execa.mockImplementationOnce(() => - Promise.resolve({ - stdout: '', - stderr: 'Linter finished with error', - code: 1, - failed: true, - cmd: 'mock cmd' - }) - ) - - try { - await runAll({ config: { '*.js': ['echo "sample"'] } }) - } catch (err) { - console.log(err) - } + it('should not skip tasks if there are files', async () => { + expect.assertions(1) + getStagedFiles.mockImplementationOnce(async () => ['sample.js']) + await runAll({ config: { '*.js': ['echo "sample"'] } }) expect(console.printHistory()).toMatchSnapshot() - expect(gitStashSave).toHaveBeenCalledTimes(0) - expect(updateStash).toHaveBeenCalledTimes(0) - expect(gitStashPop).toHaveBeenCalledTimes(0) }) }) From 5be9cb47270fff5e7f142a59da30cb2cb7d8bba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sun, 21 Jul 2019 12:00:38 +0300 Subject: [PATCH 02/64] ci: print git version number in AppVeyor --- .appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.appveyor.yml b/.appveyor.yml index 02822eabf..c439c0d3d 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -25,6 +25,7 @@ cache: test_script: - node --version - yarn --version + - git --version - yarn test branches: From 762d4d1543c217ecd9b0f18a0d97c46c9502f293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sun, 21 Jul 2019 12:40:13 +0300 Subject: [PATCH 03/64] refactor: simplify gitWorkflow by creating only one stash --- src/gitWorkflow.js | 70 +++++++------------------- src/runAll.js | 16 +++--- test/__mocks__/gitWorkflow.js | 12 ++--- test/__snapshots__/runAll.spec.js.snap | 26 ++-------- test/runAll.spec.js | 7 --- 5 files changed, 36 insertions(+), 95 deletions(-) diff --git a/src/gitWorkflow.js b/src/gitWorkflow.js index 422712cb3..75f34f443 100644 --- a/src/gitWorkflow.js +++ b/src/gitWorkflow.js @@ -4,32 +4,20 @@ const debug = require('debug')('lint-staged:git') const execGit = require('./execGit') -const STASH_ORGINAL = 'lint-staged backup (original state)' -const STASH_MODIFICATIONS = 'lint-staged backup (modifications)' +const STASH = 'lint-staged automatic backup' let unstagedDiff /** - * From `array` of strings find index number of string containing `test` string - * - * @param {Array} array - Array of strings - * @param {string} test - Test string - * @returns {number} - Index number - */ -const findIndex = (array, test) => array.findIndex(line => line.includes(test)) - -/** - * Get names of stashes + * Get name of backup stash * * @param {Object} [options] * @returns {Promise} */ -async function getStashes(options) { +async function getBackupStash(options) { const stashList = (await execGit(['stash', 'list'], options)).split('\n') - return { - original: `stash@{${findIndex(stashList, STASH_ORGINAL)}}`, - modifications: `stash@{${findIndex(stashList, STASH_MODIFICATIONS)}}` - } + const index = stashList.findIndex(line => line.includes(STASH)) + return `stash@{${index}}` } /** @@ -39,16 +27,16 @@ async function getStashes(options) { * @param {Object} [options] * @returns {Promise} */ -async function backupOriginalState(options) { +async function stashBackup(options) { debug('Backing up original state...') // Get stash of entire original state, including unstaged changes // Keep index so that tasks only work on those files - await execGit(['stash', 'save', '--include-untracked', '--keep-index', STASH_ORGINAL], options) + await execGit(['stash', 'save', '--quiet', '--include-untracked', '--keep-index', STASH], options) // Since only staged files are now present, get a diff of unstaged changes // by comparing current index against original stash, but in reverse - const { original } = await getStashes(options) + const original = await getBackupStash(options) unstagedDiff = await execGit( ['diff', '--unified=0', '--no-color', '--no-ext-diff', '-p', original, '-R'], options @@ -64,27 +52,8 @@ async function backupOriginalState(options) { * @param {Object} [options] * @returns {Promise} */ -async function applyModifications(options) { - debug('Applying modifications by tasks...') - - // Save index with possible modifications by tasks. - await execGit(['stash', 'save', STASH_MODIFICATIONS], options) - // Reset HEAD - await execGit(['reset'], options) - await execGit(['checkout', '.'], options) - - // Get diff of index against reseted HEAD, this includes all staged changes, - // with possible changes by tasks - const { modifications } = await getStashes(options) - const stagedDiff = await execGit( - ['diff', '--unified=0', '--no-color', '--no-ext-diff', 'HEAD', '-p', modifications], - options - ) - - await execGit(['apply', '-v', '--index', '--whitespace=nowarn', '--recount', '--unidiff-zero'], { - ...options, - input: `${stagedDiff}\n` - }) +async function restoreUnstagedChanges(options) { + debug('Restoring unstaged changes...') if (unstagedDiff) { await execGit(['apply', '-v', '--whitespace=nowarn', '--recount', '--unidiff-zero'], { @@ -93,7 +62,7 @@ async function applyModifications(options) { }) } - debug('Done applying modifications by tasks!') + debug('Done restoring unstaged changes!') } /** @@ -104,9 +73,9 @@ async function applyModifications(options) { */ async function restoreOriginalState(options) { debug('Restoring original state...') - const { original } = await getStashes(options) + const original = await getBackupStash(options) await execGit(['reset', '--hard', 'HEAD'], options) - await execGit(['stash', 'apply', '--index', original], options) + await execGit(['stash', 'apply', '--quiet', '--index', original], options) debug('Done restoring original state!') } @@ -116,18 +85,17 @@ async function restoreOriginalState(options) { * @param {Object} [options] * @returns {Promise} */ -async function dropBackupStashes(options) { +async function dropBackup(options) { debug('Dropping backup stash...') - const { original, modifications } = await getStashes(options) - await execGit(['stash', 'drop', original], options) - await execGit(['stash', 'drop', modifications], options) + const original = await getBackupStash(options) + await execGit(['stash', 'drop', '--quiet', original], options) debug('Done dropping backup stash!') } module.exports = { execGit, - backupOriginalState, - applyModifications, + stashBackup, + restoreUnstagedChanges, restoreOriginalState, - dropBackupStashes + dropBackup } diff --git a/src/runAll.js b/src/runAll.js index 82c85b1b9..16e9e7666 100644 --- a/src/runAll.js +++ b/src/runAll.js @@ -105,26 +105,24 @@ https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-com return new Listr( [ { - title: 'Backing up...', - task: () => git.backupOriginalState({ cwd: gitDir }) + title: 'Preparing...', + task: () => git.stashBackup({ cwd: gitDir }) }, { title: 'Running tasks...', task: () => new Listr(tasks, { ...listrOptions, concurrent: true, exitOnError: false }) }, - { - title: 'Applying modifications by tasks...', - skip: ctx => ctx.hasErrors, - task: () => git.applyModifications({ cwd: gitDir }) - }, { title: 'Restoring original state due to errors...', enabled: ctx => ctx.hasErrors, task: () => git.restoreOriginalState({ cwd: gitDir }) }, { - title: 'Clearing backup...', - task: () => git.dropBackupStashes({ cwd: gitDir }) + title: 'Cleaning up...', + task: async ctx => { + if (!ctx.hasErrors) await git.restoreUnstagedChanges({ cwd: gitDir }) + await git.dropBackup({ cwd: gitDir }) + } } ], listrOptions diff --git a/test/__mocks__/gitWorkflow.js b/test/__mocks__/gitWorkflow.js index 6692f2577..74d49e155 100644 --- a/test/__mocks__/gitWorkflow.js +++ b/test/__mocks__/gitWorkflow.js @@ -1,11 +1,11 @@ -const backupOriginalState = jest.fn().mockImplementation(() => Promise.resolve(null)) -const applyModifications = jest.fn().mockImplementation(() => Promise.resolve(null)) +const stashBackup = jest.fn().mockImplementation(() => Promise.resolve(null)) +const restoreUnstagedChanges = jest.fn().mockImplementation(() => Promise.resolve(null)) const restoreOriginalState = jest.fn().mockImplementation(() => Promise.resolve(null)) -const dropBackupStashes = jest.fn().mockImplementation(() => Promise.resolve(null)) +const dropBackup = jest.fn().mockImplementation(() => Promise.resolve(null)) module.exports = { - backupOriginalState, - applyModifications, + stashBackup, + restoreUnstagedChanges, restoreOriginalState, - dropBackupStashes + dropBackup } diff --git a/test/__snapshots__/runAll.spec.js.snap b/test/__snapshots__/runAll.spec.js.snap index 4351a59f2..040bcaa6d 100644 --- a/test/__snapshots__/runAll.spec.js.snap +++ b/test/__snapshots__/runAll.spec.js.snap @@ -1,21 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`runAll should not skip tasks if there are files 1`] = ` -" -LOG Backing up... [started] -LOG Backing up... [completed] -LOG Running tasks... [started] -LOG Running tasks for *.js [started] -LOG echo \\"sample\\" [started] -LOG echo \\"sample\\" [completed] -LOG Running tasks for *.js [completed] -LOG Running tasks... [completed] -LOG Applying modifications by tasks... [started] -LOG Applying modifications by tasks... [completed] -LOG Clearing backup... [started] -LOG Clearing backup... [completed]" -`; - exports[`runAll should resolve the promise with no files 1`] = ` " LOG No staged files match any of provided globs." @@ -31,16 +15,14 @@ exports[`runAll should warn if the argument length is longer than what the platf WARN ‼ lint-staged generated an argument string of 999999 characters, and commands might not run correctly on your platform. It is recommended to use functions as linters and split your command based on the number of staged files. For more info, please visit: https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-commands -LOG Backing up... [started] -LOG Backing up... [completed] +LOG Preparing... [started] +LOG Preparing... [completed] LOG Running tasks... [started] LOG Running tasks for *.js [started] LOG echo \\"sample\\" [started] LOG echo \\"sample\\" [completed] LOG Running tasks for *.js [completed] LOG Running tasks... [completed] -LOG Applying modifications by tasks... [started] -LOG Applying modifications by tasks... [completed] -LOG Clearing backup... [started] -LOG Clearing backup... [completed]" +LOG Cleaning up... [started] +LOG Cleaning up... [completed]" `; diff --git a/test/runAll.spec.js b/test/runAll.spec.js index 34e137be9..1e68485dd 100644 --- a/test/runAll.spec.js +++ b/test/runAll.spec.js @@ -65,11 +65,4 @@ describe('runAll', () => { await runAll({ config: { '*.js': ['echo "sample"'] }, debug: true }, logger) expect(logger.printHistory()).toMatchSnapshot() }) - - it('should not skip tasks if there are files', async () => { - expect.assertions(1) - getStagedFiles.mockImplementationOnce(async () => ['sample.js']) - await runAll({ config: { '*.js': ['echo "sample"'] } }) - expect(console.printHistory()).toMatchSnapshot() - }) }) From d843d07915f05c466d133a6369ee7d0212ef9bbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sun, 21 Jul 2019 15:30:05 +0300 Subject: [PATCH 04/64] test: update test for restoring changes --- test/runAll.unmocked.spec.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index cacbd7dbd..929cbfbb6 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -344,6 +344,16 @@ index f80f875..1c5643c 100644 // Remove lock file await fs.remove(`${cwd}/.git/index.lock`) + + // Luckily there is a stash + expect(await execGit(['stash', 'list'])).toMatchInlineSnapshot( + `"stash@{0}: On master: lint-staged automatic backup"` + ) + await execGit(['reset', '--hard']) + await execGit(['stash', 'pop', '--index']) + + expect(await execGit(['diff'])).toEqual(diff) + expect(await readFile('test.js')).toEqual(testJsFileUgly + appended) }) afterEach(async () => { From 76cb08f6eecd68f3ae7e606216b4c5fdc1da94f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sun, 21 Jul 2019 15:30:15 +0300 Subject: [PATCH 05/64] fix: retry failing apply with 3-way merge --- src/gitWorkflow.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/gitWorkflow.js b/src/gitWorkflow.js index 75f34f443..08f3f29b7 100644 --- a/src/gitWorkflow.js +++ b/src/gitWorkflow.js @@ -45,6 +45,8 @@ async function stashBackup(options) { debug('Done backing up original state!') } +const gitApplyArgs = ['apply', '-v', '--whitespace=nowarn', '--recount', '--unidiff-zero'] + /** * Resets everything and applies back unstaged and staged changes, * possibly with modifications by tasks @@ -56,10 +58,15 @@ async function restoreUnstagedChanges(options) { debug('Restoring unstaged changes...') if (unstagedDiff) { - await execGit(['apply', '-v', '--whitespace=nowarn', '--recount', '--unidiff-zero'], { - ...options, - input: `${unstagedDiff}\n` - }) + try { + await execGit(gitApplyArgs, { ...options, input: `${unstagedDiff}\n` }) + } catch (error) { + debug('Error when restoring changes:') + debug(error) + debug('Retrying with 3-way merge') + // Retry with `--3way` if normal apply fails + await execGit([...gitApplyArgs, '--3way'], { ...options, input: `${unstagedDiff}\n` }) + } } debug('Done restoring unstaged changes!') From 9b101cd170593caee8dca76b66a1056e3330edb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Mon, 22 Jul 2019 18:29:28 +0300 Subject: [PATCH 06/64] refactor: improvements --- src/gitWorkflow.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gitWorkflow.js b/src/gitWorkflow.js index 08f3f29b7..402ee641d 100644 --- a/src/gitWorkflow.js +++ b/src/gitWorkflow.js @@ -6,7 +6,7 @@ const execGit = require('./execGit') const STASH = 'lint-staged automatic backup' -let unstagedDiff +let unstagedDiff = null /** * Get name of backup stash @@ -15,8 +15,8 @@ let unstagedDiff * @returns {Promise} */ async function getBackupStash(options) { - const stashList = (await execGit(['stash', 'list'], options)).split('\n') - const index = stashList.findIndex(line => line.includes(STASH)) + const stashes = await execGit(['stash', 'list'], options) + const index = stashes.split('\n').findIndex(line => line.includes(STASH)) return `stash@{${index}}` } @@ -96,6 +96,7 @@ async function dropBackup(options) { debug('Dropping backup stash...') const original = await getBackupStash(options) await execGit(['stash', 'drop', '--quiet', original], options) + unstagedDiff = null debug('Done dropping backup stash!') } From 128631d24ac830d5193076c86e57117cfe8faafd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Mon, 22 Jul 2019 20:51:32 +0300 Subject: [PATCH 07/64] refactor: GitWorkflow is a class --- src/gitWorkflow.js | 181 +++++++++++++++++----------------- src/runAll.js | 12 ++- test/__mocks__/gitWorkflow.js | 17 ++-- test/runAll.spec.js | 4 +- 4 files changed, 105 insertions(+), 109 deletions(-) diff --git a/src/gitWorkflow.js b/src/gitWorkflow.js index 402ee641d..d7a8639a0 100644 --- a/src/gitWorkflow.js +++ b/src/gitWorkflow.js @@ -6,104 +6,103 @@ const execGit = require('./execGit') const STASH = 'lint-staged automatic backup' -let unstagedDiff = null - -/** - * Get name of backup stash - * - * @param {Object} [options] - * @returns {Promise} - */ -async function getBackupStash(options) { - const stashes = await execGit(['stash', 'list'], options) - const index = stashes.split('\n').findIndex(line => line.includes(STASH)) - return `stash@{${index}}` -} - -/** - * Create backup stashes, one of everything and one of only staged changes - * Leves stages files in index for running tasks - * - * @param {Object} [options] - * @returns {Promise} - */ -async function stashBackup(options) { - debug('Backing up original state...') - - // Get stash of entire original state, including unstaged changes - // Keep index so that tasks only work on those files - await execGit(['stash', 'save', '--quiet', '--include-untracked', '--keep-index', STASH], options) - - // Since only staged files are now present, get a diff of unstaged changes - // by comparing current index against original stash, but in reverse - const original = await getBackupStash(options) - unstagedDiff = await execGit( - ['diff', '--unified=0', '--no-color', '--no-ext-diff', '-p', original, '-R'], - options - ) +const gitApplyArgs = ['apply', '-v', '--whitespace=nowarn', '--recount', '--unidiff-zero'] - debug('Done backing up original state!') -} +class GitWorkflow { + constructor(cwd) { + this.execGit = (args, options = {}) => execGit(args, { ...options, cwd }) + this.unstagedDiff = null + } -const gitApplyArgs = ['apply', '-v', '--whitespace=nowarn', '--recount', '--unidiff-zero'] + /** + * Get name of backup stash + * + * @param {Object} [options] + * @returns {Promise} + */ + async getBackupStash() { + const stashes = await this.execGit(['stash', 'list']) + const index = stashes.split('\n').findIndex(line => line.includes(STASH)) + return `stash@{${index}}` + } -/** - * Resets everything and applies back unstaged and staged changes, - * possibly with modifications by tasks - * - * @param {Object} [options] - * @returns {Promise} - */ -async function restoreUnstagedChanges(options) { - debug('Restoring unstaged changes...') + /** + * Create backup stashes, one of everything and one of only staged changes + * Leves stages files in index for running tasks + * + * @param {Object} [options] + * @returns {Promise} + */ + async stashBackup() { + debug('Backing up original state...') + // Get stash of entire original state, including unstaged changes + // Keep index so that tasks only work on those files + await this.execGit(['stash', 'save', '--quiet', '--include-untracked', '--keep-index', STASH]) + // Since only staged files are now present, get a diff of unstaged changes + // by comparing current index against original stash, but in reverse + const original = await this.getBackupStash() + this.unstagedDiff = await this.execGit([ + 'diff', + '--unified=0', + '--no-color', + '--no-ext-diff', + '-p', + original, + '-R' + ]) + debug('Done backing up original state!') + } - if (unstagedDiff) { - try { - await execGit(gitApplyArgs, { ...options, input: `${unstagedDiff}\n` }) - } catch (error) { - debug('Error when restoring changes:') - debug(error) - debug('Retrying with 3-way merge') - // Retry with `--3way` if normal apply fails - await execGit([...gitApplyArgs, '--3way'], { ...options, input: `${unstagedDiff}\n` }) + /** + * Resets everything and applies back unstaged and staged changes, + * possibly with modifications by tasks + * + * @param {Object} [options] + * @returns {Promise} + */ + async restoreUnstagedChanges() { + debug('Restoring unstaged changes...') + if (this.unstagedDiff) { + try { + await this.execGit(gitApplyArgs, { input: `${this.unstagedDiff}\n` }) + } catch (error) { + debug('Error when restoring changes:') + debug(error) + debug('Retrying with 3-way merge') + // Retry with `--3way` if normal apply fails + await this.execGit([...gitApplyArgs, '--3way'], { input: `${this.unstagedDiff}\n` }) + } } + debug('Done restoring unstaged changes!') } - debug('Done restoring unstaged changes!') -} - -/** - * Restore original HEAD state in case of errors - * - * @param {Object} [options] - * @returns {Promise} - */ -async function restoreOriginalState(options) { - debug('Restoring original state...') - const original = await getBackupStash(options) - await execGit(['reset', '--hard', 'HEAD'], options) - await execGit(['stash', 'apply', '--quiet', '--index', original], options) - debug('Done restoring original state!') -} + /** + * Restore original HEAD state in case of errors + * + * @param {Object} [options] + * @returns {Promise} + */ + async restoreOriginalState() { + debug('Restoring original state...') + const original = await this.getBackupStash() + await this.execGit(['reset', '--hard', 'HEAD']) + await this.execGit(['stash', 'apply', '--quiet', '--index', original]) + debug('Done restoring original state!') + } -/** - * Drop the created stashes after everything has run - * - * @param {Object} [options] - * @returns {Promise} - */ -async function dropBackup(options) { - debug('Dropping backup stash...') - const original = await getBackupStash(options) - await execGit(['stash', 'drop', '--quiet', original], options) - unstagedDiff = null - debug('Done dropping backup stash!') + /** + * Drop the created stashes after everything has run + * + * @param {Object} [options] + * @returns {Promise} + */ + async dropBackup() { + debug('Dropping backup stash...') + const original = await this.getBackupStash() + await this.execGit(['stash', 'drop', '--quiet', original]) + this.unstagedDiff = null + debug('Done dropping backup stash!') + } } -module.exports = { - execGit, - stashBackup, - restoreUnstagedChanges, - restoreOriginalState, - dropBackup -} +module.exports = GitWorkflow diff --git a/src/runAll.js b/src/runAll.js index 16e9e7666..e6adedcff 100644 --- a/src/runAll.js +++ b/src/runAll.js @@ -9,7 +9,7 @@ const symbols = require('log-symbols') const generateTasks = require('./generateTasks') const getStagedFiles = require('./getStagedFiles') -const git = require('./gitWorkflow') +const GitWorkflow = require('./gitWorkflow') const makeCmdTasks = require('./makeCmdTasks') const resolveGitDir = require('./resolveGitDir') @@ -102,11 +102,13 @@ https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-com return 'No tasks to run.' } + const git = new GitWorkflow(gitDir) + return new Listr( [ { title: 'Preparing...', - task: () => git.stashBackup({ cwd: gitDir }) + task: () => git.stashBackup() }, { title: 'Running tasks...', @@ -115,13 +117,13 @@ https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-com { title: 'Restoring original state due to errors...', enabled: ctx => ctx.hasErrors, - task: () => git.restoreOriginalState({ cwd: gitDir }) + task: () => git.restoreOriginalState() }, { title: 'Cleaning up...', task: async ctx => { - if (!ctx.hasErrors) await git.restoreUnstagedChanges({ cwd: gitDir }) - await git.dropBackup({ cwd: gitDir }) + if (!ctx.hasErrors) await git.restoreUnstagedChanges() + await git.dropBackup() } } ], diff --git a/test/__mocks__/gitWorkflow.js b/test/__mocks__/gitWorkflow.js index 74d49e155..7b846dd7c 100644 --- a/test/__mocks__/gitWorkflow.js +++ b/test/__mocks__/gitWorkflow.js @@ -1,11 +1,8 @@ -const stashBackup = jest.fn().mockImplementation(() => Promise.resolve(null)) -const restoreUnstagedChanges = jest.fn().mockImplementation(() => Promise.resolve(null)) -const restoreOriginalState = jest.fn().mockImplementation(() => Promise.resolve(null)) -const dropBackup = jest.fn().mockImplementation(() => Promise.resolve(null)) - -module.exports = { - stashBackup, - restoreUnstagedChanges, - restoreOriginalState, - dropBackup +const stub = { + stashBackup: jest.fn().mockImplementation(() => Promise.resolve()), + restoreUnstagedChanges: jest.fn().mockImplementation(() => Promise.resolve()), + restoreOriginalState: jest.fn().mockImplementation(() => Promise.resolve()), + dropBackup: jest.fn().mockImplementation(() => Promise.resolve()) } + +module.exports = () => stub diff --git a/test/runAll.spec.js b/test/runAll.spec.js index 1e68485dd..575ed067a 100644 --- a/test/runAll.spec.js +++ b/test/runAll.spec.js @@ -36,14 +36,11 @@ describe('runAll', () => { }) it('should resolve the promise with no tasks', async () => { - expect.assertions(1) const res = await runAll({ config: {} }) - expect(res).toEqual('No tasks to run.') }) it('should resolve the promise with no files', async () => { - expect.assertions(1) await runAll({ config: { '*.js': ['echo "sample"'] } }) expect(console.printHistory()).toMatchSnapshot() }) @@ -56,6 +53,7 @@ describe('runAll', () => { } catch (err) { console.log(err) } + expect(console.printHistory()).toMatchSnapshot() }) From 061946ca19b823b8d414d33746613a1312a4ef78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Tue, 23 Jul 2019 06:46:07 +0300 Subject: [PATCH 08/64] test: increase jest timeout for slow CI runners --- testSetup.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testSetup.js b/testSetup.js index 73b97afdb..32cc1e7a6 100644 --- a/testSetup.js +++ b/testSetup.js @@ -2,3 +2,6 @@ // Overwrite TTY mode to always render without ansi codes process.stdout.isTTY = false + +// Increase timeout for slow CI runners +jest.setTimeout(10000) From 357934fe1e193040d1a138d3d138da1377004be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sat, 17 Aug 2019 10:47:08 +0300 Subject: [PATCH 09/64] fix: try applying unstaged changes before handling errors --- src/runAll.js | 10 ++++++---- test/__snapshots__/runAll.spec.js.snap | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/runAll.js b/src/runAll.js index e6adedcff..580e11928 100644 --- a/src/runAll.js +++ b/src/runAll.js @@ -114,6 +114,11 @@ https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-com title: 'Running tasks...', task: () => new Listr(tasks, { ...listrOptions, concurrent: true, exitOnError: false }) }, + { + title: 'Applying unstaged changes...', + skip: ctx => ctx.hasErrors && 'Skipped because of errors from tasks', + task: () => git.restoreUnstagedChanges() + }, { title: 'Restoring original state due to errors...', enabled: ctx => ctx.hasErrors, @@ -121,10 +126,7 @@ https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-com }, { title: 'Cleaning up...', - task: async ctx => { - if (!ctx.hasErrors) await git.restoreUnstagedChanges() - await git.dropBackup() - } + task: () => git.dropBackup() } ], listrOptions diff --git a/test/__snapshots__/runAll.spec.js.snap b/test/__snapshots__/runAll.spec.js.snap index 040bcaa6d..ccd4b18d7 100644 --- a/test/__snapshots__/runAll.spec.js.snap +++ b/test/__snapshots__/runAll.spec.js.snap @@ -23,6 +23,8 @@ LOG echo \\"sample\\" [started] LOG echo \\"sample\\" [completed] LOG Running tasks for *.js [completed] LOG Running tasks... [completed] +LOG Applying unstaged changes... [started] +LOG Applying unstaged changes... [completed] LOG Cleaning up... [started] LOG Cleaning up... [completed]" `; From bbfdbce60ce1bee5a110f2232beba0cac6ce2573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sat, 17 Aug 2019 13:17:38 +0300 Subject: [PATCH 10/64] test: add some runAll tests --- test/__snapshots__/runAll.spec.js.snap | 78 ++++++++++++++++++++++++++ test/runAll.spec.js | 52 +++++++++++++++++ 2 files changed, 130 insertions(+) diff --git a/test/__snapshots__/runAll.spec.js.snap b/test/__snapshots__/runAll.spec.js.snap index ccd4b18d7..a5f364a3d 100644 --- a/test/__snapshots__/runAll.spec.js.snap +++ b/test/__snapshots__/runAll.spec.js.snap @@ -1,10 +1,88 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`runAll should not skip tasks if there are files 1`] = ` +" +LOG Preparing... [started] +LOG Preparing... [completed] +LOG Running tasks... [started] +LOG Running tasks for *.js [started] +LOG echo \\"sample\\" [started] +LOG echo \\"sample\\" [completed] +LOG Running tasks for *.js [completed] +LOG Running tasks... [completed] +LOG Applying unstaged changes... [started] +LOG Applying unstaged changes... [completed] +LOG Cleaning up... [started] +LOG Cleaning up... [completed]" +`; + exports[`runAll should resolve the promise with no files 1`] = ` " LOG No staged files match any of provided globs." `; +exports[`runAll should skip applying unstaged modifications if there are errors during linting 1`] = ` +" +LOG Preparing... [started] +LOG Preparing... [completed] +LOG Running tasks... [started] +LOG Running tasks for *.js [started] +LOG echo \\"sample\\" [started] +LOG echo \\"sample\\" [failed] +LOG → +LOG Running tasks for *.js [failed] +LOG → +LOG Running tasks... [failed] +LOG Applying unstaged changes... [started] +LOG Applying unstaged changes... [skipped] +LOG → Skipped because of errors from tasks +LOG Restoring original state due to errors... [started] +LOG Restoring original state due to errors... [completed] +LOG Cleaning up... [started] +LOG Cleaning up... [completed] +LOG { + name: 'ListrError', + errors: [ + { + privateMsg: '\\\\n\\\\n\\\\n× echo \\"sample\\" found some errors. Please fix them and try committing again.\\\\n\\\\nLinter finished with error', + context: {hasErrors: true} + } + ], + context: {hasErrors: true} +}" +`; + +exports[`runAll should skip tasks and restore state if terminated 1`] = ` +" +LOG Preparing... [started] +LOG Preparing... [completed] +LOG Running tasks... [started] +LOG Running tasks for *.js [started] +LOG echo \\"sample\\" [started] +LOG echo \\"sample\\" [failed] +LOG → +LOG Running tasks for *.js [failed] +LOG → +LOG Running tasks... [failed] +LOG Applying unstaged changes... [started] +LOG Applying unstaged changes... [skipped] +LOG → Skipped because of errors from tasks +LOG Restoring original state due to errors... [started] +LOG Restoring original state due to errors... [completed] +LOG Cleaning up... [started] +LOG Cleaning up... [completed] +LOG { + name: 'ListrError', + errors: [ + { + privateMsg: '\\\\n\\\\n\\\\n‼ echo \\"sample\\" was terminated with SIGINT', + context: {hasErrors: true} + } + ], + context: {hasErrors: true} +}" +`; + exports[`runAll should use an injected logger 1`] = ` " LOG No staged files match any of provided globs." diff --git a/test/runAll.spec.js b/test/runAll.spec.js index 575ed067a..ac47ecdbc 100644 --- a/test/runAll.spec.js +++ b/test/runAll.spec.js @@ -1,4 +1,5 @@ import makeConsoleMock from 'consolemock' +import execa from 'execa' import normalize from 'normalize-path' import resolveGitDir from '../src/resolveGitDir' @@ -63,4 +64,55 @@ describe('runAll', () => { await runAll({ config: { '*.js': ['echo "sample"'] }, debug: true }, logger) expect(logger.printHistory()).toMatchSnapshot() }) + + it('should not skip tasks if there are files', async () => { + expect.assertions(1) + getStagedFiles.mockImplementationOnce(async () => ['sample.js']) + await runAll({ config: { '*.js': ['echo "sample"'] } }) + expect(console.printHistory()).toMatchSnapshot() + }) + + it('should skip applying unstaged modifications if there are errors during linting', async () => { + expect.assertions(1) + getStagedFiles.mockImplementationOnce(async () => ['sample.js']) + execa.mockImplementation(() => + Promise.resolve({ + stdout: '', + stderr: 'Linter finished with error', + code: 1, + failed: true, + cmd: 'mock cmd' + }) + ) + + try { + await runAll({ config: { '*.js': ['echo "sample"'] } }) + } catch (err) { + console.log(err) + } + expect(console.printHistory()).toMatchSnapshot() + }) + + it('should skip tasks and restore state if terminated', async () => { + expect.assertions(1) + getStagedFiles.mockImplementationOnce(async () => ['sample.js']) + execa.mockImplementation(() => + Promise.resolve({ + stdout: '', + stderr: '', + code: 0, + failed: false, + killed: true, + signal: 'SIGINT', + cmd: 'mock cmd' + }) + ) + + try { + await runAll({ config: { '*.js': ['echo "sample"'] } }) + } catch (err) { + console.log(err) + } + expect(console.printHistory()).toMatchSnapshot() + }) }) From a2b9716e9d00ac79cd2cb1b56723387201011c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Tue, 10 Sep 2019 07:30:27 +0300 Subject: [PATCH 11/64] test: add test for failing merge conflict resolution lint-staged loses the MERGE_HEAD while stashing backups, so the current behaviour breaks merge conflict resolution. Solution is to manually check, save, and restore the MERGE_HEAD during runtime. This should be fixed and the test adjusted for successful run --- test/runAll.unmocked.spec.js | 160 +++++++++++++++++++++-------------- 1 file changed, 98 insertions(+), 62 deletions(-) diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 929cbfbb6..800e0b057 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -33,20 +33,26 @@ const readFile = async (filename, dir = cwd) => const appendFile = async (filename, content, dir = cwd) => fs.appendFile(path.join(dir, filename), content) +// Write (over) file, creating if it doesn't exist +const writeFile = async (filename, content, dir = cwd) => + fs.writeFile(path.join(dir, filename), content) + // Wrap execGit to always pass `gitOps` const execGit = async args => execGitBase(args, { cwd }) // Execute runAll before git commit to emulate lint-staged -const gitCommit = async options => { +const gitCommit = async (options, message = 'test') => { try { await runAll({ ...options, cwd, quiet: true }) - await execGit(['commit', '-m "test"']) + await execGit(['commit', `-m "${message}"`]) return true } catch (error) { return false } } +const fixJsConfig = { config: { '*.js': ['prettier --write', 'git add'] } } + describe('runAll', () => { it('should throw when not in a git directory', async () => { const nonGitDir = tmp.dirSync({ unsafeCleanup: true }) @@ -82,10 +88,7 @@ describe('runAll', () => { // Nothing is wrong, so a new commit is created expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') - expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` -" \\"test\\" -" -`) + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('test') expect(await readFile('test.js')).toEqual(testJsFilePretty) }) @@ -95,15 +98,12 @@ describe('runAll', () => { await execGit(['add', 'test.js']) // Run lint-staged with `prettier --write` and commit pretty file - const success = await gitCommit({ config: { '*.js': ['prettier --write', 'git add'] } }) + const success = await gitCommit(fixJsConfig) expect(success).toEqual(true) // Nothing is wrong, so a new commit is created and file is pretty expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') - expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` -" \\"test\\" -" -`) + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('test') expect(await readFile('test.js')).toEqual(testJsFilePretty) }) @@ -119,10 +119,7 @@ describe('runAll', () => { // Something was wrong so the repo is returned to original state expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') - expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` -" initial commit -" -`) + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('initial commit') expect(await execGit(['status'])).toEqual(status) expect(await readFile('test.js')).toEqual(testJsFileUgly) }) @@ -134,15 +131,12 @@ describe('runAll', () => { const status = await execGit(['status']) // Run lint-staged with `prettier --write` to break the linter - const success = await gitCommit({ config: { '*.js': ['prettier --write', 'git add'] } }) + const success = await gitCommit(fixJsConfig) expect(success).toEqual(false) // Something was wrong so the repo is returned to original state expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') - expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` -" initial commit -" -`) + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('initial commit') expect(await execGit(['status'])).toEqual(status) expect(await readFile('test.js')).toEqual(testJsFileUnfixable) }) @@ -162,10 +156,7 @@ describe('runAll', () => { // Nothing is wrong, so a new commit is created and file is pretty expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') - expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` -" \\"test\\" -" -`) + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('test') // Latest commit contains pretty file // `git show` strips empty line from here here @@ -188,15 +179,12 @@ describe('runAll', () => { await appendFile('test.js', appended) // Run lint-staged with `prettier --write` and commit pretty file - const success = await gitCommit({ config: { '*.js': ['prettier --write', 'git add'] } }) + const success = await gitCommit(fixJsConfig) expect(success).toEqual(true) // Nothing is wrong, so a new commit is created and file is pretty expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') - expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` -" \\"test\\" -" -`) + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('test') // Latest commit contains pretty file // `git show` strips empty line from here here @@ -227,10 +215,7 @@ describe('runAll', () => { // Something was wrong so the repo is returned to original state expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') - expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` -" initial commit -" -`) + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('initial commit') expect(await execGit(['status'])).toEqual(status) expect(await readFile('test.js')).toEqual(testJsFileUgly + appended) }) @@ -246,15 +231,12 @@ describe('runAll', () => { const status = await execGit(['status']) // Run lint-staged with `prettier --write` to break the linter - const success = await gitCommit({ config: { '*.js': ['prettier --write', 'git add'] } }) + const success = await gitCommit(fixJsConfig) expect(success).toEqual(false) // Something was wrong so the repo is returned to original state expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') - expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` -" initial commit -" -`) + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('initial commit') expect(await execGit(['status'])).toEqual(status) expect(await readFile('test.js')).toEqual(testJsFileUnfixable + appended) }) @@ -269,25 +251,19 @@ describe('runAll', () => { await appendFile('test.js', testJsFilePretty) // Run lint-staged with `prettier --write` and commit pretty file - const success = await gitCommit({ config: { '*.js': ['prettier --write', 'git add'] } }) + const success = await gitCommit(fixJsConfig) expect(success).toEqual(true) // Nothing is wrong, so a new commit is created and file is pretty expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') - expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` -" \\"test\\" -" -`) + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('test') // Latest commit contains pretty file // `git show` strips empty line from here here expect(await execGit(['show', 'HEAD:test.js'])).toEqual(testJsFilePretty.replace(/\n$/, '')) // Nothing is staged - expect(await execGit(['status'])).toMatchInlineSnapshot(` -"On branch master -nothing to commit, working tree clean" -`) + expect(await execGit(['status'])).toMatch('nothing to commit, working tree clean') // File is pretty, and has been edited expect(await readFile('test.js')).toEqual(testJsFilePretty) @@ -319,25 +295,22 @@ nothing to commit, working tree clean" // Something was wrong so new commit wasn't created expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') - expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` -" initial commit -" -`) + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('initial commit') // But local modifications are gone expect(await execGit(['diff'])).not.toEqual(diff) expect(await execGit(['diff'])).toMatchInlineSnapshot(` -"diff --git a/test.js b/test.js -index f80f875..1c5643c 100644 ---- a/test.js -+++ b/test.js -@@ -1,3 +1,3 @@ - module.exports = { -- 'foo': 'bar', --} -+ foo: \\"bar\\" -+};" -`) + "diff --git a/test.js b/test.js + index f80f875..1c5643c 100644 + --- a/test.js + +++ b/test.js + @@ -1,3 +1,3 @@ + module.exports = { + - 'foo': 'bar', + -} + + foo: \\"bar\\" + +};" + `) expect(await readFile('test.js')).not.toEqual(testJsFileUgly + appended) expect(await readFile('test.js')).toEqual(testJsFilePretty) @@ -356,6 +329,69 @@ index f80f875..1c5643c 100644 expect(await readFile('test.js')).toEqual(testJsFileUgly + appended) }) + it('should handle merge conflicts', async () => { + const fileInBranchA = `module.exports = "foo";\n` + const fileInBranchB = `module.exports = 'bar'\n` + const fileInBranchBFixed = `module.exports = "bar";\n` + + // Create one branch + await execGit(['checkout', '-b', 'branch-a']) + await appendFile('test.js', fileInBranchA) + await execGit(['add', '.']) + const successA = await gitCommit(fixJsConfig, 'commit a') + expect(successA).toEqual(true) + expect(await readFile('test.js')).toEqual(fileInBranchA) + + await execGit(['checkout', 'master']) + + // Create another branch + await execGit(['checkout', '-b', 'branch-b']) + await appendFile('test.js', fileInBranchB) + await execGit(['add', '.']) + const successB = await gitCommit(fixJsConfig, 'commit b') + expect(successB).toEqual(true) + expect(await readFile('test.js')).toEqual(fileInBranchBFixed) + + // Merge first branch + await execGit(['checkout', 'master']) + await execGit(['merge', 'branch-a']) + expect(await readFile('test.js')).toEqual(fileInBranchA) + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('commit a') + + // Merge second branch, causing merge conflict + try { + await execGit(['merge', 'branch-b']) + } catch ({ stdout }) { + expect(stdout).toMatch('Merge conflict in test.js') + } + + expect(await readFile('test.js')).toMatchInlineSnapshot(` + "<<<<<<< HEAD + module.exports = \\"foo\\"; + ======= + module.exports = \\"bar\\"; + >>>>>>> branch-b + " + `) + + // Fix conflict and commit using lint-staged + await writeFile('test.js', fileInBranchB) + expect(await readFile('test.js')).toEqual(fileInBranchB) + await execGit(['add', '.']) + + // Do not use `gitCommit` wrapper here + await runAll({ ...fixJsConfig, cwd, quiet: true }) + + // Lint-staged lost MERGE_HEAD + try { + await execGit(['merge', '--continue']) + } catch ({ stderr }) { + expect(stderr).toMatch('There is no merge in progress (MERGE_HEAD missing)') + } + + // TODO: Fix behaviour by saving/restoring MERGE_HEAD, and then complete test + }) + afterEach(async () => { wcDir.removeCallback() }) From effdb4cd7740390ff0b8aa3c63a147909f8700c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Wed, 11 Sep 2019 17:33:53 +0300 Subject: [PATCH 12/64] refactor: use execa.command to avoid parsing of commands --- package.json | 1 - src/resolveTaskFn.js | 55 +++++++++----------------------------- test/__mocks__/execa.js | 6 ++++- test/index.spec.js | 2 +- test/makeCmdTasks.spec.js | 4 +-- test/resolveTaskFn.spec.js | 10 +++---- yarn.lock | 5 ---- 7 files changed, 26 insertions(+), 57 deletions(-) diff --git a/package.json b/package.json index 7df2ba07c..465619557 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,6 @@ "micromatch": "^4.0.2", "normalize-path": "^3.0.0", "please-upgrade-node": "^3.1.1", - "string-argv": "^0.3.0", "stringify-object": "^3.3.0" }, "devDependencies": { diff --git a/src/resolveTaskFn.js b/src/resolveTaskFn.js index 33eafbef6..39d999629 100644 --- a/src/resolveTaskFn.js +++ b/src/resolveTaskFn.js @@ -4,27 +4,9 @@ const chalk = require('chalk') const dedent = require('dedent') const execa = require('execa') const symbols = require('log-symbols') -const stringArgv = require('string-argv') const debug = require('debug')('lint-staged:task') -/** - * Execute the given linter cmd using execa and - * return the promise. - * - * @param {string} cmd - * @param {Array} args - * @param {Object} execaOptions - * @return {Promise} child_process - */ -const execLinter = (cmd, args, execaOptions) => { - debug('cmd:', cmd) - if (args) debug('args:', args) - debug('execaOptions:', execaOptions) - - return args ? execa(cmd, args, execaOptions) : execa(cmd, execaOptions) -} - const successMsg = linter => `${symbols.success} ${linter} passed!` /** @@ -73,21 +55,22 @@ function makeErr(linter, result, context = {}) { } /** - * Returns the task function for the linter. It handles chunking for file paths - * if the OS is Windows. + * Returns the task function for the linter. * * @param {Object} options * @param {string} options.command — Linter task * @param {String} options.gitDir - Current git repo path * @param {Boolean} options.isFn - Whether the linter task is a function - * @param {Array} options.pathsToLint — Filepaths to run the linter task against + * @param {Array} options.files — Filepaths to run the linter task against * @param {Boolean} [options.relative] — Whether the filepaths should be relative * @param {Boolean} [options.shell] — Whether to skip parsing linter task for better shell support * @returns {function(): Promise>} */ module.exports = function resolveTaskFn({ command, files, gitDir, isFn, relative, shell = false }) { - const execaOptions = { preferLocal: true, reject: false, shell } + const cmd = isFn ? command : `${command} ${files.join(' ')}` + debug('cmd:', cmd) + const execaOptions = { preferLocal: true, reject: false, shell } if (relative) { execaOptions.cwd = process.cwd() } else if (/^git(\.exe)?/i.test(command) && gitDir !== process.cwd()) { @@ -95,27 +78,15 @@ module.exports = function resolveTaskFn({ command, files, gitDir, isFn, relative // e.g `npm` should run tasks in the actual CWD execaOptions.cwd = gitDir } + debug('execaOptions:', execaOptions) - let cmd - let args - - if (shell) { - execaOptions.shell = true - // If `shell`, passed command shouldn't be parsed - // If `linter` is a function, command already includes `files`. - cmd = isFn ? command : `${command} ${files.join(' ')}` - } else { - const [parsedCmd, ...parsedArgs] = stringArgv.parseArgsStringToArgv(command) - cmd = parsedCmd - args = isFn ? parsedArgs : parsedArgs.concat(files) - } + return async ctx => { + const result = await execa.command(cmd, execaOptions) - return ctx => - execLinter(cmd, args, execaOptions).then(result => { - if (result.failed || result.killed || result.signal != null) { - throw makeErr(command, result, ctx) - } + if (result.failed || result.killed || result.signal != null) { + throw makeErr(command, result, ctx) + } - return successMsg(command) - }) + return successMsg(command) + } } diff --git a/test/__mocks__/execa.js b/test/__mocks__/execa.js index 9b5606b6a..52bc88fd7 100644 --- a/test/__mocks__/execa.js +++ b/test/__mocks__/execa.js @@ -1,4 +1,4 @@ -module.exports = jest.fn(() => +const execa = jest.fn(() => Promise.resolve({ stdout: 'a-ok', stderr: '', @@ -9,3 +9,7 @@ module.exports = jest.fn(() => signal: null }) ) + +execa.command = execa + +module.exports = execa diff --git a/test/index.spec.js b/test/index.spec.js index 6d2e3c243..880c1b9a6 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -161,7 +161,7 @@ describe('lintStaged', () => { } mockCosmiconfigWith({ config }) getStagedFiles.mockImplementationOnce(async () => ['sample.java']) - const passed = await lintStaged({ quiet: true }, logger) + const passed = await lintStaged({ quiet: true, shell: true }, logger) expect(logger.printHistory()).toMatchSnapshot() expect(passed).toBe(false) }) diff --git a/test/makeCmdTasks.spec.js b/test/makeCmdTasks.spec.js index 284700aae..9caf1893e 100644 --- a/test/makeCmdTasks.spec.js +++ b/test/makeCmdTasks.spec.js @@ -41,7 +41,7 @@ describe('makeCmdTasks', () => { expect(taskPromise).toBeInstanceOf(Promise) await taskPromise expect(execa).toHaveBeenCalledTimes(1) - expect(execa).lastCalledWith('test', ['test.js'], { + expect(execa).lastCalledWith('test test.js', { preferLocal: true, reject: false, shell: false @@ -50,7 +50,7 @@ describe('makeCmdTasks', () => { expect(taskPromise).toBeInstanceOf(Promise) await taskPromise expect(execa).toHaveBeenCalledTimes(2) - expect(execa).lastCalledWith('test2', ['test.js'], { + expect(execa).lastCalledWith('test2 test.js', { preferLocal: true, reject: false, shell: false diff --git a/test/resolveTaskFn.spec.js b/test/resolveTaskFn.spec.js index 9b5696670..7ad1a890b 100644 --- a/test/resolveTaskFn.spec.js +++ b/test/resolveTaskFn.spec.js @@ -17,7 +17,7 @@ describe('resolveTaskFn', () => { await taskFn() expect(execa).toHaveBeenCalledTimes(1) - expect(execa).lastCalledWith('node', ['--arg=true', './myscript.js', 'test.js'], { + expect(execa).lastCalledWith('node --arg=true ./myscript.js test.js', { preferLocal: true, reject: false, shell: false @@ -34,7 +34,7 @@ describe('resolveTaskFn', () => { await taskFn() expect(execa).toHaveBeenCalledTimes(1) - expect(execa).lastCalledWith('node', ['--arg=true', './myscript.js', 'test.js'], { + expect(execa).lastCalledWith('node --arg=true ./myscript.js test.js', { preferLocal: true, reject: false, shell: false @@ -86,7 +86,7 @@ describe('resolveTaskFn', () => { await taskFn() expect(execa).toHaveBeenCalledTimes(1) - expect(execa).lastCalledWith('git', ['add', 'test.js'], { + expect(execa).lastCalledWith('git add test.js', { cwd: '../', preferLocal: true, reject: false, @@ -100,7 +100,7 @@ describe('resolveTaskFn', () => { await taskFn() expect(execa).toHaveBeenCalledTimes(1) - expect(execa).lastCalledWith('jest', ['test.js'], { + expect(execa).lastCalledWith('jest test.js', { preferLocal: true, reject: false, shell: false @@ -117,7 +117,7 @@ describe('resolveTaskFn', () => { await taskFn() expect(execa).toHaveBeenCalledTimes(1) - expect(execa).lastCalledWith('git', ['add', 'test.js'], { + expect(execa).lastCalledWith('git add test.js', { cwd: process.cwd(), preferLocal: true, reject: false, diff --git a/yarn.lock b/yarn.lock index dc539b1db..23cac436e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5463,11 +5463,6 @@ stealthy-require@^1.1.1: resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= -string-argv@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.0.tgz#0ea99e7257fea5e97a1bfcdfc19cf12d68e6ec6a" - integrity sha512-NGZHq3nkSXVtGZXTBjFru3MNfoZyIzN25T7BmvdgnSC0LCJczAGLLMQLyjywSIaAoqSemgLzBRHOsnrHbt60+Q== - string-length@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" From 2f1e886cba422844b0496a96696dae5296835862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Wed, 11 Sep 2019 18:37:33 +0300 Subject: [PATCH 13/64] fix: gitWorkflow handles active merge mode --- src/gitWorkflow.js | 59 +++++++++++++++++++++++++++++++++++- test/runAll.unmocked.spec.js | 53 +++++++++++++++++--------------- 2 files changed, 86 insertions(+), 26 deletions(-) diff --git a/src/gitWorkflow.js b/src/gitWorkflow.js index d7a8639a0..0840daf19 100644 --- a/src/gitWorkflow.js +++ b/src/gitWorkflow.js @@ -1,9 +1,15 @@ 'use strict' const debug = require('debug')('lint-staged:git') +const fs = require('fs') +const path = require('path') const execGit = require('./execGit') +const MERGE_HEAD = 'MERGE_HEAD' +const MERGE_MODE = 'MERGE_MODE' +const MERGE_MSG = 'MERGE_MSG' + const STASH = 'lint-staged automatic backup' const gitApplyArgs = ['apply', '-v', '--whitespace=nowarn', '--recount', '--unidiff-zero'] @@ -12,6 +18,33 @@ class GitWorkflow { constructor(cwd) { this.execGit = (args, options = {}) => execGit(args, { ...options, cwd }) this.unstagedDiff = null + this.cwd = cwd + } + + /** + * Read file from .git directory, returning a buffer or null + * @param {String} filename Relative path to file + * @returns {Promise} + */ + readGitConfigFile(filename) { + const resolvedPath = path.resolve(this.cwd, '.git', filename) + return new Promise(resolve => { + fs.readFile(resolvedPath, (error, file) => { + resolve(error && error.code === 'ENOENT' ? null : file) + }) + }) + } + + /** + * Write buffer to relative .git directory + * @param {String} filename Relative path to file + * @param {Buffer} buffer + */ + writeGitConfigFile(filename, buffer) { + const resolvedPath = path.resolve(this.cwd, '.git', filename) + return new Promise(resolve => { + fs.writeFile(resolvedPath, buffer, resolve) + }) } /** @@ -35,6 +68,21 @@ class GitWorkflow { */ async stashBackup() { debug('Backing up original state...') + + // Git stash loses metadata about a possible merge mode + // Manually check and backup if necessary + const mergeHead = await this.readGitConfigFile(MERGE_HEAD) + if (mergeHead) { + debug('Detected current merge mode!') + debug('Backing up merge state...') + this.mergeHead = mergeHead + await Promise.all([ + this.readGitConfigFile(MERGE_MODE).then(mergeMode => (this.mergeMode = mergeMode)), + this.readGitConfigFile(MERGE_MSG).then(mergeMsg => (this.mergeMsg = mergeMsg)) + ]) + debug('Done backing up merge state!') + } + // Get stash of entire original state, including unstaged changes // Keep index so that tasks only work on those files await this.execGit(['stash', 'save', '--quiet', '--include-untracked', '--keep-index', STASH]) @@ -100,8 +148,17 @@ class GitWorkflow { debug('Dropping backup stash...') const original = await this.getBackupStash() await this.execGit(['stash', 'drop', '--quiet', original]) - this.unstagedDiff = null debug('Done dropping backup stash!') + + if (this.mergeHead) { + debug('Detected backup merge state!') + debug('Restoring merge state...') + const writePromises = [this.writeGitConfigFile(MERGE_HEAD, this.mergeHead)] + if (this.mergeMode) writePromises.push(this.writeGitConfigFile(MERGE_MODE, this.mergeMode)) + if (this.mergeMsg) writePromises.push(this.writeGitConfigFile(MERGE_MSG, this.mergeMsg)) + await Promise.all(writePromises) + debug('Done restoring merge state!') + } } } diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 800e0b057..323a77245 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -300,17 +300,17 @@ describe('runAll', () => { // But local modifications are gone expect(await execGit(['diff'])).not.toEqual(diff) expect(await execGit(['diff'])).toMatchInlineSnapshot(` - "diff --git a/test.js b/test.js - index f80f875..1c5643c 100644 - --- a/test.js - +++ b/test.js - @@ -1,3 +1,3 @@ - module.exports = { - - 'foo': 'bar', - -} - + foo: \\"bar\\" - +};" - `) + "diff --git a/test.js b/test.js + index f80f875..1c5643c 100644 + --- a/test.js + +++ b/test.js + @@ -1,3 +1,3 @@ + module.exports = { + - 'foo': 'bar', + -} + + foo: \\"bar\\" + +};" + `) expect(await readFile('test.js')).not.toEqual(testJsFileUgly + appended) expect(await readFile('test.js')).toEqual(testJsFilePretty) @@ -366,13 +366,13 @@ describe('runAll', () => { } expect(await readFile('test.js')).toMatchInlineSnapshot(` - "<<<<<<< HEAD - module.exports = \\"foo\\"; - ======= - module.exports = \\"bar\\"; - >>>>>>> branch-b - " - `) + "<<<<<<< HEAD + module.exports = \\"foo\\"; + ======= + module.exports = \\"bar\\"; + >>>>>>> branch-b + " + `) // Fix conflict and commit using lint-staged await writeFile('test.js', fileInBranchB) @@ -381,15 +381,18 @@ describe('runAll', () => { // Do not use `gitCommit` wrapper here await runAll({ ...fixJsConfig, cwd, quiet: true }) + await execGit(['commit', '--no-edit']) - // Lint-staged lost MERGE_HEAD - try { - await execGit(['merge', '--continue']) - } catch ({ stderr }) { - expect(stderr).toMatch('There is no merge in progress (MERGE_HEAD missing)') - } + // Nothing is wrong, so a new commit is created and file is pretty + expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('4') + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` + "Merge branch 'branch-b' - // TODO: Fix behaviour by saving/restoring MERGE_HEAD, and then complete test + # Conflicts: + # test.js + " + `) + expect(await readFile('test.js')).toEqual(fileInBranchBFixed) }) afterEach(async () => { From e68255a32ed490cc5dd9091100a947c7f1380710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Thu, 12 Sep 2019 18:36:11 +0300 Subject: [PATCH 14/64] test: move mock files inside test directory --- {__mocks__ => test/__mocks__}/my-lint-staged-config/index.js | 2 -- .../__mocks__}/my-lint-staged-config/package.json | 0 2 files changed, 2 deletions(-) rename {__mocks__ => test/__mocks__}/my-lint-staged-config/index.js (72%) rename {__mocks__ => test/__mocks__}/my-lint-staged-config/package.json (100%) diff --git a/__mocks__/my-lint-staged-config/index.js b/test/__mocks__/my-lint-staged-config/index.js similarity index 72% rename from __mocks__/my-lint-staged-config/index.js rename to test/__mocks__/my-lint-staged-config/index.js index d8a754d96..cf9fcaad6 100644 --- a/__mocks__/my-lint-staged-config/index.js +++ b/test/__mocks__/my-lint-staged-config/index.js @@ -1,5 +1,3 @@ -'use strict' - module.exports = { '*': 'mytask' } diff --git a/__mocks__/my-lint-staged-config/package.json b/test/__mocks__/my-lint-staged-config/package.json similarity index 100% rename from __mocks__/my-lint-staged-config/package.json rename to test/__mocks__/my-lint-staged-config/package.json From cb9aaf084ea0e6466a4596b558df75b8e70420eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Thu, 12 Sep 2019 18:37:09 +0300 Subject: [PATCH 15/64] test: rework usage of tmp module --- test/execGit.spec.js | 5 ----- test/runAll.unmocked.spec.js | 29 ++++++++++++++++++++--------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/test/execGit.spec.js b/test/execGit.spec.js index 5499ceb19..f8e5ef909 100644 --- a/test/execGit.spec.js +++ b/test/execGit.spec.js @@ -1,12 +1,7 @@ -/* eslint no-underscore-dangle: 0 */ - import path from 'path' -import tmp from 'tmp' import execa from 'execa' import execGit from '../src/execGit' -tmp.setGracefulCleanup() - describe('execGit', () => { it('should execute git in process.cwd if working copy is not specified', async () => { const cwd = process.cwd() diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 323a77245..a5e455eb2 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -1,4 +1,5 @@ import fs from 'fs-extra' +import normalize from 'normalize-path' import path from 'path' import tmp from 'tmp' @@ -22,7 +23,15 @@ const testJsFileUnfixable = `const obj = { 'foo': 'bar' ` -let wcDir +// Create temporary directory by wrapping `tmp` in a Promise +const createTempDir = () => + new Promise((resolve, reject) => { + tmp.dir({ keep: true, unsafeCleanup: true }, (error, name, cleanupCallback) => { + if (error) reject(error) + resolve({ name, cleanupCallback }) + }) + }) + let cwd // Get file content @@ -55,18 +64,20 @@ const fixJsConfig = { config: { '*.js': ['prettier --write', 'git add'] } } describe('runAll', () => { it('should throw when not in a git directory', async () => { - const nonGitDir = tmp.dirSync({ unsafeCleanup: true }) + const nonGitDir = await createTempDir() await expect(runAll({ cwd: nonGitDir })).rejects.toThrowErrorMatchingInlineSnapshot( `"Current directory is not a git directory!"` ) - nonGitDir.removeCallback() + nonGitDir.cleanupCallback() }) }) describe('runAll', () => { + let tmpDir + beforeEach(async () => { - wcDir = tmp.dirSync({ unsafeCleanup: true }) - cwd = await fs.realpath(wcDir.name) + tmpDir = await createTempDir() + cwd = normalize(await fs.realpath(tmpDir.name)) // Init repository with initial commit await execGit('init') @@ -77,6 +88,10 @@ describe('runAll', () => { await execGit(['commit', '-m initial commit']) }) + afterEach(async () => { + await tmpDir.cleanupCallback() + }) + it('Should commit entire staged file when no errors from linter', async () => { // Stage pretty file await appendFile('test.js', testJsFilePretty) @@ -394,8 +409,4 @@ describe('runAll', () => { `) expect(await readFile('test.js')).toEqual(fileInBranchBFixed) }) - - afterEach(async () => { - wcDir.removeCallback() - }) }) From b3eb3fcfffe55bd0cec85dc8ab7e87d399f52cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Thu, 12 Sep 2019 18:51:50 +0300 Subject: [PATCH 16/64] refactor: no need to use path.resolve since path is normalized --- src/gitWorkflow.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gitWorkflow.js b/src/gitWorkflow.js index 0840daf19..366968b03 100644 --- a/src/gitWorkflow.js +++ b/src/gitWorkflow.js @@ -2,7 +2,6 @@ const debug = require('debug')('lint-staged:git') const fs = require('fs') -const path = require('path') const execGit = require('./execGit') @@ -27,7 +26,7 @@ class GitWorkflow { * @returns {Promise} */ readGitConfigFile(filename) { - const resolvedPath = path.resolve(this.cwd, '.git', filename) + const resolvedPath = `${this.cwd}/.git/${filename}` return new Promise(resolve => { fs.readFile(resolvedPath, (error, file) => { resolve(error && error.code === 'ENOENT' ? null : file) @@ -41,7 +40,7 @@ class GitWorkflow { * @param {Buffer} buffer */ writeGitConfigFile(filename, buffer) { - const resolvedPath = path.resolve(this.cwd, '.git', filename) + const resolvedPath = `${this.cwd}/.git/${filename}` return new Promise(resolve => { fs.writeFile(resolvedPath, buffer, resolve) }) From eb54a8976057f4ded466b50a2a8a88dad9a773a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Fri, 13 Sep 2019 06:35:52 +0300 Subject: [PATCH 17/64] refactor: check for merge using fs.access before fs.readfile --- src/gitWorkflow.js | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/gitWorkflow.js b/src/gitWorkflow.js index 366968b03..80bfb2893 100644 --- a/src/gitWorkflow.js +++ b/src/gitWorkflow.js @@ -20,29 +20,44 @@ class GitWorkflow { this.cwd = cwd } + /** + * Resolve file path from .git directory + */ + resolveGitFile(filename) { + return `${this.cwd}/.git/${filename}` + } + + /** + * Check if file exists in .git directory + * @param {String} filename + */ + checkGitConfigFile(filename) { + return new Promise(resolve => { + fs.access(this.resolveGitFile(filename), fs.constants.R_OK, error => resolve(!error)) + }) + } + /** * Read file from .git directory, returning a buffer or null - * @param {String} filename Relative path to file + * @param {String} filename * @returns {Promise} */ readGitConfigFile(filename) { - const resolvedPath = `${this.cwd}/.git/${filename}` return new Promise(resolve => { - fs.readFile(resolvedPath, (error, file) => { - resolve(error && error.code === 'ENOENT' ? null : file) + fs.readFile(this.resolveGitFile(filename), (error, file) => { + resolve(file) }) }) } /** * Write buffer to relative .git directory - * @param {String} filename Relative path to file + * @param {String} filename * @param {Buffer} buffer */ writeGitConfigFile(filename, buffer) { - const resolvedPath = `${this.cwd}/.git/${filename}` return new Promise(resolve => { - fs.writeFile(resolvedPath, buffer, resolve) + fs.writeFile(this.resolveGitFile(filename), buffer, resolve) }) } @@ -70,12 +85,11 @@ class GitWorkflow { // Git stash loses metadata about a possible merge mode // Manually check and backup if necessary - const mergeHead = await this.readGitConfigFile(MERGE_HEAD) - if (mergeHead) { + if (await this.checkGitConfigFile(MERGE_HEAD)) { debug('Detected current merge mode!') debug('Backing up merge state...') - this.mergeHead = mergeHead await Promise.all([ + this.readGitConfigFile(MERGE_HEAD).then(mergeHead => (this.mergeHead = mergeHead)), this.readGitConfigFile(MERGE_MODE).then(mergeMode => (this.mergeMode = mergeMode)), this.readGitConfigFile(MERGE_MSG).then(mergeMsg => (this.mergeMsg = mergeMsg)) ]) @@ -152,10 +166,11 @@ class GitWorkflow { if (this.mergeHead) { debug('Detected backup merge state!') debug('Restoring merge state...') - const writePromises = [this.writeGitConfigFile(MERGE_HEAD, this.mergeHead)] - if (this.mergeMode) writePromises.push(this.writeGitConfigFile(MERGE_MODE, this.mergeMode)) - if (this.mergeMsg) writePromises.push(this.writeGitConfigFile(MERGE_MSG, this.mergeMsg)) - await Promise.all(writePromises) + await Promise.all([ + this.writeGitConfigFile(MERGE_HEAD, this.mergeHead), + this.writeGitConfigFile(MERGE_MODE, this.mergeMode), + this.writeGitConfigFile(MERGE_MSG, this.mergeMsg) + ]) debug('Done restoring merge state!') } } From 158c90080036bc38ee8605d407a8a138403bcbbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Fri, 13 Sep 2019 06:57:27 +0300 Subject: [PATCH 18/64] refactor: move file operations to separate file --- src/file.js | 51 +++++++++++++++++++++++++++++++++ src/gitWorkflow.js | 70 ++++++++++++++-------------------------------- 2 files changed, 72 insertions(+), 49 deletions(-) create mode 100644 src/file.js diff --git a/src/file.js b/src/file.js new file mode 100644 index 000000000..2c6eece33 --- /dev/null +++ b/src/file.js @@ -0,0 +1,51 @@ +'use strict' + +const debug = require('debug')('lint-staged:file') +const fs = require('fs') + +/** + * Check if file exists and is accessible + * @param {String} filename + * @returns {Promise} + */ +module.exports.checkFile = filename => + new Promise(resolve => { + debug('Trying to access `%s`', filename) + fs.access(filename, fs.constants.R_OK, error => { + if (error) { + debug('Unable to access file `%s` with error:', filename) + debug(error) + } else { + debug('Successfully accesses file `%s`', filename) + } + + resolve(!error) + }) + }) + +/** + * @param {String} filename + * @returns {Promise} + */ +module.exports.readBufferFromFile = filename => + new Promise(resolve => { + debug('Reading buffer from file `%s`', filename) + fs.readFile(filename, (error, file) => { + debug('Done reading buffer from file `%s`!', filename) + resolve(file) + }) + }) + +/** + * @param {String} filename + * @param {Buffer} buffer + * @returns {Promise} + */ +module.exports.writeBufferToFile = (filename, buffer) => + new Promise(resolve => { + debug('Writing buffer to file `%s`', filename) + fs.writeFile(filename, buffer, () => { + debug('Done writing buffer to file `%s`!', filename) + resolve() + }) + }) diff --git a/src/gitWorkflow.js b/src/gitWorkflow.js index 80bfb2893..cf0518e84 100644 --- a/src/gitWorkflow.js +++ b/src/gitWorkflow.js @@ -1,9 +1,10 @@ 'use strict' const debug = require('debug')('lint-staged:git') -const fs = require('fs') +const path = require('path') const execGit = require('./execGit') +const { checkFile, readBufferFromFile, writeBufferToFile } = require('./file') const MERGE_HEAD = 'MERGE_HEAD' const MERGE_MODE = 'MERGE_MODE' @@ -18,47 +19,14 @@ class GitWorkflow { this.execGit = (args, options = {}) => execGit(args, { ...options, cwd }) this.unstagedDiff = null this.cwd = cwd - } - - /** - * Resolve file path from .git directory - */ - resolveGitFile(filename) { - return `${this.cwd}/.git/${filename}` - } - /** - * Check if file exists in .git directory - * @param {String} filename - */ - checkGitConfigFile(filename) { - return new Promise(resolve => { - fs.access(this.resolveGitFile(filename), fs.constants.R_OK, error => resolve(!error)) - }) - } - - /** - * Read file from .git directory, returning a buffer or null - * @param {String} filename - * @returns {Promise} - */ - readGitConfigFile(filename) { - return new Promise(resolve => { - fs.readFile(this.resolveGitFile(filename), (error, file) => { - resolve(file) - }) - }) - } - - /** - * Write buffer to relative .git directory - * @param {String} filename - * @param {Buffer} buffer - */ - writeGitConfigFile(filename, buffer) { - return new Promise(resolve => { - fs.writeFile(this.resolveGitFile(filename), buffer, resolve) - }) + /** + * These three files hold state about an ongoing git merge + * Resolve paths during constructor + */ + this.mergeHeadFile = path.resolve(this.cwd, '.git', MERGE_HEAD) + this.mergeModeFile = path.resolve(this.cwd, '.git', MERGE_MODE) + this.mergeMsgFile = path.resolve(this.cwd, '.git', MERGE_MSG) } /** @@ -85,13 +53,17 @@ class GitWorkflow { // Git stash loses metadata about a possible merge mode // Manually check and backup if necessary - if (await this.checkGitConfigFile(MERGE_HEAD)) { + if (await checkFile(this.mergeHeadFile)) { debug('Detected current merge mode!') debug('Backing up merge state...') await Promise.all([ - this.readGitConfigFile(MERGE_HEAD).then(mergeHead => (this.mergeHead = mergeHead)), - this.readGitConfigFile(MERGE_MODE).then(mergeMode => (this.mergeMode = mergeMode)), - this.readGitConfigFile(MERGE_MSG).then(mergeMsg => (this.mergeMsg = mergeMsg)) + readBufferFromFile(this.mergeHeadFile).then( + mergeHead => (this.mergeHeadBuffer = mergeHead) + ), + readBufferFromFile(this.mergeModeFile).then( + mergeMode => (this.mergeModeBuffer = mergeMode) + ), + readBufferFromFile(this.mergeMsgFile).then(mergeMsg => (this.mergeMsgBuffer = mergeMsg)) ]) debug('Done backing up merge state!') } @@ -163,13 +135,13 @@ class GitWorkflow { await this.execGit(['stash', 'drop', '--quiet', original]) debug('Done dropping backup stash!') - if (this.mergeHead) { + if (this.mergeHeadBuffer) { debug('Detected backup merge state!') debug('Restoring merge state...') await Promise.all([ - this.writeGitConfigFile(MERGE_HEAD, this.mergeHead), - this.writeGitConfigFile(MERGE_MODE, this.mergeMode), - this.writeGitConfigFile(MERGE_MSG, this.mergeMsg) + writeBufferToFile(this.mergeHeadFile, this.mergeHeadBuffer), + writeBufferToFile(this.mergeModeFile, this.mergeModeBuffer), + writeBufferToFile(this.mergeMsgFile, this.mergeMsgBuffer) ]) debug('Done restoring merge state!') } From 09e6edfa71d618f1426973f48648038867032e91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Fri, 13 Sep 2019 09:31:33 +0300 Subject: [PATCH 19/64] test: scope global jest timeout to only runAll.unmocked.spec --- test/runAll.unmocked.spec.js | 2 ++ testSetup.js | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index a5e455eb2..b4483be98 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -9,6 +9,8 @@ import runAll from '../src/runAll' tmp.setGracefulCleanup() jest.unmock('execa') +jest.setTimeout(10000) + const testJsFilePretty = `module.exports = { foo: "bar" }; diff --git a/testSetup.js b/testSetup.js index 32cc1e7a6..73b97afdb 100644 --- a/testSetup.js +++ b/testSetup.js @@ -2,6 +2,3 @@ // Overwrite TTY mode to always render without ansi codes process.stdout.isTTY = false - -// Increase timeout for slow CI runners -jest.setTimeout(10000) From 1b9e85a0ea9b2a16eed49623df6d71c1de43ff21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Fri, 13 Sep 2019 09:43:05 +0300 Subject: [PATCH 20/64] test: remove non-functioning, throwing tests --- test/runAll.spec.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/test/runAll.spec.js b/test/runAll.spec.js index ac47ecdbc..3e92e5507 100644 --- a/test/runAll.spec.js +++ b/test/runAll.spec.js @@ -28,14 +28,6 @@ describe('runAll', () => { console = globalConsoleTemp }) - it('should not throw when a valid config is provided', () => { - expect(() => runAll({})).not.toThrow() - }) - - it('should return a promise', () => { - expect(runAll({})).toBeInstanceOf(Promise) - }) - it('should resolve the promise with no tasks', async () => { const res = await runAll({ config: {} }) expect(res).toEqual('No tasks to run.') From 49659efb6205e817688e32cb1f74b631a8cd5380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Fri, 13 Sep 2019 09:55:05 +0300 Subject: [PATCH 21/64] refactor: rename src/ to lib/ since it's not compiled --- bin/lint-staged | 2 +- {src => lib}/execGit.js | 0 {src => lib}/file.js | 0 {src => lib}/generateTasks.js | 0 {src => lib}/getStagedFiles.js | 0 {src => lib}/gitWorkflow.js | 0 {src => lib}/index.js | 0 {src => lib}/makeCmdTasks.js | 0 {src => lib}/printErrors.js | 0 {src => lib}/resolveGitDir.js | 0 {src => lib}/resolveTaskFn.js | 0 {src => lib}/runAll.js | 0 {src => lib}/validateConfig.js | 0 package.json | 8 ++++---- test/execGit.spec.js | 2 +- test/generateTasks.spec.js | 6 +++--- test/getStagedFiles.spec.js | 6 +++--- test/index.spec.js | 8 ++++---- test/index2.spec.js | 2 +- test/makeCmdTasks.spec.js | 2 +- test/printErrors.spec.js | 2 +- test/resolveGitDir.spec.js | 2 +- test/resolveTaskFn.spec.js | 2 +- test/resolveTaskFn.unmocked.spec.js | 2 +- test/runAll.spec.js | 12 ++++++------ test/runAll.unmocked.spec.js | 4 ++-- test/validateConfig.spec.js | 2 +- wallaby.js | 4 ++-- 28 files changed, 33 insertions(+), 33 deletions(-) rename {src => lib}/execGit.js (100%) rename {src => lib}/file.js (100%) rename {src => lib}/generateTasks.js (100%) rename {src => lib}/getStagedFiles.js (100%) rename {src => lib}/gitWorkflow.js (100%) rename {src => lib}/index.js (100%) rename {src => lib}/makeCmdTasks.js (100%) rename {src => lib}/printErrors.js (100%) rename {src => lib}/resolveGitDir.js (100%) rename {src => lib}/resolveTaskFn.js (100%) rename {src => lib}/runAll.js (100%) rename {src => lib}/validateConfig.js (100%) diff --git a/bin/lint-staged b/bin/lint-staged index 2f26eee17..277f1b681 100755 --- a/bin/lint-staged +++ b/bin/lint-staged @@ -23,7 +23,7 @@ require('please-upgrade-node')( const cmdline = require('commander') const debugLib = require('debug') -const lintStaged = require('../src') +const lintStaged = require('../lib') const debug = debugLib('lint-staged:bin') diff --git a/src/execGit.js b/lib/execGit.js similarity index 100% rename from src/execGit.js rename to lib/execGit.js diff --git a/src/file.js b/lib/file.js similarity index 100% rename from src/file.js rename to lib/file.js diff --git a/src/generateTasks.js b/lib/generateTasks.js similarity index 100% rename from src/generateTasks.js rename to lib/generateTasks.js diff --git a/src/getStagedFiles.js b/lib/getStagedFiles.js similarity index 100% rename from src/getStagedFiles.js rename to lib/getStagedFiles.js diff --git a/src/gitWorkflow.js b/lib/gitWorkflow.js similarity index 100% rename from src/gitWorkflow.js rename to lib/gitWorkflow.js diff --git a/src/index.js b/lib/index.js similarity index 100% rename from src/index.js rename to lib/index.js diff --git a/src/makeCmdTasks.js b/lib/makeCmdTasks.js similarity index 100% rename from src/makeCmdTasks.js rename to lib/makeCmdTasks.js diff --git a/src/printErrors.js b/lib/printErrors.js similarity index 100% rename from src/printErrors.js rename to lib/printErrors.js diff --git a/src/resolveGitDir.js b/lib/resolveGitDir.js similarity index 100% rename from src/resolveGitDir.js rename to lib/resolveGitDir.js diff --git a/src/resolveTaskFn.js b/lib/resolveTaskFn.js similarity index 100% rename from src/resolveTaskFn.js rename to lib/resolveTaskFn.js diff --git a/src/runAll.js b/lib/runAll.js similarity index 100% rename from src/runAll.js rename to lib/runAll.js diff --git a/src/validateConfig.js b/lib/validateConfig.js similarity index 100% rename from src/validateConfig.js rename to lib/validateConfig.js diff --git a/package.json b/package.json index 465619557..78e5927d9 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,11 @@ "Suhas Karanth ", "Iiro Jäppinen (https://iiro.fi)" ], - "main": "./src/index.js", "bin": "./bin/lint-staged", + "main": "./lib/index.js", "files": [ - "src", - "bin" + "bin", + "lib" ], "scripts": { "cz": "git-cz", @@ -79,7 +79,7 @@ "jest": { "collectCoverage": true, "collectCoverageFrom": [ - "src/**/*.js" + "lib/**/*.js" ], "setupFiles": [ "./testSetup.js" diff --git a/test/execGit.spec.js b/test/execGit.spec.js index f8e5ef909..d06ec5d8b 100644 --- a/test/execGit.spec.js +++ b/test/execGit.spec.js @@ -1,6 +1,6 @@ import path from 'path' import execa from 'execa' -import execGit from '../src/execGit' +import execGit from '../lib/execGit' describe('execGit', () => { it('should execute git in process.cwd if working copy is not specified', async () => { diff --git a/test/generateTasks.spec.js b/test/generateTasks.spec.js index 8a73f44f9..6a6d5c744 100644 --- a/test/generateTasks.spec.js +++ b/test/generateTasks.spec.js @@ -2,8 +2,8 @@ import os from 'os' import normalize from 'normalize-path' import path from 'path' -import generateTasks from '../src/generateTasks' -import resolveGitDir from '../src/resolveGitDir' +import generateTasks from '../lib/generateTasks' +import resolveGitDir from '../lib/resolveGitDir' const normalizePath = path => normalize(path) @@ -28,7 +28,7 @@ const files = [ ] // Mocks get hoisted -jest.mock('../src/resolveGitDir.js') +jest.mock('../lib/resolveGitDir.js') const gitDir = path.join(os.tmpdir(), 'tmp-lint-staged') resolveGitDir.mockResolvedValue(gitDir) const cwd = gitDir diff --git a/test/getStagedFiles.spec.js b/test/getStagedFiles.spec.js index 3ced4734a..07bc7aa50 100644 --- a/test/getStagedFiles.spec.js +++ b/test/getStagedFiles.spec.js @@ -1,7 +1,7 @@ -import getStagedFiles from '../src/getStagedFiles' -import execGit from '../src/execGit' +import getStagedFiles from '../lib/getStagedFiles' +import execGit from '../lib/execGit' -jest.mock('../src/execGit') +jest.mock('../lib/execGit') describe('getStagedFiles', () => { it('should return array of file names', async () => { diff --git a/test/index.spec.js b/test/index.spec.js index 880c1b9a6..1cab890e0 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -5,11 +5,11 @@ import path from 'path' jest.unmock('execa') // eslint-disable-next-line import/first -import getStagedFiles from '../src/getStagedFiles' +import getStagedFiles from '../lib/getStagedFiles' // eslint-disable-next-line import/first -import lintStaged from '../src/index' +import lintStaged from '../lib/index' -jest.mock('../src/getStagedFiles') +jest.mock('../lib/getStagedFiles') const replaceSerializer = (from, to) => ({ test: val => typeof val === 'string' && from.test(val), @@ -22,7 +22,7 @@ const mockCosmiconfigWith = result => { })) } -jest.mock('../src/gitWorkflow') +jest.mock('../lib/gitWorkflow') async function withMockedConsole(mockConsole, fn) { const previousConsole = console diff --git a/test/index2.spec.js b/test/index2.spec.js index 1cff7330b..6c7bb751c 100644 --- a/test/index2.spec.js +++ b/test/index2.spec.js @@ -8,7 +8,7 @@ console.error = jest.fn(() => {}) jest.mock('listr') // eslint-disable-next-line import/first -import lintStaged from '../src/index' +import lintStaged from '../lib/index' describe('lintStaged', () => { afterEach(() => { diff --git a/test/makeCmdTasks.spec.js b/test/makeCmdTasks.spec.js index 9caf1893e..f1121b256 100644 --- a/test/makeCmdTasks.spec.js +++ b/test/makeCmdTasks.spec.js @@ -1,5 +1,5 @@ import execa from 'execa' -import makeCmdTasks from '../src/makeCmdTasks' +import makeCmdTasks from '../lib/makeCmdTasks' describe('makeCmdTasks', () => { const gitDir = process.cwd() diff --git a/test/printErrors.spec.js b/test/printErrors.spec.js index 5c05b427e..9dd0e3cb7 100644 --- a/test/printErrors.spec.js +++ b/test/printErrors.spec.js @@ -1,6 +1,6 @@ import Listr from 'listr' import makeConsoleMock from 'consolemock' -import printErrors from '../src/printErrors' +import printErrors from '../lib/printErrors' describe('printErrors', () => { const logger = makeConsoleMock() diff --git a/test/resolveGitDir.spec.js b/test/resolveGitDir.spec.js index ff2591e0a..ad09654c2 100644 --- a/test/resolveGitDir.spec.js +++ b/test/resolveGitDir.spec.js @@ -1,7 +1,7 @@ import normalize from 'normalize-path' import path from 'path' -import resolveGitDir from '../src/resolveGitDir' +import resolveGitDir from '../lib/resolveGitDir' /** * resolveGitDir runs execa, so the mock needs to be disabled for these tests diff --git a/test/resolveTaskFn.spec.js b/test/resolveTaskFn.spec.js index 7ad1a890b..11f482709 100644 --- a/test/resolveTaskFn.spec.js +++ b/test/resolveTaskFn.spec.js @@ -1,5 +1,5 @@ import execa from 'execa' -import resolveTaskFn from '../src/resolveTaskFn' +import resolveTaskFn from '../lib/resolveTaskFn' const defaultOpts = { files: ['test.js'] } diff --git a/test/resolveTaskFn.unmocked.spec.js b/test/resolveTaskFn.unmocked.spec.js index a368fb704..e41589ba8 100644 --- a/test/resolveTaskFn.unmocked.spec.js +++ b/test/resolveTaskFn.unmocked.spec.js @@ -1,4 +1,4 @@ -import resolveTaskFn from '../src/resolveTaskFn' +import resolveTaskFn from '../lib/resolveTaskFn' jest.unmock('execa') diff --git a/test/runAll.spec.js b/test/runAll.spec.js index 3e92e5507..c72939970 100644 --- a/test/runAll.spec.js +++ b/test/runAll.spec.js @@ -2,13 +2,13 @@ import makeConsoleMock from 'consolemock' import execa from 'execa' import normalize from 'normalize-path' -import resolveGitDir from '../src/resolveGitDir' -import getStagedFiles from '../src/getStagedFiles' -import runAll from '../src/runAll' +import resolveGitDir from '../lib/resolveGitDir' +import getStagedFiles from '../lib/getStagedFiles' +import runAll from '../lib/runAll' -jest.mock('../src/resolveGitDir') -jest.mock('../src/getStagedFiles') -jest.mock('../src/gitWorkflow') +jest.mock('../lib/resolveGitDir') +jest.mock('../lib/getStagedFiles') +jest.mock('../lib/gitWorkflow') resolveGitDir.mockImplementation(async () => normalize(process.cwd())) getStagedFiles.mockImplementation(async () => []) diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index b4483be98..3f0da9bc6 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -3,8 +3,8 @@ import normalize from 'normalize-path' import path from 'path' import tmp from 'tmp' -import execGitBase from '../src/execGit' -import runAll from '../src/runAll' +import execGitBase from '../lib/execGit' +import runAll from '../lib/runAll' tmp.setGracefulCleanup() jest.unmock('execa') diff --git a/test/validateConfig.spec.js b/test/validateConfig.spec.js index c1949ea27..eeb6f9365 100644 --- a/test/validateConfig.spec.js +++ b/test/validateConfig.spec.js @@ -1,6 +1,6 @@ import makeConsoleMock from 'consolemock' -import validateConfig from '../src/validateConfig' +import validateConfig from '../lib/validateConfig' describe('validateConfig', () => { const originalConsole = global.console diff --git a/wallaby.js b/wallaby.js index 7ce61bfa8..e9d7ab013 100644 --- a/wallaby.js +++ b/wallaby.js @@ -3,8 +3,8 @@ module.exports = wallaby => ({ files: [ { pattern: 'test/__fixtures__/*', instrument: false }, - 'src/*.js', - 'src/__mocks__/*.js', + 'lib/*.js', + 'lib/__mocks__/*.js', '!test/*.spec.js' ], From 2b4764305b7ccf7e50b1e11313719d6353d04ce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Fri, 13 Sep 2019 11:03:08 +0300 Subject: [PATCH 22/64] refactor: improve long argument warning indentation --- lib/runAll.js | 15 +++++++-------- test/__snapshots__/runAll.spec.js.snap | 8 +++++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/runAll.js b/lib/runAll.js index 580e11928..d7c5fe1c2 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -3,7 +3,6 @@ /** @typedef {import('./index').Logger} Logger */ const chalk = require('chalk') -const dedent = require('dedent') const Listr = require('listr') const symbols = require('log-symbols') @@ -60,13 +59,13 @@ module.exports = async function runAll( const argLength = files.join(' ').length if (argLength > MAX_ARG_LENGTH) { - logger.warn( - dedent`${symbols.warning} ${chalk.yellow( - `lint-staged generated an argument string of ${argLength} characters, and commands might not run correctly on your platform. -It is recommended to use functions as linters and split your command based on the number of staged files. For more info, please visit: -https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-commands` - )}` - ) + logger.warn(` + ${symbols.warning} ${chalk.yellow( + `lint-staged generated an argument string of ${argLength} characters, and commands might not run correctly on your platform. + It is recommended to use functions as linters and split your command based on the number of staged files. For more info, please visit: + https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-commands` + )} +`) } const tasks = generateTasks({ config, cwd, gitDir, files, relative }).map(task => ({ diff --git a/test/__snapshots__/runAll.spec.js.snap b/test/__snapshots__/runAll.spec.js.snap index a5f364a3d..bbf2818ec 100644 --- a/test/__snapshots__/runAll.spec.js.snap +++ b/test/__snapshots__/runAll.spec.js.snap @@ -90,9 +90,11 @@ LOG No staged files match any of provided globs." exports[`runAll should warn if the argument length is longer than what the platform can handle 1`] = ` " -WARN ‼ lint-staged generated an argument string of 999999 characters, and commands might not run correctly on your platform. -It is recommended to use functions as linters and split your command based on the number of staged files. For more info, please visit: -https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-commands +WARN + ‼ lint-staged generated an argument string of 999999 characters, and commands might not run correctly on your platform. + It is recommended to use functions as linters and split your command based on the number of staged files. For more info, please visit: + https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-commands + LOG Preparing... [started] LOG Preparing... [completed] LOG Running tasks... [started] From 74fe356eed1a57b736f48b25b56b556717b482af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Fri, 13 Sep 2019 11:12:17 +0300 Subject: [PATCH 23/64] refactor: show helpful warning about git failures --- lib/execGit.js | 14 ++-- lib/runAll.js | 69 ++++++++++-------- test/runAll.unmocked.spec.js | 131 ++++++++++++++++++----------------- 3 files changed, 118 insertions(+), 96 deletions(-) diff --git a/lib/execGit.js b/lib/execGit.js index 557fb7d97..e9194a1b1 100644 --- a/lib/execGit.js +++ b/lib/execGit.js @@ -5,9 +5,13 @@ const execa = require('execa') module.exports = async function execGit(cmd, options = {}) { debug('Running git command', cmd) - const { stdout } = await execa('git', [].concat(cmd), { - ...options, - cwd: options.cwd || process.cwd() - }) - return stdout + try { + const { stdout } = await execa('git', [].concat(cmd), { + ...options, + cwd: options.cwd || process.cwd() + }) + return stdout + } catch ({ all }) { + throw new Error(all) + } } diff --git a/lib/runAll.js b/lib/runAll.js index d7c5fe1c2..05875a875 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -103,31 +103,46 @@ module.exports = async function runAll( const git = new GitWorkflow(gitDir) - return new Listr( - [ - { - title: 'Preparing...', - task: () => git.stashBackup() - }, - { - title: 'Running tasks...', - task: () => new Listr(tasks, { ...listrOptions, concurrent: true, exitOnError: false }) - }, - { - title: 'Applying unstaged changes...', - skip: ctx => ctx.hasErrors && 'Skipped because of errors from tasks', - task: () => git.restoreUnstagedChanges() - }, - { - title: 'Restoring original state due to errors...', - enabled: ctx => ctx.hasErrors, - task: () => git.restoreOriginalState() - }, - { - title: 'Cleaning up...', - task: () => git.dropBackup() - } - ], - listrOptions - ).run() + try { + await new Listr( + [ + { + title: 'Preparing...', + task: () => git.stashBackup() + }, + { + title: 'Running tasks...', + task: () => new Listr(tasks, { ...listrOptions, concurrent: true, exitOnError: false }) + }, + { + title: 'Applying unstaged changes...', + skip: ctx => ctx.hasErrors && 'Skipped because of errors from tasks', + task: () => git.restoreUnstagedChanges() + }, + { + title: 'Restoring original state due to errors...', + enabled: ctx => ctx.hasErrors, + task: () => git.restoreOriginalState() + }, + { + title: 'Cleaning up...', + task: () => git.dropBackup() + } + ], + listrOptions + ).run() + } catch (error) { + if (error.message.includes('Another git process seems to be running in this repository')) { + logger.error(` + ${symbols.error} ${chalk.red(`lint-staged failed due to a git error. + Any lost modifications can be restored from a git stash: + + > git stash list + stash@{0}: On master: automatic lint-staged backup + > git stash pop stash@{0}`)} +`) + } + + throw error + } } diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 3f0da9bc6..bef71a0c9 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -53,13 +53,8 @@ const execGit = async args => execGitBase(args, { cwd }) // Execute runAll before git commit to emulate lint-staged const gitCommit = async (options, message = 'test') => { - try { - await runAll({ ...options, cwd, quiet: true }) - await execGit(['commit', `-m "${message}"`]) - return true - } catch (error) { - return false - } + await runAll({ ...options, cwd, quiet: true }) + await execGit(['commit', `-m "${message}"`]) } const fixJsConfig = { config: { '*.js': ['prettier --write', 'git add'] } } @@ -100,8 +95,7 @@ describe('runAll', () => { await execGit(['add', 'test.js']) // Run lint-staged with `prettier --list-different` and commit pretty file - const success = await gitCommit({ config: { '*.js': 'prettier --list-different' } }) - expect(success).toEqual(true) + await gitCommit({ config: { '*.js': 'prettier --list-different' } }) // Nothing is wrong, so a new commit is created expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') @@ -115,8 +109,7 @@ describe('runAll', () => { await execGit(['add', 'test.js']) // Run lint-staged with `prettier --write` and commit pretty file - const success = await gitCommit(fixJsConfig) - expect(success).toEqual(true) + await gitCommit(fixJsConfig) // Nothing is wrong, so a new commit is created and file is pretty expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') @@ -131,8 +124,11 @@ describe('runAll', () => { const status = await execGit(['status']) // Run lint-staged with `prettier --list-different` to break the linter - const success = await gitCommit({ config: { '*.js': 'prettier --list-different' } }) - expect(success).toEqual(false) + try { + await gitCommit({ config: { '*.js': 'prettier --list-different' } }) + } catch (error) { + expect(error.message).toMatchInlineSnapshot(`"Something went wrong"`) + } // Something was wrong so the repo is returned to original state expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') @@ -148,8 +144,11 @@ describe('runAll', () => { const status = await execGit(['status']) // Run lint-staged with `prettier --write` to break the linter - const success = await gitCommit(fixJsConfig) - expect(success).toEqual(false) + try { + await gitCommit(fixJsConfig) + } catch (error) { + expect(error.message).toMatchInlineSnapshot(`"Something went wrong"`) + } // Something was wrong so the repo is returned to original state expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') @@ -168,8 +167,7 @@ describe('runAll', () => { await appendFile('test.js', appended) // Run lint-staged with `prettier --list-different` and commit pretty file - const success = await gitCommit({ config: { '*.js': 'prettier --list-different' } }) - expect(success).toEqual(true) + await gitCommit({ config: { '*.js': 'prettier --list-different' } }) // Nothing is wrong, so a new commit is created and file is pretty expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') @@ -196,8 +194,7 @@ describe('runAll', () => { await appendFile('test.js', appended) // Run lint-staged with `prettier --write` and commit pretty file - const success = await gitCommit(fixJsConfig) - expect(success).toEqual(true) + await gitCommit(fixJsConfig) // Nothing is wrong, so a new commit is created and file is pretty expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') @@ -227,8 +224,11 @@ describe('runAll', () => { const status = await execGit(['status']) // Run lint-staged with `prettier --list-different` to break the linter - const success = await gitCommit({ config: { '*.js': 'prettier --list-different' } }) - expect(success).toEqual(false) + try { + await gitCommit({ config: { '*.js': 'prettier --list-different' } }) + } catch (error) { + expect(error.message).toMatchInlineSnapshot(`"Something went wrong"`) + } // Something was wrong so the repo is returned to original state expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') @@ -248,8 +248,11 @@ describe('runAll', () => { const status = await execGit(['status']) // Run lint-staged with `prettier --write` to break the linter - const success = await gitCommit(fixJsConfig) - expect(success).toEqual(false) + try { + await gitCommit(fixJsConfig) + } catch (error) { + expect(error.message).toMatchInlineSnapshot(`"Something went wrong"`) + } // Something was wrong so the repo is returned to original state expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') @@ -268,8 +271,7 @@ describe('runAll', () => { await appendFile('test.js', testJsFilePretty) // Run lint-staged with `prettier --write` and commit pretty file - const success = await gitCommit(fixJsConfig) - expect(success).toEqual(true) + await gitCommit(fixJsConfig) // Nothing is wrong, so a new commit is created and file is pretty expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') @@ -299,16 +301,19 @@ describe('runAll', () => { // Run lint-staged with `prettier --write` and commit pretty file // The task creates a git lock file to simulate failure - const success = await gitCommit({ - config: { - '*.js': files => [ - `touch ${cwd}/.git/index.lock`, - `prettier --write ${files.join(' ')}`, - `git add ${files.join(' ')}` - ] - } - }) - expect(success).toEqual(false) + try { + await gitCommit({ + config: { + '*.js': files => [ + `touch ${cwd}/.git/index.lock`, + `prettier --write ${files.join(' ')}`, + `git add ${files.join(' ')}` + ] + } + }) + } catch (error) { + expect(error.message).toMatch('Another git process seems to be running in this repository') + } // Something was wrong so new commit wasn't created expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') @@ -317,17 +322,17 @@ describe('runAll', () => { // But local modifications are gone expect(await execGit(['diff'])).not.toEqual(diff) expect(await execGit(['diff'])).toMatchInlineSnapshot(` - "diff --git a/test.js b/test.js - index f80f875..1c5643c 100644 - --- a/test.js - +++ b/test.js - @@ -1,3 +1,3 @@ - module.exports = { - - 'foo': 'bar', - -} - + foo: \\"bar\\" - +};" - `) + "diff --git a/test.js b/test.js + index f80f875..1c5643c 100644 + --- a/test.js + +++ b/test.js + @@ -1,3 +1,3 @@ + module.exports = { + - 'foo': 'bar', + -} + + foo: \\"bar\\" + +};" + `) expect(await readFile('test.js')).not.toEqual(testJsFileUgly + appended) expect(await readFile('test.js')).toEqual(testJsFilePretty) @@ -355,8 +360,7 @@ describe('runAll', () => { await execGit(['checkout', '-b', 'branch-a']) await appendFile('test.js', fileInBranchA) await execGit(['add', '.']) - const successA = await gitCommit(fixJsConfig, 'commit a') - expect(successA).toEqual(true) + await gitCommit(fixJsConfig, 'commit a') expect(await readFile('test.js')).toEqual(fileInBranchA) await execGit(['checkout', 'master']) @@ -365,8 +369,7 @@ describe('runAll', () => { await execGit(['checkout', '-b', 'branch-b']) await appendFile('test.js', fileInBranchB) await execGit(['add', '.']) - const successB = await gitCommit(fixJsConfig, 'commit b') - expect(successB).toEqual(true) + await gitCommit(fixJsConfig, 'commit b') expect(await readFile('test.js')).toEqual(fileInBranchBFixed) // Merge first branch @@ -378,18 +381,18 @@ describe('runAll', () => { // Merge second branch, causing merge conflict try { await execGit(['merge', 'branch-b']) - } catch ({ stdout }) { - expect(stdout).toMatch('Merge conflict in test.js') + } catch (error) { + expect(error.message).toMatch('Merge conflict in test.js') } expect(await readFile('test.js')).toMatchInlineSnapshot(` - "<<<<<<< HEAD - module.exports = \\"foo\\"; - ======= - module.exports = \\"bar\\"; - >>>>>>> branch-b - " - `) + "<<<<<<< HEAD + module.exports = \\"foo\\"; + ======= + module.exports = \\"bar\\"; + >>>>>>> branch-b + " + `) // Fix conflict and commit using lint-staged await writeFile('test.js', fileInBranchB) @@ -403,12 +406,12 @@ describe('runAll', () => { // Nothing is wrong, so a new commit is created and file is pretty expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('4') expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` - "Merge branch 'branch-b' + "Merge branch 'branch-b' - # Conflicts: - # test.js - " - `) + # Conflicts: + # test.js + " + `) expect(await readFile('test.js')).toEqual(fileInBranchBFixed) }) }) From 761f984b89d3003743d99ce98975271fb72b5713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Fri, 13 Sep 2019 11:30:05 +0300 Subject: [PATCH 24/64] test: do not use tmp for creation of tmp directories --- package.json | 2 +- test/runAll.unmocked.spec.js | 49 +++++++++++++++++++++++------------- yarn.lock | 12 ++++----- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 78e5927d9..e3a6a8d27 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "jest-snapshot-serializer-ansi": "^1.0.0", "jsonlint": "^1.6.3", "prettier": "1.18.2", - "tmp": "0.1.0" + "uuid": "^3.3.3" }, "config": { "commitizen": { diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index bef71a0c9..b861505d3 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -1,12 +1,12 @@ import fs from 'fs-extra' import normalize from 'normalize-path' +import os from 'os' import path from 'path' -import tmp from 'tmp' +import uuid from 'uuid' import execGitBase from '../lib/execGit' import runAll from '../lib/runAll' -tmp.setGracefulCleanup() jest.unmock('execa') jest.setTimeout(10000) @@ -25,15 +25,31 @@ const testJsFileUnfixable = `const obj = { 'foo': 'bar' ` -// Create temporary directory by wrapping `tmp` in a Promise -const createTempDir = () => - new Promise((resolve, reject) => { - tmp.dir({ keep: true, unsafeCleanup: true }, (error, name, cleanupCallback) => { - if (error) reject(error) - resolve({ name, cleanupCallback }) - }) - }) +const fixJsConfig = { config: { '*.js': ['prettier --write', 'git add'] } } + +const isAppveyor = !!process.env.APPVEYOR +const osTmpDir = isAppveyor ? 'C:\\projects' : fs.realpathSync(os.tmpdir()) + +/** + * Create temporary directory and return its path + * @returns {Promise} + */ +const createTempDir = async () => { + const dirname = path.resolve(osTmpDir, 'lint-staged-test', uuid()) + await fs.ensureDir(dirname) + return dirname +} + +/** + * Remove temporary directory + * @param {String} dirname + * @returns {Promise} + */ +const removeTempDir = async dirname => { + await fs.remove(dirname) +} +let tmpDir let cwd // Get file content @@ -57,25 +73,20 @@ const gitCommit = async (options, message = 'test') => { await execGit(['commit', `-m "${message}"`]) } -const fixJsConfig = { config: { '*.js': ['prettier --write', 'git add'] } } - describe('runAll', () => { it('should throw when not in a git directory', async () => { const nonGitDir = await createTempDir() await expect(runAll({ cwd: nonGitDir })).rejects.toThrowErrorMatchingInlineSnapshot( `"Current directory is not a git directory!"` ) - nonGitDir.cleanupCallback() + await removeTempDir(nonGitDir) }) }) describe('runAll', () => { - let tmpDir - beforeEach(async () => { tmpDir = await createTempDir() - cwd = normalize(await fs.realpath(tmpDir.name)) - + cwd = normalize(tmpDir) // Init repository with initial commit await execGit('init') await execGit(['config', 'user.name', '"test"']) @@ -86,7 +97,9 @@ describe('runAll', () => { }) afterEach(async () => { - await tmpDir.cleanupCallback() + if (!isAppveyor) { + await removeTempDir(tmpDir) + } }) it('Should commit entire staged file when no errors from linter', async () => { diff --git a/yarn.lock b/yarn.lock index 23cac436e..16aff1e93 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5649,13 +5649,6 @@ timers-ext@^0.1.5: es5-ext "~0.10.46" next-tick "1" -tmp@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" - integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== - dependencies: - rimraf "^2.6.3" - tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -5861,6 +5854,11 @@ uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== +uuid@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" + integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== + v8-compile-cache@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" From d8f7f1da864c573aefe407f198dddbb01268e337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Fri, 13 Sep 2019 13:40:27 +0300 Subject: [PATCH 25/64] test: add mock console --- test/runAll.unmocked.spec.js | 69 ++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index b861505d3..611d3fc0f 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -1,4 +1,5 @@ import fs from 'fs-extra' +import makeConsoleMock from 'consolemock' import normalize from 'normalize-path' import os from 'os' import path from 'path' @@ -83,7 +84,13 @@ describe('runAll', () => { }) }) +const globalConsoleTemp = console + describe('runAll', () => { + beforeAll(() => { + console = makeConsoleMock() + }) + beforeEach(async () => { tmpDir = await createTempDir() cwd = normalize(tmpDir) @@ -97,11 +104,16 @@ describe('runAll', () => { }) afterEach(async () => { + console.clearHistory() if (!isAppveyor) { await removeTempDir(tmpDir) } }) + afterAll(() => { + console = globalConsoleTemp + }) + it('Should commit entire staged file when no errors from linter', async () => { // Stage pretty file await appendFile('test.js', testJsFilePretty) @@ -326,6 +338,17 @@ describe('runAll', () => { }) } catch (error) { expect(error.message).toMatch('Another git process seems to be running in this repository') + expect(console.printHistory()).toMatchInlineSnapshot(` + " + ERROR + × lint-staged failed due to a git error. + Any lost modifications can be restored from a git stash: + + > git stash list + stash@{0}: On master: automatic lint-staged backup + > git stash pop stash@{0} + " + `) } // Something was wrong so new commit wasn't created @@ -335,17 +358,17 @@ describe('runAll', () => { // But local modifications are gone expect(await execGit(['diff'])).not.toEqual(diff) expect(await execGit(['diff'])).toMatchInlineSnapshot(` - "diff --git a/test.js b/test.js - index f80f875..1c5643c 100644 - --- a/test.js - +++ b/test.js - @@ -1,3 +1,3 @@ - module.exports = { - - 'foo': 'bar', - -} - + foo: \\"bar\\" - +};" - `) + "diff --git a/test.js b/test.js + index f80f875..1c5643c 100644 + --- a/test.js + +++ b/test.js + @@ -1,3 +1,3 @@ + module.exports = { + - 'foo': 'bar', + -} + + foo: \\"bar\\" + +};" + `) expect(await readFile('test.js')).not.toEqual(testJsFileUgly + appended) expect(await readFile('test.js')).toEqual(testJsFilePretty) @@ -399,13 +422,13 @@ describe('runAll', () => { } expect(await readFile('test.js')).toMatchInlineSnapshot(` - "<<<<<<< HEAD - module.exports = \\"foo\\"; - ======= - module.exports = \\"bar\\"; - >>>>>>> branch-b - " - `) + "<<<<<<< HEAD + module.exports = \\"foo\\"; + ======= + module.exports = \\"bar\\"; + >>>>>>> branch-b + " + `) // Fix conflict and commit using lint-staged await writeFile('test.js', fileInBranchB) @@ -419,12 +442,12 @@ describe('runAll', () => { // Nothing is wrong, so a new commit is created and file is pretty expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('4') expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` - "Merge branch 'branch-b' + "Merge branch 'branch-b' - # Conflicts: - # test.js - " - `) + # Conflicts: + # test.js + " + `) expect(await readFile('test.js')).toEqual(fileInBranchBFixed) }) }) From 90da8a88271f7251de17e652c0e9be36024465e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Fri, 13 Sep 2019 14:19:59 +0300 Subject: [PATCH 26/64] test: further increase timeout for long test --- test/runAll.unmocked.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 611d3fc0f..c3794e51d 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -10,7 +10,7 @@ import runAll from '../lib/runAll' jest.unmock('execa') -jest.setTimeout(10000) +jest.setTimeout(20000) const testJsFilePretty = `module.exports = { foo: "bar" From fc03fdc2e869384eb2d6423ff31f84e3cf22007e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sun, 15 Sep 2019 09:12:29 +0300 Subject: [PATCH 27/64] fix: keep untracked files around by backing them up Git diff completely ignores new, untracked files, but they can be read/written separately --- lib/gitWorkflow.js | 36 ++++++++++++++++++++++++++++++++++++ test/runAll.unmocked.spec.js | 19 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index cf0518e84..b6d5af1d9 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -1,6 +1,7 @@ 'use strict' const debug = require('debug')('lint-staged:git') +const normalize = require('normalize-path') const path = require('path') const execGit = require('./execGit') @@ -68,6 +69,31 @@ class GitWorkflow { debug('Done backing up merge state!') } + // Git stash ignores new, untracked files, so back them up separately + // Use `git ls-files` to list untracked files: + // `--others includes` all untracked files, including ignored files + // `--exclude-standard` excludes ignored files, the .git/ dir and so on... + let untrackedFiles = await this.execGit(['ls-files', '--others', '--exclude-standard']) + if (untrackedFiles) { + debug('Detected untracked files:') + debug(untrackedFiles) + debug('Backing up untracked files...') + // Resolve untrackedFiles output into filenames + untrackedFiles = untrackedFiles + .split('\n') + .map(file => normalize(path.resolve(this.cwd, file))) + this.untrackedFiles = new Map() + const readPromises = [] + for (const file of untrackedFiles) { + // Read all untracked files into buffers, and save them into internal Map + readPromises.push( + readBufferFromFile(file).then(buffer => this.untrackedFiles.set(file, buffer)) + ) + } + await Promise.all(readPromises) + debug('Done backing up untracked files!') + } + // Get stash of entire original state, including unstaged changes // Keep index so that tasks only work on those files await this.execGit(['stash', 'save', '--quiet', '--include-untracked', '--keep-index', STASH]) @@ -107,6 +133,16 @@ class GitWorkflow { } } debug('Done restoring unstaged changes!') + + if (this.untrackedFiles) { + debug('Restoring untracked files...') + const writePromises = [] + this.untrackedFiles.forEach((buffer, file) => { + writePromises.push(writeBufferToFile(file, buffer)) + }) + await Promise.all(writePromises) + debug('Done restoring untracked files!') + } } /** diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index c3794e51d..3e9e9be47 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -450,4 +450,23 @@ describe('runAll', () => { `) expect(await readFile('test.js')).toEqual(fileInBranchBFixed) }) + + it('should keep untracked files', async () => { + // Stage pretty file + await appendFile('test.js', testJsFilePretty) + await execGit(['add', 'test.js']) + + // Add another file, but keep it untracked + await appendFile('test-untracked.js', testJsFilePretty) + + // Run lint-staged with `prettier --list-different` and commit pretty file + await gitCommit({ config: { '*.js': 'prettier --list-different' } }) + + // Nothing is wrong, so a new commit is created + expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('test') + expect(await readFile('test.js')).toEqual(testJsFilePretty) + expect(await readFile('test-untracked.js')).toEqual(testJsFilePretty) + console = makeConsoleMock() + }) }) From 6fa9c85d1d03c8a9b4b3dea8be8f3857798c82c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20Ja=CC=88ppinen?= Date: Thu, 26 Sep 2019 14:48:06 +0300 Subject: [PATCH 28/64] refactor: improvements based on PR review --- lib/gitWorkflow.js | 50 ++++++++++++++++---------- lib/runAll.js | 4 +-- package.json | 4 +-- test/__snapshots__/runAll.spec.js.snap | 24 ++++++------- test/runAll.unmocked.spec.js | 5 ++- yarn.lock | 10 +++--- 6 files changed, 54 insertions(+), 43 deletions(-) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index b6d5af1d9..66e6c3072 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -44,7 +44,7 @@ class GitWorkflow { /** * Create backup stashes, one of everything and one of only staged changes - * Leves stages files in index for running tasks + * Staged files are left in the index for running tasks * * @param {Object} [options] * @returns {Promise} @@ -83,14 +83,11 @@ class GitWorkflow { .split('\n') .map(file => normalize(path.resolve(this.cwd, file))) this.untrackedFiles = new Map() - const readPromises = [] - for (const file of untrackedFiles) { - // Read all untracked files into buffers, and save them into internal Map - readPromises.push( + await Promise.all( + untrackedFiles.map(file => readBufferFromFile(file).then(buffer => this.untrackedFiles.set(file, buffer)) ) - } - await Promise.all(readPromises) + ) debug('Done backing up untracked files!') } @@ -105,42 +102,57 @@ class GitWorkflow { '--unified=0', '--no-color', '--no-ext-diff', - '-p', + '--patch', original, - '-R' + '-R' // Show diff in reverse ]) debug('Done backing up original state!') } /** - * Resets everything and applies back unstaged and staged changes, - * possibly with modifications by tasks + * Applies back unstaged changes that have been hidden in the stash. + * In case of a merge-conflict retry with 3-way merge. * * @param {Object} [options] * @returns {Promise} */ async restoreUnstagedChanges() { debug('Restoring unstaged changes...') + if (this.unstagedDiff) { try { await this.execGit(gitApplyArgs, { input: `${this.unstagedDiff}\n` }) } catch (error) { - debug('Error when restoring changes:') + debug('Error while restoring changes:') debug(error) debug('Retrying with 3-way merge') - // Retry with `--3way` if normal apply fails - await this.execGit([...gitApplyArgs, '--3way'], { input: `${this.unstagedDiff}\n` }) + + try { + // Retry with `--3way` if normal apply fails + await this.execGit([...gitApplyArgs, '--3way'], { input: `${this.unstagedDiff}\n` }) + } catch (error2) { + debug('Error while restoring unstaged changes using 3-way merge:') + debug(error2) + throw new Error('Unstaged changes could not be restored due to a merge conflict!') + } } } debug('Done restoring unstaged changes!') if (this.untrackedFiles) { debug('Restoring untracked files...') - const writePromises = [] - this.untrackedFiles.forEach((buffer, file) => { - writePromises.push(writeBufferToFile(file, buffer)) - }) - await Promise.all(writePromises) + try { + // Iterate over Map and await for all to complete + const writePromises = [] + this.untrackedFiles.forEach((buffer, file) => { + writePromises.push(writeBufferToFile(file, buffer)) + }) + await Promise.all(writePromises) + } catch (error) { + debug('Error while restoring untracked changes:') + debug(error) + throw new Error('Untracked changes could not be restored due to an error!') + } debug('Done restoring untracked files!') } } diff --git a/lib/runAll.js b/lib/runAll.js index 05875a875..acfcfb90c 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -115,12 +115,12 @@ module.exports = async function runAll( task: () => new Listr(tasks, { ...listrOptions, concurrent: true, exitOnError: false }) }, { - title: 'Applying unstaged changes...', + title: 'Restoring unstaged changes...', skip: ctx => ctx.hasErrors && 'Skipped because of errors from tasks', task: () => git.restoreUnstagedChanges() }, { - title: 'Restoring original state due to errors...', + title: 'Reverting to original state...', enabled: ctx => ctx.hasErrors, task: () => git.restoreOriginalState() }, diff --git a/package.json b/package.json index e3a6a8d27..d62b83aab 100644 --- a/package.json +++ b/package.json @@ -68,8 +68,8 @@ "jest": "^24.8.0", "jest-snapshot-serializer-ansi": "^1.0.0", "jsonlint": "^1.6.3", - "prettier": "1.18.2", - "uuid": "^3.3.3" + "nanoid": "^2.1.1", + "prettier": "1.18.2" }, "config": { "commitizen": { diff --git a/test/__snapshots__/runAll.spec.js.snap b/test/__snapshots__/runAll.spec.js.snap index bbf2818ec..65f538180 100644 --- a/test/__snapshots__/runAll.spec.js.snap +++ b/test/__snapshots__/runAll.spec.js.snap @@ -10,8 +10,8 @@ LOG echo \\"sample\\" [started] LOG echo \\"sample\\" [completed] LOG Running tasks for *.js [completed] LOG Running tasks... [completed] -LOG Applying unstaged changes... [started] -LOG Applying unstaged changes... [completed] +LOG Restoring unstaged changes... [started] +LOG Restoring unstaged changes... [completed] LOG Cleaning up... [started] LOG Cleaning up... [completed]" `; @@ -33,11 +33,11 @@ LOG → LOG Running tasks for *.js [failed] LOG → LOG Running tasks... [failed] -LOG Applying unstaged changes... [started] -LOG Applying unstaged changes... [skipped] +LOG Restoring unstaged changes... [started] +LOG Restoring unstaged changes... [skipped] LOG → Skipped because of errors from tasks -LOG Restoring original state due to errors... [started] -LOG Restoring original state due to errors... [completed] +LOG Reverting to original state... [started] +LOG Reverting to original state... [completed] LOG Cleaning up... [started] LOG Cleaning up... [completed] LOG { @@ -64,11 +64,11 @@ LOG → LOG Running tasks for *.js [failed] LOG → LOG Running tasks... [failed] -LOG Applying unstaged changes... [started] -LOG Applying unstaged changes... [skipped] +LOG Restoring unstaged changes... [started] +LOG Restoring unstaged changes... [skipped] LOG → Skipped because of errors from tasks -LOG Restoring original state due to errors... [started] -LOG Restoring original state due to errors... [completed] +LOG Reverting to original state... [started] +LOG Reverting to original state... [completed] LOG Cleaning up... [started] LOG Cleaning up... [completed] LOG { @@ -103,8 +103,8 @@ LOG echo \\"sample\\" [started] LOG echo \\"sample\\" [completed] LOG Running tasks for *.js [completed] LOG Running tasks... [completed] -LOG Applying unstaged changes... [started] -LOG Applying unstaged changes... [completed] +LOG Restoring unstaged changes... [started] +LOG Restoring unstaged changes... [completed] LOG Cleaning up... [started] LOG Cleaning up... [completed]" `; diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 3e9e9be47..0381d3ba3 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -3,7 +3,7 @@ import makeConsoleMock from 'consolemock' import normalize from 'normalize-path' import os from 'os' import path from 'path' -import uuid from 'uuid' +import nanoid from 'nanoid' import execGitBase from '../lib/execGit' import runAll from '../lib/runAll' @@ -36,7 +36,7 @@ const osTmpDir = isAppveyor ? 'C:\\projects' : fs.realpathSync(os.tmpdir()) * @returns {Promise} */ const createTempDir = async () => { - const dirname = path.resolve(osTmpDir, 'lint-staged-test', uuid()) + const dirname = path.resolve(osTmpDir, 'lint-staged-test', nanoid()) await fs.ensureDir(dirname) return dirname } @@ -467,6 +467,5 @@ describe('runAll', () => { expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('test') expect(await readFile('test.js')).toEqual(testJsFilePretty) expect(await readFile('test-untracked.js')).toEqual(testJsFilePretty) - console = makeConsoleMock() }) }) diff --git a/yarn.lock b/yarn.lock index 16aff1e93..69c9503ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4173,6 +4173,11 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== +nanoid@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.1.tgz#524fd4acd45c126e0c87cd43ab5ee8346e695df9" + integrity sha512-0YbJdaL4JFoejIOoawgLcYValFGJ2iyUuVDIWL3g8Es87SSOWFbWdRUMV3VMSiyPs3SQ3QxCIxFX00q5DLkMCw== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -5854,11 +5859,6 @@ uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== -uuid@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" - integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== - v8-compile-cache@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" From 9c33515ea43d178b75581166114a3e7aacc8f8fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Wed, 2 Oct 2019 05:52:31 +0300 Subject: [PATCH 29/64] docs: remove bit about next release --- README.md | 79 +++++++++++++++++++------------------------------------ 1 file changed, 27 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 4e53ac639..c30ed38f8 100644 --- a/README.md +++ b/README.md @@ -2,30 +2,6 @@ Run linters against staged git files and don't let :poop: slip into your code base! ---- - -## 🚧 Help test `lint-staged@next`! - -Version 10 of `lint-staged` is coming with changes that help it run faster on large git repositories and prevent loss of data during errors. Please help test the `next` version and report any inconsistencies in our [GitHub Issues](https://github.com/okonet/lint-staged/issues): - -**Using npm** - - npm install --save-dev lint-staged@next - -**Using yarn** - - yarn add -D lint-staged@next - -### Notable changes - -- A git stash is created before running any tasks, so in case of errors any lost changes can be restored easily (and automatically unless lint-staged itself crashes) -- Instead of write-tree/read-tree, `lint-staged@next` uses git stashes to hide unstaged changes while running tasks against staged files - - This results in a performance increase of up to 45x on very large repositories -- The behaviour of committing modifications during tasks (eg. `prettier --write && git add`) is different. The current version creates a diff of these modifications, and applies it against the original state, silently ignoring any errors. The `next` version leaves modifications of staged files as-is, and then restores all hidden unstaged changes as patch. If applying the patch fails due to a merge conflict (because tasks have modified the same lines), a 3-way merge will be retried. If this also fails, the entire commit will fail and the original state will be restored. - - **TL;DR** the `next` version will never skip committing any changes by tasks (due to a merge conflict), but might fail in very complex situations where unstaged changes cannot be restored cleanly. If this happens to you, we are very interested in a repeatable test scenario. - ---- - [![asciicast](https://asciinema.org/a/199934.svg)](https://asciinema.org/a/199934) ## Why @@ -36,10 +12,10 @@ This project contains a script that will run arbitrary shell tasks with a list o ## Related blogs posts and talks -* [Make Linting Great Again](https://medium.com/@okonetchnikov/make-linting-great-again-f3890e1ad6b8#.8qepn2b5l) -* [Running Jest Tests Before Each Git Commit](https://benmccormick.org/2017/02/26/running-jest-tests-before-each-git-commit/) -* [AgentConf: Make Linting Great Again](https://www.youtube.com/watch?v=-mhY7e-EsC4) -* [SurviveJS Interview](https://survivejs.com/blog/lint-staged-interview/) +- [Make Linting Great Again](https://medium.com/@okonetchnikov/make-linting-great-again-f3890e1ad6b8#.8qepn2b5l) +- [Running Jest Tests Before Each Git Commit](https://benmccormick.org/2017/02/26/running-jest-tests-before-each-git-commit/) +- [AgentConf: Make Linting Great Again](https://www.youtube.com/watch?v=-mhY7e-EsC4) +- [SurviveJS Interview](https://survivejs.com/blog/lint-staged-interview/) > If you've written one, please submit a PR with the link to it! @@ -79,22 +55,22 @@ Options: -h, --help output usage information ``` -* **`--config [path]`**: This can be used to manually specify the `lint-staged` config file location. However, if the specified file cannot be found, it will error out instead of performing the usual search. You may pass a npm package name for configuration also. -* **`--relative`**: By default filepaths will be passed to the linter tasks as *absolute*. This flag makes them relative to `process.cwd()` (where `lint-staged` runs). -* **`--shell`**: By default linter commands will be parsed for speed and security. This has the side-effect that regular shell scripts might not work as expected. You can skip parsing of commands with this option. -* **`--quiet`**: By default `lint-staged` will print progress status to console while running linters. Use this flag to supress all output, except for linter scripts. -* **`--debug`**: Enabling the debug mode does the following: - * `lint-staged` uses the [debug](https://github.com/visionmedia/debug) module internally to log information about staged files, commands being executed, location of binaries, etc. Debug logs, which are automatically enabled by passing the flag, can also be enabled by setting the environment variable `$DEBUG` to `lint-staged*`. - * Use the [`verbose` renderer](https://github.com/SamVerschueren/listr-verbose-renderer) for `listr`. +- **`--config [path]`**: This can be used to manually specify the `lint-staged` config file location. However, if the specified file cannot be found, it will error out instead of performing the usual search. You may pass a npm package name for configuration also. +- **`--relative`**: By default filepaths will be passed to the linter tasks as _absolute_. This flag makes them relative to `process.cwd()` (where `lint-staged` runs). +- **`--shell`**: By default linter commands will be parsed for speed and security. This has the side-effect that regular shell scripts might not work as expected. You can skip parsing of commands with this option. +- **`--quiet`**: By default `lint-staged` will print progress status to console while running linters. Use this flag to supress all output, except for linter scripts. +- **`--debug`**: Enabling the debug mode does the following: + - `lint-staged` uses the [debug](https://github.com/visionmedia/debug) module internally to log information about staged files, commands being executed, location of binaries, etc. Debug logs, which are automatically enabled by passing the flag, can also be enabled by setting the environment variable `$DEBUG` to `lint-staged*`. + - Use the [`verbose` renderer](https://github.com/SamVerschueren/listr-verbose-renderer) for `listr`. ## Configuration Starting with v3.1 you can now use different ways of configuring it: -* `lint-staged` object in your `package.json` -* `.lintstagedrc` file in JSON or YML format -* `lint-staged.config.js` file in JS format -* Pass a configuration file using the `--config` or `-c` flag +- `lint-staged` object in your `package.json` +- `.lintstagedrc` file in JSON or YML format +- `lint-staged.config.js` file in JS format +- Pass a configuration file using the `--config` or `-c` flag See [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) for more details on what formats are supported. @@ -128,19 +104,19 @@ So, considering you did `git add file1.ext file2.ext`, lint-staged will run the Linter commands work on a subset of all staged files, defined by a _glob pattern_. `lint-staged´ uses [micromatch](https://github.com/micromatch/micromatch) for matching files with the following rules: -* If the glob pattern contains no slashes (`/`), micromatch's `matchBase` option will enabled, so globs match a file's basename regardless of directory: - * **`"*.js"`** will match all JS files, like `/test.js` and `/foo/bar/test.js` - * **`"!(*test).js"`**. will match all JS files, except those ending in `test.js`, so `foo.js` but not `foo.test.js` -* If the glob pattern does contain a slash (`/`), it will match for paths as well: - * **`"/*.js"`** will match all JS files in the git repo root, so `/test.js` but not `/foo/bar/test.js` - * **`"foo/**/*.js"`** will match all JS files inside the`/foo`directory, so`/foo/bar/test.js`but not`/test.js` +- If the glob pattern contains no slashes (`/`), micromatch's `matchBase` option will enabled, so globs match a file's basename regardless of directory: + - **`"*.js"`** will match all JS files, like `/test.js` and `/foo/bar/test.js` + - **`"!(*test).js"`**. will match all JS files, except those ending in `test.js`, so `foo.js` but not `foo.test.js` +- If the glob pattern does contain a slash (`/`), it will match for paths as well: + - **`"/*.js"`** will match all JS files in the git repo root, so `/test.js` but not `/foo/bar/test.js` + - **`"foo/**/\*.js"`** will match all JS files inside the`/foo`directory, so`/foo/bar/test.js`but not`/test.js` When matching, `lint-staged` will do the following -* Resolve the git root automatically, no configuration needed. -* Pick the staged files which are present inside the project directory. -* Filter them using the specified glob patterns. -* Pass absolute paths to the linters as arguments. +- Resolve the git root automatically, no configuration needed. +- Pick the staged files which are present inside the project directory. +- Filter them using the specified glob patterns. +- Pass absolute paths to the linters as arguments. **NOTE:** `lint-staged` will pass _absolute_ paths to the linters to avoid any confusion in case they're executed in a different working directory (i.e. when your `.git` directory isn't the same as your `package.json` directory). @@ -156,7 +132,7 @@ In advanced scenarios, where it is impossible to configure the linter task itsel ## What commands are supported? -Supported are any executables installed locally or globally via `npm` as well as any executable from your $PATH. +Supported are any executables installed locally or globally via `npm` as well as any executable from your \$PATH. > Using globally installed scripts is discouraged, since lint-staged may not work for someone who doesn’t have it installed. @@ -407,7 +383,7 @@ const lintStaged = require('lint-staged') try { const success = await lintStaged() console.log(success ? 'Linting was successful!' : 'Linting failed!') -} catch(e) { +} catch (e) { // Failed to load configuration console.error(e) } @@ -426,7 +402,6 @@ const success = await lintStaged({ You can also pass config directly with `config` option: - ```js const success = await lintStaged({ config: { From 1a87333f9ee0704b3bb332bf5fbc11dbd25f7821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Wed, 2 Oct 2019 06:33:39 +0300 Subject: [PATCH 30/64] fix: workaround for stashing deleted files for git < 2.23 --- lib/gitWorkflow.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index 66e6c3072..b6ad63e93 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -92,18 +92,25 @@ class GitWorkflow { } // Get stash of entire original state, including unstaged changes - // Keep index so that tasks only work on those files - await this.execGit(['stash', 'save', '--quiet', '--include-untracked', '--keep-index', STASH]) + await this.execGit(['stash', 'save', '--quiet', '--include-untracked', STASH]) + // Apply index from previous stash back to enable running tasks against + // staged files only. `git stash --keep-index` cannot be used here because of + // a bug affecting deleted files. The bug has been fixed in git v2.23.0 + // See https://github.com/git/git/blob/master/Documentation/RelNotes/2.23.0.txt#L322 + await this.execGit(['stash', 'apply', '--index', await this.getBackupStash()]) + // Clear any unstaged changes since they are saved in the stash, + // and shouldn't be affected by tasks + await this.execGit(['clean', '-df']) + await this.execGit(['checkout', '.']) // Since only staged files are now present, get a diff of unstaged changes // by comparing current index against original stash, but in reverse - const original = await this.getBackupStash() this.unstagedDiff = await this.execGit([ 'diff', '--unified=0', '--no-color', '--no-ext-diff', '--patch', - original, + await this.getBackupStash(), '-R' // Show diff in reverse ]) debug('Done backing up original state!') From 91ee67a219e84439aed54b4ac868ed49d6dc5dfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Thu, 3 Oct 2019 07:00:38 +0300 Subject: [PATCH 31/64] test: should work when amending previous commit with unstaged changes --- test/runAll.unmocked.spec.js | 107 +++++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 37 deletions(-) diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 0381d3ba3..0dec32507 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -69,9 +69,9 @@ const writeFile = async (filename, content, dir = cwd) => const execGit = async args => execGitBase(args, { cwd }) // Execute runAll before git commit to emulate lint-staged -const gitCommit = async (options, message = 'test') => { +const gitCommit = async (options, args = ['-m test']) => { await runAll({ ...options, cwd, quiet: true }) - await execGit(['commit', `-m "${message}"`]) + await execGit(['commit', ...args]) } describe('runAll', () => { @@ -339,16 +339,16 @@ describe('runAll', () => { } catch (error) { expect(error.message).toMatch('Another git process seems to be running in this repository') expect(console.printHistory()).toMatchInlineSnapshot(` - " - ERROR - × lint-staged failed due to a git error. - Any lost modifications can be restored from a git stash: - - > git stash list - stash@{0}: On master: automatic lint-staged backup - > git stash pop stash@{0} - " - `) + " + ERROR + × lint-staged failed due to a git error. + Any lost modifications can be restored from a git stash: + + > git stash list + stash@{0}: On master: automatic lint-staged backup + > git stash pop stash@{0} + " + `) } // Something was wrong so new commit wasn't created @@ -358,17 +358,17 @@ describe('runAll', () => { // But local modifications are gone expect(await execGit(['diff'])).not.toEqual(diff) expect(await execGit(['diff'])).toMatchInlineSnapshot(` - "diff --git a/test.js b/test.js - index f80f875..1c5643c 100644 - --- a/test.js - +++ b/test.js - @@ -1,3 +1,3 @@ - module.exports = { - - 'foo': 'bar', - -} - + foo: \\"bar\\" - +};" - `) + "diff --git a/test.js b/test.js + index f80f875..1c5643c 100644 + --- a/test.js + +++ b/test.js + @@ -1,3 +1,3 @@ + module.exports = { + - 'foo': 'bar', + -} + + foo: \\"bar\\" + +};" + `) expect(await readFile('test.js')).not.toEqual(testJsFileUgly + appended) expect(await readFile('test.js')).toEqual(testJsFilePretty) @@ -396,7 +396,7 @@ describe('runAll', () => { await execGit(['checkout', '-b', 'branch-a']) await appendFile('test.js', fileInBranchA) await execGit(['add', '.']) - await gitCommit(fixJsConfig, 'commit a') + await gitCommit(fixJsConfig, ['-m commit a']) expect(await readFile('test.js')).toEqual(fileInBranchA) await execGit(['checkout', 'master']) @@ -405,7 +405,7 @@ describe('runAll', () => { await execGit(['checkout', '-b', 'branch-b']) await appendFile('test.js', fileInBranchB) await execGit(['add', '.']) - await gitCommit(fixJsConfig, 'commit b') + await gitCommit(fixJsConfig, ['-m commit b']) expect(await readFile('test.js')).toEqual(fileInBranchBFixed) // Merge first branch @@ -422,13 +422,13 @@ describe('runAll', () => { } expect(await readFile('test.js')).toMatchInlineSnapshot(` - "<<<<<<< HEAD - module.exports = \\"foo\\"; - ======= - module.exports = \\"bar\\"; - >>>>>>> branch-b - " - `) + "<<<<<<< HEAD + module.exports = \\"foo\\"; + ======= + module.exports = \\"bar\\"; + >>>>>>> branch-b + " + `) // Fix conflict and commit using lint-staged await writeFile('test.js', fileInBranchB) @@ -442,12 +442,12 @@ describe('runAll', () => { // Nothing is wrong, so a new commit is created and file is pretty expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('4') expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` - "Merge branch 'branch-b' + "Merge branch 'branch-b' - # Conflicts: - # test.js - " - `) + # Conflicts: + # test.js + " + `) expect(await readFile('test.js')).toEqual(fileInBranchBFixed) }) @@ -468,4 +468,37 @@ describe('runAll', () => { expect(await readFile('test.js')).toEqual(testJsFilePretty) expect(await readFile('test-untracked.js')).toEqual(testJsFilePretty) }) + + it('should work when amending previous commit with unstaged changes', async () => { + // Edit file from previous commit + await appendFile('README.md', '\n## Amended\n') + await execGit(['add', 'README.md']) + + // Edit again, but keep it unstaged + await appendFile('README.md', '\n## Edited\n') + await appendFile('test-untracked.js', testJsFilePretty) + + // Run lint-staged with `prettier --list-different` and commit pretty file + await gitCommit({ config: { '*.{js,md}': 'prettier --list-different' } }, [ + '--amend', + '--no-edit' + ]) + + // Nothing is wrong, so the commit was amended + expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('initial commit') + expect(await readFile('README.md')).toMatchInlineSnapshot(` + "# Test + + ## Amended + + ## Edited + " + `) + expect(await readFile('test-untracked.js')).toEqual(testJsFilePretty) + const status = await execGit(['status']) + expect(status).toMatch('modified: README.md') + expect(status).toMatch('test-untracked.js') + expect(status).toMatch('no changes added to commit') + }) }) From 7b144b44462edfc3daac1799d5774a35a1796481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Thu, 3 Oct 2019 07:49:53 +0300 Subject: [PATCH 32/64] test: improve coverage of gitWorkflow --- test/runAll.unmocked.2.spec.js | 109 +++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 test/runAll.unmocked.2.spec.js diff --git a/test/runAll.unmocked.2.spec.js b/test/runAll.unmocked.2.spec.js new file mode 100644 index 000000000..558871cd6 --- /dev/null +++ b/test/runAll.unmocked.2.spec.js @@ -0,0 +1,109 @@ +import fs from 'fs-extra' +import makeConsoleMock from 'consolemock' +import normalize from 'normalize-path' +import os from 'os' +import path from 'path' +import nanoid from 'nanoid' + +jest.mock('../lib/file') + +import execGitBase from '../lib/execGit' +import { readBufferFromFile, writeBufferToFile } from '../lib/file' +import runAll from '../lib/runAll' + +jest.unmock('execa') + +jest.setTimeout(20000) + +const testJsFilePretty = `module.exports = { + foo: "bar" +}; +` + +const isAppveyor = !!process.env.APPVEYOR +const osTmpDir = isAppveyor ? 'C:\\projects' : fs.realpathSync(os.tmpdir()) + +/** + * Create temporary directory and return its path + * @returns {Promise} + */ +const createTempDir = async () => { + const dirname = path.resolve(osTmpDir, 'lint-staged-test', nanoid()) + await fs.ensureDir(dirname) + return dirname +} + +/** + * Remove temporary directory + * @param {String} dirname + * @returns {Promise} + */ +const removeTempDir = async dirname => { + await fs.remove(dirname) +} + +let tmpDir +let cwd + +// Append to file, creating if it doesn't exist +const appendFile = async (filename, content, dir = cwd) => + fs.appendFile(path.join(dir, filename), content) + +// Wrap execGit to always pass `gitOps` +const execGit = async args => execGitBase(args, { cwd }) + +// Execute runAll before git commit to emulate lint-staged +const gitCommit = async (options, args = ['-m test']) => { + await runAll({ ...options, cwd, quiet: true }) + await execGit(['commit', ...args]) +} + +const globalConsoleTemp = console + +describe('runAll', () => { + beforeAll(() => { + console = makeConsoleMock() + }) + + beforeEach(async () => { + tmpDir = await createTempDir() + cwd = normalize(tmpDir) + // Init repository with initial commit + await execGit('init') + await execGit(['config', 'user.name', '"test"']) + await execGit(['config', 'user.email', '"test@test.com"']) + await appendFile('README.md', '# Test\n') + await execGit(['add', 'README.md']) + await execGit(['commit', '-m initial commit']) + }) + + afterEach(async () => { + console.clearHistory() + if (!isAppveyor) { + await removeTempDir(tmpDir) + } + }) + + afterAll(() => { + console = globalConsoleTemp + }) + + it('Should throw when restoring untracked files fails', async () => { + readBufferFromFile.mockImplementation(async () => [Buffer.from('')]) + writeBufferToFile.mockImplementation(async () => Promise.reject('test')) + + // Stage pretty file + await appendFile('test.js', testJsFilePretty) + await execGit(['add', 'test.js']) + + // Create untracked file + await appendFile('test-untracked.js', testJsFilePretty) + + try { + // Run lint-staged with `prettier --list-different` and commit pretty file + await gitCommit({ config: { '*.js': 'prettier --list-different' } }) + } catch (error) { + expect(error.message).toEqual('Untracked changes could not be restored due to an error!') + } + }) +}) From 74ed28d5edc70c66d769f7658b90b550029a2acf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Mon, 21 Oct 2019 17:14:12 +0300 Subject: [PATCH 33/64] feat: automatically stage task modifications --- .lintstagedrc.json | 6 +++--- lib/gitWorkflow.js | 17 +++++++++++++---- lib/runAll.js | 4 ++-- test/__mocks__/gitWorkflow.js | 2 +- test/__snapshots__/runAll.spec.js.snap | 16 ++++++++-------- test/runAll.unmocked.spec.js | 2 +- 6 files changed, 28 insertions(+), 19 deletions(-) diff --git a/.lintstagedrc.json b/.lintstagedrc.json index 565435dcc..e52d997e7 100644 --- a/.lintstagedrc.json +++ b/.lintstagedrc.json @@ -1,5 +1,5 @@ { - "*.{js,json,md}": ["prettier --write", "git add"], - "*.js": ["npm run lint:base --fix", "git add"], - ".*{rc, json}": ["jsonlint --in-place", "git add"] + "*.{js,json,md}": ["prettier --write"], + "*.js": ["npm run lint:base --fix"], + ".*{rc, json}": ["jsonlint --in-place"] } diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index b6ad63e93..5a1020059 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -117,16 +117,25 @@ class GitWorkflow { } /** - * Applies back unstaged changes that have been hidden in the stash. + * Applies back task modifications, and unstaged changes hidden in the stash. * In case of a merge-conflict retry with 3-way merge. * * @param {Object} [options] * @returns {Promise} */ - async restoreUnstagedChanges() { - debug('Restoring unstaged changes...') + async applyModifications() { + let modifiedFiles = await this.execGit(['ls-files', '--modified']) + if (modifiedFiles) { + modifiedFiles = modifiedFiles.split('\n') + debug('Detected files modified by tasks:') + debug(modifiedFiles) + debug('Adding files to index...') + await this.execGit(['add', modifiedFiles]) + debug('Done adding files to index!') + } if (this.unstagedDiff) { + debug('Restoring unstaged changes...') try { await this.execGit(gitApplyArgs, { input: `${this.unstagedDiff}\n` }) } catch (error) { @@ -143,8 +152,8 @@ class GitWorkflow { throw new Error('Unstaged changes could not be restored due to a merge conflict!') } } + debug('Done restoring unstaged changes!') } - debug('Done restoring unstaged changes!') if (this.untrackedFiles) { debug('Restoring untracked files...') diff --git a/lib/runAll.js b/lib/runAll.js index acfcfb90c..2704ed0e7 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -115,9 +115,9 @@ module.exports = async function runAll( task: () => new Listr(tasks, { ...listrOptions, concurrent: true, exitOnError: false }) }, { - title: 'Restoring unstaged changes...', + title: 'Applying modifications...', skip: ctx => ctx.hasErrors && 'Skipped because of errors from tasks', - task: () => git.restoreUnstagedChanges() + task: () => git.applyModifications() }, { title: 'Reverting to original state...', diff --git a/test/__mocks__/gitWorkflow.js b/test/__mocks__/gitWorkflow.js index 7b846dd7c..212655108 100644 --- a/test/__mocks__/gitWorkflow.js +++ b/test/__mocks__/gitWorkflow.js @@ -1,6 +1,6 @@ const stub = { stashBackup: jest.fn().mockImplementation(() => Promise.resolve()), - restoreUnstagedChanges: jest.fn().mockImplementation(() => Promise.resolve()), + applyModifications: jest.fn().mockImplementation(() => Promise.resolve()), restoreOriginalState: jest.fn().mockImplementation(() => Promise.resolve()), dropBackup: jest.fn().mockImplementation(() => Promise.resolve()) } diff --git a/test/__snapshots__/runAll.spec.js.snap b/test/__snapshots__/runAll.spec.js.snap index 65f538180..130ed3b91 100644 --- a/test/__snapshots__/runAll.spec.js.snap +++ b/test/__snapshots__/runAll.spec.js.snap @@ -10,8 +10,8 @@ LOG echo \\"sample\\" [started] LOG echo \\"sample\\" [completed] LOG Running tasks for *.js [completed] LOG Running tasks... [completed] -LOG Restoring unstaged changes... [started] -LOG Restoring unstaged changes... [completed] +LOG Applying modifications... [started] +LOG Applying modifications... [completed] LOG Cleaning up... [started] LOG Cleaning up... [completed]" `; @@ -33,8 +33,8 @@ LOG → LOG Running tasks for *.js [failed] LOG → LOG Running tasks... [failed] -LOG Restoring unstaged changes... [started] -LOG Restoring unstaged changes... [skipped] +LOG Applying modifications... [started] +LOG Applying modifications... [skipped] LOG → Skipped because of errors from tasks LOG Reverting to original state... [started] LOG Reverting to original state... [completed] @@ -64,8 +64,8 @@ LOG → LOG Running tasks for *.js [failed] LOG → LOG Running tasks... [failed] -LOG Restoring unstaged changes... [started] -LOG Restoring unstaged changes... [skipped] +LOG Applying modifications... [started] +LOG Applying modifications... [skipped] LOG → Skipped because of errors from tasks LOG Reverting to original state... [started] LOG Reverting to original state... [completed] @@ -103,8 +103,8 @@ LOG echo \\"sample\\" [started] LOG echo \\"sample\\" [completed] LOG Running tasks for *.js [completed] LOG Running tasks... [completed] -LOG Restoring unstaged changes... [started] -LOG Restoring unstaged changes... [completed] +LOG Applying modifications... [started] +LOG Applying modifications... [completed] LOG Cleaning up... [started] LOG Cleaning up... [completed]" `; diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 0dec32507..8c693e6ad 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -26,7 +26,7 @@ const testJsFileUnfixable = `const obj = { 'foo': 'bar' ` -const fixJsConfig = { config: { '*.js': ['prettier --write', 'git add'] } } +const fixJsConfig = { config: { '*.js': 'prettier --write' } } const isAppveyor = !!process.env.APPVEYOR const osTmpDir = isAppveyor ? 'C:\\projects' : fs.realpathSync(os.tmpdir()) From 52083990166cbea3bfe3d316ad6598c6c198fe1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Wed, 23 Oct 2019 06:01:16 +0300 Subject: [PATCH 34/64] feat: warn when task contains "git add" --- .lintstagedrc.json | 6 +-- lib/makeCmdTasks.js | 5 ++- lib/resolveTaskFn.js | 18 ++++++++- lib/runAll.js | 8 +++- test/makeCmdTasks.spec.js | 1 + test/resolveTaskFn.spec.js | 39 +++++++++++++----- test/runAll.unmocked.spec.js | 78 ++++++++++++++++++------------------ 7 files changed, 99 insertions(+), 56 deletions(-) diff --git a/.lintstagedrc.json b/.lintstagedrc.json index e52d997e7..144f4ebbf 100644 --- a/.lintstagedrc.json +++ b/.lintstagedrc.json @@ -1,5 +1,5 @@ { - "*.{js,json,md}": ["prettier --write"], - "*.js": ["npm run lint:base --fix"], - ".*{rc, json}": ["jsonlint --in-place"] + "*.{js,json,md}": "prettier --write", + "*.js": "npm run lint:base --fix", + ".*{rc, json}": "jsonlint --in-place" } diff --git a/lib/makeCmdTasks.js b/lib/makeCmdTasks.js index 958ac9230..d68dea7a5 100644 --- a/lib/makeCmdTasks.js +++ b/lib/makeCmdTasks.js @@ -11,9 +11,10 @@ const debug = require('debug')('lint-staged:make-cmd-tasks') * @param {Array|string|Function} options.commands * @param {Array} options.files * @param {string} options.gitDir + * @param {Function} [options.logger] * @param {Boolean} shell */ -module.exports = async function makeCmdTasks({ commands, files, gitDir, shell }) { +module.exports = async function makeCmdTasks({ commands, files, gitDir, logger, shell }) { debug('Creating listr tasks for commands %o', commands) const commandsArray = Array.isArray(commands) ? commands : [commands] @@ -41,7 +42,7 @@ module.exports = async function makeCmdTasks({ commands, files, gitDir, shell }) title = mockCommands[i].replace(/\[file\].*\[file\]/, '[file]') } - const task = { title, task: resolveTaskFn({ gitDir, isFn, command, files, shell }) } + const task = { title, task: resolveTaskFn({ command, files, gitDir, isFn, logger, shell }) } tasks.push(task) }) diff --git a/lib/resolveTaskFn.js b/lib/resolveTaskFn.js index 39d999629..f9be525ad 100644 --- a/lib/resolveTaskFn.js +++ b/lib/resolveTaskFn.js @@ -62,14 +62,30 @@ function makeErr(linter, result, context = {}) { * @param {String} options.gitDir - Current git repo path * @param {Boolean} options.isFn - Whether the linter task is a function * @param {Array} options.files — Filepaths to run the linter task against + * @param {Function} [options.logger] * @param {Boolean} [options.relative] — Whether the filepaths should be relative * @param {Boolean} [options.shell] — Whether to skip parsing linter task for better shell support * @returns {function(): Promise>} */ -module.exports = function resolveTaskFn({ command, files, gitDir, isFn, relative, shell = false }) { +module.exports = function resolveTaskFn({ + command, + files, + gitDir, + isFn, + logger, + relative, + shell = false +}) { const cmd = isFn ? command : `${command} ${files.join(' ')}` debug('cmd:', cmd) + if (logger && cmd.includes('git add')) { + logger.warn(` + ${symbols.warning} ${chalk.yellow( + `Detected a task using \`git add\`. Lint-staged version 10 will automatically add any task modifications to the git index, and you should remove this command.` + )}`) + } + const execaOptions = { preferLocal: true, reject: false, shell } if (relative) { execaOptions.cwd = process.cwd() diff --git a/lib/runAll.js b/lib/runAll.js index 2704ed0e7..20d9b9ad7 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -72,7 +72,13 @@ module.exports = async function runAll( title: `Running tasks for ${task.pattern}`, task: async () => new Listr( - await makeCmdTasks({ commands: task.commands, files: task.fileList, gitDir, shell }), + await makeCmdTasks({ + commands: task.commands, + files: task.fileList, + gitDir, + logger, + shell + }), { // In sub-tasks we don't want to run concurrently // and we want to abort on errors diff --git a/test/makeCmdTasks.spec.js b/test/makeCmdTasks.spec.js index f1121b256..0c94e1d65 100644 --- a/test/makeCmdTasks.spec.js +++ b/test/makeCmdTasks.spec.js @@ -1,4 +1,5 @@ import execa from 'execa' + import makeCmdTasks from '../lib/makeCmdTasks' describe('makeCmdTasks', () => { diff --git a/test/resolveTaskFn.spec.js b/test/resolveTaskFn.spec.js index 11f482709..cd038a59b 100644 --- a/test/resolveTaskFn.spec.js +++ b/test/resolveTaskFn.spec.js @@ -1,4 +1,6 @@ import execa from 'execa' +import makeConsoleMock from 'consolemock' + import resolveTaskFn from '../lib/resolveTaskFn' const defaultOpts = { files: ['test.js'] } @@ -80,13 +82,13 @@ describe('resolveTaskFn', () => { expect.assertions(2) const taskFn = resolveTaskFn({ ...defaultOpts, - command: 'git add', + command: 'git diff', gitDir: '../' }) await taskFn() expect(execa).toHaveBeenCalledTimes(1) - expect(execa).lastCalledWith('git add test.js', { + expect(execa).lastCalledWith('git diff test.js', { cwd: '../', preferLocal: true, reject: false, @@ -111,13 +113,13 @@ describe('resolveTaskFn', () => { expect.assertions(2) const taskFn = resolveTaskFn({ ...defaultOpts, - command: 'git add', + command: 'git diff', relative: true }) await taskFn() expect(execa).toHaveBeenCalledTimes(1) - expect(execa).lastCalledWith('git add test.js', { + expect(execa).lastCalledWith('git diff test.js', { cwd: process.cwd(), preferLocal: true, reject: false, @@ -140,12 +142,12 @@ describe('resolveTaskFn', () => { await taskFn() } catch (err) { expect(err.privateMsg).toMatchInlineSnapshot(` -" + " -× mock-fail-linter found some errors. Please fix them and try committing again. -Mock error" -`) + × mock-fail-linter found some errors. Please fix them and try committing again. + Mock error" + `) } }) @@ -166,11 +168,11 @@ Mock error" await taskFn() } catch (err) { expect(err.privateMsg).toMatchInlineSnapshot(` -" + " -‼ mock-killed-linter was terminated with SIGINT" -`) + ‼ mock-killed-linter was terminated with SIGINT" + `) } }) @@ -199,4 +201,19 @@ Mock error" expect(context.hasErrors).toEqual(true) } }) + + it('should warn when tasks include git add', async () => { + const logger = makeConsoleMock() + await resolveTaskFn({ + ...defaultOpts, + command: 'git add', + logger, + relative: true + }) + expect(logger.printHistory()).toMatchInlineSnapshot(` + " + WARN + ‼ Detected a task using \`git add\`. Lint-staged version 10 will automatically add any task modifications to the git index, and you should remove this command." + `) + }) }) diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 8c693e6ad..044c54dee 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -339,16 +339,18 @@ describe('runAll', () => { } catch (error) { expect(error.message).toMatch('Another git process seems to be running in this repository') expect(console.printHistory()).toMatchInlineSnapshot(` - " - ERROR - × lint-staged failed due to a git error. - Any lost modifications can be restored from a git stash: - - > git stash list - stash@{0}: On master: automatic lint-staged backup - > git stash pop stash@{0} - " - `) + " + WARN + ‼ Detected a task using \`git add\`. Lint-staged version 10 will automatically add any task modifications to the git index, and you should remove this command. + ERROR + × lint-staged failed due to a git error. + Any lost modifications can be restored from a git stash: + + > git stash list + stash@{0}: On master: automatic lint-staged backup + > git stash pop stash@{0} + " + `) } // Something was wrong so new commit wasn't created @@ -358,17 +360,17 @@ describe('runAll', () => { // But local modifications are gone expect(await execGit(['diff'])).not.toEqual(diff) expect(await execGit(['diff'])).toMatchInlineSnapshot(` - "diff --git a/test.js b/test.js - index f80f875..1c5643c 100644 - --- a/test.js - +++ b/test.js - @@ -1,3 +1,3 @@ - module.exports = { - - 'foo': 'bar', - -} - + foo: \\"bar\\" - +};" - `) + "diff --git a/test.js b/test.js + index f80f875..1c5643c 100644 + --- a/test.js + +++ b/test.js + @@ -1,3 +1,3 @@ + module.exports = { + - 'foo': 'bar', + -} + + foo: \\"bar\\" + +};" + `) expect(await readFile('test.js')).not.toEqual(testJsFileUgly + appended) expect(await readFile('test.js')).toEqual(testJsFilePretty) @@ -422,13 +424,13 @@ describe('runAll', () => { } expect(await readFile('test.js')).toMatchInlineSnapshot(` - "<<<<<<< HEAD - module.exports = \\"foo\\"; - ======= - module.exports = \\"bar\\"; - >>>>>>> branch-b - " - `) + "<<<<<<< HEAD + module.exports = \\"foo\\"; + ======= + module.exports = \\"bar\\"; + >>>>>>> branch-b + " + `) // Fix conflict and commit using lint-staged await writeFile('test.js', fileInBranchB) @@ -442,12 +444,12 @@ describe('runAll', () => { // Nothing is wrong, so a new commit is created and file is pretty expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('4') expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` - "Merge branch 'branch-b' + "Merge branch 'branch-b' - # Conflicts: - # test.js - " - `) + # Conflicts: + # test.js + " + `) expect(await readFile('test.js')).toEqual(fileInBranchBFixed) }) @@ -488,13 +490,13 @@ describe('runAll', () => { expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('initial commit') expect(await readFile('README.md')).toMatchInlineSnapshot(` - "# Test + "# Test - ## Amended + ## Amended - ## Edited - " - `) + ## Edited + " + `) expect(await readFile('test-untracked.js')).toEqual(testJsFilePretty) const status = await execGit(['status']) expect(status).toMatch('modified: README.md') From d1da3fc51ab8c8d7930af6a14eda874de63317cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Wed, 23 Oct 2019 06:31:54 +0300 Subject: [PATCH 35/64] test: add test for supplying object config via node api --- test/__snapshots__/index.spec.js.snap | 9 +++++++++ test/index.spec.js | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/test/__snapshots__/index.spec.js.snap b/test/__snapshots__/index.spec.js.snap index 8a4dcb834..ebf095066 100644 --- a/test/__snapshots__/index.spec.js.snap +++ b/test/__snapshots__/index.spec.js.snap @@ -78,6 +78,15 @@ ERROR Please make sure you have created it correctly. See https://github.com/okonet/lint-staged#configuration." `; +exports[`lintStaged should use config object 1`] = ` +" +LOG Running lint-staged with the following config: +LOG { + '*': 'node -e \\"process.exit(1)\\"' +} +ERROR Unable to get staged files!" +`; + exports[`lintStaged should use cosmiconfig if no params are passed 1`] = ` " ERROR Unable to get staged files!" diff --git a/test/index.spec.js b/test/index.spec.js index 1cab890e0..bfc888796 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -120,6 +120,15 @@ describe('lintStaged', () => { expect(logger.printHistory()).toMatchSnapshot() }) + it('should use config object', async () => { + const config = { + '*': 'node -e "process.exit(1)"' + } + expect.assertions(1) + await lintStaged({ config, debug: true, quiet: true }, logger) + expect(logger.printHistory()).toMatchSnapshot() + }) + it('should load an npm config package when specified', async () => { expect.assertions(1) jest.mock('my-lint-staged-config') From c7d05922b24524707795c4045339801c86affe9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20Ja=CC=88ppinen?= Date: Tue, 29 Oct 2019 13:16:09 +0200 Subject: [PATCH 36/64] fix: correctly restore untracked files from backup stash --- lib/gitWorkflow.js | 49 ++++++++++------------------------------------ 1 file changed, 10 insertions(+), 39 deletions(-) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index 5a1020059..05dc198ce 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -1,7 +1,6 @@ 'use strict' const debug = require('debug')('lint-staged:git') -const normalize = require('normalize-path') const path = require('path') const execGit = require('./execGit') @@ -69,28 +68,6 @@ class GitWorkflow { debug('Done backing up merge state!') } - // Git stash ignores new, untracked files, so back them up separately - // Use `git ls-files` to list untracked files: - // `--others includes` all untracked files, including ignored files - // `--exclude-standard` excludes ignored files, the .git/ dir and so on... - let untrackedFiles = await this.execGit(['ls-files', '--others', '--exclude-standard']) - if (untrackedFiles) { - debug('Detected untracked files:') - debug(untrackedFiles) - debug('Backing up untracked files...') - // Resolve untrackedFiles output into filenames - untrackedFiles = untrackedFiles - .split('\n') - .map(file => normalize(path.resolve(this.cwd, file))) - this.untrackedFiles = new Map() - await Promise.all( - untrackedFiles.map(file => - readBufferFromFile(file).then(buffer => this.untrackedFiles.set(file, buffer)) - ) - ) - debug('Done backing up untracked files!') - } - // Get stash of entire original state, including unstaged changes await this.execGit(['stash', 'save', '--quiet', '--include-untracked', STASH]) // Apply index from previous stash back to enable running tasks against @@ -155,22 +132,16 @@ class GitWorkflow { debug('Done restoring unstaged changes!') } - if (this.untrackedFiles) { - debug('Restoring untracked files...') - try { - // Iterate over Map and await for all to complete - const writePromises = [] - this.untrackedFiles.forEach((buffer, file) => { - writePromises.push(writeBufferToFile(file, buffer)) - }) - await Promise.all(writePromises) - } catch (error) { - debug('Error while restoring untracked changes:') - debug(error) - throw new Error('Untracked changes could not be restored due to an error!') - } - debug('Done restoring untracked files!') - } + // Restore untracked files by reading from the third commit associated with the backup stash + // Git will return with error code if the commit doesn't exist + // See https://stackoverflow.com/a/52357762 + try { + const backupStash = await this.getBackupStash() + const output = await this.execGit(['show', '--format=%b', `${backupStash}^3`]) + const untrackedDiff = output.replace(/^\n*/, '') // remove empty lines from start of output + if (!untrackedDiff) return + await this.execGit([...gitApplyArgs], { input: `${untrackedDiff}\n` }) + } catch (err) {} // eslint-disable-line no-empty } /** From cce9809a2ce335a3b2c3f44e4c521270b13f9d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Wed, 30 Oct 2019 06:47:30 +0200 Subject: [PATCH 37/64] fix: prevent Listr from hiding git add warning --- lib/generateTasks.js | 1 - lib/makeCmdTasks.js | 10 +-- lib/resolveTaskFn.js | 18 +----- lib/runAll.js | 114 ++++++++++++++++++++--------------- test/resolveTaskFn.spec.js | 16 ----- test/runAll.unmocked.spec.js | 60 +++++++++--------- 6 files changed, 101 insertions(+), 118 deletions(-) diff --git a/lib/generateTasks.js b/lib/generateTasks.js index a554e91f6..4d6dcfa69 100644 --- a/lib/generateTasks.js +++ b/lib/generateTasks.js @@ -15,7 +15,6 @@ const debug = require('debug')('lint-staged:gen-tasks') * @param {boolean} [options.gitDir] - Git root directory * @param {boolean} [options.files] - Staged filepaths * @param {boolean} [options.relative] - Whether filepaths to should be relative to gitDir - * @returns {Promise} */ module.exports = function generateTasks({ config, diff --git a/lib/makeCmdTasks.js b/lib/makeCmdTasks.js index d68dea7a5..6d1482906 100644 --- a/lib/makeCmdTasks.js +++ b/lib/makeCmdTasks.js @@ -11,10 +11,9 @@ const debug = require('debug')('lint-staged:make-cmd-tasks') * @param {Array|string|Function} options.commands * @param {Array} options.files * @param {string} options.gitDir - * @param {Function} [options.logger] * @param {Boolean} shell */ -module.exports = async function makeCmdTasks({ commands, files, gitDir, logger, shell }) { +module.exports = function makeCmdTasks({ commands, files, gitDir, shell }) { debug('Creating listr tasks for commands %o', commands) const commandsArray = Array.isArray(commands) ? commands : [commands] @@ -42,8 +41,11 @@ module.exports = async function makeCmdTasks({ commands, files, gitDir, logger, title = mockCommands[i].replace(/\[file\].*\[file\]/, '[file]') } - const task = { title, task: resolveTaskFn({ command, files, gitDir, isFn, logger, shell }) } - tasks.push(task) + tasks.push({ + title, + command, + task: resolveTaskFn({ command, files, gitDir, isFn, shell }) + }) }) return tasks diff --git a/lib/resolveTaskFn.js b/lib/resolveTaskFn.js index f9be525ad..39d999629 100644 --- a/lib/resolveTaskFn.js +++ b/lib/resolveTaskFn.js @@ -62,30 +62,14 @@ function makeErr(linter, result, context = {}) { * @param {String} options.gitDir - Current git repo path * @param {Boolean} options.isFn - Whether the linter task is a function * @param {Array} options.files — Filepaths to run the linter task against - * @param {Function} [options.logger] * @param {Boolean} [options.relative] — Whether the filepaths should be relative * @param {Boolean} [options.shell] — Whether to skip parsing linter task for better shell support * @returns {function(): Promise>} */ -module.exports = function resolveTaskFn({ - command, - files, - gitDir, - isFn, - logger, - relative, - shell = false -}) { +module.exports = function resolveTaskFn({ command, files, gitDir, isFn, relative, shell = false }) { const cmd = isFn ? command : `${command} ${files.join(' ')}` debug('cmd:', cmd) - if (logger && cmd.includes('git add')) { - logger.warn(` - ${symbols.warning} ${chalk.yellow( - `Detected a task using \`git add\`. Lint-staged version 10 will automatically add any task modifications to the git index, and you should remove this command.` - )}`) - } - const execaOptions = { preferLocal: true, reject: false, shell } if (relative) { execaOptions.cwd = process.cwd() diff --git a/lib/runAll.js b/lib/runAll.js index 20d9b9ad7..06915049b 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -68,75 +68,89 @@ module.exports = async function runAll( `) } - const tasks = generateTasks({ config, cwd, gitDir, files, relative }).map(task => ({ - title: `Running tasks for ${task.pattern}`, - task: async () => - new Listr( - await makeCmdTasks({ - commands: task.commands, - files: task.fileList, - gitDir, - logger, - shell - }), - { + const tasks = generateTasks({ config, cwd, gitDir, files, relative }) + + // lint-staged 10 will automatically add modifications to index + // Warn user when their command includes `git add` + let hasDeprecatedGitAdd = false + + const listrTasks = tasks.map(task => { + const subTasks = makeCmdTasks({ commands: task.commands, files: task.fileList, gitDir, shell }) + + if (subTasks.some(subTask => subTask.command.includes('git add'))) { + hasDeprecatedGitAdd = true + } + + return { + title: `Running tasks for ${task.pattern}`, + task: async () => + new Listr(subTasks, { // In sub-tasks we don't want to run concurrently // and we want to abort on errors dateFormat: false, concurrent: false, exitOnError: true + }), + skip: () => { + if (task.fileList.length === 0) { + return `No staged files match ${task.pattern}` } - ), - skip: () => { - if (task.fileList.length === 0) { - return `No staged files match ${task.pattern}` + return false } - return false } - })) + }) - const listrOptions = { - dateFormat: false, - renderer: (quiet && 'silent') || (debug && 'verbose') || 'update' + if (hasDeprecatedGitAdd) { + logger.warn(`${symbols.warning} ${chalk.yellow( + `Detected a task using \`git add\`. Lint-staged version 10 will automatically add any task modifications to the git index, and you should remove this command.` + )} +`) } - // If all of the configured "linters" should be skipped + // If all of the configured tasks should be skipped // avoid executing any lint-staged logic - if (tasks.every(task => task.skip())) { + if (listrTasks.every(task => task.skip())) { logger.log('No staged files match any of provided globs.') return 'No tasks to run.' } + const listrOptions = { + dateFormat: false, + renderer: (quiet && 'silent') || (debug && 'verbose') || 'update' + } + const git = new GitWorkflow(gitDir) + const runner = new Listr( + [ + { + title: 'Preparing...', + task: () => git.stashBackup() + }, + { + title: 'Running tasks...', + task: () => new Listr(listrTasks, { ...listrOptions, concurrent: true, exitOnError: false }) + }, + { + title: 'Applying modifications...', + skip: ctx => ctx.hasErrors && 'Skipped because of errors from tasks', + task: () => git.applyModifications() + }, + { + title: 'Reverting to original state...', + enabled: ctx => ctx.hasErrors, + task: () => git.restoreOriginalState() + }, + { + title: 'Cleaning up...', + task: () => git.dropBackup() + } + ], + listrOptions + ) + try { - await new Listr( - [ - { - title: 'Preparing...', - task: () => git.stashBackup() - }, - { - title: 'Running tasks...', - task: () => new Listr(tasks, { ...listrOptions, concurrent: true, exitOnError: false }) - }, - { - title: 'Applying modifications...', - skip: ctx => ctx.hasErrors && 'Skipped because of errors from tasks', - task: () => git.applyModifications() - }, - { - title: 'Reverting to original state...', - enabled: ctx => ctx.hasErrors, - task: () => git.restoreOriginalState() - }, - { - title: 'Cleaning up...', - task: () => git.dropBackup() - } - ], - listrOptions - ).run() + await runner.run() } catch (error) { if (error.message.includes('Another git process seems to be running in this repository')) { logger.error(` diff --git a/test/resolveTaskFn.spec.js b/test/resolveTaskFn.spec.js index cd038a59b..56bab7270 100644 --- a/test/resolveTaskFn.spec.js +++ b/test/resolveTaskFn.spec.js @@ -1,5 +1,4 @@ import execa from 'execa' -import makeConsoleMock from 'consolemock' import resolveTaskFn from '../lib/resolveTaskFn' @@ -201,19 +200,4 @@ describe('resolveTaskFn', () => { expect(context.hasErrors).toEqual(true) } }) - - it('should warn when tasks include git add', async () => { - const logger = makeConsoleMock() - await resolveTaskFn({ - ...defaultOpts, - command: 'git add', - logger, - relative: true - }) - expect(logger.printHistory()).toMatchInlineSnapshot(` - " - WARN - ‼ Detected a task using \`git add\`. Lint-staged version 10 will automatically add any task modifications to the git index, and you should remove this command." - `) - }) }) diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 044c54dee..b76e6b948 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -340,8 +340,8 @@ describe('runAll', () => { expect(error.message).toMatch('Another git process seems to be running in this repository') expect(console.printHistory()).toMatchInlineSnapshot(` " - WARN - ‼ Detected a task using \`git add\`. Lint-staged version 10 will automatically add any task modifications to the git index, and you should remove this command. + WARN ‼ Detected a task using \`git add\`. Lint-staged version 10 will automatically add any task modifications to the git index, and you should remove this command. + ERROR × lint-staged failed due to a git error. Any lost modifications can be restored from a git stash: @@ -360,17 +360,17 @@ describe('runAll', () => { // But local modifications are gone expect(await execGit(['diff'])).not.toEqual(diff) expect(await execGit(['diff'])).toMatchInlineSnapshot(` - "diff --git a/test.js b/test.js - index f80f875..1c5643c 100644 - --- a/test.js - +++ b/test.js - @@ -1,3 +1,3 @@ - module.exports = { - - 'foo': 'bar', - -} - + foo: \\"bar\\" - +};" - `) + "diff --git a/test.js b/test.js + index f80f875..1c5643c 100644 + --- a/test.js + +++ b/test.js + @@ -1,3 +1,3 @@ + module.exports = { + - 'foo': 'bar', + -} + + foo: \\"bar\\" + +};" + `) expect(await readFile('test.js')).not.toEqual(testJsFileUgly + appended) expect(await readFile('test.js')).toEqual(testJsFilePretty) @@ -424,13 +424,13 @@ describe('runAll', () => { } expect(await readFile('test.js')).toMatchInlineSnapshot(` - "<<<<<<< HEAD - module.exports = \\"foo\\"; - ======= - module.exports = \\"bar\\"; - >>>>>>> branch-b - " - `) + "<<<<<<< HEAD + module.exports = \\"foo\\"; + ======= + module.exports = \\"bar\\"; + >>>>>>> branch-b + " + `) // Fix conflict and commit using lint-staged await writeFile('test.js', fileInBranchB) @@ -444,12 +444,12 @@ describe('runAll', () => { // Nothing is wrong, so a new commit is created and file is pretty expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('4') expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` - "Merge branch 'branch-b' + "Merge branch 'branch-b' - # Conflicts: - # test.js - " - `) + # Conflicts: + # test.js + " + `) expect(await readFile('test.js')).toEqual(fileInBranchBFixed) }) @@ -490,13 +490,13 @@ describe('runAll', () => { expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('initial commit') expect(await readFile('README.md')).toMatchInlineSnapshot(` - "# Test + "# Test - ## Amended + ## Amended - ## Edited - " - `) + ## Edited + " + `) expect(await readFile('test-untracked.js')).toEqual(testJsFilePretty) const status = await execGit(['status']) expect(status).toMatch('modified: README.md') From 6467a66b13657f1a39b0f1f3a079dc31a8461fe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sun, 3 Nov 2019 11:03:16 +0200 Subject: [PATCH 38/64] fix: update warning about git add, and to README BREAKING CHANGE: Prior to version 10, tasks had to manually include `git add` as the final step. This behavior has been integrated into lint-staged itself in order to prevent race conditions with multiple tasks editing the same files. If lint-staged detects `git add` in task configurations, it will show a warning in the console. Please remove `git add` from your configuration after upgrading. --- README.md | 28 ++++++++--------- lib/runAll.js | 2 +- test/runAll.unmocked.spec.js | 58 ++++++++++++++++++------------------ 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index c30ed38f8..cab810f5d 100644 --- a/README.md +++ b/README.md @@ -229,15 +229,15 @@ module.exports = { ## Reformatting the code -Tools like [Prettier](https://prettier.io), ESLint/TSLint, or stylelint can reformat your code according to an appropriate config by running `prettier --write`/`eslint --fix`/`tslint --fix`/`stylelint --fix`. After the code is reformatted, we want it to be added to the same commit. This can be done using following config: +Tools like [Prettier](https://prettier.io), ESLint/TSLint, or stylelint can reformat your code according to an appropriate config by running `prettier --write`/`eslint --fix`/`tslint --fix`/`stylelint --fix`. Lint-staged will automatically add any modifications to the commit as long as there are no errors. ```json { - "*.js": ["prettier --write", "git add"] + "*.js": "prettier --write" } ``` -Starting from v8, lint-staged will stash your remaining changes (not added to the index) and restore them from stash afterwards if there are partially staged files detected. This allows you to create partial commits with hunks using `git add --patch`. See the [blog post](https://medium.com/@okonetchnikov/announcing-lint-staged-with-support-for-partially-staged-files-abc24a40d3ff) +Prior to version 10, tasks had to manually include `git add` as the final step. This behavior has been integrated into lint-staged itself in order to prevent race conditions with multiple tasks editing the same files. If lint-staged detects `git add` in task configurations, it will show a warning in the console. Please remove `git add` from your configuration after upgrading. ## Examples @@ -273,7 +273,7 @@ _Note we don’t pass a path as an argument for the runners. This is important s ```json { - "*.js": ["eslint --fix", "git add"] + "*.js": "eslint --fix" } ``` @@ -285,7 +285,7 @@ If you wish to reuse a npm script defined in your package.json: ```json { - "*.js": ["npm run my-custom-script --", "git add"] + "*.js": "npm run my-custom-script --" } ``` @@ -293,7 +293,7 @@ The following is equivalent: ```json { - "*.js": ["linter --arg1 --arg2", "git add"] + "*.js": "linter --arg1 --arg2" } ``` @@ -313,19 +313,19 @@ For example, here is `jest` running on all `.js` files with the `NODE_ENV` varia ```json { - "*.{js,jsx}": ["prettier --write", "git add"] + "*.{js,jsx}": "prettier --write" } ``` ```json { - "*.{ts,tsx}": ["prettier --write", "git add"] + "*.{ts,tsx}": "prettier --write" } ``` ```json { - "*.{md,html}": ["prettier --write", "git add"] + "*.{md,html}": "prettier --write" } ``` @@ -338,19 +338,19 @@ For example, here is `jest` running on all `.js` files with the `NODE_ENV` varia } ``` -### Run PostCSS sorting, add files to commit and run Stylelint to check +### Run PostCSS sorting and Stylelint to check ```json { - "*.scss": ["postcss --config path/to/your/config --replace", "stylelint", "git add"] + "*.scss": "postcss --config path/to/your/config --replace", "stylelint" } ``` -### Minify the images and add files to commit +### Minify the images ```json { - "*.{png,jpeg,jpg,gif,svg}": ["imagemin-lint-staged", "git add"] + "*.{png,jpeg,jpg,gif,svg}": "imagemin-lint-staged" } ``` @@ -367,7 +367,7 @@ See more on [this blog post](https://medium.com/@tomchentw/imagemin-lint-staged- ```json { - "*.{js,jsx}": ["flow focus-check", "git add"] + "*.{js,jsx}": "flow focus-check" } ``` diff --git a/lib/runAll.js b/lib/runAll.js index 06915049b..21c1cef61 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -102,7 +102,7 @@ module.exports = async function runAll( if (hasDeprecatedGitAdd) { logger.warn(`${symbols.warning} ${chalk.yellow( - `Detected a task using \`git add\`. Lint-staged version 10 will automatically add any task modifications to the git index, and you should remove this command.` + `Some of your tasks use \`git add\` command. Please remove it from the config since all modifications made by tasks will be automatically added to the git commit index.` )} `) } diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index b76e6b948..76a20c21f 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -340,7 +340,7 @@ describe('runAll', () => { expect(error.message).toMatch('Another git process seems to be running in this repository') expect(console.printHistory()).toMatchInlineSnapshot(` " - WARN ‼ Detected a task using \`git add\`. Lint-staged version 10 will automatically add any task modifications to the git index, and you should remove this command. + WARN ‼ Some of your tasks use \`git add\` command. Please remove it from the config since all modifications made by tasks will be automatically added to the git commit index. ERROR × lint-staged failed due to a git error. @@ -360,17 +360,17 @@ describe('runAll', () => { // But local modifications are gone expect(await execGit(['diff'])).not.toEqual(diff) expect(await execGit(['diff'])).toMatchInlineSnapshot(` - "diff --git a/test.js b/test.js - index f80f875..1c5643c 100644 - --- a/test.js - +++ b/test.js - @@ -1,3 +1,3 @@ - module.exports = { - - 'foo': 'bar', - -} - + foo: \\"bar\\" - +};" - `) + "diff --git a/test.js b/test.js + index f80f875..1c5643c 100644 + --- a/test.js + +++ b/test.js + @@ -1,3 +1,3 @@ + module.exports = { + - 'foo': 'bar', + -} + + foo: \\"bar\\" + +};" + `) expect(await readFile('test.js')).not.toEqual(testJsFileUgly + appended) expect(await readFile('test.js')).toEqual(testJsFilePretty) @@ -424,13 +424,13 @@ describe('runAll', () => { } expect(await readFile('test.js')).toMatchInlineSnapshot(` - "<<<<<<< HEAD - module.exports = \\"foo\\"; - ======= - module.exports = \\"bar\\"; - >>>>>>> branch-b - " - `) + "<<<<<<< HEAD + module.exports = \\"foo\\"; + ======= + module.exports = \\"bar\\"; + >>>>>>> branch-b + " + `) // Fix conflict and commit using lint-staged await writeFile('test.js', fileInBranchB) @@ -444,12 +444,12 @@ describe('runAll', () => { // Nothing is wrong, so a new commit is created and file is pretty expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('4') expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` - "Merge branch 'branch-b' + "Merge branch 'branch-b' - # Conflicts: - # test.js - " - `) + # Conflicts: + # test.js + " + `) expect(await readFile('test.js')).toEqual(fileInBranchBFixed) }) @@ -490,13 +490,13 @@ describe('runAll', () => { expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('initial commit') expect(await readFile('README.md')).toMatchInlineSnapshot(` - "# Test + "# Test - ## Amended + ## Amended - ## Edited - " - `) + ## Edited + " + `) expect(await readFile('test-untracked.js')).toEqual(testJsFilePretty) const status = await execGit(['status']) expect(status).toMatch('modified: README.md') From bc17363e28782a16e335291cafee9a0186bdf602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sun, 3 Nov 2019 11:15:48 +0200 Subject: [PATCH 39/64] test: should not resurrect removed files due to git bug --- test/runAll.unmocked.spec.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 76a20c21f..b9e4a3281 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -503,4 +503,13 @@ describe('runAll', () => { expect(status).toMatch('test-untracked.js') expect(status).toMatch('no changes added to commit') }) + + it('should not resurrect removed files due to git bug', async () => { + const readmeFile = path.resolve(cwd, 'README.md') + await fs.remove(readmeFile) // Remove file from previous commit + await execGit(['add', '.']) + await gitCommit({ config: { '*.{js,md}': 'prettier --list-different' } }) + const exists = await fs.exists(readmeFile) + expect(exists).toEqual(false) + }) }) From 869bac617dd1ef46e6689027c9d3ec67b3a00934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sun, 3 Nov 2019 11:27:09 +0200 Subject: [PATCH 40/64] fix: no need to run `git clean -df` since untracked changes are stashed --- lib/gitWorkflow.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index 05dc198ce..315cfe272 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -68,16 +68,14 @@ class GitWorkflow { debug('Done backing up merge state!') } - // Get stash of entire original state, including unstaged changes + // Save stash of entire original state, including unstaged and untracked changes. + // This should remove all changes from the index. + // The `--keep-index` option cannot be used since it resurrects deleted files on + // git versions before v2.23.0 (https://github.com/git/git/blob/master/Documentation/RelNotes/2.23.0.txt#L322) await this.execGit(['stash', 'save', '--quiet', '--include-untracked', STASH]) - // Apply index from previous stash back to enable running tasks against - // staged files only. `git stash --keep-index` cannot be used here because of - // a bug affecting deleted files. The bug has been fixed in git v2.23.0 - // See https://github.com/git/git/blob/master/Documentation/RelNotes/2.23.0.txt#L322 + // Apply only the staged changes back to index await this.execGit(['stash', 'apply', '--index', await this.getBackupStash()]) - // Clear any unstaged changes since they are saved in the stash, - // and shouldn't be affected by tasks - await this.execGit(['clean', '-df']) + // Checkout everything just in case there are unstaged files left behind. await this.execGit(['checkout', '.']) // Since only staged files are now present, get a diff of unstaged changes // by comparing current index against original stash, but in reverse From bf532c2af9dbd3514b16768a106fea82ddc99923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20Ja=CC=88ppinen?= Date: Thu, 14 Nov 2019 08:16:58 +0200 Subject: [PATCH 41/64] fix: add all modified files to git index with `git add .` --- lib/gitWorkflow.js | 2 +- test/runAll.unmocked.spec.js | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index 315cfe272..f7dea4f64 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -105,7 +105,7 @@ class GitWorkflow { debug('Detected files modified by tasks:') debug(modifiedFiles) debug('Adding files to index...') - await this.execGit(['add', modifiedFiles]) + await this.execGit(['add', '.']) debug('Done adding files to index!') } diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index b9e4a3281..84d66a56a 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -129,10 +129,13 @@ describe('runAll', () => { }) it('Should commit entire staged file when no errors and linter modifies file', async () => { - // Stage ugly file + // Stage multiple ugly files await appendFile('test.js', testJsFileUgly) await execGit(['add', 'test.js']) + await appendFile('test2.js', testJsFileUgly) + await execGit(['add', 'test2.js']) + // Run lint-staged with `prettier --write` and commit pretty file await gitCommit(fixJsConfig) @@ -140,6 +143,7 @@ describe('runAll', () => { expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('test') expect(await readFile('test.js')).toEqual(testJsFilePretty) + expect(await readFile('test2.js')).toEqual(testJsFilePretty) }) it('Should fail to commit entire staged file when errors from linter', async () => { From e58ebbfa2dbbcd0c05ae13026a65c33ff791e211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20Ja=CC=88ppinen?= Date: Thu, 14 Nov 2019 08:41:14 +0200 Subject: [PATCH 42/64] Revert "fix: no need to run `git clean -df` since untracked changes are stashed" This reverts commit 869bac617dd1ef46e6689027c9d3ec67b3a00934. --- lib/gitWorkflow.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index f7dea4f64..ecc6502bc 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -68,14 +68,16 @@ class GitWorkflow { debug('Done backing up merge state!') } - // Save stash of entire original state, including unstaged and untracked changes. - // This should remove all changes from the index. - // The `--keep-index` option cannot be used since it resurrects deleted files on - // git versions before v2.23.0 (https://github.com/git/git/blob/master/Documentation/RelNotes/2.23.0.txt#L322) + // Get stash of entire original state, including unstaged changes await this.execGit(['stash', 'save', '--quiet', '--include-untracked', STASH]) - // Apply only the staged changes back to index + // Apply index from previous stash back to enable running tasks against + // staged files only. `git stash --keep-index` cannot be used here because of + // a bug affecting deleted files. The bug has been fixed in git v2.23.0 + // See https://github.com/git/git/blob/master/Documentation/RelNotes/2.23.0.txt#L322 await this.execGit(['stash', 'apply', '--index', await this.getBackupStash()]) - // Checkout everything just in case there are unstaged files left behind. + // Clear any unstaged changes since they are saved in the stash, + // and shouldn't be affected by tasks + await this.execGit(['clean', '-df']) await this.execGit(['checkout', '.']) // Since only staged files are now present, get a diff of unstaged changes // by comparing current index against original stash, but in reverse From cfde9ca64bed7fa236eda69e63478c536f9f9068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20Ja=CC=88ppinen?= Date: Thu, 14 Nov 2019 08:41:42 +0200 Subject: [PATCH 43/64] fix: correctly leave only staged files for running tasks --- lib/gitWorkflow.js | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index ecc6502bc..c2127246f 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -68,19 +68,18 @@ class GitWorkflow { debug('Done backing up merge state!') } - // Get stash of entire original state, including unstaged changes + // Get diff of staged modifications. This will be applied back to the index. after stashing all changes. + // The `git stash save --keep-index` option cannot be used since it resurrects deleted files on + // git versions before v2.23.0 (https://github.com/git/git/blob/master/Documentation/RelNotes/2.23.0.txt#L322) + const stagedDiff = await this.execGit(['diff', '--cached']) + + // Save stash of entire original state, including unstaged and untracked changes. + // This should remove all changes from the index. await this.execGit(['stash', 'save', '--quiet', '--include-untracked', STASH]) - // Apply index from previous stash back to enable running tasks against - // staged files only. `git stash --keep-index` cannot be used here because of - // a bug affecting deleted files. The bug has been fixed in git v2.23.0 - // See https://github.com/git/git/blob/master/Documentation/RelNotes/2.23.0.txt#L322 - await this.execGit(['stash', 'apply', '--index', await this.getBackupStash()]) - // Clear any unstaged changes since they are saved in the stash, - // and shouldn't be affected by tasks - await this.execGit(['clean', '-df']) - await this.execGit(['checkout', '.']) - // Since only staged files are now present, get a diff of unstaged changes - // by comparing current index against original stash, but in reverse + + // Apply staged modifications back to the index + await this.execGit([...gitApplyArgs, '--index'], { input: `${stagedDiff}\n` }) + this.unstagedDiff = await this.execGit([ 'diff', '--unified=0', From 7b3a334ac33ffe1bda930583a055fb1db0b6d181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20Ja=CC=88ppinen?= Date: Thu, 14 Nov 2019 10:56:32 +0200 Subject: [PATCH 44/64] fix: support binary files --- lib/gitWorkflow.js | 3 ++- test/runAll.unmocked.spec.js | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index c2127246f..128a96b13 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -71,7 +71,7 @@ class GitWorkflow { // Get diff of staged modifications. This will be applied back to the index. after stashing all changes. // The `git stash save --keep-index` option cannot be used since it resurrects deleted files on // git versions before v2.23.0 (https://github.com/git/git/blob/master/Documentation/RelNotes/2.23.0.txt#L322) - const stagedDiff = await this.execGit(['diff', '--cached']) + const stagedDiff = await this.execGit(['diff', '--binary', '--cached']) // Save stash of entire original state, including unstaged and untracked changes. // This should remove all changes from the index. @@ -82,6 +82,7 @@ class GitWorkflow { this.unstagedDiff = await this.execGit([ 'diff', + '--binary', '--unified=0', '--no-color', '--no-ext-diff', diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 84d66a56a..affb64255 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -516,4 +516,21 @@ describe('runAll', () => { const exists = await fs.exists(readmeFile) expect(exists).toEqual(false) }) + + it('should handle binary files', async () => { + // mark test.js as binary file + await appendFile('.gitattributes', 'test.js binary\n') + + // Stage pretty file + await appendFile('test.js', testJsFilePretty) + await execGit(['add', 'test.js']) + + // Run lint-staged with `prettier --list-different` and commit pretty file + await gitCommit({ config: { '*.js': 'prettier --list-different' } }) + + // Nothing is wrong, so a new commit is created + expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('test') + expect(await readFile('test.js')).toEqual(testJsFilePretty) + }) }) From 5d989acfe3f88989f02d0168cd983ecb059f4509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Fri, 15 Nov 2019 07:18:53 +0200 Subject: [PATCH 45/64] chore: update all dependencies --- lib/execGit.js | 1 + lib/index.js | 2 +- package.json | 41 +- test/__mocks__/cosmiconfig.js | 4 +- test/execGit.spec.js | 4 +- test/index.spec.js | 2 +- yarn.lock | 2558 +++++++++++++++++---------------- 7 files changed, 1316 insertions(+), 1296 deletions(-) diff --git a/lib/execGit.js b/lib/execGit.js index e9194a1b1..461236117 100644 --- a/lib/execGit.js +++ b/lib/execGit.js @@ -8,6 +8,7 @@ module.exports = async function execGit(cmd, options = {}) { try { const { stdout } = await execa('git', [].concat(cmd), { ...options, + all: true, cwd: options.cwd || process.cwd() }) return stdout diff --git a/lib/index.js b/lib/index.js index 15334dc23..bdfd92bba 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,7 +1,7 @@ 'use strict' const dedent = require('dedent') -const cosmiconfig = require('cosmiconfig') +const { cosmiconfig } = require('cosmiconfig') const stringifyObject = require('stringify-object') const printErrors = require('./printErrors') const runAll = require('./runAll') diff --git a/package.json b/package.json index d62b83aab..5b561f17e 100644 --- a/package.json +++ b/package.json @@ -31,45 +31,44 @@ } }, "dependencies": { - "chalk": "^2.4.2", - "commander": "^2.20.0", - "cosmiconfig": "^5.2.1", + "chalk": "^3.0.0", + "commander": "^4.0.1", + "cosmiconfig": "^6.0.0", "debug": "^4.1.1", "dedent": "^0.7.0", - "del": "^5.0.0", - "execa": "^2.0.3", + "execa": "^3.3.0", "listr": "^0.14.3", "log-symbols": "^3.0.0", "micromatch": "^4.0.2", "normalize-path": "^3.0.0", - "please-upgrade-node": "^3.1.1", + "please-upgrade-node": "^3.2.0", "stringify-object": "^3.3.0" }, "devDependencies": { - "@babel/core": "^7.5.5", - "@babel/plugin-proposal-object-rest-spread": "^7.5.5", - "@babel/preset-env": "^7.5.5", - "babel-eslint": "^10.0.2", - "babel-jest": "^24.8.0", + "@babel/core": "^7.7.2", + "@babel/plugin-proposal-object-rest-spread": "^7.6.2", + "@babel/preset-env": "^7.7.1", + "babel-eslint": "^10.0.3", + "babel-jest": "^24.9.0", "commitizen": "3.1.2", "consolemock": "^1.1.0", "cz-conventional-changelog": "2.1.0", - "eslint": "^6.1.0", + "eslint": "^6.6.0", "eslint-config-okonet": "^7.0.2", - "eslint-config-prettier": "^6.0.0", - "eslint-plugin-flowtype": "^3.12.1", + "eslint-config-prettier": "^6.5.0", + "eslint-plugin-flowtype": "^4.4.1", "eslint-plugin-import": "^2.18.2", "eslint-plugin-jsx-a11y": "^6.2.3", - "eslint-plugin-node": "^9.1.0", - "eslint-plugin-prettier": "^3.1.0", - "eslint-plugin-react": "^7.14.2", + "eslint-plugin-node": "^10.0.0", + "eslint-plugin-prettier": "^3.1.1", + "eslint-plugin-react": "^7.16.0", "fs-extra": "^8.1.0", - "husky": "^3.0.1", - "jest": "^24.8.0", + "husky": "^3.0.9", + "jest": "^24.9.0", "jest-snapshot-serializer-ansi": "^1.0.0", "jsonlint": "^1.6.3", - "nanoid": "^2.1.1", - "prettier": "1.18.2" + "nanoid": "^2.1.6", + "prettier": "^1.19.1" }, "config": { "commitizen": { diff --git a/test/__mocks__/cosmiconfig.js b/test/__mocks__/cosmiconfig.js index 86965f8c8..c54105291 100644 --- a/test/__mocks__/cosmiconfig.js +++ b/test/__mocks__/cosmiconfig.js @@ -1,7 +1,7 @@ const actual = require.requireActual('cosmiconfig') function cosmiconfig(name, options) { - return actual(name, options) + return actual.cosmiconfig(name, options) } -module.exports = jest.fn(cosmiconfig) +module.exports.cosmiconfig = jest.fn(cosmiconfig) diff --git a/test/execGit.spec.js b/test/execGit.spec.js index d06ec5d8b..ac84f60d5 100644 --- a/test/execGit.spec.js +++ b/test/execGit.spec.js @@ -6,12 +6,12 @@ describe('execGit', () => { it('should execute git in process.cwd if working copy is not specified', async () => { const cwd = process.cwd() await execGit(['init', 'param']) - expect(execa).toHaveBeenCalledWith('git', ['init', 'param'], { cwd }) + expect(execa).toHaveBeenCalledWith('git', ['init', 'param'], { all: true, cwd }) }) it('should execute git in a given working copy', async () => { const cwd = path.join(process.cwd(), 'test', '__fixtures__') await execGit(['init', 'param'], { cwd }) - expect(execa).toHaveBeenCalledWith('git', ['init', 'param'], { cwd }) + expect(execa).toHaveBeenCalledWith('git', ['init', 'param'], { all: true, cwd }) }) }) diff --git a/test/index.spec.js b/test/index.spec.js index bfc888796..c895c9112 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -1,4 +1,4 @@ -import cosmiconfig from 'cosmiconfig' +import { cosmiconfig } from 'cosmiconfig' import makeConsoleMock from 'consolemock' import path from 'path' diff --git a/yarn.lock b/yarn.lock index 69c9503ad..6d2d3e282 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,19 +9,19 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@^7.1.0", "@babel/core@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" - integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== +"@babel/core@^7.1.0", "@babel/core@^7.7.2": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.2.tgz#ea5b99693bcfc058116f42fa1dd54da412b29d91" + integrity sha512-eeD7VEZKfhK1KUXGiyPFettgF3m513f8FoBSWiQ1xTvl1RAopLs42Wp9+Ze911I6H0N9lNqJMDgoZT7gHsipeQ== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.5.5" - "@babel/helpers" "^7.5.5" - "@babel/parser" "^7.5.5" - "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" - convert-source-map "^1.1.0" + "@babel/generator" "^7.7.2" + "@babel/helpers" "^7.7.0" + "@babel/parser" "^7.7.2" + "@babel/template" "^7.7.0" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.7.2" + convert-source-map "^1.7.0" debug "^4.1.0" json5 "^2.1.0" lodash "^4.17.13" @@ -29,113 +29,120 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.4.0", "@babel/generator@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf" - integrity sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ== +"@babel/generator@^7.4.0", "@babel/generator@^7.7.2": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.2.tgz#2f4852d04131a5e17ea4f6645488b5da66ebf3af" + integrity sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ== dependencies: - "@babel/types" "^7.5.5" + "@babel/types" "^7.7.2" jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" - trim-right "^1.0.1" -"@babel/helper-annotate-as-pure@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" - integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== +"@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.0.tgz#efc54032d43891fe267679e63f6860aa7dbf4a5e" + integrity sha512-k50CQxMlYTYo+GGyUGFwpxKVtxVJi9yh61sXZji3zYHccK9RYliZGSTOgci85T+r+0VFN2nWbGM04PIqwfrpMg== dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.7.0" "@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" - integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w== + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.0.tgz#32dd9551d6ed3a5fc2edc50d6912852aa18274d9" + integrity sha512-Cd8r8zs4RKDwMG/92lpZcnn5WPQ3LAMQbCw42oqUh4s7vsSN5ANUZjMel0OOnxDLq57hoDDbai+ryygYfCTOsw== dependencies: - "@babel/helper-explode-assignable-expression" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/helper-explode-assignable-expression" "^7.7.0" + "@babel/types" "^7.7.0" "@babel/helper-call-delegate@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz#87c1f8ca19ad552a736a7a27b1c1fcf8b1ff1f43" - integrity sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ== + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.7.0.tgz#df8942452c2c1a217335ca7e393b9afc67f668dc" + integrity sha512-Su0Mdq7uSSWGZayGMMQ+z6lnL00mMCnGAbO/R0ZO9odIdB/WNU/VfQKqMQU0fdIsxQYbRjDM4BixIa93SQIpvw== dependencies: - "@babel/helper-hoist-variables" "^7.4.4" - "@babel/traverse" "^7.4.4" - "@babel/types" "^7.4.4" + "@babel/helper-hoist-variables" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" -"@babel/helper-define-map@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz#3dec32c2046f37e09b28c93eb0b103fd2a25d369" - integrity sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg== +"@babel/helper-create-regexp-features-plugin@^7.7.0": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.2.tgz#6f20443778c8fce2af2ff4206284afc0ced65db6" + integrity sha512-pAil/ZixjTlrzNpjx+l/C/wJk002Wo7XbbZ8oujH/AoJ3Juv0iN/UTcPUHXKMFLqsfS0Hy6Aow8M31brUYBlQQ== + dependencies: + "@babel/helper-regex" "^7.4.4" + regexpu-core "^4.6.0" + +"@babel/helper-define-map@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.7.0.tgz#60b0e9fd60def9de5054c38afde8c8ee409c7529" + integrity sha512-kPKWPb0dMpZi+ov1hJiwse9dWweZsz3V9rP4KdytnX1E7z3cTNmFGglwklzFPuqIcHLIY3bgKSs4vkwXXdflQA== dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/types" "^7.5.5" + "@babel/helper-function-name" "^7.7.0" + "@babel/types" "^7.7.0" lodash "^4.17.13" -"@babel/helper-explode-assignable-expression@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" - integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA== +"@babel/helper-explode-assignable-expression@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.0.tgz#db2a6705555ae1f9f33b4b8212a546bc7f9dc3ef" + integrity sha512-CDs26w2shdD1urNUAji2RJXyBFCaR+iBEGnFz3l7maizMkQe3saVw9WtjG1tz8CwbjvlFnaSLVhgnu1SWaherg== dependencies: - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" -"@babel/helper-function-name@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" - integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== +"@babel/helper-function-name@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz#44a5ad151cfff8ed2599c91682dda2ec2c8430a3" + integrity sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q== dependencies: - "@babel/helper-get-function-arity" "^7.0.0" - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/helper-get-function-arity" "^7.7.0" + "@babel/template" "^7.7.0" + "@babel/types" "^7.7.0" -"@babel/helper-get-function-arity@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" - integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== +"@babel/helper-get-function-arity@^7.0.0", "@babel/helper-get-function-arity@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz#c604886bc97287a1d1398092bc666bc3d7d7aa2d" + integrity sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw== dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.7.0" -"@babel/helper-hoist-variables@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz#0298b5f25c8c09c53102d52ac4a98f773eb2850a" - integrity sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w== +"@babel/helper-hoist-variables@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.0.tgz#b4552e4cfe5577d7de7b183e193e84e4ec538c81" + integrity sha512-LUe/92NqsDAkJjjCEWkNe+/PcpnisvnqdlRe19FahVapa4jndeuJ+FBiTX1rcAKWKcJGE+C3Q3tuEuxkSmCEiQ== dependencies: - "@babel/types" "^7.4.4" + "@babel/types" "^7.7.0" -"@babel/helper-member-expression-to-functions@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz#1fb5b8ec4453a93c439ee9fe3aeea4a84b76b590" - integrity sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA== +"@babel/helper-member-expression-to-functions@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.0.tgz#472b93003a57071f95a541ea6c2b098398bcad8a" + integrity sha512-QaCZLO2RtBcmvO/ekOLp8p7R5X2JriKRizeDpm5ChATAFWrrYDcDxPuCIBXKyBjY+i1vYSdcUTMIb8psfxHDPA== dependencies: - "@babel/types" "^7.5.5" + "@babel/types" "^7.7.0" -"@babel/helper-module-imports@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" - integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A== +"@babel/helper-module-imports@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.7.0.tgz#99c095889466e5f7b6d66d98dffc58baaf42654d" + integrity sha512-Dv3hLKIC1jyfTkClvyEkYP2OlkzNvWs5+Q8WgPbxM5LMeorons7iPP91JM+DU7tRbhqA1ZeooPaMFvQrn23RHw== dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.7.0" -"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz#f84ff8a09038dcbca1fd4355661a500937165b4a" - integrity sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-simple-access" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/template" "^7.4.4" - "@babel/types" "^7.5.5" +"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.7.0.tgz#154a69f0c5b8fd4d39e49750ff7ac4faa3f36786" + integrity sha512-rXEefBuheUYQyX4WjV19tuknrJFwyKw0HgzRwbkyTbB+Dshlq7eqkWbyjzToLrMZk/5wKVKdWFluiAsVkHXvuQ== + dependencies: + "@babel/helper-module-imports" "^7.7.0" + "@babel/helper-simple-access" "^7.7.0" + "@babel/helper-split-export-declaration" "^7.7.0" + "@babel/template" "^7.7.0" + "@babel/types" "^7.7.0" lodash "^4.17.13" -"@babel/helper-optimise-call-expression@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" - integrity sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g== +"@babel/helper-optimise-call-expression@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.0.tgz#4f66a216116a66164135dc618c5d8b7a959f9365" + integrity sha512-48TeqmbazjNU/65niiiJIJRc5JozB8acui1OS7bSd6PgxfuovWsvjfWSzlgx+gPFdVveNzUdpdIg5l56Pl5jqg== dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.7.0" "@babel/helper-plugin-utils@^7.0.0": version "7.0.0" @@ -149,60 +156,60 @@ dependencies: lodash "^4.17.13" -"@babel/helper-remap-async-to-generator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" - integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-wrap-function" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-replace-supers@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz#f84ce43df031222d2bad068d2626cb5799c34bc2" - integrity sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.5.5" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" - -"@babel/helper-simple-access@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" - integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w== - dependencies: - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-split-export-declaration@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677" - integrity sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q== - dependencies: - "@babel/types" "^7.4.4" - -"@babel/helper-wrap-function@^7.1.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa" - integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.2.0" - -"@babel/helpers@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e" - integrity sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g== - dependencies: - "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" +"@babel/helper-remap-async-to-generator@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.0.tgz#4d69ec653e8bff5bce62f5d33fc1508f223c75a7" + integrity sha512-pHx7RN8X0UNHPB/fnuDnRXVZ316ZigkO8y8D835JlZ2SSdFKb6yH9MIYRU4fy/KPe5sPHDFOPvf8QLdbAGGiyw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.7.0" + "@babel/helper-wrap-function" "^7.7.0" + "@babel/template" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" + +"@babel/helper-replace-supers@^7.5.5", "@babel/helper-replace-supers@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.7.0.tgz#d5365c8667fe7cbd13b8ddddceb9bd7f2b387512" + integrity sha512-5ALYEul5V8xNdxEeWvRsBzLMxQksT7MaStpxjJf9KsnLxpAKBtfw5NeMKZJSYDa0lKdOcy0g+JT/f5mPSulUgg== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.7.0" + "@babel/helper-optimise-call-expression" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" + +"@babel/helper-simple-access@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.7.0.tgz#97a8b6c52105d76031b86237dc1852b44837243d" + integrity sha512-AJ7IZD7Eem3zZRuj5JtzFAptBw7pMlS3y8Qv09vaBWoFsle0d1kAn5Wq6Q9MyBXITPOKnxwkZKoAm4bopmv26g== + dependencies: + "@babel/template" "^7.7.0" + "@babel/types" "^7.7.0" + +"@babel/helper-split-export-declaration@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz#1365e74ea6c614deeb56ebffabd71006a0eb2300" + integrity sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA== + dependencies: + "@babel/types" "^7.7.0" + +"@babel/helper-wrap-function@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.7.0.tgz#15af3d3e98f8417a60554acbb6c14e75e0b33b74" + integrity sha512-sd4QjeMgQqzshSjecZjOp8uKfUtnpmCyQhKQrVJBBgeHAB/0FPi33h3AbVlVp07qQtMD4QgYSzaMI7VwncNK/w== + dependencies: + "@babel/helper-function-name" "^7.7.0" + "@babel/template" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" + +"@babel/helpers@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.7.0.tgz#359bb5ac3b4726f7c1fde0ec75f64b3f4275d60b" + integrity sha512-VnNwL4YOhbejHb7x/b5F39Zdg5vIQpUUNzJwx0ww1EcVRt41bbGRZWhAURrfY32T5zTT3qwNOQFWpn+P0i0a2g== + dependencies: + "@babel/template" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" "@babel/highlight@^7.0.0": version "7.5.0" @@ -213,24 +220,24 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b" - integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g== +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0", "@babel/parser@^7.7.2": + version "7.7.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.3.tgz#5fad457c2529de476a248f75b0f090b3060af043" + integrity sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A== -"@babel/plugin-proposal-async-generator-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" - integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ== +"@babel/plugin-proposal-async-generator-functions@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.0.tgz#83ef2d6044496b4c15d8b4904e2219e6dccc6971" + integrity sha512-ot/EZVvf3mXtZq0Pd0+tSOfGWMizqmOohXmNZg6LNFjHOV+wOPv7BvVYh8oPR8LhpIP3ye8nNooKL50YRWxpYA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.1.0" + "@babel/helper-remap-async-to-generator" "^7.7.0" "@babel/plugin-syntax-async-generators" "^7.2.0" -"@babel/plugin-proposal-dynamic-import@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz#e532202db4838723691b10a67b8ce509e397c506" - integrity sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw== +"@babel/plugin-proposal-dynamic-import@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.7.0.tgz#dc02a8bad8d653fb59daf085516fa416edd2aa7f" + integrity sha512-7poL3Xi+QFPC7sGAzEIbXUyYzGJwbc2+gSD0AkiC5k52kH2cqHdqxm5hNFfLW3cRSTcx9bN0Fl7/6zWcLLnKAQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-dynamic-import" "^7.2.0" @@ -243,10 +250,10 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-json-strings" "^7.2.0" -"@babel/plugin-proposal-object-rest-spread@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58" - integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw== +"@babel/plugin-proposal-object-rest-spread@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz#8ffccc8f3a6545e9f78988b6bf4fe881b88e8096" + integrity sha512-LDBXlmADCsMZV1Y9OQwMc0MyGZ8Ta/zlD9N67BfQT8uYwkRswiu2hU6nJKrjrt/58aH/vqfQlR/9yId/7A2gWw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" @@ -259,14 +266,13 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" -"@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz#501ffd9826c0b91da22690720722ac7cb1ca9c78" - integrity sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA== +"@babel/plugin-proposal-unicode-property-regex@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.0.tgz#549fe1717a1bd0a2a7e63163841cb37e78179d5d" + integrity sha512-mk34H+hp7kRBWJOOAR0ZMGCydgKMD4iN9TpDRp3IIcbunltxEY89XSimc6WbtSLCDrwcdy/EEw7h5CFCzxTchw== dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" "@babel/plugin-syntax-async-generators@^7.2.0": version "7.2.0" @@ -303,6 +309,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-top-level-await@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.7.0.tgz#f5699549f50bbe8d12b1843a4e82f0a37bb65f4d" + integrity sha512-hi8FUNiFIY1fnUI2n1ViB1DR0R4QeK4iHcTlW6aJkrPoTdb8Rf1EMQ6GT3f67DDkYyWgew9DFoOZ6gOoEsdzTA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-arrow-functions@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" @@ -310,14 +323,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-async-to-generator@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz#89a3848a0166623b5bc481164b5936ab947e887e" - integrity sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg== +"@babel/plugin-transform-async-to-generator@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.0.tgz#e2b84f11952cf5913fe3438b7d2585042772f492" + integrity sha512-vLI2EFLVvRBL3d8roAMqtVY0Bm9C1QzLkdS57hiKrjUBSqsQYrBsMCeOg/0KK7B0eK9V71J5mWcha9yyoI2tZw== dependencies: - "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-module-imports" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.1.0" + "@babel/helper-remap-async-to-generator" "^7.7.0" "@babel/plugin-transform-block-scoped-functions@^7.2.0": version "7.2.0" @@ -326,26 +339,26 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-block-scoping@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz#a35f395e5402822f10d2119f6f8e045e3639a2ce" - integrity sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg== +"@babel/plugin-transform-block-scoping@^7.6.3": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.3.tgz#6e854e51fbbaa84351b15d4ddafe342f3a5d542a" + integrity sha512-7hvrg75dubcO3ZI2rjYTzUrEuh1E9IyDEhhB6qfcooxhDA33xx2MasuLVgdxzcP6R/lipAC6n9ub9maNW6RKdw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.13" -"@babel/plugin-transform-classes@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz#d094299d9bd680a14a2a0edae38305ad60fb4de9" - integrity sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg== +"@babel/plugin-transform-classes@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.0.tgz#b411ecc1b8822d24b81e5d184f24149136eddd4a" + integrity sha512-/b3cKIZwGeUesZheU9jNYcwrEA7f/Bo4IdPmvp7oHgvks2majB5BoT5byAql44fiNQYOPzhk2w8DbgfuafkMoA== dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-define-map" "^7.5.5" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-annotate-as-pure" "^7.7.0" + "@babel/helper-define-map" "^7.7.0" + "@babel/helper-function-name" "^7.7.0" + "@babel/helper-optimise-call-expression" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" - "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/helper-replace-supers" "^7.7.0" + "@babel/helper-split-export-declaration" "^7.7.0" globals "^11.1.0" "@babel/plugin-transform-computed-properties@^7.2.0": @@ -355,21 +368,20 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-destructuring@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz#f6c09fdfe3f94516ff074fe877db7bc9ef05855a" - integrity sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ== +"@babel/plugin-transform-destructuring@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz#44bbe08b57f4480094d57d9ffbcd96d309075ba6" + integrity sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz#361a148bc951444312c69446d76ed1ea8e4450c3" - integrity sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg== +"@babel/plugin-transform-dotall-regex@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.0.tgz#c5c9ecacab3a5e0c11db6981610f0c32fd698b3b" + integrity sha512-3QQlF7hSBnSuM1hQ0pS3pmAbWLax/uGNCbPBND9y+oJ4Y776jsyujG2k0Sn2Aj2a0QwVOiOFL5QVPA7spjvzSA== dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" "@babel/plugin-transform-duplicate-keys@^7.5.0": version "7.5.0" @@ -393,12 +405,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-function-name@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz#e1436116abb0610c2259094848754ac5230922ad" - integrity sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA== +"@babel/plugin-transform-function-name@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.0.tgz#0fa786f1eef52e3b7d4fc02e54b2129de8a04c2a" + integrity sha512-P5HKu0d9+CzZxP5jcrWdpe7ZlFDe24bmqP6a6X8BHEBl/eizAsY8K6LX8LASZL0Jxdjm5eEfzp+FIrxCm/p8bA== dependencies: - "@babel/helper-function-name" "^7.1.0" + "@babel/helper-function-name" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-literals@^7.2.0": @@ -424,39 +436,39 @@ "@babel/helper-plugin-utils" "^7.0.0" babel-plugin-dynamic-import-node "^2.3.0" -"@babel/plugin-transform-modules-commonjs@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz#425127e6045231360858eeaa47a71d75eded7a74" - integrity sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ== +"@babel/plugin-transform-modules-commonjs@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.0.tgz#3e5ffb4fd8c947feede69cbe24c9554ab4113fe3" + integrity sha512-KEMyWNNWnjOom8vR/1+d+Ocz/mILZG/eyHHO06OuBQ2aNhxT62fr4y6fGOplRx+CxCSp3IFwesL8WdINfY/3kg== dependencies: - "@babel/helper-module-transforms" "^7.4.4" + "@babel/helper-module-transforms" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-simple-access" "^7.1.0" + "@babel/helper-simple-access" "^7.7.0" babel-plugin-dynamic-import-node "^2.3.0" -"@babel/plugin-transform-modules-systemjs@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz#e75266a13ef94202db2a0620977756f51d52d249" - integrity sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg== +"@babel/plugin-transform-modules-systemjs@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.7.0.tgz#9baf471213af9761c1617bb12fd278e629041417" + integrity sha512-ZAuFgYjJzDNv77AjXRqzQGlQl4HdUM6j296ee4fwKVZfhDR9LAGxfvXjBkb06gNETPnN0sLqRm9Gxg4wZH6dXg== dependencies: - "@babel/helper-hoist-variables" "^7.4.4" + "@babel/helper-hoist-variables" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" babel-plugin-dynamic-import-node "^2.3.0" -"@babel/plugin-transform-modules-umd@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae" - integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw== +"@babel/plugin-transform-modules-umd@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.7.0.tgz#d62c7da16670908e1d8c68ca0b5d4c0097b69966" + integrity sha512-u7eBA03zmUswQ9LQ7Qw0/ieC1pcAkbp5OQatbWUzY1PaBccvuJXUkYzoN1g7cqp7dbTu6Dp9bXyalBvD04AANA== dependencies: - "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-module-transforms" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-named-capturing-groups-regex@^7.4.5": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz#9d269fd28a370258199b4294736813a60bbdd106" - integrity sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg== +"@babel/plugin-transform-named-capturing-groups-regex@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.7.0.tgz#358e6fd869b9a4d8f5cbc79e4ed4fc340e60dcaf" + integrity sha512-+SicSJoKouPctL+j1pqktRVCgy+xAch1hWWTMy13j0IflnyNjaoskj+DwRQFimHbLqO3sq2oN2CXMvXq3Bgapg== dependencies: - regexp-tree "^0.1.6" + "@babel/helper-create-regexp-features-plugin" "^7.7.0" "@babel/plugin-transform-new-target@^7.4.4": version "7.4.4" @@ -489,10 +501,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-regenerator@^7.4.5": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz#629dc82512c55cee01341fb27bdfcb210354680f" - integrity sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA== +"@babel/plugin-transform-regenerator@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.0.tgz#f1b20b535e7716b622c99e989259d7dd942dd9cc" + integrity sha512-AXmvnC+0wuj/cFkkS/HFHIojxH3ffSXE+ttulrqWjZZRaUOonfJc60e1wSNT4rV8tIunvu/R3wCp71/tLAa9xg== dependencies: regenerator-transform "^0.14.0" @@ -510,10 +522,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-spread@^7.2.0": - version "7.2.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" - integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== +"@babel/plugin-transform-spread@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.6.2.tgz#fc77cf798b24b10c46e1b51b1b88c2bf661bb8dd" + integrity sha512-DpSvPFryKdK1x+EDJYCy28nmAaIMdxmhot62jAXF/o99iA33Zj2Lmcp3vDmz+MUh0LNYVPvfj5iC3feb3/+PFg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -540,106 +552,106 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-unicode-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz#ab4634bb4f14d36728bf5978322b35587787970f" - integrity sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA== +"@babel/plugin-transform-unicode-regex@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.0.tgz#743d9bcc44080e3cc7d49259a066efa30f9187a3" + integrity sha512-RrThb0gdrNwFAqEAAx9OWgtx6ICK69x7i9tCnMdVrxQwSDp/Abu9DXFU5Hh16VP33Rmxh04+NGW28NsIkFvFKA== dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" -"@babel/preset-env@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.5.5.tgz#bc470b53acaa48df4b8db24a570d6da1fef53c9a" - integrity sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A== +"@babel/preset-env@^7.7.1": + version "7.7.1" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.7.1.tgz#04a2ff53552c5885cf1083e291c8dd5490f744bb" + integrity sha512-/93SWhi3PxcVTDpSqC+Dp4YxUu3qZ4m7I76k0w73wYfn7bGVuRIO4QUz95aJksbS+AD1/mT1Ie7rbkT0wSplaA== dependencies: - "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-module-imports" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-async-generator-functions" "^7.2.0" - "@babel/plugin-proposal-dynamic-import" "^7.5.0" + "@babel/plugin-proposal-async-generator-functions" "^7.7.0" + "@babel/plugin-proposal-dynamic-import" "^7.7.0" "@babel/plugin-proposal-json-strings" "^7.2.0" - "@babel/plugin-proposal-object-rest-spread" "^7.5.5" + "@babel/plugin-proposal-object-rest-spread" "^7.6.2" "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-proposal-unicode-property-regex" "^7.7.0" "@babel/plugin-syntax-async-generators" "^7.2.0" "@babel/plugin-syntax-dynamic-import" "^7.2.0" "@babel/plugin-syntax-json-strings" "^7.2.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@babel/plugin-syntax-top-level-await" "^7.7.0" "@babel/plugin-transform-arrow-functions" "^7.2.0" - "@babel/plugin-transform-async-to-generator" "^7.5.0" + "@babel/plugin-transform-async-to-generator" "^7.7.0" "@babel/plugin-transform-block-scoped-functions" "^7.2.0" - "@babel/plugin-transform-block-scoping" "^7.5.5" - "@babel/plugin-transform-classes" "^7.5.5" + "@babel/plugin-transform-block-scoping" "^7.6.3" + "@babel/plugin-transform-classes" "^7.7.0" "@babel/plugin-transform-computed-properties" "^7.2.0" - "@babel/plugin-transform-destructuring" "^7.5.0" - "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/plugin-transform-destructuring" "^7.6.0" + "@babel/plugin-transform-dotall-regex" "^7.7.0" "@babel/plugin-transform-duplicate-keys" "^7.5.0" "@babel/plugin-transform-exponentiation-operator" "^7.2.0" "@babel/plugin-transform-for-of" "^7.4.4" - "@babel/plugin-transform-function-name" "^7.4.4" + "@babel/plugin-transform-function-name" "^7.7.0" "@babel/plugin-transform-literals" "^7.2.0" "@babel/plugin-transform-member-expression-literals" "^7.2.0" "@babel/plugin-transform-modules-amd" "^7.5.0" - "@babel/plugin-transform-modules-commonjs" "^7.5.0" - "@babel/plugin-transform-modules-systemjs" "^7.5.0" - "@babel/plugin-transform-modules-umd" "^7.2.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.4.5" + "@babel/plugin-transform-modules-commonjs" "^7.7.0" + "@babel/plugin-transform-modules-systemjs" "^7.7.0" + "@babel/plugin-transform-modules-umd" "^7.7.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.7.0" "@babel/plugin-transform-new-target" "^7.4.4" "@babel/plugin-transform-object-super" "^7.5.5" "@babel/plugin-transform-parameters" "^7.4.4" "@babel/plugin-transform-property-literals" "^7.2.0" - "@babel/plugin-transform-regenerator" "^7.4.5" + "@babel/plugin-transform-regenerator" "^7.7.0" "@babel/plugin-transform-reserved-words" "^7.2.0" "@babel/plugin-transform-shorthand-properties" "^7.2.0" - "@babel/plugin-transform-spread" "^7.2.0" + "@babel/plugin-transform-spread" "^7.6.2" "@babel/plugin-transform-sticky-regex" "^7.2.0" "@babel/plugin-transform-template-literals" "^7.4.4" "@babel/plugin-transform-typeof-symbol" "^7.2.0" - "@babel/plugin-transform-unicode-regex" "^7.4.4" - "@babel/types" "^7.5.5" + "@babel/plugin-transform-unicode-regex" "^7.7.0" + "@babel/types" "^7.7.1" browserslist "^4.6.0" core-js-compat "^3.1.1" invariant "^2.2.2" js-levenshtein "^1.1.3" semver "^5.5.0" -"@babel/runtime@^7.4.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" - integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== +"@babel/runtime@^7.4.5", "@babel/runtime@^7.6.3": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.2.tgz#111a78002a5c25fc8e3361bedc9529c696b85a6a" + integrity sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw== dependencies: regenerator-runtime "^0.13.2" -"@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237" - integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw== +"@babel/template@^7.4.0", "@babel/template@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.7.0.tgz#4fadc1b8e734d97f56de39c77de76f2562e597d0" + integrity sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.4.4" - "@babel/types" "^7.4.4" + "@babel/parser" "^7.7.0" + "@babel/types" "^7.7.0" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb" - integrity sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.7.2.tgz#ef0a65e07a2f3c550967366b3d9b62a2dcbeae09" + integrity sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.5.5" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/parser" "^7.5.5" - "@babel/types" "^7.5.5" + "@babel/generator" "^7.7.2" + "@babel/helper-function-name" "^7.7.0" + "@babel/helper-split-export-declaration" "^7.7.0" + "@babel/parser" "^7.7.2" + "@babel/types" "^7.7.2" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a" - integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw== +"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.7.0", "@babel/types@^7.7.1", "@babel/types@^7.7.2": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.2.tgz#550b82e5571dcd174af576e23f0adba7ffc683f7" + integrity sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA== dependencies: esutils "^2.0.2" lodash "^4.17.13" @@ -653,76 +665,77 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@jest/console@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.7.1.tgz#32a9e42535a97aedfe037e725bd67e954b459545" - integrity sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg== +"@jest/console@^24.7.1", "@jest/console@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" + integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ== dependencies: - "@jest/source-map" "^24.3.0" + "@jest/source-map" "^24.9.0" chalk "^2.0.1" slash "^2.0.0" -"@jest/core@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.8.0.tgz#fbbdcd42a41d0d39cddbc9f520c8bab0c33eed5b" - integrity sha512-R9rhAJwCBQzaRnrRgAdVfnglUuATXdwTRsYqs6NMdVcAl5euG8LtWDe+fVkN27YfKVBW61IojVsXKaOmSnqd/A== +"@jest/core@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.9.0.tgz#2ceccd0b93181f9c4850e74f2a9ad43d351369c4" + integrity sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A== dependencies: "@jest/console" "^24.7.1" - "@jest/reporters" "^24.8.0" - "@jest/test-result" "^24.8.0" - "@jest/transform" "^24.8.0" - "@jest/types" "^24.8.0" + "@jest/reporters" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" ansi-escapes "^3.0.0" chalk "^2.0.1" exit "^0.1.2" graceful-fs "^4.1.15" - jest-changed-files "^24.8.0" - jest-config "^24.8.0" - jest-haste-map "^24.8.0" - jest-message-util "^24.8.0" + jest-changed-files "^24.9.0" + jest-config "^24.9.0" + jest-haste-map "^24.9.0" + jest-message-util "^24.9.0" jest-regex-util "^24.3.0" - jest-resolve-dependencies "^24.8.0" - jest-runner "^24.8.0" - jest-runtime "^24.8.0" - jest-snapshot "^24.8.0" - jest-util "^24.8.0" - jest-validate "^24.8.0" - jest-watcher "^24.8.0" + jest-resolve "^24.9.0" + jest-resolve-dependencies "^24.9.0" + jest-runner "^24.9.0" + jest-runtime "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + jest-watcher "^24.9.0" micromatch "^3.1.10" p-each-series "^1.0.0" - pirates "^4.0.1" realpath-native "^1.1.0" rimraf "^2.5.4" + slash "^2.0.0" strip-ansi "^5.0.0" -"@jest/environment@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.8.0.tgz#0342261383c776bdd652168f68065ef144af0eac" - integrity sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw== - dependencies: - "@jest/fake-timers" "^24.8.0" - "@jest/transform" "^24.8.0" - "@jest/types" "^24.8.0" - jest-mock "^24.8.0" - -"@jest/fake-timers@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.8.0.tgz#2e5b80a4f78f284bcb4bd5714b8e10dd36a8d3d1" - integrity sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw== - dependencies: - "@jest/types" "^24.8.0" - jest-message-util "^24.8.0" - jest-mock "^24.8.0" - -"@jest/reporters@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.8.0.tgz#075169cd029bddec54b8f2c0fc489fd0b9e05729" - integrity sha512-eZ9TyUYpyIIXfYCrw0UHUWUvE35vx5I92HGMgS93Pv7du+GHIzl+/vh8Qj9MCWFK/4TqyttVBPakWMOfZRIfxw== - dependencies: - "@jest/environment" "^24.8.0" - "@jest/test-result" "^24.8.0" - "@jest/transform" "^24.8.0" - "@jest/types" "^24.8.0" +"@jest/environment@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18" + integrity sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ== + dependencies: + "@jest/fake-timers" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + +"@jest/fake-timers@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" + integrity sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A== + dependencies: + "@jest/types" "^24.9.0" + jest-message-util "^24.9.0" + jest-mock "^24.9.0" + +"@jest/reporters@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" + integrity sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" chalk "^2.0.1" exit "^0.1.2" glob "^7.1.2" @@ -730,95 +743,75 @@ istanbul-lib-instrument "^3.0.1" istanbul-lib-report "^2.0.4" istanbul-lib-source-maps "^3.0.1" - istanbul-reports "^2.1.1" - jest-haste-map "^24.8.0" - jest-resolve "^24.8.0" - jest-runtime "^24.8.0" - jest-util "^24.8.0" + istanbul-reports "^2.2.6" + jest-haste-map "^24.9.0" + jest-resolve "^24.9.0" + jest-runtime "^24.9.0" + jest-util "^24.9.0" jest-worker "^24.6.0" - node-notifier "^5.2.1" + node-notifier "^5.4.2" slash "^2.0.0" source-map "^0.6.0" string-length "^2.0.0" -"@jest/source-map@^24.3.0": - version "24.3.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.3.0.tgz#563be3aa4d224caf65ff77edc95cd1ca4da67f28" - integrity sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag== +"@jest/source-map@^24.3.0", "@jest/source-map@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" + integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg== dependencies: callsites "^3.0.0" graceful-fs "^4.1.15" source-map "^0.6.0" -"@jest/test-result@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.8.0.tgz#7675d0aaf9d2484caa65e048d9b467d160f8e9d3" - integrity sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng== +"@jest/test-result@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" + integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA== dependencies: - "@jest/console" "^24.7.1" - "@jest/types" "^24.8.0" + "@jest/console" "^24.9.0" + "@jest/types" "^24.9.0" "@types/istanbul-lib-coverage" "^2.0.0" -"@jest/test-sequencer@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.8.0.tgz#2f993bcf6ef5eb4e65e8233a95a3320248cf994b" - integrity sha512-OzL/2yHyPdCHXEzhoBuq37CE99nkme15eHkAzXRVqthreWZamEMA0WoetwstsQBCXABhczpK03JNbc4L01vvLg== +"@jest/test-sequencer@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz#f8f334f35b625a4f2f355f2fe7e6036dad2e6b31" + integrity sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A== dependencies: - "@jest/test-result" "^24.8.0" - jest-haste-map "^24.8.0" - jest-runner "^24.8.0" - jest-runtime "^24.8.0" + "@jest/test-result" "^24.9.0" + jest-haste-map "^24.9.0" + jest-runner "^24.9.0" + jest-runtime "^24.9.0" -"@jest/transform@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.8.0.tgz#628fb99dce4f9d254c6fd9341e3eea262e06fef5" - integrity sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA== +"@jest/transform@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56" + integrity sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" babel-plugin-istanbul "^5.1.0" chalk "^2.0.1" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.1.15" - jest-haste-map "^24.8.0" - jest-regex-util "^24.3.0" - jest-util "^24.8.0" + jest-haste-map "^24.9.0" + jest-regex-util "^24.9.0" + jest-util "^24.9.0" micromatch "^3.1.10" + pirates "^4.0.1" realpath-native "^1.1.0" slash "^2.0.0" source-map "^0.6.1" write-file-atomic "2.4.1" -"@jest/types@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.8.0.tgz#f31e25948c58f0abd8c845ae26fcea1491dea7ad" - integrity sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg== +"@jest/types@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" + integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^12.0.9" - -"@nodelib/fs.scandir@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.1.tgz#7fa8fed654939e1a39753d286b48b4836d00e0eb" - integrity sha512-NT/skIZjgotDSiXs0WqYhgcuBKhUMgfekCmCGtkUAiLqZdOnrdjmZr9wRl3ll64J9NF79uZ4fk16Dx0yMc/Xbg== - dependencies: - "@nodelib/fs.stat" "2.0.1" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.1", "@nodelib/fs.stat@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.1.tgz#814f71b1167390cfcb6a6b3d9cdeb0951a192c14" - integrity sha512-+RqhBlLn6YRBGOIoVYthsG0J9dfpO79eJyN7BYBkZJtfqrBwf2KK+rD/M/yjZR6WBmIhAgOV7S60eCgaSWtbFw== - -"@nodelib/fs.walk@^1.2.1": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.2.tgz#6a6450c5e17012abd81450eb74949a4d970d2807" - integrity sha512-J/DR3+W12uCzAJkw7niXDcqcKBg6+5G5Q/ZpThpGNzAUz70eOR6RV4XnnSN01qHZiVl0eavoxJsBypQoKsV2QQ== - dependencies: - "@nodelib/fs.scandir" "2.1.1" - fastq "^1.6.0" + "@types/yargs" "^13.0.0" "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" @@ -828,9 +821,9 @@ any-observable "^0.3.0" "@types/babel__core@^7.1.0": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.2.tgz#608c74f55928033fce18b99b213c16be4b3d114f" - integrity sha512-cfCCrFmiGY/yq0NuKNxIQvZFy9kY/1immpSpTngOnyIbD4+eJOG5mxphhHDv3CHL9GltO4GcKr54kGBg3RNdbg== + version "7.1.3" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30" + integrity sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -839,9 +832,9 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.0.2.tgz#d2112a6b21fad600d7674274293c85dce0cb47fc" - integrity sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ== + version "7.6.0" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.0.tgz#f1ec1c104d1bb463556ecb724018ab788d0c172a" + integrity sha512-c1mZUu4up5cp9KROs/QAw0gTeHrw/x7m52LcnvMxxOZ03DmLwPV0MlGmlgzV3cnSdjhJOZsj7E7FHeioai+egw== dependencies: "@babel/types" "^7.0.0" @@ -860,19 +853,10 @@ dependencies: "@babel/types" "^7.3.0" -"@types/events@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" - integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== - -"@types/glob@^7.1.1": - version "7.1.1" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" - integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== - dependencies: - "@types/events" "*" - "@types/minimatch" "*" - "@types/node" "*" +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": version "2.0.1" @@ -894,30 +878,32 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" -"@types/minimatch@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" - integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== - -"@types/node@*": - version "12.6.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c" - integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg== - "@types/normalize-package-data@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== -"@types/yargs@^12.0.2", "@types/yargs@^12.0.9": - version "12.0.12" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.12.tgz#45dd1d0638e8c8f153e87d296907659296873916" - integrity sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw== +"@types/yargs-parser@*": + version "13.1.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" + integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg== + +"@types/yargs@^13.0.0": + version "13.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.3.tgz#76482af3981d4412d65371a318f992d33464a380" + integrity sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ== + dependencies: + "@types/yargs-parser" "*" JSV@^4.0.x: version "4.0.2" @@ -925,9 +911,9 @@ JSV@^4.0.x: integrity sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c= abab@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f" - integrity sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w== + version "2.0.3" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" + integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== abbrev@1: version "1.1.1" @@ -935,17 +921,17 @@ abbrev@1: integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== acorn-globals@^4.1.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.2.tgz#4e2c2313a597fd589720395f6354b41cd5ec8006" - integrity sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ== + version "4.3.4" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" + integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== dependencies: acorn "^6.0.1" acorn-walk "^6.0.1" -acorn-jsx@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" - integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== +acorn-jsx@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384" + integrity sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw== acorn-walk@^6.0.1: version "6.2.0" @@ -957,10 +943,15 @@ acorn@^5.5.3: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== -acorn@^6.0.1, acorn@^6.0.7: - version "6.2.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51" - integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== +acorn@^6.0.1: + version "6.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" + integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA== + +acorn@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c" + integrity sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ== agent-base@^4.3.0: version "4.3.0" @@ -979,11 +970,18 @@ ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: +ansi-escapes@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== +ansi-escapes@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.2.1.tgz#4dccdb846c3eee10f6d64dea66273eab90c37228" + integrity sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q== + dependencies: + type-fest "^0.5.2" + ansi-regex@^2.0.0, ansi-regex@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -999,6 +997,11 @@ ansi-regex@^4.0.0, ansi-regex@^4.1.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -1011,6 +1014,14 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +ansi-styles@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.0.tgz#5681f0dcf7ae5880a7841d8831c4724ed9cc0172" + integrity sha512-7kFQgnEaMdRtwf6uSfUnVr9gSGC7faurn+J/Mv90/W+iTtN0405/nLdopfMWwchyxhbGYl6TC4Sccn9TUkGAgg== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + ansi-styles@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" @@ -1085,11 +1096,6 @@ array-includes@^3.0.3: define-properties "^1.1.2" es-abstract "^1.7.0" -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" @@ -1123,9 +1129,9 @@ astral-regex@^1.0.0: integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== async-limiter@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" - integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== asynckit@^0.4.0: version "0.4.0" @@ -1154,28 +1160,28 @@ axobject-query@^2.0.2: dependencies: ast-types-flow "0.0.7" -babel-eslint@^10.0.2: - version "10.0.2" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.2.tgz#182d5ac204579ff0881684b040560fdcc1558456" - integrity sha512-UdsurWPtgiPgpJ06ryUnuaSXC2s0WoSZnQmEpbAH65XZSdwowgN5MvyP7e88nW07FYXv72erVtpBkxyDVKhH1Q== +babel-eslint@^10.0.3: + version "10.0.3" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.3.tgz#81a2c669be0f205e19462fed2482d33e4687a88a" + integrity sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA== dependencies: "@babel/code-frame" "^7.0.0" "@babel/parser" "^7.0.0" "@babel/traverse" "^7.0.0" "@babel/types" "^7.0.0" - eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" + resolve "^1.12.0" -babel-jest@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.8.0.tgz#5c15ff2b28e20b0f45df43fe6b7f2aae93dba589" - integrity sha512-+5/kaZt4I9efoXzPlZASyK/lN9qdRKmmUav9smVc0ruPQD7IsfucQ87gpOE8mn2jbDuS6M/YOW6n3v9ZoIfgnw== +babel-jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54" + integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw== dependencies: - "@jest/transform" "^24.8.0" - "@jest/types" "^24.8.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" "@types/babel__core" "^7.1.0" babel-plugin-istanbul "^5.1.0" - babel-preset-jest "^24.6.0" + babel-preset-jest "^24.9.0" chalk "^2.4.2" slash "^2.0.0" @@ -1196,10 +1202,10 @@ babel-plugin-istanbul@^5.1.0: istanbul-lib-instrument "^3.3.0" test-exclude "^5.2.3" -babel-plugin-jest-hoist@^24.6.0: - version "24.6.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.6.0.tgz#f7f7f7ad150ee96d7a5e8e2c5da8319579e78019" - integrity sha512-3pKNH6hMt9SbOv0F3WVmy5CWQ4uogS3k0GY5XLyQHJ9EGpAT9XWkFd2ZiXXtkwFHdAHa5j7w7kfxSP5lAIwu7w== +babel-plugin-jest-hoist@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756" + integrity sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw== dependencies: "@types/babel__traverse" "^7.0.6" @@ -1212,13 +1218,13 @@ babel-polyfill@^6.26.0: core-js "^2.5.0" regenerator-runtime "^0.10.5" -babel-preset-jest@^24.6.0: - version "24.6.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.6.0.tgz#66f06136eefce87797539c0d63f1769cc3915984" - integrity sha512-pdZqLEdmy1ZK5kyRUfvBb2IfTPb2BUvIJczlPspS8fWmBQslNNDBqVfh7BW5leOVJMDZKzjD8XEyABTk6gQ5yw== +babel-preset-jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc" + integrity sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg== dependencies: "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^24.6.0" + babel-plugin-jest-hoist "^24.9.0" babel-runtime@^6.26.0: version "6.26.0" @@ -1296,19 +1302,19 @@ browser-resolve@^1.11.3: dependencies: resolve "1.1.7" -browserslist@^4.6.0, browserslist@^4.6.2: - version "4.6.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453" - integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA== +browserslist@^4.6.0, browserslist@^4.7.2: + version "4.7.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.2.tgz#1bb984531a476b5d389cedecb195b2cd69fb1348" + integrity sha512-uZavT/gZXJd2UTi9Ov7/Z340WOSQ3+m1iBVRUknf+okKxonL9P83S3ctiBDtuRmRu8PiCHjqyueqQ9HYlJhxiw== dependencies: - caniuse-lite "^1.0.30000984" - electron-to-chromium "^1.3.191" - node-releases "^1.1.25" + caniuse-lite "^1.0.30001004" + electron-to-chromium "^1.3.295" + node-releases "^1.1.38" bser@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.0.tgz#65fc784bf7f87c009b973c12db6546902fa9c7b5" - integrity sha512-8zsjWrQkkBoLK6uxASk1nJ2SKv97ltiGDo6A3wA0/yRPz+CwmEyDo0hUrhIuukG2JHpAl3bvFIixw2/3Hi0DOg== + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== dependencies: node-int64 "^0.4.0" @@ -1361,15 +1367,15 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camelcase@^5.0.0: +camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-lite@^1.0.30000984: - version "1.0.30000985" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000985.tgz#0eb40f6c8a8c219155cbe43c4975c0efb4a0f77f" - integrity sha512-1ngiwkgqAYPG0JSSUp3PUDGPKKY59EK7NrGGX+VOxaKCNzRbNc7uXMny+c3VJfZxtoK3wSImTvG9T9sXiTw2+w== +caniuse-lite@^1.0.30001004: + version "1.0.30001010" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001010.tgz#397a14034d384260453cc81994f494626d34b938" + integrity sha512-RA5GH9YjFNea4ZQszdWgh2SC+dpLiRAg4VDQS2b5JRI45OxmbGrYocYHTa9x0bKMQUE7uvHkNPNffUr+pCxSGw== capture-exit@^2.0.0: version "2.0.0" @@ -1403,6 +1409,14 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" @@ -1418,9 +1432,9 @@ chardet@^0.7.0: integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== chownr@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.2.tgz#a18f1e0b269c8a6a5d3c86eb298beb14c3dd7bf6" - integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A== + version "1.1.3" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" + integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== ci-info@^2.0.0: version "2.0.0" @@ -1456,6 +1470,13 @@ cli-cursor@^2.0.0, cli-cursor@^2.1.0: dependencies: restore-cursor "^2.0.0" +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + cli-truncate@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" @@ -1469,14 +1490,14 @@ cli-width@^2.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= -cliui@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" co@^4.6.0: version "4.6.0" @@ -1503,11 +1524,23 @@ color-convert@^1.9.0: dependencies: color-name "1.1.3" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + 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= +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -1515,10 +1548,15 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.11.0, commander@^2.20.0, commander@~2.20.0: - version "2.20.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" - integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== +commander@^2.11.0, commander@~2.20.3: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.0.1.tgz#b67622721785993182e807f4883633e6401ba53c" + integrity sha512-IPF4ouhCP+qdlcmCedhxX4xiGBPyigb8v5NeUp+0LyhwLgxMqyp3S0vl7TAPfS/hiP7FC3caI/PB9lTmP8r1NA== commitizen@3.1.2: version "3.1.2" @@ -1569,14 +1607,14 @@ contains-path@^0.1.0: integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= conventional-commit-types@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/conventional-commit-types/-/conventional-commit-types-2.1.1.tgz#352eb53f56fbc7c1a6c1ba059c2b6670c90b2a8a" - integrity sha512-0Ts+fEdmjqYDOQ1yZ+LNgdSPO335XZw9qC10M7CxtLP3nIMGmeMhmkM8Taffa4+MXN13bRPlp0CtH+QfOzKTzw== + version "2.3.0" + resolved "https://registry.yarnpkg.com/conventional-commit-types/-/conventional-commit-types-2.3.0.tgz#bc3c8ebba0a9e4b3ecc548f1d0674e251ab8be22" + integrity sha512-6iB39PrcGYdz0n3z31kj6/Km6mK9hm9oMRhwcLnKxE7WNoeRKZbTAobliKrbYZ5jqyCvtcVEfjCiaEzhL3AVmQ== -convert-source-map@^1.1.0, convert-source-map@^1.4.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" - integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== +convert-source-map@^1.4.0, convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== dependencies: safe-buffer "~5.1.1" @@ -1586,23 +1624,17 @@ copy-descriptor@^0.1.0: integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-js-compat@^3.1.1: - version "3.1.4" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.1.4.tgz#e4d0c40fbd01e65b1d457980fe4112d4358a7408" - integrity sha512-Z5zbO9f1d0YrJdoaQhphVAnKPimX92D6z8lCGphH89MNRxlL1prI9ExJPqVwP0/kgkQCv8c4GJGT8X16yUncOg== + version "3.4.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.4.1.tgz#e12c5a3ef9fcb50fd9d9a32805bfe674f9139246" + integrity sha512-YdeJI26gLc0CQJ9asLE5obEgBz2I0+CIgnoTbS2T0d5IPQw/OCgCIFR527RmpduxjrB3gSEHoGOCTq9sigOyfw== dependencies: - browserslist "^4.6.2" - core-js-pure "3.1.4" - semver "^6.1.1" - -core-js-pure@3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.1.4.tgz#5fa17dc77002a169a3566cc48dc774d2e13e3769" - integrity sha512-uJ4Z7iPNwiu1foygbcZYJsJs1jiXrTTCvxfLDXNhI/I+NHbSIEyr548y4fcsCEyWY0XgfAG/qqaunJ1SThHenA== + browserslist "^4.7.2" + semver "^6.3.0" core-js@^2.4.0, core-js@^2.5.0: - version "2.6.9" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" - integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== + version "2.6.10" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.10.tgz#8a5b8391f8cc7013da703411ce5b585706300d7f" + integrity sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -1619,6 +1651,17 @@ cosmiconfig@^5.2.1: js-yaml "^3.13.1" parse-json "^4.0.0" +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + 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" @@ -1630,6 +1673,15 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" + integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" @@ -1653,7 +1705,7 @@ cz-conventional-changelog@2.1.0: right-pad "^1.0.1" word-wrap "^1.0.3" -d@1: +d@1, d@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== @@ -1762,17 +1814,6 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" -del@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/del/-/del-5.0.0.tgz#4fa698b7a1ffb4e2ab3e8929ed699799654d6720" - integrity sha512-TfU3nUY0WDIhN18eq+pgpbLY9AfL5RfiE9czKaTSolc6aK7qASXfDErvYgjV1UqCR4sNXDoxO0/idPmhDUt2Sg== - dependencies: - globby "^10.0.0" - is-path-cwd "^2.0.0" - is-path-in-cwd "^2.0.0" - p-map "^2.0.0" - rimraf "^2.6.3" - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1803,17 +1844,10 @@ detect-newline@^2.1.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= -diff-sequences@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.3.0.tgz#0f20e8a1df1abddaf4d9c226680952e64118b975" - integrity sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" +diff-sequences@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" + integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== doctrine@1.5.0: version "1.5.0" @@ -1852,10 +1886,10 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -electron-to-chromium@^1.3.191: - version "1.3.199" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.199.tgz#f9a62a74cda77854310a2abffde8b75591ea09a1" - integrity sha512-gachlDdHSK47s0N2e58GH9HMC6Z4ip0SfmYUa5iEbE50AKaOUXysaJnXMfKj0xB245jWbYcyFSH+th3rqsF8hA== +electron-to-chromium@^1.3.295: + version "1.3.306" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.306.tgz#e8265301d053d5f74e36cb876486830261fbe946" + integrity sha512-frDqXvrIROoYvikSKTIKbHbzO6M3/qC6kCIt/1FOa9kALe++c4VAJnwjSFvf1tYLEUsP2n9XZ4XSCyqc3l7A/A== elegant-spinner@^1.0.1: version "1.0.1" @@ -1867,10 +1901,15 @@ emoji-regex@^7.0.1, emoji-regex@^7.0.2: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + end-of-stream@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" - integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" @@ -1881,35 +1920,39 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.11.0, es-abstract@^1.12.0, es-abstract@^1.5.1, es-abstract@^1.7.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" - integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== +es-abstract@^1.12.0, es-abstract@^1.15.0, es-abstract@^1.5.1, es-abstract@^1.7.0: + version "1.16.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.16.0.tgz#d3a26dc9c3283ac9750dca569586e976d9dcc06d" + integrity sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg== dependencies: es-to-primitive "^1.2.0" function-bind "^1.1.1" has "^1.0.3" + has-symbols "^1.0.0" is-callable "^1.1.4" is-regex "^1.0.4" - object-keys "^1.0.12" + object-inspect "^1.6.0" + object-keys "^1.1.1" + string.prototype.trimleft "^2.1.0" + string.prototype.trimright "^2.1.0" es-to-primitive@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" - integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== dependencies: is-callable "^1.1.4" is-date-object "^1.0.1" is-symbol "^1.0.2" es5-ext@^0.10.35, es5-ext@^0.10.45, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: - version "0.10.50" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.50.tgz#6d0e23a0abdb27018e5ac4fd09b412bc5517a778" - integrity sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw== + version "0.10.52" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.52.tgz#bb21777e919a04263736ded120a9d665f10ea63f" + integrity sha512-bWCbE9fbpYQY4CU6hJbJ1vSz70EClMlDgJ7BmwI+zEJhxrwjesZRPglGJlsZhu0334U3hI+gaspwksH9IGD6ag== dependencies: es6-iterator "~2.0.3" - es6-symbol "~3.1.1" - next-tick "^1.0.0" + es6-symbol "~3.1.2" + next-tick "~1.0.0" es6-iterator@^2.0.3, es6-iterator@~2.0.3: version "2.0.3" @@ -1932,13 +1975,13 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -es6-symbol@^3.1.1, es6-symbol@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" - integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= +es6-symbol@^3.1.1, es6-symbol@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== dependencies: - d "1" - es5-ext "~0.10.14" + d "^1.0.1" + ext "^1.1.2" es6-weak-map@^2.0.2: version "2.0.3" @@ -1956,9 +1999,9 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= escodegen@^1.9.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.1.tgz#c485ff8d6b4cdb89e27f4a856e91f118401ca510" - integrity sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw== + version "1.12.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.0.tgz#f763daf840af172bb3a2b6dd7219c0e17f7ff541" + integrity sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg== dependencies: esprima "^3.1.3" estraverse "^4.2.0" @@ -1974,10 +2017,10 @@ eslint-config-okonet@^7.0.2: dependencies: install-peerdeps "^1.2.0" -eslint-config-prettier@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.0.0.tgz#f429a53bde9fc7660e6353910fd996d6284d3c25" - integrity sha512-vDrcCFE3+2ixNT5H83g28bO/uYAwibJxerXPj+E7op4qzBCsAV36QfvdAyVOoNxKAH2Os/e01T/2x++V0LPukA== +eslint-config-prettier@^6.5.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.5.0.tgz#aaf9a495e2a816865e541bfdbb73a65cc162b3eb" + integrity sha512-cjXp8SbO9VFGW/Z7mbTydqS9to8Z58E5aYhj3e1+Hx7lS9s6gL5ILKNpCqZAFOVYRcSkWPFYljHrEh8QFEK5EQ== dependencies: get-stdin "^6.0.0" @@ -1997,20 +2040,20 @@ eslint-module-utils@^2.4.0: debug "^2.6.8" pkg-dir "^2.0.0" -eslint-plugin-es@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz#475f65bb20c993fc10e8c8fe77d1d60068072da6" - integrity sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw== +eslint-plugin-es@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz#0f5f5da5f18aa21989feebe8a73eadefb3432976" + integrity sha512-f6fceVtg27BR02EYnBhgWLFQfK6bN4Ll0nQFrBHOlCsAyxeZkn0NHns5O0YZOPrV1B3ramd6cgFwaoFLcSkwEQ== dependencies: - eslint-utils "^1.3.0" - regexpp "^2.0.1" + eslint-utils "^1.4.2" + regexpp "^3.0.0" -eslint-plugin-flowtype@^3.12.1: - version "3.12.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-3.12.1.tgz#b673c716b578c9aa66887feef3bc146f8cbe1c21" - integrity sha512-NZqf5iRgsfHOC31HQdtX2pvzCi0n/j9pB+L7Cf9QtuYxpx0i2wObT+R3rPKhQK4KtEDzGuzPYVf75j4eg+s9ZQ== +eslint-plugin-flowtype@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-4.4.1.tgz#b388f42bdc1237f68a8010d2ede52cd67a057e40" + integrity sha512-TNkrdJbvmBEIf02tjMKrYmLILV7OVwcvDUAnrnoGQZJhBMsu61X7E7/A1yvLTsFeDaqhbBx7rgsHzh4Yx7IqvA== dependencies: - lodash "^4.17.11" + lodash "^4.17.15" eslint-plugin-import@^2.18.2: version "2.18.2" @@ -2044,47 +2087,39 @@ eslint-plugin-jsx-a11y@^6.2.3: has "^1.0.3" jsx-ast-utils "^2.2.1" -eslint-plugin-node@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-9.1.0.tgz#f2fd88509a31ec69db6e9606d76dabc5adc1b91a" - integrity sha512-ZwQYGm6EoV2cfLpE1wxJWsfnKUIXfM/KM09/TlorkukgCAwmkgajEJnPCmyzoFPQQkmvo5DrW/nyKutNIw36Mw== +eslint-plugin-node@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz#fd1adbc7a300cf7eb6ac55cf4b0b6fc6e577f5a6" + integrity sha512-1CSyM/QCjs6PXaT18+zuAXsjXGIGo5Rw630rSKwokSs2jrYURQc4R5JZpoanNCqwNmepg+0eZ9L7YiRUJb8jiQ== dependencies: - eslint-plugin-es "^1.4.0" - eslint-utils "^1.3.1" + eslint-plugin-es "^2.0.0" + eslint-utils "^1.4.2" ignore "^5.1.1" minimatch "^3.0.4" resolve "^1.10.1" semver "^6.1.0" -eslint-plugin-prettier@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.0.tgz#8695188f95daa93b0dc54b249347ca3b79c4686d" - integrity sha512-XWX2yVuwVNLOUhQijAkXz+rMPPoCr7WFiAl8ig6I7Xn+pPVhDhzg4DxHpmbeb0iqjO9UronEA3Tb09ChnFVHHA== +eslint-plugin-prettier@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.1.tgz#507b8562410d02a03f0ddc949c616f877852f2ba" + integrity sha512-A+TZuHZ0KU0cnn56/9mfR7/KjUJ9QNVXUhwvRFSR7PGPe0zQR6PTkmyqg1AtUUEOzTqeRsUwyKFh0oVZKVCrtA== dependencies: prettier-linter-helpers "^1.0.0" -eslint-plugin-react@^7.14.2: - version "7.14.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.2.tgz#94c193cc77a899ac0ecbb2766fbef88685b7ecc1" - integrity sha512-jZdnKe3ip7FQOdjxks9XPN0pjUKZYq48OggNMd16Sk+8VXx6JOvXmlElxROCgp7tiUsTsze3jd78s/9AFJP2mA== +eslint-plugin-react@^7.16.0: + version "7.16.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.16.0.tgz#9928e4f3e2122ed3ba6a5b56d0303ba3e41d8c09" + integrity sha512-GacBAATewhhptbK3/vTP09CbFrgUJmBSaaRcWdbQLFvUZy9yVcQxigBNHGPU/KE2AyHpzj3AWXpxoMTsIDiHug== dependencies: array-includes "^3.0.3" doctrine "^2.1.0" has "^1.0.3" - jsx-ast-utils "^2.1.0" + jsx-ast-utils "^2.2.1" object.entries "^1.1.0" object.fromentries "^2.0.0" object.values "^1.1.0" prop-types "^15.7.2" - resolve "^1.10.1" - -eslint-scope@3.7.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" - integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug= - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" + resolve "^1.12.0" eslint-scope@^5.0.0: version "5.0.0" @@ -2094,7 +2129,7 @@ eslint-scope@^5.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-utils@^1.3.0, eslint-utils@^1.3.1: +eslint-utils@^1.4.2, eslint-utils@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== @@ -2106,10 +2141,10 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== -eslint@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.1.0.tgz#06438a4a278b1d84fb107d24eaaa35471986e646" - integrity sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ== +eslint@^6.6.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.6.0.tgz#4a01a2fb48d32aacef5530ee9c5a78f11a8afd04" + integrity sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -2118,9 +2153,9 @@ eslint@^6.1.0: debug "^4.0.1" doctrine "^3.0.0" eslint-scope "^5.0.0" - eslint-utils "^1.3.1" - eslint-visitor-keys "^1.0.0" - espree "^6.0.0" + eslint-utils "^1.4.3" + eslint-visitor-keys "^1.1.0" + espree "^6.1.2" esquery "^1.0.1" esutils "^2.0.2" file-entry-cache "^5.0.1" @@ -2130,7 +2165,7 @@ eslint@^6.1.0: ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" - inquirer "^6.4.1" + inquirer "^7.0.0" is-glob "^4.0.0" js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" @@ -2149,14 +2184,14 @@ eslint@^6.1.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.0.0.tgz#716fc1f5a245ef5b9a7fdb1d7b0d3f02322e75f6" - integrity sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q== +espree@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.2.tgz#6c272650932b4f91c3714e5e7b5f5e2ecf47262d" + integrity sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA== dependencies: - acorn "^6.0.7" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" + acorn "^7.1.0" + acorn-jsx "^5.1.0" + eslint-visitor-keys "^1.1.0" esprima@^3.1.3: version "3.1.3" @@ -2183,14 +2218,14 @@ esrecurse@^4.1.0: estraverse "^4.1.0" estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== event-emitter@^0.3.5: version "0.3.5" @@ -2201,9 +2236,9 @@ event-emitter@^0.3.5: es5-ext "~0.10.14" exec-sh@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b" - integrity sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg== + version "0.3.4" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" + integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== execa@^1.0.0: version "1.0.0" @@ -2218,16 +2253,17 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/execa/-/execa-2.0.3.tgz#4b84301b33042cfb622771e886ed0b10e5634642" - integrity sha512-iM124nlyGSrXmuyZF1EMe83ESY2chIYVyDRZKgmcDynid2Q2v/+GuE7gNMl6Sy9Niwf4MC0DDxagOxeMPjuLsw== +execa@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-3.3.0.tgz#7e348eef129a1937f21ecbbd53390942653522c1" + integrity sha512-j5Vit5WZR/cbHlqU97+qcnw9WHRCIL4V1SVe75VcHcD1JRBdt8fv0zw89b7CQHQdUHTt2VjuhcF5ibAgVOxqpg== dependencies: - cross-spawn "^6.0.5" + cross-spawn "^7.0.0" get-stream "^5.0.0" + human-signals "^1.1.1" is-stream "^2.0.0" merge-stream "^2.0.0" - npm-run-path "^3.0.0" + npm-run-path "^4.0.0" onetime "^5.1.0" p-finally "^2.0.0" signal-exit "^3.0.2" @@ -2258,17 +2294,24 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" -expect@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-24.8.0.tgz#471f8ec256b7b6129ca2524b2a62f030df38718d" - integrity sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA== +expect@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" + integrity sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" ansi-styles "^3.2.0" - jest-get-type "^24.8.0" - jest-matcher-utils "^24.8.0" - jest-message-util "^24.8.0" - jest-regex-util "^24.3.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-regex-util "^24.9.0" + +ext@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.2.0.tgz#8dd8d2dd21bcced3045be09621fa0cbf73908ba4" + integrity sha512-0ccUQK/9e3NreLFg6K6np8aPyRgwycx+oFGtfx1dSp7Wj00Ozw9r05FgBRlzjf2XBM7LAzwgLyDscRrtSU91hA== + dependencies: + type "^2.0.0" extend-shallow@^2.0.1: version "2.0.1" @@ -2333,35 +2376,16 @@ fast-diff@^1.1.2: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== -fast-glob@^3.0.3: - version "3.0.4" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.0.4.tgz#d484a41005cb6faeb399b951fd1bd70ddaebb602" - integrity sha512-wkIbV6qg37xTJwqSsdnIphL1e+LaGz4AIQqr00mIubMaEhv1/HEmJ0uuCGZRNRUkZZmOB5mJKO0ZUTVq+SxMQg== - dependencies: - "@nodelib/fs.stat" "^2.0.1" - "@nodelib/fs.walk" "^1.2.1" - glob-parent "^5.0.0" - is-glob "^4.0.1" - merge2 "^1.2.3" - micromatch "^4.0.2" - fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= -fast-levenshtein@~2.0.4: +fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -fastq@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.0.tgz#4ec8a38f4ac25f21492673adb7eae9cfef47d1c2" - integrity sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA== - dependencies: - reusify "^1.0.0" - fb-watchman@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" @@ -2384,6 +2408,13 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" +figures@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.1.0.tgz#4b198dd07d8d71530642864af2d45dd9e459c4ec" + integrity sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg== + dependencies: + escape-string-regexp "^1.0.5" + file-entry-cache@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" @@ -2512,11 +2543,11 @@ fs-extra@^8.1.0: universalify "^0.1.0" fs-minipass@^1.2.5: - version "1.2.6" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" - integrity sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ== + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== dependencies: - minipass "^2.2.1" + minipass "^2.6.0" fs.realpath@^1.0.0: version "1.0.0" @@ -2555,15 +2586,15 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-own-enumerable-property-symbols@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz#b877b49a5c16aefac3655f2ed2ea5b684df8d203" - integrity sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg== + version "3.0.1" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.1.tgz#6f7764f88ea11e0b514bd9bd860a132259992ca4" + integrity sha512-09/VS4iek66Dh2bctjRkowueRJbY1JDGR1L/zRxO1Qk8Uxs6PnqaNSqalpizPT+CDjre3hnEsuzvhgomz9qYrA== get-stdin@^6.0.0: version "6.0.0" @@ -2602,9 +2633,9 @@ getpass@^0.1.1: assert-plus "^1.0.0" glob-parent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954" - integrity sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg== + version "5.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2" + integrity sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw== dependencies: is-glob "^4.0.1" @@ -2621,9 +2652,9 @@ glob@7.1.3: path-is-absolute "^1.0.0" glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: - version "7.1.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" - integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -2657,24 +2688,10 @@ globals@^11.1.0, globals@^11.7.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globby@^10.0.0: - version "10.0.1" - resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.1.tgz#4782c34cb75dd683351335c5829cc3420e606b22" - integrity sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A== - dependencies: - "@types/glob" "^7.1.1" - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.0.3" - glob "^7.1.3" - ignore "^5.1.1" - merge2 "^1.2.3" - slash "^3.0.0" - graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" - integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg== + version "4.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" + integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== growly@^1.3.0: version "1.3.0" @@ -2682,9 +2699,9 @@ growly@^1.3.0: integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= handlebars@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67" - integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw== + version "4.5.2" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.2.tgz#5a4eb92ab5962ca3415ac188c86dc7f784f76a0f" + integrity sha512-29Zxv/cynYB7mkT1rVWQnV7mGX6v7H/miQ6dbEpYTKq5eJBN7PsRB+ViYJlcT6JINTSu4dVB9kOqEun78h6Exg== dependencies: neo-async "^2.6.0" optimist "^0.6.1" @@ -2729,6 +2746,11 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + has-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" @@ -2785,9 +2807,9 @@ homedir-polyfill@^1.0.1: parse-passwd "^1.0.0" hosted-git-info@^2.1.4: - version "2.7.1" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" - integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + version "2.8.5" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c" + integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg== html-encoding-sniffer@^1.0.2: version "1.0.2" @@ -2806,27 +2828,32 @@ http-signature@~1.2.0: sshpk "^1.7.0" https-proxy-agent@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz#271ea8e90f836ac9f119daccd39c19ff7dfb0793" - integrity sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg== + version "2.2.4" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" + integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== dependencies: agent-base "^4.3.0" debug "^3.1.0" -husky@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/husky/-/husky-3.0.1.tgz#06152c28e129622b05fa09c494209de8cf2dfb59" - integrity sha512-PXBv+iGKw23GHUlgELRlVX9932feFL407/wHFwtsGeArp0dDM4u+/QusSQwPKxmNgjpSL+ustbOdQ2jetgAZbA== +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + +husky@^3.0.9: + version "3.0.9" + resolved "https://registry.yarnpkg.com/husky/-/husky-3.0.9.tgz#a2c3e9829bfd6b4957509a9500d2eef5dbfc8044" + integrity sha512-Yolhupm7le2/MqC1VYLk/cNmYxsSsqKkTyBhzQHhPK1jFnC89mmmNVuGtLNabjDI6Aj8UNIr0KpRNuBkiC4+sg== dependencies: chalk "^2.4.2" + ci-info "^2.0.0" cosmiconfig "^5.2.1" execa "^1.0.0" get-stdin "^7.0.0" - is-ci "^2.0.0" opencollective-postinstall "^2.0.2" pkg-dir "^4.2.0" - please-upgrade-node "^3.1.1" - read-pkg "^5.1.1" + please-upgrade-node "^3.2.0" + read-pkg "^5.2.0" run-node "^1.0.0" slash "^3.0.0" @@ -2838,9 +2865,9 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: safer-buffer ">= 2.1.2 < 3" ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + version "3.0.3" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" + integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== dependencies: minimatch "^3.0.4" @@ -2850,9 +2877,9 @@ ignore@^4.0.6: integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== ignore@^5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.2.tgz#e28e584d43ad7e92f96995019cc43b9e1ac49558" - integrity sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ== + version "5.1.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" + integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== import-fresh@^2.0.0: version "2.0.0" @@ -2862,10 +2889,10 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.1.0.tgz#6d33fa1dcef6df930fae003446f33415af905118" - integrity sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ== +import-fresh@^3.0.0, import-fresh@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" @@ -2925,22 +2952,22 @@ inquirer@6.2.0: strip-ansi "^4.0.0" through "^2.3.6" -inquirer@^6.4.1: - version "6.5.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.0.tgz#2303317efc9a4ea7ec2e2df6f86569b734accf42" - integrity sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA== +inquirer@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.0.tgz#9e2b032dde77da1db5db804758b8fea3a970519a" + integrity sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ== dependencies: - ansi-escapes "^3.2.0" + ansi-escapes "^4.2.1" chalk "^2.4.2" - cli-cursor "^2.1.0" + cli-cursor "^3.1.0" cli-width "^2.0.0" external-editor "^3.0.3" - figures "^2.0.0" - lodash "^4.17.12" - mute-stream "0.0.7" + figures "^3.0.0" + lodash "^4.17.15" + mute-stream "0.0.8" run-async "^2.2.0" rxjs "^6.4.0" - string-width "^2.1.0" + string-width "^4.1.0" strip-ansi "^5.1.0" through "^2.3.6" @@ -2970,11 +2997,6 @@ invariant@^2.2.2, invariant@^2.2.4: dependencies: loose-envify "^1.0.0" -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== - is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" @@ -3082,6 +3104,11 @@ is-fullwidth-code-point@^2.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + is-generator-fn@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" @@ -3118,25 +3145,6 @@ is-observable@^1.1.0: dependencies: symbol-observable "^1.1.0" -is-path-cwd@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - -is-path-in-cwd@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" - integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== - dependencies: - is-path-inside "^2.1.0" - -is-path-inside@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" - integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== - dependencies: - path-is-inside "^1.0.2" - is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -3263,287 +3271,288 @@ istanbul-lib-source-maps@^3.0.1: rimraf "^2.6.3" source-map "^0.6.1" -istanbul-reports@^2.1.1: +istanbul-reports@^2.2.6: version "2.2.6" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.6.tgz#7b4f2660d82b29303a8fe6091f8ca4bf058da1af" integrity sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA== dependencies: handlebars "^4.1.2" -jest-changed-files@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.8.0.tgz#7e7eb21cf687587a85e50f3d249d1327e15b157b" - integrity sha512-qgANC1Yrivsq+UrLXsvJefBKVoCsKB0Hv+mBb6NMjjZ90wwxCDmU3hsCXBya30cH+LnPYjwgcU65i6yJ5Nfuug== +jest-changed-files@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" + integrity sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" execa "^1.0.0" throat "^4.0.0" -jest-cli@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.8.0.tgz#b075ac914492ed114fa338ade7362a301693e989" - integrity sha512-+p6J00jSMPQ116ZLlHJJvdf8wbjNbZdeSX9ptfHX06/MSNaXmKihQzx5vQcw0q2G6JsdVkUIdWbOWtSnaYs3yA== +jest-cli@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" + integrity sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg== dependencies: - "@jest/core" "^24.8.0" - "@jest/test-result" "^24.8.0" - "@jest/types" "^24.8.0" + "@jest/core" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" chalk "^2.0.1" exit "^0.1.2" import-local "^2.0.0" is-ci "^2.0.0" - jest-config "^24.8.0" - jest-util "^24.8.0" - jest-validate "^24.8.0" + jest-config "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" prompts "^2.0.1" realpath-native "^1.1.0" - yargs "^12.0.2" + yargs "^13.3.0" -jest-config@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.8.0.tgz#77db3d265a6f726294687cbbccc36f8a76ee0f4f" - integrity sha512-Czl3Nn2uEzVGsOeaewGWoDPD8GStxCpAe0zOYs2x2l0fZAgPbCr3uwUkgNKV3LwE13VXythM946cd5rdGkkBZw== +jest-config@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" + integrity sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^24.8.0" - "@jest/types" "^24.8.0" - babel-jest "^24.8.0" + "@jest/test-sequencer" "^24.9.0" + "@jest/types" "^24.9.0" + babel-jest "^24.9.0" chalk "^2.0.1" glob "^7.1.1" - jest-environment-jsdom "^24.8.0" - jest-environment-node "^24.8.0" - jest-get-type "^24.8.0" - jest-jasmine2 "^24.8.0" + jest-environment-jsdom "^24.9.0" + jest-environment-node "^24.9.0" + jest-get-type "^24.9.0" + jest-jasmine2 "^24.9.0" jest-regex-util "^24.3.0" - jest-resolve "^24.8.0" - jest-util "^24.8.0" - jest-validate "^24.8.0" + jest-resolve "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" micromatch "^3.1.10" - pretty-format "^24.8.0" + pretty-format "^24.9.0" realpath-native "^1.1.0" -jest-diff@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.8.0.tgz#146435e7d1e3ffdf293d53ff97e193f1d1546172" - integrity sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g== +jest-diff@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" + integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== dependencies: chalk "^2.0.1" - diff-sequences "^24.3.0" - jest-get-type "^24.8.0" - pretty-format "^24.8.0" + diff-sequences "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" jest-docblock@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.3.0.tgz#b9c32dac70f72e4464520d2ba4aec02ab14db5dd" - integrity sha512-nlANmF9Yq1dufhFlKG9rasfQlrY7wINJbo3q01tu56Jv5eBU5jirylhF2O5ZBnLxzOVBGRDz/9NAwNyBtG4Nyg== + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" + integrity sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA== dependencies: detect-newline "^2.1.0" -jest-each@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.8.0.tgz#a05fd2bf94ddc0b1da66c6d13ec2457f35e52775" - integrity sha512-NrwK9gaL5+XgrgoCsd9svsoWdVkK4gnvyhcpzd6m487tXHqIdYeykgq3MKI1u4I+5Zf0tofr70at9dWJDeb+BA== +jest-each@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" + integrity sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" chalk "^2.0.1" - jest-get-type "^24.8.0" - jest-util "^24.8.0" - pretty-format "^24.8.0" - -jest-environment-jsdom@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.8.0.tgz#300f6949a146cabe1c9357ad9e9ecf9f43f38857" - integrity sha512-qbvgLmR7PpwjoFjM/sbuqHJt/NCkviuq9vus9NBn/76hhSidO+Z6Bn9tU8friecegbJL8gzZQEMZBQlFWDCwAQ== - dependencies: - "@jest/environment" "^24.8.0" - "@jest/fake-timers" "^24.8.0" - "@jest/types" "^24.8.0" - jest-mock "^24.8.0" - jest-util "^24.8.0" + jest-get-type "^24.9.0" + jest-util "^24.9.0" + pretty-format "^24.9.0" + +jest-environment-jsdom@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" + integrity sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + jest-util "^24.9.0" jsdom "^11.5.1" -jest-environment-node@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.8.0.tgz#d3f726ba8bc53087a60e7a84ca08883a4c892231" - integrity sha512-vIGUEScd1cdDgR6sqn2M08sJTRLQp6Dk/eIkCeO4PFHxZMOgy+uYLPMC4ix3PEfM5Au/x3uQ/5Tl0DpXXZsJ/Q== +jest-environment-node@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.9.0.tgz#333d2d2796f9687f2aeebf0742b519f33c1cbfd3" + integrity sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA== dependencies: - "@jest/environment" "^24.8.0" - "@jest/fake-timers" "^24.8.0" - "@jest/types" "^24.8.0" - jest-mock "^24.8.0" - jest-util "^24.8.0" + "@jest/environment" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + jest-util "^24.9.0" -jest-get-type@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.8.0.tgz#a7440de30b651f5a70ea3ed7ff073a32dfe646fc" - integrity sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ== +jest-get-type@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" + integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== -jest-haste-map@^24.8.0: - version "24.8.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.8.1.tgz#f39cc1d2b1d907e014165b4bd5a957afcb992982" - integrity sha512-SwaxMGVdAZk3ernAx2Uv2sorA7jm3Kx+lR0grp6rMmnY06Kn/urtKx1LPN2mGTea4fCT38impYT28FfcLUhX0g== +jest-haste-map@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" + integrity sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" anymatch "^2.0.0" fb-watchman "^2.0.0" graceful-fs "^4.1.15" invariant "^2.2.4" - jest-serializer "^24.4.0" - jest-util "^24.8.0" - jest-worker "^24.6.0" + jest-serializer "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.9.0" micromatch "^3.1.10" sane "^4.0.3" walker "^1.0.7" optionalDependencies: fsevents "^1.2.7" -jest-jasmine2@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.8.0.tgz#a9c7e14c83dd77d8b15e820549ce8987cc8cd898" - integrity sha512-cEky88npEE5LKd5jPpTdDCLvKkdyklnaRycBXL6GNmpxe41F0WN44+i7lpQKa/hcbXaQ+rc9RMaM4dsebrYong== +jest-jasmine2@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" + integrity sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^24.8.0" - "@jest/test-result" "^24.8.0" - "@jest/types" "^24.8.0" + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" chalk "^2.0.1" co "^4.6.0" - expect "^24.8.0" + expect "^24.9.0" is-generator-fn "^2.0.0" - jest-each "^24.8.0" - jest-matcher-utils "^24.8.0" - jest-message-util "^24.8.0" - jest-runtime "^24.8.0" - jest-snapshot "^24.8.0" - jest-util "^24.8.0" - pretty-format "^24.8.0" + jest-each "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-runtime "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + pretty-format "^24.9.0" throat "^4.0.0" -jest-leak-detector@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.8.0.tgz#c0086384e1f650c2d8348095df769f29b48e6980" - integrity sha512-cG0yRSK8A831LN8lIHxI3AblB40uhv0z+SsQdW3GoMMVcK+sJwrIIyax5tu3eHHNJ8Fu6IMDpnLda2jhn2pD/g== +jest-leak-detector@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz#b665dea7c77100c5c4f7dfcb153b65cf07dcf96a" + integrity sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA== dependencies: - pretty-format "^24.8.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" -jest-matcher-utils@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz#2bce42204c9af12bde46f83dc839efe8be832495" - integrity sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw== +jest-matcher-utils@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" + integrity sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA== dependencies: chalk "^2.0.1" - jest-diff "^24.8.0" - jest-get-type "^24.8.0" - pretty-format "^24.8.0" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" -jest-message-util@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.8.0.tgz#0d6891e72a4beacc0292b638685df42e28d6218b" - integrity sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g== +jest-message-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" + integrity sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^24.8.0" - "@jest/types" "^24.8.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" "@types/stack-utils" "^1.0.1" chalk "^2.0.1" micromatch "^3.1.10" slash "^2.0.0" stack-utils "^1.0.1" -jest-mock@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.8.0.tgz#2f9d14d37699e863f1febf4e4d5a33b7fdbbde56" - integrity sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A== +jest-mock@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" + integrity sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" jest-pnp-resolver@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== -jest-regex-util@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.3.0.tgz#d5a65f60be1ae3e310d5214a0307581995227b36" - integrity sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg== +jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" + integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== -jest-resolve-dependencies@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.8.0.tgz#19eec3241f2045d3f990dba331d0d7526acff8e0" - integrity sha512-hyK1qfIf/krV+fSNyhyJeq3elVMhK9Eijlwy+j5jqmZ9QsxwKBiP6qukQxaHtK8k6zql/KYWwCTQ+fDGTIJauw== +jest-resolve-dependencies@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" + integrity sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" jest-regex-util "^24.3.0" - jest-snapshot "^24.8.0" + jest-snapshot "^24.9.0" -jest-resolve@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.8.0.tgz#84b8e5408c1f6a11539793e2b5feb1b6e722439f" - integrity sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw== +jest-resolve@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" + integrity sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" browser-resolve "^1.11.3" chalk "^2.0.1" jest-pnp-resolver "^1.2.1" realpath-native "^1.1.0" -jest-runner@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.8.0.tgz#4f9ae07b767db27b740d7deffad0cf67ccb4c5bb" - integrity sha512-utFqC5BaA3JmznbissSs95X1ZF+d+4WuOWwpM9+Ak356YtMhHE/GXUondZdcyAAOTBEsRGAgH/0TwLzfI9h7ow== +jest-runner@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" + integrity sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg== dependencies: "@jest/console" "^24.7.1" - "@jest/environment" "^24.8.0" - "@jest/test-result" "^24.8.0" - "@jest/types" "^24.8.0" + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" chalk "^2.4.2" exit "^0.1.2" graceful-fs "^4.1.15" - jest-config "^24.8.0" + jest-config "^24.9.0" jest-docblock "^24.3.0" - jest-haste-map "^24.8.0" - jest-jasmine2 "^24.8.0" - jest-leak-detector "^24.8.0" - jest-message-util "^24.8.0" - jest-resolve "^24.8.0" - jest-runtime "^24.8.0" - jest-util "^24.8.0" + jest-haste-map "^24.9.0" + jest-jasmine2 "^24.9.0" + jest-leak-detector "^24.9.0" + jest-message-util "^24.9.0" + jest-resolve "^24.9.0" + jest-runtime "^24.9.0" + jest-util "^24.9.0" jest-worker "^24.6.0" source-map-support "^0.5.6" throat "^4.0.0" -jest-runtime@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.8.0.tgz#05f94d5b05c21f6dc54e427cd2e4980923350620" - integrity sha512-Mq0aIXhvO/3bX44ccT+czU1/57IgOMyy80oM0XR/nyD5zgBcesF84BPabZi39pJVA6UXw+fY2Q1N+4BiVUBWOA== +jest-runtime@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" + integrity sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw== dependencies: "@jest/console" "^24.7.1" - "@jest/environment" "^24.8.0" + "@jest/environment" "^24.9.0" "@jest/source-map" "^24.3.0" - "@jest/transform" "^24.8.0" - "@jest/types" "^24.8.0" - "@types/yargs" "^12.0.2" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/yargs" "^13.0.0" chalk "^2.0.1" exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.1.15" - jest-config "^24.8.0" - jest-haste-map "^24.8.0" - jest-message-util "^24.8.0" - jest-mock "^24.8.0" + jest-config "^24.9.0" + jest-haste-map "^24.9.0" + jest-message-util "^24.9.0" + jest-mock "^24.9.0" jest-regex-util "^24.3.0" - jest-resolve "^24.8.0" - jest-snapshot "^24.8.0" - jest-util "^24.8.0" - jest-validate "^24.8.0" + jest-resolve "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" realpath-native "^1.1.0" slash "^2.0.0" strip-bom "^3.0.0" - yargs "^12.0.2" + yargs "^13.3.0" -jest-serializer@^24.4.0: - version "24.4.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.4.0.tgz#f70c5918c8ea9235ccb1276d232e459080588db3" - integrity sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q== +jest-serializer@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" + integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== jest-snapshot-serializer-ansi@^1.0.0: version "1.0.0" @@ -3553,34 +3562,35 @@ jest-snapshot-serializer-ansi@^1.0.0: has-ansi "^3.0.0" strip-ansi "^4.0.0" -jest-snapshot@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.8.0.tgz#3bec6a59da2ff7bc7d097a853fb67f9d415cb7c6" - integrity sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg== +jest-snapshot@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" + integrity sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" chalk "^2.0.1" - expect "^24.8.0" - jest-diff "^24.8.0" - jest-matcher-utils "^24.8.0" - jest-message-util "^24.8.0" - jest-resolve "^24.8.0" + expect "^24.9.0" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-resolve "^24.9.0" mkdirp "^0.5.1" natural-compare "^1.4.0" - pretty-format "^24.8.0" - semver "^5.5.0" - -jest-util@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.8.0.tgz#41f0e945da11df44cc76d64ffb915d0716f46cd1" - integrity sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA== - dependencies: - "@jest/console" "^24.7.1" - "@jest/fake-timers" "^24.8.0" - "@jest/source-map" "^24.3.0" - "@jest/test-result" "^24.8.0" - "@jest/types" "^24.8.0" + pretty-format "^24.9.0" + semver "^6.2.0" + +jest-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162" + integrity sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg== + dependencies: + "@jest/console" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/source-map" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" callsites "^3.0.0" chalk "^2.0.1" graceful-fs "^4.1.15" @@ -3589,46 +3599,46 @@ jest-util@^24.8.0: slash "^2.0.0" source-map "^0.6.0" -jest-validate@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.8.0.tgz#624c41533e6dfe356ffadc6e2423a35c2d3b4849" - integrity sha512-+/N7VOEMW1Vzsrk3UWBDYTExTPwf68tavEPKDnJzrC6UlHtUDU/fuEdXqFoHzv9XnQ+zW6X3qMZhJ3YexfeLDA== +jest-validate@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" + integrity sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ== dependencies: - "@jest/types" "^24.8.0" - camelcase "^5.0.0" + "@jest/types" "^24.9.0" + camelcase "^5.3.1" chalk "^2.0.1" - jest-get-type "^24.8.0" - leven "^2.1.0" - pretty-format "^24.8.0" - -jest-watcher@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.8.0.tgz#58d49915ceddd2de85e238f6213cef1c93715de4" - integrity sha512-SBjwHt5NedQoVu54M5GEx7cl7IGEFFznvd/HNT8ier7cCAx/Qgu9ZMlaTQkvK22G1YOpcWBLQPFSImmxdn3DAw== - dependencies: - "@jest/test-result" "^24.8.0" - "@jest/types" "^24.8.0" - "@types/yargs" "^12.0.9" + jest-get-type "^24.9.0" + leven "^3.1.0" + pretty-format "^24.9.0" + +jest-watcher@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.9.0.tgz#4b56e5d1ceff005f5b88e528dc9afc8dd4ed2b3b" + integrity sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw== + dependencies: + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/yargs" "^13.0.0" ansi-escapes "^3.0.0" chalk "^2.0.1" - jest-util "^24.8.0" + jest-util "^24.9.0" string-length "^2.0.0" -jest-worker@^24.6.0: - version "24.6.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.6.0.tgz#7f81ceae34b7cde0c9827a6980c35b7cdc0161b3" - integrity sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ== +jest-worker@^24.6.0, jest-worker@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" + integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== dependencies: - merge-stream "^1.0.1" + merge-stream "^2.0.0" supports-color "^6.1.0" -jest@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.8.0.tgz#d5dff1984d0d1002196e9b7f12f75af1b2809081" - integrity sha512-o0HM90RKFRNWmAWvlyV8i5jGZ97pFwkeVoGvPW1EtLTgJc2+jcuqcbbqcSZLE/3f2S5pt0y2ZBETuhpWNl1Reg== +jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" + integrity sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw== dependencies: import-local "^2.0.0" - jest-cli "^24.8.0" + jest-cli "^24.9.0" js-levenshtein@^1.1.3: version "1.1.6" @@ -3721,9 +3731,9 @@ json-stringify-safe@~5.0.1: integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= json5@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" - integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== + version "2.1.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6" + integrity sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ== dependencies: minimist "^1.2.0" @@ -3752,10 +3762,10 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jsx-ast-utils@^2.1.0, jsx-ast-utils@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz#4d4973ebf8b9d2837ee91a8208cc66f3a2776cfb" - integrity sha512-v3FxCcAf20DayI+uxnCuw795+oOIkVu6EnJ1+kSzhqqTZHNkTZ7B66ZgLp4oLJ/gbA64cI0B7WRoHZMSRdyVRQ== +jsx-ast-utils@^2.2.1: + version "2.2.3" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz#8a9364e402448a3ce7f14d357738310d9248054f" + integrity sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA== dependencies: array-includes "^3.0.3" object.assign "^4.1.0" @@ -3784,27 +3794,20 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== -kleur@^3.0.2: +kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== - dependencies: - invert-kv "^2.0.0" - left-pad@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== -leven@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" - integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== levn@^0.3.0, levn@~0.3.0: version "0.3.0" @@ -3921,7 +3924,7 @@ lodash@4.17.14: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== -lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14: +lodash@^4.17.10, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -3983,13 +3986,6 @@ makeerror@1.0.x: dependencies: tmpl "1.0.x" -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -4002,15 +3998,6 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - memoizee@^0.4.14: version "0.4.14" resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.14.tgz#07a00f204699f9a95c2d9e77218271c7cd610d57" @@ -4025,23 +4012,11 @@ memoizee@^0.4.14: next-tick "1" timers-ext "^0.1.5" -merge-stream@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" - integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= - dependencies: - readable-stream "^2.0.1" - merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" - integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== - merge@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" @@ -4074,24 +4049,24 @@ micromatch@^4.0.2: braces "^3.0.1" picomatch "^2.0.5" -mime-db@1.40.0: - version "1.40.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" - integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== +mime-db@1.42.0: + version "1.42.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" + integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.24" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" - integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== + version "2.1.25" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" + integrity sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg== dependencies: - mime-db "1.40.0" + mime-db "1.42.0" mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== -mimic-fn@^2.0.0, mimic-fn@^2.1.0: +mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== @@ -4118,20 +4093,20 @@ minimist@~0.0.1: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= -minipass@^2.2.1, minipass@^2.3.5: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== +minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" minizlib@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" - integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== dependencies: - minipass "^2.2.1" + minipass "^2.9.0" mixin-deep@^1.2.0: version "1.3.2" @@ -4163,7 +4138,7 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -mute-stream@~0.0.4: +mute-stream@0.0.8, mute-stream@~0.0.4: version "0.0.8" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== @@ -4173,10 +4148,10 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== -nanoid@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.1.tgz#524fd4acd45c126e0c87cd43ab5ee8346e695df9" - integrity sha512-0YbJdaL4JFoejIOoawgLcYValFGJ2iyUuVDIWL3g8Es87SSOWFbWdRUMV3VMSiyPs3SQ3QxCIxFX00q5DLkMCw== +nanoid@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.6.tgz#0665418f692e54cf44f34d4010761f3240a03314" + integrity sha512-2NDzpiuEy3+H0AVtdt8LoFi7PnqkOnIzYmJQp7xsEU6VexLluHQwKREuiz57XaQC5006seIadPrIZJhyS2n7aw== nanomatch@^1.2.9: version "1.2.13" @@ -4214,7 +4189,7 @@ neo-async@^2.6.0: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== -next-tick@1, next-tick@^1.0.0: +next-tick@1, next-tick@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= @@ -4234,10 +4209,10 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-notifier@^5.2.1: - version "5.4.0" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.0.tgz#7b455fdce9f7de0c63538297354f3db468426e6a" - integrity sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ== +node-notifier@^5.4.2: + version "5.4.3" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" + integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== dependencies: growly "^1.3.0" is-wsl "^1.1.0" @@ -4261,12 +4236,12 @@ node-pre-gyp@^0.12.0: semver "^5.3.0" tar "^4" -node-releases@^1.1.25: - version "1.1.25" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.25.tgz#0c2d7dbc7fed30fbe02a9ee3007b8c90bf0133d3" - integrity sha512-fI5BXuk83lKEoZDdH3gRhtsNgh05/wZacuXkgbiYkceE7+QIMXOg98n9ZV7mz27B+kFHnqHcUpscZZlGRSmTpQ== +node-releases@^1.1.38: + version "1.1.40" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.40.tgz#a94facfa8e2d612302601ca1361741d529c4515a" + integrity sha512-r4LPcC5b/bS8BdtWH1fbeK88ib/wg9aqmg6/s3ngNLn2Ewkn/8J6Iw3P9RTlfIAdSdvYvQl2thCY5Y+qTAQ2iQ== dependencies: - semver "^5.3.0" + semver "^6.3.0" nomnom@^1.5.x: version "1.8.1" @@ -4312,9 +4287,9 @@ npm-bundled@^1.0.1: integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== npm-packlist@^1.1.6: - version "1.4.4" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.4.tgz#866224233850ac534b63d1a6e76050092b5d2f44" - integrity sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw== + version "1.4.6" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.6.tgz#53ba3ed11f8523079f1457376dd379ee4ea42ff4" + integrity sha512-u65uQdb+qwtGvEJh/DgQgW1Xg7sqeNbmxYyrvlNznaVTjV3E5P6F/EFjM+BVHXl7JJlsdG8A64M0XI8FI/IOlg== dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" @@ -4326,10 +4301,10 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npm-run-path@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-3.1.0.tgz#7f91be317f6a466efed3c9f2980ad8a4ee8b0fa5" - integrity sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg== +npm-run-path@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.0.tgz#d644ec1bd0569187d2a52909971023a0a58e8438" + integrity sha512-8eyAOAH+bYXFPSnNnKr3J+yoybe8O87Is5rtAQ8qRczJz1ajcsjg8l2oZqP+Ppx15Ii3S1vUTjQN2h4YO2tWWQ== dependencies: path-key "^3.0.0" @@ -4349,9 +4324,9 @@ number-is-nan@^1.0.0: integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= nwsapi@^2.0.7: - version "2.1.4" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.1.4.tgz#e006a878db23636f8e8a67d33ca0e4edf61a842f" - integrity sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw== + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== oauth-sign@~0.9.0: version "0.9.0" @@ -4372,7 +4347,12 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-keys@^1.0.11, object-keys@^1.0.12: +object-inspect@^1.6.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -4405,14 +4385,14 @@ object.entries@^1.1.0: has "^1.0.3" object.fromentries@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.0.tgz#49a543d92151f8277b3ac9600f1e930b189d30ab" - integrity sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA== + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.1.tgz#050f077855c7af8ae6649f45c80b16ee2d31e704" + integrity sha512-PUQv8Hbg3j2QX0IQYv3iAGCbGcu4yY4KQ92/dhA4sFSixBmSmp13UpDLs6jGK8rBtbmhNNIK99LD2k293jpiGA== dependencies: - define-properties "^1.1.2" - es-abstract "^1.11.0" + define-properties "^1.1.3" + es-abstract "^1.15.0" function-bind "^1.1.1" - has "^1.0.1" + has "^1.0.3" object.getownpropertydescriptors@^2.0.3: version "2.0.3" @@ -4474,31 +4454,22 @@ optimist@^0.6.1: wordwrap "~0.0.2" optionator@^0.8.1, optionator@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== dependencies: deep-is "~0.1.3" - fast-levenshtein "~2.0.4" + fast-levenshtein "~2.0.6" levn "~0.3.0" prelude-ls "~1.1.2" type-check "~0.3.2" - wordwrap "~1.0.0" + word-wrap "~1.2.3" os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= -os-locale@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -4512,11 +4483,6 @@ osenv@^0.1.4: os-homedir "^1.0.0" os-tmpdir "^1.0.0" -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - p-each-series@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" @@ -4534,11 +4500,6 @@ p-finally@^2.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== - p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -4547,9 +4508,9 @@ p-limit@^1.1.0: p-try "^1.0.0" p-limit@^2.0.0, p-limit@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" - integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== + version "2.2.1" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" + integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== dependencies: p-try "^2.0.0" @@ -4656,17 +4617,12 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-key@^3.0.0: +path-key@^3.0.0, path-key@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.0.tgz#99a10d870a803bdd5ee6f0470e58dfcd2f9a54d3" integrity sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg== @@ -4701,9 +4657,9 @@ performance-now@^2.1.0: integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= picomatch@^2.0.5: - version "2.0.7" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6" - integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA== + version "2.1.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.1.tgz#ecdfbea7704adb5fe6fb47f9866c4c0e15e905c5" + integrity sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA== pify@^2.0.0: version "2.3.0" @@ -4748,10 +4704,10 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -please-upgrade-node@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" - integrity sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ== +please-upgrade-node@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" + integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== dependencies: semver-compare "^1.0.0" @@ -4777,17 +4733,17 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@1.18.2: - version "1.18.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" - integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== +prettier@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" + integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== -pretty-format@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.8.0.tgz#8dae7044f58db7cb8be245383b565a963e3c27f2" - integrity sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw== +pretty-format@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" + integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" ansi-regex "^4.0.0" ansi-styles "^3.2.0" react-is "^16.8.4" @@ -4815,12 +4771,12 @@ promptly@^2.1.0: read "^1.0.4" prompts@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.1.0.tgz#bf90bc71f6065d255ea2bdc0fe6520485c1b45db" - integrity sha512-+x5TozgqYdOwWsQFZizE/Tra3fKvAoy037kOyU6cgz84n8f6zxngLOV4O32kTwt9FcLCxAqw0P/c8rOr9y+Gfg== + version "2.3.0" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.0.tgz#a444e968fa4cc7e86689a74050685ac8006c4cc4" + integrity sha512-NfbbPPg/74fT7wk2XYQ7hAIp9zJyZp5Fu19iRbORqqy1BhtrkZ0fPafBU+7bmn8ie69DpT0R6QpJIN2oisYjJg== dependencies: - kleur "^3.0.2" - sisteransi "^1.0.0" + kleur "^3.0.3" + sisteransi "^1.0.3" prop-types@^15.7.2: version "15.7.2" @@ -4832,9 +4788,9 @@ prop-types@^15.7.2: react-is "^16.8.1" psl@^1.1.24, psl@^1.1.28: - version "1.2.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.2.0.tgz#df12b5b1b3a30f51c329eacbdef98f3a6e136dc6" - integrity sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA== + version "1.4.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.4.0.tgz#5dd26156cdb69fa1fdb8ab1991667d3f80ced7c2" + integrity sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw== pump@^3.0.0: version "3.0.0" @@ -4870,9 +4826,9 @@ rc@^1.2.7: strip-json-comments "~2.0.1" react-is@^16.8.1, react-is@^16.8.4: - version "16.8.6" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" - integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA== + version "16.12.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c" + integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q== read-pkg-up@^2.0.0: version "2.0.0" @@ -4908,7 +4864,7 @@ read-pkg@^3.0.0: normalize-package-data "^2.3.2" path-type "^3.0.0" -read-pkg@^5.1.1: +read-pkg@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== @@ -4925,7 +4881,7 @@ read@^1.0.4: dependencies: mute-stream "~0.0.4" -readable-stream@^2.0.1, readable-stream@^2.0.6: +readable-stream@^2.0.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -4952,7 +4908,7 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" -regenerate-unicode-properties@^8.0.2: +regenerate-unicode-properties@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== @@ -4994,32 +4950,32 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp-tree@^0.1.6: - version "0.1.11" - resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.11.tgz#c9c7f00fcf722e0a56c7390983a7a63dd6c272f3" - integrity sha512-7/l/DgapVVDzZobwMCCgMlqiqyLFJ0cduo/j+3BcDJIB+yJdsYCfKuI3l/04NV+H/rfNRdPIDbXNZHM9XvQatg== - regexpp@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== -regexpu-core@^4.5.4: - version "4.5.4" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae" - integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ== +regexpp@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.0.0.tgz#dd63982ee3300e67b41c1956f850aa680d9d330e" + integrity sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g== + +regexpu-core@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6" + integrity sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg== dependencies: regenerate "^1.4.0" - regenerate-unicode-properties "^8.0.2" + regenerate-unicode-properties "^8.1.0" regjsgen "^0.5.0" regjsparser "^0.6.0" unicode-match-property-ecmascript "^1.0.4" unicode-match-property-value-ecmascript "^1.1.0" regjsgen@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd" - integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA== + version "0.5.1" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c" + integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg== regjsparser@^0.6.0: version "0.6.0" @@ -5043,19 +4999,19 @@ repeat-string@^1.6.1: resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -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== +request-promise-core@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" + integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ== dependencies: - lodash "^4.17.11" + lodash "^4.17.15" request-promise-native@^1.0.5: - 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== + version "1.0.8" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" + integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ== dependencies: - request-promise-core "1.1.2" + request-promise-core "1.1.3" stealthy-require "^1.1.1" tough-cookie "^2.3.3" @@ -5090,11 +5046,6 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - require-main-filename@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" @@ -5135,10 +5086,10 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.3.2, resolve@^1.5.0: - version "1.11.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" - integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw== +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.5.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6" + integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w== dependencies: path-parse "^1.0.6" @@ -5150,28 +5101,38 @@ restore-cursor@^2.0.0: onetime "^2.0.0" signal-exit "^3.0.2" +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -reusify@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - right-pad@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/right-pad/-/right-pad-1.0.1.tgz#8ca08c2cbb5b55e74dafa96bf7fd1a27d568c8d0" integrity sha1-jKCMLLtbVedNr6lr9/0aJ9VoyNA= -rimraf@2.6.3, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: +rimraf@2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== dependencies: glob "^7.1.3" +rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + rsvp@^4.8.4: version "4.8.5" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" @@ -5189,15 +5150,10 @@ run-node@^1.0.0: resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A== -run-parallel@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" - integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== - rxjs@^6.1.0, rxjs@^6.3.3, rxjs@^6.4.0: - version "6.5.2" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.2.tgz#2e35ce815cd46d84d02a209fb4e5921e051dbec7" - integrity sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg== + version "6.5.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" + integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== dependencies: tslib "^1.9.0" @@ -5249,14 +5205,14 @@ semver-compare@^1.0.0: integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: - version "5.7.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" - integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + 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.1.2: - version "6.2.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db" - integrity sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A== +semver@^6.0.0, semver@^6.1.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" @@ -5280,11 +5236,23 @@ shebang-command@^1.2.0: dependencies: shebang-regex "^1.0.0" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + shelljs@0.7.6: version "0.7.6" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.6.tgz#379cccfb56b91c8601e4793356eb5382924de9ad" @@ -5304,10 +5272,10 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= -sisteransi@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.2.tgz#ec57d64b6f25c4f26c0e2c7dd23f2d7f12f7e418" - integrity sha512-ZcYcZcT69nSLAR2oLN2JwNmLkJEKGooFMCdvOkFrToUt/WfcRWqhIg4P4KwY4dmLbuyXIx4o4YmPsvMRJYJd/w== +sisteransi@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.4.tgz#386713f1ef688c7c0304dc4c0632898941cad2e3" + integrity sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig== slash@^2.0.0: version "2.0.0" @@ -5375,9 +5343,9 @@ source-map-resolve@^0.5.0: urix "^0.1.0" source-map-support@^0.5.6: - version "0.5.12" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" - integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== + version "0.5.16" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" + integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -5485,7 +5453,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2", string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -5493,7 +5461,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string-width@^3.0.0: +string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== @@ -5502,6 +5470,31 @@ string-width@^3.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" +string-width@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.trimleft@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" + integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string.prototype.trimright@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" + integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -5539,6 +5532,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + strip-ansi@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" @@ -5588,6 +5588,13 @@ supports-color@^6.1.0: dependencies: has-flag "^3.0.0" +supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + symbol-observable@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" @@ -5599,9 +5606,9 @@ symbol-tree@^3.2.2: integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== table@^5.2.3: - version "5.4.4" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.4.tgz#6e0f88fdae3692793d1077fd172a4667afe986a6" - integrity sha512-IIfEAUx5QlODLblLrGTTLJA7Tk0iLSGBvgY8essPRVNGHAzThujww1YqHLs6h3HfTg55h++RzLHH5Xw/rfv+mg== + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== dependencies: ajv "^6.10.2" lodash "^4.17.14" @@ -5609,13 +5616,13 @@ table@^5.2.3: string-width "^3.0.0" tar@^4: - version "4.4.10" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1" - integrity sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA== + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== dependencies: chownr "^1.1.1" fs-minipass "^1.2.5" - minipass "^2.3.5" + minipass "^2.8.6" minizlib "^1.2.1" mkdirp "^0.5.0" safe-buffer "^5.1.2" @@ -5726,11 +5733,6 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= - tslib@^1.9.0: version "1.10.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" @@ -5755,22 +5757,32 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-fest@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2" + integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw== + type-fest@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== type@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/type/-/type-1.0.1.tgz#084c9a17fcc9151a2cdb1459905c2e45e4bb7d61" - integrity sha512-MAM5dBMJCJNKs9E7JXo4CXRAansRfG0nlJxW7Wf6GZzSOvH31zClSaHdIMWLehe/EGMBkqeC55rrkaOr5Oo7Nw== + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" + integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== uglify-js@^3.1.4: - version "3.6.0" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5" - integrity sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg== + version "3.6.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.9.tgz#85d353edb6ddfb62a9d798f36e91792249320611" + integrity sha512-pcnnhaoG6RtrvHJ1dFncAe8Od6Nuy30oaJ82ts6//sGSXOP5UjBMEthiProjXmMNHOfd93sqlkztifFMcb+4yw== dependencies: - commander "~2.20.0" + commander "~2.20.3" source-map "~0.6.1" underscore@~1.6.0: @@ -5855,14 +5867,14 @@ util.promisify@^1.0.0: object.getownpropertydescriptors "^2.0.3" 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== + version "3.3.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" + integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== v8-compile-cache@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" - integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== + version "2.1.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" + integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== validate-npm-package-license@^3.0.1: version "3.0.4" @@ -5922,9 +5934,9 @@ whatwg-url@^6.4.1: webidl-conversions "^4.0.2" whatwg-url@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" - integrity sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ== + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== dependencies: lodash.sortby "^4.7.0" tr46 "^1.0.1" @@ -5942,6 +5954,13 @@ which@^1.2.14, which@^1.2.9, which@^1.3.0: dependencies: isexe "^2.0.0" +which@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.1.tgz#f1cf94d07a8e571b6ff006aeb91d0300c47ef0a4" + integrity sha512-N7GBZOTswtB9lkQBZA4+zAXrjEIWAUOB93AvzUiudRzRxhUdLURQ7D/gAIMY1gatT/LTbmbcv8SiYazy3eYB7w== + dependencies: + isexe "^2.0.0" + wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" @@ -5949,7 +5968,7 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -word-wrap@^1.0.3: +word-wrap@^1.0.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== @@ -5959,19 +5978,6 @@ wordwrap@~0.0.2: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= -wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" @@ -5980,6 +5986,15 @@ wrap-ansi@^3.0.1: string-width "^2.1.1" strip-ansi "^4.0.0" +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -6013,38 +6028,43 @@ xml-name-validator@^3.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== -"y18n@^3.2.1 || ^4.0.0": +y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== yallist@^3.0.0, yallist@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" - integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yaml@^1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.7.2.tgz#f26aabf738590ab61efaca502358e48dc9f348b2" + integrity sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw== + dependencies: + "@babel/runtime" "^7.6.3" -yargs-parser@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" - integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== +yargs-parser@^13.1.1: + version "13.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" + integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" -yargs@^12.0.2: - version "12.0.5" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" - integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== +yargs@^13.3.0: + version "13.3.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" + integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== dependencies: - cliui "^4.0.0" - decamelize "^1.2.0" + cliui "^5.0.0" find-up "^3.0.0" - get-caller-file "^1.0.1" - os-locale "^3.0.0" + get-caller-file "^2.0.1" require-directory "^2.1.1" - require-main-filename "^1.0.1" + require-main-filename "^2.0.0" set-blocking "^2.0.0" - string-width "^2.0.0" + string-width "^3.0.0" which-module "^2.0.0" - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^11.1.1" + y18n "^4.0.0" + yargs-parser "^13.1.1" From 5f0a807b4660636bd6a2e12dcc3816d605a38c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sun, 17 Nov 2019 16:09:08 +0200 Subject: [PATCH 46/64] chore(deps): remove unused devDependencies --- package.json | 2 - yarn.lock | 256 ++++----------------------------------------------- 2 files changed, 19 insertions(+), 239 deletions(-) diff --git a/package.json b/package.json index 5b561f17e..b862c2007 100644 --- a/package.json +++ b/package.json @@ -50,9 +50,7 @@ "@babel/preset-env": "^7.7.1", "babel-eslint": "^10.0.3", "babel-jest": "^24.9.0", - "commitizen": "3.1.2", "consolemock": "^1.1.0", - "cz-conventional-changelog": "2.1.0", "eslint": "^6.6.0", "eslint-config-okonet": "^7.0.2", "eslint-config-prettier": "^6.5.0", diff --git a/yarn.lock b/yarn.lock index 6d2d3e282..694265057 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1338,11 +1338,6 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -cachedir@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.1.0.tgz#b448c32b44cd9c0cd6ce4c419fa5b3c112c02191" - integrity sha512-xGBpPqoBvn3unBW7oxgb8aJn42K0m9m1/wyjmazah10Fq7bROGG3kRAE6OIyr3U3PIJUqGuebhCEdMk9OKJG0A== - caller-callsite@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" @@ -1558,27 +1553,6 @@ commander@^4.0.1: resolved "https://registry.yarnpkg.com/commander/-/commander-4.0.1.tgz#b67622721785993182e807f4883633e6401ba53c" integrity sha512-IPF4ouhCP+qdlcmCedhxX4xiGBPyigb8v5NeUp+0LyhwLgxMqyp3S0vl7TAPfS/hiP7FC3caI/PB9lTmP8r1NA== -commitizen@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/commitizen/-/commitizen-3.1.2.tgz#29ddd8b39396923e9058a0e4840cbeef144290be" - integrity sha512-eD0uTUsogu8ksFjFFYq75LLfXeLXsCIa27TPfOqvBI+tCx1Pp5QfKqC9oC+qTpSz3nTn9/+7TL5mE/wurB22JQ== - dependencies: - cachedir "2.1.0" - cz-conventional-changelog "2.1.0" - dedent "0.7.0" - detect-indent "^5.0.0" - find-node-modules "2.0.0" - find-root "1.1.0" - fs-extra "^7.0.0" - glob "7.1.3" - inquirer "6.2.0" - is-utf8 "^0.2.1" - lodash "4.17.14" - minimist "1.2.0" - shelljs "0.7.6" - strip-bom "3.0.0" - strip-json-comments "2.0.1" - component-emitter@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" @@ -1606,11 +1580,6 @@ contains-path@^0.1.0: resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= -conventional-commit-types@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/conventional-commit-types/-/conventional-commit-types-2.3.0.tgz#bc3c8ebba0a9e4b3ecc548f1d0674e251ab8be22" - integrity sha512-6iB39PrcGYdz0n3z31kj6/Km6mK9hm9oMRhwcLnKxE7WNoeRKZbTAobliKrbYZ5jqyCvtcVEfjCiaEzhL3AVmQ== - convert-source-map@^1.4.0, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" @@ -1694,17 +1663,6 @@ cssstyle@^1.0.0: dependencies: cssom "0.3.x" -cz-conventional-changelog@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cz-conventional-changelog/-/cz-conventional-changelog-2.1.0.tgz#2f4bc7390e3244e4df293e6ba351e4c740a7c764" - integrity sha1-L0vHOQ4yROTfKT5ro1Hkx0Cnx2Q= - dependencies: - conventional-commit-types "^2.0.0" - lodash.map "^4.5.1" - longest "^1.0.1" - right-pad "^1.0.1" - word-wrap "^1.0.3" - d@1, d@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" @@ -1770,7 +1728,7 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= -dedent@0.7.0, dedent@^0.7.0: +dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= @@ -1824,16 +1782,6 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= -detect-file@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" - integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= - -detect-indent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" - integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= - detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" @@ -2287,13 +2235,6 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expand-tilde@^2.0.0, expand-tilde@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" - integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= - dependencies: - homedir-polyfill "^1.0.1" - expect@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" @@ -2333,7 +2274,7 @@ extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -external-editor@^3.0.0, external-editor@^3.0.3: +external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== @@ -2439,19 +2380,6 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -find-node-modules@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/find-node-modules/-/find-node-modules-2.0.0.tgz#5db1fb9e668a3d451db3d618cd167cdd59e41b69" - integrity sha512-8MWIBRgJi/WpjjfVXumjPKCtmQ10B+fjx6zmSA+770GMJirLhWIzg8l763rhjl9xaeaHbnxPNRQKq2mgMhr+aw== - dependencies: - findup-sync "^3.0.0" - merge "^1.2.1" - -find-root@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" - integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== - find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -2474,16 +2402,6 @@ find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" -findup-sync@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" - integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== - dependencies: - detect-file "^1.0.0" - is-glob "^4.0.0" - micromatch "^3.0.4" - resolve-dir "^1.0.1" - flat-cache@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" @@ -2524,15 +2442,6 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -fs-extra@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" @@ -2639,19 +2548,7 @@ glob-parent@^5.0.0: dependencies: is-glob "^4.0.1" -glob@7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: +glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -2663,26 +2560,6 @@ glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -global-modules@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" - integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== - dependencies: - global-prefix "^1.0.1" - is-windows "^1.0.1" - resolve-dir "^1.0.0" - -global-prefix@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" - integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= - dependencies: - expand-tilde "^2.0.2" - homedir-polyfill "^1.0.1" - ini "^1.3.4" - is-windows "^1.0.1" - which "^1.2.14" - globals@^11.1.0, globals@^11.7.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -2799,13 +2676,6 @@ has@^1.0.1, has@^1.0.3: dependencies: function-bind "^1.1.1" -homedir-polyfill@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" - integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== - dependencies: - parse-passwd "^1.0.0" - hosted-git-info@^2.1.4: version "2.8.5" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c" @@ -2928,30 +2798,11 @@ inherits@2, inherits@~2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ini@^1.3.4, ini@~1.3.0: +ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== -inquirer@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8" - integrity sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg== - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^3.0.0" - figures "^2.0.0" - lodash "^4.17.10" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^6.1.0" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - inquirer@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.0.tgz#9e2b032dde77da1db5db804758b8fea3a970519a" @@ -2985,11 +2836,6 @@ install-peerdeps@^1.2.0: request-promise-native "^1.0.5" semver "^5.5.0" -interpret@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" - integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== - invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -3191,12 +3037,7 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -is-utf8@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - -is-windows@^1.0.1, is-windows@^1.0.2: +is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== @@ -3909,22 +3750,12 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash.map@^4.5.1: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" - integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= - lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= -lodash@4.17.14: - version "4.17.14" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" - integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== - -lodash@^4.17.10, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15: +lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -3952,11 +3783,6 @@ log-update@^2.3.0: cli-cursor "^2.0.0" wrap-ansi "^3.0.1" -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= - loose-envify@^1.0.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -4017,12 +3843,7 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" - integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== - -micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: +micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -4083,7 +3904,7 @@ minimist@0.0.8: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -minimist@1.2.0, minimist@^1.1.1, minimist@^1.2.0: +minimist@^1.1.1, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= @@ -4133,11 +3954,6 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= - mute-stream@0.0.8, mute-stream@~0.0.4: version "0.0.8" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" @@ -4587,11 +4403,6 @@ parse-json@^5.0.0: json-parse-better-errors "^1.0.1" lines-and-columns "^1.1.6" -parse-passwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" - integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= - parse5@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" @@ -4901,13 +4712,6 @@ realpath-native@^1.1.0: dependencies: util.promisify "^1.0.0" -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= - dependencies: - resolve "^1.1.6" - regenerate-unicode-properties@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" @@ -5058,14 +4862,6 @@ resolve-cwd@^2.0.0: dependencies: resolve-from "^3.0.0" -resolve-dir@^1.0.0, resolve-dir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" - integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= - dependencies: - expand-tilde "^2.0.0" - global-modules "^1.0.0" - resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" @@ -5086,7 +4882,7 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.5.0: +resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.5.0: version "1.12.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6" integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w== @@ -5114,11 +4910,6 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -right-pad@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/right-pad/-/right-pad-1.0.1.tgz#8ca08c2cbb5b55e74dafa96bf7fd1a27d568c8d0" - integrity sha1-jKCMLLtbVedNr6lr9/0aJ9VoyNA= - rimraf@2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" @@ -5150,7 +4941,7 @@ run-node@^1.0.0: resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A== -rxjs@^6.1.0, rxjs@^6.3.3, rxjs@^6.4.0: +rxjs@^6.3.3, rxjs@^6.4.0: version "6.5.3" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== @@ -5253,15 +5044,6 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shelljs@0.7.6: - version "0.7.6" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.6.tgz#379cccfb56b91c8601e4793356eb5382924de9ad" - integrity sha1-N5zM+1a5HIYB5HkzVutTgpJN6a0= - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - shellwords@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" @@ -5453,7 +5235,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.1.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2", string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -5544,7 +5326,7 @@ strip-ansi@~0.1.0: resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" integrity sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE= -strip-bom@3.0.0, strip-bom@^3.0.0: +strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= @@ -5559,16 +5341,16 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@2.0.1, strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - strip-json-comments@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -5947,7 +5729,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.2.14, which@^1.2.9, which@^1.3.0: +which@^1.2.9, which@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -5968,7 +5750,7 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -word-wrap@^1.0.3, word-wrap@~1.2.3: +word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== From cb43872fb6c05366a8fc25a8bd889b95918f45a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Wed, 20 Nov 2019 11:56:44 +0200 Subject: [PATCH 47/64] feat: split tasks into chunks to support shells with limited max argument length (#732) * feat: split tasks into chunks to support shells with limited max argument length * refactor: use a function for getting max arg lenth * refactor: simplify spreading of listrTasks into main runner tasks --- README.md | 6 ++ bin/lint-staged | 19 +++++ lib/chunkFiles.js | 40 +++++++++ lib/index.js | 13 ++- lib/runAll.js | 112 ++++++++++++++----------- test/__snapshots__/runAll.spec.js.snap | 21 ----- test/chunkFiles.spec.js | 29 +++++++ test/runAll.spec.js | 12 --- test/runAll.unmocked.spec.js | 23 +++++ 9 files changed, 192 insertions(+), 83 deletions(-) create mode 100644 lib/chunkFiles.js create mode 100644 test/chunkFiles.spec.js diff --git a/README.md b/README.md index a171e46e6..fe953ead0 100644 --- a/README.md +++ b/README.md @@ -394,6 +394,8 @@ Parameters to `lintStaged` are equivalent to their CLI counterparts: ```js const success = await lintStaged({ configPath: './path/to/configuration/file', + maxArgLength: null, + relative: false, shell: false, quiet: false, debug: false @@ -407,12 +409,16 @@ const success = await lintStaged({ config: { '*.js': 'eslint --fix' }, + maxArgLength: null, + relative: false, shell: false, quiet: false, debug: false }) ``` +The `maxArgLength` option configures chunking of tasks into multiple parts that are run one after the other. This is to avoid issues on Windows platforms where the maximum length of the command line argument string is limited to 8192 characters. Lint-staged might generate a very long argument string when there are many staged files. This option is set automatically from the cli, but not via the Node.js API by default. + ### Using with JetBrains IDEs _(WebStorm, PyCharm, IntelliJ IDEA, RubyMine, etc.)_ _**Update**_: The latest version of JetBrains IDEs now support running hooks as you would expect. diff --git a/bin/lint-staged b/bin/lint-staged index 277f1b681..eea0d69fc 100755 --- a/bin/lint-staged +++ b/bin/lint-staged @@ -42,8 +42,27 @@ if (cmdline.debug) { debug('Running `lint-staged@%s`', pkg.version) +/** + * Get the maximum length of a command-line argument string based on current platform + * + * https://serverfault.com/questions/69430/what-is-the-maximum-length-of-a-command-line-in-mac-os-x + * https://support.microsoft.com/en-us/help/830473/command-prompt-cmd-exe-command-line-string-limitation + * https://unix.stackexchange.com/a/120652 + */ +const getMaxArgLength = () => { + switch (process.platform) { + case 'darwin': + return 262144 + case 'win32': + return 8191 + default: + return 131072 + } +} + lintStaged({ configPath: cmdline.config, + maxArgLength: getMaxArgLength(), relative: !!cmdline.relative, shell: !!cmdline.shell, quiet: !!cmdline.quiet, diff --git a/lib/chunkFiles.js b/lib/chunkFiles.js new file mode 100644 index 000000000..824c383d7 --- /dev/null +++ b/lib/chunkFiles.js @@ -0,0 +1,40 @@ +'use strict' + +const normalize = require('normalize-path') +const path = require('path') + +/** + * Chunk array into sub-arrays + * @param {Array} arr + * @param {Number} chunkCount + * @retuns {Array} + */ +function chunkArray(arr, chunkCount) { + if (chunkCount === 1) return [arr] + const chunked = [] + let position = 0 + for (let i = 0; i < chunkCount; i++) { + const chunkLength = Math.ceil((arr.length - position) / (chunkCount - i)) + chunked.push([]) + chunked[i] = arr.slice(position, chunkLength + position) + position += chunkLength + } + return chunked +} + +/** + * Chunk files into sub-arrays based on the length of the resulting argument string + * @param {Object} opts + * @param {Array} opts.files + * @param {String} opts.gitDir + * @param {number} [opts.maxArgLength] the maximum argument string length + * @param {Boolean} [opts.relative] whether files are relative to `gitDir` or should be resolved as absolute + * @returns {Array>} + */ +module.exports = function chunkFiles({ files, gitDir, maxArgLength = null, relative = false }) { + if (!maxArgLength) return [files] + const normalizedFiles = files.map(file => normalize(relative ? file : path.resolve(gitDir, file))) + const fileListLength = normalizedFiles.join(' ').length + const chunkCount = Math.min(Math.ceil(fileListLength / maxArgLength), files.length) + return chunkArray(files, chunkCount) +} diff --git a/lib/index.js b/lib/index.js index bdfd92bba..53827a493 100644 --- a/lib/index.js +++ b/lib/index.js @@ -44,6 +44,7 @@ function loadConfig(configPath) { * @param {object} options * @param {string} [options.configPath] - Path to configuration file * @param {object} [options.config] - Object with configuration for programmatic API + * @param {number} [options.maxArgLength] - Maximum argument string length * @param {boolean} [options.relative] - Pass relative filepaths to tasks * @param {boolean} [options.shell] - Skip parsing of tasks for better shell support * @param {boolean} [options.quiet] - Disable lint-staged’s own console output @@ -53,7 +54,15 @@ function loadConfig(configPath) { * @returns {Promise} Promise of whether the linting passed or failed */ module.exports = function lintStaged( - { configPath, config, relative = false, shell = false, quiet = false, debug = false } = {}, + { + configPath, + config, + maxArgLength, + relative = false, + shell = false, + quiet = false, + debug = false + } = {}, logger = console ) { debugLog('Loading config using `cosmiconfig`') @@ -76,7 +85,7 @@ module.exports = function lintStaged( debugLog('lint-staged config:\n%O', config) } - return runAll({ config, relative, shell, quiet, debug }, logger) + return runAll({ config, maxArgLength, relative, shell, quiet, debug }, logger) .then(() => { debugLog('tasks were executed successfully!') return Promise.resolve(true) diff --git a/lib/runAll.js b/lib/runAll.js index 21c1cef61..cbc6adaae 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -6,6 +6,7 @@ const chalk = require('chalk') const Listr = require('listr') const symbols = require('log-symbols') +const chunkFiles = require('./chunkFiles') const generateTasks = require('./generateTasks') const getStagedFiles = require('./getStagedFiles') const GitWorkflow = require('./gitWorkflow') @@ -14,20 +15,13 @@ const resolveGitDir = require('./resolveGitDir') const debugLog = require('debug')('lint-staged:run') -/** - * https://serverfault.com/questions/69430/what-is-the-maximum-length-of-a-command-line-in-mac-os-x - * https://support.microsoft.com/en-us/help/830473/command-prompt-cmd-exe-command-line-string-limitation - * https://unix.stackexchange.com/a/120652 - */ -const MAX_ARG_LENGTH = - (process.platform === 'darwin' && 262144) || (process.platform === 'win32' && 8191) || 131072 - /** * Executes all tasks and either resolves or rejects the promise * * @param {object} options * @param {Object} [options.config] - Task configuration * @param {Object} [options.cwd] - Current working directory + * @param {number} [options.maxArgLength] - Maximum argument string length * @param {boolean} [options.relative] - Pass relative filepaths to tasks * @param {boolean} [options.shell] - Skip parsing of tasks for better shell support * @param {boolean} [options.quiet] - Disable lint-staged’s own console output @@ -36,7 +30,15 @@ const MAX_ARG_LENGTH = * @returns {Promise} */ module.exports = async function runAll( - { config, cwd = process.cwd(), debug = false, quiet = false, relative = false, shell = false }, + { + config, + cwd = process.cwd(), + debug = false, + maxArgLength, + quiet = false, + relative = false, + shell = false + }, logger = console ) { debugLog('Running all linter scripts') @@ -57,48 +59,70 @@ module.exports = async function runAll( debugLog('Loaded list of staged files in git:\n%O', files) - const argLength = files.join(' ').length - if (argLength > MAX_ARG_LENGTH) { - logger.warn(` - ${symbols.warning} ${chalk.yellow( - `lint-staged generated an argument string of ${argLength} characters, and commands might not run correctly on your platform. - It is recommended to use functions as linters and split your command based on the number of staged files. For more info, please visit: - https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-commands` - )} -`) + const chunkedFiles = chunkFiles({ files, gitDir, maxArgLength, relative }) + const chunkCount = chunkedFiles.length + if (chunkCount > 1) { + debugLog(`Chunked staged files into ${chunkCount} part`, chunkCount) } - const tasks = generateTasks({ config, cwd, gitDir, files, relative }) - // lint-staged 10 will automatically add modifications to index // Warn user when their command includes `git add` let hasDeprecatedGitAdd = false - const listrTasks = tasks.map(task => { - const subTasks = makeCmdTasks({ commands: task.commands, files: task.fileList, gitDir, shell }) + const listrOptions = { + dateFormat: false, + renderer: (quiet && 'silent') || (debug && 'verbose') || 'update' + } - if (subTasks.some(subTask => subTask.command.includes('git add'))) { - hasDeprecatedGitAdd = true - } + const listrTasks = [] + + for (const [index, files] of chunkedFiles.entries()) { + const chunkTasks = generateTasks({ config, cwd, gitDir, files, relative }) + const chunkListrTasks = chunkTasks.map(task => { + const subTasks = makeCmdTasks({ + commands: task.commands, + files: task.fileList, + gitDir, + shell + }) - return { - title: `Running tasks for ${task.pattern}`, - task: async () => - new Listr(subTasks, { - // In sub-tasks we don't want to run concurrently - // and we want to abort on errors - dateFormat: false, - concurrent: false, - exitOnError: true - }), + if (subTasks.some(subTask => subTask.command.includes('git add'))) { + hasDeprecatedGitAdd = true + } + + return { + title: `Running tasks for ${task.pattern}`, + task: async () => + new Listr(subTasks, { + // In sub-tasks we don't want to run concurrently + // and we want to abort on errors + dateFormat: false, + concurrent: false, + exitOnError: true + }), + skip: () => { + if (task.fileList.length === 0) { + return `No staged files match ${task.pattern}` + } + return false + } + } + }) + + listrTasks.push({ + // No need to show number of task chunks when there's only one + title: + chunkCount > 1 ? `Running tasks (chunk ${index}/${chunkCount})...` : 'Running tasks...', + task: () => + new Listr(chunkListrTasks, { ...listrOptions, concurrent: false, exitOnError: false }), skip: () => { - if (task.fileList.length === 0) { - return `No staged files match ${task.pattern}` + if (chunkListrTasks.every(task => task.skip())) { + return 'No tasks to run' } return false } - } - }) + }) + } if (hasDeprecatedGitAdd) { logger.warn(`${symbols.warning} ${chalk.yellow( @@ -114,11 +138,6 @@ module.exports = async function runAll( return 'No tasks to run.' } - const listrOptions = { - dateFormat: false, - renderer: (quiet && 'silent') || (debug && 'verbose') || 'update' - } - const git = new GitWorkflow(gitDir) const runner = new Listr( @@ -127,10 +146,7 @@ module.exports = async function runAll( title: 'Preparing...', task: () => git.stashBackup() }, - { - title: 'Running tasks...', - task: () => new Listr(listrTasks, { ...listrOptions, concurrent: true, exitOnError: false }) - }, + ...listrTasks, { title: 'Applying modifications...', skip: ctx => ctx.hasErrors && 'Skipped because of errors from tasks', diff --git a/test/__snapshots__/runAll.spec.js.snap b/test/__snapshots__/runAll.spec.js.snap index 130ed3b91..3ce7f0e71 100644 --- a/test/__snapshots__/runAll.spec.js.snap +++ b/test/__snapshots__/runAll.spec.js.snap @@ -87,24 +87,3 @@ exports[`runAll should use an injected logger 1`] = ` " LOG No staged files match any of provided globs." `; - -exports[`runAll should warn if the argument length is longer than what the platform can handle 1`] = ` -" -WARN - ‼ lint-staged generated an argument string of 999999 characters, and commands might not run correctly on your platform. - It is recommended to use functions as linters and split your command based on the number of staged files. For more info, please visit: - https://github.com/okonet/lint-staged#using-js-functions-to-customize-linter-commands - -LOG Preparing... [started] -LOG Preparing... [completed] -LOG Running tasks... [started] -LOG Running tasks for *.js [started] -LOG echo \\"sample\\" [started] -LOG echo \\"sample\\" [completed] -LOG Running tasks for *.js [completed] -LOG Running tasks... [completed] -LOG Applying modifications... [started] -LOG Applying modifications... [completed] -LOG Cleaning up... [started] -LOG Cleaning up... [completed]" -`; diff --git a/test/chunkFiles.spec.js b/test/chunkFiles.spec.js new file mode 100644 index 000000000..7686d448b --- /dev/null +++ b/test/chunkFiles.spec.js @@ -0,0 +1,29 @@ +import chunkFiles from '../lib/chunkFiles' + +describe('chunkFiles', () => { + const files = ['example.js', 'foo.js', 'bar.js', 'foo/bar.js'] + const gitDir = '/opt/git/example.git' + + it('should default to sane value', () => { + const chunkedFiles = chunkFiles({ files: ['foo.js'], gitDir, relative: true }) + expect(chunkedFiles).toEqual([['foo.js']]) + }) + + it('should not chunk short argument string', () => { + const chunkedFiles = chunkFiles({ files, gitDir, maxArgLength: 1000 }) + expect(chunkedFiles).toEqual([files]) + }) + + it('should chunk too long argument string', () => { + const chunkedFiles = chunkFiles({ files, gitDir, maxArgLength: 20 }) + expect(chunkedFiles).toEqual(files.map(file => [file])) + }) + + it('should take into account relative setting', () => { + const chunkedFiles = chunkFiles({ files, gitDir, maxArgLength: 20, relative: true }) + expect(chunkedFiles).toEqual([ + [files[0], files[1]], + [files[2], files[3]] + ]) + }) +}) diff --git a/test/runAll.spec.js b/test/runAll.spec.js index c72939970..c5d32b91b 100644 --- a/test/runAll.spec.js +++ b/test/runAll.spec.js @@ -38,18 +38,6 @@ describe('runAll', () => { expect(console.printHistory()).toMatchSnapshot() }) - it('should warn if the argument length is longer than what the platform can handle', async () => { - getStagedFiles.mockImplementationOnce(async () => new Array(100000).fill('sample.js')) - - try { - await runAll({ config: { '*.js': () => 'echo "sample"' } }) - } catch (err) { - console.log(err) - } - - expect(console.printHistory()).toMatchSnapshot() - }) - it('should use an injected logger', async () => { expect.assertions(1) const logger = makeConsoleMock() diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index affb64255..52c6f9078 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -82,6 +82,11 @@ describe('runAll', () => { ) await removeTempDir(nonGitDir) }) + + it('should short-circuit with no staged files', async () => { + const status = await runAll({ config: { '*.js': 'echo success' }, cwd }) + expect(status).toEqual('No tasks to run.') + }) }) const globalConsoleTemp = console @@ -533,4 +538,22 @@ describe('runAll', () => { expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('test') expect(await readFile('test.js')).toEqual(testJsFilePretty) }) + + it('should run chunked tasks when necessary', async () => { + // Stage two files + await appendFile('test.js', testJsFilePretty) + await execGit(['add', 'test.js']) + await appendFile('test2.js', testJsFilePretty) + await execGit(['add', 'test2.js']) + + // Run lint-staged with `prettier --list-different` and commit pretty file + // Set maxArgLength low enough so that chunking is used + await gitCommit({ config: { '*.js': 'prettier --list-different' }, maxArgLength: 10 }) + + // Nothing is wrong, so a new commit is created + expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('test') + expect(await readFile('test.js')).toEqual(testJsFilePretty) + expect(await readFile('test2.js')).toEqual(testJsFilePretty) + }) }) From f88e22619b8dea4fbcda3d57a85ca9d1be152908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20Ja=CC=88ppinen?= Date: Wed, 27 Nov 2019 07:12:20 +0200 Subject: [PATCH 48/64] fix: improve debug logging --- bin/lint-staged | 8 ++++++-- lib/chunkFiles.js | 13 +++++++++++-- lib/runAll.js | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/bin/lint-staged b/bin/lint-staged index eea0d69fc..90126cae3 100755 --- a/bin/lint-staged +++ b/bin/lint-staged @@ -60,14 +60,18 @@ const getMaxArgLength = () => { } } -lintStaged({ +const options = { configPath: cmdline.config, maxArgLength: getMaxArgLength(), relative: !!cmdline.relative, shell: !!cmdline.shell, quiet: !!cmdline.quiet, debug: !!cmdline.debug -}) +} + +debug('Options parsed from command-line:', options) + +lintStaged(options) .then(passed => { process.exitCode = passed ? 0 : 1 }) diff --git a/lib/chunkFiles.js b/lib/chunkFiles.js index 824c383d7..f375a40b9 100644 --- a/lib/chunkFiles.js +++ b/lib/chunkFiles.js @@ -1,5 +1,6 @@ 'use strict' +const debug = require('debug')('lint-staged:chunkFiles') const normalize = require('normalize-path') const path = require('path') @@ -32,9 +33,17 @@ function chunkArray(arr, chunkCount) { * @returns {Array>} */ module.exports = function chunkFiles({ files, gitDir, maxArgLength = null, relative = false }) { - if (!maxArgLength) return [files] + if (!maxArgLength) { + debug('Skip chunking files because of undefined maxArgLength') + return [files] + } + const normalizedFiles = files.map(file => normalize(relative ? file : path.resolve(gitDir, file))) const fileListLength = normalizedFiles.join(' ').length - const chunkCount = Math.min(Math.ceil(fileListLength / maxArgLength), files.length) + debug( + `Resolved an argument string length of ${fileListLength} characters from ${normalizedFiles.length} files` + ) + const chunkCount = Math.min(Math.ceil(fileListLength / maxArgLength), normalizedFiles.length) + debug(`Creating ${chunkCount} chunks for maxArgLength of ${maxArgLength}`) return chunkArray(files, chunkCount) } diff --git a/lib/runAll.js b/lib/runAll.js index cbc6adaae..5039f49f6 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -112,7 +112,7 @@ module.exports = async function runAll( listrTasks.push({ // No need to show number of task chunks when there's only one title: - chunkCount > 1 ? `Running tasks (chunk ${index}/${chunkCount})...` : 'Running tasks...', + chunkCount > 1 ? `Running tasks (chunk ${index + 1}/${chunkCount})...` : 'Running tasks...', task: () => new Listr(chunkListrTasks, { ...listrOptions, concurrent: false, exitOnError: false }), skip: () => { From 03ea13242cd9db34b563b7b45376d0789185393e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20Ja=CC=88ppinen?= Date: Wed, 27 Nov 2019 08:10:39 +0200 Subject: [PATCH 49/64] refactor: linStaged is an async function --- lib/index.js | 92 ++++++++++++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/lib/index.js b/lib/index.js index 53827a493..1e76a61ac 100644 --- a/lib/index.js +++ b/lib/index.js @@ -53,10 +53,10 @@ function loadConfig(configPath) { * * @returns {Promise} Promise of whether the linting passed or failed */ -module.exports = function lintStaged( +module.exports = async function lintStaged( { configPath, - config, + config: configObject, maxArgLength, relative = false, shell = false, @@ -65,54 +65,54 @@ module.exports = function lintStaged( } = {}, logger = console ) { - debugLog('Loading config using `cosmiconfig`') - - return (config ? Promise.resolve({ config, filepath: '(input)' }) : loadConfig(configPath)) - .then(result => { - if (result == null) throw errConfigNotFound + try { + debugLog('Loading config using `cosmiconfig`') - debugLog('Successfully loaded config from `%s`:\n%O', result.filepath, result.config) - // result.config is the parsed configuration object - // result.filepath is the path to the config file that was found - const config = validateConfig(result.config) - if (debug) { - // Log using logger to be able to test through `consolemock`. - logger.log('Running lint-staged with the following config:') - logger.log(stringifyObject(config, { indent: ' ' })) - } else { - // We might not be in debug mode but `DEBUG=lint-staged*` could have - // been set. - debugLog('lint-staged config:\n%O', config) - } + const resolved = configObject + ? { config: configObject, filepath: '(input)' } + : await loadConfig(configPath) + if (resolved == null) throw errConfigNotFound - return runAll({ config, maxArgLength, relative, shell, quiet, debug }, logger) - .then(() => { - debugLog('tasks were executed successfully!') - return Promise.resolve(true) - }) - .catch(error => { - printErrors(error, logger) - return Promise.resolve(false) - }) - }) - .catch(err => { - if (err === errConfigNotFound) { - logger.error(`${err.message}.`) - } else { - // It was probably a parsing error - logger.error(dedent` - Could not parse lint-staged config. + debugLog('Successfully loaded config from `%s`:\n%O', resolved.filepath, resolved.config) + // resolved.config is the parsed configuration object + // resolved.filepath is the path to the config file that was found + const config = validateConfig(resolved.config) + if (debug) { + // Log using logger to be able to test through `consolemock`. + logger.log('Running lint-staged with the following config:') + logger.log(stringifyObject(config, { indent: ' ' })) + } else { + // We might not be in debug mode but `DEBUG=lint-staged*` could have + // been set. + debugLog('lint-staged config:\n%O', config) + } - ${err} - `) - } - logger.error() // empty line - // Print helpful message for all errors + try { + await runAll({ config, maxArgLength, relative, shell, quiet, debug }, logger) + debugLog('tasks were executed successfully!') + return true + } catch (runAllError) { + printErrors(runAllError, logger) + return false + } + } catch (lintStagedError) { + if (lintStagedError === errConfigNotFound) { + logger.error(`${lintStagedError.message}.`) + } else { + // It was probably a parsing error logger.error(dedent` - Please make sure you have created it correctly. - See https://github.com/okonet/lint-staged#configuration. + Could not parse lint-staged config. + + ${lintStagedError} `) + } + logger.error() // empty line + // Print helpful message for all errors + logger.error(dedent` + Please make sure you have created it correctly. + See https://github.com/okonet/lint-staged#configuration. + `) - return Promise.reject(err) - }) + throw lintStagedError + } } From 80406c20fd3d1a86b0a0558c10f6747b2b47698e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20Ja=CC=88ppinen?= Date: Wed, 27 Nov 2019 08:12:06 +0200 Subject: [PATCH 50/64] fix: max arg length is by default half of the allowed to prevent edge cases --- bin/lint-staged | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/lint-staged b/bin/lint-staged index 90126cae3..49c1eb869 100755 --- a/bin/lint-staged +++ b/bin/lint-staged @@ -62,7 +62,7 @@ const getMaxArgLength = () => { const options = { configPath: cmdline.config, - maxArgLength: getMaxArgLength(), + maxArgLength: getMaxArgLength() / 2, relative: !!cmdline.relative, shell: !!cmdline.shell, quiet: !!cmdline.quiet, From 0eedacdb12b65c99a8a0e098cc48b2a50974d84d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20Ja=CC=88ppinen?= Date: Wed, 27 Nov 2019 14:36:21 +0200 Subject: [PATCH 51/64] test: remove non-working concurrency tests for now --- test/runAll.unmocked.spec.js | 75 ------------------------------------ 1 file changed, 75 deletions(-) diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index ef6428d04..52c6f9078 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -133,81 +133,6 @@ describe('runAll', () => { expect(await readFile('test.js')).toEqual(testJsFilePretty) }) - it('Should succeed when conflicting tasks sequentially edit a file', async () => { - await appendFile('test.js', testJsFileUgly) - - await fs.mkdir(cwd + '/files') - await appendFile('file.js', testJsFileUgly, cwd + '/files') - - await execGit(['add', 'test.js']) - await execGit(['add', 'files']) - - const success = await gitCommit({ - config: { - 'file.js': ['prettier --write', 'git add'], - 'test.js': files => { - // concurrent: false, means this should still work - fs.removeSync(`${cwd}/files`) - return [`prettier --write ${files.join(' ')}`, `git add ${files.join(' ')}`] - } - }, - concurrent: false - }) - - expect(success).toEqual(true) - }) - - it('Should fail when conflicting tasks concurrently edit a file', async () => { - await appendFile('test.js', testJsFileUgly) - await appendFile('test2.js', testJsFileUgly) - - await fs.mkdir(cwd + '/files') - await appendFile('file.js', testJsFileUgly, cwd + '/files') - - await execGit(['add', 'test.js']) - await execGit(['add', 'test2.js']) - await execGit(['add', 'files']) - - const success = await gitCommit({ - config: { - 'file.js': ['prettier --write', 'git add'], - 'test.js': ['prettier --write', 'git add'], - 'test2.js': files => { - // remove `files` so the 1st command should fail - fs.removeSync(`${cwd}/files`) - return [`prettier --write ${files.join(' ')}`, `git add ${files.join(' ')}`] - } - }, - concurrent: true - }) - - expect(success).toEqual(false) - }) - - it('Should succeed when conflicting tasks concurrently (max concurrency 1) edit a file', async () => { - await appendFile('test.js', testJsFileUgly) - - await fs.mkdir(cwd + '/files') - await appendFile('file.js', testJsFileUgly, cwd + '/files') - - await execGit(['add', 'test.js']) - await execGit(['add', 'files']) - - const success = await gitCommit({ - config: { - 'file.js': ['prettier --write', 'git add'], - 'test2.js': files => { - // concurrency of one should prevent save this operation - fs.removeSync(`${cwd}/files`) - return [`prettier --write ${files.join(' ')}`, `git add ${files.join(' ')}`] - } - }, - concurrent: 1 - }) - - expect(success).toEqual(true) - }) - it('Should commit entire staged file when no errors and linter modifies file', async () => { // Stage multiple ugly files await appendFile('test.js', testJsFileUgly) From 814b9dfe131f55c18a8996f775dd5dd582d0a766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Tue, 3 Dec 2019 11:54:15 +0200 Subject: [PATCH 52/64] feat: bump Node.js version dependency to at least 10.13.0 (#747) BREAKING CHANGE: Node.js v8 is no longer supported because it will reach EOL on 2019-12-31 --- .appveyor.yml | 2 +- .travis.yml | 2 +- bin/lint-staged | 2 +- package.json | 20 +- yarn.lock | 894 +++++++++++++++++++++++++++--------------------- 5 files changed, 526 insertions(+), 394 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index c439c0d3d..21972265f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -4,9 +4,9 @@ environment: matrix: + - nodejs_version: '13' - nodejs_version: '12' - nodejs_version: '10' - - nodejs_version: '8' matrix: fast_finish: true diff --git a/.travis.yml b/.travis.yml index 9704a0612..9b142f754 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,9 @@ language: node_js node_js: + - '13' - '12' - '10' - - '8' before_install: yarn global add greenkeeper-lockfile@1 install: yarn install diff --git a/bin/lint-staged b/bin/lint-staged index a76846d3e..81f0e6f2c 100755 --- a/bin/lint-staged +++ b/bin/lint-staged @@ -16,7 +16,7 @@ const pkg = require('../package.json') require('please-upgrade-node')( Object.assign({}, pkg, { engines: { - node: '>=8.12.0' + node: '>=10.13.0' // First LTS release of 'Dubnium' } }) ) diff --git a/package.json b/package.json index b862c2007..643814cf7 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "cosmiconfig": "^6.0.0", "debug": "^4.1.1", "dedent": "^0.7.0", - "execa": "^3.3.0", + "execa": "^3.4.0", "listr": "^0.14.3", "log-symbols": "^3.0.0", "micromatch": "^4.0.2", @@ -45,27 +45,27 @@ "stringify-object": "^3.3.0" }, "devDependencies": { - "@babel/core": "^7.7.2", - "@babel/plugin-proposal-object-rest-spread": "^7.6.2", - "@babel/preset-env": "^7.7.1", + "@babel/core": "^7.7.4", + "@babel/plugin-proposal-object-rest-spread": "^7.7.4", + "@babel/preset-env": "^7.7.4", "babel-eslint": "^10.0.3", "babel-jest": "^24.9.0", "consolemock": "^1.1.0", - "eslint": "^6.6.0", + "eslint": "^6.7.2", "eslint-config-okonet": "^7.0.2", - "eslint-config-prettier": "^6.5.0", - "eslint-plugin-flowtype": "^4.4.1", + "eslint-config-prettier": "^6.7.0", + "eslint-plugin-flowtype": "^4.5.2", "eslint-plugin-import": "^2.18.2", "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-node": "^10.0.0", "eslint-plugin-prettier": "^3.1.1", - "eslint-plugin-react": "^7.16.0", + "eslint-plugin-react": "^7.17.0", "fs-extra": "^8.1.0", - "husky": "^3.0.9", + "husky": "^3.1.0", "jest": "^24.9.0", "jest-snapshot-serializer-ansi": "^1.0.0", "jsonlint": "^1.6.3", - "nanoid": "^2.1.6", + "nanoid": "^2.1.7", "prettier": "^1.19.1" }, "config": { diff --git a/yarn.lock b/yarn.lock index 694265057..f892eb965 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,7 +9,7 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@^7.1.0", "@babel/core@^7.7.2": +"@babel/core@^7.1.0": version "7.7.2" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.2.tgz#ea5b99693bcfc058116f42fa1dd54da412b29d91" integrity sha512-eeD7VEZKfhK1KUXGiyPFettgF3m513f8FoBSWiQ1xTvl1RAopLs42Wp9+Ze911I6H0N9lNqJMDgoZT7gHsipeQ== @@ -29,6 +29,26 @@ semver "^5.4.1" source-map "^0.5.0" +"@babel/core@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.4.tgz#37e864532200cb6b50ee9a4045f5f817840166ab" + integrity sha512-+bYbx56j4nYBmpsWtnPUsKW3NdnYxbqyfrP2w9wILBuHzdfIKz9prieZK0DFPyIzkjYVUe4QkusGL07r5pXznQ== + dependencies: + "@babel/code-frame" "^7.5.5" + "@babel/generator" "^7.7.4" + "@babel/helpers" "^7.7.4" + "@babel/parser" "^7.7.4" + "@babel/template" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" + convert-source-map "^1.7.0" + debug "^4.1.0" + json5 "^2.1.0" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + "@babel/generator@^7.4.0", "@babel/generator@^7.7.2": version "7.7.2" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.2.tgz#2f4852d04131a5e17ea4f6645488b5da66ebf3af" @@ -39,54 +59,64 @@ lodash "^4.17.13" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.0.tgz#efc54032d43891fe267679e63f6860aa7dbf4a5e" - integrity sha512-k50CQxMlYTYo+GGyUGFwpxKVtxVJi9yh61sXZji3zYHccK9RYliZGSTOgci85T+r+0VFN2nWbGM04PIqwfrpMg== +"@babel/generator@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.4.tgz#db651e2840ca9aa66f327dcec1dc5f5fa9611369" + integrity sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg== dependencies: - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.4" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.0.tgz#32dd9551d6ed3a5fc2edc50d6912852aa18274d9" - integrity sha512-Cd8r8zs4RKDwMG/92lpZcnn5WPQ3LAMQbCw42oqUh4s7vsSN5ANUZjMel0OOnxDLq57hoDDbai+ryygYfCTOsw== +"@babel/helper-annotate-as-pure@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.4.tgz#bb3faf1e74b74bd547e867e48f551fa6b098b6ce" + integrity sha512-2BQmQgECKzYKFPpiycoF9tlb5HA4lrVyAmLLVK177EcQAqjVLciUb2/R+n1boQ9y5ENV3uz2ZqiNw7QMBBw1Og== dependencies: - "@babel/helper-explode-assignable-expression" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.4" -"@babel/helper-call-delegate@^7.4.4": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.7.0.tgz#df8942452c2c1a217335ca7e393b9afc67f668dc" - integrity sha512-Su0Mdq7uSSWGZayGMMQ+z6lnL00mMCnGAbO/R0ZO9odIdB/WNU/VfQKqMQU0fdIsxQYbRjDM4BixIa93SQIpvw== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.4.tgz#5f73f2b28580e224b5b9bd03146a4015d6217f5f" + integrity sha512-Biq/d/WtvfftWZ9Uf39hbPBYDUo986m5Bb4zhkeYDGUllF43D+nUe5M6Vuo6/8JDK/0YX/uBdeoQpyaNhNugZQ== dependencies: - "@babel/helper-hoist-variables" "^7.7.0" - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/helper-explode-assignable-expression" "^7.7.4" + "@babel/types" "^7.7.4" -"@babel/helper-create-regexp-features-plugin@^7.7.0": - version "7.7.2" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.2.tgz#6f20443778c8fce2af2ff4206284afc0ced65db6" - integrity sha512-pAil/ZixjTlrzNpjx+l/C/wJk002Wo7XbbZ8oujH/AoJ3Juv0iN/UTcPUHXKMFLqsfS0Hy6Aow8M31brUYBlQQ== +"@babel/helper-call-delegate@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.7.4.tgz#621b83e596722b50c0066f9dc37d3232e461b801" + integrity sha512-8JH9/B7J7tCYJ2PpWVpw9JhPuEVHztagNVuQAFBVFYluRMlpG7F1CgKEgGeL6KFqcsIa92ZYVj6DSc0XwmN1ZA== + dependencies: + "@babel/helper-hoist-variables" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" + +"@babel/helper-create-regexp-features-plugin@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.4.tgz#6d5762359fd34f4da1500e4cff9955b5299aaf59" + integrity sha512-Mt+jBKaxL0zfOIWrfQpnfYCN7/rS6GKx6CCCfuoqVVd+17R8zNDlzVYmIi9qyb2wOk002NsmSTDymkIygDUH7A== dependencies: "@babel/helper-regex" "^7.4.4" regexpu-core "^4.6.0" -"@babel/helper-define-map@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.7.0.tgz#60b0e9fd60def9de5054c38afde8c8ee409c7529" - integrity sha512-kPKWPb0dMpZi+ov1hJiwse9dWweZsz3V9rP4KdytnX1E7z3cTNmFGglwklzFPuqIcHLIY3bgKSs4vkwXXdflQA== +"@babel/helper-define-map@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.7.4.tgz#2841bf92eb8bd9c906851546fe6b9d45e162f176" + integrity sha512-v5LorqOa0nVQUvAUTUF3KPastvUt/HzByXNamKQ6RdJRTV7j8rLL+WB5C/MzzWAwOomxDhYFb1wLLxHqox86lg== dependencies: - "@babel/helper-function-name" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/helper-function-name" "^7.7.4" + "@babel/types" "^7.7.4" lodash "^4.17.13" -"@babel/helper-explode-assignable-expression@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.0.tgz#db2a6705555ae1f9f33b4b8212a546bc7f9dc3ef" - integrity sha512-CDs26w2shdD1urNUAji2RJXyBFCaR+iBEGnFz3l7maizMkQe3saVw9WtjG1tz8CwbjvlFnaSLVhgnu1SWaherg== +"@babel/helper-explode-assignable-expression@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.4.tgz#fa700878e008d85dc51ba43e9fb835cddfe05c84" + integrity sha512-2/SicuFrNSXsZNBxe5UGdLr+HZg+raWBLE9vC98bdYOKX/U6PY0mdGlYUJdtTDPSU0Lw0PNbKKDpwYHJLn2jLg== dependencies: - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" "@babel/helper-function-name@^7.7.0": version "7.7.0" @@ -97,52 +127,68 @@ "@babel/template" "^7.7.0" "@babel/types" "^7.7.0" -"@babel/helper-get-function-arity@^7.0.0", "@babel/helper-get-function-arity@^7.7.0": +"@babel/helper-function-name@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz#ab6e041e7135d436d8f0a3eca15de5b67a341a2e" + integrity sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ== + dependencies: + "@babel/helper-get-function-arity" "^7.7.4" + "@babel/template" "^7.7.4" + "@babel/types" "^7.7.4" + +"@babel/helper-get-function-arity@^7.7.0": version "7.7.0" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz#c604886bc97287a1d1398092bc666bc3d7d7aa2d" integrity sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw== dependencies: "@babel/types" "^7.7.0" -"@babel/helper-hoist-variables@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.0.tgz#b4552e4cfe5577d7de7b183e193e84e4ec538c81" - integrity sha512-LUe/92NqsDAkJjjCEWkNe+/PcpnisvnqdlRe19FahVapa4jndeuJ+FBiTX1rcAKWKcJGE+C3Q3tuEuxkSmCEiQ== +"@babel/helper-get-function-arity@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz#cb46348d2f8808e632f0ab048172130e636005f0" + integrity sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA== dependencies: - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.4" -"@babel/helper-member-expression-to-functions@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.0.tgz#472b93003a57071f95a541ea6c2b098398bcad8a" - integrity sha512-QaCZLO2RtBcmvO/ekOLp8p7R5X2JriKRizeDpm5ChATAFWrrYDcDxPuCIBXKyBjY+i1vYSdcUTMIb8psfxHDPA== +"@babel/helper-hoist-variables@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.4.tgz#612384e3d823fdfaaf9fce31550fe5d4db0f3d12" + integrity sha512-wQC4xyvc1Jo/FnLirL6CEgPgPCa8M74tOdjWpRhQYapz5JC7u3NYU1zCVoVAGCE3EaIP9T1A3iW0WLJ+reZlpQ== dependencies: - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.4" -"@babel/helper-module-imports@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.7.0.tgz#99c095889466e5f7b6d66d98dffc58baaf42654d" - integrity sha512-Dv3hLKIC1jyfTkClvyEkYP2OlkzNvWs5+Q8WgPbxM5LMeorons7iPP91JM+DU7tRbhqA1ZeooPaMFvQrn23RHw== +"@babel/helper-member-expression-to-functions@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.4.tgz#356438e2569df7321a8326644d4b790d2122cb74" + integrity sha512-9KcA1X2E3OjXl/ykfMMInBK+uVdfIVakVe7W7Lg3wfXUNyS3Q1HWLFRwZIjhqiCGbslummPDnmb7vIekS0C1vw== dependencies: - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.4" -"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.7.0.tgz#154a69f0c5b8fd4d39e49750ff7ac4faa3f36786" - integrity sha512-rXEefBuheUYQyX4WjV19tuknrJFwyKw0HgzRwbkyTbB+Dshlq7eqkWbyjzToLrMZk/5wKVKdWFluiAsVkHXvuQ== +"@babel/helper-module-imports@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.7.4.tgz#e5a92529f8888bf319a6376abfbd1cebc491ad91" + integrity sha512-dGcrX6K9l8258WFjyDLJwuVKxR4XZfU0/vTUgOQYWEnRD8mgr+p4d6fCUMq/ys0h4CCt/S5JhbvtyErjWouAUQ== dependencies: - "@babel/helper-module-imports" "^7.7.0" - "@babel/helper-simple-access" "^7.7.0" - "@babel/helper-split-export-declaration" "^7.7.0" - "@babel/template" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.4" + +"@babel/helper-module-transforms@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.7.4.tgz#8d7cdb1e1f8ea3d8c38b067345924ac4f8e0879a" + integrity sha512-ehGBu4mXrhs0FxAqN8tWkzF8GSIGAiEumu4ONZ/hD9M88uHcD+Yu2ttKfOCgwzoesJOJrtQh7trI5YPbRtMmnA== + dependencies: + "@babel/helper-module-imports" "^7.7.4" + "@babel/helper-simple-access" "^7.7.4" + "@babel/helper-split-export-declaration" "^7.7.4" + "@babel/template" "^7.7.4" + "@babel/types" "^7.7.4" lodash "^4.17.13" -"@babel/helper-optimise-call-expression@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.0.tgz#4f66a216116a66164135dc618c5d8b7a959f9365" - integrity sha512-48TeqmbazjNU/65niiiJIJRc5JozB8acui1OS7bSd6PgxfuovWsvjfWSzlgx+gPFdVveNzUdpdIg5l56Pl5jqg== +"@babel/helper-optimise-call-expression@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.4.tgz#034af31370d2995242aa4df402c3b7794b2dcdf2" + integrity sha512-VB7gWZ2fDkSuqW6b1AKXkJWO5NyNI3bFL/kK79/30moK57blr6NbH8xcl2XcKCwOmJosftWunZqfO84IGq3ZZg== dependencies: - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.4" "@babel/helper-plugin-utils@^7.0.0": version "7.0.0" @@ -156,34 +202,34 @@ dependencies: lodash "^4.17.13" -"@babel/helper-remap-async-to-generator@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.0.tgz#4d69ec653e8bff5bce62f5d33fc1508f223c75a7" - integrity sha512-pHx7RN8X0UNHPB/fnuDnRXVZ316ZigkO8y8D835JlZ2SSdFKb6yH9MIYRU4fy/KPe5sPHDFOPvf8QLdbAGGiyw== +"@babel/helper-remap-async-to-generator@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.4.tgz#c68c2407350d9af0e061ed6726afb4fff16d0234" + integrity sha512-Sk4xmtVdM9sA/jCI80f+KS+Md+ZHIpjuqmYPk1M7F/upHou5e4ReYmExAiu6PVe65BhJPZA2CY9x9k4BqE5klw== dependencies: - "@babel/helper-annotate-as-pure" "^7.7.0" - "@babel/helper-wrap-function" "^7.7.0" - "@babel/template" "^7.7.0" - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/helper-annotate-as-pure" "^7.7.4" + "@babel/helper-wrap-function" "^7.7.4" + "@babel/template" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" -"@babel/helper-replace-supers@^7.5.5", "@babel/helper-replace-supers@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.7.0.tgz#d5365c8667fe7cbd13b8ddddceb9bd7f2b387512" - integrity sha512-5ALYEul5V8xNdxEeWvRsBzLMxQksT7MaStpxjJf9KsnLxpAKBtfw5NeMKZJSYDa0lKdOcy0g+JT/f5mPSulUgg== +"@babel/helper-replace-supers@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.7.4.tgz#3c881a6a6a7571275a72d82e6107126ec9e2cdd2" + integrity sha512-pP0tfgg9hsZWo5ZboYGuBn/bbYT/hdLPVSS4NMmiRJdwWhP0IznPwN9AE1JwyGsjSPLC364I0Qh5p+EPkGPNpg== dependencies: - "@babel/helper-member-expression-to-functions" "^7.7.0" - "@babel/helper-optimise-call-expression" "^7.7.0" - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/helper-member-expression-to-functions" "^7.7.4" + "@babel/helper-optimise-call-expression" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" -"@babel/helper-simple-access@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.7.0.tgz#97a8b6c52105d76031b86237dc1852b44837243d" - integrity sha512-AJ7IZD7Eem3zZRuj5JtzFAptBw7pMlS3y8Qv09vaBWoFsle0d1kAn5Wq6Q9MyBXITPOKnxwkZKoAm4bopmv26g== +"@babel/helper-simple-access@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.7.4.tgz#a169a0adb1b5f418cfc19f22586b2ebf58a9a294" + integrity sha512-zK7THeEXfan7UlWsG2A6CI/L9jVnI5+xxKZOdej39Y0YtDYKx9raHk5F2EtK9K8DHRTihYwg20ADt9S36GR78A== dependencies: - "@babel/template" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/template" "^7.7.4" + "@babel/types" "^7.7.4" "@babel/helper-split-export-declaration@^7.7.0": version "7.7.0" @@ -192,15 +238,22 @@ dependencies: "@babel/types" "^7.7.0" -"@babel/helper-wrap-function@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.7.0.tgz#15af3d3e98f8417a60554acbb6c14e75e0b33b74" - integrity sha512-sd4QjeMgQqzshSjecZjOp8uKfUtnpmCyQhKQrVJBBgeHAB/0FPi33h3AbVlVp07qQtMD4QgYSzaMI7VwncNK/w== +"@babel/helper-split-export-declaration@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz#57292af60443c4a3622cf74040ddc28e68336fd8" + integrity sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug== dependencies: - "@babel/helper-function-name" "^7.7.0" - "@babel/template" "^7.7.0" - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.4" + +"@babel/helper-wrap-function@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.7.4.tgz#37ab7fed5150e22d9d7266e830072c0cdd8baace" + integrity sha512-VsfzZt6wmsocOaVU0OokwrIytHND55yvyT4BPB9AIIgwr8+x7617hetdJTsuGwygN5RC6mxA9EJztTjuwm2ofg== + dependencies: + "@babel/helper-function-name" "^7.7.4" + "@babel/template" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" "@babel/helpers@^7.7.0": version "7.7.0" @@ -211,6 +264,15 @@ "@babel/traverse" "^7.7.0" "@babel/types" "^7.7.0" +"@babel/helpers@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.7.4.tgz#62c215b9e6c712dadc15a9a0dcab76c92a940302" + integrity sha512-ak5NGZGJ6LV85Q1Zc9gn2n+ayXOizryhjSUBTdu5ih1tlVCJeuQENzc4ItyCVhINVXvIT/ZQ4mheGIsfBkpskg== + dependencies: + "@babel/template" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" + "@babel/highlight@^7.0.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" @@ -225,392 +287,404 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.3.tgz#5fad457c2529de476a248f75b0f090b3060af043" integrity sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A== -"@babel/plugin-proposal-async-generator-functions@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.0.tgz#83ef2d6044496b4c15d8b4904e2219e6dccc6971" - integrity sha512-ot/EZVvf3mXtZq0Pd0+tSOfGWMizqmOohXmNZg6LNFjHOV+wOPv7BvVYh8oPR8LhpIP3ye8nNooKL50YRWxpYA== +"@babel/parser@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.4.tgz#75ab2d7110c2cf2fa949959afb05fa346d2231bb" + integrity sha512-jIwvLO0zCL+O/LmEJQjWA75MQTWwx3c3u2JOTDK5D3/9egrWRRA0/0hk9XXywYnXZVVpzrBYeIQTmhwUaePI9g== + +"@babel/plugin-proposal-async-generator-functions@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.4.tgz#0351c5ac0a9e927845fffd5b82af476947b7ce6d" + integrity sha512-1ypyZvGRXriY/QP668+s8sFr2mqinhkRDMPSQLNghCQE+GAkFtp+wkHVvg2+Hdki8gwP+NFzJBJ/N1BfzCCDEw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.7.0" - "@babel/plugin-syntax-async-generators" "^7.2.0" + "@babel/helper-remap-async-to-generator" "^7.7.4" + "@babel/plugin-syntax-async-generators" "^7.7.4" -"@babel/plugin-proposal-dynamic-import@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.7.0.tgz#dc02a8bad8d653fb59daf085516fa416edd2aa7f" - integrity sha512-7poL3Xi+QFPC7sGAzEIbXUyYzGJwbc2+gSD0AkiC5k52kH2cqHdqxm5hNFfLW3cRSTcx9bN0Fl7/6zWcLLnKAQ== +"@babel/plugin-proposal-dynamic-import@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.7.4.tgz#dde64a7f127691758cbfed6cf70de0fa5879d52d" + integrity sha512-StH+nGAdO6qDB1l8sZ5UBV8AC3F2VW2I8Vfld73TMKyptMU9DY5YsJAS8U81+vEtxcH3Y/La0wG0btDrhpnhjQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.2.0" + "@babel/plugin-syntax-dynamic-import" "^7.7.4" -"@babel/plugin-proposal-json-strings@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" - integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg== +"@babel/plugin-proposal-json-strings@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.7.4.tgz#7700a6bfda771d8dc81973249eac416c6b4c697d" + integrity sha512-wQvt3akcBTfLU/wYoqm/ws7YOAQKu8EVJEvHip/mzkNtjaclQoCCIqKXFP5/eyfnfbQCDV3OLRIK3mIVyXuZlw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-json-strings" "^7.2.0" + "@babel/plugin-syntax-json-strings" "^7.7.4" -"@babel/plugin-proposal-object-rest-spread@^7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz#8ffccc8f3a6545e9f78988b6bf4fe881b88e8096" - integrity sha512-LDBXlmADCsMZV1Y9OQwMc0MyGZ8Ta/zlD9N67BfQT8uYwkRswiu2hU6nJKrjrt/58aH/vqfQlR/9yId/7A2gWw== +"@babel/plugin-proposal-object-rest-spread@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.4.tgz#cc57849894a5c774214178c8ab64f6334ec8af71" + integrity sha512-rnpnZR3/iWKmiQyJ3LKJpSwLDcX/nSXhdLk4Aq/tXOApIvyu7qoabrige0ylsAJffaUC51WiBu209Q0U+86OWQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + "@babel/plugin-syntax-object-rest-spread" "^7.7.4" -"@babel/plugin-proposal-optional-catch-binding@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" - integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== +"@babel/plugin-proposal-optional-catch-binding@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.7.4.tgz#ec21e8aeb09ec6711bc0a39ca49520abee1de379" + integrity sha512-DyM7U2bnsQerCQ+sejcTNZh8KQEUuC3ufzdnVnSiUv/qoGJp2Z3hanKL18KDhsBT5Wj6a7CMT5mdyCNJsEaA9w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.7.4" -"@babel/plugin-proposal-unicode-property-regex@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.0.tgz#549fe1717a1bd0a2a7e63163841cb37e78179d5d" - integrity sha512-mk34H+hp7kRBWJOOAR0ZMGCydgKMD4iN9TpDRp3IIcbunltxEY89XSimc6WbtSLCDrwcdy/EEw7h5CFCzxTchw== +"@babel/plugin-proposal-unicode-property-regex@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.4.tgz#7c239ccaf09470dbe1d453d50057460e84517ebb" + integrity sha512-cHgqHgYvffluZk85dJ02vloErm3Y6xtH+2noOBOJ2kXOJH3aVCDnj5eR/lVNlTnYu4hndAPJD3rTFjW3qee0PA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.0" + "@babel/helper-create-regexp-features-plugin" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-async-generators@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" - integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== +"@babel/plugin-syntax-async-generators@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.7.4.tgz#331aaf310a10c80c44a66b238b6e49132bd3c889" + integrity sha512-Li4+EjSpBgxcsmeEF8IFcfV/+yJGxHXDirDkEoyFjumuwbmfCVHUt0HuowD/iGM7OhIRyXJH9YXxqiH6N815+g== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-dynamic-import@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz#69c159ffaf4998122161ad8ebc5e6d1f55df8612" - integrity sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w== +"@babel/plugin-syntax-dynamic-import@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.7.4.tgz#29ca3b4415abfe4a5ec381e903862ad1a54c3aec" + integrity sha512-jHQW0vbRGvwQNgyVxwDh4yuXu4bH1f5/EICJLAhl1SblLs2CDhrsmCk+v5XLdE9wxtAFRyxx+P//Iw+a5L/tTg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-json-strings@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470" - integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg== +"@babel/plugin-syntax-json-strings@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.7.4.tgz#86e63f7d2e22f9e27129ac4e83ea989a382e86cc" + integrity sha512-QpGupahTQW1mHRXddMG5srgpHWqRLwJnJZKXTigB9RPFCCGbDGCgBeM/iC82ICXp414WeYx/tD54w7M2qRqTMg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.2.0": +"@babel/plugin-syntax-object-rest-spread@^7.0.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-optional-catch-binding@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" - integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== +"@babel/plugin-syntax-object-rest-spread@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.7.4.tgz#47cf220d19d6d0d7b154304701f468fc1cc6ff46" + integrity sha512-mObR+r+KZq0XhRVS2BrBKBpr5jqrqzlPvS9C9vuOf5ilSwzloAl7RPWLrgKdWS6IreaVrjHxTjtyqFiOisaCwg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-top-level-await@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.7.0.tgz#f5699549f50bbe8d12b1843a4e82f0a37bb65f4d" - integrity sha512-hi8FUNiFIY1fnUI2n1ViB1DR0R4QeK4iHcTlW6aJkrPoTdb8Rf1EMQ6GT3f67DDkYyWgew9DFoOZ6gOoEsdzTA== +"@babel/plugin-syntax-optional-catch-binding@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.7.4.tgz#a3e38f59f4b6233867b4a92dcb0ee05b2c334aa6" + integrity sha512-4ZSuzWgFxqHRE31Glu+fEr/MirNZOMYmD/0BhBWyLyOOQz/gTAl7QmWm2hX1QxEIXsr2vkdlwxIzTyiYRC4xcQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-arrow-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" - integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== +"@babel/plugin-syntax-top-level-await@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.7.4.tgz#bd7d8fa7b9fee793a36e4027fd6dd1aa32f946da" + integrity sha512-wdsOw0MvkL1UIgiQ/IFr3ETcfv1xb8RMM0H9wbiDyLaJFyiDg5oZvDLCXosIXmFeIlweML5iOBXAkqddkYNizg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-async-to-generator@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.0.tgz#e2b84f11952cf5913fe3438b7d2585042772f492" - integrity sha512-vLI2EFLVvRBL3d8roAMqtVY0Bm9C1QzLkdS57hiKrjUBSqsQYrBsMCeOg/0KK7B0eK9V71J5mWcha9yyoI2tZw== +"@babel/plugin-transform-arrow-functions@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.7.4.tgz#76309bd578addd8aee3b379d809c802305a98a12" + integrity sha512-zUXy3e8jBNPiffmqkHRNDdZM2r8DWhCB7HhcoyZjiK1TxYEluLHAvQuYnTT+ARqRpabWqy/NHkO6e3MsYB5YfA== dependencies: - "@babel/helper-module-imports" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.7.0" -"@babel/plugin-transform-block-scoped-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" - integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== +"@babel/plugin-transform-async-to-generator@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.4.tgz#694cbeae6d613a34ef0292713fa42fb45c4470ba" + integrity sha512-zpUTZphp5nHokuy8yLlyafxCJ0rSlFoSHypTUWgpdwoDXWQcseaect7cJ8Ppk6nunOM6+5rPMkod4OYKPR5MUg== + dependencies: + "@babel/helper-module-imports" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.7.4" + +"@babel/plugin-transform-block-scoped-functions@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.7.4.tgz#d0d9d5c269c78eaea76227ace214b8d01e4d837b" + integrity sha512-kqtQzwtKcpPclHYjLK//3lH8OFsCDuDJBaFhVwf8kqdnF6MN4l618UDlcA7TfRs3FayrHj+svYnSX8MC9zmUyQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-block-scoping@^7.6.3": - version "7.6.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.3.tgz#6e854e51fbbaa84351b15d4ddafe342f3a5d542a" - integrity sha512-7hvrg75dubcO3ZI2rjYTzUrEuh1E9IyDEhhB6qfcooxhDA33xx2MasuLVgdxzcP6R/lipAC6n9ub9maNW6RKdw== +"@babel/plugin-transform-block-scoping@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.7.4.tgz#200aad0dcd6bb80372f94d9e628ea062c58bf224" + integrity sha512-2VBe9u0G+fDt9B5OV5DQH4KBf5DoiNkwFKOz0TCvBWvdAN2rOykCTkrL+jTLxfCAm76l9Qo5OqL7HBOx2dWggg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.13" -"@babel/plugin-transform-classes@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.0.tgz#b411ecc1b8822d24b81e5d184f24149136eddd4a" - integrity sha512-/b3cKIZwGeUesZheU9jNYcwrEA7f/Bo4IdPmvp7oHgvks2majB5BoT5byAql44fiNQYOPzhk2w8DbgfuafkMoA== +"@babel/plugin-transform-classes@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.4.tgz#c92c14be0a1399e15df72667067a8f510c9400ec" + integrity sha512-sK1mjWat7K+buWRuImEzjNf68qrKcrddtpQo3swi9j7dUcG6y6R6+Di039QN2bD1dykeswlagupEmpOatFHHUg== dependencies: - "@babel/helper-annotate-as-pure" "^7.7.0" - "@babel/helper-define-map" "^7.7.0" - "@babel/helper-function-name" "^7.7.0" - "@babel/helper-optimise-call-expression" "^7.7.0" + "@babel/helper-annotate-as-pure" "^7.7.4" + "@babel/helper-define-map" "^7.7.4" + "@babel/helper-function-name" "^7.7.4" + "@babel/helper-optimise-call-expression" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.7.0" - "@babel/helper-split-export-declaration" "^7.7.0" + "@babel/helper-replace-supers" "^7.7.4" + "@babel/helper-split-export-declaration" "^7.7.4" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" - integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== +"@babel/plugin-transform-computed-properties@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.7.4.tgz#e856c1628d3238ffe12d668eb42559f79a81910d" + integrity sha512-bSNsOsZnlpLLyQew35rl4Fma3yKWqK3ImWMSC/Nc+6nGjC9s5NFWAer1YQ899/6s9HxO2zQC1WoFNfkOqRkqRQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-destructuring@^7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz#44bbe08b57f4480094d57d9ffbcd96d309075ba6" - integrity sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ== +"@babel/plugin-transform-destructuring@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.7.4.tgz#2b713729e5054a1135097b6a67da1b6fe8789267" + integrity sha512-4jFMXI1Cu2aXbcXXl8Lr6YubCn6Oc7k9lLsu8v61TZh+1jny2BWmdtvY9zSUlLdGUvcy9DMAWyZEOqjsbeg/wA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-dotall-regex@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.0.tgz#c5c9ecacab3a5e0c11db6981610f0c32fd698b3b" - integrity sha512-3QQlF7hSBnSuM1hQ0pS3pmAbWLax/uGNCbPBND9y+oJ4Y776jsyujG2k0Sn2Aj2a0QwVOiOFL5QVPA7spjvzSA== +"@babel/plugin-transform-dotall-regex@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.4.tgz#f7ccda61118c5b7a2599a72d5e3210884a021e96" + integrity sha512-mk0cH1zyMa/XHeb6LOTXTbG7uIJ8Rrjlzu91pUx/KS3JpcgaTDwMS8kM+ar8SLOvlL2Lofi4CGBAjCo3a2x+lw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.0" + "@babel/helper-create-regexp-features-plugin" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-duplicate-keys@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz#c5dbf5106bf84cdf691222c0974c12b1df931853" - integrity sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ== +"@babel/plugin-transform-duplicate-keys@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.7.4.tgz#3d21731a42e3f598a73835299dd0169c3b90ac91" + integrity sha512-g1y4/G6xGWMD85Tlft5XedGaZBCIVN+/P0bs6eabmcPP9egFleMAo65OOjlhcz1njpwagyY3t0nsQC9oTFegJA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-exponentiation-operator@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" - integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== +"@babel/plugin-transform-exponentiation-operator@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.7.4.tgz#dd30c0191e3a1ba19bcc7e389bdfddc0729d5db9" + integrity sha512-MCqiLfCKm6KEA1dglf6Uqq1ElDIZwFuzz1WH5mTf8k2uQSxEJMbOIEh7IZv7uichr7PMfi5YVSrr1vz+ipp7AQ== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-for-of@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz#0267fc735e24c808ba173866c6c4d1440fc3c556" - integrity sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ== +"@babel/plugin-transform-for-of@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.7.4.tgz#248800e3a5e507b1f103d8b4ca998e77c63932bc" + integrity sha512-zZ1fD1B8keYtEcKF+M1TROfeHTKnijcVQm0yO/Yu1f7qoDoxEIc/+GX6Go430Bg84eM/xwPFp0+h4EbZg7epAA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-function-name@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.0.tgz#0fa786f1eef52e3b7d4fc02e54b2129de8a04c2a" - integrity sha512-P5HKu0d9+CzZxP5jcrWdpe7ZlFDe24bmqP6a6X8BHEBl/eizAsY8K6LX8LASZL0Jxdjm5eEfzp+FIrxCm/p8bA== +"@babel/plugin-transform-function-name@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.4.tgz#75a6d3303d50db638ff8b5385d12451c865025b1" + integrity sha512-E/x09TvjHNhsULs2IusN+aJNRV5zKwxu1cpirZyRPw+FyyIKEHPXTsadj48bVpc1R5Qq1B5ZkzumuFLytnbT6g== dependencies: - "@babel/helper-function-name" "^7.7.0" + "@babel/helper-function-name" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" - integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== +"@babel/plugin-transform-literals@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.7.4.tgz#27fe87d2b5017a2a5a34d1c41a6b9f6a6262643e" + integrity sha512-X2MSV7LfJFm4aZfxd0yLVFrEXAgPqYoDG53Br/tCKiKYfX0MjVjQeWPIhPHHsCqzwQANq+FLN786fF5rgLS+gw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-member-expression-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz#fa10aa5c58a2cb6afcf2c9ffa8cb4d8b3d489a2d" - integrity sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA== +"@babel/plugin-transform-member-expression-literals@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.7.4.tgz#aee127f2f3339fc34ce5e3055d7ffbf7aa26f19a" + integrity sha512-9VMwMO7i69LHTesL0RdGy93JU6a+qOPuvB4F4d0kR0zyVjJRVJRaoaGjhtki6SzQUu8yen/vxPKN6CWnCUw6bA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-amd@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz#ef00435d46da0a5961aa728a1d2ecff063e4fb91" - integrity sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg== +"@babel/plugin-transform-modules-amd@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.4.tgz#276b3845ca2b228f2995e453adc2e6f54d72fb71" + integrity sha512-/542/5LNA18YDtg1F+QHvvUSlxdvjZoD/aldQwkq+E3WCkbEjNSN9zdrOXaSlfg3IfGi22ijzecklF/A7kVZFQ== dependencies: - "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-module-transforms" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" babel-plugin-dynamic-import-node "^2.3.0" -"@babel/plugin-transform-modules-commonjs@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.0.tgz#3e5ffb4fd8c947feede69cbe24c9554ab4113fe3" - integrity sha512-KEMyWNNWnjOom8vR/1+d+Ocz/mILZG/eyHHO06OuBQ2aNhxT62fr4y6fGOplRx+CxCSp3IFwesL8WdINfY/3kg== +"@babel/plugin-transform-modules-commonjs@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.4.tgz#bee4386e550446343dd52a571eda47851ff857a3" + integrity sha512-k8iVS7Jhc367IcNF53KCwIXtKAH7czev866ThsTgy8CwlXjnKZna2VHwChglzLleYrcHz1eQEIJlGRQxB53nqA== dependencies: - "@babel/helper-module-transforms" "^7.7.0" + "@babel/helper-module-transforms" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-simple-access" "^7.7.0" + "@babel/helper-simple-access" "^7.7.4" babel-plugin-dynamic-import-node "^2.3.0" -"@babel/plugin-transform-modules-systemjs@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.7.0.tgz#9baf471213af9761c1617bb12fd278e629041417" - integrity sha512-ZAuFgYjJzDNv77AjXRqzQGlQl4HdUM6j296ee4fwKVZfhDR9LAGxfvXjBkb06gNETPnN0sLqRm9Gxg4wZH6dXg== +"@babel/plugin-transform-modules-systemjs@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.7.4.tgz#cd98152339d3e763dfe838b7d4273edaf520bb30" + integrity sha512-y2c96hmcsUi6LrMqvmNDPBBiGCiQu0aYqpHatVVu6kD4mFEXKjyNxd/drc18XXAf9dv7UXjrZwBVmTTGaGP8iw== dependencies: - "@babel/helper-hoist-variables" "^7.7.0" + "@babel/helper-hoist-variables" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" babel-plugin-dynamic-import-node "^2.3.0" -"@babel/plugin-transform-modules-umd@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.7.0.tgz#d62c7da16670908e1d8c68ca0b5d4c0097b69966" - integrity sha512-u7eBA03zmUswQ9LQ7Qw0/ieC1pcAkbp5OQatbWUzY1PaBccvuJXUkYzoN1g7cqp7dbTu6Dp9bXyalBvD04AANA== +"@babel/plugin-transform-modules-umd@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.7.4.tgz#1027c355a118de0aae9fee00ad7813c584d9061f" + integrity sha512-u2B8TIi0qZI4j8q4C51ktfO7E3cQ0qnaXFI1/OXITordD40tt17g/sXqgNNCcMTcBFKrUPcGDx+TBJuZxLx7tw== dependencies: - "@babel/helper-module-transforms" "^7.7.0" + "@babel/helper-module-transforms" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-named-capturing-groups-regex@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.7.0.tgz#358e6fd869b9a4d8f5cbc79e4ed4fc340e60dcaf" - integrity sha512-+SicSJoKouPctL+j1pqktRVCgy+xAch1hWWTMy13j0IflnyNjaoskj+DwRQFimHbLqO3sq2oN2CXMvXq3Bgapg== +"@babel/plugin-transform-named-capturing-groups-regex@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.7.4.tgz#fb3bcc4ee4198e7385805007373d6b6f42c98220" + integrity sha512-jBUkiqLKvUWpv9GLSuHUFYdmHg0ujC1JEYoZUfeOOfNydZXp1sXObgyPatpcwjWgsdBGsagWW0cdJpX/DO2jMw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.0" + "@babel/helper-create-regexp-features-plugin" "^7.7.4" -"@babel/plugin-transform-new-target@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz#18d120438b0cc9ee95a47f2c72bc9768fbed60a5" - integrity sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA== +"@babel/plugin-transform-new-target@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.7.4.tgz#4a0753d2d60639437be07b592a9e58ee00720167" + integrity sha512-CnPRiNtOG1vRodnsyGX37bHQleHE14B9dnnlgSeEs3ek3fHN1A1SScglTCg1sfbe7sRQ2BUcpgpTpWSfMKz3gg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-object-super@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz#c70021df834073c65eb613b8679cc4a381d1a9f9" - integrity sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ== +"@babel/plugin-transform-object-super@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.7.4.tgz#48488937a2d586c0148451bf51af9d7dda567262" + integrity sha512-ho+dAEhC2aRnff2JCA0SAK7V2R62zJd/7dmtoe7MHcso4C2mS+vZjn1Pb1pCVZvJs1mgsvv5+7sT+m3Bysb6eg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" + "@babel/helper-replace-supers" "^7.7.4" -"@babel/plugin-transform-parameters@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz#7556cf03f318bd2719fe4c922d2d808be5571e16" - integrity sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw== +"@babel/plugin-transform-parameters@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.4.tgz#da4555c97f39b51ac089d31c7380f03bca4075ce" + integrity sha512-VJwhVePWPa0DqE9vcfptaJSzNDKrWU/4FbYCjZERtmqEs05g3UMXnYMZoXja7JAJ7Y7sPZipwm/pGApZt7wHlw== dependencies: - "@babel/helper-call-delegate" "^7.4.4" - "@babel/helper-get-function-arity" "^7.0.0" + "@babel/helper-call-delegate" "^7.7.4" + "@babel/helper-get-function-arity" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-property-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz#03e33f653f5b25c4eb572c98b9485055b389e905" - integrity sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ== +"@babel/plugin-transform-property-literals@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.7.4.tgz#2388d6505ef89b266103f450f9167e6bd73f98c2" + integrity sha512-MatJhlC4iHsIskWYyawl53KuHrt+kALSADLQQ/HkhTjX954fkxIEh4q5slL4oRAnsm/eDoZ4q0CIZpcqBuxhJQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-regenerator@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.0.tgz#f1b20b535e7716b622c99e989259d7dd942dd9cc" - integrity sha512-AXmvnC+0wuj/cFkkS/HFHIojxH3ffSXE+ttulrqWjZZRaUOonfJc60e1wSNT4rV8tIunvu/R3wCp71/tLAa9xg== +"@babel/plugin-transform-regenerator@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.4.tgz#d18eac0312a70152d7d914cbed2dc3999601cfc0" + integrity sha512-e7MWl5UJvmPEwFJTwkBlPmqixCtr9yAASBqff4ggXTNicZiwbF8Eefzm6NVgfiBp7JdAGItecnctKTgH44q2Jw== dependencies: regenerator-transform "^0.14.0" -"@babel/plugin-transform-reserved-words@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz#4792af87c998a49367597d07fedf02636d2e1634" - integrity sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw== +"@babel/plugin-transform-reserved-words@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.7.4.tgz#6a7cf123ad175bb5c69aec8f6f0770387ed3f1eb" + integrity sha512-OrPiUB5s5XvkCO1lS7D8ZtHcswIC57j62acAnJZKqGGnHP+TIc/ljQSrgdX/QyOTdEK5COAhuc820Hi1q2UgLQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-shorthand-properties@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" - integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== +"@babel/plugin-transform-shorthand-properties@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.7.4.tgz#74a0a9b2f6d67a684c6fbfd5f0458eb7ba99891e" + integrity sha512-q+suddWRfIcnyG5YiDP58sT65AJDZSUhXQDZE3r04AuqD6d/XLaQPPXSBzP2zGerkgBivqtQm9XKGLuHqBID6Q== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-spread@^7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.6.2.tgz#fc77cf798b24b10c46e1b51b1b88c2bf661bb8dd" - integrity sha512-DpSvPFryKdK1x+EDJYCy28nmAaIMdxmhot62jAXF/o99iA33Zj2Lmcp3vDmz+MUh0LNYVPvfj5iC3feb3/+PFg== +"@babel/plugin-transform-spread@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.7.4.tgz#aa673b356fe6b7e70d69b6e33a17fef641008578" + integrity sha512-8OSs0FLe5/80cndziPlg4R0K6HcWSM0zyNhHhLsmw/Nc5MaA49cAsnoJ/t/YZf8qkG7fD+UjTRaApVDB526d7Q== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-sticky-regex@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" - integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== +"@babel/plugin-transform-sticky-regex@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.7.4.tgz#ffb68c05090c30732076b1285dc1401b404a123c" + integrity sha512-Ls2NASyL6qtVe1H1hXts9yuEeONV2TJZmplLONkMPUG158CtmnrzW5Q5teibM5UVOFjG0D3IC5mzXR6pPpUY7A== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" -"@babel/plugin-transform-template-literals@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz#9d28fea7bbce637fb7612a0750989d8321d4bcb0" - integrity sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g== +"@babel/plugin-transform-template-literals@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.7.4.tgz#1eb6411736dd3fe87dbd20cc6668e5121c17d604" + integrity sha512-sA+KxLwF3QwGj5abMHkHgshp9+rRz+oY9uoRil4CyLtgEuE/88dpkeWgNk5qKVsJE9iSfly3nvHapdRiIS2wnQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-annotate-as-pure" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-typeof-symbol@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2" - integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw== +"@babel/plugin-transform-typeof-symbol@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.7.4.tgz#3174626214f2d6de322882e498a38e8371b2140e" + integrity sha512-KQPUQ/7mqe2m0B8VecdyaW5XcQYaePyl9R7IsKd+irzj6jvbhoGnRE+M0aNkyAzI07VfUQ9266L5xMARitV3wg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-unicode-regex@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.0.tgz#743d9bcc44080e3cc7d49259a066efa30f9187a3" - integrity sha512-RrThb0gdrNwFAqEAAx9OWgtx6ICK69x7i9tCnMdVrxQwSDp/Abu9DXFU5Hh16VP33Rmxh04+NGW28NsIkFvFKA== +"@babel/plugin-transform-unicode-regex@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.4.tgz#a3c0f65b117c4c81c5b6484f2a5e7b95346b83ae" + integrity sha512-N77UUIV+WCvE+5yHw+oks3m18/umd7y392Zv7mYTpFqHtkpcc+QUz+gLJNTWVlWROIWeLqY0f3OjZxV5TcXnRw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.0" + "@babel/helper-create-regexp-features-plugin" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/preset-env@^7.7.1": - version "7.7.1" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.7.1.tgz#04a2ff53552c5885cf1083e291c8dd5490f744bb" - integrity sha512-/93SWhi3PxcVTDpSqC+Dp4YxUu3qZ4m7I76k0w73wYfn7bGVuRIO4QUz95aJksbS+AD1/mT1Ie7rbkT0wSplaA== +"@babel/preset-env@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.7.4.tgz#ccaf309ae8d1ee2409c85a4e2b5e280ceee830f8" + integrity sha512-Dg+ciGJjwvC1NIe/DGblMbcGq1HOtKbw8RLl4nIjlfcILKEOkWT/vRqPpumswABEBVudii6dnVwrBtzD7ibm4g== dependencies: - "@babel/helper-module-imports" "^7.7.0" + "@babel/helper-module-imports" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-async-generator-functions" "^7.7.0" - "@babel/plugin-proposal-dynamic-import" "^7.7.0" - "@babel/plugin-proposal-json-strings" "^7.2.0" - "@babel/plugin-proposal-object-rest-spread" "^7.6.2" - "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.7.0" - "@babel/plugin-syntax-async-generators" "^7.2.0" - "@babel/plugin-syntax-dynamic-import" "^7.2.0" - "@babel/plugin-syntax-json-strings" "^7.2.0" - "@babel/plugin-syntax-object-rest-spread" "^7.2.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" - "@babel/plugin-syntax-top-level-await" "^7.7.0" - "@babel/plugin-transform-arrow-functions" "^7.2.0" - "@babel/plugin-transform-async-to-generator" "^7.7.0" - "@babel/plugin-transform-block-scoped-functions" "^7.2.0" - "@babel/plugin-transform-block-scoping" "^7.6.3" - "@babel/plugin-transform-classes" "^7.7.0" - "@babel/plugin-transform-computed-properties" "^7.2.0" - "@babel/plugin-transform-destructuring" "^7.6.0" - "@babel/plugin-transform-dotall-regex" "^7.7.0" - "@babel/plugin-transform-duplicate-keys" "^7.5.0" - "@babel/plugin-transform-exponentiation-operator" "^7.2.0" - "@babel/plugin-transform-for-of" "^7.4.4" - "@babel/plugin-transform-function-name" "^7.7.0" - "@babel/plugin-transform-literals" "^7.2.0" - "@babel/plugin-transform-member-expression-literals" "^7.2.0" - "@babel/plugin-transform-modules-amd" "^7.5.0" - "@babel/plugin-transform-modules-commonjs" "^7.7.0" - "@babel/plugin-transform-modules-systemjs" "^7.7.0" - "@babel/plugin-transform-modules-umd" "^7.7.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.7.0" - "@babel/plugin-transform-new-target" "^7.4.4" - "@babel/plugin-transform-object-super" "^7.5.5" - "@babel/plugin-transform-parameters" "^7.4.4" - "@babel/plugin-transform-property-literals" "^7.2.0" - "@babel/plugin-transform-regenerator" "^7.7.0" - "@babel/plugin-transform-reserved-words" "^7.2.0" - "@babel/plugin-transform-shorthand-properties" "^7.2.0" - "@babel/plugin-transform-spread" "^7.6.2" - "@babel/plugin-transform-sticky-regex" "^7.2.0" - "@babel/plugin-transform-template-literals" "^7.4.4" - "@babel/plugin-transform-typeof-symbol" "^7.2.0" - "@babel/plugin-transform-unicode-regex" "^7.7.0" - "@babel/types" "^7.7.1" + "@babel/plugin-proposal-async-generator-functions" "^7.7.4" + "@babel/plugin-proposal-dynamic-import" "^7.7.4" + "@babel/plugin-proposal-json-strings" "^7.7.4" + "@babel/plugin-proposal-object-rest-spread" "^7.7.4" + "@babel/plugin-proposal-optional-catch-binding" "^7.7.4" + "@babel/plugin-proposal-unicode-property-regex" "^7.7.4" + "@babel/plugin-syntax-async-generators" "^7.7.4" + "@babel/plugin-syntax-dynamic-import" "^7.7.4" + "@babel/plugin-syntax-json-strings" "^7.7.4" + "@babel/plugin-syntax-object-rest-spread" "^7.7.4" + "@babel/plugin-syntax-optional-catch-binding" "^7.7.4" + "@babel/plugin-syntax-top-level-await" "^7.7.4" + "@babel/plugin-transform-arrow-functions" "^7.7.4" + "@babel/plugin-transform-async-to-generator" "^7.7.4" + "@babel/plugin-transform-block-scoped-functions" "^7.7.4" + "@babel/plugin-transform-block-scoping" "^7.7.4" + "@babel/plugin-transform-classes" "^7.7.4" + "@babel/plugin-transform-computed-properties" "^7.7.4" + "@babel/plugin-transform-destructuring" "^7.7.4" + "@babel/plugin-transform-dotall-regex" "^7.7.4" + "@babel/plugin-transform-duplicate-keys" "^7.7.4" + "@babel/plugin-transform-exponentiation-operator" "^7.7.4" + "@babel/plugin-transform-for-of" "^7.7.4" + "@babel/plugin-transform-function-name" "^7.7.4" + "@babel/plugin-transform-literals" "^7.7.4" + "@babel/plugin-transform-member-expression-literals" "^7.7.4" + "@babel/plugin-transform-modules-amd" "^7.7.4" + "@babel/plugin-transform-modules-commonjs" "^7.7.4" + "@babel/plugin-transform-modules-systemjs" "^7.7.4" + "@babel/plugin-transform-modules-umd" "^7.7.4" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.7.4" + "@babel/plugin-transform-new-target" "^7.7.4" + "@babel/plugin-transform-object-super" "^7.7.4" + "@babel/plugin-transform-parameters" "^7.7.4" + "@babel/plugin-transform-property-literals" "^7.7.4" + "@babel/plugin-transform-regenerator" "^7.7.4" + "@babel/plugin-transform-reserved-words" "^7.7.4" + "@babel/plugin-transform-shorthand-properties" "^7.7.4" + "@babel/plugin-transform-spread" "^7.7.4" + "@babel/plugin-transform-sticky-regex" "^7.7.4" + "@babel/plugin-transform-template-literals" "^7.7.4" + "@babel/plugin-transform-typeof-symbol" "^7.7.4" + "@babel/plugin-transform-unicode-regex" "^7.7.4" + "@babel/types" "^7.7.4" browserslist "^4.6.0" core-js-compat "^3.1.1" invariant "^2.2.2" @@ -633,6 +707,15 @@ "@babel/parser" "^7.7.0" "@babel/types" "^7.7.0" +"@babel/template@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.7.4.tgz#428a7d9eecffe27deac0a98e23bf8e3675d2a77b" + integrity sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.7.4" + "@babel/types" "^7.7.4" + "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2": version "7.7.2" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.7.2.tgz#ef0a65e07a2f3c550967366b3d9b62a2dcbeae09" @@ -648,7 +731,22 @@ globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.7.0", "@babel/types@^7.7.1", "@babel/types@^7.7.2": +"@babel/traverse@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.7.4.tgz#9c1e7c60fb679fe4fcfaa42500833333c2058558" + integrity sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw== + dependencies: + "@babel/code-frame" "^7.5.5" + "@babel/generator" "^7.7.4" + "@babel/helper-function-name" "^7.7.4" + "@babel/helper-split-export-declaration" "^7.7.4" + "@babel/parser" "^7.7.4" + "@babel/types" "^7.7.4" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.7.0", "@babel/types@^7.7.2": version "7.7.2" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.2.tgz#550b82e5571dcd174af576e23f0adba7ffc683f7" integrity sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA== @@ -657,6 +755,15 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" +"@babel/types@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.4.tgz#516570d539e44ddf308c07569c258ff94fde9193" + integrity sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA== + dependencies: + esutils "^2.0.2" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + "@cnakazawa/watch@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" @@ -1965,10 +2072,10 @@ eslint-config-okonet@^7.0.2: dependencies: install-peerdeps "^1.2.0" -eslint-config-prettier@^6.5.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.5.0.tgz#aaf9a495e2a816865e541bfdbb73a65cc162b3eb" - integrity sha512-cjXp8SbO9VFGW/Z7mbTydqS9to8Z58E5aYhj3e1+Hx7lS9s6gL5ILKNpCqZAFOVYRcSkWPFYljHrEh8QFEK5EQ== +eslint-config-prettier@^6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.7.0.tgz#9a876952e12df2b284adbd3440994bf1f39dfbb9" + integrity sha512-FamQVKM3jjUVwhG4hEMnbtsq7xOIDm+SY5iBPfR8gKsJoAB2IQnNF+bk1+8Fy44Nq7PPJaLvkRxILYdJWoguKQ== dependencies: get-stdin "^6.0.0" @@ -1996,10 +2103,15 @@ eslint-plugin-es@^2.0.0: eslint-utils "^1.4.2" regexpp "^3.0.0" -eslint-plugin-flowtype@^4.4.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-4.4.1.tgz#b388f42bdc1237f68a8010d2ede52cd67a057e40" - integrity sha512-TNkrdJbvmBEIf02tjMKrYmLILV7OVwcvDUAnrnoGQZJhBMsu61X7E7/A1yvLTsFeDaqhbBx7rgsHzh4Yx7IqvA== +eslint-plugin-eslint-plugin@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-plugin/-/eslint-plugin-eslint-plugin-2.1.0.tgz#a7a00f15a886957d855feacaafee264f039e62d5" + integrity sha512-kT3A/ZJftt28gbl/Cv04qezb/NQ1dwYIbi8lyf806XMxkus7DvOVCLIfTXMrorp322Pnoez7+zabXH29tADIDg== + +eslint-plugin-flowtype@^4.5.2: + version "4.5.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-4.5.2.tgz#5353449692663ef70e8fc8c2386cebdecac7e86b" + integrity sha512-ByV0EtEQOqiCl6bsrtXtTGnXlIXoyvDrvUq3Nz28huODAhnRDuMotyTrwP+TjAKZMPWbtaNGFHMoUxW3DktGOw== dependencies: lodash "^4.17.15" @@ -2054,20 +2166,21 @@ eslint-plugin-prettier@^3.1.1: dependencies: prettier-linter-helpers "^1.0.0" -eslint-plugin-react@^7.16.0: - version "7.16.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.16.0.tgz#9928e4f3e2122ed3ba6a5b56d0303ba3e41d8c09" - integrity sha512-GacBAATewhhptbK3/vTP09CbFrgUJmBSaaRcWdbQLFvUZy9yVcQxigBNHGPU/KE2AyHpzj3AWXpxoMTsIDiHug== +eslint-plugin-react@^7.17.0: + version "7.17.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.17.0.tgz#a31b3e134b76046abe3cd278e7482bd35a1d12d7" + integrity sha512-ODB7yg6lxhBVMeiH1c7E95FLD4E/TwmFjltiU+ethv7KPdCwgiFuOZg9zNRHyufStTDLl/dEFqI2Q1VPmCd78A== dependencies: array-includes "^3.0.3" doctrine "^2.1.0" + eslint-plugin-eslint-plugin "^2.1.0" has "^1.0.3" - jsx-ast-utils "^2.2.1" + jsx-ast-utils "^2.2.3" object.entries "^1.1.0" - object.fromentries "^2.0.0" + object.fromentries "^2.0.1" object.values "^1.1.0" prop-types "^15.7.2" - resolve "^1.12.0" + resolve "^1.13.1" eslint-scope@^5.0.0: version "5.0.0" @@ -2089,10 +2202,10 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== -eslint@^6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.6.0.tgz#4a01a2fb48d32aacef5530ee9c5a78f11a8afd04" - integrity sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g== +eslint@^6.7.2: + version "6.7.2" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.7.2.tgz#c17707ca4ad7b2d8af986a33feba71e18a9fecd1" + integrity sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -2109,7 +2222,7 @@ eslint@^6.6.0: file-entry-cache "^5.0.1" functional-red-black-tree "^1.0.1" glob-parent "^5.0.0" - globals "^11.7.0" + globals "^12.1.0" ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" @@ -2122,7 +2235,7 @@ eslint@^6.6.0: minimatch "^3.0.4" mkdirp "^0.5.1" natural-compare "^1.4.0" - optionator "^0.8.2" + optionator "^0.8.3" progress "^2.0.0" regexpp "^2.0.1" semver "^6.1.2" @@ -2201,10 +2314,10 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-3.3.0.tgz#7e348eef129a1937f21ecbbd53390942653522c1" - integrity sha512-j5Vit5WZR/cbHlqU97+qcnw9WHRCIL4V1SVe75VcHcD1JRBdt8fv0zw89b7CQHQdUHTt2VjuhcF5ibAgVOxqpg== +execa@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" + integrity sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g== dependencies: cross-spawn "^7.0.0" get-stream "^5.0.0" @@ -2560,11 +2673,18 @@ glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -globals@^11.1.0, globals@^11.7.0: +globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +globals@^12.1.0: + version "12.3.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-12.3.0.tgz#1e564ee5c4dded2ab098b0f88f24702a3c56be13" + integrity sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw== + dependencies: + type-fest "^0.8.1" + graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" @@ -2710,10 +2830,10 @@ human-signals@^1.1.1: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== -husky@^3.0.9: - version "3.0.9" - resolved "https://registry.yarnpkg.com/husky/-/husky-3.0.9.tgz#a2c3e9829bfd6b4957509a9500d2eef5dbfc8044" - integrity sha512-Yolhupm7le2/MqC1VYLk/cNmYxsSsqKkTyBhzQHhPK1jFnC89mmmNVuGtLNabjDI6Aj8UNIr0KpRNuBkiC4+sg== +husky@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/husky/-/husky-3.1.0.tgz#5faad520ab860582ed94f0c1a77f0f04c90b57c0" + integrity sha512-FJkPoHHB+6s4a+jwPqBudBDvYZsoQW5/HBuMSehC8qDiCe50kpcxeqFoDSlow+9I6wg47YxBoT3WxaURlrDIIQ== dependencies: chalk "^2.4.2" ci-info "^2.0.0" @@ -3603,7 +3723,7 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jsx-ast-utils@^2.2.1: +jsx-ast-utils@^2.2.1, jsx-ast-utils@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz#8a9364e402448a3ce7f14d357738310d9248054f" integrity sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA== @@ -3964,10 +4084,10 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== -nanoid@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.6.tgz#0665418f692e54cf44f34d4010761f3240a03314" - integrity sha512-2NDzpiuEy3+H0AVtdt8LoFi7PnqkOnIzYmJQp7xsEU6VexLluHQwKREuiz57XaQC5006seIadPrIZJhyS2n7aw== +nanoid@^2.1.7: + version "2.1.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.7.tgz#d775e3e7c6470bbaaae3da9a647a80e228e0abf7" + integrity sha512-fmS3qwDldm4bE01HCIRqNk+f255CNjnAoeV3Zzzv0KemObHKqYgirVaZA9DtKcjogicWjYcHkJs4D5A8CjnuVQ== nanomatch@^1.2.9: version "1.2.13" @@ -4200,7 +4320,7 @@ object.entries@^1.1.0: function-bind "^1.1.1" has "^1.0.3" -object.fromentries@^2.0.0: +object.fromentries@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.1.tgz#050f077855c7af8ae6649f45c80b16ee2d31e704" integrity sha512-PUQv8Hbg3j2QX0IQYv3iAGCbGcu4yY4KQ92/dhA4sFSixBmSmp13UpDLs6jGK8rBtbmhNNIK99LD2k293jpiGA== @@ -4269,7 +4389,7 @@ optimist@^0.6.1: minimist "~0.0.1" wordwrap "~0.0.2" -optionator@^0.8.1, optionator@^0.8.2: +optionator@^0.8.1, optionator@^0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== @@ -4889,6 +5009,13 @@ resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.3 dependencies: path-parse "^1.0.6" +resolve@^1.13.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.13.1.tgz#be0aa4c06acd53083505abb35f4d66932ab35d16" + integrity sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w== + dependencies: + path-parse "^1.0.6" + restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -5549,6 +5676,11 @@ type-fest@^0.6.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + type@^1.0.1: version "1.2.0" resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" From 083b8e7d67307a177d427d694ead22cb0c95b0ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20Ja=CC=88ppinen?= Date: Wed, 4 Dec 2019 15:26:15 +0200 Subject: [PATCH 53/64] fix: automatically add modifications only to originally staged files Using `git add .` does not work when an unrelated 3rd-party makes a file edit while lint-staged is running tasks. This change at least limits adding of modifications to those files that originally had staged changes. Unfortunately we have no way of detecting if a 3rd-party edits the same file. --- lib/gitWorkflow.js | 19 ++++++++++++------- lib/runAll.js | 8 ++++---- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index 128a96b13..ac178163c 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -15,18 +15,19 @@ const STASH = 'lint-staged automatic backup' const gitApplyArgs = ['apply', '-v', '--whitespace=nowarn', '--recount', '--unidiff-zero'] class GitWorkflow { - constructor(cwd) { - this.execGit = (args, options = {}) => execGit(args, { ...options, cwd }) + constructor({ gitDir, stagedFileChunks }) { + this.execGit = (args, options = {}) => execGit(args, { ...options, cwd: gitDir }) this.unstagedDiff = null - this.cwd = cwd + this.gitDir = gitDir + this.stagedFileChunks = stagedFileChunks /** * These three files hold state about an ongoing git merge * Resolve paths during constructor */ - this.mergeHeadFile = path.resolve(this.cwd, '.git', MERGE_HEAD) - this.mergeModeFile = path.resolve(this.cwd, '.git', MERGE_MODE) - this.mergeMsgFile = path.resolve(this.cwd, '.git', MERGE_MSG) + this.mergeHeadFile = path.resolve(this.gitDir, '.git', MERGE_HEAD) + this.mergeModeFile = path.resolve(this.gitDir, '.git', MERGE_MODE) + this.mergeMsgFile = path.resolve(this.gitDir, '.git', MERGE_MSG) } /** @@ -107,7 +108,11 @@ class GitWorkflow { debug('Detected files modified by tasks:') debug(modifiedFiles) debug('Adding files to index...') - await this.execGit(['add', '.']) + await Promise.all( + // stagedFileChunks includes staged files that lint-staged originally detected. + // Add only these files so any 3rd-party edits to other files won't be included in the commit. + this.stagedFileChunks.map(stagedFiles => this.execGit(['add', ...stagedFiles])) + ) debug('Done adding files to index!') } diff --git a/lib/runAll.js b/lib/runAll.js index 1ae43f911..7a4621245 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -61,8 +61,8 @@ module.exports = async function runAll( debugLog('Loaded list of staged files in git:\n%O', files) - const chunkedFiles = chunkFiles({ files, gitDir, maxArgLength, relative }) - const chunkCount = chunkedFiles.length + const stagedFileChunks = chunkFiles({ files, gitDir, maxArgLength, relative }) + const chunkCount = stagedFileChunks.length if (chunkCount > 1) { debugLog(`Chunked staged files into ${chunkCount} part`, chunkCount) } @@ -78,7 +78,7 @@ module.exports = async function runAll( const listrTasks = [] - for (const [index, files] of chunkedFiles.entries()) { + for (const [index, files] of stagedFileChunks.entries()) { const chunkTasks = generateTasks({ config, cwd, gitDir, files, relative }) const chunkListrTasks = chunkTasks.map(task => { const subTasks = makeCmdTasks({ @@ -139,7 +139,7 @@ module.exports = async function runAll( return 'No tasks to run.' } - const git = new GitWorkflow(gitDir) + const git = new GitWorkflow({ gitDir, stagedFileChunks }) const runner = new Listr( [ From f3ae378aa8d7207f990c4ffec854cc8da4d38b1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sat, 14 Dec 2019 10:19:16 +0200 Subject: [PATCH 54/64] fix: better workaround for git stash --keep-index bug --- lib/gitWorkflow.js | 34 +++++++++++----- test/gitWorkflow.spec.js | 77 ++++++++++++++++++++++++++++++++++++ test/runAll.unmocked.spec.js | 6 +-- 3 files changed, 105 insertions(+), 12 deletions(-) create mode 100644 test/gitWorkflow.spec.js diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index ac178163c..0674831b9 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -14,6 +14,23 @@ const STASH = 'lint-staged automatic backup' const gitApplyArgs = ['apply', '-v', '--whitespace=nowarn', '--recount', '--unidiff-zero'] +/** + * Delete untracked files using `git clean` + * @param {Function} execGit function for executing git commands using execa + * @returns {Promise} + */ +const cleanUntrackedFiles = async execGit => { + const untrackedFiles = await execGit(['ls-files', '--others', '--exclude-standard']) + if (untrackedFiles) { + debug('Detected unstaged, untracked files: ', untrackedFiles) + debug( + 'This is probably due to a bug in git =< 2.13.0 where `git stash --keep-index` resurrects deleted files.' + ) + debug('Deleting the files using `git clean`...') + await execGit(['clean', '--force', untrackedFiles.split('\n').join(' ')]) + } +} + class GitWorkflow { constructor({ gitDir, stagedFileChunks }) { this.execGit = (args, options = {}) => execGit(args, { ...options, cwd: gitDir }) @@ -69,18 +86,15 @@ class GitWorkflow { debug('Done backing up merge state!') } - // Get diff of staged modifications. This will be applied back to the index. after stashing all changes. - // The `git stash save --keep-index` option cannot be used since it resurrects deleted files on - // git versions before v2.23.0 (https://github.com/git/git/blob/master/Documentation/RelNotes/2.23.0.txt#L322) - const stagedDiff = await this.execGit(['diff', '--binary', '--cached']) - // Save stash of entire original state, including unstaged and untracked changes. - // This should remove all changes from the index. - await this.execGit(['stash', 'save', '--quiet', '--include-untracked', STASH]) + // `--keep-index leaves only staged files on disk, for tasks.` + await this.execGit(['stash', 'save', '--quiet', '--include-untracked', '--keep-index', STASH]) - // Apply staged modifications back to the index - await this.execGit([...gitApplyArgs, '--index'], { input: `${stagedDiff}\n` }) + // There is a bug in git =< 2.13.0 where `--keep-index` resurrects deleted files. + // These files should be listed and deleted before proceeding. + await cleanUntrackedFiles(this.execGit) + // Get a diff of unstaged changes by saved stash against what's left on disk. this.unstagedDiff = await this.execGit([ 'diff', '--binary', @@ -91,6 +105,7 @@ class GitWorkflow { await this.getBackupStash(), '-R' // Show diff in reverse ]) + debug('Done backing up original state!') } @@ -189,3 +204,4 @@ class GitWorkflow { } module.exports = GitWorkflow +module.exports.cleanUntrackedFiles = cleanUntrackedFiles diff --git a/test/gitWorkflow.spec.js b/test/gitWorkflow.spec.js new file mode 100644 index 000000000..f52a0af81 --- /dev/null +++ b/test/gitWorkflow.spec.js @@ -0,0 +1,77 @@ +import fs from 'fs-extra' +import normalize from 'normalize-path' +import os from 'os' +import path from 'path' +import nanoid from 'nanoid' + +import execGitBase from '../lib/execGit' +import { cleanUntrackedFiles } from '../lib/gitWorkflow' + +jest.unmock('execa') + +jest.setTimeout(20000) + +const isAppveyor = !!process.env.APPVEYOR +const osTmpDir = isAppveyor ? 'C:\\projects' : fs.realpathSync(os.tmpdir()) + +/** + * Create temporary directory and return its path + * @returns {Promise} + */ +const createTempDir = async () => { + const dirname = path.resolve(osTmpDir, 'lint-staged-test', nanoid()) + await fs.ensureDir(dirname) + return dirname +} + +/** + * Remove temporary directory + * @param {String} dirname + * @returns {Promise} + */ +const removeTempDir = async dirname => { + await fs.remove(dirname) +} + +let tmpDir, cwd + +/** Append to file, creating if it doesn't exist */ +const appendFile = async (filename, content, dir = cwd) => + fs.appendFile(path.resolve(dir, filename), content) + +/** Wrap execGit to always pass `gitOps` */ +const execGit = async args => execGitBase(args, { cwd }) + +/** Initialize git repo for test */ +const initGitRepo = async () => { + await execGit('init') + await execGit(['config', 'user.name', '"test"']) + await execGit(['config', 'user.email', '"test@test.com"']) + await appendFile('README.md', '# Test\n') + await execGit(['add', 'README.md']) + await execGit(['commit', '-m initial commit']) +} + +describe('gitWorkflow', () => { + beforeEach(async () => { + tmpDir = await createTempDir() + cwd = normalize(tmpDir) + await initGitRepo() + }) + + afterEach(async () => { + if (!isAppveyor) { + await removeTempDir(tmpDir) + } + }) + + describe('cleanUntrackedFiles', () => { + it('should delete untracked, unstaged files', async () => { + const testFile = path.resolve(cwd, 'test.js') + await appendFile(testFile, 'test') + expect(await fs.exists(testFile)).toEqual(true) + await cleanUntrackedFiles(execGit) + expect(await fs.exists(testFile)).toEqual(false) + }) + }) +}) diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 52c6f9078..6c14c310e 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -55,15 +55,15 @@ let cwd // Get file content const readFile = async (filename, dir = cwd) => - fs.readFile(path.join(dir, filename), { encoding: 'utf-8' }) + fs.readFile(path.resolve(dir, filename), { encoding: 'utf-8' }) // Append to file, creating if it doesn't exist const appendFile = async (filename, content, dir = cwd) => - fs.appendFile(path.join(dir, filename), content) + fs.appendFile(path.resolve(dir, filename), content) // Write (over) file, creating if it doesn't exist const writeFile = async (filename, content, dir = cwd) => - fs.writeFile(path.join(dir, filename), content) + fs.writeFile(path.resolve(dir, filename), content) // Wrap execGit to always pass `gitOps` const execGit = async args => execGitBase(args, { cwd }) From 22ba124a7b22562a4ecef48d4a209ceb508a9668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Sat, 14 Dec 2019 10:49:04 +0200 Subject: [PATCH 55/64] refactor: minor optimizations --- lib/gitWorkflow.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index 0674831b9..182d871c5 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -27,7 +27,7 @@ const cleanUntrackedFiles = async execGit => { 'This is probably due to a bug in git =< 2.13.0 where `git stash --keep-index` resurrects deleted files.' ) debug('Deleting the files using `git clean`...') - await execGit(['clean', '--force', untrackedFiles.split('\n').join(' ')]) + await execGit(['clean', '--force', ...untrackedFiles.split('\n')]) } } @@ -94,7 +94,7 @@ class GitWorkflow { // These files should be listed and deleted before proceeding. await cleanUntrackedFiles(this.execGit) - // Get a diff of unstaged changes by saved stash against what's left on disk. + // Get a diff of unstaged changes by diffing the saved stash against what's left on disk. this.unstagedDiff = await this.execGit([ 'diff', '--binary', @@ -119,7 +119,6 @@ class GitWorkflow { async applyModifications() { let modifiedFiles = await this.execGit(['ls-files', '--modified']) if (modifiedFiles) { - modifiedFiles = modifiedFiles.split('\n') debug('Detected files modified by tasks:') debug(modifiedFiles) debug('Adding files to index...') From f8ddfc22d22fec2b417a67249573e7cd6abdb9fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Mon, 16 Dec 2019 18:44:36 +0200 Subject: [PATCH 56/64] fix: restore metadata about git merge before running tasks --- lib/gitWorkflow.js | 95 +++++++++++++++---------------- test/runAll.unmocked.spec.js | 105 +++++++++++++++++++++++++++-------- 2 files changed, 130 insertions(+), 70 deletions(-) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index 182d871c5..5a9c6f950 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -42,16 +42,13 @@ class GitWorkflow { * These three files hold state about an ongoing git merge * Resolve paths during constructor */ - this.mergeHeadFile = path.resolve(this.gitDir, '.git', MERGE_HEAD) - this.mergeModeFile = path.resolve(this.gitDir, '.git', MERGE_MODE) - this.mergeMsgFile = path.resolve(this.gitDir, '.git', MERGE_MSG) + this.mergeHeadFilename = path.resolve(this.gitDir, '.git', MERGE_HEAD) + this.mergeModeFilename = path.resolve(this.gitDir, '.git', MERGE_MODE) + this.mergeMsgFilename = path.resolve(this.gitDir, '.git', MERGE_MSG) } /** * Get name of backup stash - * - * @param {Object} [options] - * @returns {Promise} */ async getBackupStash() { const stashes = await this.execGit(['stash', 'list']) @@ -59,37 +56,56 @@ class GitWorkflow { return `stash@{${index}}` } + /** + * Save meta information about ongoing git merge + */ + async backupMergeStatus() { + debug('Detected current merge mode!') + debug('Backing up merge state...') + await Promise.all([ + readBufferFromFile(this.mergeHeadFilename).then(buffer => (this.mergeHeadBuffer = buffer)), + readBufferFromFile(this.mergeModeFilename).then(buffer => (this.mergeModeBuffer = buffer)), + readBufferFromFile(this.mergeMsgFilename).then(buffer => (this.mergeMsgBuffer = buffer)) + ]) + debug('Done backing up merge state!') + } + + /** + * Restore meta information about ongoing git merge + */ + async restoreMergeStatus() { + debug('Detected backup merge state!') + debug('Restoring merge state...') + await Promise.all([ + writeBufferToFile(this.mergeHeadFilename, this.mergeHeadBuffer), + writeBufferToFile(this.mergeModeFilename, this.mergeModeBuffer), + writeBufferToFile(this.mergeMsgFilename, this.mergeMsgBuffer) + ]) + debug('Done restoring merge state!') + } + /** * Create backup stashes, one of everything and one of only staged changes * Staged files are left in the index for running tasks - * - * @param {Object} [options] - * @returns {Promise} */ async stashBackup() { debug('Backing up original state...') - // Git stash loses metadata about a possible merge mode + // the `git stash` clears metadata about a possible git merge // Manually check and backup if necessary - if (await checkFile(this.mergeHeadFile)) { - debug('Detected current merge mode!') - debug('Backing up merge state...') - await Promise.all([ - readBufferFromFile(this.mergeHeadFile).then( - mergeHead => (this.mergeHeadBuffer = mergeHead) - ), - readBufferFromFile(this.mergeModeFile).then( - mergeMode => (this.mergeModeBuffer = mergeMode) - ), - readBufferFromFile(this.mergeMsgFile).then(mergeMsg => (this.mergeMsgBuffer = mergeMsg)) - ]) - debug('Done backing up merge state!') + if (await checkFile(this.mergeHeadFilename)) { + await this.backupMergeStatus() } // Save stash of entire original state, including unstaged and untracked changes. // `--keep-index leaves only staged files on disk, for tasks.` await this.execGit(['stash', 'save', '--quiet', '--include-untracked', '--keep-index', STASH]) + // Restore meta information about ongoing git merge + if (this.mergeHeadBuffer) { + await this.restoreMergeStatus() + } + // There is a bug in git =< 2.13.0 where `--keep-index` resurrects deleted files. // These files should be listed and deleted before proceeding. await cleanUntrackedFiles(this.execGit) @@ -112,9 +128,6 @@ class GitWorkflow { /** * Applies back task modifications, and unstaged changes hidden in the stash. * In case of a merge-conflict retry with 3-way merge. - * - * @param {Object} [options] - * @returns {Promise} */ async applyModifications() { let modifiedFiles = await this.execGit(['ls-files', '--modified']) @@ -165,40 +178,28 @@ class GitWorkflow { /** * Restore original HEAD state in case of errors - * - * @param {Object} [options] - * @returns {Promise} */ async restoreOriginalState() { debug('Restoring original state...') - const original = await this.getBackupStash() + const backupStash = await this.getBackupStash() await this.execGit(['reset', '--hard', 'HEAD']) - await this.execGit(['stash', 'apply', '--quiet', '--index', original]) + await this.execGit(['stash', 'apply', '--quiet', '--index', backupStash]) debug('Done restoring original state!') + + // Restore meta information about ongoing git merge + if (this.mergeHeadBuffer) { + await this.restoreMergeStatus() + } } /** * Drop the created stashes after everything has run - * - * @param {Object} [options] - * @returns {Promise} */ async dropBackup() { debug('Dropping backup stash...') - const original = await this.getBackupStash() - await this.execGit(['stash', 'drop', '--quiet', original]) + const backupStash = await this.getBackupStash() + await this.execGit(['stash', 'drop', '--quiet', backupStash]) debug('Done dropping backup stash!') - - if (this.mergeHeadBuffer) { - debug('Detected backup merge state!') - debug('Restoring merge state...') - await Promise.all([ - writeBufferToFile(this.mergeHeadFile, this.mergeHeadBuffer), - writeBufferToFile(this.mergeModeFile, this.mergeModeBuffer), - writeBufferToFile(this.mergeMsgFile, this.mergeMsgBuffer) - ]) - debug('Done restoring merge state!') - } } } diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 6c14c310e..7b1c2fe06 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -369,17 +369,17 @@ describe('runAll', () => { // But local modifications are gone expect(await execGit(['diff'])).not.toEqual(diff) expect(await execGit(['diff'])).toMatchInlineSnapshot(` - "diff --git a/test.js b/test.js - index f80f875..1c5643c 100644 - --- a/test.js - +++ b/test.js - @@ -1,3 +1,3 @@ - module.exports = { - - 'foo': 'bar', - -} - + foo: \\"bar\\" - +};" - `) + "diff --git a/test.js b/test.js + index f80f875..1c5643c 100644 + --- a/test.js + +++ b/test.js + @@ -1,3 +1,3 @@ + module.exports = { + - 'foo': 'bar', + -} + + foo: \\"bar\\" + +};" + `) expect(await readFile('test.js')).not.toEqual(testJsFileUgly + appended) expect(await readFile('test.js')).toEqual(testJsFilePretty) @@ -433,13 +433,13 @@ describe('runAll', () => { } expect(await readFile('test.js')).toMatchInlineSnapshot(` - "<<<<<<< HEAD - module.exports = \\"foo\\"; - ======= - module.exports = \\"bar\\"; - >>>>>>> branch-b - " - `) + "<<<<<<< HEAD + module.exports = \\"foo\\"; + ======= + module.exports = \\"bar\\"; + >>>>>>> branch-b + " + `) // Fix conflict and commit using lint-staged await writeFile('test.js', fileInBranchB) @@ -453,15 +453,74 @@ describe('runAll', () => { // Nothing is wrong, so a new commit is created and file is pretty expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('4') expect(await execGit(['log', '-1', '--pretty=%B'])).toMatchInlineSnapshot(` - "Merge branch 'branch-b' + "Merge branch 'branch-b' - # Conflicts: - # test.js - " - `) + # Conflicts: + # test.js + " + `) expect(await readFile('test.js')).toEqual(fileInBranchBFixed) }) + it('should handle merge conflict when task errors', async () => { + const fileInBranchA = `module.exports = "foo";\n` + const fileInBranchB = `module.exports = 'bar'\n` + const fileInBranchBFixed = `module.exports = "bar";\n` + + // Create one branch + await execGit(['checkout', '-b', 'branch-a']) + await appendFile('test.js', fileInBranchA) + await execGit(['add', '.']) + await gitCommit(fixJsConfig, ['-m commit a']) + expect(await readFile('test.js')).toEqual(fileInBranchA) + + await execGit(['checkout', 'master']) + + // Create another branch + await execGit(['checkout', '-b', 'branch-b']) + await appendFile('test.js', fileInBranchB) + await execGit(['add', '.']) + await gitCommit(fixJsConfig, ['-m commit b']) + expect(await readFile('test.js')).toEqual(fileInBranchBFixed) + + // Merge first branch + await execGit(['checkout', 'master']) + await execGit(['merge', 'branch-a']) + expect(await readFile('test.js')).toEqual(fileInBranchA) + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('commit a') + + // Merge second branch, causing merge conflict + try { + await execGit(['merge', 'branch-b']) + } catch (error) { + expect(error.message).toMatch('Merge conflict in test.js') + } + + expect(await readFile('test.js')).toMatchInlineSnapshot(` + "<<<<<<< HEAD + module.exports = \\"foo\\"; + ======= + module.exports = \\"bar\\"; + >>>>>>> branch-b + " + `) + + // Fix conflict and commit using lint-staged + await writeFile('test.js', fileInBranchB) + expect(await readFile('test.js')).toEqual(fileInBranchB) + await execGit(['add', '.']) + + // Do not use `gitCommit` wrapper here + await expect( + runAll({ config: { '*.js': 'prettier --list-different' }, cwd, quiet: true }) + ).rejects.toThrowErrorMatchingInlineSnapshot(`"Something went wrong"`) + + // Something went wrong, so runAll failed and merge is still going + expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') + expect(await execGit(['status'])).toMatch('All conflicts fixed but you are still merging') + expect(await readFile('test.js')).toEqual(fileInBranchB) + }) + it('should keep untracked files', async () => { // Stage pretty file await appendFile('test.js', testJsFilePretty) From d091f71ff50b1eddc59e759b1b09a95ed613c4d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Tue, 17 Dec 2019 21:34:19 +0200 Subject: [PATCH 57/64] fix: correctly recover when unstaged changes cannot be restored --- lib/gitWorkflow.js | 33 +++++++++++------ lib/runAll.js | 10 +++--- test/index2.spec.js | 12 +++++-- test/runAll.unmocked.spec.js | 70 +++++++++++++++++++++++++----------- 4 files changed, 89 insertions(+), 36 deletions(-) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index 5a9c6f950..921597161 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -31,6 +31,14 @@ const cleanUntrackedFiles = async execGit => { } } +const handleGitLockError = (error, ctx) => { + if (error.message.includes('Another git process seems to be running in this repository')) { + ctx.hasErrors = true + ctx.hasGitLockError = true + } + throw error +} + class GitWorkflow { constructor({ gitDir, stagedFileChunks }) { this.execGit = (args, options = {}) => execGit(args, { ...options, cwd: gitDir }) @@ -129,7 +137,7 @@ class GitWorkflow { * Applies back task modifications, and unstaged changes hidden in the stash. * In case of a merge-conflict retry with 3-way merge. */ - async applyModifications() { + async applyModifications(ctx) { let modifiedFiles = await this.execGit(['ls-files', '--modified']) if (modifiedFiles) { debug('Detected files modified by tasks:') @@ -158,6 +166,7 @@ class GitWorkflow { } catch (error2) { debug('Error while restoring unstaged changes using 3-way merge:') debug(error2) + ctx.hasErrors = true throw new Error('Unstaged changes could not be restored due to a merge conflict!') } } @@ -179,16 +188,20 @@ class GitWorkflow { /** * Restore original HEAD state in case of errors */ - async restoreOriginalState() { - debug('Restoring original state...') - const backupStash = await this.getBackupStash() - await this.execGit(['reset', '--hard', 'HEAD']) - await this.execGit(['stash', 'apply', '--quiet', '--index', backupStash]) - debug('Done restoring original state!') + async restoreOriginalState(ctx) { + try { + debug('Restoring original state...') + const backupStash = await this.getBackupStash() + await this.execGit(['reset', '--hard', 'HEAD']) + await this.execGit(['stash', 'apply', '--quiet', '--index', backupStash]) + debug('Done restoring original state!') - // Restore meta information about ongoing git merge - if (this.mergeHeadBuffer) { - await this.restoreMergeStatus() + // Restore meta information about ongoing git merge + if (this.mergeHeadBuffer) { + await this.restoreMergeStatus() + } + } catch (error) { + handleGitLockError(error, ctx) } } diff --git a/lib/runAll.js b/lib/runAll.js index 7a4621245..e4b3ba4a8 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -73,6 +73,7 @@ module.exports = async function runAll( const listrOptions = { dateFormat: false, + exitOnError: false, renderer: (quiet && 'silent') || (debug && 'verbose') || 'update' } @@ -115,7 +116,7 @@ module.exports = async function runAll( // No need to show number of task chunks when there's only one title: chunkCount > 1 ? `Running tasks (chunk ${index + 1}/${chunkCount})...` : 'Running tasks...', - task: () => new Listr(chunkListrTasks, { ...listrOptions, concurrent, exitOnError: false }), + task: () => new Listr(chunkListrTasks, { ...listrOptions, concurrent }), skip: () => { if (chunkListrTasks.every(task => task.skip())) { return 'No tasks to run.' @@ -151,15 +152,16 @@ module.exports = async function runAll( { title: 'Applying modifications...', skip: ctx => ctx.hasErrors && 'Skipped because of errors from tasks', - task: () => git.applyModifications() + task: ctx => git.applyModifications(ctx) }, { title: 'Reverting to original state...', enabled: ctx => ctx.hasErrors, - task: () => git.restoreOriginalState() + task: ctx => git.restoreOriginalState(ctx) }, { title: 'Cleaning up...', + skip: ctx => ctx.hasGitLockError && 'Skipped because of previous git error', task: () => git.dropBackup() } ], @@ -169,7 +171,7 @@ module.exports = async function runAll( try { await runner.run() } catch (error) { - if (error.message.includes('Another git process seems to be running in this repository')) { + if (error.context.hasGitLockError) { logger.error(` ${symbols.error} ${chalk.red(`lint-staged failed due to a git error. Any lost modifications can be restored from a git stash: diff --git a/test/index2.spec.js b/test/index2.spec.js index 6c7bb751c..99d2a1d8a 100644 --- a/test/index2.spec.js +++ b/test/index2.spec.js @@ -21,7 +21,11 @@ describe('lintStaged', () => { { configPath: path.join(__dirname, '__mocks__', 'my-config.json'), quiet: true }, console ) - expect(Listr.mock.calls[0][1]).toEqual({ dateFormat: false, renderer: 'silent' }) + expect(Listr.mock.calls[0][1]).toEqual({ + dateFormat: false, + exitOnError: false, + renderer: 'silent' + }) }) it('should pass debug flag to Listr', async () => { @@ -33,6 +37,10 @@ describe('lintStaged', () => { }, console ) - expect(Listr.mock.calls[0][1]).toEqual({ dateFormat: false, renderer: 'verbose' }) + expect(Listr.mock.calls[0][1]).toEqual({ + dateFormat: false, + exitOnError: false, + renderer: 'verbose' + }) }) }) diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 7b1c2fe06..35988bc99 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -70,7 +70,7 @@ const execGit = async args => execGitBase(args, { cwd }) // Execute runAll before git commit to emulate lint-staged const gitCommit = async (options, args = ['-m test']) => { - await runAll({ ...options, cwd, quiet: true }) + await runAll({ quiet: true, ...options, cwd }) await execGit(['commit', ...args]) } @@ -191,6 +191,38 @@ describe('runAll', () => { expect(await readFile('test.js')).toEqual(testJsFileUnfixable) }) + it('Should fail to commit entire staged file when there are unrecoverable merge conflicts', async () => { + // Stage file + await appendFile('test.js', testJsFileUgly) + await execGit(['add', 'test.js']) + + // Run lint-staged with action that does horrible things to the file, causing a merge conflict + await expect( + gitCommit({ + config: { + '*.js': file => { + fs.writeFileSync(file[0], Buffer.from(testJsFileUnfixable, 'binary')) + return `prettier --write ${file[0]}` + } + }, + quiet: false, + debug: true + }) + ).rejects.toThrowError() + + expect(console.printHistory()).toMatch( + 'Unstaged changes could not be restored due to a merge conflict!' + ) + + // Something was wrong so the repo is returned to original state + expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('initial commit') + // Git status is a bit messed up because the horrible things we did + // in the config above were done before creating the initial backup stash, + // and thus included in it. + expect(await execGit(['status', '--porcelain'])).toMatchInlineSnapshot(`"AM test.js"`) + }) + it('Should commit partial change from partially staged file when no errors from linter', async () => { // Stage pretty file await appendFile('test.js', testJsFilePretty) @@ -334,9 +366,9 @@ describe('runAll', () => { const diff = await execGit(['diff']) // Run lint-staged with `prettier --write` and commit pretty file - // The task creates a git lock file to simulate failure - try { - await gitCommit({ + // The task creates a git lock file and runs `git add` to simulate failure + await expect( + gitCommit({ config: { '*.js': files => [ `touch ${cwd}/.git/index.lock`, @@ -345,22 +377,20 @@ describe('runAll', () => { ] } }) - } catch (error) { - expect(error.message).toMatch('Another git process seems to be running in this repository') - expect(console.printHistory()).toMatchInlineSnapshot(` - " - WARN ‼ Some of your tasks use \`git add\` command. Please remove it from the config since all modifications made by tasks will be automatically added to the git commit index. - - ERROR - × lint-staged failed due to a git error. - Any lost modifications can be restored from a git stash: - - > git stash list - stash@{0}: On master: automatic lint-staged backup - > git stash pop stash@{0} - " - `) - } + ).rejects.toThrowError() + expect(console.printHistory()).toMatchInlineSnapshot(` + " + WARN ‼ Some of your tasks use \`git add\` command. Please remove it from the config since all modifications made by tasks will be automatically added to the git commit index. + + ERROR + × lint-staged failed due to a git error. + Any lost modifications can be restored from a git stash: + + > git stash list + stash@{0}: On master: automatic lint-staged backup + > git stash pop stash@{0} + " + `) // Something was wrong so new commit wasn't created expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('1') From 9913bb2fdb6a9254bd6dd975ca5ed796c0f96dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Tue, 17 Dec 2019 21:44:52 +0200 Subject: [PATCH 58/64] test: do not write file into repo during test run --- test/runAll.unmocked.spec.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 35988bc99..70026fe73 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -197,12 +197,13 @@ describe('runAll', () => { await execGit(['add', 'test.js']) // Run lint-staged with action that does horrible things to the file, causing a merge conflict + const testFile = path.resolve(cwd, 'test.js') await expect( gitCommit({ config: { - '*.js': file => { - fs.writeFileSync(file[0], Buffer.from(testJsFileUnfixable, 'binary')) - return `prettier --write ${file[0]}` + '*.js': () => { + fs.writeFileSync(testFile, Buffer.from(testJsFileUnfixable, 'binary')) + return `prettier --write ${testFile}` } }, quiet: false, From 1b64239163f5560b7235843909a9d30ff7ca1b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Tue, 17 Dec 2019 21:56:59 +0200 Subject: [PATCH 59/64] fix: fail with a message when backup stash is missing --- lib/gitWorkflow.js | 15 ++++++++++----- lib/runAll.js | 2 +- test/runAll.unmocked.spec.js | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index 921597161..b3a13d86a 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -61,6 +61,7 @@ class GitWorkflow { async getBackupStash() { const stashes = await this.execGit(['stash', 'list']) const index = stashes.split('\n').findIndex(line => line.includes(STASH)) + if (index === -1) throw new Error('lint-staged automatic backup is missing!') return `stash@{${index}}` } @@ -208,11 +209,15 @@ class GitWorkflow { /** * Drop the created stashes after everything has run */ - async dropBackup() { - debug('Dropping backup stash...') - const backupStash = await this.getBackupStash() - await this.execGit(['stash', 'drop', '--quiet', backupStash]) - debug('Done dropping backup stash!') + async dropBackup(ctx) { + try { + debug('Dropping backup stash...') + const backupStash = await this.getBackupStash() + await this.execGit(['stash', 'drop', '--quiet', backupStash]) + debug('Done dropping backup stash!') + } catch (error) { + handleGitLockError(error, ctx) + } } } diff --git a/lib/runAll.js b/lib/runAll.js index e4b3ba4a8..8b930174f 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -162,7 +162,7 @@ module.exports = async function runAll( { title: 'Cleaning up...', skip: ctx => ctx.hasGitLockError && 'Skipped because of previous git error', - task: () => git.dropBackup() + task: ctx => git.dropBackup(ctx) } ], listrOptions diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index 70026fe73..bb37f12dd 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -646,4 +646,36 @@ describe('runAll', () => { expect(await readFile('test.js')).toEqual(testJsFilePretty) expect(await readFile('test2.js')).toEqual(testJsFilePretty) }) + + it('should fail when backup stash is missing', async () => { + await appendFile('test.js', testJsFilePretty) + await execGit(['add', 'test.js']) + + // Remove backup stash during run + await expect( + gitCommit({ + config: { '*.js': () => 'git stash drop' }, + shell: true, + debug: true, + quiet: false + }) + ).rejects.toThrowError() + + expect(console.printHistory()).toMatchInlineSnapshot(` + " + LOG Preparing... [started] + LOG Preparing... [completed] + LOG Running tasks... [started] + LOG Running tasks for *.js [started] + LOG git stash drop [started] + LOG git stash drop [completed] + LOG Running tasks for *.js [completed] + LOG Running tasks... [completed] + LOG Applying modifications... [started] + LOG Applying modifications... [completed] + LOG Cleaning up... [started] + LOG Cleaning up... [failed] + LOG → lint-staged automatic backup is missing!" + `) + }) }) From 20d5c5d4cb92f9a4c501e5308cc51379d10581a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20Ja=CC=88ppinen?= Date: Wed, 18 Dec 2019 07:29:47 +0200 Subject: [PATCH 60/64] feat: support async function tasks --- README.md | 10 +++++----- lib/makeCmdTasks.js | 32 +++++++++++++++++--------------- lib/runAll.js | 12 +++++++----- test/makeCmdTasks.spec.js | 14 ++++++++++---- 4 files changed, 39 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 5f0bb1fde..82f1d653e 100644 --- a/README.md +++ b/README.md @@ -153,12 +153,12 @@ Pass arguments to your commands separated by space as you would do in the shell. Starting from [v2.0.0](https://github.com/okonet/lint-staged/releases/tag/2.0.0) sequences of commands are supported. Pass an array of commands instead of a single one and they will run sequentially. This is useful for running autoformatting tools like `eslint --fix` or `stylefmt` but can be used for any arbitrary sequences. -## Using JS functions to customize linter commands +## Using JS functions to customize tasks -When supplying configuration in JS format it is possible to define the linter command as a function which receives an array of staged filenames/paths and returns the complete linter command as a string. It is also possible to return an array of complete command strings, for example when the linter command supports only a single file input. +When supplying configuration in JS format it is possible to define the task as a function, which will receive an array of staged filenames/paths and should return the complete command as a string. It is also possible to return an array of complete command strings, for example when the task supports only a single file input. The function can be either sync or async. ```ts -type LinterFn = (filenames: string[]) => string | string[] +type TaskFn = (filenames: string[]) => string | string[] | Promise ``` ### Example: Wrap filenames in single quotes and run once per file @@ -196,7 +196,7 @@ const micromatch = require('micromatch') module.exports = { '*': allFiles => { const match = micromatch(allFiles, ['*.js', '*.ts']) - return `eslint ${match.join(" ")}` + return `eslint ${match.join(' ')}` } } ``` @@ -212,7 +212,7 @@ module.exports = { '*.js': files => { // from `files` filter those _NOT_ matching `*test.js` const match = micromatch.not(files, '*test.js') - return `eslint ${match.join(" ")}` + return `eslint ${match.join(' ')}` } } ``` diff --git a/lib/makeCmdTasks.js b/lib/makeCmdTasks.js index 6d1482906..703611973 100644 --- a/lib/makeCmdTasks.js +++ b/lib/makeCmdTasks.js @@ -13,41 +13,43 @@ const debug = require('debug')('lint-staged:make-cmd-tasks') * @param {string} options.gitDir * @param {Boolean} shell */ -module.exports = function makeCmdTasks({ commands, files, gitDir, shell }) { +module.exports = async function makeCmdTasks({ commands, files, gitDir, shell }) { debug('Creating listr tasks for commands %o', commands) const commandsArray = Array.isArray(commands) ? commands : [commands] + const cmdTasks = [] - return commandsArray.reduce((tasks, command) => { + for (const cmd of commandsArray) { // command function may return array of commands that already include `stagedFiles` - const isFn = typeof command === 'function' - const resolved = isFn ? command(files) : command - const commands = Array.isArray(resolved) ? resolved : [resolved] // Wrap non-array command as array + const isFn = typeof cmd === 'function' + const resolved = isFn ? await cmd(files) : cmd + + const resolvedArray = Array.isArray(resolved) ? resolved : [resolved] // Wrap non-array command as array // Function command should not be used as the task title as-is // because the resolved string it might be very long // Create a matching command array with [file] in place of file names - let mockCommands + let mockCmdTasks if (isFn) { const mockFileList = Array(files.length).fill('[file]') - const resolved = command(mockFileList) - mockCommands = Array.isArray(resolved) ? resolved : [resolved] + const resolved = await cmd(mockFileList) + mockCmdTasks = Array.isArray(resolved) ? resolved : [resolved] } - commands.forEach((command, i) => { + for (const [i, command] of resolvedArray.entries()) { let title = isFn ? '[Function]' : command - if (isFn && mockCommands[i]) { + if (isFn && mockCmdTasks[i]) { // If command is a function, use the matching mock command as title, // but since might include multiple [file] arguments, shorten to one - title = mockCommands[i].replace(/\[file\].*\[file\]/, '[file]') + title = mockCmdTasks[i].replace(/\[file\].*\[file\]/, '[file]') } - tasks.push({ + cmdTasks.push({ title, command, task: resolveTaskFn({ command, files, gitDir, isFn, shell }) }) - }) + } + } - return tasks - }, []) + return cmdTasks } diff --git a/lib/runAll.js b/lib/runAll.js index 8b930174f..4edf39324 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -81,8 +81,10 @@ module.exports = async function runAll( for (const [index, files] of stagedFileChunks.entries()) { const chunkTasks = generateTasks({ config, cwd, gitDir, files, relative }) - const chunkListrTasks = chunkTasks.map(task => { - const subTasks = makeCmdTasks({ + const chunkListrTasks = [] + + for (const task of chunkTasks) { + const subTasks = await makeCmdTasks({ commands: task.commands, files: task.fileList, gitDir, @@ -93,7 +95,7 @@ module.exports = async function runAll( hasDeprecatedGitAdd = true } - return { + chunkListrTasks.push({ title: `Running tasks for ${task.pattern}`, task: async () => new Listr(subTasks, { @@ -109,8 +111,8 @@ module.exports = async function runAll( } return false } - } - }) + }) + } listrTasks.push({ // No need to show number of task chunks when there's only one diff --git a/test/makeCmdTasks.spec.js b/test/makeCmdTasks.spec.js index 0c94e1d65..393f820b2 100644 --- a/test/makeCmdTasks.spec.js +++ b/test/makeCmdTasks.spec.js @@ -58,13 +58,13 @@ describe('makeCmdTasks', () => { }) }) - it('should work with function linter returning a string', async () => { + it('should work with function task returning a string', async () => { const res = await makeCmdTasks({ commands: () => 'test', gitDir, files: ['test.js'] }) expect(res.length).toBe(1) expect(res[0].title).toEqual('test') }) - it('should work with function linter returning array of string', async () => { + it('should work with function task returning array of string', async () => { const res = await makeCmdTasks({ commands: () => ['test', 'test2'], gitDir, @@ -75,7 +75,7 @@ describe('makeCmdTasks', () => { expect(res[1].title).toEqual('test2') }) - it('should work with function linter accepting arguments', async () => { + it('should work with function task accepting arguments', async () => { const res = await makeCmdTasks({ commands: filenames => filenames.map(file => `test ${file}`), gitDir, @@ -86,7 +86,7 @@ describe('makeCmdTasks', () => { expect(res[1].title).toEqual('test [file]') }) - it('should work with array of mixed string and function linters', async () => { + it('should work with array of mixed string and function tasks', async () => { const res = await makeCmdTasks({ commands: [() => 'test', 'test2', files => files.map(file => `test ${file}`)], gitDir, @@ -109,4 +109,10 @@ describe('makeCmdTasks', () => { expect(res.length).toBe(1) expect(res[0].title).toEqual('test --file [file]') }) + + it('should work with async function tasks', async () => { + const res = await makeCmdTasks({ commands: async () => 'test', gitDir, files: ['test.js'] }) + expect(res.length).toBe(1) + expect(res[0].title).toEqual('test') + }) }) From da22cf22bbd21be98a73b880a4ce43dbd0129021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Fri, 20 Dec 2019 11:12:52 +0200 Subject: [PATCH 61/64] fix: handle git MERGE_* files separately; improve error handling --- lib/file.js | 30 +++------- lib/gitWorkflow.js | 102 ++++++++++++++++++--------------- lib/runAll.js | 15 ++--- test/runAll.unmocked.2.spec.js | 43 +++++++++++--- 4 files changed, 105 insertions(+), 85 deletions(-) diff --git a/lib/file.js b/lib/file.js index 2c6eece33..9a26a44a5 100644 --- a/lib/file.js +++ b/lib/file.js @@ -3,36 +3,20 @@ const debug = require('debug')('lint-staged:file') const fs = require('fs') -/** - * Check if file exists and is accessible - * @param {String} filename - * @returns {Promise} - */ -module.exports.checkFile = filename => - new Promise(resolve => { - debug('Trying to access `%s`', filename) - fs.access(filename, fs.constants.R_OK, error => { - if (error) { - debug('Unable to access file `%s` with error:', filename) - debug(error) - } else { - debug('Successfully accesses file `%s`', filename) - } - - resolve(!error) - }) - }) - /** * @param {String} filename * @returns {Promise} */ -module.exports.readBufferFromFile = filename => +module.exports.readBufferFromFile = (filename, rejectENOENT = false) => new Promise(resolve => { debug('Reading buffer from file `%s`', filename) - fs.readFile(filename, (error, file) => { + fs.readFile(filename, (error, buffer) => { + if (!rejectENOENT && error && error.code === 'ENOENT') { + debug("File `%s` doesn't exist, ignoring...", filename) + return resolve(null) // no-op file doesn't exist + } debug('Done reading buffer from file `%s`!', filename) - resolve(file) + resolve(buffer) }) }) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index b3a13d86a..0c34391fa 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -4,7 +4,7 @@ const debug = require('debug')('lint-staged:git') const path = require('path') const execGit = require('./execGit') -const { checkFile, readBufferFromFile, writeBufferToFile } = require('./file') +const { readBufferFromFile, writeBufferToFile } = require('./file') const MERGE_HEAD = 'MERGE_HEAD' const MERGE_MODE = 'MERGE_MODE' @@ -31,10 +31,18 @@ const cleanUntrackedFiles = async execGit => { } } -const handleGitLockError = (error, ctx) => { - if (error.message.includes('Another git process seems to be running in this repository')) { - ctx.hasErrors = true +const isGitLockError = error => + error.message.includes('Another git process seems to be running in this repository') + +const isGitMergeStateError = error => + error.message.includes('Merge state could not be restored due to an error!') + +const handleError = (error, ctx) => { + ctx.hasErrors = true + if (isGitLockError(error)) { ctx.hasGitLockError = true + } else if (isGitMergeStateError(error)) { + ctx.hasGitMergeStateError = true } throw error } @@ -69,7 +77,6 @@ class GitWorkflow { * Save meta information about ongoing git merge */ async backupMergeStatus() { - debug('Detected current merge mode!') debug('Backing up merge state...') await Promise.all([ readBufferFromFile(this.mergeHeadFilename).then(buffer => (this.mergeHeadBuffer = buffer)), @@ -83,55 +90,60 @@ class GitWorkflow { * Restore meta information about ongoing git merge */ async restoreMergeStatus() { - debug('Detected backup merge state!') debug('Restoring merge state...') - await Promise.all([ - writeBufferToFile(this.mergeHeadFilename, this.mergeHeadBuffer), - writeBufferToFile(this.mergeModeFilename, this.mergeModeBuffer), - writeBufferToFile(this.mergeMsgFilename, this.mergeMsgBuffer) - ]) - debug('Done restoring merge state!') + try { + await Promise.all([ + this.mergeHeadBuffer && writeBufferToFile(this.mergeHeadFilename, this.mergeHeadBuffer), + this.mergeModeBuffer && writeBufferToFile(this.mergeModeFilename, this.mergeModeBuffer), + this.mergeMsgBuffer && writeBufferToFile(this.mergeMsgFilename, this.mergeMsgBuffer) + ]) + debug('Done restoring merge state!') + } catch (error) { + debug('Failed restoring merge state with error:') + debug(error) + throw new Error('Merge state could not be restored due to an error!') + } } /** * Create backup stashes, one of everything and one of only staged changes * Staged files are left in the index for running tasks */ - async stashBackup() { - debug('Backing up original state...') + async stashBackup(ctx) { + try { + debug('Backing up original state...') - // the `git stash` clears metadata about a possible git merge - // Manually check and backup if necessary - if (await checkFile(this.mergeHeadFilename)) { + // the `git stash` clears metadata about a possible git merge + // Manually check and backup if necessary await this.backupMergeStatus() - } - // Save stash of entire original state, including unstaged and untracked changes. - // `--keep-index leaves only staged files on disk, for tasks.` - await this.execGit(['stash', 'save', '--quiet', '--include-untracked', '--keep-index', STASH]) + // Save stash of entire original state, including unstaged and untracked changes. + // `--keep-index leaves only staged files on disk, for tasks.` + await this.execGit(['stash', 'save', '--quiet', '--include-untracked', '--keep-index', STASH]) - // Restore meta information about ongoing git merge - if (this.mergeHeadBuffer) { + // Restore meta information about ongoing git merge await this.restoreMergeStatus() - } - - // There is a bug in git =< 2.13.0 where `--keep-index` resurrects deleted files. - // These files should be listed and deleted before proceeding. - await cleanUntrackedFiles(this.execGit) - - // Get a diff of unstaged changes by diffing the saved stash against what's left on disk. - this.unstagedDiff = await this.execGit([ - 'diff', - '--binary', - '--unified=0', - '--no-color', - '--no-ext-diff', - '--patch', - await this.getBackupStash(), - '-R' // Show diff in reverse - ]) - debug('Done backing up original state!') + // There is a bug in git =< 2.13.0 where `--keep-index` resurrects deleted files. + // These files should be listed and deleted before proceeding. + await cleanUntrackedFiles(this.execGit) + + // Get a diff of unstaged changes by diffing the saved stash against what's left on disk. + this.unstagedDiff = await this.execGit([ + 'diff', + '--binary', + '--unified=0', + '--no-color', + '--no-ext-diff', + '--patch', + await this.getBackupStash(), + '-R' // Show diff in reverse + ]) + + debug('Done backing up original state!') + } catch (error) { + handleError(error, ctx) + } } /** @@ -198,11 +210,9 @@ class GitWorkflow { debug('Done restoring original state!') // Restore meta information about ongoing git merge - if (this.mergeHeadBuffer) { - await this.restoreMergeStatus() - } + await this.restoreMergeStatus() } catch (error) { - handleGitLockError(error, ctx) + handleError(error, ctx) } } @@ -216,7 +226,7 @@ class GitWorkflow { await this.execGit(['stash', 'drop', '--quiet', backupStash]) debug('Done dropping backup stash!') } catch (error) { - handleGitLockError(error, ctx) + handleError(error, ctx) } } } diff --git a/lib/runAll.js b/lib/runAll.js index 4edf39324..58c5b570b 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -119,10 +119,9 @@ module.exports = async function runAll( title: chunkCount > 1 ? `Running tasks (chunk ${index + 1}/${chunkCount})...` : 'Running tasks...', task: () => new Listr(chunkListrTasks, { ...listrOptions, concurrent }), - skip: () => { - if (chunkListrTasks.every(task => task.skip())) { - return 'No tasks to run.' - } + skip: ctx => { + if (ctx && ctx.hasErrors) return 'Skipped because of previous git error' + if (chunkListrTasks.every(task => task.skip())) return 'No tasks to run.' return false } }) @@ -148,7 +147,7 @@ module.exports = async function runAll( [ { title: 'Preparing...', - task: () => git.stashBackup() + task: ctx => git.stashBackup(ctx) }, ...listrTasks, { @@ -163,7 +162,9 @@ module.exports = async function runAll( }, { title: 'Cleaning up...', - skip: ctx => ctx.hasGitLockError && 'Skipped because of previous git error', + skip: ctx => + (ctx.hasGitLockError || ctx.hasGitMergeStateError) && + 'Skipped because of previous git error', task: ctx => git.dropBackup(ctx) } ], @@ -173,7 +174,7 @@ module.exports = async function runAll( try { await runner.run() } catch (error) { - if (error.context.hasGitLockError) { + if (error.context.hasGitLockError || error.context.hasGitMergeStateError) { logger.error(` ${symbols.error} ${chalk.red(`lint-staged failed due to a git error. Any lost modifications can be restored from a git stash: diff --git a/test/runAll.unmocked.2.spec.js b/test/runAll.unmocked.2.spec.js index 558871cd6..1bfcaf902 100644 --- a/test/runAll.unmocked.2.spec.js +++ b/test/runAll.unmocked.2.spec.js @@ -54,7 +54,7 @@ const execGit = async args => execGitBase(args, { cwd }) // Execute runAll before git commit to emulate lint-staged const gitCommit = async (options, args = ['-m test']) => { - await runAll({ ...options, cwd, quiet: true }) + await runAll({ quiet: true, ...options, cwd }) await execGit(['commit', ...args]) } @@ -88,8 +88,8 @@ describe('runAll', () => { console = globalConsoleTemp }) - it('Should throw when restoring untracked files fails', async () => { - readBufferFromFile.mockImplementation(async () => [Buffer.from('')]) + it.only('Should throw when restoring untracked files fails', async () => { + readBufferFromFile.mockImplementation(async () => Buffer.from('test')) writeBufferToFile.mockImplementation(async () => Promise.reject('test')) // Stage pretty file @@ -99,11 +99,36 @@ describe('runAll', () => { // Create untracked file await appendFile('test-untracked.js', testJsFilePretty) - try { - // Run lint-staged with `prettier --list-different` and commit pretty file - await gitCommit({ config: { '*.js': 'prettier --list-different' } }) - } catch (error) { - expect(error.message).toEqual('Untracked changes could not be restored due to an error!') - } + // Run lint-staged with `prettier --list-different` + await expect( + gitCommit({ config: { '*.js': 'prettier --list-different' }, quiet: false }) + ).rejects.toThrowErrorMatchingInlineSnapshot(`"Something went wrong"`) + + expect(console.printHistory()).toMatchInlineSnapshot(` + " + LOG Preparing... [started] + LOG Preparing... [failed] + LOG → Merge state could not be restored due to an error! + LOG Running tasks... [started] + LOG Running tasks... [skipped] + LOG → Skipped because of previous git error + LOG Applying modifications... [started] + LOG Applying modifications... [skipped] + LOG → Skipped because of errors from tasks + LOG Reverting to original state... [started] + LOG Reverting to original state... [failed] + LOG → Merge state could not be restored due to an error! + LOG Cleaning up... [started] + LOG Cleaning up... [skipped] + LOG → Skipped because of previous git error + ERROR + × lint-staged failed due to a git error. + Any lost modifications can be restored from a git stash: + + > git stash list + stash@{0}: On master: automatic lint-staged backup + > git stash pop stash@{0} + " + `) }) }) From 30b480925a313f5c2b614eb40eb1a340a6cefae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Tue, 24 Dec 2019 11:41:21 +0200 Subject: [PATCH 62/64] fix: error handling skips dropping backup stash after internal git errors --- lib/gitWorkflow.js | 35 +++++++++++--------------- lib/resolveTaskFn.js | 3 +-- lib/runAll.js | 31 ++++++++++++++++------- test/__snapshots__/runAll.spec.js.snap | 12 ++++----- test/resolveTaskFn.spec.js | 8 +++--- test/runAll.unmocked.2.spec.js | 9 +++---- 6 files changed, 51 insertions(+), 47 deletions(-) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index 0c34391fa..f1d192af3 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -31,19 +31,8 @@ const cleanUntrackedFiles = async execGit => { } } -const isGitLockError = error => - error.message.includes('Another git process seems to be running in this repository') - -const isGitMergeStateError = error => - error.message.includes('Merge state could not be restored due to an error!') - const handleError = (error, ctx) => { - ctx.hasErrors = true - if (isGitLockError(error)) { - ctx.hasGitLockError = true - } else if (isGitMergeStateError(error)) { - ctx.hasGitMergeStateError = true - } + ctx.gitError = true throw error } @@ -66,10 +55,13 @@ class GitWorkflow { /** * Get name of backup stash */ - async getBackupStash() { + async getBackupStash(ctx) { const stashes = await this.execGit(['stash', 'list']) const index = stashes.split('\n').findIndex(line => line.includes(STASH)) - if (index === -1) throw new Error('lint-staged automatic backup is missing!') + if (index === -1) { + ctx.gitGetBackupStashError = true + throw new Error('lint-staged automatic backup is missing!') + } return `stash@{${index}}` } @@ -136,7 +128,7 @@ class GitWorkflow { '--no-color', '--no-ext-diff', '--patch', - await this.getBackupStash(), + await this.getBackupStash(ctx), '-R' // Show diff in reverse ]) @@ -179,8 +171,11 @@ class GitWorkflow { } catch (error2) { debug('Error while restoring unstaged changes using 3-way merge:') debug(error2) - ctx.hasErrors = true - throw new Error('Unstaged changes could not be restored due to a merge conflict!') + ctx.gitApplyModificationsError = true + handleError( + new Error('Unstaged changes could not be restored due to a merge conflict!'), + ctx + ) } } debug('Done restoring unstaged changes!') @@ -190,7 +185,7 @@ class GitWorkflow { // Git will return with error code if the commit doesn't exist // See https://stackoverflow.com/a/52357762 try { - const backupStash = await this.getBackupStash() + const backupStash = await this.getBackupStash(ctx) const output = await this.execGit(['show', '--format=%b', `${backupStash}^3`]) const untrackedDiff = output.replace(/^\n*/, '') // remove empty lines from start of output if (!untrackedDiff) return @@ -204,7 +199,7 @@ class GitWorkflow { async restoreOriginalState(ctx) { try { debug('Restoring original state...') - const backupStash = await this.getBackupStash() + const backupStash = await this.getBackupStash(ctx) await this.execGit(['reset', '--hard', 'HEAD']) await this.execGit(['stash', 'apply', '--quiet', '--index', backupStash]) debug('Done restoring original state!') @@ -222,7 +217,7 @@ class GitWorkflow { async dropBackup(ctx) { try { debug('Dropping backup stash...') - const backupStash = await this.getBackupStash() + const backupStash = await this.getBackupStash(ctx) await this.execGit(['stash', 'drop', '--quiet', backupStash]) debug('Done dropping backup stash!') } catch (error) { diff --git a/lib/resolveTaskFn.js b/lib/resolveTaskFn.js index 39d999629..44c23db89 100644 --- a/lib/resolveTaskFn.js +++ b/lib/resolveTaskFn.js @@ -38,8 +38,7 @@ function throwError(message) { * @returns {Error} */ function makeErr(linter, result, context = {}) { - // Indicate that some linter will fail so we don't update the index with formatting changes - context.hasErrors = true // eslint-disable-line no-param-reassign + context.taskError = true const { stdout, stderr, killed, signal } = result if (killed || (signal && signal !== '')) { return throwError( diff --git a/lib/runAll.js b/lib/runAll.js index 58c5b570b..f803441b1 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -106,6 +106,7 @@ module.exports = async function runAll( exitOnError: true }), skip: () => { + // Skip task when no files matched if (task.fileList.length === 0) { return `No staged files match ${task.pattern}` } @@ -119,8 +120,10 @@ module.exports = async function runAll( title: chunkCount > 1 ? `Running tasks (chunk ${index + 1}/${chunkCount})...` : 'Running tasks...', task: () => new Listr(chunkListrTasks, { ...listrOptions, concurrent }), - skip: ctx => { - if (ctx && ctx.hasErrors) return 'Skipped because of previous git error' + skip: (ctx = {}) => { + // Skip if the first step (backup) failed + if (ctx.gitError) return 'Skipped because of previous git error.' + // Skip chunk when no every task is skipped (due to no matches) if (chunkListrTasks.every(task => task.skip())) return 'No tasks to run.' return false } @@ -143,6 +146,12 @@ module.exports = async function runAll( const git = new GitWorkflow({ gitDir, stagedFileChunks }) + // Running git reset or dropping the backup stash should be skipped + // when there are git errors NOT related to applying unstaged modifications. + // In the latter case, the original state is restored. + const cleanupNotSafe = ctx => + ctx.gitError && !ctx.gitApplyModificationsError && 'Skipped because of previous git error.' + const runner = new Listr( [ { @@ -152,19 +161,21 @@ module.exports = async function runAll( ...listrTasks, { title: 'Applying modifications...', - skip: ctx => ctx.hasErrors && 'Skipped because of errors from tasks', + skip: ctx => { + if (ctx.gitError) return 'Skipped because of previous git error.' + if (ctx.taskError) return 'Skipped because of errors from tasks.' + }, task: ctx => git.applyModifications(ctx) }, { title: 'Reverting to original state...', - enabled: ctx => ctx.hasErrors, + enabled: ctx => ctx.taskError || ctx.gitApplyModificationsError, + skip: cleanupNotSafe, task: ctx => git.restoreOriginalState(ctx) }, { title: 'Cleaning up...', - skip: ctx => - (ctx.hasGitLockError || ctx.hasGitMergeStateError) && - 'Skipped because of previous git error', + skip: cleanupNotSafe, task: ctx => git.dropBackup(ctx) } ], @@ -172,9 +183,11 @@ module.exports = async function runAll( ) try { - await runner.run() + await runner.run({}) } catch (error) { - if (error.context.hasGitLockError || error.context.hasGitMergeStateError) { + // Show help text about manual restore in case of git errors. + // No sense to show this if the backup stash itself is missing. + if (error.context.gitError && !error.context.gitGetBackupStashError) { logger.error(` ${symbols.error} ${chalk.red(`lint-staged failed due to a git error. Any lost modifications can be restored from a git stash: diff --git a/test/__snapshots__/runAll.spec.js.snap b/test/__snapshots__/runAll.spec.js.snap index 3ce7f0e71..29ac4200d 100644 --- a/test/__snapshots__/runAll.spec.js.snap +++ b/test/__snapshots__/runAll.spec.js.snap @@ -35,7 +35,7 @@ LOG → LOG Running tasks... [failed] LOG Applying modifications... [started] LOG Applying modifications... [skipped] -LOG → Skipped because of errors from tasks +LOG → Skipped because of errors from tasks. LOG Reverting to original state... [started] LOG Reverting to original state... [completed] LOG Cleaning up... [started] @@ -45,10 +45,10 @@ LOG { errors: [ { privateMsg: '\\\\n\\\\n\\\\n× echo \\"sample\\" found some errors. Please fix them and try committing again.\\\\n\\\\nLinter finished with error', - context: {hasErrors: true} + context: {taskError: true} } ], - context: {hasErrors: true} + context: {taskError: true} }" `; @@ -66,7 +66,7 @@ LOG → LOG Running tasks... [failed] LOG Applying modifications... [started] LOG Applying modifications... [skipped] -LOG → Skipped because of errors from tasks +LOG → Skipped because of errors from tasks. LOG Reverting to original state... [started] LOG Reverting to original state... [completed] LOG Cleaning up... [started] @@ -76,10 +76,10 @@ LOG { errors: [ { privateMsg: '\\\\n\\\\n\\\\n‼ echo \\"sample\\" was terminated with SIGINT', - context: {hasErrors: true} + context: {taskError: true} } ], - context: {hasErrors: true} + context: {taskError: true} }" `; diff --git a/test/resolveTaskFn.spec.js b/test/resolveTaskFn.spec.js index 56bab7270..bcfefc7dc 100644 --- a/test/resolveTaskFn.spec.js +++ b/test/resolveTaskFn.spec.js @@ -175,15 +175,15 @@ describe('resolveTaskFn', () => { } }) - it('should not set hasErrors on context if no error occur', async () => { + it('should not set taskError on context if no error occur', async () => { expect.assertions(1) const context = {} const taskFn = resolveTaskFn({ ...defaultOpts, command: 'jest', gitDir: '../' }) await taskFn(context) - expect(context.hasErrors).toBeUndefined() + expect(context.taskError).toBeUndefined() }) - it('should set hasErrors on context to true on error', async () => { + it('should set taskError on context to true on error', async () => { execa.mockResolvedValueOnce({ stdout: 'Mock error', stderr: '', @@ -197,7 +197,7 @@ describe('resolveTaskFn', () => { try { await taskFn(context) } catch (err) { - expect(context.hasErrors).toEqual(true) + expect(context.taskError).toEqual(true) } }) }) diff --git a/test/runAll.unmocked.2.spec.js b/test/runAll.unmocked.2.spec.js index 1bfcaf902..47b7805a0 100644 --- a/test/runAll.unmocked.2.spec.js +++ b/test/runAll.unmocked.2.spec.js @@ -111,16 +111,13 @@ describe('runAll', () => { LOG → Merge state could not be restored due to an error! LOG Running tasks... [started] LOG Running tasks... [skipped] - LOG → Skipped because of previous git error + LOG → Skipped because of previous git error. LOG Applying modifications... [started] LOG Applying modifications... [skipped] - LOG → Skipped because of errors from tasks - LOG Reverting to original state... [started] - LOG Reverting to original state... [failed] - LOG → Merge state could not be restored due to an error! + LOG → Skipped because of previous git error. LOG Cleaning up... [started] LOG Cleaning up... [skipped] - LOG → Skipped because of previous git error + LOG → Skipped because of previous git error. ERROR × lint-staged failed due to a git error. Any lost modifications can be restored from a git stash: From 8bdeec067f425150722bd0ee78e310e0992a1444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Wed, 8 Jan 2020 21:53:38 +0200 Subject: [PATCH 63/64] feat: throw error to prevent empty commits unless --allow-empty is used (#762) BREAKING CHANGE: Previously, lint-staged would allow empty commits in the situation where a linter task like "prettier --write" reverts all staged changes automatically. Now the default behaviour is to throw an error with a helpful warning message. The --allow empty option can be used to allow empty commits, or `allowEmpty: true` for the Node.js API. --- README.md | 33 +++++++++++---------- bin/lint-staged | 22 +++++++------- lib/gitWorkflow.js | 13 ++++++-- lib/index.js | 16 ++++++---- lib/runAll.js | 20 ++++++++++--- test/runAll.unmocked.spec.js | 57 ++++++++++++++++++++++++++++++++++++ 6 files changed, 125 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 82f1d653e..781087e03 100644 --- a/README.md +++ b/README.md @@ -42,31 +42,34 @@ See [Releases](https://github.com/okonet/lint-staged/releases) ## Command line flags ```bash -$ npx lint-staged --help +❯ npx lint-staged --help Usage: lint-staged [options] Options: - -V, --version output the version number - -c, --config [path] Path to configuration file - -r, --relative Pass relative filepaths to tasks - -x, --shell Skip parsing of tasks for better shell support - -q, --quiet Disable lint-staged’s own console output - -d, --debug Enable debug mode - -p, --concurrent [parallel tasks] The number of tasks to run concurrently, or false to run tasks sequentially - -h, --help output usage information + -V, --version output the version number + --allow-empty allow empty commits when tasks revert all staged changes (default: false) + -c, --config [path] path to configuration file + -d, --debug print additional debug information (default: false) + -p, --concurrent the number of tasks to run concurrently, or false to run tasks serially (default: true) + -q, --quiet disable lint-staged’s own console output (default: false) + -r, --relative pass relative filepaths to tasks (default: false) + -x, --shell skip parsing of tasks for better shell support (default: false) + -h, --help output usage information ``` +- **`--allow-empty`**: By default lint-stage will exit with an error — aborting the commit — when after running tasks there are no staged modifications. Use this disable this behaviour and create empty git commits. + - This can happen when tasks use libraries like _prettier_ or _eslint_ with automatic code formatting - **`--config [path]`**: This can be used to manually specify the `lint-staged` config file location. However, if the specified file cannot be found, it will error out instead of performing the usual search. You may pass a npm package name for configuration also. -- **`--relative`**: By default filepaths will be passed to the linter tasks as _absolute_. This flag makes them relative to `process.cwd()` (where `lint-staged` runs). -- **`--shell`**: By default linter commands will be parsed for speed and security. This has the side-effect that regular shell scripts might not work as expected. You can skip parsing of commands with this option. -- **`--quiet`**: By default `lint-staged` will print progress status to console while running linters. Use this flag to supress all output, except for linter scripts. -- **`--debug`**: Enabling the debug mode does the following: - - `lint-staged` uses the [debug](https://github.com/visionmedia/debug) module internally to log information about staged files, commands being executed, location of binaries, etc. Debug logs, which are automatically enabled by passing the flag, can also be enabled by setting the environment variable `$DEBUG` to `lint-staged*`. - - Use the [`verbose` renderer](https://github.com/SamVerschueren/listr-verbose-renderer) for `listr`. - **`--concurrent [number | (true/false)]`**: Controls the concurrency of tasks being run by lint-staged. **NOTE**: This does NOT affect the concurrency of subtasks (they will always be run sequentially). Possible values are: - `false`: Run all tasks serially - `true` (default) : _Infinite_ concurrency. Runs as many tasks in parallel as possible. - `{number}`: Run the specified number of tasks in parallel, where `1` is equivalent to `false`. +- **`--debug`**: Enabling the debug mode does the following: + - `lint-staged` uses the [debug](https://github.com/visionmedia/debug) module internally to log information about staged files, commands being executed, location of binaries, etc. Debug logs, which are automatically enabled by passing the flag, can also be enabled by setting the environment variable `$DEBUG` to `lint-staged*`. + - Use the [`verbose` renderer](https://github.com/SamVerschueren/listr-verbose-renderer) for `listr`. +- **`--quiet`**: By default `lint-staged` will print progress status to console while running linters. Use this flag to supress all output, except for linter scripts. +- **`--relative`**: By default filepaths will be passed to the linter tasks as _absolute_. This flag makes them relative to `process.cwd()` (where `lint-staged` runs). +- **`--shell`**: By default linter commands will be parsed for speed and security. This has the side-effect that regular shell scripts might not work as expected. You can skip parsing of commands with this option. ## Configuration diff --git a/bin/lint-staged b/bin/lint-staged index 81f0e6f2c..ae9a11c05 100755 --- a/bin/lint-staged +++ b/bin/lint-staged @@ -29,16 +29,17 @@ const debug = debugLib('lint-staged:bin') cmdline .version(pkg.version) - .option('-c, --config [path]', 'Path to configuration file') - .option('-r, --relative', 'Pass relative filepaths to tasks') - .option('-x, --shell', 'Skip parsing of tasks for better shell support') - .option('-q, --quiet', 'Disable lint-staged’s own console output') - .option('-d, --debug', 'Enable debug mode') + .option('--allow-empty', 'allow empty commits when tasks revert all staged changes', false) + .option('-c, --config [path]', 'path to configuration file') + .option('-d, --debug', 'print additional debug information', false) .option( '-p, --concurrent ', - 'The number of tasks to run concurrently, or false to run tasks serially', + 'the number of tasks to run concurrently, or false to run tasks serially', true - ) + ) + .option('-q, --quiet', 'disable lint-staged’s own console output', false) + .option('-r, --relative', 'pass relative filepaths to tasks', false) + .option('-x, --shell', 'skip parsing of tasks for better shell support', false) .parse(process.argv) if (cmdline.debug) { @@ -66,13 +67,14 @@ const getMaxArgLength = () => { } const options = { + allowEmpty: !!cmdline.allowEmpty, + concurrent: cmdline.concurrent, configPath: cmdline.config, + debug: !!cmdline.debug, maxArgLength: getMaxArgLength() / 2, + quiet: !!cmdline.quiet, relative: !!cmdline.relative, shell: !!cmdline.shell, - quiet: !!cmdline.quiet, - debug: !!cmdline.debug, - concurrent: cmdline.concurrent } debug('Options parsed from command-line:', options) diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js index f1d192af3..6fd01ae82 100644 --- a/lib/gitWorkflow.js +++ b/lib/gitWorkflow.js @@ -37,10 +37,11 @@ const handleError = (error, ctx) => { } class GitWorkflow { - constructor({ gitDir, stagedFileChunks }) { + constructor({ allowEmpty, gitDir, stagedFileChunks }) { this.execGit = (args, options = {}) => execGit(args, { ...options, cwd: gitDir }) this.unstagedDiff = null this.gitDir = gitDir + this.allowEmpty = allowEmpty this.stagedFileChunks = stagedFileChunks /** @@ -143,7 +144,7 @@ class GitWorkflow { * In case of a merge-conflict retry with 3-way merge. */ async applyModifications(ctx) { - let modifiedFiles = await this.execGit(['ls-files', '--modified']) + const modifiedFiles = await this.execGit(['ls-files', '--modified']) if (modifiedFiles) { debug('Detected files modified by tasks:') debug(modifiedFiles) @@ -156,6 +157,14 @@ class GitWorkflow { debug('Done adding files to index!') } + const modifiedFilesAfterAdd = await this.execGit(['status', '--porcelain']) + if (!modifiedFilesAfterAdd && !this.allowEmpty) { + // Tasks reverted all staged changes and the commit would be empty + // Throw error to stop commit unless `--allow-empty` was used + ctx.gitApplyEmptyCommit = true + handleError(new Error('Prevented an empty git commit!'), ctx) + } + if (this.unstagedDiff) { debug('Restoring unstaged changes...') try { diff --git a/lib/index.js b/lib/index.js index a75578a1b..b33b1c7af 100644 --- a/lib/index.js +++ b/lib/index.js @@ -42,8 +42,10 @@ function loadConfig(configPath) { * Root lint-staged function that is called from `bin/lint-staged`. * * @param {object} options - * @param {string} [options.configPath] - Path to configuration file + * @param {Object} [options.allowEmpty] - Allow empty commits when tasks revert all staged changes + * @param {boolean | number} [options.concurrent] - The number of tasks to run concurrently, or false to run tasks serially * @param {object} [options.config] - Object with configuration for programmatic API + * @param {string} [options.configPath] - Path to configuration file * @param {number} [options.maxArgLength] - Maximum argument string length * @param {boolean} [options.relative] - Pass relative filepaths to tasks * @param {boolean} [options.shell] - Skip parsing of tasks for better shell support @@ -56,14 +58,15 @@ function loadConfig(configPath) { */ module.exports = async function lintStaged( { - configPath, + allowEmpty = false, + concurrent = true, config: configObject, + configPath, maxArgLength, relative = false, shell = false, quiet = false, - debug = false, - concurrent = true + debug = false } = {}, logger = console ) { @@ -90,7 +93,10 @@ module.exports = async function lintStaged( } try { - await runAll({ config, maxArgLength, relative, shell, quiet, debug, concurrent }, logger) + await runAll( + { allowEmpty, concurrent, config, debug, maxArgLength, quiet, relative, shell }, + logger + ) debugLog('tasks were executed successfully!') return true } catch (runAllError) { diff --git a/lib/runAll.js b/lib/runAll.js index f803441b1..3203fc1d1 100644 --- a/lib/runAll.js +++ b/lib/runAll.js @@ -19,6 +19,7 @@ const debugLog = require('debug')('lint-staged:run') * Executes all tasks and either resolves or rejects the promise * * @param {object} options + * @param {Object} [options.allowEmpty] - Allow empty commits when tasks revert all staged changes * @param {Object} [options.config] - Task configuration * @param {Object} [options.cwd] - Current working directory * @param {number} [options.maxArgLength] - Maximum argument string length @@ -32,6 +33,7 @@ const debugLog = require('debug')('lint-staged:run') */ module.exports = async function runAll( { + allowEmpty = false, config, cwd = process.cwd(), debug = false, @@ -144,13 +146,16 @@ module.exports = async function runAll( return 'No tasks to run.' } - const git = new GitWorkflow({ gitDir, stagedFileChunks }) + const git = new GitWorkflow({ allowEmpty, gitDir, stagedFileChunks }) // Running git reset or dropping the backup stash should be skipped // when there are git errors NOT related to applying unstaged modifications. // In the latter case, the original state is restored. const cleanupNotSafe = ctx => - ctx.gitError && !ctx.gitApplyModificationsError && 'Skipped because of previous git error.' + ctx.gitError && + !ctx.gitApplyEmptyCommit && + !ctx.gitApplyModificationsError && + 'Skipped because of previous git error.' const runner = new Listr( [ @@ -169,7 +174,7 @@ module.exports = async function runAll( }, { title: 'Reverting to original state...', - enabled: ctx => ctx.taskError || ctx.gitApplyModificationsError, + enabled: ctx => ctx.taskError || ctx.gitApplyEmptyCommit || ctx.gitApplyModificationsError, skip: cleanupNotSafe, task: ctx => git.restoreOriginalState(ctx) }, @@ -185,9 +190,16 @@ module.exports = async function runAll( try { await runner.run({}) } catch (error) { + if (error.context.gitApplyEmptyCommit) { + logger.warn(` + ${symbols.warning} ${chalk.yellow(`lint-staged prevented an empty git commit. + Use the --allow-empty option to continue, or check your task configuration`)} +`) + } + // Show help text about manual restore in case of git errors. // No sense to show this if the backup stash itself is missing. - if (error.context.gitError && !error.context.gitGetBackupStashError) { + else if (error.context.gitError && !error.context.gitGetBackupStashError) { logger.error(` ${symbols.error} ${chalk.red(`lint-staged failed due to a git error. Any lost modifications can be restored from a git stash: diff --git a/test/runAll.unmocked.spec.js b/test/runAll.unmocked.spec.js index bb37f12dd..eb730494e 100644 --- a/test/runAll.unmocked.spec.js +++ b/test/runAll.unmocked.spec.js @@ -678,4 +678,61 @@ describe('runAll', () => { LOG → lint-staged automatic backup is missing!" `) }) + + it('should fail when task reverts staged changes, to prevent an empty git commit', async () => { + // Create and commit a pretty file without running lint-staged + // This way the file will be available for the next step + await appendFile('test.js', testJsFilePretty) + await execGit(['add', 'test.js']) + await execGit(['commit', '-m committed pretty file']) + + // Edit file to be ugly + await fs.remove(path.resolve(cwd, 'test.js')) + await appendFile('test.js', testJsFileUgly) + await execGit(['add', 'test.js']) + + // Run lint-staged with prettier --write to automatically fix the file + // Since prettier reverts all changes, the commit should fail + await expect( + gitCommit({ config: { '*.js': 'prettier --write' } }) + ).rejects.toThrowErrorMatchingInlineSnapshot(`"Something went wrong"`) + + expect(console.printHistory()).toMatchInlineSnapshot(` + " + WARN + ‼ lint-staged prevented an empty git commit. + Use the --allow-empty option to continue, or check your task configuration + " + `) + + // Something was wrong so the repo is returned to original state + expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('2') + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('committed pretty file') + expect(await readFile('test.js')).toEqual(testJsFileUgly) + }) + + it('should create commit when task reverts staged changed and --allow-empty is used', async () => { + // Create and commit a pretty file without running lint-staged + // This way the file will be available for the next step + await appendFile('test.js', testJsFilePretty) + await execGit(['add', 'test.js']) + await execGit(['commit', '-m committed pretty file']) + + // Edit file to be ugly + await writeFile('test.js', testJsFileUgly) + await execGit(['add', 'test.js']) + + // Run lint-staged with prettier --write to automatically fix the file + // Here we also pass '--allow-empty' to gitCommit because this part is not the full lint-staged + await gitCommit({ allowEmpty: true, config: { '*.js': 'prettier --write' } }, [ + '-m test', + '--allow-empty' + ]) + + // Nothing was wrong so the empty commit is created + expect(await execGit(['rev-list', '--count', 'HEAD'])).toEqual('3') + expect(await execGit(['log', '-1', '--pretty=%B'])).toMatch('test') + expect(await execGit(['diff', '-1'])).toEqual('') + expect(await readFile('test.js')).toEqual(testJsFilePretty) + }) }) From f9e128d7e9393ba685fda16f49dceda16d4c540f Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Sun, 19 Jan 2020 17:52:30 +0100 Subject: [PATCH 64/64] docs: Improve config section documentation --- README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 8f25eb5c0..294ba0499 100644 --- a/README.md +++ b/README.md @@ -57,18 +57,17 @@ Options: -h, --help output usage information ``` -- **`--allow-empty`**: By default lint-stage will exit with an error — aborting the commit — when after running tasks there are no staged modifications. Use this disable this behaviour and create empty git commits. - - This can happen when tasks use libraries like _prettier_ or _eslint_ with automatic code formatting -- **`--config [path]`**: This can be used to manually specify the `lint-staged` config file location. However, if the specified file cannot be found, it will error out instead of performing the usual search. You may pass a npm package name for configuration also. -- **`--debug`**: Enabling the debug mode does the following: - - `lint-staged` uses the [debug](https://github.com/visionmedia/debug) module internally to log information about staged files, commands being executed, location of binaries, etc. Debug logs, which are automatically enabled by passing the flag, can also be enabled by setting the environment variable `$DEBUG` to `lint-staged*`. - - Use the [`verbose` renderer](https://github.com/SamVerschueren/listr-verbose-renderer) for `listr`; this causes serial, uncoloured output to the terminal, instead of the default (beautified, dynamic) output. +- **`--allow-empty`**: By default, when after running tasks there are no staged modifications, lint-staged will exit with an error and abort the commit. Use this flag to allow creating empty git commits. +- **`--config [path]`**: Manually specify a path to a config file or npm package name. Note: when used, lint-staged won't perform the config file search and print an error if the specified file cannot be found. +- **`--debug`**: Run in debug mode. When set, it does the following: + - uses [debug](https://github.com/visionmedia/debug) internally to log additional information about staged files, commands being executed, location of binaries, etc. Debug logs, which are automatically enabled by passing the flag, can also be enabled by setting the environment variable `$DEBUG` to `lint-staged*`. + - uses [`verbose` renderer](https://github.com/SamVerschueren/listr-verbose-renderer) for `listr`; this causes serial, uncoloured output to the terminal, instead of the default (beautified, dynamic) output. - **`--concurrent [number | (true/false)]`**: Controls the concurrency of tasks being run by lint-staged. **NOTE**: This does NOT affect the concurrency of subtasks (they will always be run sequentially). Possible values are: - `false`: Run all tasks serially - `true` (default) : _Infinite_ concurrency. Runs as many tasks in parallel as possible. - `{number}`: Run the specified number of tasks in parallel, where `1` is equivalent to `false`. -- **`--quiet`**: By default `lint-staged` will print progress status to console while running linters. Use this flag to supress all output, except for linter scripts. -- **`--relative`**: By default filepaths will be passed to the linter tasks as _absolute_. This flag makes them relative to `process.cwd()` (where `lint-staged` runs). +- **`--quiet`**: Supress all CLI output, except from tasks. +- **`--relative`**: Pass filepaths relative to `process.cwd()` (where `lint-staged` runs) to tasks. Default is `false`. - **`--shell`**: By default linter commands will be parsed for speed and security. This has the side-effect that regular shell scripts might not work as expected. You can skip parsing of commands with this option. ## Configuration