From 86f41ee659e2b62c88ac4aa8885aebf7d4bc4c10 Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Mon, 20 Jan 2020 11:02:16 +0100 Subject: [PATCH] [v2.0.0] Bundle chokidar (#3331) * Create a separate chunk for watch mode via a dynamic import * Bundle chokidar * Handle conditional fsevents import * Only run tests on Node 10 and 12 as we want to do this anyway and chokidar depends on utils.promisify * Improve chunking * Refactor and simplify watcher * Make watcher a proper parameter * Only unwatch and watch on Linux systems * No longer run JS files through TypeScript for improved bundling performance --- .github/workflows/node-windows.yml | 2 +- LICENSE.md | 205 ++ build-plugins/add-bin-shebang.js | 14 + build-plugins/conditional-fsevents-import.js | 25 + build-plugins/fix-acorn-esm-import.js | 23 + build-plugins/generate-license-file.js | 57 + docs/999-big-list-of-options.md | 8 +- package-lock.json | 1706 +------------ package.json | 6 +- rollup.config.js | 131 +- scripts/test-package.js | 25 +- src/Graph.ts | 2 +- src/browser-entry.ts | 2 +- src/node-entry.ts | 4 +- src/rollup/{index.ts => rollup.ts} | 17 +- src/rollup/types.d.ts | 6 +- src/utils/PluginContext.ts | 2 +- src/utils/PluginDriver.ts | 4 +- src/watch/chokidar.ts | 12 - src/watch/fileWatcher.ts | 65 + src/watch/fileWatchers.ts | 117 - src/watch/fsevents-importer.ts | 18 + src/watch/watch-proxy.ts | 23 + src/watch/{index.ts => watch.ts} | 162 +- test/function/index.js | 6 +- test/hooks/index.js | 76 +- test/watch/index.js | 2313 +++++++++--------- 27 files changed, 1868 insertions(+), 3163 deletions(-) create mode 100644 build-plugins/add-bin-shebang.js create mode 100644 build-plugins/conditional-fsevents-import.js create mode 100644 build-plugins/fix-acorn-esm-import.js create mode 100644 build-plugins/generate-license-file.js rename src/rollup/{index.ts => rollup.ts} (98%) delete mode 100644 src/watch/chokidar.ts create mode 100644 src/watch/fileWatcher.ts delete mode 100644 src/watch/fileWatchers.ts create mode 100644 src/watch/fsevents-importer.ts create mode 100644 src/watch/watch-proxy.ts rename src/watch/{index.ts => watch.ts} (57%) diff --git a/.github/workflows/node-windows.yml b/.github/workflows/node-windows.yml index 57a7424ec66..62c8e5ca682 100644 --- a/.github/workflows/node-windows.yml +++ b/.github/workflows/node-windows.yml @@ -20,7 +20,7 @@ jobs: uses: actions/setup-node@v1 with: node-version: ${{ matrix.node }} - - name: Install dependencies + - name: Install dependencies run: npm ci --ignore-scripts - name: Run tests run: npm test diff --git a/LICENSE.md b/LICENSE.md index 964b6f61724..082a6dda1dc 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -109,6 +109,36 @@ Repository: https://github.com/acornjs/acorn.git --------------------------------------- +## anymatch +License: ISC +By: Elan Shanker +Repository: https://github.com/micromatch/anymatch + +> The ISC License +> +> Copyright (c) 2019 Elan Shanker, Paul Miller (https://paulmillr.com) +> +> Permission to use, copy, modify, and/or distribute this software for any +> purpose with or without fee is hereby granted, provided that the above +> copyright notice and this permission notice appear in all copies. +> +> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +> WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +> MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +> ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +> WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +> ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +> IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +--------------------------------------- + +## binary-extensions +License: MIT +By: Sindre Sorhus +Repository: sindresorhus/binary-extensions + +--------------------------------------- + ## braces License: MIT By: Jon Schlinkert, Brian Woodward, Elan Shanker, Eugene Sharygin, hemanth.hm @@ -138,6 +168,35 @@ Repository: micromatch/braces --------------------------------------- +## chokidar +License: MIT +By: Paul Miller, Elan Shanker +Repository: git+https://github.com/paulmillr/chokidar.git + +> The MIT License (MIT) +> +> Copyright (c) 2012-2019 Paul Miller (https://paulmillr.com), Elan Shanker +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the “Software”), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in +> all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +> THE SOFTWARE. + +--------------------------------------- + ## date-time License: MIT By: Sindre Sorhus @@ -174,6 +233,29 @@ Repository: jonschlinkert/fill-range --------------------------------------- +## glob-parent +License: ISC +By: Gulp Team, Elan Shanker, Blaine Bublitz +Repository: gulpjs/glob-parent + +> The ISC License +> +> Copyright (c) 2015, 2019 Elan Shanker +> +> Permission to use, copy, modify, and/or distribute this software for any +> purpose with or without fee is hereby granted, provided that the above +> copyright notice and this permission notice appear in all copies. +> +> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +> WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +> MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +> ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +> WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +> ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +> IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +--------------------------------------- + ## hash.js License: MIT By: Fedor Indutny @@ -203,6 +285,71 @@ Repository: git://github.com/isaacs/inherits --------------------------------------- +## is-binary-path +License: MIT +By: Sindre Sorhus +Repository: sindresorhus/is-binary-path + +--------------------------------------- + +## is-extglob +License: MIT +By: Jon Schlinkert +Repository: jonschlinkert/is-extglob + +> The MIT License (MIT) +> +> Copyright (c) 2014-2016, Jon Schlinkert +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in +> all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +> THE SOFTWARE. + +--------------------------------------- + +## is-glob +License: MIT +By: Jon Schlinkert, Brian Woodward, Daniel Perez +Repository: micromatch/is-glob + +> The MIT License (MIT) +> +> Copyright (c) 2014-2017, Jon Schlinkert. +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in +> all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +> THE SOFTWARE. + +--------------------------------------- + ## is-number License: MIT By: Jon Schlinkert, Olsten Larck, Rouven Weßling @@ -336,6 +483,35 @@ Repository: git://github.com/substack/minimist.git --------------------------------------- +## normalize-path +License: MIT +By: Jon Schlinkert, Blaine Bublitz +Repository: jonschlinkert/normalize-path + +> The MIT License (MIT) +> +> Copyright (c) 2014-2018, Jon Schlinkert. +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in +> all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +> THE SOFTWARE. + +--------------------------------------- + ## parse-ms License: MIT By: Sindre Sorhus @@ -386,6 +562,35 @@ Repository: sindresorhus/pretty-ms --------------------------------------- +## readdirp +License: MIT +By: Thorsten Lorenz, Paul Miller +Repository: git://github.com/paulmillr/readdirp.git + +> MIT License +> +> Copyright (c) 2012-2019 Thorsten Lorenz, Paul Miller (https://paulmillr.com) +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in all +> copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +> SOFTWARE. + +--------------------------------------- + ## require-relative License: MIT By: Valerio Proietti diff --git a/build-plugins/add-bin-shebang.js b/build-plugins/add-bin-shebang.js new file mode 100644 index 00000000000..7078239ce4b --- /dev/null +++ b/build-plugins/add-bin-shebang.js @@ -0,0 +1,14 @@ +import MagicString from 'magic-string'; + +export default function addBinShebang() { + return { + name: 'add-bin-shebang', + renderChunk(code, chunkInfo) { + if (chunkInfo.fileName === 'bin/rollup') { + const magicString = new MagicString(code); + magicString.prepend('#!/usr/bin/env node\n\n'); + return { code: magicString.toString(), map: magicString.generateMap({ hires: true }) }; + } + } + }; +} diff --git a/build-plugins/conditional-fsevents-import.js b/build-plugins/conditional-fsevents-import.js new file mode 100644 index 00000000000..ddab24bd9ca --- /dev/null +++ b/build-plugins/conditional-fsevents-import.js @@ -0,0 +1,25 @@ +import MagicString from 'magic-string'; + +const FSEVENTS_REQUIRE = "require('fsevents')"; +const REPLACEMENT = "require('../../../src/watch/fsevents-importer').getFsEvents()"; + +export default function conditionalFsEventsImport() { + return { + name: 'conditional-fs-events-import', + transform(code, id) { + if (id.endsWith('fsevents-handler.js')) { + const requireStatementPos = code.indexOf(FSEVENTS_REQUIRE); + if (requireStatementPos < 0) { + throw new Error(`Could not find expected fsevents import "${FSEVENTS_REQUIRE}"`); + } + const magicString = new MagicString(code); + magicString.overwrite( + requireStatementPos, + requireStatementPos + FSEVENTS_REQUIRE.length, + REPLACEMENT + ); + return { code: magicString.toString(), map: magicString.generateMap({ hires: true }) }; + } + } + }; +} diff --git a/build-plugins/fix-acorn-esm-import.js b/build-plugins/fix-acorn-esm-import.js new file mode 100644 index 00000000000..bdb5284ce98 --- /dev/null +++ b/build-plugins/fix-acorn-esm-import.js @@ -0,0 +1,23 @@ +const expectedAcornImport = "import acorn, { Parser } from 'acorn';"; +const newAcornImport = "import * as acorn from 'acorn';\nimport { Parser } from 'acorn';"; + +// by default, rollup-plugin-commonjs will translate require statements as default imports +// which can cause issues for secondary tools that use the ESM version of acorn +export default function fixAcornEsmImport() { + let found = false; + + return { + name: 'fix-acorn-esm-import', + renderChunk(code) { + return code.replace(expectedAcornImport, () => { + found = true; + return newAcornImport; + }); + }, + writeBundle() { + if (!found) { + this.error('Could not find expected acorn import, please examine generated code.'); + } + } + }; +} diff --git a/build-plugins/generate-license-file.js b/build-plugins/generate-license-file.js new file mode 100644 index 00000000000..286bd2a9926 --- /dev/null +++ b/build-plugins/generate-license-file.js @@ -0,0 +1,57 @@ +import fs from 'fs'; + +export default function generateLicenseFile(dependencies) { + const coreLicense = fs.readFileSync('LICENSE-CORE.md'); + const licenses = new Set(); + const dependencyLicenseTexts = dependencies + .sort(({ name: nameA }, { name: nameB }) => (nameA > nameB ? 1 : -1)) + .map(({ name, license, licenseText, author, maintainers, contributors, repository }) => { + let text = `## ${name}\n`; + if (license) { + text += `License: ${license}\n`; + } + const names = new Set(); + if (author && author.name) { + names.add(author.name); + } + for (const person of maintainers.concat(contributors)) { + if (person && person.name) { + names.add(person.name); + } + } + if (names.size > 0) { + text += `By: ${Array.from(names).join(', ')}\n`; + } + if (repository) { + text += `Repository: ${repository.url || repository}\n`; + } + if (licenseText) { + text += + '\n' + + licenseText + .trim() + .replace(/(\r\n|\r)/gm, '\n') + .split('\n') + .map(line => `> ${line}`) + .join('\n') + + '\n'; + } + licenses.add(license); + return text; + }) + .join('\n---------------------------------------\n\n'); + const licenseText = + `# Rollup core license\n` + + `Rollup is released under the MIT license:\n\n` + + coreLicense + + `\n# Licenses of bundled dependencies\n` + + `The published Rollup artifact additionally contains code with the following licenses:\n` + + `${Array.from(licenses).join(', ')}\n\n` + + `# Bundled dependencies:\n` + + dependencyLicenseTexts; + const existingLicenseText = fs.readFileSync('LICENSE.md', 'utf8'); + if (existingLicenseText !== licenseText) { + fs.writeFileSync('LICENSE.md', licenseText); + console.warn('LICENSE.md updated. You should commit the updated file.'); + } +} diff --git a/docs/999-big-list-of-options.md b/docs/999-big-list-of-options.md index d584349b690..410e9afe4af 100755 --- a/docs/999-big-list-of-options.md +++ b/docs/999-big-list-of-options.md @@ -1092,13 +1092,9 @@ For each key, the first number represents the elapsed time while the second repr These options only take effect when running Rollup with the `--watch` flag, or using `rollup.watch`. #### watch.chokidar -Type: `boolean | ChokidarOptions`
-CLI: `--watch.chokidar`/`--no-watch.chokidar`
-Default: `false` - -A `Boolean` indicating that [chokidar](https://github.com/paulmillr/chokidar) should be used instead of the built-in `fs.watch`, or an `Object` of options that are passed through to chokidar. +Type: `ChokidarOptions`
-You must install chokidar separately if you wish to use it. +An optional object of watch options that will be passed to the bundled [chokidar](https://github.com/paulmillr/chokidar) instance. See the [chokidar documentation](https://github.com/paulmillr/chokidar#api) to find out what options are available. #### watch.clearScreen Type: `boolean`
diff --git a/package-lock.json b/package-lock.json index f43b3ea6863..6e132f795df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -340,15 +340,6 @@ "integrity": "sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw==", "dev": true }, - "@types/chokidar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@types/chokidar/-/chokidar-2.1.3.tgz", - "integrity": "sha512-6qK3xoLLAhQVTucQGHTySwOVA1crHRXnJeLwqK6KIFkkKa2aoMFXh+WEi8PotxDtvN6MQJLyYN9ag9P6NLV81w==", - "dev": true, - "requires": { - "chokidar": "*" - } - }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -437,13 +428,6 @@ "@types/node": "*" } }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true, - "optional": true - }, "acorn": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", @@ -547,45 +531,13 @@ "dev": true }, "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", "dev": true, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, "append-transform": { @@ -597,30 +549,12 @@ "default-require-extensions": "^3.0.0" } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, - "optional": true - }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -636,24 +570,6 @@ "integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=", "dev": true }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", @@ -677,12 +593,6 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, "array.prototype.flat": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", @@ -693,132 +603,41 @@ "es-abstract": "^1.17.0-next.1" } }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" } }, "browser-stdout": { @@ -859,12 +678,6 @@ "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } - }, - "os-homedir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-2.0.0.tgz", - "integrity": "sha512-saRNz0DSC5C/I++gFIaJTXoFJMRwiP5zHar5vV3xQ2TkgEw6hDCcU5F272JjUylpiVgBrZNQHnfjkLabTfb92Q==", - "dev": true } } }, @@ -880,23 +693,6 @@ "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", "dev": true }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, "caching-transform": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", @@ -965,61 +761,27 @@ "dev": true }, "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", + "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", "dev": true, "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.3.0" } }, - "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", - "dev": true, - "optional": true - }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -1200,16 +962,6 @@ "urlgrey": "^0.4.4" } }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1243,23 +995,11 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "console-group": { "version": "0.3.3", @@ -1282,24 +1022,12 @@ "safe-buffer": "~5.1.1" } }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, "core-js": { "version": "3.6.4", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==", "dev": true }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, "cosmiconfig": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", @@ -1389,12 +1117,6 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -1439,47 +1161,6 @@ "object-keys": "^1.0.12" } }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, "del": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz", @@ -1513,20 +1194,6 @@ } } }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, - "optional": true - }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", @@ -1738,15 +1405,6 @@ "ms": "^2.1.1" } }, - "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, "globals": { "version": "12.3.0", "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz", @@ -1995,62 +1653,6 @@ } } }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, "external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", @@ -2062,71 +1664,6 @@ "tmp": "^0.0.33" } }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", @@ -2144,17 +1681,6 @@ "glob-parent": "^5.1.0", "merge2": "^1.3.0", "micromatch": "^4.0.2" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } } }, "fast-json-stable-stringify": { @@ -2197,26 +1723,12 @@ } }, "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "to-regex-range": "^5.0.1" } }, "find-cache-dir": { @@ -2319,14 +1831,6 @@ "dev": true, "requires": { "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } } }, "flat-cache": { @@ -2357,12 +1861,6 @@ "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "dev": true }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, "foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -2416,15 +1914,6 @@ } } }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, "fromentries": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.0.tgz", @@ -2433,100 +1922,27 @@ }, "fs-extra": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-minipass": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - } + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -2539,64 +1955,6 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -2624,16 +1982,11 @@ "pump": "^3.0.0" } }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, "glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2644,24 +1997,12 @@ } }, "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", "dev": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } + "is-glob": "^4.0.1" } }, "globals": { @@ -2750,45 +2091,6 @@ "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", "dev": true }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "hash.js": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", @@ -3067,6 +2369,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -3075,7 +2378,8 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true }, "ini": { "version": "1.3.5", @@ -3186,26 +2490,6 @@ "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", "dev": true }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -3213,18 +2497,18 @@ "dev": true }, "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { - "binary-extensions": "^1.0.0" + "binary-extensions": "^2.0.0" } }, "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", "dev": true }, "is-callable": { @@ -3233,63 +2517,18 @@ "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", "dev": true }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", "dev": true }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, "is-directory": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "dev": true }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3318,24 +2557,10 @@ "dev": true }, "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true }, "is-obj": { "version": "1.0.1", @@ -3364,15 +2589,6 @@ "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", "dev": true }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", @@ -3456,12 +2672,6 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, "istanbul-lib-coverage": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", @@ -3724,12 +2934,6 @@ "graceful-fs": "^4.1.6" } }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -4202,21 +3406,6 @@ } } }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, "markdown-it": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", @@ -4319,41 +3508,6 @@ "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" - }, - "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } } }, "mimic-fn": { @@ -4372,6 +3526,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -4382,48 +3537,6 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, - "minipass": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", - "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", - "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", @@ -4644,69 +3757,12 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "needle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.3.0.tgz", - "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", - "dev": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "optional": true - } - } - }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -4737,25 +3793,6 @@ "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", "dev": true }, - "node-pre-gyp": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz", - "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, "node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -4765,17 +3802,6 @@ "process-on-spawn": "^1.0.0" } }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -4796,33 +3822,15 @@ "requires": { "path-parse": "^1.0.6" } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-bundled": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", - "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz", - "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" + } } }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -4840,23 +3848,11 @@ } } }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true }, "nyc": { "version": "15.0.0", @@ -4986,37 +3982,6 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "object-inspect": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", @@ -5029,15 +3994,6 @@ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, "object.assign": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", @@ -5066,15 +4022,6 @@ } } }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, "object.values": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", @@ -5091,6 +4038,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } @@ -5125,11 +4073,10 @@ } }, "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, - "optional": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-2.0.0.tgz", + "integrity": "sha512-saRNz0DSC5C/I++gFIaJTXoFJMRwiP5zHar5vV3xQ2TkgEw6hDCcU5F272JjUylpiVgBrZNQHnfjkLabTfb92Q==", + "dev": true }, "os-tmpdir": { "version": "1.0.2", @@ -5137,17 +4084,6 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, "p-finally": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", @@ -5223,18 +4159,6 @@ "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", "dev": true }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -5244,7 +4168,8 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "path-key": { "version": "2.0.1", @@ -5297,12 +4222,6 @@ "semver-compare": "^1.0.0" } }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -5330,12 +4249,6 @@ "parse-ms": "^2.1.0" } }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, "process-on-spawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", @@ -5414,53 +4327,13 @@ "read-pkg": "^2.0.0" } }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", + "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } + "picomatch": "^2.0.7" } }, "rechoir": { @@ -5493,16 +4366,6 @@ "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", "dev": true }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", @@ -5547,24 +4410,6 @@ "es6-error": "^4.0.1" } }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -5610,12 +4455,6 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, "restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -5626,12 +4465,6 @@ "signal-exit": "^3.0.2" } }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -5895,15 +4728,6 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -5921,13 +4745,6 @@ "rimraf": "^2.5.2" } }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "optional": true - }, "semver": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", @@ -5952,29 +4769,6 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -6035,138 +4829,12 @@ "is-fullwidth-code-point": "^2.0.0" } }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, "source-map-support": { "version": "0.5.16", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", @@ -6177,12 +4845,6 @@ "source-map": "^0.6.0" } }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, "sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", @@ -6292,42 +4954,12 @@ "spdx-ranges": "^2.0.0" } }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, "string-argv": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", @@ -6364,15 +4996,6 @@ "function-bind": "^1.1.1" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, "stringify-object": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", @@ -6472,22 +5095,6 @@ } } }, - "tar": { - "version": "4.4.8", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", - "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, "teeny-request": { "version": "3.11.3", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", @@ -6585,46 +5192,13 @@ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "is-number": "^7.0.0" } }, "tslib": { @@ -6747,70 +5321,12 @@ "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", "dev": true }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, - "upath": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", - "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", - "dev": true - }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -6820,12 +5336,6 @@ "punycode": "^2.1.0" } }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, "url-parse": { "version": "1.4.7", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", @@ -6842,18 +5352,6 @@ "integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=", "dev": true }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", @@ -6925,7 +5423,8 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "write": { "version": "1.0.3", @@ -6954,13 +5453,6 @@ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true }, - "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true, - "optional": true - }, "yaml": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz", diff --git a/package.json b/package.json index 72b6c8a7a19..ec495db1947 100644 --- a/package.json +++ b/package.json @@ -64,8 +64,10 @@ "@types/node": "*", "acorn": "^7.1.0" }, + "optionalDependencies": { + "fsevents": "~2.1.2" + }, "devDependencies": { - "@types/chokidar": "^2.1.3", "@types/micromatch": "^4.0.0", "@types/minimist": "^1.2.0", "acorn-export-ns-from": "^0.1.0", @@ -73,7 +75,7 @@ "acorn-jsx": "^5.1.0", "acorn-walk": "^7.0.0", "buble": "^0.19.8", - "chokidar": "^2.1.8", + "chokidar": "^3.3.1", "codecov": "^3.6.1", "console-group": "^0.3.3", "core-js": "^3.6.4", diff --git a/rollup.config.js b/rollup.config.js index 74cc004878c..c7def536965 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,5 +1,4 @@ import fs from 'fs'; -import MagicString from 'magic-string'; import path from 'path'; import alias from 'rollup-plugin-alias'; import commonjs from 'rollup-plugin-commonjs'; @@ -9,6 +8,10 @@ import resolve from 'rollup-plugin-node-resolve'; import { string } from 'rollup-plugin-string'; import { terser } from 'rollup-plugin-terser'; import typescript from 'rollup-plugin-typescript'; +import addBinShebang from './build-plugins/add-bin-shebang'; +import conditionalFsEventsImport from './build-plugins/conditional-fsevents-import'; +import fixAcornEsmImport from './build-plugins/fix-acorn-esm-import'; +import generateLicenseFile from './build-plugins/generate-license-file'; import pkg from './package.json'; const commitHash = (function() { @@ -42,99 +45,6 @@ const onwarn = warning => { throw new Error(warning.message); }; -function addSheBang() { - return { - name: 'add-bin-shebang', - renderChunk(code, chunkInfo) { - if (chunkInfo.fileName === 'bin/rollup') { - const magicString = new MagicString(code); - magicString.prepend('#!/usr/bin/env node\n\n'); - return { code: magicString.toString(), map: magicString.generateMap({ hires: true }) }; - } - } - }; -} - -function generateLicenseFile(dependencies) { - const coreLicense = fs.readFileSync('LICENSE-CORE.md'); - const licenses = new Set(); - const dependencyLicenseTexts = dependencies - .sort(({ name: nameA }, { name: nameB }) => (nameA > nameB ? 1 : -1)) - .map(({ name, license, licenseText, author, maintainers, contributors, repository }) => { - let text = `## ${name}\n`; - if (license) { - text += `License: ${license}\n`; - } - const names = new Set(); - if (author && author.name) { - names.add(author.name); - } - for (const person of maintainers.concat(contributors)) { - if (person && person.name) { - names.add(person.name); - } - } - if (names.size > 0) { - text += `By: ${Array.from(names).join(', ')}\n`; - } - if (repository) { - text += `Repository: ${repository.url || repository}\n`; - } - if (licenseText) { - text += - '\n' + - licenseText - .trim() - .replace(/(\r\n|\r)/gm, '\n') - .split('\n') - .map(line => `> ${line}`) - .join('\n') + - '\n'; - } - licenses.add(license); - return text; - }) - .join('\n---------------------------------------\n\n'); - const licenseText = - `# Rollup core license\n` + - `Rollup is released under the MIT license:\n\n` + - coreLicense + - `\n# Licenses of bundled dependencies\n` + - `The published Rollup artifact additionally contains code with the following licenses:\n` + - `${Array.from(licenses).join(', ')}\n\n` + - `# Bundled dependencies:\n` + - dependencyLicenseTexts; - const existingLicenseText = fs.readFileSync('LICENSE.md', 'utf8'); - if (existingLicenseText !== licenseText) { - fs.writeFileSync('LICENSE.md', licenseText); - console.warn('LICENSE.md updated. You should commit the updated file.'); - } -} - -const expectedAcornImport = "import acorn__default, { Parser } from 'acorn';"; -const newAcornImport = "import * as acorn__default from 'acorn';\nimport { Parser } from 'acorn';"; - -// by default, rollup-plugin-commonjs will translate require statements as default imports -// which can cause issues for secondary tools that use the ESM version of acorn -function fixAcornEsmImport() { - return { - name: 'fix-acorn-esm-import', - renderChunk(code) { - let found = false; - const fixedCode = code.replace(expectedAcornImport, () => { - found = true; - return newAcornImport; - }); - if (!found) { - this.error( - 'Could not find expected acorn import, please deactive this plugin and examine generated code.' - ); - } - return fixedCode; - } - }; -} - const moduleAliases = { resolve: ['.js', '.json', '.md'], entries: [ @@ -153,9 +63,10 @@ const nodePlugins = [ alias(moduleAliases), resolve(), json(), + conditionalFsEventsImport(), string({ include: '**/*.md' }), commonjs({ include: 'node_modules/**' }), - typescript({ include: '**/*.{ts,js}' }) + typescript() ]; export default command => { @@ -167,15 +78,29 @@ export default command => { onwarn, plugins: [ ...nodePlugins, - addSheBang(), + addBinShebang(), !command.configTest && license({ thirdParty: generateLicenseFile }) ], // acorn needs to be external as some plugins rely on a shared acorn instance - external: ['acorn', 'assert', 'crypto', 'events', 'fs', 'module', 'path', 'util'], + // fsevents is a dependency of chokidar that cannot be bundled as it contains binary code + external: [ + 'acorn', + 'assert', + 'crypto', + 'events', + 'fs', + 'fsevents', + 'module', + 'path', + 'os', + 'stream', + 'util' + ], treeshake, + manualChunks: { rollup: ['src/node-entry.ts'] }, output: { banner, - chunkFileNames: 'shared/[name].js', + chunkFileNames: 'shared-cjs/[name].js', dir: 'dist', entryFileNames: '[name]', externalLiveBindings: false, @@ -191,9 +116,13 @@ export default command => { } const esmBuild = Object.assign({}, commonJSBuild, { - input: 'src/node-entry.ts', + input: { 'rollup.es.js': 'src/node-entry.ts' }, plugins: [...nodePlugins, fixAcornEsmImport()], - output: { file: 'dist/rollup.es.js', format: 'esm', banner } + output: Object.assign({}, commonJSBuild.output, { + chunkFileNames: 'shared-es/[name].js', + format: 'esm', + sourcemap: false + }) }); const browserBuilds = { @@ -211,7 +140,7 @@ export default command => { } }, commonjs(), - typescript({ include: '**/*.{ts,js}' }), + typescript(), terser({ module: true, output: { comments: 'some' } }) ], treeshake, diff --git a/scripts/test-package.js b/scripts/test-package.js index ad43213ae8e..5d5563ccaca 100644 --- a/scripts/test-package.js +++ b/scripts/test-package.js @@ -1,7 +1,26 @@ const pkg = require('../package.json'); -for (const key of Object.keys((pkg.dependencies))) { - if (key.startsWith('@types') && pkg.dependencies[key] !== '*') { - throw new Error(`The dependency ${key} should have version range "*" but it was "${pkg.dependencies[key]}".`); +function checkTypes() { + for (const key of Object.keys(pkg.dependencies)) { + if (key.startsWith('@types') && pkg.dependencies[key] !== '*') { + throw new Error( + `The dependency ${key} should have version range "*" but it has "${pkg.dependencies[key]}".` + ); + } } } + +function checkChokidar() { + const chokidarPkg = require('../node_modules/chokidar/package.json'); + const chokidarFsevents = chokidarPkg.dependencies.fsevents; + if (!chokidarFsevents) return; + const pkgFsevents = pkg.optionalDependencies.fsevents; + if (chokidarFsevents !== pkgFsevents) { + throw new Error( + `The dependency "fsevents" should exist with the same version range "${chokidarFsevents}" as it has for chokidar but it has "${pkgFsevents}".` + ); + } +} + +checkTypes(); +checkChokidar(); diff --git a/src/Graph.ts b/src/Graph.ts index 378ed4a163b..e8285ed260f 100644 --- a/src/Graph.ts +++ b/src/Graph.ts @@ -83,7 +83,7 @@ export default class Graph { private pluginCache?: Record; private strictDeprecations: boolean; - constructor(options: InputOptions, watcher?: RollupWatcher) { + constructor(options: InputOptions, watcher: RollupWatcher | null) { this.onwarn = (options.onwarn as WarningHandler) || makeOnwarn(); this.deoptimizationTracker = new PathTracker(); this.cachedModules = new Map(); diff --git a/src/browser-entry.ts b/src/browser-entry.ts index b5935b2694a..228d6517e81 100644 --- a/src/browser-entry.ts +++ b/src/browser-entry.ts @@ -1,2 +1,2 @@ -export { default as rollup } from './rollup/index'; +export { default as rollup } from './rollup/rollup'; export { version as VERSION } from 'package.json'; diff --git a/src/node-entry.ts b/src/node-entry.ts index 6e00c254d94..a488fb584ac 100644 --- a/src/node-entry.ts +++ b/src/node-entry.ts @@ -1,3 +1,3 @@ -export { default as rollup } from './rollup/index'; -export { default as watch } from './watch/index'; +export { default as rollup } from './rollup/rollup'; +export { default as watch } from './watch/watch-proxy'; export { version as VERSION } from 'package.json'; diff --git a/src/rollup/index.ts b/src/rollup/rollup.ts similarity index 98% rename from src/rollup/index.ts rename to src/rollup/rollup.ts index 457ca362dda..fca26101ae4 100644 --- a/src/rollup/index.ts +++ b/src/rollup/rollup.ts @@ -146,11 +146,6 @@ function getInputOptions(rawInputOptions: GenericConfigObject): InputOptions { return inputOptions; } -let curWatcher: RollupWatcher; -export function setWatcher(watcher: RollupWatcher) { - curWatcher = watcher; -} - function assignChunksToBundle( chunks: Chunk[], outputBundle: OutputBundleWithPlaceholders @@ -179,12 +174,18 @@ function assignChunksToBundle( return outputBundle as OutputBundle; } -export default async function rollup(rawInputOptions: GenericConfigObject): Promise { +export default function rollup(rawInputOptions: GenericConfigObject): Promise { + return rollupInternal(rawInputOptions, null); +} + +export async function rollupInternal( + rawInputOptions: GenericConfigObject, + watcher: RollupWatcher | null +): Promise { const inputOptions = getInputOptions(rawInputOptions); initialiseTimers(inputOptions); - const graph = new Graph(inputOptions, curWatcher); - curWatcher = undefined as any; + const graph = new Graph(inputOptions, watcher); // remove the cache option from the memory after graph creation (cache is not used anymore) const useCache = rawInputOptions.cache !== false; diff --git a/src/rollup/types.d.ts b/src/rollup/types.d.ts index 064fa10709e..0110a7f8f0d 100644 --- a/src/rollup/types.d.ts +++ b/src/rollup/types.d.ts @@ -577,8 +577,8 @@ export interface RollupOptions extends InputOptions { } export function rollup(options: RollupOptions): Promise; -// chokidar watch options -export interface WatchOptions { + +export interface ChokidarOptions { alwaysStat?: boolean; atomic?: boolean | number; awaitWriteFinish?: @@ -602,7 +602,7 @@ export interface WatchOptions { } export interface WatcherOptions { - chokidar?: boolean | WatchOptions; + chokidar?: ChokidarOptions; clearScreen?: boolean; exclude?: string[]; include?: string[]; diff --git a/src/utils/PluginContext.ts b/src/utils/PluginContext.ts index 2efb81f4a8d..5b2f14ec1cf 100644 --- a/src/utils/PluginContext.ts +++ b/src/utils/PluginContext.ts @@ -49,7 +49,7 @@ export function getPluginContexts( pluginCache: Record | void, graph: Graph, fileEmitter: FileEmitter, - watcher: RollupWatcher | undefined + watcher: RollupWatcher | null ): (plugin: Plugin, pluginIndex: number) => PluginContext { const existingPluginNames = new Set(); return (plugin, pidx) => { diff --git a/src/utils/PluginDriver.ts b/src/utils/PluginDriver.ts index 96632d7a100..a3003de71af 100644 --- a/src/utils/PluginDriver.ts +++ b/src/utils/PluginDriver.ts @@ -36,14 +36,14 @@ export class PluginDriver { private plugins: Plugin[]; private preserveSymlinks: boolean; private previousHooks = new Set(['options']); - private watcher: RollupWatcher | undefined; + private watcher: RollupWatcher | null; constructor( graph: Graph, userPlugins: Plugin[], pluginCache: Record | undefined, preserveSymlinks: boolean, - watcher: RollupWatcher | undefined, + watcher: RollupWatcher | null, basePluginDriver?: PluginDriver ) { warnDeprecatedHooks(userPlugins, graph); diff --git a/src/watch/chokidar.ts b/src/watch/chokidar.ts deleted file mode 100644 index 618f61ddc03..00000000000 --- a/src/watch/chokidar.ts +++ /dev/null @@ -1,12 +0,0 @@ -import * as chokidarType from 'chokidar'; -import relative from 'require-relative'; - -let chokidar: typeof chokidarType; - -try { - chokidar = relative('chokidar', process.cwd()); -} catch { - chokidar = null as any; -} - -export default chokidar; diff --git a/src/watch/fileWatcher.ts b/src/watch/fileWatcher.ts new file mode 100644 index 00000000000..518dda168a7 --- /dev/null +++ b/src/watch/fileWatcher.ts @@ -0,0 +1,65 @@ +import chokidar, { FSWatcher } from 'chokidar'; +import { platform } from 'os'; +import { ChokidarOptions } from '../rollup/types'; +import { Task } from './watch'; + +export class FileWatcher { + private chokidarOptions: ChokidarOptions; + private task: Task; + private transformWatchers = new Map(); + private watcher: FSWatcher; + + constructor(task: Task, chokidarOptions: ChokidarOptions) { + this.chokidarOptions = chokidarOptions; + this.task = task; + this.watcher = this.createWatcher(null); + } + + close() { + this.watcher.close(); + for (const watcher of this.transformWatchers.values()) { + watcher.close(); + } + } + + unwatch(id: string) { + this.watcher.unwatch(id); + const transformWatcher = this.transformWatchers.get(id); + if (transformWatcher) { + this.transformWatchers.delete(id); + transformWatcher.close(); + } + } + + watch(id: string, isTransformDependency: boolean) { + if (isTransformDependency) { + const watcher = this.transformWatchers.get(id) || this.createWatcher(id); + watcher.add(id); + this.transformWatchers.set(id, watcher); + } else { + this.watcher.add(id); + } + } + + private createWatcher(transformWatcherId: string | null): FSWatcher { + const task = this.task; + const isLinux = platform() === 'linux'; + const isTransformDependency = transformWatcherId !== null; + const handleChange = (id: string) => { + const changedId = transformWatcherId || id; + if (isLinux) { + // unwatching and watching fixes an issue with chokidar where on certain systems, + // a file that was unlinked and immediately recreated would create a change event + // but then no longer any further events + watcher.unwatch(changedId); + watcher.add(changedId); + } + task.invalidate(changedId, isTransformDependency); + }; + const watcher = chokidar + .watch([], this.chokidarOptions) + .on('change', handleChange) + .on('unlink', handleChange); + return watcher; + } +} diff --git a/src/watch/fileWatchers.ts b/src/watch/fileWatchers.ts deleted file mode 100644 index 52f968e9309..00000000000 --- a/src/watch/fileWatchers.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { FSWatcher, WatchOptions } from 'chokidar'; -import * as fs from 'fs'; -import chokidar from './chokidar'; -import { Task } from './index'; - -const opts = { encoding: 'utf-8', persistent: true }; - -const watchers = new Map>(); - -export function addTask( - id: string, - task: Task, - chokidarOptions: WatchOptions, - chokidarOptionsHash: string, - isTransformDependency: boolean -) { - if (!watchers.has(chokidarOptionsHash)) watchers.set(chokidarOptionsHash, new Map()); - const group = watchers.get(chokidarOptionsHash)!; - - const watcher = group.get(id) || new FileWatcher(id, chokidarOptions, group); - if (!watcher.fsWatcher) { - if (isTransformDependency) throw new Error(`Transform dependency ${id} does not exist.`); - } else { - watcher.addTask(task, isTransformDependency); - } -} - -export function deleteTask(id: string, target: Task, chokidarOptionsHash: string) { - const group = watchers.get(chokidarOptionsHash)!; - const watcher = group.get(id); - if (watcher) watcher.deleteTask(target, group); -} - -export default class FileWatcher { - fsWatcher?: FSWatcher | fs.FSWatcher; - - private id: string; - private tasks: Set; - private transformDependencyTasks: Set; - - constructor(id: string, chokidarOptions: WatchOptions, group: Map) { - this.id = id; - this.tasks = new Set(); - this.transformDependencyTasks = new Set(); - - let modifiedTime: number; - - try { - const stats = fs.statSync(id); - modifiedTime = +stats.mtime; - } catch (err) { - if (err.code === 'ENOENT') { - // can't watch files that don't exist (e.g. injected - // by plugins somehow) - return; - } - throw err; - } - - const handleWatchEvent = (event: string) => { - if (event === 'rename' || event === 'unlink') { - this.close(); - group.delete(id); - this.trigger(id); - return; - } else { - let stats: fs.Stats; - try { - stats = fs.statSync(id); - } catch (err) { - if (err.code === 'ENOENT') { - modifiedTime = -1; - this.trigger(id); - return; - } - throw err; - } - // debounce - if (+stats.mtime - modifiedTime > 15) this.trigger(id); - } - }; - - this.fsWatcher = chokidarOptions - ? chokidar.watch(id, chokidarOptions).on('all', handleWatchEvent) - : fs.watch(id, opts, handleWatchEvent); - - group.set(id, this); - } - - addTask(task: Task, isTransformDependency: boolean) { - if (isTransformDependency) this.transformDependencyTasks.add(task); - else this.tasks.add(task); - } - - close() { - if (this.fsWatcher) this.fsWatcher.close(); - } - - deleteTask(task: Task, group: Map) { - let deleted = this.tasks.delete(task); - deleted = this.transformDependencyTasks.delete(task) || deleted; - - if (deleted && this.tasks.size === 0 && this.transformDependencyTasks.size === 0) { - group.delete(this.id); - this.close(); - } - } - - trigger(id: string) { - for (const task of this.tasks) { - task.invalidate(id, false); - } - for (const task of this.transformDependencyTasks) { - task.invalidate(id, true); - } - } -} diff --git a/src/watch/fsevents-importer.ts b/src/watch/fsevents-importer.ts new file mode 100644 index 00000000000..d9ee8bc60d4 --- /dev/null +++ b/src/watch/fsevents-importer.ts @@ -0,0 +1,18 @@ +let fsEvents: any; +let fsEventsImportError: any; + +export function loadFsEvents() { + return import('fsevents') + .then(namespace => { + fsEvents = namespace.default; + }) + .catch(err => { + fsEventsImportError = err; + }); +} + +// A call to this function will be injected into the chokidar code +export function getFsEvents() { + if (fsEventsImportError) throw fsEventsImportError; + return fsEvents; +} diff --git a/src/watch/watch-proxy.ts b/src/watch/watch-proxy.ts new file mode 100644 index 00000000000..66bf7e4499d --- /dev/null +++ b/src/watch/watch-proxy.ts @@ -0,0 +1,23 @@ +import { EventEmitter } from 'events'; +import { RollupWatcher } from '../rollup/types'; +import { GenericConfigObject } from '../utils/mergeOptions'; +import { loadFsEvents } from './fsevents-importer'; + +class WatchEmitter extends EventEmitter { + constructor() { + super(); + // Allows more than 10 bundles to be watched without + // showing the `MaxListenersExceededWarning` to the user. + this.setMaxListeners(Infinity); + } + + close() {} +} + +export default function watch(configs: GenericConfigObject[] | GenericConfigObject): RollupWatcher { + const emitter = new WatchEmitter() as RollupWatcher; + loadFsEvents() + .then(() => import('./watch')) + .then(({ Watcher }) => new Watcher(configs, emitter)); + return emitter; +} diff --git a/src/watch/index.ts b/src/watch/watch.ts similarity index 57% rename from src/watch/index.ts rename to src/watch/watch.ts index 36b8b5fd849..896a5f7105e 100644 --- a/src/watch/index.ts +++ b/src/watch/watch.ts @@ -1,20 +1,16 @@ -import { WatchOptions } from 'chokidar'; -import { EventEmitter } from 'events'; import path from 'path'; import createFilter from 'rollup-pluginutils/src/createFilter'; -import rollup, { setWatcher } from '../rollup/index'; +import { rollupInternal } from '../rollup/rollup'; import { InputOptions, OutputOptions, RollupBuild, RollupCache, - RollupError, RollupWatcher, WatcherOptions } from '../rollup/types'; import mergeOptions, { GenericConfigObject } from '../utils/mergeOptions'; -import chokidar from './chokidar'; -import { addTask, deleteTask } from './fileWatchers'; +import { FileWatcher } from './fileWatcher'; const DELAY = 200; @@ -27,17 +23,9 @@ export class Watcher { private running: boolean; private tasks: Task[]; - constructor(configs: GenericConfigObject[] | GenericConfigObject) { - this.emitter = new (class extends EventEmitter { - close: () => void; - constructor(close: () => void) { - super(); - this.close = close; - // Allows more than 10 bundles to be watched without - // showing the `MaxListenersExceededWarning` to the user. - this.setMaxListeners(Infinity); - } - })(this.close.bind(this)) as RollupWatcher; + constructor(configs: GenericConfigObject[] | GenericConfigObject, emitter: RollupWatcher) { + this.emitter = emitter; + emitter.close = this.close.bind(this); this.tasks = (Array.isArray(configs) ? configs : configs ? [configs] : []).map( config => new Task(this, config) ); @@ -50,7 +38,6 @@ export class Watcher { for (const task of this.tasks) { task.close(); } - this.emitter.removeAllListeners(); } @@ -80,36 +67,33 @@ export class Watcher { }, DELAY); } - private run() { + private async run() { this.running = true; this.emit('event', { code: 'START' }); - let taskPromise = Promise.resolve(); - for (const task of this.tasks) taskPromise = taskPromise.then(() => task.run()); - return taskPromise - .then(() => { - this.running = false; - - this.emit('event', { - code: 'END' - }); - }) - .catch(error => { - this.running = false; - this.emit('event', { - code: 'ERROR', - error - }); - }) - .then(() => { - if (this.rerun) { - this.rerun = false; - this.invalidate(); - } + try { + for (const task of this.tasks) { + await task.run(); + } + this.running = false; + this.emit('event', { + code: 'END' + }); + } catch (error) { + this.running = false; + this.emit('event', { + code: 'ERROR', + error }); + } + + if (this.rerun) { + this.rerun = false; + this.invalidate(); + } } } @@ -117,9 +101,8 @@ export class Task { cache: RollupCache = { modules: [] }; watchFiles: string[] = []; - private chokidarOptions: WatchOptions; - private chokidarOptionsHash: string; private closed: boolean; + private fileWatcher: FileWatcher; private filter: (id: string) => boolean; private inputOptions: InputOptions; private invalidated = true; @@ -130,7 +113,6 @@ export class Task { constructor(watcher: Watcher, config: GenericConfigObject) { this.watcher = watcher; - this.closed = false; this.watched = new Set(); @@ -138,7 +120,6 @@ export class Task { config }); this.inputOptions = inputOptions; - this.outputs = outputOptions; this.outputFiles = this.outputs.map(output => { if (output.file || output.dir) return path.resolve(output.file || output.dir!); @@ -146,37 +127,20 @@ export class Task { }); const watchOptions: WatcherOptions = inputOptions.watch || {}; - if ('useChokidar' in watchOptions) - (watchOptions as any).chokidar = (watchOptions as any).useChokidar; - let chokidarOptions = 'chokidar' in watchOptions ? watchOptions.chokidar : !!chokidar; - if (chokidarOptions) { - chokidarOptions = { - ...(chokidarOptions === true ? {} : chokidarOptions), - disableGlobbing: true, - ignoreInitial: true - }; - } - - if (chokidarOptions && !chokidar) { - throw new Error( - `watch.chokidar was provided, but chokidar could not be found. Have you installed it?` - ); - } - - this.chokidarOptions = chokidarOptions as WatchOptions; - this.chokidarOptionsHash = JSON.stringify(chokidarOptions); - this.filter = createFilter(watchOptions.include, watchOptions.exclude); + this.fileWatcher = new FileWatcher(this, { + ...watchOptions.chokidar, + disableGlobbing: true, + ignoreInitial: true + }); } close() { this.closed = true; - for (const id of this.watched) { - deleteTask(id, this, this.chokidarOptionsHash); - } + this.fileWatcher.close(); } - invalidate(id: string, isTransformDependency: boolean) { + invalidate(id: string, isTransformDependency: boolean | undefined) { this.invalidated = true; if (isTransformDependency) { for (const module of this.cache.modules) { @@ -188,7 +152,7 @@ export class Task { this.watcher.invalidate(id); } - run() { + async run() { if (!this.invalidated) return; this.invalidated = false; @@ -205,32 +169,32 @@ export class Task { output: this.outputFiles }); - setWatcher(this.watcher.emitter); - return rollup(options) - .then(result => { - if (this.closed) return undefined as any; - this.updateWatchedFiles(result); - return Promise.all(this.outputs.map(output => result.write(output))).then(() => result); - }) - .then((result: RollupBuild) => { - this.watcher.emit('event', { - code: 'BUNDLE_END', - duration: Date.now() - start, - input: this.inputOptions.input, - output: this.outputFiles, - result - }); - }) - .catch((error: RollupError) => { - if (this.closed) return; + try { + const result = await rollupInternal(options, this.watcher.emitter); + if (this.closed) { + return; + } + this.updateWatchedFiles(result); + await Promise.all(this.outputs.map(output => result.write(output))); + this.watcher.emit('event', { + code: 'BUNDLE_END', + duration: Date.now() - start, + input: this.inputOptions.input, + output: this.outputFiles, + result + }); + } catch (error) { + if (this.closed) { + return; + } - if (Array.isArray(error.watchFiles)) { - for (const id of error.watchFiles) { - this.watchFile(id); - } + if (Array.isArray(error.watchFiles)) { + for (const id of error.watchFiles) { + this.watchFile(id); } - throw error; - }); + } + throw error; + } } private updateWatchedFiles(result: RollupBuild) { @@ -247,7 +211,9 @@ export class Task { } } for (const id of previouslyWatched) { - if (!this.watched.has(id)) deleteTask(id, this, this.chokidarOptionsHash); + if (!this.watched.has(id)) { + this.fileWatcher.unwatch(id); + } } } @@ -261,10 +227,6 @@ export class Task { // this is necessary to ensure that any 'renamed' files // continue to be watched following an error - addTask(id, this, this.chokidarOptions, this.chokidarOptionsHash, isTransformDependency); + this.fileWatcher.watch(id, isTransformDependency); } } - -export default function watch(configs: GenericConfigObject[] | GenericConfigObject): RollupWatcher { - return new Watcher(configs).emitter; -} diff --git a/test/function/index.js b/test/function/index.js index 4f2a850e8ce..4cb614eb7b4 100644 --- a/test/function/index.js +++ b/test/function/index.js @@ -113,7 +113,11 @@ runTestSuiteWithSamples('function', path.resolve(__dirname, 'samples'), (dir, co const entryId = result.length === 1 ? result[0].fileName : 'main.js'; if (!codeMap.hasOwnProperty(entryId)) { - throw new Error(`Could not find entry "${entryId}" in generated output.`); + throw new Error( + `Could not find entry "${entryId}" in generated output.\nChunks:\n${Object.keys( + codeMap + ).join('\n')}` + ); } const { exports, error } = runCodeSplitTest(codeMap, entryId, config.context); if (config.runtimeError) { diff --git a/test/hooks/index.js b/test/hooks/index.js index 719b6a128ed..904775bef7f 100644 --- a/test/hooks/index.js +++ b/test/hooks/index.js @@ -916,20 +916,23 @@ describe('hooks', () => { if (event.code === 'BUNDLE_END') resolve(); else if (event.code === 'ERROR') reject(event.error); }); - }).catch(err => { - assert.strictEqual( - err.message, - 'You must specify "output.file" or "output.dir" for the build.' - ); - assert.strictEqual(warnings.length, 1); - const warning = warnings[0]; - assert.strictEqual(warning.code, 'PLUGIN_WARNING'); - assert.strictEqual(warning.pluginCode, 'PLUGIN_WATCHER_DEPRECATED'); - assert.strictEqual( - warning.message, - 'this.watcher usage is deprecated in plugins. Use the watchChange plugin hook and this.addWatchFile() instead.' - ); - }); + }) + .catch(err => { + watcher.close(); + assert.strictEqual( + err.message, + 'You must specify "output.file" or "output.dir" for the build.' + ); + assert.strictEqual(warnings.length, 1); + const warning = warnings[0]; + assert.strictEqual(warning.code, 'PLUGIN_WARNING'); + assert.strictEqual(warning.pluginCode, 'PLUGIN_WATCHER_DEPRECATED'); + assert.strictEqual( + warning.message, + 'this.watcher usage is deprecated in plugins. Use the watchChange plugin hook and this.addWatchFile() instead.' + ); + }) + .then(() => watcher.close()); }); it('Throws when not specifying "file" or "dir"', () => { @@ -945,12 +948,15 @@ describe('hooks', () => { if (event.code === 'BUNDLE_END') reject(new Error('Expected an error')); else if (event.code === 'ERROR') reject(event.error); }); - }).catch(err => { - assert.strictEqual( - err.message, - 'You must specify "output.file" or "output.dir" for the build.' - ); - }); + }) + .catch(err => { + watcher.close(); + assert.strictEqual( + err.message, + 'You must specify "output.file" or "output.dir" for the build.' + ); + }) + .then(() => watcher.close()); }); it('Throws when using the "file"" option for multiple chunks', () => { @@ -967,12 +973,15 @@ describe('hooks', () => { if (event.code === 'BUNDLE_END') reject(new Error('Expected an error')); else if (event.code === 'ERROR') reject(event.error); }); - }).catch(err => { - assert.strictEqual( - err.message, - 'You must set "output.dir" instead of "output.file" when generating multiple chunks.' - ); - }); + }) + .catch(err => { + watcher.close(); + assert.strictEqual( + err.message, + 'You must set "output.dir" instead of "output.file" when generating multiple chunks.' + ); + }) + .then(() => watcher.close()); }); it('Throws when using the "sourcemapFile" option for multiple chunks', () => { @@ -990,12 +999,15 @@ describe('hooks', () => { if (event.code === 'BUNDLE_END') reject(new Error('Expected an error')); else if (event.code === 'ERROR') reject(event.error); }); - }).catch(err => { - assert.strictEqual( - err.message, - '"output.sourcemapFile" is only supported for single-file builds.' - ); - }); + }) + .catch(err => { + watcher.close(); + assert.strictEqual( + err.message, + '"output.sourcemapFile" is only supported for single-file builds.' + ); + }) + .then(() => watcher.close()); }); it('assigns chunk IDs before creating outputBundle chunks', () => { diff --git a/test/watch/index.js b/test/watch/index.js index f454536bdd9..fa1bb565b4b 100644 --- a/test/watch/index.js +++ b/test/watch/index.js @@ -12,11 +12,20 @@ function wait(ms) { } describe('rollup.watch', () => { + let watcher; + beforeEach(() => { process.chdir(cwd); return sander.rimraf('test/_tmp'); }); + afterEach(() => { + if (watcher) { + watcher.close(); + watcher = null; + } + }); + function run(file) { const resolved = require.resolve(file); delete require.cache[resolved]; @@ -57,29 +66,895 @@ describe('rollup.watch', () => { }); } - describe('fs.watch', () => { - runTests(false); + it('watches a file and triggers reruns if necessary', () => { + let triggerRestart = false; + + return sander + .copydir('test/watch/samples/basic') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + plugins: { + transform(code) { + if (triggerRestart) { + triggerRestart = false; + return wait(100) + .then(() => sander.writeFileSync('test/_tmp/input/main.js', 'export default 44;')) + .then(() => wait(100)) + .then(() => code); + } + } + }, + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' + } + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + triggerRestart = true; + sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 44); + } + ]); + }); }); - if (!process.env.CI) { - describe('chokidar', () => { - runTests(true); - }); - } + it('does not fail for virtual files', () => { + return sander + .copydir('test/watch/samples/basic') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + plugins: { + resolveId(id) { + if (id === 'virtual') { + return id; + } + }, + load(id) { + if (id === 'virtual') { + return `export const value = 42;`; + } + } + }, + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' + } + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + sander.writeFileSync( + 'test/_tmp/input/main.js', + "import {value} from 'virtual';\nexport default value + 1;" + ); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + } + ]); + }); + }); + + it('passes file events to the watchChange plugin hook once for each change', () => { + let watchChangeCnt = 0; + return sander + .copydir('test/watch/samples/basic') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' + }, + plugins: { + watchChange(id) { + watchChangeCnt++; + assert.strictEqual(id, path.resolve('test/_tmp/input/main.js')); + } + } + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + assert.strictEqual(watchChangeCnt, 0); + sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + assert.strictEqual(watchChangeCnt, 1); + sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + assert.strictEqual(watchChangeCnt, 2); + sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + assert.strictEqual(watchChangeCnt, 3); + } + ]); + }); + }); + + it('watches a file in code-splitting mode', () => { + return sander + .copydir('test/watch/samples/code-splitting') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: ['test/_tmp/input/main1.js', 'test/_tmp/input/main2.js'], + output: { + dir: 'test/_tmp/output', + format: 'cjs' + } + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/main1.js'), 21); + assert.strictEqual(run('../_tmp/output/main2.js'), 42); + sander.writeFileSync('test/_tmp/input/shared.js', 'export const value = 22;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/main1.js'), 22); + assert.strictEqual(run('../_tmp/output/main2.js'), 44); + } + ]); + }); + }); + + it('watches a file in code-splitting mode with an input object', () => { + return sander + .copydir('test/watch/samples/code-splitting') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: { + _main_1: 'test/_tmp/input/main1.js', + 'subfolder/_main_2': 'test/_tmp/input/main2.js' + }, + output: { + dir: 'test/_tmp/output', + format: 'cjs' + } + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/_main_1.js'), 21); + assert.strictEqual(run('../_tmp/output/subfolder/_main_2.js'), 42); + sander.writeFileSync('test/_tmp/input/shared.js', 'export const value = 22;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/_main_1.js'), 22); + assert.strictEqual(run('../_tmp/output/subfolder/_main_2.js'), 44); + } + ]); + }); + }); + + it('recovers from an error', () => { + return sander + .copydir('test/watch/samples/basic') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' + } + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + sander.writeFileSync('test/_tmp/input/main.js', 'export nope;'); + }, + 'START', + 'BUNDLE_START', + 'ERROR', + () => { + sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + } + ]); + }); + }); + + it('recovers from an error on initial build', () => { + return sander + .copydir('test/watch/samples/error') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' + } + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'ERROR', + () => { + assert.strictEqual(sander.existsSync('../_tmp/output/bundle.js'), false); + sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + } + ]); + }); + }); + + it('recovers from a plugin error on initial build', () => { + let count = 0; + return sander + .copydir('test/watch/samples/basic') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + plugins: { + transform() { + if (count++ === 0) { + this.error('The first run failed, try again.'); + } + } + }, + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' + } + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'ERROR', + () => { + assert.strictEqual(sander.existsSync('../_tmp/output/bundle.js'), false); + sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + } + ]); + }); + }); + + it('recovers from an error even when erroring entry was "renamed" (#38)', () => { + return sander + .copydir('test/watch/samples/basic') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' + } + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + sander.unlinkSync('test/_tmp/input/main.js'); + sander.writeFileSync('test/_tmp/input/main.js', 'export nope;'); + }, + 'START', + 'BUNDLE_START', + 'ERROR', + () => { + sander.unlinkSync('test/_tmp/input/main.js'); + sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + } + ]); + }); + }); + + it('recovers from an error even when erroring dependency was "renamed" (#38)', () => { + return sander + .copydir('test/watch/samples/dependency') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' + } + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + sander.unlinkSync('test/_tmp/input/dep.js'); + sander.writeFileSync('test/_tmp/input/dep.js', 'export nope;'); + }, + 'START', + 'BUNDLE_START', + 'ERROR', + () => { + sander.unlinkSync('test/_tmp/input/dep.js'); + sander.writeFileSync('test/_tmp/input/dep.js', 'export const value = 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 44); + } + ]); + }); + }); + + it('handles closing the watcher during a build', () => { + return sander + .copydir('test/watch/samples/basic') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + plugins: { + load() { + watcher.close(); + } + }, + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' + } + }); + const events = []; + watcher.on('event', event => events.push(event.code)); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + () => { + sander.writeFileSync('test/_tmp/input/main.js', 'export default 44;'); + return wait(400).then(() => assert.deepStrictEqual(events, ['START', 'BUNDLE_START'])); + } + ]); + }); + }); + + it('handles closing the watcher during a build even if an error occurred', () => { + return sander + .copydir('test/watch/samples/error') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + plugins: { + load() { + watcher.close(); + } + }, + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' + } + }); + const events = []; + watcher.on('event', event => events.push(event.code)); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + () => { + sander.writeFileSync('test/_tmp/input/main.js', 'export default 44;'); + return wait(400).then(() => assert.deepStrictEqual(events, ['START', 'BUNDLE_START'])); + } + ]); + }); + }); + + it('stops watching files that are no longer part of the graph', () => { + return sander + .copydir('test/watch/samples/dependency') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' + } + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + sander.writeFileSync('test/_tmp/input/main.js', 'export default 42;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + let unexpectedEvent = false; + watcher.once('event', event => { + unexpectedEvent = event; + }); + sander.writeFileSync('test/_tmp/input/dep.js', '= invalid'); + return wait(400).then(() => assert.strictEqual(unexpectedEvent, false)); + } + ]); + }); + }); + + it('refuses to watch the output file (#15)', () => { + return sander + .copydir('test/watch/samples/basic') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' + } + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + sander.writeFileSync('test/_tmp/input/main.js', `import '../output/bundle.js'`); + }, + 'START', + 'BUNDLE_START', + 'ERROR', + event => { + assert.strictEqual(event.error.message, 'Cannot import the generated bundle'); + sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + } + ]); + }); + }); + + it('ignores files that are not specified in options.watch.include, if given', () => { + return sander + .copydir('test/watch/samples/ignored') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' + }, + watch: { + include: ['test/_tmp/input/+(main|foo).js'] + } + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { + foo: 'foo-1', + bar: 'bar-1' + }); + sander.writeFileSync('test/_tmp/input/foo.js', `export default 'foo-2';`); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { + foo: 'foo-2', + bar: 'bar-1' + }); + let unexpectedEvent = false; + watcher.once('event', event => { + unexpectedEvent = event; + }); + sander.writeFileSync('test/_tmp/input/bar.js', "export default 'bar-2';"); + return wait(400).then(() => { + assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { + foo: 'foo-2', + bar: 'bar-1' + }); + assert.strictEqual(unexpectedEvent, false); + }); + } + ]); + }); + }); + + it('ignores files that are specified in options.watch.exclude, if given', () => { + return sander + .copydir('test/watch/samples/ignored') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' + }, + watch: { + exclude: ['test/_tmp/input/bar.js'] + } + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { + foo: 'foo-1', + bar: 'bar-1' + }); + sander.writeFileSync('test/_tmp/input/foo.js', `export default 'foo-2';`); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { + foo: 'foo-2', + bar: 'bar-1' + }); + let unexpectedEvent = false; + watcher.once('event', event => { + unexpectedEvent = event; + }); + sander.writeFileSync('test/_tmp/input/bar.js', "export default 'bar-2';"); + return wait(400).then(() => { + assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { + foo: 'foo-2', + bar: 'bar-1' + }); + assert.strictEqual(unexpectedEvent, false); + }); + } + ]); + }); + }); + + it('only rebuilds the appropriate configs', () => { + return sander + .copydir('test/watch/samples/multiple') + .to('test/_tmp/input') + .then(() => wait(100)) + .then(() => { + watcher = rollup.watch([ + { + input: 'test/_tmp/input/main1.js', + output: { + file: 'test/_tmp/output/bundle1.js', + format: 'cjs' + } + }, + { + input: 'test/_tmp/input/main2.js', + output: { + file: 'test/_tmp/output/bundle2.js', + format: 'cjs' + } + } + ]); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.deepStrictEqual(run('../_tmp/output/bundle1.js'), 42); + assert.deepStrictEqual(run('../_tmp/output/bundle2.js'), 43); + sander.writeFileSync('test/_tmp/input/main2.js', 'export default 44'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.deepStrictEqual(run('../_tmp/output/bundle1.js'), 42); + assert.deepStrictEqual(run('../_tmp/output/bundle2.js'), 44); + } + ]); + }); + }); + + it('respects output.globals', () => { + return sander + .copydir('test/watch/samples/globals') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'iife', + globals: { + jquery: 'jQuery' + } + }, + external: ['jquery'] + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + const generated = sander.readFileSync('test/_tmp/output/bundle.js', { + encoding: 'utf-8' + }); + assert.ok(/jQuery/.test(generated)); + } + ]); + }); + }); - function runTests(chokidar) { - it('watches a file', () => { + it('treats filenames literally, not as globs', () => { + return sander + .copydir('test/watch/samples/non-glob') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' + } + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + sander.writeFileSync('test/_tmp/input/[foo]/bar.js', `export const bar = 43;`); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + } + ]); + }); + }); + + it('updates the right hashes on dependency changes', () => { + let dynamicName; + let staticName; + let chunkName; + return sander + .copydir('test/watch/samples/hashing') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: ['test/_tmp/input/main-static.js', 'test/_tmp/input/main-dynamic.js'], + output: { + dir: 'test/_tmp/output', + format: 'cjs', + entryFileNames: '[name].[hash].js', + chunkFileNames: '[name].[hash].js' + }, + experimentalCodeSplitting: true + }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + [dynamicName, staticName, chunkName] = sander.readdirSync('test/_tmp/output').sort(); + sander.rimrafSync('test/_tmp/output'); + + // this should only update the hash of that particular entry point + sander.writeFileSync( + 'test/_tmp/input/main-static.js', + "import {value} from './shared';\nexport default 2 * value;" + ); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + const [newDynamicName, newStaticName, newChunkName] = sander + .readdirSync('test/_tmp/output') + .sort(); + sander.rimrafSync('test/_tmp/output'); + assert.notEqual(newStaticName, staticName); + assert.strictEqual(newDynamicName, dynamicName); + assert.strictEqual(newChunkName, chunkName); + staticName = newStaticName; + + // this should update all hashes + sander.writeFileSync('test/_tmp/input/shared.js', 'export const value = 42;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + const [newDynamicName, newStaticName, newChunkName] = sander + .readdirSync('test/_tmp/output') + .sort(); + assert.notEqual(newStaticName, staticName); + assert.notEqual(newDynamicName, dynamicName); + assert.notEqual(newChunkName, chunkName); + } + ]); + }); + }); + + describe('addWatchFile', () => { + it('supports adding additional watch files in plugin hooks', () => { + const watchChangeIds = []; + const buildStartFile = path.resolve('test/_tmp/input/buildStart'); + const loadFile = path.resolve('test/_tmp/input/load'); + const resolveIdFile = path.resolve('test/_tmp/input/resolveId'); + const transformFile = path.resolve('test/_tmp/input/transform'); + const watchFiles = [buildStartFile, loadFile, resolveIdFile, transformFile]; return sander .copydir('test/watch/samples/basic') .to('test/_tmp/input') .then(() => { - const watcher = rollup.watch({ + for (const file of watchFiles) sander.writeFileSync(file, 'initial'); + watcher = rollup.watch({ input: 'test/_tmp/input/main.js', output: { file: 'test/_tmp/output/bundle.js', format: 'cjs' }, - watch: { chokidar } + plugins: { + buildStart() { + this.addWatchFile(buildStartFile); + }, + load() { + this.addWatchFile(loadFile); + }, + resolveId() { + this.addWatchFile(resolveIdFile); + }, + transform() { + this.addWatchFile(transformFile); + }, + watchChange(id) { + watchChangeIds.push(id); + } + } }); return sequence(watcher, [ @@ -89,43 +964,41 @@ describe('rollup.watch', () => { 'END', () => { assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + assert.deepStrictEqual(watchChangeIds, []); + for (const file of watchFiles) sander.writeFileSync(file, 'changed'); }, 'START', 'BUNDLE_START', 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + assert.deepStrictEqual(watchChangeIds.sort(), watchFiles.sort()); } ]); }); }); - it('does not fail for virtual files', () => { + it('respects changed watched files in the load hook', () => { return sander - .copydir('test/watch/samples/basic') + .copydir('test/watch/samples/watch-files') .to('test/_tmp/input') .then(() => { - const watcher = rollup.watch({ + watcher = rollup.watch({ input: 'test/_tmp/input/main.js', - plugins: { - resolveId(id) { - if (id === 'virtual') { - return id; - } - }, - load(id) { - if (id === 'virtual') { - return `export const value = 42;`; - } - } - }, output: { file: 'test/_tmp/output/bundle.js', format: 'cjs' }, - watch: { chokidar } + plugins: { + load() { + this.addWatchFile('test/_tmp/input/watched'); + return `export default "${sander + .readFileSync('test/_tmp/input/watched') + .toString() + .trim()}"`; + } + } }); return sequence(watcher, [ @@ -134,42 +1007,54 @@ describe('rollup.watch', () => { 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - sander.writeFileSync( - 'test/_tmp/input/main.js', - "import {value} from 'virtual';\nexport default value + 1;" - ); + assert.strictEqual(run('../_tmp/output/bundle.js'), 'initial'); + sander.writeFileSync('test/_tmp/input/watched', 'next'); }, 'START', 'BUNDLE_START', 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + assert.strictEqual(run('../_tmp/output/bundle.js'), 'next'); } ]); }); }); - it('passes file events to the watchChange plugin hook once for each change', () => { - let watchChangeCnt = 0; + it('respects changed watched files in the transform hook', () => { return sander - .copydir('test/watch/samples/basic') + .copydir('test/watch/samples/watch-files') .to('test/_tmp/input') .then(() => { - const watcher = rollup.watch({ + watcher = rollup.watch({ input: 'test/_tmp/input/main.js', output: { file: 'test/_tmp/output/bundle.js', format: 'cjs' }, plugins: { - watchChange(id) { - watchChangeCnt++; - assert.strictEqual(id, path.resolve('test/_tmp/input/main.js')); + resolveId(id) { + if (id === 'dep') { + return id; + } + }, + load(id) { + if (id === 'dep') { + return `throw new Error('This should not be executed);`; + } + }, + transform(code, id) { + if (id.endsWith('main.js')) { + return `export { value as default } from 'dep';`; + } else { + this.addWatchFile('test/_tmp/input/watched'); + return `export const value = "${sander + .readFileSync('test/_tmp/input/watched') + .toString() + .trim()}"`; + } } - }, - watch: { chokidar } + } }); return sequence(watcher, [ @@ -178,52 +1063,79 @@ describe('rollup.watch', () => { 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - assert.strictEqual(watchChangeCnt, 0); - sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + assert.strictEqual(run('../_tmp/output/bundle.js'), 'initial'); + sander.writeFileSync('test/_tmp/input/watched', 'next'); }, 'START', 'BUNDLE_START', 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); - assert.strictEqual(watchChangeCnt, 1); - sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + assert.strictEqual(run('../_tmp/output/bundle.js'), 'next'); + } + ]); + }); + }); + + it('respects changed watched modules that are already part of the graph in the transform hook', () => { + return sander + .copydir('test/watch/samples/watch-files') + .to('test/_tmp/input') + .then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs' }, + plugins: { + transform() { + this.addWatchFile('test/_tmp/input/main.js'); + return `export default "${sander + .readFileSync('test/_tmp/input/main.js') + .toString() + .trim()}"`; + } + } + }); + + return sequence(watcher, [ 'START', 'BUNDLE_START', 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); - assert.strictEqual(watchChangeCnt, 2); - sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + assert.strictEqual(run('../_tmp/output/bundle.js'), 'export default 42;'); + sander.writeFileSync('test/_tmp/input/main.js', 'next'); }, 'START', 'BUNDLE_START', 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); - assert.strictEqual(watchChangeCnt, 3); + assert.strictEqual(run('../_tmp/output/bundle.js'), 'next'); } ]); }); }); - it('watches a file in code-splitting mode', () => { + it('respects changed watched directories in the transform hook', () => { return sander - .copydir('test/watch/samples/code-splitting') + .copydir('test/watch/samples/watch-files') .to('test/_tmp/input') .then(() => { - const watcher = rollup.watch({ - input: ['test/_tmp/input/main1.js', 'test/_tmp/input/main2.js'], + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', output: { - dir: 'test/_tmp/output', + file: 'test/_tmp/output/bundle.js', format: 'cjs' }, - watch: { chokidar } + plugins: { + transform() { + this.addWatchFile('test/_tmp/input'); + return `export default ${sander.existsSync('test/_tmp/input/watched')}`; + } + } }); return sequence(watcher, [ @@ -232,37 +1144,48 @@ describe('rollup.watch', () => { 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/main1.js'), 21); - assert.strictEqual(run('../_tmp/output/main2.js'), 42); - sander.writeFileSync('test/_tmp/input/shared.js', 'export const value = 22;'); + assert.strictEqual(run('../_tmp/output/bundle.js'), true); + sander.unlinkSync('test/_tmp/input/watched'); }, 'START', 'BUNDLE_START', 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/main1.js'), 22); - assert.strictEqual(run('../_tmp/output/main2.js'), 44); + assert.strictEqual(run('../_tmp/output/bundle.js'), false); + watcher.close(); } ]); }); }); - it('watches a file in code-splitting mode with an input object', () => { + it('does not rerun the transform hook if a non-watched change triggered the re-run', () => { + let transformRuns = 0; return sander - .copydir('test/watch/samples/code-splitting') + .copydir('test/watch/samples/watch-files') .to('test/_tmp/input') + .then(() => wait(100)) .then(() => { - const watcher = rollup.watch({ - input: { - _main_1: 'test/_tmp/input/main1.js', - 'subfolder/_main_2': 'test/_tmp/input/main2.js' - }, + sander.writeFileSync('test/_tmp/input/alsoWatched', 'initial'); + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', output: { - dir: 'test/_tmp/output', + file: 'test/_tmp/output/bundle.js', format: 'cjs' }, - watch: { chokidar } + plugins: { + buildStart() { + this.addWatchFile('test/_tmp/input/alsoWatched'); + }, + transform() { + transformRuns++; + this.addWatchFile('test/_tmp/input/watched'); + return `export default "${sander + .readFileSync('test/_tmp/input/watched') + .toString() + .trim()}"`; + } + } }); return sequence(watcher, [ @@ -271,34 +1194,49 @@ describe('rollup.watch', () => { 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/_main_1.js'), 21); - assert.strictEqual(run('../_tmp/output/subfolder/_main_2.js'), 42); - sander.writeFileSync('test/_tmp/input/shared.js', 'export const value = 22;'); + assert.strictEqual(transformRuns, 1); + sander.writeFileSync('test/_tmp/input/alsoWatched', 'next'); }, 'START', 'BUNDLE_START', 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/_main_1.js'), 22); - assert.strictEqual(run('../_tmp/output/subfolder/_main_2.js'), 44); + assert.strictEqual(transformRuns, 1); } ]); }); }); + }); - it('recovers from an error', () => { + describe('deprecated features', () => { + it('provides the watcher through the plugin context', () => { + const events = []; return sander .copydir('test/watch/samples/basic') .to('test/_tmp/input') .then(() => { - const watcher = rollup.watch({ + watcher = rollup.watch({ input: 'test/_tmp/input/main.js', output: { file: 'test/_tmp/output/bundle.js', format: 'cjs' }, - watch: { chokidar } + onwarn(warning) { + assert.strictEqual( + warning.message, + 'this.watcher usage is deprecated in plugins. Use the watchChange plugin hook and this.addWatchFile() instead.' + ); + }, + plugins: { + buildStart(id) { + if (!this.watcher) throw new Error('No Watcher'); + + this.watcher.on('event', event => { + events.push(event); + }); + } + } }); return sequence(watcher, [ @@ -307,13 +1245,8 @@ describe('rollup.watch', () => { 'BUNDLE_END', 'END', () => { + assert.strictEqual(events.length, 2); assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - sander.writeFileSync('test/_tmp/input/main.js', 'export nope;'); - }, - 'START', - 'BUNDLE_START', - 'ERROR', - () => { sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); }, 'START', @@ -322,203 +1255,117 @@ describe('rollup.watch', () => { 'END', () => { assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + assert.strictEqual(events.length, 8); } ]); }); }); - it('recovers from an error on initial build', () => { + it('watches and rebuilds transform dependencies', () => { return sander - .copydir('test/watch/samples/error') + .copydir('test/watch/samples/watch-files') .to('test/_tmp/input') .then(() => { - const watcher = rollup.watch({ + watcher = rollup.watch({ input: 'test/_tmp/input/main.js', output: { file: 'test/_tmp/output/bundle.js', format: 'cjs' }, - watch: { chokidar } + plugins: { + transform() { + return { + code: `export default "${sander + .readFileSync('test/_tmp/input/watched') + .toString() + .trim()}"`, + dependencies: ['./watched'] + }; + } + } }); return sequence(watcher, [ 'START', 'BUNDLE_START', - 'ERROR', + 'BUNDLE_END', + 'END', () => { - assert.strictEqual(sander.existsSync('../_tmp/output/bundle.js'), false); - sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + assert.strictEqual(run('../_tmp/output/bundle.js'), 'initial'); + sander.writeFileSync('test/_tmp/input/watched', 'next'); }, 'START', 'BUNDLE_START', 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + assert.strictEqual(run('../_tmp/output/bundle.js'), 'next'); } ]); }); }); - it('recovers from a plugin error on initial build', () => { - let count = 0; + it('watches and rebuilds transform dependencies that are modules', () => { return sander - .copydir('test/watch/samples/basic') + .copydir('test/watch/samples/watch-files') .to('test/_tmp/input') .then(() => { - const watcher = rollup.watch({ + watcher = rollup.watch({ input: 'test/_tmp/input/main.js', - plugins: { - transform() { - if (count++ === 0) { - this.error('The first run failed, try again.'); - } - } - }, output: { file: 'test/_tmp/output/bundle.js', format: 'cjs' }, - watch: { chokidar } + plugins: { + transform() { + const dependencies = ['./main.js']; + const text = sander + .readFileSync('test/_tmp/input/main.js') + .toString() + .trim(); + return { code: `export default "${text}"`, dependencies }; + } + } }); return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'ERROR', - () => { - assert.strictEqual(sander.existsSync('../_tmp/output/bundle.js'), false); - sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); - }, 'START', 'BUNDLE_START', 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); - } - ]); - }); - }); - - it('recovers from an error even when erroring file was "renamed" (#38)', () => { - return sander - .copydir('test/watch/samples/basic') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' + assert.strictEqual(run('../_tmp/output/bundle.js'), 'export default 42;'); + sander.writeFileSync('test/_tmp/input/main.js', 'next'); }, - watch: { chokidar } - }); - - return sequence(watcher, [ 'START', 'BUNDLE_START', 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - sander.unlinkSync('test/_tmp/input/main.js'); - sander.writeFileSync('test/_tmp/input/main.js', 'export nope;'); - }, - 'START', - 'BUNDLE_START', - 'ERROR', - () => { - sander.unlinkSync('test/_tmp/input/main.js'); - sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + assert.strictEqual(run('../_tmp/output/bundle.js'), 'next'); } ]); }); }); - it('handles closing the watcher during a build', () => { + it('watches and rebuilds transform dependencies directories', () => { + let v = 1; return sander - .copydir('test/watch/samples/basic') + .copydir('test/watch/samples/watch-files') .to('test/_tmp/input') .then(() => { - const watcher = rollup.watch({ + watcher = rollup.watch({ input: 'test/_tmp/input/main.js', output: { file: 'test/_tmp/output/bundle.js', format: 'cjs' }, - watch: { chokidar } - }); - - setTimeout(() => watcher.close(), 50); - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - () => { - sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); - let unexpectedEvent = false; - watcher.once('event', event => { - unexpectedEvent = event; - }); - sander.writeFileSync('test/_tmp/input/dep.js', '= invalid'); - return wait(400).then(() => assert.strictEqual(unexpectedEvent, false)); - } - ]); - }); - }); - - it('handles closing the watcher during a build even if an error occurred', () => { - return sander - .copydir('test/watch/samples/error') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - watch: { chokidar } - }); - - setTimeout(() => watcher.close(), 50); - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'ERROR', - () => { - sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); - let unexpectedEvent = false; - watcher.once('event', event => { - unexpectedEvent = event; - }); - sander.writeFileSync('test/_tmp/input/dep.js', '= invalid'); - return wait(400).then(() => assert.strictEqual(unexpectedEvent, false)); + plugins: { + transform() { + const dependencies = ['./']; + return { code: `export default ${v++}`, dependencies }; + } } - ]); - }); - }); - - it('stops watching files that are no longer part of the graph', () => { - return sander - .copydir('test/watch/samples/dependency') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - watch: { chokidar } }); return sequence(watcher, [ @@ -527,38 +1374,49 @@ describe('rollup.watch', () => { 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); - sander.writeFileSync('test/_tmp/input/main.js', 'export default 42;'); + assert.strictEqual(run('../_tmp/output/bundle.js'), 1); + sander.unlinkSync('test/_tmp/input/watched'); }, 'START', 'BUNDLE_START', 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - let unexpectedEvent = false; - watcher.once('event', event => { - unexpectedEvent = event; - }); - sander.writeFileSync('test/_tmp/input/dep.js', '= invalid'); - return wait(400).then(() => assert.strictEqual(unexpectedEvent, false)); + assert.strictEqual(run('../_tmp/output/bundle.js'), 2); + watcher.close(); } ]); }); }); - it('refuses to watch the output file (#15)', () => { + it('watches and rebuilds transform dependencies, with transform cache opt-out for custom cache', () => { + const file = 'test/_tmp/input/watched'; + let v = 1; return sander - .copydir('test/watch/samples/basic') + .copydir('test/watch/samples/watch-files') .to('test/_tmp/input') .then(() => { - const watcher = rollup.watch({ + watcher = rollup.watch({ input: 'test/_tmp/input/main.js', output: { file: 'test/_tmp/output/bundle.js', format: 'cjs' }, - watch: { chokidar } + plugins: { + name: 'x', + buildStart() { + try { + const text = sander.readFileSync(file).toString(); + this.emitAsset('test', text); + } catch (err) { + if (err.code !== 'ENOENT') throw err; + } + }, + transform() { + this.cache.set('someValue', 'someContent'); + return { code: `export default ${v++}`, dependencies: [path.resolve(file)] }; + } + } }); return sequence(watcher, [ @@ -567,41 +1425,47 @@ describe('rollup.watch', () => { 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - sander.writeFileSync('test/_tmp/input/main.js', `import '../output/bundle.js'`); - }, - 'START', - 'BUNDLE_START', - 'ERROR', - event => { - assert.strictEqual(event.error.message, 'Cannot import the generated bundle'); - sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + assert.strictEqual(run('../_tmp/output/bundle.js'), 1); + sander.unlinkSync('test/_tmp/input/watched'); }, 'START', 'BUNDLE_START', 'BUNDLE_END', 'END', () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + assert.strictEqual(run('../_tmp/output/bundle.js'), 2); } ]); }); }); - it('ignores files that are not specified in options.watch.include, if given', () => { + it('watches and rebuilds asset transform dependencies', () => { + let v = 1; return sander - .copydir('test/watch/samples/ignored') + .copydir('test/watch/samples/watch-files') .to('test/_tmp/input') .then(() => { - const watcher = rollup.watch({ + watcher = rollup.watch({ input: 'test/_tmp/input/main.js', output: { file: 'test/_tmp/output/bundle.js', format: 'cjs' }, - watch: { - chokidar, - include: ['test/_tmp/input/+(main|foo).js'] + plugins: { + transform() { + const file = 'test/_tmp/input/watched'; + try { + const text = sander.readFileSync(file).toString(); + this.emitAsset('test', text); + } catch (err) { + if (err.code !== 'ENOENT') throw err; + this.emitAsset('test', 'test'); + } + return { + code: `export default ${v++}`, + dependencies: v === 2 ? [path.resolve(file)] : [] + }; + } } }); @@ -611,52 +1475,38 @@ describe('rollup.watch', () => { 'BUNDLE_END', 'END', () => { - assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { - foo: 'foo-1', - bar: 'bar-1' - }); - sander.writeFileSync('test/_tmp/input/foo.js', `export default 'foo-2';`); + assert.strictEqual(run('../_tmp/output/bundle.js'), 1); + sander.unlinkSync('test/_tmp/input/watched'); }, 'START', 'BUNDLE_START', 'BUNDLE_END', 'END', () => { - assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { - foo: 'foo-2', - bar: 'bar-1' - }); - let unexpectedEvent = false; - watcher.once('event', event => { - unexpectedEvent = event; - }); - sander.writeFileSync('test/_tmp/input/bar.js', "export default 'bar-2';"); - return wait(400).then(() => { - assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { - foo: 'foo-2', - bar: 'bar-1' - }); - assert.strictEqual(unexpectedEvent, false); - }); + assert.strictEqual(run('../_tmp/output/bundle.js'), 2); } ]); }); }); - it('ignores files that are specified in options.watch.exclude, if given', () => { + it('watches and rebuilds transform dependencies created and removed between runs', () => { + let v = 1; return sander - .copydir('test/watch/samples/ignored') + .copydir('test/watch/samples/watch-files') .to('test/_tmp/input') .then(() => { - const watcher = rollup.watch({ + watcher = rollup.watch({ input: 'test/_tmp/input/main.js', output: { file: 'test/_tmp/output/bundle.js', format: 'cjs' }, - watch: { - chokidar, - exclude: ['test/_tmp/input/bar.js'] + plugins: { + transform() { + let dependencies = []; + if (v === 2) dependencies = ['./watched']; + return { code: `export default ${v++}`, dependencies }; + } } }); @@ -666,171 +1516,51 @@ describe('rollup.watch', () => { 'BUNDLE_END', 'END', () => { - assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { - foo: 'foo-1', - bar: 'bar-1' - }); - sander.writeFileSync('test/_tmp/input/foo.js', `export default 'foo-2';`); + assert.strictEqual(run('../_tmp/output/bundle.js'), 1); + sander.writeFileSync('test/_tmp/input/main.js', 'next'); }, 'START', 'BUNDLE_START', 'BUNDLE_END', 'END', () => { - assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { - foo: 'foo-2', - bar: 'bar-1' - }); - let unexpectedEvent = false; - watcher.once('event', event => { - unexpectedEvent = event; - }); - sander.writeFileSync('test/_tmp/input/bar.js', "export default 'bar-2';"); - return wait(400).then(() => { - assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { - foo: 'foo-2', - bar: 'bar-1' - }); - assert.strictEqual(unexpectedEvent, false); - }); - } - ]); - }); - }); - - it('only rebuilds the appropriate configs', () => { - return sander - .copydir('test/watch/samples/multiple') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch([ - { - input: 'test/_tmp/input/main1.js', - output: { - file: 'test/_tmp/output/bundle1.js', - format: 'cjs' - }, - watch: { chokidar } + assert.strictEqual(run('../_tmp/output/bundle.js'), 2); + sander.unlinkSync('test/_tmp/input/watched'); }, - { - input: 'test/_tmp/input/main2.js', - output: { - file: 'test/_tmp/output/bundle2.js', - format: 'cjs' - }, - watch: { chokidar } - } - ]); - - return sequence(watcher, [ 'START', 'BUNDLE_START', 'BUNDLE_END', - 'BUNDLE_START', - 'BUNDLE_END', 'END', () => { - assert.deepStrictEqual(run('../_tmp/output/bundle1.js'), 42); - assert.deepStrictEqual(run('../_tmp/output/bundle2.js'), 43); - sander.writeFileSync('test/_tmp/input/main2.js', 'export default 44'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.deepStrictEqual(run('../_tmp/output/bundle1.js'), 42); - assert.deepStrictEqual(run('../_tmp/output/bundle2.js'), 44); - } - ]); - }); - }); - - it('respects output.globals', () => { - return sander - .copydir('test/watch/samples/globals') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'iife', - globals: { - jquery: 'jQuery' - } - }, - watch: { chokidar }, - external: ['jquery'] - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - const generated = sander.readFileSync('test/_tmp/output/bundle.js', { - encoding: 'utf-8' - }); - assert.ok(/jQuery/.test(generated)); + assert.strictEqual(run('../_tmp/output/bundle.js'), 3); + sander.writeFileSync('test/_tmp/input/watched', 'ignored'); + return new Promise(resolve => setTimeout(resolve, 50)); } ]); }); }); - it('treats filenames literally, not as globs', () => { + it('watches transform dependencies when there are multiple modules', () => { + let v = 1; return sander - .copydir('test/watch/samples/non-glob') + .copydir('test/watch/samples/watch-files-multiple') .to('test/_tmp/input') .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', + watcher = rollup.watch({ + input: 'test/_tmp/input/index.js', output: { file: 'test/_tmp/output/bundle.js', format: 'cjs' }, - watch: { chokidar } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - sander.writeFileSync('test/_tmp/input/[foo]/bar.js', `export const bar = 43;`); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + plugins: { + transform(code, id) { + if (!id.includes('dep.txt')) { + return; + } + this.addWatchFile('test/_tmp/input/depdep.txt'); + return `export default ${v++};`; + } } - ]); - }); - }); - - it('updates the right hashes on dependency changes', () => { - let dynamicName; - let staticName; - let chunkName; - return sander - .copydir('test/watch/samples/hashing') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: ['test/_tmp/input/main-static.js', 'test/_tmp/input/main-dynamic.js'], - output: { - dir: 'test/_tmp/output', - format: 'cjs', - entryFileNames: '[name].[hash].js', - chunkFileNames: '[name].[hash].js' - }, - watch: { chokidar }, - experimentalCodeSplitting: true }); return sequence(watcher, [ @@ -839,761 +1569,18 @@ describe('rollup.watch', () => { 'BUNDLE_END', 'END', () => { - [dynamicName, staticName, chunkName] = sander.readdirSync('test/_tmp/output').sort(); - sander.rimrafSync('test/_tmp/output'); - - // this should only update the hash of that particular entry point - sander.writeFileSync( - 'test/_tmp/input/main-static.js', - "import {value} from './shared';\nexport default 2 * value;" - ); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - const [newDynamicName, newStaticName, newChunkName] = sander - .readdirSync('test/_tmp/output') - .sort(); - sander.rimrafSync('test/_tmp/output'); - assert.notEqual(newStaticName, staticName); - assert.strictEqual(newDynamicName, dynamicName); - assert.strictEqual(newChunkName, chunkName); - staticName = newStaticName; - - // this should update all hashes - sander.writeFileSync('test/_tmp/input/shared.js', 'export const value = 42;'); + assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { dep: 1, first: 'b' }); + sander.writeFileSync('test/_tmp/input/depdep.txt', 'changed'); }, 'START', 'BUNDLE_START', 'BUNDLE_END', 'END', () => { - const [newDynamicName, newStaticName, newChunkName] = sander - .readdirSync('test/_tmp/output') - .sort(); - assert.notEqual(newStaticName, staticName); - assert.notEqual(newDynamicName, dynamicName); - assert.notEqual(newChunkName, chunkName); + assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { dep: 2, first: 'b' }); } ]); }); }); - - describe('addWatchFile', () => { - it('supports adding additional watch files in plugin hooks', () => { - const watchChangeIds = []; - const buildStartFile = path.resolve('test/_tmp/input/buildStart'); - const loadFile = path.resolve('test/_tmp/input/load'); - const resolveIdFile = path.resolve('test/_tmp/input/resolveId'); - const transformFile = path.resolve('test/_tmp/input/transform'); - const watchFiles = [buildStartFile, loadFile, resolveIdFile, transformFile]; - return sander - .copydir('test/watch/samples/basic') - .to('test/_tmp/input') - .then(() => { - for (const file of watchFiles) sander.writeFileSync(file, 'initial'); - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - plugins: { - buildStart() { - this.addWatchFile(buildStartFile); - }, - load() { - this.addWatchFile(loadFile); - }, - resolveId() { - this.addWatchFile(resolveIdFile); - }, - transform() { - this.addWatchFile(transformFile); - }, - watchChange(id) { - watchChangeIds.push(id); - } - }, - watch: { chokidar } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - assert.deepStrictEqual(watchChangeIds, []); - for (const file of watchFiles) sander.writeFileSync(file, 'changed'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - assert.deepStrictEqual(watchChangeIds.sort(), watchFiles.sort()); - } - ]); - }); - }); - - it('respects changed watched files in the load hook', () => { - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - plugins: { - load() { - this.addWatchFile('test/_tmp/input/watched'); - return `export default "${sander - .readFileSync('test/_tmp/input/watched') - .toString() - .trim()}"`; - } - }, - watch: { chokidar } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 'initial'); - sander.writeFileSync('test/_tmp/input/watched', 'next'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 'next'); - } - ]); - }); - }); - - it('respects changed watched files in the transform hook', () => { - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - plugins: { - resolveId(id) { - if (id === 'dep') { - return id; - } - }, - load(id) { - if (id === 'dep') { - return `throw new Error('This should not be executed);`; - } - }, - transform(code, id) { - if (id.endsWith('main.js')) { - return `export { value as default } from 'dep';`; - } else { - this.addWatchFile('test/_tmp/input/watched'); - return `export const value = "${sander - .readFileSync('test/_tmp/input/watched') - .toString() - .trim()}"`; - } - } - }, - watch: { chokidar } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 'initial'); - sander.writeFileSync('test/_tmp/input/watched', 'next'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 'next'); - } - ]); - }); - }); - - it('respects changed watched modules that are already part of the graph in the transform hook', () => { - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - plugins: { - transform() { - this.addWatchFile('test/_tmp/input/main.js'); - return `export default "${sander - .readFileSync('test/_tmp/input/main.js') - .toString() - .trim()}"`; - } - }, - watch: { chokidar } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 'export default 42;'); - sander.writeFileSync('test/_tmp/input/main.js', 'next'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 'next'); - } - ]); - }); - }); - - it('respects changed watched directories in the transform hook', () => { - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - plugins: { - transform() { - this.addWatchFile('test/_tmp/input'); - return `export default ${sander.existsSync('test/_tmp/input/watched')}`; - } - }, - watch: { chokidar } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), true); - sander.unlinkSync('test/_tmp/input/watched'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), false); - watcher.close(); - } - ]); - }); - }); - - it('does not rerun the transform hook if a non-watched change triggered the re-run', () => { - let transformRuns = 0; - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') - .then(() => { - sander.writeFileSync('test/_tmp/input/alsoWatched', 'initial'); - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - plugins: { - buildStart() { - this.addWatchFile('test/_tmp/input/alsoWatched'); - }, - transform() { - transformRuns++; - this.addWatchFile('test/_tmp/input/watched'); - return `export default "${sander - .readFileSync('test/_tmp/input/watched') - .toString() - .trim()}"`; - } - }, - watch: { chokidar } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(transformRuns, 1); - sander.writeFileSync('test/_tmp/input/alsoWatched', 'next'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(transformRuns, 1); - } - ]); - }); - }); - }); - - describe('deprecated features', () => { - it('provides the watcher through the plugin context', () => { - const events = []; - return sander - .copydir('test/watch/samples/basic') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - onwarn(warning) { - assert.strictEqual( - warning.message, - 'this.watcher usage is deprecated in plugins. Use the watchChange plugin hook and this.addWatchFile() instead.' - ); - }, - watch: { chokidar }, - plugins: { - buildStart(id) { - if (!this.watcher) throw new Error('No Watcher'); - - this.watcher.on('event', event => { - events.push(event); - }); - } - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(events.length, 2); - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - sander.writeFileSync('test/_tmp/input/main.js', 'export default 43;'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); - assert.strictEqual(events.length, 8); - } - ]); - }); - }); - - it('watches and rebuilds transform dependencies', () => { - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - plugins: { - transform() { - return { - code: `export default "${sander - .readFileSync('test/_tmp/input/watched') - .toString() - .trim()}"`, - dependencies: ['./watched'] - }; - } - }, - watch: { chokidar } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 'initial'); - sander.writeFileSync('test/_tmp/input/watched', 'next'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 'next'); - } - ]); - }); - }); - - it("throws if transform dependency doesn't exist", () => { - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - plugins: { - transform() { - return { - code: `export default "${sander - .readFileSync('test/_tmp/input/watched') - .toString() - .trim()}"`, - dependencies: ['./doesnotexist'] - }; - } - }, - watch: { chokidar } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'ERROR', - event => { - assert.ok(event.error.message.startsWith('Transform dependency')); - assert.ok(event.error.message.endsWith('does not exist.')); - } - ]); - }); - }); - - it('watches and rebuilds transform dependencies that are modules', () => { - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - plugins: { - transform() { - const dependencies = ['./main.js']; - const text = sander - .readFileSync('test/_tmp/input/main.js') - .toString() - .trim(); - return { code: `export default "${text}"`, dependencies }; - } - }, - watch: { chokidar } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 'export default 42;'); - sander.writeFileSync('test/_tmp/input/main.js', 'next'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 'next'); - } - ]); - }); - }); - - it('watches and rebuilds transform dependencies directories', () => { - let v = 1; - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - plugins: { - transform() { - const dependencies = ['./']; - return { code: `export default ${v++}`, dependencies }; - } - }, - watch: { chokidar } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 1); - sander.unlinkSync('test/_tmp/input/watched'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 2); - watcher.close(); - } - ]); - }); - }); - - it('watches and rebuilds transform dependencies, with transform cache opt-out for custom cache', () => { - const file = 'test/_tmp/input/watched'; - let v = 1; - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - plugins: { - name: 'x', - buildStart() { - try { - const text = sander.readFileSync(file).toString(); - this.emitAsset('test', text); - } catch (err) { - if (err.code !== 'ENOENT') throw err; - } - }, - transform() { - this.cache.set('someValue', 'someContent'); - return { code: `export default ${v++}`, dependencies: [path.resolve(file)] }; - } - }, - watch: { chokidar } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 1); - sander.unlinkSync('test/_tmp/input/watched'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 2); - } - ]); - }); - }); - - it('watches and rebuilds asset transform dependencies', () => { - let v = 1; - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - plugins: { - transform() { - const file = 'test/_tmp/input/watched'; - try { - const text = sander.readFileSync(file).toString(); - this.emitAsset('test', text); - } catch (err) { - if (err.code !== 'ENOENT') throw err; - this.emitAsset('test', 'test'); - } - return { - code: `export default ${v++}`, - dependencies: v === 2 ? [path.resolve(file)] : [] - }; - } - }, - watch: { chokidar } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 1); - sander.unlinkSync('test/_tmp/input/watched'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 2); - } - ]); - }); - }); - - it('watches and rebuilds transform dependencies created and removed between runs', () => { - let v = 1; - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - plugins: { - transform() { - let dependencies = []; - if (v === 2) dependencies = ['./watched']; - return { code: `export default ${v++}`, dependencies }; - } - }, - watch: { chokidar } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 1); - sander.writeFileSync('test/_tmp/input/main.js', 'next'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 2); - sander.unlinkSync('test/_tmp/input/watched'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 3); - sander.writeFileSync('test/_tmp/input/watched', 'ignored'); - return new Promise(resolve => setTimeout(resolve, 50)); - } - ]); - }); - }); - - it('watches transform dependencies when there are multiple modules', () => { - let v = 1; - return sander - .copydir('test/watch/samples/watch-files-multiple') - .to('test/_tmp/input') - .then(() => { - const watcher = rollup.watch({ - input: 'test/_tmp/input/index.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs' - }, - plugins: { - transform(code, id) { - if (!id.includes('dep.txt')) { - return; - } - this.addWatchFile('test/_tmp/input/depdep.txt'); - return `export default ${v++};`; - } - }, - watch: { chokidar } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { dep: 1, first: 'b' }); - sander.writeFileSync('test/_tmp/input/depdep.txt', 'changed'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { dep: 2, first: 'b' }); - } - ]); - }); - }); - }); - } + }); });