diff --git a/package.json b/package.json index acfa40d2..d0dd5300 100644 --- a/package.json +++ b/package.json @@ -75,8 +75,8 @@ "@babel/core": "7.7.4", "@babel/preset-env": "7.7.4", "@fortawesome/fontawesome-free": "5.11.2", - "@vue/server-test-utils": "1.0.0-beta.29", - "@vue/test-utils": "1.0.0-beta.29", + "@vue/server-test-utils": "1.0.0-beta.30", + "@vue/test-utils": "1.0.0-beta.30", "babel-loader": "8.0.6", "babel-plugin-istanbul": "5.2.0", "chai": "4.2.0", diff --git a/test/client/js/helpers/parse.js b/test/client/js/helpers/parse.js index 70272cd1..84ae096f 100644 --- a/test/client/js/helpers/parse.js +++ b/test/client/js/helpers/parse.js @@ -5,8 +5,8 @@ const expect = require("chai").expect; import {renderToString} from "@vue/server-test-utils"; import ParsedMessageTestWrapper from "../../components/ParsedMessageTestWrapper.vue"; -function getParsedMessageContents(text, message) { - let contents = renderToString(ParsedMessageTestWrapper, { +async function getParsedMessageContents(text, message) { + let contents = await renderToString(ParsedMessageTestWrapper, { propsData: { text, message, @@ -20,7 +20,7 @@ function getParsedMessageContents(text, message) { } describe("IRC formatted message parser", () => { - it("should not introduce xss", () => { + it("should not introduce xss", async () => { const testCases = [ { input: "", @@ -34,13 +34,15 @@ describe("IRC formatted message parser", () => { }, ]; - const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input)); + const actual = await Promise.all( + testCases.map((testCase) => getParsedMessageContents(testCase.input)) + ); const expected = testCases.map((testCase) => testCase.expected); expect(actual).to.deep.equal(expected); }); - it("should skip all <32 ASCII codes except linefeed", () => { + it("should skip all <32 ASCII codes except linefeed", async () => { const testCases = [ { input: @@ -50,13 +52,15 @@ describe("IRC formatted message parser", () => { }, ]; - const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input)); + const actual = await Promise.all( + testCases.map((testCase) => getParsedMessageContents(testCase.input)) + ); const expected = testCases.map((testCase) => testCase.expected); expect(actual).to.deep.equal(expected); }); - it("should find urls", () => { + it("should find urls", async () => { const testCases = [ { input: "irc://freenode.net/thelounge", @@ -99,13 +103,15 @@ describe("IRC formatted message parser", () => { }, ]; - const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input)); + const actual = await Promise.all( + testCases.map((testCase) => getParsedMessageContents(testCase.input)) + ); const expected = testCases.map((testCase) => testCase.expected); expect(actual).to.deep.equal(expected); }); - it("url with a dot parsed correctly", () => { + it("url with a dot parsed correctly", async () => { const input = "bonuspunkt: your URL parser misparses this URL: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx"; const correctResult = @@ -114,12 +120,12 @@ describe("IRC formatted message parser", () => { "https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx" + ""; - const actual = getParsedMessageContents(input); + const actual = await getParsedMessageContents(input); expect(actual).to.deep.equal(correctResult); }); - it("should balance brackets", () => { + it("should balance brackets", async () => { const testCases = [ { input: "", @@ -155,13 +161,15 @@ describe("IRC formatted message parser", () => { }, ]; - const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input)); + const actual = await Promise.all( + testCases.map((testCase) => getParsedMessageContents(testCase.input)) + ); const expected = testCases.map((testCase) => testCase.expected); expect(actual).to.deep.equal(expected); }); - it("should not find urls", () => { + it("should not find urls", async () => { const testCases = [ { input: "text www. text", @@ -173,13 +181,15 @@ describe("IRC formatted message parser", () => { }, ]; - const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input)); + const actual = await Promise.all( + testCases.map((testCase) => getParsedMessageContents(testCase.input)) + ); const expected = testCases.map((testCase) => testCase.expected); expect(actual).to.deep.equal(expected); }); - it("should find channels", () => { + it("should find channels", async () => { const testCases = [ { input: "#a", @@ -228,13 +238,15 @@ describe("IRC formatted message parser", () => { }, ]; - const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input)); + const actual = await Promise.all( + testCases.map((testCase) => getParsedMessageContents(testCase.input)) + ); const expected = testCases.map((testCase) => testCase.expected); expect(actual).to.deep.equal(expected); }); - it("should not find channels", () => { + it("should not find channels", async () => { const testCases = [ { input: "hi#test", @@ -246,7 +258,9 @@ describe("IRC formatted message parser", () => { }, ]; - const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input)); + const actual = await Promise.all( + testCases.map((testCase) => getParsedMessageContents(testCase.input)) + ); const expected = testCases.map((testCase) => testCase.expected); expect(actual).to.deep.equal(expected); @@ -342,14 +356,13 @@ describe("IRC formatted message parser", () => { expected: 'bold' + " " + 'bold', }, - ].forEach((item) => { - // TODO: In Node v6+, use `{name, input, expected}` - it(`should handle style characters: ${item.name}`, function() { - expect(getParsedMessageContents(item.input)).to.equal(item.expected); + ].forEach(({name, input, expected}) => { + it(`should handle style characters: ${name}`, async () => { + expect(await getParsedMessageContents(input)).to.equal(expected); }); }); - it("should find nicks", () => { + it("should find nicks", async () => { const testCases = [ { message: { @@ -364,15 +377,15 @@ describe("IRC formatted message parser", () => { }, ]; - const actual = testCases.map((testCase) => - getParsedMessageContents(testCase.input, testCase.message) + const actual = await Promise.all( + testCases.map((testCase) => getParsedMessageContents(testCase.input, testCase.message)) ); const expected = testCases.map((testCase) => testCase.expected); expect(actual).to.deep.equal(expected); }); - it("should not find nicks", () => { + it("should not find nicks", async () => { const testCases = [ { users: ["MaxLeiter, test"], @@ -392,13 +405,15 @@ describe("IRC formatted message parser", () => { }, ]; - const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input)); + const actual = await Promise.all( + testCases.map((testCase) => getParsedMessageContents(testCase.input)) + ); const expected = testCases.map((testCase) => testCase.expected); expect(actual).to.deep.equal(expected); }); - it("should go bonkers like mirc", () => { + it("should go bonkers like mirc", async () => { const testCases = [ { input: "\x02irc\x0f://\x1dfreenode.net\x0f/\x034,8thelounge", @@ -421,7 +436,9 @@ describe("IRC formatted message parser", () => { }, ]; - const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input)); + const actual = await Promise.all( + testCases.map((testCase) => getParsedMessageContents(testCase.input)) + ); const expected = testCases.map((testCase) => testCase.expected); expect(actual).to.deep.equal(expected); @@ -495,14 +512,13 @@ describe("IRC formatted message parser", () => { expected: '#i❤️thelounge', }, - ].forEach((item) => { - // TODO: In Node v6+, use `{name, input, expected}` - it(`should find emoji: ${item.name}`, function() { - expect(getParsedMessageContents(item.input)).to.equal(item.expected); + ].forEach(({name, input, expected}) => { + it(`should find emoji: ${name}`, async () => { + expect(await getParsedMessageContents(input)).to.equal(expected); }); }); - it("should optimize generated html", () => { + it("should optimize generated html", async () => { const testCases = [ { input: @@ -515,13 +531,15 @@ describe("IRC formatted message parser", () => { }, ]; - const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input)); + const actual = await Promise.all( + testCases.map((testCase) => getParsedMessageContents(testCase.input)) + ); const expected = testCases.map((testCase) => testCase.expected); expect(actual).to.deep.equal(expected); }); - it("should trim common protocols", () => { + it("should trim common protocols", async () => { const testCases = [ { input: "like..http://example.com", @@ -541,13 +559,15 @@ describe("IRC formatted message parser", () => { }, ]; - const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input)); + const actual = await Promise.all( + testCases.map((testCase) => getParsedMessageContents(testCase.input)) + ); const expected = testCases.map((testCase) => testCase.expected); expect(actual).to.deep.equal(expected); }); - it("should not find channel in fragment", () => { + it("should not find channel in fragment", async () => { const testCases = [ { input: "http://example.com/#hash", @@ -558,15 +578,17 @@ describe("IRC formatted message parser", () => { }, ]; - const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input)); + const actual = await Promise.all( + testCases.map((testCase) => getParsedMessageContents(testCase.input)) + ); const expected = testCases.map((testCase) => testCase.expected); expect(actual).to.deep.equal(expected); }); - it("should not overlap parts", () => { + it("should not overlap parts", async () => { const input = "Url: http://example.com/path Channel: ##channel"; - const actual = getParsedMessageContents(input); + const actual = await getParsedMessageContents(input); expect(actual).to.equal( 'Url: http://example.com/path ' + @@ -574,9 +596,9 @@ describe("IRC formatted message parser", () => { ); }); - it("should handle overlapping parts by using first starting", () => { + it("should handle overlapping parts by using first starting", async () => { const input = "#test-https://example.com"; - const actual = getParsedMessageContents(input); + const actual = await getParsedMessageContents(input); expect(actual).to.equal( '' + diff --git a/yarn.lock b/yarn.lock index 2761001d..c55eef27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -742,6 +742,13 @@ dependencies: defer-to-connect "^1.0.1" +"@types/cheerio@^0.22.10": + version "0.22.14" + resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.14.tgz#d150889891e7db892c6a0b16bd5583cc70b3fc44" + integrity sha512-SVtcP2fvPYrebTwpyqxjxb7K5v3ZOAdH409yAEWFPpZThCSGa1K2IFfx6Rg6ttvThCBQXP4fU9WF94sqLoiQGg== + dependencies: + "@types/node" "*" + "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" @@ -822,20 +829,22 @@ source-map "~0.6.1" vue-template-es2015-compiler "^1.9.0" -"@vue/server-test-utils@1.0.0-beta.29": - version "1.0.0-beta.29" - resolved "https://registry.yarnpkg.com/@vue/server-test-utils/-/server-test-utils-1.0.0-beta.29.tgz#8a61a9900992b742cda7c143593db1c5e4a019bd" - integrity sha512-N6e2cixTnz7+mos0wL+R3LM/2op+f3ym1aSQYuNfksZzvX81lrQtjGr6Aszv0+1Ryms+WrqlL18Jb/MY8XyXaQ== +"@vue/server-test-utils@1.0.0-beta.30": + version "1.0.0-beta.30" + resolved "https://registry.yarnpkg.com/@vue/server-test-utils/-/server-test-utils-1.0.0-beta.30.tgz#960a6383de81ba5ff763bdd6e961b9443e98fa82" + integrity sha512-H5vABB3uWbr+JlpN9pA7OpepYsHSmocbIHJQA00Xz0s4Qqmg4jX93GArO4KVC7zs/QS12w3mXfmMlYV8w7DwEg== dependencies: + "@types/cheerio" "^0.22.10" cheerio "^1.0.0-rc.2" -"@vue/test-utils@1.0.0-beta.29": - version "1.0.0-beta.29" - resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.0.0-beta.29.tgz#c942cf25e891cf081b6a03332b4ae1ef430726f0" - integrity sha512-yX4sxEIHh4M9yAbLA/ikpEnGKMNBCnoX98xE1RwxfhQVcn0MaXNSj1Qmac+ZydTj6VBSEVukchBogXBTwc+9iA== +"@vue/test-utils@1.0.0-beta.30": + version "1.0.0-beta.30" + resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.0.0-beta.30.tgz#d5f26d1e2411fdb7fa7fdedb61b4b4ea4194c49d" + integrity sha512-Wyvcha9fNk8+kzTDwb3xWGjPkCPzHSYSwKP6MplrPTG/auhqoad7JqUEceZLc6u7AU4km2pPQ8/m9s0RgCZ0NA== dependencies: dom-event-types "^1.0.0" - lodash "^4.17.4" + lodash "^4.17.15" + pretty "^2.0.0" "@webassemblyjs/ast@1.8.5": version "1.8.5" @@ -2020,16 +2029,16 @@ commander@4.0.1: resolved "https://registry.yarnpkg.com/commander/-/commander-4.0.1.tgz#b67622721785993182e807f4883633e6401ba53c" integrity sha512-IPF4ouhCP+qdlcmCedhxX4xiGBPyigb8v5NeUp+0LyhwLgxMqyp3S0vl7TAPfS/hiP7FC3caI/PB9lTmP8r1NA== +commander@^2.19.0, commander@~2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + commander@^2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== -commander@~2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -2070,6 +2079,23 @@ concat-stream@^1.5.0: readable-stream "^2.2.2" typedarray "^0.0.6" +condense-newlines@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/condense-newlines/-/condense-newlines-0.2.1.tgz#3de985553139475d32502c83b02f60684d24c55f" + integrity sha1-PemFVTE5R10yUCyDsC9gaE0kxV8= + dependencies: + extend-shallow "^2.0.1" + is-whitespace "^0.3.0" + kind-of "^3.0.2" + +config-chain@^1.1.12: + version "1.1.12" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" + integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + console-browserify@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" @@ -2807,6 +2833,16 @@ ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer "^5.0.1" +editorconfig@^0.15.3: + version "0.15.3" + resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" + integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== + dependencies: + commander "^2.19.0" + lru-cache "^4.1.5" + semver "^5.6.0" + sigmund "^1.0.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -4581,6 +4617,11 @@ is-whitespace-character@^1.0.0: resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.3.tgz#b3ad9546d916d7d3ffa78204bca0c26b56257fac" integrity sha512-SNPgMLz9JzPccD3nPctcj8sZlX9DAMJSKH8bP7Z6bohCwuNgX8xbWr1eTAYXX9Vpi/aSn8Y1akL9WgM3t43YNQ== +is-whitespace@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-whitespace/-/is-whitespace-0.3.0.tgz#1639ecb1be036aec69a54cbb401cfbed7114ab7f" + integrity sha1-Fjnssb4DauxppUy7QBz77XEUq38= + is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -4692,6 +4733,17 @@ istanbul-reports@^2.2.4: dependencies: handlebars "^4.1.2" +js-beautify@^1.6.12: + version "1.10.2" + resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.10.2.tgz#88c9099cd6559402b124cfab18754936f8a7b178" + integrity sha512-ZtBYyNUYJIsBWERnQP0rPN9KjkrDfJcMjuVGcvXOUJrD1zmOGwhRwQ4msG+HJ+Ni/FA7+sRQEMYVzdTQDvnzvQ== + dependencies: + config-chain "^1.1.12" + editorconfig "^0.15.3" + glob "^7.1.3" + mkdirp "~0.5.1" + nopt "~4.0.1" + js-levenshtein@^1.1.3: version "1.1.6" resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" @@ -4979,7 +5031,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@4.17.15, lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4: +lodash@4.17.15, lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -5033,7 +5085,7 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== -lru-cache@^4.0.1, lru-cache@^4.1.2: +lru-cache@^4.0.1, lru-cache@^4.1.2, lru-cache@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== @@ -5634,7 +5686,7 @@ nodent-runtime@^3.2.1: resolved "https://registry.yarnpkg.com/nodent-runtime/-/nodent-runtime-3.2.1.tgz#9e2755d85e39f764288f0d4752ebcfe3e541e00e" integrity sha512-7Ws63oC+215smeKJQCxzrK21VFVlCFBkwl0MOObt0HOpVQXs3u483sAmtkF33nNqZ5rSOQjB76fgyPBmAUrtCA== -nopt@^4.0.1: +nopt@^4.0.1, nopt@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= @@ -7017,6 +7069,15 @@ pretty-quick@2.0.1: mri "^1.1.4" multimatch "^4.0.0" +pretty@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pretty/-/pretty-2.0.0.tgz#adbc7960b7bbfe289a557dc5f737619a220d06a5" + integrity sha1-rbx5YLe7/iiaVX3F9zdhmiINBqU= + dependencies: + condense-newlines "^0.2.1" + extend-shallow "^2.0.1" + js-beautify "^1.6.12" + primer-support@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/primer-support/-/primer-support-5.0.0.tgz#d19c7cea59e8783400b9391943c8a2bb2ebddc5e" @@ -7054,6 +7115,11 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + proxy-addr@~2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34" @@ -7787,6 +7853,11 @@ shell-quote@^1.6.1: resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== +sigmund@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"