From f348d9a943006158837973baa7685da611402a12 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Goetz?= <onigoetz@onigoetz.ch>
Date: Tue, 31 Aug 2021 22:43:11 +0200
Subject: [PATCH] Fix many tests, add hot-patching to get the ball rolling

---
 package.json                                  |   4 +-
 packages/crafty-preset-babel/src/gulp.js      |   7 +-
 .../src/commands/jsLint.js                    |   2 +-
 packages/crafty-preset-eslint/src/index.js    |   1 +
 packages/crafty-preset-eslint/src/resolver.js |   2 +-
 packages/crafty-preset-swc/src/gulp.js        |   7 +-
 packages/crafty-preset-typescript/src/gulp.js |   7 +-
 .../__snapshots__/crafty-preset-babel.js.snap |   3 -
 .../__snapshots__/crafty-preset-swc.js.snap   |   3 -
 patches/@eslint+eslintrc+1.0.0.patch          |  36 ++++
 patches/eslint+8.0.0-beta.1.patch             |  68 +++++++
 patches/eslint-plugin-import+2.24.2.patch     |  13 ++
 patches/gulp-eslint7+0.3.1.patch              |  70 +++++++
 yarn.lock                                     | 186 ++++++++----------
 14 files changed, 291 insertions(+), 118 deletions(-)
 create mode 100644 patches/@eslint+eslintrc+1.0.0.patch
 create mode 100644 patches/eslint+8.0.0-beta.1.patch
 create mode 100644 patches/eslint-plugin-import+2.24.2.patch
 create mode 100644 patches/gulp-eslint7+0.3.1.patch

diff --git a/package.json b/package.json
index 134b96948..8835b9b9f 100644
--- a/package.json
+++ b/package.json
@@ -19,12 +19,14 @@
     "test": "jest --projects packages/integration packages/eslint-plugin-swissquote packages/stylelint-config-swissquote packages/crafty-runner-webpack packages/crafty && cd packages/rollup-plugin-eslint && yarn test",
     "test:ci": "sh test_ci.sh",
     "publish:canary": "oao publish --no-git-commit --no-check-uncommitted --no-changelog --publish-tag canary --bump-dependent-reqs=exact",
-    "publish:all": "oao publish --no-changelog --bump-dependent-reqs=exact"
+    "publish:all": "oao publish --no-changelog --bump-dependent-reqs=exact",
+    "postinstall": "patch-package"
   },
   "dependencies": {
     "jest": "27.1.0",
     "markdown-spellcheck": "1.3.1",
     "oao": "2.0.2",
+    "patch-package": "^6.4.7",
     "write-good": "1.0.8"
   },
   "engines": {
diff --git a/packages/crafty-preset-babel/src/gulp.js b/packages/crafty-preset-babel/src/gulp.js
index ead7f81d6..aa483ce05 100644
--- a/packages/crafty-preset-babel/src/gulp.js
+++ b/packages/crafty-preset-babel/src/gulp.js
@@ -19,7 +19,12 @@ module.exports = function createTask(crafty, bundle, StreamHandler) {
       toTempFile
     } = require("@swissquote/crafty-preset-eslint/src/eslintConfigurator");
     const eslint = require("gulp-eslint7");
-    stream.add(eslint(toTempFile(crafty.config.eslint))).add(eslint.format());
+    stream.add(eslint(
+      {
+        resolver: require.resolve("@swissquote/crafty-preset-eslint/src/resolver.js"),
+        overrideConfigFile: toTempFile(crafty.config.eslint)
+      }
+    )).add(eslint.format());
 
     // Fail the build if we have linting
     // errors and we build directly
diff --git a/packages/crafty-preset-eslint/src/commands/jsLint.js b/packages/crafty-preset-eslint/src/commands/jsLint.js
index f27e33434..01a6e457a 100755
--- a/packages/crafty-preset-eslint/src/commands/jsLint.js
+++ b/packages/crafty-preset-eslint/src/commands/jsLint.js
@@ -20,4 +20,4 @@ process.argv.push(require.resolve("../resolver.js"))
 process.argv.push("--config");
 process.argv.push(tmpfile);
 
-require("eslint/bin/eslint");
+require(".bin/eslint");
diff --git a/packages/crafty-preset-eslint/src/index.js b/packages/crafty-preset-eslint/src/index.js
index 81ba683ec..bb592e330 100644
--- a/packages/crafty-preset-eslint/src/index.js
+++ b/packages/crafty-preset-eslint/src/index.js
@@ -80,6 +80,7 @@ module.exports = {
       weight: -20,
       options: {
         overrideConfigFile: toTempFile(crafty.config.eslint),
+        resolver: require.resolve("@swissquote/crafty-preset-eslint/src/resolver.js"),
         throwOnError: crafty.getEnvironment() === "production",
         exclude: [/node_modules/],
         include: crafty.config.eslintExtensions.map(
diff --git a/packages/crafty-preset-eslint/src/resolver.js b/packages/crafty-preset-eslint/src/resolver.js
index 4096536bb..08f593a49 100644
--- a/packages/crafty-preset-eslint/src/resolver.js
+++ b/packages/crafty-preset-eslint/src/resolver.js
@@ -3,7 +3,7 @@ const {
 } = require("@eslint/eslintrc");
 
 function resolve(moduleName, relativeToPath) {
-  console.log("resolving", { moduleName, relativeToPath });
+  //console.log({moduleName, relativeToPath});
   try {
     // First check for the module relative to the current location
     return ModuleResolver.resolve(moduleName, __filename);
diff --git a/packages/crafty-preset-swc/src/gulp.js b/packages/crafty-preset-swc/src/gulp.js
index 1f8b238ba..39a588d3c 100644
--- a/packages/crafty-preset-swc/src/gulp.js
+++ b/packages/crafty-preset-swc/src/gulp.js
@@ -19,7 +19,12 @@ module.exports = function createTask(crafty, bundle, StreamHandler) {
       toTempFile
     } = require("@swissquote/crafty-preset-eslint/src/eslintConfigurator");
     const eslint = require("gulp-eslint7");
-    stream.add(eslint(toTempFile(crafty.config.eslint))).add(eslint.format());
+    stream.add(eslint(
+      {
+        resolver: require.resolve("@swissquote/crafty-preset-eslint/src/resolver.js"),
+        overrideConfigFile: toTempFile(crafty.config.eslint)
+      }
+    )).add(eslint.format());
 
     // Fail the build if we have linting
     // errors and we build directly
diff --git a/packages/crafty-preset-typescript/src/gulp.js b/packages/crafty-preset-typescript/src/gulp.js
index 26351d10d..f075ac57e 100644
--- a/packages/crafty-preset-typescript/src/gulp.js
+++ b/packages/crafty-preset-typescript/src/gulp.js
@@ -20,7 +20,12 @@ module.exports = function createTask(crafty, bundle, StreamHandler) {
     } = require("@swissquote/crafty-preset-eslint/src/eslintConfigurator");
     const eslint = require("gulp-eslint7");
     stream
-      .add(eslint({ configFile: toTempFile(crafty.config.eslint) }))
+      .add(eslint(
+        {
+          resolver: require.resolve("@swissquote/crafty-preset-eslint/src/resolver.js"),
+          overrideConfigFile: toTempFile(crafty.config.eslint)
+        }
+      ))
       .add(eslint.format());
 
     // Fail the build if we have linting
diff --git a/packages/integration/__tests__/__snapshots__/crafty-preset-babel.js.snap b/packages/integration/__tests__/__snapshots__/crafty-preset-babel.js.snap
index 83513e187..9186d913a 100644
--- a/packages/integration/__tests__/__snapshots__/crafty-preset-babel.js.snap
+++ b/packages/integration/__tests__/__snapshots__/crafty-preset-babel.js.snap
@@ -17,9 +17,6 @@ exports[`Generates IDE Helper 2`] = `
 // This file is generated to improve IDE Integration
 // You don't need to commit this file, nor need it to run \`crafty build\`
 
-// Fix module resolution
-require(\\"__PATH__/packages/crafty-preset-eslint/src/patchModuleResolver.js\\");
-
 module.exports = {
     \\"plugins\\": [
         \\"@swissquote/swissquote\\"
diff --git a/packages/integration/__tests__/__snapshots__/crafty-preset-swc.js.snap b/packages/integration/__tests__/__snapshots__/crafty-preset-swc.js.snap
index 7b8451fbd..05c3dc89d 100644
--- a/packages/integration/__tests__/__snapshots__/crafty-preset-swc.js.snap
+++ b/packages/integration/__tests__/__snapshots__/crafty-preset-swc.js.snap
@@ -17,9 +17,6 @@ exports[`Generates IDE Helper 2`] = `
 // This file is generated to improve IDE Integration
 // You don't need to commit this file, nor need it to run \`crafty build\`
 
-// Fix module resolution
-require(\\"__PATH__/packages/crafty-preset-eslint/src/patchModuleResolver.js\\");
-
 module.exports = {
     \\"plugins\\": [
         \\"@swissquote/swissquote\\"
diff --git a/patches/@eslint+eslintrc+1.0.0.patch b/patches/@eslint+eslintrc+1.0.0.patch
new file mode 100644
index 000000000..813f43602
--- /dev/null
+++ b/patches/@eslint+eslintrc+1.0.0.patch
@@ -0,0 +1,36 @@
+diff --git a/node_modules/@eslint/eslintrc/dist/eslintrc.cjs b/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
+index b8d5f8c..bbd1ccc 100644
+--- a/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
++++ b/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
+@@ -3228,11 +3228,11 @@ class ConfigArrayFactory {
+     _loadParser(nameOrPath, ctx) {
+         debug$2("Loading parser %j from %s", nameOrPath, ctx.filePath);
+ 
+-        const { cwd } = internalSlotsMap$1.get(this);
++        const { cwd, resolver } = internalSlotsMap$1.get(this);
+         const relativeTo = ctx.filePath || path__default['default'].join(cwd, "__placeholder__.js");
+ 
+         try {
+-            const filePath = resolve(nameOrPath, relativeTo);
++            const filePath = resolver.resolve(nameOrPath, relativeTo);
+ 
+             writeDebugLogForLoading(nameOrPath, relativeTo, filePath);
+ 
+@@ -3279,7 +3279,7 @@ class ConfigArrayFactory {
+     _loadPlugin(name, ctx) {
+         debug$2("Loading plugin %j from %s", name, ctx.filePath);
+ 
+-        const { additionalPluginPool } = internalSlotsMap$1.get(this);
++        const { additionalPluginPool, resolver } = internalSlotsMap$1.get(this);
+         const request = normalizePackageName(name, "eslint-plugin");
+         const id = getShorthandName(request, "eslint-plugin");
+         const relativeTo = path__default['default'].join(ctx.pluginBasePath, "__placeholder__.js");
+@@ -3320,7 +3320,7 @@ class ConfigArrayFactory {
+         let error;
+ 
+         try {
+-            filePath = resolve(request, relativeTo);
++            filePath = resolver.resolve(request, relativeTo);
+         } catch (resolveError) {
+             error = resolveError;
+             /* istanbul ignore else */
diff --git a/patches/eslint+8.0.0-beta.1.patch b/patches/eslint+8.0.0-beta.1.patch
new file mode 100644
index 000000000..2303dede5
--- /dev/null
+++ b/patches/eslint+8.0.0-beta.1.patch
@@ -0,0 +1,68 @@
+diff --git a/node_modules/eslint/lib/cli-engine/cli-engine.js b/node_modules/eslint/lib/cli-engine/cli-engine.js
+index aae7160..45c7156 100644
+--- a/node_modules/eslint/lib/cli-engine/cli-engine.js
++++ b/node_modules/eslint/lib/cli-engine/cli-engine.js
+@@ -595,6 +595,7 @@ class CLIEngine {
+             cwd: options.cwd,
+             ignorePath: options.ignorePath,
+             resolvePluginsRelativeTo: options.resolvePluginsRelativeTo,
++            resolver: options.resolver,
+             rulePaths: options.rulePaths,
+             specificConfigPath: options.configFile,
+             useEslintrc: options.useEslintrc,
+diff --git a/node_modules/eslint/lib/cli.js b/node_modules/eslint/lib/cli.js
+index 477310d..af6a75a 100644
+--- a/node_modules/eslint/lib/cli.js
++++ b/node_modules/eslint/lib/cli.js
+@@ -83,6 +83,7 @@ function translateOptions({
+     quiet,
+     reportUnusedDisableDirectives,
+     resolvePluginsRelativeTo,
++    resolver,
+     rule,
+     rulesdir
+ }) {
+@@ -119,6 +120,7 @@ function translateOptions({
+         overrideConfigFile: config,
+         reportUnusedDisableDirectives: reportUnusedDisableDirectives ? "error" : void 0,
+         resolvePluginsRelativeTo,
++        resolver,
+         rulePaths: rulesdir,
+         useEslintrc: eslintrc
+     };
+diff --git a/node_modules/eslint/lib/eslint/eslint.js b/node_modules/eslint/lib/eslint/eslint.js
+index b4a1d02..89213d0 100644
+--- a/node_modules/eslint/lib/eslint/eslint.js
++++ b/node_modules/eslint/lib/eslint/eslint.js
+@@ -173,6 +173,7 @@ function processOptions({
+     plugins = {},
+     reportUnusedDisableDirectives = null, // ← should be null by default because if it's a string then it overrides the 'reportUnusedDisableDirectives' setting in config files. And we cannot use `overrideConfig.reportUnusedDisableDirectives` instead because we cannot configure the `error` severity with that.
+     resolvePluginsRelativeTo = null, // ← should be null by default because if it's a string then it suppresses RFC47 feature.
++    resolver = null,
+     rulePaths = [],
+     useEslintrc = true,
+     ...unknownOptions
+@@ -305,6 +306,7 @@ function processOptions({
+         ignorePath,
+         reportUnusedDisableDirectives,
+         resolvePluginsRelativeTo,
++        resolver: resolver ? require(resolver) : undefined,
+         rulePaths,
+         useEslintrc
+     };
+diff --git a/node_modules/eslint/lib/options.js b/node_modules/eslint/lib/options.js
+index 2dd186d..dfe32c1 100644
+--- a/node_modules/eslint/lib/options.js
++++ b/node_modules/eslint/lib/options.js
+@@ -115,6 +115,11 @@ module.exports = optionator({
+             type: "path::String",
+             description: "A folder where plugins should be resolved from, CWD by default"
+         },
++        {
++            option: "resolver",
++            type: "path::String",
++            description: "Absolute path to a resolver module"
++        },
+         {
+             heading: "Specifying rules and plugins"
+         },
diff --git a/patches/eslint-plugin-import+2.24.2.patch b/patches/eslint-plugin-import+2.24.2.patch
new file mode 100644
index 000000000..f5b221131
--- /dev/null
+++ b/patches/eslint-plugin-import+2.24.2.patch
@@ -0,0 +1,13 @@
+diff --git a/node_modules/eslint-plugin-import/lib/rules/no-unused-modules.js b/node_modules/eslint-plugin-import/lib/rules/no-unused-modules.js
+index bda956c..29be68e 100644
+--- a/node_modules/eslint-plugin-import/lib/rules/no-unused-modules.js
++++ b/node_modules/eslint-plugin-import/lib/rules/no-unused-modules.js
+@@ -17,7 +17,7 @@ var _arrayIncludes = require('array-includes');var _arrayIncludes2 = _interopReq
+                                                                                                                                                                                                                                                                                                                                                                                                        * @author René Fermann
+                                                                                                                                                                                                                                                                                                                                                                                                        */ // eslint/lib/util/glob-util has been moved to eslint/lib/util/glob-utils with version 5.3
+ // and has been moved to eslint/lib/cli-engine/file-enumerator in version 6
+-var listFilesToProcess = void 0;try {var FileEnumerator = require('eslint/lib/cli-engine/file-enumerator').FileEnumerator;
++var listFilesToProcess = void 0;try {var FileEnumerator = require('eslint/use-at-your-own-risk').FileEnumerator;
+   listFilesToProcess = function listFilesToProcess(src, extensions) {
+     var e = new FileEnumerator({
+       extensions: extensions });
diff --git a/patches/gulp-eslint7+0.3.1.patch b/patches/gulp-eslint7+0.3.1.patch
new file mode 100644
index 000000000..5942fde49
--- /dev/null
+++ b/patches/gulp-eslint7+0.3.1.patch
@@ -0,0 +1,70 @@
+diff --git a/node_modules/gulp-eslint7/index.js b/node_modules/gulp-eslint7/index.js
+index 533550e..7592722 100644
+--- a/node_modules/gulp-eslint7/index.js
++++ b/node_modules/gulp-eslint7/index.js
+@@ -70,6 +70,11 @@ function gulpEslint(options) {
+ 	const { eslintOptions, quiet, warnIgnored } = migrateOptions(options);
+ 	const linter = new ESLint(eslintOptions);
+ 
++	// yes that's ugly, we'll see for a better solution in a PR
++	resolveFormatter(linter, "stylish").then(formatter => {
++		gulpEslint.formatter = formatter;
++	})
++
+ 	return transform((file, enc, cb) => {
+ 		lintFile(linter, file, quiet, warnIgnored)
+ 			.then(() => cb(null, file))
+@@ -174,10 +179,9 @@ gulpEslint.failAfterError = () => {
+  * @returns {stream} gulp file stream
+  */
+ gulpEslint.formatEach = (formatter, writable) => {
+-	formatter = resolveFormatter(formatter);
+ 	writable = resolveWritable(writable);
+ 
+-	return gulpEslint.result(result => writeResults([result], formatter, writable));
++	return gulpEslint.result(result => writeResults([result], gulpEslint.formatter, writable));
+ };
+ 
+ /**
+@@ -188,13 +192,12 @@ gulpEslint.formatEach = (formatter, writable) => {
+  * @returns {stream} gulp file stream
+  */
+ gulpEslint.format = (formatter, writable) => {
+-	formatter = resolveFormatter(formatter);
+ 	writable = resolveWritable(writable);
+ 
+ 	return gulpEslint.results(results => {
+ 		// Only format results if files has been lint'd
+ 		if (results.length) {
+-			writeResults(results, formatter, writable);
++			writeResults(results, gulpEslint.formatter, writable);
+ 		}
+ 	});
+ };
+diff --git a/node_modules/gulp-eslint7/util.js b/node_modules/gulp-eslint7/util.js
+index bf44540..9635b59 100644
+--- a/node_modules/gulp-eslint7/util.js
++++ b/node_modules/gulp-eslint7/util.js
+@@ -282,11 +282,11 @@ exports.filterResult = (result, filter) => {
+  * @param {(String|Function)} [formatter=stylish] - A name to resolve as a formatter. If a function is provided, the same function is returned.
+  * @returns {Function} An ESLint formatter
+  */
+-exports.resolveFormatter = (formatter) => {
++exports.resolveFormatter = async (linter, formatter) => {
+ 	// use ESLint to look up formatter references
+ 	if (typeof formatter !== 'function') {
+ 		// load formatter (module, relative to cwd, ESLint formatter)
+-		formatter =	CLIEngine.getFormatter(formatter);
++		formatter =	linter.loadFormatter(formatter);
+ 	}
+ 
+ 	return formatter;
+@@ -321,7 +321,7 @@ exports.writeResults = (results, formatter, writable) => {
+ 
+ 	const firstResult = results.find(result => result.config);
+ 
+-	const message = formatter(results, firstResult ? firstResult.config : {});
++	const message = formatter.format(results, firstResult ? firstResult.config : {});
+ 	if (writable && message != null && message !== '') {
+ 		writable(message);
+ 	}
diff --git a/yarn.lock b/yarn.lock
index 0017eec15..f0471c126 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,13 +2,6 @@
 # yarn lockfile v1
 
 
-"@babel/code-frame@7.12.11":
-  version "7.12.11"
-  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
-  integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==
-  dependencies:
-    "@babel/highlight" "^7.10.4"
-
 "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5", "@babel/code-frame@^7.8.3":
   version "7.14.5"
   resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb"
@@ -258,7 +251,7 @@
     "@babel/traverse" "^7.15.0"
     "@babel/types" "^7.15.0"
 
-"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5":
+"@babel/highlight@^7.14.5":
   version "7.14.5"
   resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9"
   integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==
@@ -984,21 +977,6 @@
   resolved "https://registry.yarnpkg.com/@csstools/sass-import-resolve/-/sass-import-resolve-1.0.0.tgz#32c3cdb2f7af3cd8f0dca357b592e7271f3831b5"
   integrity sha512-pH4KCsbtBLLe7eqUrw8brcuFO8IZlN36JjdKlOublibVdAIPHCzEnpBWOVUXK5sCf+DpBi8ZtuWtjF0srybdeA==
 
-"@eslint/eslintrc@^0.4.3":
-  version "0.4.3"
-  resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
-  integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==
-  dependencies:
-    ajv "^6.12.4"
-    debug "^4.1.1"
-    espree "^7.3.0"
-    globals "^13.9.0"
-    ignore "^4.0.6"
-    import-fresh "^3.2.1"
-    js-yaml "^3.13.1"
-    minimatch "^3.0.4"
-    strip-json-comments "^3.1.1"
-
 "@eslint/eslintrc@^1.0.0":
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.0.tgz#08309b915051dbfcfea8c3cdfc832375303396c9"
@@ -1038,15 +1016,6 @@
     normalize-path "^2.0.1"
     through2 "^2.0.3"
 
-"@humanwhocodes/config-array@^0.5.0":
-  version "0.5.0"
-  resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9"
-  integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==
-  dependencies:
-    "@humanwhocodes/object-schema" "^1.2.0"
-    debug "^4.1.1"
-    minimatch "^3.0.4"
-
 "@humanwhocodes/config-array@^0.6.0":
   version "0.6.0"
   resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.6.0.tgz#b5621fdb3b32309d2d16575456cbc277fa8f021a"
@@ -1918,6 +1887,11 @@
   resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
   integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
 
+"@yarnpkg/lockfile@^1.1.0":
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
+  integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
+
 "@zeit/schemas@2.6.0":
   version "2.6.0"
   resolved "https://registry.yarnpkg.com/@zeit/schemas/-/schemas-2.6.0.tgz#004e8e553b4cd53d538bd38eac7bcbf58a867fe3"
@@ -1964,7 +1938,7 @@ acorn@^6.4.1:
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
   integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==
 
-acorn@^7.1.1, acorn@^7.4.0:
+acorn@^7.1.1:
   version "7.4.1"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
   integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
@@ -3223,6 +3197,11 @@ chrome-trace-event@^1.0.2:
   resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac"
   integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==
 
+ci-info@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
+  integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
+
 ci-info@^3.1.1:
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6"
@@ -3481,7 +3460,7 @@ commander@^6.2.0:
   resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
   integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
 
-commander@^7.2.0:
+commander@^7.1.0:
   version "7.2.0"
   resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
   integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
@@ -3722,7 +3701,7 @@ cross-spawn@^5.0.1:
     shebang-command "^1.2.0"
     which "^1.2.9"
 
-cross-spawn@^6.0.0:
+cross-spawn@^6.0.0, cross-spawn@^6.0.5:
   version "6.0.5"
   resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
   integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
@@ -3814,7 +3793,7 @@ css-tokenize@^1.0.1:
     inherits "^2.0.1"
     readable-stream "^1.0.33"
 
-css-tree@^1.1.2, css-tree@^1.1.3:
+css-tree@^1.1.2:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
   integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==
@@ -3937,7 +3916,7 @@ debug@3.X, debug@^3.1.0, debug@^3.1.1, debug@^3.2.7:
   dependencies:
     ms "^2.1.1"
 
-debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2:
+debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2:
   version "4.3.2"
   resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
   integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
@@ -4591,13 +4570,6 @@ eslint-scope@^6.0.0:
     esrecurse "^4.3.0"
     estraverse "^5.2.0"
 
-eslint-utils@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27"
-  integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==
-  dependencies:
-    eslint-visitor-keys "^1.1.0"
-
 eslint-utils@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672"
@@ -4605,11 +4577,6 @@ eslint-utils@^3.0.0:
   dependencies:
     eslint-visitor-keys "^2.0.0"
 
-eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e"
-  integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==
-
 eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
@@ -4632,7 +4599,7 @@ eslint-webpack-plugin@2.5.4:
     normalize-path "^3.0.0"
     schema-utils "^3.0.0"
 
-eslint@8.0.0-beta.1:
+eslint@8.0.0-beta.1, eslint@^7.25.0:
   version "8.0.0-beta.1"
   resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.0.0-beta.1.tgz#5cd74684dbcfd8abee08cc10de578294124539b5"
   integrity sha512-+3EHhCIJHUXuksq6dUSe1Nv9+sdFaLfct6ZiWdFYrHU8u9tX6QQWGdKJQuQXUlUdhMMh6cchRFIQ7OqSAcyq7A==
@@ -4676,61 +4643,6 @@ eslint@8.0.0-beta.1:
     text-table "^0.2.0"
     v8-compile-cache "^2.0.3"
 
-eslint@^7.25.0:
-  version "7.32.0"
-  resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d"
-  integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==
-  dependencies:
-    "@babel/code-frame" "7.12.11"
-    "@eslint/eslintrc" "^0.4.3"
-    "@humanwhocodes/config-array" "^0.5.0"
-    ajv "^6.10.0"
-    chalk "^4.0.0"
-    cross-spawn "^7.0.2"
-    debug "^4.0.1"
-    doctrine "^3.0.0"
-    enquirer "^2.3.5"
-    escape-string-regexp "^4.0.0"
-    eslint-scope "^5.1.1"
-    eslint-utils "^2.1.0"
-    eslint-visitor-keys "^2.0.0"
-    espree "^7.3.1"
-    esquery "^1.4.0"
-    esutils "^2.0.2"
-    fast-deep-equal "^3.1.3"
-    file-entry-cache "^6.0.1"
-    functional-red-black-tree "^1.0.1"
-    glob-parent "^5.1.2"
-    globals "^13.6.0"
-    ignore "^4.0.6"
-    import-fresh "^3.0.0"
-    imurmurhash "^0.1.4"
-    is-glob "^4.0.0"
-    js-yaml "^3.13.1"
-    json-stable-stringify-without-jsonify "^1.0.1"
-    levn "^0.4.1"
-    lodash.merge "^4.6.2"
-    minimatch "^3.0.4"
-    natural-compare "^1.4.0"
-    optionator "^0.9.1"
-    progress "^2.0.0"
-    regexpp "^3.1.0"
-    semver "^7.2.1"
-    strip-ansi "^6.0.0"
-    strip-json-comments "^3.1.0"
-    table "^6.0.9"
-    text-table "^0.2.0"
-    v8-compile-cache "^2.0.3"
-
-espree@^7.3.0, espree@^7.3.1:
-  version "7.3.1"
-  resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6"
-  integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==
-  dependencies:
-    acorn "^7.4.0"
-    acorn-jsx "^5.3.1"
-    eslint-visitor-keys "^1.3.0"
-
 espree@^8.0.0:
   version "8.0.0"
   resolved "https://registry.yarnpkg.com/espree/-/espree-8.0.0.tgz#08c92c31814c96c96c54d3a35cc80f1cdb420275"
@@ -5209,6 +5121,13 @@ find-up@^4.0.0, find-up@^4.1.0:
     locate-path "^5.0.0"
     path-exists "^4.0.0"
 
+find-yarn-workspace-root@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd"
+  integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==
+  dependencies:
+    micromatch "^4.0.2"
+
 flat-cache@^3.0.4:
   version "3.0.4"
   resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11"
@@ -5334,6 +5253,15 @@ fs-extra@8.1.0:
     jsonfile "^4.0.0"
     universalify "^0.1.0"
 
+fs-extra@^7.0.1:
+  version "7.0.1"
+  resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
+  integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==
+  dependencies:
+    graceful-fs "^4.1.2"
+    jsonfile "^4.0.0"
+    universalify "^0.1.0"
+
 fs-extra@^9.0.0:
   version "9.1.0"
   resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
@@ -6336,6 +6264,13 @@ is-callable@^1.1.4, is-callable@^1.2.3:
   resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945"
   integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==
 
+is-ci@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c"
+  integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==
+  dependencies:
+    ci-info "^2.0.0"
+
 is-ci@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.0.tgz#c7e7be3c9d8eef7d0fa144390bd1e4b88dc4c994"
@@ -7335,6 +7270,13 @@ kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3:
   resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
   integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
 
+klaw-sync@^6.0.0:
+  version "6.0.0"
+  resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c"
+  integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==
+  dependencies:
+    graceful-fs "^4.1.11"
+
 kleur@^3.0.3:
   version "3.0.3"
   resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
@@ -8477,6 +8419,14 @@ onetime@^5.1.2:
   dependencies:
     mimic-fn "^2.1.0"
 
+open@^7.4.2:
+  version "7.4.2"
+  resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321"
+  integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==
+  dependencies:
+    is-docker "^2.0.0"
+    is-wsl "^2.1.1"
+
 open@^8.0.9:
   version "8.2.1"
   resolved "https://registry.yarnpkg.com/open/-/open-8.2.1.tgz#82de42da0ccbf429bc12d099dad2e0975e14e8af"
@@ -8727,6 +8677,25 @@ passive-voice@^0.1.0:
   resolved "https://registry.yarnpkg.com/passive-voice/-/passive-voice-0.1.0.tgz#16ff91ae40ba0e92c43e671763fdc842a70270b1"
   integrity sha1-Fv+RrkC6DpLEPmcXY/3IQqcCcLE=
 
+patch-package@^6.4.7:
+  version "6.4.7"
+  resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.4.7.tgz#2282d53c397909a0d9ef92dae3fdeb558382b148"
+  integrity sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==
+  dependencies:
+    "@yarnpkg/lockfile" "^1.1.0"
+    chalk "^2.4.2"
+    cross-spawn "^6.0.5"
+    find-yarn-workspace-root "^2.0.0"
+    fs-extra "^7.0.1"
+    is-ci "^2.0.0"
+    klaw-sync "^6.0.0"
+    minimist "^1.2.0"
+    open "^7.4.2"
+    rimraf "^2.6.3"
+    semver "^5.6.0"
+    slash "^2.0.0"
+    tmp "^0.0.33"
+
 path-browserify@0.0.1:
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a"
@@ -10587,6 +10556,11 @@ sisteransi@^1.0.5:
   resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
   integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==
 
+slash@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
+  integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==
+
 slash@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
@@ -11248,7 +11222,7 @@ symbol-tree@^3.2.4:
   resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
   integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
 
-table@^6.0.9, table@^6.6.0:
+table@^6.6.0:
   version "6.7.1"
   resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2"
   integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==