diff --git a/.github/header.psd b/.github/header.psd deleted file mode 100644 index 6b97142e..00000000 Binary files a/.github/header.psd and /dev/null differ diff --git a/.github/workflows/node-ci.js.yml b/.github/workflows/automated-tests.yml similarity index 82% rename from .github/workflows/node-ci.js.yml rename to .github/workflows/automated-tests.yml index 3178607d..9e1047b3 100644 --- a/.github/workflows/node-ci.js.yml +++ b/.github/workflows/automated-tests.yml @@ -17,18 +17,21 @@ jobs: matrix: node-version: [12.x, 14.x, 16.x] steps: - - uses: actions/checkout@v2 + - name: Checkout code + uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - - run: | - node -v + - name: Install dependencies and run tests + run: | Xvfb :99 -screen 0 1024x768x16 & export DISPLAY=:99 npm install + touch css/custom.css npm run test:prettier npm run test:js npm run test:css npm run test:unit npm run test:e2e + npm run test:electron diff --git a/.github/workflows/codecov-test-suites.yml b/.github/workflows/codecov-test-suites.yml index 88b7574d..8c2be8da 100644 --- a/.github/workflows/codecov-test-suites.yml +++ b/.github/workflows/codecov-test-suites.yml @@ -13,13 +13,17 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 steps: - - uses: actions/checkout@v2 - - run: | + - name: Checkout code + uses: actions/checkout@v2 + - name: Install dependencies and run coverage + run: | Xvfb :99 -screen 0 1024x768x16 & export DISPLAY=:99 npm ci + touch css/custom.css npm run test:coverage - - uses: codecov/codecov-action@v1 + - name: Upload coverage results to codecov + uses: codecov/codecov-action@v1 with: file: ./coverage/lcov.info fail_ci_if_error: true diff --git a/.github/workflows/enforce-changelog.yml b/.github/workflows/enforce-changelog.yml index a4f5d246..e1c2856d 100644 --- a/.github/workflows/enforce-changelog.yml +++ b/.github/workflows/enforce-changelog.yml @@ -11,8 +11,10 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 steps: - - uses: actions/checkout@v2 - - uses: dangoslen/changelog-enforcer@v1.6.1 + - name: Checkout code + uses: actions/checkout@v2 + - name: Enforce changelog️ + uses: dangoslen/changelog-enforcer@v1.6.1 with: changeLogPath: "CHANGELOG.md" skipLabels: "Skip Changelog" diff --git a/CHANGELOG.md b/CHANGELOG.md index 3eb00227..31bcb06a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,27 @@ This project adheres to [Semantic Versioning](https://semver.org/). ❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/donate) With your help we can continue to improve the MagicMirror² -## [2.17.0] - Unreleased (Develop Branch) +## [2.18.0] - Unreleased (Develop Branch) -_This release is scheduled to be released on 2021-10-01._ +_This release is scheduled to be released on 2022-01-01._ + +### Added + +### Updated + +- Cleaned up `updatenotification` module and switched to nunjuck template. + +### Fixed + +## [2.17.1] - 2021-10-01 + +### Fixed + +- Fixed error when accessing letsencrypt certificates + +## [2.17.0] - 2021-10-01 + +Special thanks to the following contributors: @apiontek, @eouia, @jupadin, @khassel and @rejas. ### Added @@ -27,7 +45,8 @@ _This release is scheduled to be released on 2021-10-01._ - Refactored methods from weatherproviders into weatherobject (isDaytime, updateSunTime). - Use of `logger.js` in jest tests. - Run prettier over all relevant files. -- Cleaned up updatenotification module and switched to nunjuck rendering. +- Move tests needing electron in new category `electron`, use `server only` mode in `e2e` tests. +- Update dependencies in package.json. ### Fixed diff --git a/js/app.js b/js/app.js index 6315370b..9ead45b2 100644 --- a/js/app.js +++ b/js/app.js @@ -48,6 +48,7 @@ process.on("uncaughtException", function (err) { */ function App() { let nodeHelpers = []; + let httpServer; /** * Loads the config file. Combines it with the defaults, and runs the @@ -222,7 +223,7 @@ function App() { } loadModules(modules, function () { - const server = new Server(config, function (app, io) { + httpServer = new Server(config, function (app, io) { Log.log("Server started ..."); for (let nodeHelper of nodeHelpers) { @@ -253,6 +254,7 @@ function App() { nodeHelper.stop(); } } + httpServer.close(); }; /** diff --git a/js/logger.js b/js/logger.js index 38185153..0ea523d7 100644 --- a/js/logger.js +++ b/js/logger.js @@ -9,12 +9,13 @@ */ (function (root, factory) { if (typeof exports === "object") { - // add timestamps in front of log messages - require("console-stamp")(console, { - pattern: "yyyy-mm-dd HH:MM:ss.l", - include: ["debug", "log", "info", "warn", "error"] - }); - + if (process.env.JEST_WORKER_ID === undefined) { + // add timestamps in front of log messages + require("console-stamp")(console, { + pattern: "yyyy-mm-dd HH:MM:ss.l", + include: ["debug", "log", "info", "warn", "error"] + }); + } // Node, CommonJS-like module.exports = factory(root.config); } else { @@ -22,32 +23,57 @@ root.Log = factory(root.config); } })(this, function (config) { - let logLevel = { - debug: Function.prototype.bind.call(console.debug, console), - log: Function.prototype.bind.call(console.log, console), - info: Function.prototype.bind.call(console.info, console), - warn: Function.prototype.bind.call(console.warn, console), - error: Function.prototype.bind.call(console.error, console), - group: Function.prototype.bind.call(console.group, console), - groupCollapsed: Function.prototype.bind.call(console.groupCollapsed, console), - groupEnd: Function.prototype.bind.call(console.groupEnd, console), - time: Function.prototype.bind.call(console.time, console), - timeEnd: Function.prototype.bind.call(console.timeEnd, console) - }; - - if ((typeof exports === "object" && process.env.JEST_WORKER_ID === undefined) || typeof exports !== "object") { - logLevel.timeStamp = Function.prototype.bind.call(console.timeStamp, console); + let logLevel; + let enableLog; + if (typeof exports === "object") { + // in nodejs and not running with jest + enableLog = process.env.JEST_WORKER_ID === undefined; + } else { + // in browser and not running with jsdom + enableLog = typeof window === "object" && window.name !== "jsdom"; } - logLevel.setLogLevel = function (newLevel) { - if (newLevel) { - Object.keys(logLevel).forEach(function (key, index) { - if (!newLevel.includes(key.toLocaleUpperCase())) { - logLevel[key] = function () {}; - } - }); - } - }; + if (enableLog) { + logLevel = { + debug: Function.prototype.bind.call(console.debug, console), + log: Function.prototype.bind.call(console.log, console), + info: Function.prototype.bind.call(console.info, console), + warn: Function.prototype.bind.call(console.warn, console), + error: Function.prototype.bind.call(console.error, console), + group: Function.prototype.bind.call(console.group, console), + groupCollapsed: Function.prototype.bind.call(console.groupCollapsed, console), + groupEnd: Function.prototype.bind.call(console.groupEnd, console), + time: Function.prototype.bind.call(console.time, console), + timeEnd: Function.prototype.bind.call(console.timeEnd, console), + timeStamp: Function.prototype.bind.call(console.timeStamp, console) + }; + + logLevel.setLogLevel = function (newLevel) { + if (newLevel) { + Object.keys(logLevel).forEach(function (key, index) { + if (!newLevel.includes(key.toLocaleUpperCase())) { + logLevel[key] = function () {}; + } + }); + } + }; + } else { + logLevel = { + debug: function () {}, + log: function () {}, + info: function () {}, + warn: function () {}, + error: function () {}, + group: function () {}, + groupCollapsed: function () {}, + groupEnd: function () {}, + time: function () {}, + timeEnd: function () {}, + timeStamp: function () {} + }; + + logLevel.setLogLevel = function () {}; + } return logLevel; }); diff --git a/js/server.js b/js/server.js index 5ce9435d..92607d39 100644 --- a/js/server.js +++ b/js/server.js @@ -23,6 +23,7 @@ const Utils = require("./utils.js"); */ function Server(config, callback) { const port = process.env.MM_PORT || config.port; + const serverSockets = new Set(); let server = null; if (config.useHttps) { @@ -42,6 +43,13 @@ function Server(config, callback) { allowEIO3: true }); + server.on("connection", (socket) => { + serverSockets.add(socket); + socket.on("close", () => { + serverSockets.delete(socket); + }); + }); + Log.log(`Starting server on port ${port} ... `); server.listen(port, config.address || "localhost"); @@ -92,6 +100,13 @@ function Server(config, callback) { if (typeof callback === "function") { callback(app, io); } + + this.close = function () { + for (const socket of serverSockets.values()) { + socket.destroy(); + } + server.close(); + }; } module.exports = Server; diff --git a/package-lock.json b/package-lock.json index 5a1c3fb9..e0d35515 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "magicmirror", - "version": "2.17.0-develop", + "version": "2.18.0-develop", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "magicmirror", - "version": "2.17.0-develop", + "version": "2.18.0-develop", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -21,22 +21,22 @@ "iconv-lite": "^0.6.3", "module-alias": "^2.2.2", "moment": "^2.29.1", - "node-fetch": "^2.6.2", + "node-fetch": "^2.6.5", "node-ical": "^0.13.0", "socket.io": "^4.2.0" }, "devDependencies": { "eslint-config-prettier": "^8.3.0", - "eslint-plugin-jest": "^24.4.0", + "eslint-plugin-jest": "^24.4.2", "eslint-plugin-jsdoc": "^36.1.0", "eslint-plugin-prettier": "^4.0.0", "express-basic-auth": "^1.2.0", "husky": "^7.0.2", - "jest": "^27.1.1", + "jest": "^27.2.2", "jsdom": "^17.0.0", "lodash": "^4.17.21", "nyc": "^15.1.0", - "prettier": "^2.4.0", + "prettier": "^2.4.1", "pretty-quick": "^3.1.1", "sinon": "^11.1.2", "spectron": "^15.0.0", @@ -50,7 +50,7 @@ "node": ">=12" }, "optionalDependencies": { - "electron": "^13.3.0" + "electron": "^13.5.1" } }, "node_modules/@babel/code-frame": { @@ -788,16 +788,16 @@ } }, "node_modules/@jest/console": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.1.1.tgz", - "integrity": "sha512-VpQJRsWSeAem0zpBjeRtDbcD6DlbNoK11dNYt+PSQ+DDORh9q2/xyEpErfwgnLjWX0EKkSZmTGx/iH9Inzs6vQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.2.2.tgz", + "integrity": "sha512-m7tbzPWyvSFfoanTknJoDnaeruDARsUe555tkVjG/qeaRDKwyPqqbgs4yFx583gmoETiAts1deeYozR5sVRhNA==", "dev": true, "dependencies": { "@jest/types": "^27.1.1", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.1.1", - "jest-util": "^27.1.1", + "jest-message-util": "^27.2.2", + "jest-util": "^27.2.0", "slash": "^3.0.0" }, "engines": { @@ -805,15 +805,15 @@ } }, "node_modules/@jest/core": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.1.1.tgz", - "integrity": "sha512-oCkKeTgI0emznKcLoq5OCD0PhxCijA4l7ejDnWW3d5bgSi+zfVaLybVqa+EQOxpNejQWtTna7tmsAXjMN9N43Q==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.2.2.tgz", + "integrity": "sha512-4b9km/h9pAGdCkwWYtbfoeiOtajOlGmr5rL1Eq6JCAVbOevOqxWHxJ6daWxRJW9eF6keXJoJ1H+uVAVcdZu8Bg==", "dev": true, "dependencies": { - "@jest/console": "^27.1.1", - "@jest/reporters": "^27.1.1", - "@jest/test-result": "^27.1.1", - "@jest/transform": "^27.1.1", + "@jest/console": "^27.2.2", + "@jest/reporters": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "ansi-escapes": "^4.2.1", @@ -822,18 +822,18 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.4", "jest-changed-files": "^27.1.1", - "jest-config": "^27.1.1", - "jest-haste-map": "^27.1.1", - "jest-message-util": "^27.1.1", + "jest-config": "^27.2.2", + "jest-haste-map": "^27.2.2", + "jest-message-util": "^27.2.2", "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.1.1", - "jest-resolve-dependencies": "^27.1.1", - "jest-runner": "^27.1.1", - "jest-runtime": "^27.1.1", - "jest-snapshot": "^27.1.1", - "jest-util": "^27.1.1", - "jest-validate": "^27.1.1", - "jest-watcher": "^27.1.1", + "jest-resolve": "^27.2.2", + "jest-resolve-dependencies": "^27.2.2", + "jest-runner": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", + "jest-watcher": "^27.2.2", "micromatch": "^4.0.4", "p-each-series": "^2.1.0", "rimraf": "^3.0.0", @@ -853,12 +853,12 @@ } }, "node_modules/@jest/environment": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.1.1.tgz", - "integrity": "sha512-+y882/ZdxhyqF5RzxIrNIANjHj991WH7jifdcplzMDosDUOyCACFYUyVTBGbSTocbU+s1cesroRzkwi8hZ9SHg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.2.2.tgz", + "integrity": "sha512-gO9gVnZfn5ldeOJ5q+35Kru9QWGHEqZCB7W/M+8mD6uCwOGC9HR6mzpLSNRuDsxY/KhaGBYHpgFqtpe4Rl1gDQ==", "dev": true, "dependencies": { - "@jest/fake-timers": "^27.1.1", + "@jest/fake-timers": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "jest-mock": "^27.1.1" @@ -868,46 +868,46 @@ } }, "node_modules/@jest/fake-timers": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.1.1.tgz", - "integrity": "sha512-u8TJ5VlsVYTsGFatoyIae2l25pku4Bu15QCPTx2Gs5z+R//Ee3tHN85462Vc9yGVcdDvgADbqNkhOLxbEwPjMQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.2.2.tgz", + "integrity": "sha512-gDIIqs0yxyjyxEI9HlJ8SEJ4uCc8qr8BupG1Hcx7tvyk/SLocyXE63rFxL+HQ0ZLMvSyEcJUmYnvvHH1osWiGA==", "dev": true, "dependencies": { "@jest/types": "^27.1.1", "@sinonjs/fake-timers": "^7.0.2", "@types/node": "*", - "jest-message-util": "^27.1.1", + "jest-message-util": "^27.2.2", "jest-mock": "^27.1.1", - "jest-util": "^27.1.1" + "jest-util": "^27.2.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/globals": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.1.1.tgz", - "integrity": "sha512-Q3JcTPmY+DAEHnr4MpnBV3mwy50EGrTC6oSDTNnW7FNGGacTJAfpWNk02D7xv422T1OzK2A2BKx+26xJOvHkyw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.2.2.tgz", + "integrity": "sha512-fWa/Luwod1hyehnuep+zCnOTqTVvyc4HLUU/1VpFNOEu0tCWNSODyvKSSOjtb1bGOpCNjgaDcyjzo5f7rl6a7g==", "dev": true, "dependencies": { - "@jest/environment": "^27.1.1", + "@jest/environment": "^27.2.2", "@jest/types": "^27.1.1", - "expect": "^27.1.1" + "expect": "^27.2.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/reporters": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.1.1.tgz", - "integrity": "sha512-cEERs62n1P4Pqox9HWyNOEkP57G95aK2mBjB6D8Ruz1Yc98fKH53b58rlVEnsY5nLmkLNZk65fxNi9C0Yds/8w==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.2.2.tgz", + "integrity": "sha512-ufwZ8XoLChEfPffDeVGroYbhbcYPom3zKDiv4Flhe97rr/o2IfUXoWkDUDoyJ3/V36RFIMjokSu0IJ/pbFtbHg==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.1.1", - "@jest/test-result": "^27.1.1", - "@jest/transform": "^27.1.1", + "@jest/console": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", "@jest/types": "^27.1.1", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -919,10 +919,10 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.1.1", - "jest-resolve": "^27.1.1", - "jest-util": "^27.1.1", - "jest-worker": "^27.1.1", + "jest-haste-map": "^27.2.2", + "jest-resolve": "^27.2.2", + "jest-util": "^27.2.0", + "jest-worker": "^27.2.2", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -956,12 +956,12 @@ } }, "node_modules/@jest/test-result": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.1.1.tgz", - "integrity": "sha512-8vy75A0Jtfz9DqXFUkjC5Co/wRla+D7qRFdShUY8SbPqBS3GBx3tpba7sGKFos8mQrdbe39n+c1zgVKtarfy6A==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.2.2.tgz", + "integrity": "sha512-yENoDEoWlEFI7l5z7UYyJb/y5Q8RqbPd4neAVhKr6l+vVaQOPKf8V/IseSMJI9+urDUIxgssA7RGNyCRhGjZvw==", "dev": true, "dependencies": { - "@jest/console": "^27.1.1", + "@jest/console": "^27.2.2", "@jest/types": "^27.1.1", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" @@ -971,24 +971,24 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.1.1.tgz", - "integrity": "sha512-l8zD3EdeixvwmLNlJoMX3hhj8iIze95okj4sqmBzOq/zW8gZLElUveH4bpKEMuR+Nweazjlwc7L6g4C26M/y6Q==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.2.2.tgz", + "integrity": "sha512-YnJqwNQP2Zeu0S4TMqkxg6NN7Y1EFq715n/nThNKrvIS9wmRZjDt2XYqsHbuvhAFjshi0iKDQ813NewFITBH+Q==", "dev": true, "dependencies": { - "@jest/test-result": "^27.1.1", + "@jest/test-result": "^27.2.2", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.1.1", - "jest-runtime": "^27.1.1" + "jest-haste-map": "^27.2.2", + "jest-runtime": "^27.2.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/transform": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.1.1.tgz", - "integrity": "sha512-qM19Eu75U6Jc5zosXXVnq900Nl9JDpoGaZ4Mg6wZs7oqbu3heYSMOZS19DlwjlhWdfNRjF4UeAgkrCJCK3fEXg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.2.2.tgz", + "integrity": "sha512-l4Z/7PpajrOjCiXLWLfMY7fgljY0H8EwW7qdzPXXuv2aQF8kY2+Uyj3O+9Popnaw1V7JCw32L8EeI/thqFDkPA==", "dev": true, "dependencies": { "@babel/core": "^7.1.0", @@ -998,9 +998,9 @@ "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.1.1", + "jest-haste-map": "^27.2.2", "jest-regex-util": "^27.0.6", - "jest-util": "^27.1.1", + "jest-util": "^27.2.0", "micromatch": "^4.0.4", "pirates": "^4.0.1", "slash": "^3.0.0", @@ -1315,9 +1315,9 @@ "dev": true }, "node_modules/@types/prettier": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.2.tgz", - "integrity": "sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", "dev": true }, "node_modules/@types/puppeteer": { @@ -1715,9 +1715,9 @@ } }, "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } @@ -1924,16 +1924,16 @@ } }, "node_modules/babel-jest": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.1.1.tgz", - "integrity": "sha512-JA+dzJl4n2RBvWQEnph6HJaTHrsIPiXGQYatt/D8nR4UpX9UG4GaDzykVVPQBbrdTebZREkRb6SOxyIXJRab6Q==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.2.2.tgz", + "integrity": "sha512-XNFNNfGKnZXzhej7TleVP4s9ktH5JjRW8Rmcbb223JJwKB/gmTyeWN0JfiPtSgnjIjDXtKNoixiy0QUHtv3vFA==", "dev": true, "dependencies": { - "@jest/transform": "^27.1.1", + "@jest/transform": "^27.2.2", "@jest/types": "^27.1.1", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.0.6", + "babel-preset-jest": "^27.2.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" @@ -1962,9 +1962,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.6.tgz", - "integrity": "sha512-CewFeM9Vv2gM7Yr9n5eyyLVPRSiBnk6lKZRjgwYnGKSl9M14TMn2vkN02wTF04OGuSDLEzlWiMzvjXuW9mB6Gw==", + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", + "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", @@ -2000,12 +2000,12 @@ } }, "node_modules/babel-preset-jest": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.0.6.tgz", - "integrity": "sha512-WObA0/Biw2LrVVwZkF/2GqbOdzhKD6Fkdwhoy9ASIrOWr/zodcSpQh72JOkEn6NWyjmnPDjNSqaGN4KnpKzhXw==", + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", + "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^27.0.6", + "babel-plugin-jest-hoist": "^27.2.0", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -3230,9 +3230,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "node_modules/electron": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-13.3.0.tgz", - "integrity": "sha512-d/BvOLDjI4i7yf9tqCuLL2fFGA2TrM/D9PyRpua+rJolG0qrwp/FohP02L0m+44kmPpofIo4l3NPwLmzyKKimA==", + "version": "13.5.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-13.5.1.tgz", + "integrity": "sha512-ZyxhIhmdaeE3xiIGObf0zqEyCyuIDqZQBv9NKX8w5FNzGm87j4qR0H1+GQg6vz+cA1Nnv1x175Zvimzc0/UwEQ==", "devOptional": true, "hasInstallScript": true, "dependencies": { @@ -3612,9 +3612,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.4.0.tgz", - "integrity": "sha512-8qnt/hgtZ94E9dA6viqfViKBfkJwFHXgJmTWlMGDgunw1XJEGqm3eiPjDsTanM3/u/3Az82nyQM9GX7PM/QGmg==", + "version": "24.4.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.4.2.tgz", + "integrity": "sha512-jNMnqwX75z0RXRMXkxwb/+9ylKJYJLJ8nT8nBT0XFM5qx4IQGxP4edMawa0qGkSbHae0BDPBmi8I2QF0/F04XQ==", "dev": true, "dependencies": { "@typescript-eslint/experimental-utils": "^4.0.1" @@ -3908,16 +3908,16 @@ } }, "node_modules/expect": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.1.1.tgz", - "integrity": "sha512-JQAzp0CJoFFHF1RnOtrMUNMdsfx/Tl0+FhRzVl8q0fa23N+JyWdPXwb3T5rkHCvyo9uttnK7lVdKCBl1b/9EDw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.2.2.tgz", + "integrity": "sha512-sjHBeEk47/eshN9oLbvPJZMgHQihOXXQzSMPCJ4MqKShbU9HOVFSNHEEU4dp4ujzxFSiNvPFzB2AMOFmkizhvA==", "dev": true, "dependencies": { "@jest/types": "^27.1.1", "ansi-styles": "^5.0.0", "jest-get-type": "^27.0.6", - "jest-matcher-utils": "^27.1.1", - "jest-message-util": "^27.1.1", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", "jest-regex-util": "^27.0.6" }, "engines": { @@ -5328,14 +5328,14 @@ } }, "node_modules/jest": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.1.1.tgz", - "integrity": "sha512-LFTEZOhoZNR/2DQM3OCaK5xC6c55c1OWhYh0njRsoHX0qd6x4nkcgenkSH0JKjsAGMTmmJAoL7/oqYHMfwhruA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.2.2.tgz", + "integrity": "sha512-XAB/9akDTe3/V0wPNKWfP9Y/NT1QPiCqyRBYGbC66EA9EvgAzdaFEqhFGLaDJ5UP2yIyXUMtju9a9IMrlYbZTQ==", "dev": true, "dependencies": { - "@jest/core": "^27.1.1", + "@jest/core": "^27.2.2", "import-local": "^3.0.2", - "jest-cli": "^27.1.1" + "jest-cli": "^27.2.2" }, "bin": { "jest": "bin/jest.js" @@ -5367,27 +5367,27 @@ } }, "node_modules/jest-circus": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.1.1.tgz", - "integrity": "sha512-Xed1ApiMFu/yzqGMBToHr8sp2gkX/ARZf4nXoGrHJrXrTUdVIWiVYheayfcOaPdQvQEE/uyBLgW7I7YBLIrAXQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.2.2.tgz", + "integrity": "sha512-8txlqs0EDrvPasCgwfLMkG0l3F4FxqQa6lxOsvYfOl04eSJjRw3F4gk9shakuC00nMD+VT+SMtFYXxe64f0VZw==", "dev": true, "dependencies": { - "@jest/environment": "^27.1.1", - "@jest/test-result": "^27.1.1", + "@jest/environment": "^27.2.2", + "@jest/test-result": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^27.1.1", + "expect": "^27.2.2", "is-generator-fn": "^2.0.0", - "jest-each": "^27.1.1", - "jest-matcher-utils": "^27.1.1", - "jest-message-util": "^27.1.1", - "jest-runtime": "^27.1.1", - "jest-snapshot": "^27.1.1", - "jest-util": "^27.1.1", - "pretty-format": "^27.1.1", + "jest-each": "^27.2.2", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "pretty-format": "^27.2.2", "slash": "^3.0.0", "stack-utils": "^2.0.3", "throat": "^6.0.1" @@ -5397,21 +5397,21 @@ } }, "node_modules/jest-cli": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.1.1.tgz", - "integrity": "sha512-LCjfEYp9D3bcOeVUUpEol9Y1ijZYMWVqflSmtw/wX+6Fb7zP4IlO14/6s9v1pxsoM4Pn46+M2zABgKuQjyDpTw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.2.2.tgz", + "integrity": "sha512-jbEythw22LR/IHYgNrjWdO74wO9wyujCxTMjbky0GLav4rC4y6qDQr4TqQ2JPP51eDYJ2awVn83advEVSs5Brg==", "dev": true, "dependencies": { - "@jest/core": "^27.1.1", - "@jest/test-result": "^27.1.1", + "@jest/core": "^27.2.2", + "@jest/test-result": "^27.2.2", "@jest/types": "^27.1.1", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", - "jest-config": "^27.1.1", - "jest-util": "^27.1.1", - "jest-validate": "^27.1.1", + "jest-config": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", "prompts": "^2.0.1", "yargs": "^16.0.3" }, @@ -5431,32 +5431,32 @@ } }, "node_modules/jest-config": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.1.1.tgz", - "integrity": "sha512-2iSd5zoJV4MsWPcLCGwUVUY/j6pZXm4Qd3rnbCtrd9EHNTg458iHw8PZztPQXfxKBKJxLfBk7tbZqYF8MGtxJA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.2.2.tgz", + "integrity": "sha512-2nhms3lp52ZpU0636bB6zIFHjDVtYxzFQIOHZjBFUeXcb6b41sEkWojbHaJ4FEIO44UbccTLa7tvNpiFCgPE7w==", "dev": true, "dependencies": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.1.1", + "@jest/test-sequencer": "^27.2.2", "@jest/types": "^27.1.1", - "babel-jest": "^27.1.1", + "babel-jest": "^27.2.2", "chalk": "^4.0.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", "is-ci": "^3.0.0", - "jest-circus": "^27.1.1", - "jest-environment-jsdom": "^27.1.1", - "jest-environment-node": "^27.1.1", + "jest-circus": "^27.2.2", + "jest-environment-jsdom": "^27.2.2", + "jest-environment-node": "^27.2.2", "jest-get-type": "^27.0.6", - "jest-jasmine2": "^27.1.1", + "jest-jasmine2": "^27.2.2", "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.1.1", - "jest-runner": "^27.1.1", - "jest-util": "^27.1.1", - "jest-validate": "^27.1.1", + "jest-resolve": "^27.2.2", + "jest-runner": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", "micromatch": "^4.0.4", - "pretty-format": "^27.1.1" + "pretty-format": "^27.2.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -5471,15 +5471,15 @@ } }, "node_modules/jest-diff": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.1.1.tgz", - "integrity": "sha512-m/6n5158rqEriTazqHtBpOa2B/gGgXJijX6nsEgZfbJ/3pxQcdpVXBe+FP39b1dxWHyLVVmuVXddmAwtqFO4Lg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.2.2.tgz", + "integrity": "sha512-o3LaDbQDSaMJif4yztJAULI4xVatxbBasbKLbEw3K8CiRdDdbxMrLArS9EKDHQFYh6Tgfrm1PC2mIYR1xhu0hQ==", "dev": true, "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^27.0.6", "jest-get-type": "^27.0.6", - "pretty-format": "^27.1.1" + "pretty-format": "^27.2.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -5498,33 +5498,33 @@ } }, "node_modules/jest-each": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.1.1.tgz", - "integrity": "sha512-r6hOsTLavUBb1xN0uDa89jdDeBmJ+K49fWpbyxeGRA2pLY46PlC4z551/cWNQzrj+IUa5/gSRsCIV/01HdNPug==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.2.2.tgz", + "integrity": "sha512-ZCDhkvwHeXHsxoFxvW43fabL18iLiVDxaipG5XWG7dSd+XWXXpzMQvBWYT9Wvzhg5x4hvrLQ24LtiOKw3I09xA==", "dev": true, "dependencies": { "@jest/types": "^27.1.1", "chalk": "^4.0.0", "jest-get-type": "^27.0.6", - "jest-util": "^27.1.1", - "pretty-format": "^27.1.1" + "jest-util": "^27.2.0", + "pretty-format": "^27.2.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-environment-jsdom": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.1.1.tgz", - "integrity": "sha512-6vOnoZ6IaExuw7FvnuJhA1qFYv1DDSnN0sQowzolNwxQp7bG1YhLxj2YU1sVXAYA3IR3MbH2mbnJUsLUWfyfzw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.2.2.tgz", + "integrity": "sha512-mzCLEdnpGWDJmNB6WIPLlZM+hpXdeiya9TryiByqcUdpliNV1O+LGC2SewzjmB4IblabGfvr3KcPN0Nme2wnDw==", "dev": true, "dependencies": { - "@jest/environment": "^27.1.1", - "@jest/fake-timers": "^27.1.1", + "@jest/environment": "^27.2.2", + "@jest/fake-timers": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "jest-mock": "^27.1.1", - "jest-util": "^27.1.1", + "jest-util": "^27.2.0", "jsdom": "^16.6.0" }, "engines": { @@ -5638,17 +5638,17 @@ } }, "node_modules/jest-environment-node": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.1.1.tgz", - "integrity": "sha512-OEGeZh0PwzngNIYWYgWrvTcLygopV8OJbC9HNb0j70VBKgEIsdZkYhwcFnaURX83OHACMqf1pa9Tv5Pw5jemrg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.2.2.tgz", + "integrity": "sha512-XgUscWs6H6UNqC96/QJjmUGZzzpql/JyprLSXVu7wkgM8tjbJdEkSqwrVAvJPm1yu526ImrmsIoh2BTHxkwL/g==", "dev": true, "dependencies": { - "@jest/environment": "^27.1.1", - "@jest/fake-timers": "^27.1.1", + "@jest/environment": "^27.2.2", + "@jest/fake-timers": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "jest-mock": "^27.1.1", - "jest-util": "^27.1.1" + "jest-util": "^27.2.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -5664,9 +5664,9 @@ } }, "node_modules/jest-haste-map": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.1.1.tgz", - "integrity": "sha512-NGLYVAdh5C8Ezg5QBFzrNeYsfxptDBPlhvZNaicLiZX77F/rS27a9M6u9ripWAaaD54xnWdZNZpEkdjD5Eo5aQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.2.2.tgz", + "integrity": "sha512-kaKiq+GbAvk6/sq++Ymor4Vzk6+lr0vbKs2HDVPdkKsHX2lIJRyvhypZG/QsNfQnROKWIZSpUpGuv2HySSosvA==", "dev": true, "dependencies": { "@jest/types": "^27.1.1", @@ -5677,8 +5677,8 @@ "graceful-fs": "^4.2.4", "jest-regex-util": "^27.0.6", "jest-serializer": "^27.0.6", - "jest-util": "^27.1.1", - "jest-worker": "^27.1.1", + "jest-util": "^27.2.0", + "jest-worker": "^27.2.2", "micromatch": "^4.0.4", "walker": "^1.0.7" }, @@ -5690,28 +5690,28 @@ } }, "node_modules/jest-jasmine2": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.1.1.tgz", - "integrity": "sha512-0LAzUmcmvQwjIdJt0cXUVX4G5qjVXE8ELt6nbMNDzv2yAs2hYCCUtQq+Eje70GwAysWCGcS64QeYj5VPHYVxPg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.2.2.tgz", + "integrity": "sha512-SczhZNfmZID9HbJ1GHhO4EzeL/PMRGeAUw23ddPUdd6kFijEZpT2yOxyNCBUKAsVQ/14OB60kjgnbuFOboZUNg==", "dev": true, "dependencies": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.1.1", + "@jest/environment": "^27.2.2", "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.1.1", + "@jest/test-result": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^27.1.1", + "expect": "^27.2.2", "is-generator-fn": "^2.0.0", - "jest-each": "^27.1.1", - "jest-matcher-utils": "^27.1.1", - "jest-message-util": "^27.1.1", - "jest-runtime": "^27.1.1", - "jest-snapshot": "^27.1.1", - "jest-util": "^27.1.1", - "pretty-format": "^27.1.1", + "jest-each": "^27.2.2", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "pretty-format": "^27.2.2", "throat": "^6.0.1" }, "engines": { @@ -5719,37 +5719,37 @@ } }, "node_modules/jest-leak-detector": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.1.1.tgz", - "integrity": "sha512-gwSgzmqShoeEsEVpgObymQPrM9P6557jt1EsFW5aCeJ46Cme0EdjYU7xr6llQZ5GpWDl56eOstUaPXiZOfiTKw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.2.2.tgz", + "integrity": "sha512-fQIYKkhXUs/4EpE4wO1AVsv7aNH3o0km1BGq3vxvSfYdwG9GLMf+b0z/ghLmBYNxb+tVpm/zv2caoKm3GfTazg==", "dev": true, "dependencies": { "jest-get-type": "^27.0.6", - "pretty-format": "^27.1.1" + "pretty-format": "^27.2.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.1.1.tgz", - "integrity": "sha512-Q1a10w9Y4sh0wegkdP6reQOa/Dtz7nAvDqBgrat1ItZAUvk4jzXAqyhXPu/ZuEtDaXaNKpdRPRQA8bvkOh2Eaw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.2.2.tgz", + "integrity": "sha512-xN3wT4p2i9DGB6zmL3XxYp5lJmq9Q6ff8XKlMtVVBS2SAshmgsPBALJFQ8dWRd2G/xf5q/N0SD0Mipt8QBA26A==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^27.1.1", + "jest-diff": "^27.2.2", "jest-get-type": "^27.0.6", - "pretty-format": "^27.1.1" + "pretty-format": "^27.2.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-message-util": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.1.1.tgz", - "integrity": "sha512-b697BOJV93+AVGvzLRtVZ0cTVRbd59OaWnbB2D75GRaIMc4I+Z9W0wHxbfjW01JWO+TqqW4yevT0aN7Fd0XWng==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.2.2.tgz", + "integrity": "sha512-/iS5/m2FSF7Nn6APFoxFymJpyhB/gPf0CJa7uFSkbYaWvrADUfQ9NTsuyjpszKErOS2/huFs44ysWhlQTKvL8Q==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", @@ -5758,7 +5758,7 @@ "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.4", - "pretty-format": "^27.1.1", + "pretty-format": "^27.2.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -5818,19 +5818,19 @@ } }, "node_modules/jest-resolve": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.1.1.tgz", - "integrity": "sha512-M41YFmWhvDVstwe7XuV21zynOiBLJB5Sk0GrIsYYgTkjfEWNLVXDjAyq1W7PHseaYNOxIc0nOGq/r5iwcZNC1A==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.2.2.tgz", + "integrity": "sha512-tfbHcBs/hJTb3fPQ/3hLWR+TsLNTzzK98TU+zIAsrL9nNzWfWROwopUOmiSUqmHMZW5t9au/433kSF2/Af+tTw==", "dev": true, "dependencies": { "@jest/types": "^27.1.1", "chalk": "^4.0.0", "escalade": "^3.1.1", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.1.1", + "jest-haste-map": "^27.2.2", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.1.1", - "jest-validate": "^27.1.1", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", "resolve": "^1.20.0", "slash": "^3.0.0" }, @@ -5839,29 +5839,29 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.1.1.tgz", - "integrity": "sha512-sYZR+uBjFDCo4VhYeazZf/T+ryYItvdLKu9vHatqkUqHGjDMrdEPOykiqC2iEpaCFTS+3iL/21CYiJuKdRbniw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.2.2.tgz", + "integrity": "sha512-nvJS+DyY51HHdZnMIwXg7fimQ5ylFx4+quQXspQXde2rXYy+4v75UYoX/J65Ln8mKCNc6YF8HEhfGaRBOrxxHg==", "dev": true, "dependencies": { "@jest/types": "^27.1.1", "jest-regex-util": "^27.0.6", - "jest-snapshot": "^27.1.1" + "jest-snapshot": "^27.2.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-runner": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.1.1.tgz", - "integrity": "sha512-lP3MBNQhg75/sQtVkC8dsAQZumvy3lHK/YIwYPfEyqGIX1qEcnYIRxP89q0ZgC5ngvi1vN2P5UFHszQxguWdng==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.2.2.tgz", + "integrity": "sha512-+bUFwBq+yTnvsOFuxetoQtkuOnqdAk2YuIGjlLmc7xLAXn/V1vjhXrLencgij0BUTTUvG9Aul3+5XDss4Wa8Eg==", "dev": true, "dependencies": { - "@jest/console": "^27.1.1", - "@jest/environment": "^27.1.1", - "@jest/test-result": "^27.1.1", - "@jest/transform": "^27.1.1", + "@jest/console": "^27.2.2", + "@jest/environment": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "chalk": "^4.0.0", @@ -5869,15 +5869,15 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.4", "jest-docblock": "^27.0.6", - "jest-environment-jsdom": "^27.1.1", - "jest-environment-node": "^27.1.1", - "jest-haste-map": "^27.1.1", - "jest-leak-detector": "^27.1.1", - "jest-message-util": "^27.1.1", - "jest-resolve": "^27.1.1", - "jest-runtime": "^27.1.1", - "jest-util": "^27.1.1", - "jest-worker": "^27.1.1", + "jest-environment-jsdom": "^27.2.2", + "jest-environment-node": "^27.2.2", + "jest-haste-map": "^27.2.2", + "jest-leak-detector": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-resolve": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-util": "^27.2.0", + "jest-worker": "^27.2.2", "source-map-support": "^0.5.6", "throat": "^6.0.1" }, @@ -5886,18 +5886,18 @@ } }, "node_modules/jest-runtime": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.1.1.tgz", - "integrity": "sha512-FEwy+tSzmsvuKaQpyYsUyk31KG5vMmA2r2BSTHgv0yNfcooQdm2Ke91LM9Ud8D3xz8CLDHJWAI24haMFTwrsPg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.2.2.tgz", + "integrity": "sha512-PtTHCK5jT+KrIpKpjJsltu/dK5uGhBtTNLOk1Z+ZD2Jrxam2qQsOqDFYLszcK0jc2TLTNsrVpclqSftn7y3aXA==", "dev": true, "dependencies": { - "@jest/console": "^27.1.1", - "@jest/environment": "^27.1.1", - "@jest/fake-timers": "^27.1.1", - "@jest/globals": "^27.1.1", + "@jest/console": "^27.2.2", + "@jest/environment": "^27.2.2", + "@jest/fake-timers": "^27.2.2", + "@jest/globals": "^27.2.2", "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.1.1", - "@jest/transform": "^27.1.1", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", "@jest/types": "^27.1.1", "@types/yargs": "^16.0.0", "chalk": "^4.0.0", @@ -5907,14 +5907,14 @@ "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.1.1", - "jest-message-util": "^27.1.1", + "jest-haste-map": "^27.2.2", + "jest-message-util": "^27.2.2", "jest-mock": "^27.1.1", "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.1.1", - "jest-snapshot": "^27.1.1", - "jest-util": "^27.1.1", - "jest-validate": "^27.1.1", + "jest-resolve": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", "slash": "^3.0.0", "strip-bom": "^4.0.0", "yargs": "^16.0.3" @@ -5937,9 +5937,9 @@ } }, "node_modules/jest-snapshot": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.1.1.tgz", - "integrity": "sha512-Wi3QGiuRFo3lU+EbQmZnBOks0CJyAMPHvYoG7iJk00Do10jeOyuOEO0Jfoaoun8+8TDv+Nzl7Aswir/IK9+1jg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.2.2.tgz", + "integrity": "sha512-7ODSvULMiiOVuuLvLZpDlpqqTqX9hDfdmijho5auVu9qRYREolvrvgH4kSNOKfcqV3EZOTuLKNdqsz1PM20PQA==", "dev": true, "dependencies": { "@babel/core": "^7.7.2", @@ -5948,23 +5948,23 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/transform": "^27.1.1", + "@jest/transform": "^27.2.2", "@jest/types": "^27.1.1", "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.1.1", + "expect": "^27.2.2", "graceful-fs": "^4.2.4", - "jest-diff": "^27.1.1", + "jest-diff": "^27.2.2", "jest-get-type": "^27.0.6", - "jest-haste-map": "^27.1.1", - "jest-matcher-utils": "^27.1.1", - "jest-message-util": "^27.1.1", - "jest-resolve": "^27.1.1", - "jest-util": "^27.1.1", + "jest-haste-map": "^27.2.2", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-resolve": "^27.2.2", + "jest-util": "^27.2.0", "natural-compare": "^1.4.0", - "pretty-format": "^27.1.1", + "pretty-format": "^27.2.2", "semver": "^7.3.2" }, "engines": { @@ -5987,9 +5987,9 @@ } }, "node_modules/jest-util": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.1.1.tgz", - "integrity": "sha512-zf9nEbrASWn2mC/L91nNb0K+GkhFvi4MP6XJG2HqnHzHvLYcs7ou/In68xYU1i1dSkJlrWcYfWXQE8nVR+nbOA==", + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.2.0.tgz", + "integrity": "sha512-T5ZJCNeFpqcLBpx+Hl9r9KoxBCUqeWlJ1Htli+vryigZVJ1vuLB9j35grEBASp4R13KFkV7jM52bBGnArpJN6A==", "dev": true, "dependencies": { "@jest/types": "^27.1.1", @@ -6004,9 +6004,9 @@ } }, "node_modules/jest-validate": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.1.1.tgz", - "integrity": "sha512-N5Er5FKav/8m2dJwn7BGnZwnoD1BSc8jx5T+diG2OvyeugvZDhPeAt5DrNaGkkaKCrSUvuE7A5E4uHyT7Vj0Mw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.2.2.tgz", + "integrity": "sha512-01mwTAs2kgDuX98Ua3Xhdhp5lXsLU4eyg6k56adTtrXnU/GbLd9uAsh5nc4MWVtUXMeNmHUyEiD4ibLqE8MuNw==", "dev": true, "dependencies": { "@jest/types": "^27.1.1", @@ -6014,7 +6014,7 @@ "chalk": "^4.0.0", "jest-get-type": "^27.0.6", "leven": "^3.1.0", - "pretty-format": "^27.1.1" + "pretty-format": "^27.2.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -6033,17 +6033,17 @@ } }, "node_modules/jest-watcher": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.1.1.tgz", - "integrity": "sha512-XQzyHbxziDe+lZM6Dzs40fEt4q9akOGwitJnxQasJ9WG0bv3JGiRlsBgjw13znGapeMtFaEsyhL0Cl04IbaoWQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.2.2.tgz", + "integrity": "sha512-7HJwZq06BCfM99RacCVzXO90B20/dNJvq+Ouiu/VrFdFRCpbnnqlQUEk4KAhBSllgDrTPgKu422SCF5KKBHDRA==", "dev": true, "dependencies": { - "@jest/test-result": "^27.1.1", + "@jest/test-result": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^27.1.1", + "jest-util": "^27.2.0", "string-length": "^4.0.1" }, "engines": { @@ -6051,9 +6051,9 @@ } }, "node_modules/jest-worker": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.1.1.tgz", - "integrity": "sha512-XJKCL7tu+362IUYTWvw8+3S75U7qMiYiRU6u5yqscB48bTvzwN6i8L/7wVTXiFLwkRsxARNM7TISnTvcgv9hxA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.2.2.tgz", + "integrity": "sha512-aG1xq9KgWB2CPC8YdMIlI8uZgga2LFNcGbHJxO8ctfXAydSaThR4EewKQGg3tBOC+kS3vhPGgymsBdi9VINjPw==", "dev": true, "dependencies": { "@types/node": "*", @@ -6948,13 +6948,35 @@ } }, "node_modules/node-fetch": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.2.tgz", - "integrity": "sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA==", + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", + "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, "engines": { "node": "4.x || >=6.0.0" } }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-ical": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/node-ical/-/node-ical-0.13.0.tgz", @@ -7741,9 +7763,9 @@ } }, "node_modules/prettier": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.0.tgz", - "integrity": "sha512-DsEPLY1dE5HF3BxCRBmD4uYZ+5DCbvatnolqTqcxEgKVZnL2kUfyu7b8pPQ5+hTBkdhU9SLUmK0/pHb07RE4WQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -7765,13 +7787,13 @@ } }, "node_modules/pretty-format": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.1.1.tgz", - "integrity": "sha512-zdBi/xlstKJL42UH7goQti5Hip/B415w1Mfj+WWWYMBylAYtKESnXGUtVVcMVid9ReVjypCotUV6CEevYPHv2g==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.2.2.tgz", + "integrity": "sha512-+DdLh+rtaElc2SQOE/YPH8k2g3Rf2OXWEpy06p8Szs3hdVSYD87QOOlYRHWAeb/59XTmeVmRKvDD0svHqf6ycA==", "dev": true, "dependencies": { "@jest/types": "^27.1.1", - "ansi-regex": "^5.0.0", + "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, @@ -9064,9 +9086,9 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -9887,9 +9909,9 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" }, "node_modules/v8-to-istanbul": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz", - "integrity": "sha512-LkmXi8UUNxnCC+JlH7/fsfsKr5AU110l+SYGJimWNkWhxbN5EyeOtm1MJ0hhvqMMOhGwBj1Fp70Yv9i+hX0QAg==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", + "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -11093,29 +11115,29 @@ "dev": true }, "@jest/console": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.1.1.tgz", - "integrity": "sha512-VpQJRsWSeAem0zpBjeRtDbcD6DlbNoK11dNYt+PSQ+DDORh9q2/xyEpErfwgnLjWX0EKkSZmTGx/iH9Inzs6vQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.2.2.tgz", + "integrity": "sha512-m7tbzPWyvSFfoanTknJoDnaeruDARsUe555tkVjG/qeaRDKwyPqqbgs4yFx583gmoETiAts1deeYozR5sVRhNA==", "dev": true, "requires": { "@jest/types": "^27.1.1", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.1.1", - "jest-util": "^27.1.1", + "jest-message-util": "^27.2.2", + "jest-util": "^27.2.0", "slash": "^3.0.0" } }, "@jest/core": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.1.1.tgz", - "integrity": "sha512-oCkKeTgI0emznKcLoq5OCD0PhxCijA4l7ejDnWW3d5bgSi+zfVaLybVqa+EQOxpNejQWtTna7tmsAXjMN9N43Q==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.2.2.tgz", + "integrity": "sha512-4b9km/h9pAGdCkwWYtbfoeiOtajOlGmr5rL1Eq6JCAVbOevOqxWHxJ6daWxRJW9eF6keXJoJ1H+uVAVcdZu8Bg==", "dev": true, "requires": { - "@jest/console": "^27.1.1", - "@jest/reporters": "^27.1.1", - "@jest/test-result": "^27.1.1", - "@jest/transform": "^27.1.1", + "@jest/console": "^27.2.2", + "@jest/reporters": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "ansi-escapes": "^4.2.1", @@ -11124,18 +11146,18 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.4", "jest-changed-files": "^27.1.1", - "jest-config": "^27.1.1", - "jest-haste-map": "^27.1.1", - "jest-message-util": "^27.1.1", + "jest-config": "^27.2.2", + "jest-haste-map": "^27.2.2", + "jest-message-util": "^27.2.2", "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.1.1", - "jest-resolve-dependencies": "^27.1.1", - "jest-runner": "^27.1.1", - "jest-runtime": "^27.1.1", - "jest-snapshot": "^27.1.1", - "jest-util": "^27.1.1", - "jest-validate": "^27.1.1", - "jest-watcher": "^27.1.1", + "jest-resolve": "^27.2.2", + "jest-resolve-dependencies": "^27.2.2", + "jest-runner": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", + "jest-watcher": "^27.2.2", "micromatch": "^4.0.4", "p-each-series": "^2.1.0", "rimraf": "^3.0.0", @@ -11144,52 +11166,52 @@ } }, "@jest/environment": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.1.1.tgz", - "integrity": "sha512-+y882/ZdxhyqF5RzxIrNIANjHj991WH7jifdcplzMDosDUOyCACFYUyVTBGbSTocbU+s1cesroRzkwi8hZ9SHg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.2.2.tgz", + "integrity": "sha512-gO9gVnZfn5ldeOJ5q+35Kru9QWGHEqZCB7W/M+8mD6uCwOGC9HR6mzpLSNRuDsxY/KhaGBYHpgFqtpe4Rl1gDQ==", "dev": true, "requires": { - "@jest/fake-timers": "^27.1.1", + "@jest/fake-timers": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "jest-mock": "^27.1.1" } }, "@jest/fake-timers": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.1.1.tgz", - "integrity": "sha512-u8TJ5VlsVYTsGFatoyIae2l25pku4Bu15QCPTx2Gs5z+R//Ee3tHN85462Vc9yGVcdDvgADbqNkhOLxbEwPjMQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.2.2.tgz", + "integrity": "sha512-gDIIqs0yxyjyxEI9HlJ8SEJ4uCc8qr8BupG1Hcx7tvyk/SLocyXE63rFxL+HQ0ZLMvSyEcJUmYnvvHH1osWiGA==", "dev": true, "requires": { "@jest/types": "^27.1.1", "@sinonjs/fake-timers": "^7.0.2", "@types/node": "*", - "jest-message-util": "^27.1.1", + "jest-message-util": "^27.2.2", "jest-mock": "^27.1.1", - "jest-util": "^27.1.1" + "jest-util": "^27.2.0" } }, "@jest/globals": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.1.1.tgz", - "integrity": "sha512-Q3JcTPmY+DAEHnr4MpnBV3mwy50EGrTC6oSDTNnW7FNGGacTJAfpWNk02D7xv422T1OzK2A2BKx+26xJOvHkyw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.2.2.tgz", + "integrity": "sha512-fWa/Luwod1hyehnuep+zCnOTqTVvyc4HLUU/1VpFNOEu0tCWNSODyvKSSOjtb1bGOpCNjgaDcyjzo5f7rl6a7g==", "dev": true, "requires": { - "@jest/environment": "^27.1.1", + "@jest/environment": "^27.2.2", "@jest/types": "^27.1.1", - "expect": "^27.1.1" + "expect": "^27.2.2" } }, "@jest/reporters": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.1.1.tgz", - "integrity": "sha512-cEERs62n1P4Pqox9HWyNOEkP57G95aK2mBjB6D8Ruz1Yc98fKH53b58rlVEnsY5nLmkLNZk65fxNi9C0Yds/8w==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.2.2.tgz", + "integrity": "sha512-ufwZ8XoLChEfPffDeVGroYbhbcYPom3zKDiv4Flhe97rr/o2IfUXoWkDUDoyJ3/V36RFIMjokSu0IJ/pbFtbHg==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.1.1", - "@jest/test-result": "^27.1.1", - "@jest/transform": "^27.1.1", + "@jest/console": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", "@jest/types": "^27.1.1", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -11201,10 +11223,10 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.1.1", - "jest-resolve": "^27.1.1", - "jest-util": "^27.1.1", - "jest-worker": "^27.1.1", + "jest-haste-map": "^27.2.2", + "jest-resolve": "^27.2.2", + "jest-util": "^27.2.0", + "jest-worker": "^27.2.2", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -11224,33 +11246,33 @@ } }, "@jest/test-result": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.1.1.tgz", - "integrity": "sha512-8vy75A0Jtfz9DqXFUkjC5Co/wRla+D7qRFdShUY8SbPqBS3GBx3tpba7sGKFos8mQrdbe39n+c1zgVKtarfy6A==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.2.2.tgz", + "integrity": "sha512-yENoDEoWlEFI7l5z7UYyJb/y5Q8RqbPd4neAVhKr6l+vVaQOPKf8V/IseSMJI9+urDUIxgssA7RGNyCRhGjZvw==", "dev": true, "requires": { - "@jest/console": "^27.1.1", + "@jest/console": "^27.2.2", "@jest/types": "^27.1.1", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.1.1.tgz", - "integrity": "sha512-l8zD3EdeixvwmLNlJoMX3hhj8iIze95okj4sqmBzOq/zW8gZLElUveH4bpKEMuR+Nweazjlwc7L6g4C26M/y6Q==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.2.2.tgz", + "integrity": "sha512-YnJqwNQP2Zeu0S4TMqkxg6NN7Y1EFq715n/nThNKrvIS9wmRZjDt2XYqsHbuvhAFjshi0iKDQ813NewFITBH+Q==", "dev": true, "requires": { - "@jest/test-result": "^27.1.1", + "@jest/test-result": "^27.2.2", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.1.1", - "jest-runtime": "^27.1.1" + "jest-haste-map": "^27.2.2", + "jest-runtime": "^27.2.2" } }, "@jest/transform": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.1.1.tgz", - "integrity": "sha512-qM19Eu75U6Jc5zosXXVnq900Nl9JDpoGaZ4Mg6wZs7oqbu3heYSMOZS19DlwjlhWdfNRjF4UeAgkrCJCK3fEXg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.2.2.tgz", + "integrity": "sha512-l4Z/7PpajrOjCiXLWLfMY7fgljY0H8EwW7qdzPXXuv2aQF8kY2+Uyj3O+9Popnaw1V7JCw32L8EeI/thqFDkPA==", "dev": true, "requires": { "@babel/core": "^7.1.0", @@ -11260,9 +11282,9 @@ "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.1.1", + "jest-haste-map": "^27.2.2", "jest-regex-util": "^27.0.6", - "jest-util": "^27.1.1", + "jest-util": "^27.2.0", "micromatch": "^4.0.4", "pirates": "^4.0.1", "slash": "^3.0.0", @@ -11545,9 +11567,9 @@ "dev": true }, "@types/prettier": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.2.tgz", - "integrity": "sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", "dev": true }, "@types/puppeteer": { @@ -11839,9 +11861,9 @@ } }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", @@ -11998,16 +12020,16 @@ } }, "babel-jest": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.1.1.tgz", - "integrity": "sha512-JA+dzJl4n2RBvWQEnph6HJaTHrsIPiXGQYatt/D8nR4UpX9UG4GaDzykVVPQBbrdTebZREkRb6SOxyIXJRab6Q==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.2.2.tgz", + "integrity": "sha512-XNFNNfGKnZXzhej7TleVP4s9ktH5JjRW8Rmcbb223JJwKB/gmTyeWN0JfiPtSgnjIjDXtKNoixiy0QUHtv3vFA==", "dev": true, "requires": { - "@jest/transform": "^27.1.1", + "@jest/transform": "^27.2.2", "@jest/types": "^27.1.1", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.0.6", + "babel-preset-jest": "^27.2.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" @@ -12027,9 +12049,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.6.tgz", - "integrity": "sha512-CewFeM9Vv2gM7Yr9n5eyyLVPRSiBnk6lKZRjgwYnGKSl9M14TMn2vkN02wTF04OGuSDLEzlWiMzvjXuW9mB6Gw==", + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", + "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -12059,12 +12081,12 @@ } }, "babel-preset-jest": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.0.6.tgz", - "integrity": "sha512-WObA0/Biw2LrVVwZkF/2GqbOdzhKD6Fkdwhoy9ASIrOWr/zodcSpQh72JOkEn6NWyjmnPDjNSqaGN4KnpKzhXw==", + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", + "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^27.0.6", + "babel-plugin-jest-hoist": "^27.2.0", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -13013,9 +13035,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-13.3.0.tgz", - "integrity": "sha512-d/BvOLDjI4i7yf9tqCuLL2fFGA2TrM/D9PyRpua+rJolG0qrwp/FohP02L0m+44kmPpofIo4l3NPwLmzyKKimA==", + "version": "13.5.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-13.5.1.tgz", + "integrity": "sha512-ZyxhIhmdaeE3xiIGObf0zqEyCyuIDqZQBv9NKX8w5FNzGm87j4qR0H1+GQg6vz+cA1Nnv1x175Zvimzc0/UwEQ==", "devOptional": true, "requires": { "@electron/get": "^1.0.1", @@ -13298,9 +13320,9 @@ "requires": {} }, "eslint-plugin-jest": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.4.0.tgz", - "integrity": "sha512-8qnt/hgtZ94E9dA6viqfViKBfkJwFHXgJmTWlMGDgunw1XJEGqm3eiPjDsTanM3/u/3Az82nyQM9GX7PM/QGmg==", + "version": "24.4.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.4.2.tgz", + "integrity": "sha512-jNMnqwX75z0RXRMXkxwb/+9ylKJYJLJ8nT8nBT0XFM5qx4IQGxP4edMawa0qGkSbHae0BDPBmi8I2QF0/F04XQ==", "dev": true, "requires": { "@typescript-eslint/experimental-utils": "^4.0.1" @@ -13486,16 +13508,16 @@ "dev": true }, "expect": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.1.1.tgz", - "integrity": "sha512-JQAzp0CJoFFHF1RnOtrMUNMdsfx/Tl0+FhRzVl8q0fa23N+JyWdPXwb3T5rkHCvyo9uttnK7lVdKCBl1b/9EDw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.2.2.tgz", + "integrity": "sha512-sjHBeEk47/eshN9oLbvPJZMgHQihOXXQzSMPCJ4MqKShbU9HOVFSNHEEU4dp4ujzxFSiNvPFzB2AMOFmkizhvA==", "dev": true, "requires": { "@jest/types": "^27.1.1", "ansi-styles": "^5.0.0", "jest-get-type": "^27.0.6", - "jest-matcher-utils": "^27.1.1", - "jest-message-util": "^27.1.1", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", "jest-regex-util": "^27.0.6" }, "dependencies": { @@ -14566,14 +14588,14 @@ } }, "jest": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.1.1.tgz", - "integrity": "sha512-LFTEZOhoZNR/2DQM3OCaK5xC6c55c1OWhYh0njRsoHX0qd6x4nkcgenkSH0JKjsAGMTmmJAoL7/oqYHMfwhruA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.2.2.tgz", + "integrity": "sha512-XAB/9akDTe3/V0wPNKWfP9Y/NT1QPiCqyRBYGbC66EA9EvgAzdaFEqhFGLaDJ5UP2yIyXUMtju9a9IMrlYbZTQ==", "dev": true, "requires": { - "@jest/core": "^27.1.1", + "@jest/core": "^27.2.2", "import-local": "^3.0.2", - "jest-cli": "^27.1.1" + "jest-cli": "^27.2.2" } }, "jest-changed-files": { @@ -14588,91 +14610,91 @@ } }, "jest-circus": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.1.1.tgz", - "integrity": "sha512-Xed1ApiMFu/yzqGMBToHr8sp2gkX/ARZf4nXoGrHJrXrTUdVIWiVYheayfcOaPdQvQEE/uyBLgW7I7YBLIrAXQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.2.2.tgz", + "integrity": "sha512-8txlqs0EDrvPasCgwfLMkG0l3F4FxqQa6lxOsvYfOl04eSJjRw3F4gk9shakuC00nMD+VT+SMtFYXxe64f0VZw==", "dev": true, "requires": { - "@jest/environment": "^27.1.1", - "@jest/test-result": "^27.1.1", + "@jest/environment": "^27.2.2", + "@jest/test-result": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^27.1.1", + "expect": "^27.2.2", "is-generator-fn": "^2.0.0", - "jest-each": "^27.1.1", - "jest-matcher-utils": "^27.1.1", - "jest-message-util": "^27.1.1", - "jest-runtime": "^27.1.1", - "jest-snapshot": "^27.1.1", - "jest-util": "^27.1.1", - "pretty-format": "^27.1.1", + "jest-each": "^27.2.2", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "pretty-format": "^27.2.2", "slash": "^3.0.0", "stack-utils": "^2.0.3", "throat": "^6.0.1" } }, "jest-cli": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.1.1.tgz", - "integrity": "sha512-LCjfEYp9D3bcOeVUUpEol9Y1ijZYMWVqflSmtw/wX+6Fb7zP4IlO14/6s9v1pxsoM4Pn46+M2zABgKuQjyDpTw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.2.2.tgz", + "integrity": "sha512-jbEythw22LR/IHYgNrjWdO74wO9wyujCxTMjbky0GLav4rC4y6qDQr4TqQ2JPP51eDYJ2awVn83advEVSs5Brg==", "dev": true, "requires": { - "@jest/core": "^27.1.1", - "@jest/test-result": "^27.1.1", + "@jest/core": "^27.2.2", + "@jest/test-result": "^27.2.2", "@jest/types": "^27.1.1", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", - "jest-config": "^27.1.1", - "jest-util": "^27.1.1", - "jest-validate": "^27.1.1", + "jest-config": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", "prompts": "^2.0.1", "yargs": "^16.0.3" } }, "jest-config": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.1.1.tgz", - "integrity": "sha512-2iSd5zoJV4MsWPcLCGwUVUY/j6pZXm4Qd3rnbCtrd9EHNTg458iHw8PZztPQXfxKBKJxLfBk7tbZqYF8MGtxJA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.2.2.tgz", + "integrity": "sha512-2nhms3lp52ZpU0636bB6zIFHjDVtYxzFQIOHZjBFUeXcb6b41sEkWojbHaJ4FEIO44UbccTLa7tvNpiFCgPE7w==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.1.1", + "@jest/test-sequencer": "^27.2.2", "@jest/types": "^27.1.1", - "babel-jest": "^27.1.1", + "babel-jest": "^27.2.2", "chalk": "^4.0.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", "is-ci": "^3.0.0", - "jest-circus": "^27.1.1", - "jest-environment-jsdom": "^27.1.1", - "jest-environment-node": "^27.1.1", + "jest-circus": "^27.2.2", + "jest-environment-jsdom": "^27.2.2", + "jest-environment-node": "^27.2.2", "jest-get-type": "^27.0.6", - "jest-jasmine2": "^27.1.1", + "jest-jasmine2": "^27.2.2", "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.1.1", - "jest-runner": "^27.1.1", - "jest-util": "^27.1.1", - "jest-validate": "^27.1.1", + "jest-resolve": "^27.2.2", + "jest-runner": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", "micromatch": "^4.0.4", - "pretty-format": "^27.1.1" + "pretty-format": "^27.2.2" } }, "jest-diff": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.1.1.tgz", - "integrity": "sha512-m/6n5158rqEriTazqHtBpOa2B/gGgXJijX6nsEgZfbJ/3pxQcdpVXBe+FP39b1dxWHyLVVmuVXddmAwtqFO4Lg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.2.2.tgz", + "integrity": "sha512-o3LaDbQDSaMJif4yztJAULI4xVatxbBasbKLbEw3K8CiRdDdbxMrLArS9EKDHQFYh6Tgfrm1PC2mIYR1xhu0hQ==", "dev": true, "requires": { "chalk": "^4.0.0", "diff-sequences": "^27.0.6", "jest-get-type": "^27.0.6", - "pretty-format": "^27.1.1" + "pretty-format": "^27.2.2" } }, "jest-docblock": { @@ -14685,30 +14707,30 @@ } }, "jest-each": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.1.1.tgz", - "integrity": "sha512-r6hOsTLavUBb1xN0uDa89jdDeBmJ+K49fWpbyxeGRA2pLY46PlC4z551/cWNQzrj+IUa5/gSRsCIV/01HdNPug==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.2.2.tgz", + "integrity": "sha512-ZCDhkvwHeXHsxoFxvW43fabL18iLiVDxaipG5XWG7dSd+XWXXpzMQvBWYT9Wvzhg5x4hvrLQ24LtiOKw3I09xA==", "dev": true, "requires": { "@jest/types": "^27.1.1", "chalk": "^4.0.0", "jest-get-type": "^27.0.6", - "jest-util": "^27.1.1", - "pretty-format": "^27.1.1" + "jest-util": "^27.2.0", + "pretty-format": "^27.2.2" } }, "jest-environment-jsdom": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.1.1.tgz", - "integrity": "sha512-6vOnoZ6IaExuw7FvnuJhA1qFYv1DDSnN0sQowzolNwxQp7bG1YhLxj2YU1sVXAYA3IR3MbH2mbnJUsLUWfyfzw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.2.2.tgz", + "integrity": "sha512-mzCLEdnpGWDJmNB6WIPLlZM+hpXdeiya9TryiByqcUdpliNV1O+LGC2SewzjmB4IblabGfvr3KcPN0Nme2wnDw==", "dev": true, "requires": { - "@jest/environment": "^27.1.1", - "@jest/fake-timers": "^27.1.1", + "@jest/environment": "^27.2.2", + "@jest/fake-timers": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "jest-mock": "^27.1.1", - "jest-util": "^27.1.1", + "jest-util": "^27.2.0", "jsdom": "^16.6.0" }, "dependencies": { @@ -14795,17 +14817,17 @@ } }, "jest-environment-node": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.1.1.tgz", - "integrity": "sha512-OEGeZh0PwzngNIYWYgWrvTcLygopV8OJbC9HNb0j70VBKgEIsdZkYhwcFnaURX83OHACMqf1pa9Tv5Pw5jemrg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.2.2.tgz", + "integrity": "sha512-XgUscWs6H6UNqC96/QJjmUGZzzpql/JyprLSXVu7wkgM8tjbJdEkSqwrVAvJPm1yu526ImrmsIoh2BTHxkwL/g==", "dev": true, "requires": { - "@jest/environment": "^27.1.1", - "@jest/fake-timers": "^27.1.1", + "@jest/environment": "^27.2.2", + "@jest/fake-timers": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "jest-mock": "^27.1.1", - "jest-util": "^27.1.1" + "jest-util": "^27.2.0" } }, "jest-get-type": { @@ -14815,9 +14837,9 @@ "dev": true }, "jest-haste-map": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.1.1.tgz", - "integrity": "sha512-NGLYVAdh5C8Ezg5QBFzrNeYsfxptDBPlhvZNaicLiZX77F/rS27a9M6u9ripWAaaD54xnWdZNZpEkdjD5Eo5aQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.2.2.tgz", + "integrity": "sha512-kaKiq+GbAvk6/sq++Ymor4Vzk6+lr0vbKs2HDVPdkKsHX2lIJRyvhypZG/QsNfQnROKWIZSpUpGuv2HySSosvA==", "dev": true, "requires": { "@jest/types": "^27.1.1", @@ -14829,64 +14851,64 @@ "graceful-fs": "^4.2.4", "jest-regex-util": "^27.0.6", "jest-serializer": "^27.0.6", - "jest-util": "^27.1.1", - "jest-worker": "^27.1.1", + "jest-util": "^27.2.0", + "jest-worker": "^27.2.2", "micromatch": "^4.0.4", "walker": "^1.0.7" } }, "jest-jasmine2": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.1.1.tgz", - "integrity": "sha512-0LAzUmcmvQwjIdJt0cXUVX4G5qjVXE8ELt6nbMNDzv2yAs2hYCCUtQq+Eje70GwAysWCGcS64QeYj5VPHYVxPg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.2.2.tgz", + "integrity": "sha512-SczhZNfmZID9HbJ1GHhO4EzeL/PMRGeAUw23ddPUdd6kFijEZpT2yOxyNCBUKAsVQ/14OB60kjgnbuFOboZUNg==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.1.1", + "@jest/environment": "^27.2.2", "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.1.1", + "@jest/test-result": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^27.1.1", + "expect": "^27.2.2", "is-generator-fn": "^2.0.0", - "jest-each": "^27.1.1", - "jest-matcher-utils": "^27.1.1", - "jest-message-util": "^27.1.1", - "jest-runtime": "^27.1.1", - "jest-snapshot": "^27.1.1", - "jest-util": "^27.1.1", - "pretty-format": "^27.1.1", + "jest-each": "^27.2.2", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "pretty-format": "^27.2.2", "throat": "^6.0.1" } }, "jest-leak-detector": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.1.1.tgz", - "integrity": "sha512-gwSgzmqShoeEsEVpgObymQPrM9P6557jt1EsFW5aCeJ46Cme0EdjYU7xr6llQZ5GpWDl56eOstUaPXiZOfiTKw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.2.2.tgz", + "integrity": "sha512-fQIYKkhXUs/4EpE4wO1AVsv7aNH3o0km1BGq3vxvSfYdwG9GLMf+b0z/ghLmBYNxb+tVpm/zv2caoKm3GfTazg==", "dev": true, "requires": { "jest-get-type": "^27.0.6", - "pretty-format": "^27.1.1" + "pretty-format": "^27.2.2" } }, "jest-matcher-utils": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.1.1.tgz", - "integrity": "sha512-Q1a10w9Y4sh0wegkdP6reQOa/Dtz7nAvDqBgrat1ItZAUvk4jzXAqyhXPu/ZuEtDaXaNKpdRPRQA8bvkOh2Eaw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.2.2.tgz", + "integrity": "sha512-xN3wT4p2i9DGB6zmL3XxYp5lJmq9Q6ff8XKlMtVVBS2SAshmgsPBALJFQ8dWRd2G/xf5q/N0SD0Mipt8QBA26A==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^27.1.1", + "jest-diff": "^27.2.2", "jest-get-type": "^27.0.6", - "pretty-format": "^27.1.1" + "pretty-format": "^27.2.2" } }, "jest-message-util": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.1.1.tgz", - "integrity": "sha512-b697BOJV93+AVGvzLRtVZ0cTVRbd59OaWnbB2D75GRaIMc4I+Z9W0wHxbfjW01JWO+TqqW4yevT0aN7Fd0XWng==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.2.2.tgz", + "integrity": "sha512-/iS5/m2FSF7Nn6APFoxFymJpyhB/gPf0CJa7uFSkbYaWvrADUfQ9NTsuyjpszKErOS2/huFs44ysWhlQTKvL8Q==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", @@ -14895,7 +14917,7 @@ "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.4", - "pretty-format": "^27.1.1", + "pretty-format": "^27.2.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -14935,44 +14957,44 @@ "dev": true }, "jest-resolve": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.1.1.tgz", - "integrity": "sha512-M41YFmWhvDVstwe7XuV21zynOiBLJB5Sk0GrIsYYgTkjfEWNLVXDjAyq1W7PHseaYNOxIc0nOGq/r5iwcZNC1A==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.2.2.tgz", + "integrity": "sha512-tfbHcBs/hJTb3fPQ/3hLWR+TsLNTzzK98TU+zIAsrL9nNzWfWROwopUOmiSUqmHMZW5t9au/433kSF2/Af+tTw==", "dev": true, "requires": { "@jest/types": "^27.1.1", "chalk": "^4.0.0", "escalade": "^3.1.1", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.1.1", + "jest-haste-map": "^27.2.2", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.1.1", - "jest-validate": "^27.1.1", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", "resolve": "^1.20.0", "slash": "^3.0.0" } }, "jest-resolve-dependencies": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.1.1.tgz", - "integrity": "sha512-sYZR+uBjFDCo4VhYeazZf/T+ryYItvdLKu9vHatqkUqHGjDMrdEPOykiqC2iEpaCFTS+3iL/21CYiJuKdRbniw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.2.2.tgz", + "integrity": "sha512-nvJS+DyY51HHdZnMIwXg7fimQ5ylFx4+quQXspQXde2rXYy+4v75UYoX/J65Ln8mKCNc6YF8HEhfGaRBOrxxHg==", "dev": true, "requires": { "@jest/types": "^27.1.1", "jest-regex-util": "^27.0.6", - "jest-snapshot": "^27.1.1" + "jest-snapshot": "^27.2.2" } }, "jest-runner": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.1.1.tgz", - "integrity": "sha512-lP3MBNQhg75/sQtVkC8dsAQZumvy3lHK/YIwYPfEyqGIX1qEcnYIRxP89q0ZgC5ngvi1vN2P5UFHszQxguWdng==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.2.2.tgz", + "integrity": "sha512-+bUFwBq+yTnvsOFuxetoQtkuOnqdAk2YuIGjlLmc7xLAXn/V1vjhXrLencgij0BUTTUvG9Aul3+5XDss4Wa8Eg==", "dev": true, "requires": { - "@jest/console": "^27.1.1", - "@jest/environment": "^27.1.1", - "@jest/test-result": "^27.1.1", - "@jest/transform": "^27.1.1", + "@jest/console": "^27.2.2", + "@jest/environment": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "chalk": "^4.0.0", @@ -14980,32 +15002,32 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.4", "jest-docblock": "^27.0.6", - "jest-environment-jsdom": "^27.1.1", - "jest-environment-node": "^27.1.1", - "jest-haste-map": "^27.1.1", - "jest-leak-detector": "^27.1.1", - "jest-message-util": "^27.1.1", - "jest-resolve": "^27.1.1", - "jest-runtime": "^27.1.1", - "jest-util": "^27.1.1", - "jest-worker": "^27.1.1", + "jest-environment-jsdom": "^27.2.2", + "jest-environment-node": "^27.2.2", + "jest-haste-map": "^27.2.2", + "jest-leak-detector": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-resolve": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-util": "^27.2.0", + "jest-worker": "^27.2.2", "source-map-support": "^0.5.6", "throat": "^6.0.1" } }, "jest-runtime": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.1.1.tgz", - "integrity": "sha512-FEwy+tSzmsvuKaQpyYsUyk31KG5vMmA2r2BSTHgv0yNfcooQdm2Ke91LM9Ud8D3xz8CLDHJWAI24haMFTwrsPg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.2.2.tgz", + "integrity": "sha512-PtTHCK5jT+KrIpKpjJsltu/dK5uGhBtTNLOk1Z+ZD2Jrxam2qQsOqDFYLszcK0jc2TLTNsrVpclqSftn7y3aXA==", "dev": true, "requires": { - "@jest/console": "^27.1.1", - "@jest/environment": "^27.1.1", - "@jest/fake-timers": "^27.1.1", - "@jest/globals": "^27.1.1", + "@jest/console": "^27.2.2", + "@jest/environment": "^27.2.2", + "@jest/fake-timers": "^27.2.2", + "@jest/globals": "^27.2.2", "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.1.1", - "@jest/transform": "^27.1.1", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", "@jest/types": "^27.1.1", "@types/yargs": "^16.0.0", "chalk": "^4.0.0", @@ -15015,14 +15037,14 @@ "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.1.1", - "jest-message-util": "^27.1.1", + "jest-haste-map": "^27.2.2", + "jest-message-util": "^27.2.2", "jest-mock": "^27.1.1", "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.1.1", - "jest-snapshot": "^27.1.1", - "jest-util": "^27.1.1", - "jest-validate": "^27.1.1", + "jest-resolve": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", "slash": "^3.0.0", "strip-bom": "^4.0.0", "yargs": "^16.0.3" @@ -15039,9 +15061,9 @@ } }, "jest-snapshot": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.1.1.tgz", - "integrity": "sha512-Wi3QGiuRFo3lU+EbQmZnBOks0CJyAMPHvYoG7iJk00Do10jeOyuOEO0Jfoaoun8+8TDv+Nzl7Aswir/IK9+1jg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.2.2.tgz", + "integrity": "sha512-7ODSvULMiiOVuuLvLZpDlpqqTqX9hDfdmijho5auVu9qRYREolvrvgH4kSNOKfcqV3EZOTuLKNdqsz1PM20PQA==", "dev": true, "requires": { "@babel/core": "^7.7.2", @@ -15050,23 +15072,23 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/transform": "^27.1.1", + "@jest/transform": "^27.2.2", "@jest/types": "^27.1.1", "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.1.1", + "expect": "^27.2.2", "graceful-fs": "^4.2.4", - "jest-diff": "^27.1.1", + "jest-diff": "^27.2.2", "jest-get-type": "^27.0.6", - "jest-haste-map": "^27.1.1", - "jest-matcher-utils": "^27.1.1", - "jest-message-util": "^27.1.1", - "jest-resolve": "^27.1.1", - "jest-util": "^27.1.1", + "jest-haste-map": "^27.2.2", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-resolve": "^27.2.2", + "jest-util": "^27.2.0", "natural-compare": "^1.4.0", - "pretty-format": "^27.1.1", + "pretty-format": "^27.2.2", "semver": "^7.3.2" }, "dependencies": { @@ -15082,9 +15104,9 @@ } }, "jest-util": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.1.1.tgz", - "integrity": "sha512-zf9nEbrASWn2mC/L91nNb0K+GkhFvi4MP6XJG2HqnHzHvLYcs7ou/In68xYU1i1dSkJlrWcYfWXQE8nVR+nbOA==", + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.2.0.tgz", + "integrity": "sha512-T5ZJCNeFpqcLBpx+Hl9r9KoxBCUqeWlJ1Htli+vryigZVJ1vuLB9j35grEBASp4R13KFkV7jM52bBGnArpJN6A==", "dev": true, "requires": { "@jest/types": "^27.1.1", @@ -15096,9 +15118,9 @@ } }, "jest-validate": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.1.1.tgz", - "integrity": "sha512-N5Er5FKav/8m2dJwn7BGnZwnoD1BSc8jx5T+diG2OvyeugvZDhPeAt5DrNaGkkaKCrSUvuE7A5E4uHyT7Vj0Mw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.2.2.tgz", + "integrity": "sha512-01mwTAs2kgDuX98Ua3Xhdhp5lXsLU4eyg6k56adTtrXnU/GbLd9uAsh5nc4MWVtUXMeNmHUyEiD4ibLqE8MuNw==", "dev": true, "requires": { "@jest/types": "^27.1.1", @@ -15106,7 +15128,7 @@ "chalk": "^4.0.0", "jest-get-type": "^27.0.6", "leven": "^3.1.0", - "pretty-format": "^27.1.1" + "pretty-format": "^27.2.2" }, "dependencies": { "camelcase": { @@ -15118,24 +15140,24 @@ } }, "jest-watcher": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.1.1.tgz", - "integrity": "sha512-XQzyHbxziDe+lZM6Dzs40fEt4q9akOGwitJnxQasJ9WG0bv3JGiRlsBgjw13znGapeMtFaEsyhL0Cl04IbaoWQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.2.2.tgz", + "integrity": "sha512-7HJwZq06BCfM99RacCVzXO90B20/dNJvq+Ouiu/VrFdFRCpbnnqlQUEk4KAhBSllgDrTPgKu422SCF5KKBHDRA==", "dev": true, "requires": { - "@jest/test-result": "^27.1.1", + "@jest/test-result": "^27.2.2", "@jest/types": "^27.1.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^27.1.1", + "jest-util": "^27.2.0", "string-length": "^4.0.1" } }, "jest-worker": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.1.1.tgz", - "integrity": "sha512-XJKCL7tu+362IUYTWvw8+3S75U7qMiYiRU6u5yqscB48bTvzwN6i8L/7wVTXiFLwkRsxARNM7TISnTvcgv9hxA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.2.2.tgz", + "integrity": "sha512-aG1xq9KgWB2CPC8YdMIlI8uZgga2LFNcGbHJxO8ctfXAydSaThR4EewKQGg3tBOC+kS3vhPGgymsBdi9VINjPw==", "dev": true, "requires": { "@types/node": "*", @@ -15827,9 +15849,33 @@ } }, "node-fetch": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.2.tgz", - "integrity": "sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA==" + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", + "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } }, "node-ical": { "version": "0.13.0", @@ -16440,9 +16486,9 @@ "devOptional": true }, "prettier": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.0.tgz", - "integrity": "sha512-DsEPLY1dE5HF3BxCRBmD4uYZ+5DCbvatnolqTqcxEgKVZnL2kUfyu7b8pPQ5+hTBkdhU9SLUmK0/pHb07RE4WQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", "dev": true }, "prettier-linter-helpers": { @@ -16455,13 +16501,13 @@ } }, "pretty-format": { - "version": "27.1.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.1.1.tgz", - "integrity": "sha512-zdBi/xlstKJL42UH7goQti5Hip/B415w1Mfj+WWWYMBylAYtKESnXGUtVVcMVid9ReVjypCotUV6CEevYPHv2g==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.2.2.tgz", + "integrity": "sha512-+DdLh+rtaElc2SQOE/YPH8k2g3Rf2OXWEpy06p8Szs3hdVSYD87QOOlYRHWAeb/59XTmeVmRKvDD0svHqf6ycA==", "dev": true, "requires": { "@jest/types": "^27.1.1", - "ansi-regex": "^5.0.0", + "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, @@ -17456,9 +17502,9 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -18067,9 +18113,9 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" }, "v8-to-istanbul": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz", - "integrity": "sha512-LkmXi8UUNxnCC+JlH7/fsfsKr5AU110l+SYGJimWNkWhxbN5EyeOtm1MJ0hhvqMMOhGwBj1Fp70Yv9i+hX0QAg==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", + "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", diff --git a/package.json b/package.json index 92350f0c..2a0107df 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "magicmirror", - "version": "2.17.0-develop", + "version": "2.18.0-develop", "description": "The open source modular smart mirror platform.", "main": "js/electron.js", "scripts": { @@ -12,6 +12,7 @@ "postinstall": "npm run install-fonts && echo \"MagicMirror installation finished successfully! \n\"", "test": "NODE_ENV=test jest -i --forceExit", "test:coverage": "NODE_ENV=test nyc --reporter=lcov --reporter=text jest -i --forceExit", + "test:electron": "NODE_ENV=test jest --selectProjects electron -i --forceExit", "test:e2e": "NODE_ENV=test jest --selectProjects e2e -i --forceExit", "test:unit": "NODE_ENV=test jest --selectProjects unit -i --forceExit", "test:prettier": "prettier . --check", @@ -46,16 +47,16 @@ "homepage": "https://magicmirror.builders", "devDependencies": { "eslint-config-prettier": "^8.3.0", - "eslint-plugin-jest": "^24.4.0", + "eslint-plugin-jest": "^24.4.2", "eslint-plugin-jsdoc": "^36.1.0", "eslint-plugin-prettier": "^4.0.0", "express-basic-auth": "^1.2.0", "husky": "^7.0.2", - "jest": "^27.1.1", + "jest": "^27.2.2", "jsdom": "^17.0.0", "lodash": "^4.17.21", "nyc": "^15.1.0", - "prettier": "^2.4.0", + "prettier": "^2.4.1", "pretty-quick": "^3.1.1", "sinon": "^11.1.2", "spectron": "^15.0.0", @@ -66,7 +67,7 @@ "suncalc": "^1.8.0" }, "optionalDependencies": { - "electron": "^13.3.0" + "electron": "^13.5.1" }, "dependencies": { "colors": "^1.4.0", @@ -80,7 +81,7 @@ "iconv-lite": "^0.6.3", "module-alias": "^2.2.2", "moment": "^2.29.1", - "node-fetch": "^2.6.2", + "node-fetch": "^2.6.5", "node-ical": "^0.13.0", "socket.io": "^4.2.0" }, @@ -106,14 +107,31 @@ "/tests/unit/mocks" ] }, + { + "displayName": "electron", + "testMatch": [ + "**/tests/electron/**/*.[jt]s?(x)" + ], + "testPathIgnorePatterns": [ + "/tests/electron/modules/mocks", + "/tests/electron/global-setup.js", + "/tests/electron/modules/basic-auth.js" + ] + }, { "displayName": "e2e", + "setupFilesAfterEnv": [ + "/tests/e2e/mock-console.js" + ], "testMatch": [ "**/tests/e2e/**/*.[jt]s?(x)" ], + "modulePaths": [ + "/js/" + ], "testPathIgnorePatterns": [ - "/tests/e2e/modules/mocks", - "/tests/e2e/global-setup.js" + "/tests/e2e/global-setup.js", + "/tests/e2e/mock-console.js" ] } ] diff --git a/tests/configs/default.js b/tests/configs/default.js index e3236318..5568e5e0 100644 --- a/tests/configs/default.js +++ b/tests/configs/default.js @@ -6,12 +6,6 @@ exports.configFactory = function (options) { return Object.assign( { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", - timeFormat: 24, - units: "metric", electronOptions: { webPreferences: { nodeIntegration: true, diff --git a/tests/configs/modules/alert/default.js b/tests/configs/modules/alert/default.js index b75a41f8..423260c7 100644 --- a/tests/configs/modules/alert/default.js +++ b/tests/configs/modules/alert/default.js @@ -3,7 +3,7 @@ * By rejas * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { modules: [ { module: "alert", @@ -13,7 +13,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/clock/clock_12hr.js b/tests/configs/modules/clock/clock_12hr.js index 35b45914..6b8917bd 100644 --- a/tests/configs/modules/clock/clock_12hr.js +++ b/tests/configs/modules/clock/clock_12hr.js @@ -3,7 +3,7 @@ * By Sergey Morozov * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { timeFormat: 12, modules: [ @@ -12,7 +12,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( position: "middle_center" } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/clock/clock_24hr.js b/tests/configs/modules/clock/clock_24hr.js index 01b2a36b..27f89d0c 100644 --- a/tests/configs/modules/clock/clock_24hr.js +++ b/tests/configs/modules/clock/clock_24hr.js @@ -3,14 +3,14 @@ * By Sergey Morozov * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { modules: [ { module: "clock", position: "middle_center" } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/clock/clock_analog.js b/tests/configs/modules/clock/clock_analog.js index b33bd051..cbe3fecc 100644 --- a/tests/configs/modules/clock/clock_analog.js +++ b/tests/configs/modules/clock/clock_analog.js @@ -2,7 +2,7 @@ * * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { modules: [ { module: "clock", @@ -13,7 +13,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/clock/clock_displaySeconds_false.js b/tests/configs/modules/clock/clock_displaySeconds_false.js index 1caef7e3..57bf006a 100644 --- a/tests/configs/modules/clock/clock_displaySeconds_false.js +++ b/tests/configs/modules/clock/clock_displaySeconds_false.js @@ -3,7 +3,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { timeFormat: 12, modules: [ @@ -15,7 +15,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/clock/clock_showPeriodUpper.js b/tests/configs/modules/clock/clock_showPeriodUpper.js index b069c438..1e01644f 100644 --- a/tests/configs/modules/clock/clock_showPeriodUpper.js +++ b/tests/configs/modules/clock/clock_showPeriodUpper.js @@ -3,7 +3,7 @@ * By Sergey Morozov * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { timeFormat: 12, modules: [ @@ -15,7 +15,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/clock/clock_showTime.js b/tests/configs/modules/clock/clock_showTime.js index 93dd83de..37bdc5cc 100644 --- a/tests/configs/modules/clock/clock_showTime.js +++ b/tests/configs/modules/clock/clock_showTime.js @@ -3,7 +3,7 @@ * By Johan Hammar * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { timeFormat: 12, modules: [ @@ -15,7 +15,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/clock/clock_showWeek.js b/tests/configs/modules/clock/clock_showWeek.js index b595ba70..2c421e85 100644 --- a/tests/configs/modules/clock/clock_showWeek.js +++ b/tests/configs/modules/clock/clock_showWeek.js @@ -3,7 +3,7 @@ * By Johan Hammar * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { timeFormat: 12, modules: [ @@ -15,7 +15,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/clock/es/clock_12hr.js b/tests/configs/modules/clock/es/clock_12hr.js index addbeb9f..07e5206a 100644 --- a/tests/configs/modules/clock/es/clock_12hr.js +++ b/tests/configs/modules/clock/es/clock_12hr.js @@ -3,7 +3,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { language: "es", timeFormat: 12, @@ -13,7 +13,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( position: "middle_center" } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/clock/es/clock_24hr.js b/tests/configs/modules/clock/es/clock_24hr.js index a5fe49ca..469f4e3b 100644 --- a/tests/configs/modules/clock/es/clock_24hr.js +++ b/tests/configs/modules/clock/es/clock_24hr.js @@ -3,7 +3,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { language: "es", modules: [ @@ -12,7 +12,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( position: "middle_center" } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/clock/es/clock_showPeriodUpper.js b/tests/configs/modules/clock/es/clock_showPeriodUpper.js index 4a5ab636..0253c28c 100644 --- a/tests/configs/modules/clock/es/clock_showPeriodUpper.js +++ b/tests/configs/modules/clock/es/clock_showPeriodUpper.js @@ -3,7 +3,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { language: "es", timeFormat: 12, @@ -16,7 +16,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/clock/es/clock_showWeek.js b/tests/configs/modules/clock/es/clock_showWeek.js index b4a436a6..dd8f6cd2 100644 --- a/tests/configs/modules/clock/es/clock_showWeek.js +++ b/tests/configs/modules/clock/es/clock_showWeek.js @@ -4,7 +4,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { language: "es", timeFormat: 12, @@ -17,7 +17,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/compliments/compliments_anytime.js b/tests/configs/modules/compliments/compliments_anytime.js index f6731edf..2034b379 100644 --- a/tests/configs/modules/compliments/compliments_anytime.js +++ b/tests/configs/modules/compliments/compliments_anytime.js @@ -3,7 +3,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { timeFormat: 12, modules: [ @@ -20,7 +20,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/compliments/compliments_date.js b/tests/configs/modules/compliments/compliments_date.js index c9549816..a89dd7de 100644 --- a/tests/configs/modules/compliments/compliments_date.js +++ b/tests/configs/modules/compliments/compliments_date.js @@ -3,7 +3,7 @@ * By Rejas * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { timeFormat: 12, modules: [ @@ -21,7 +21,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/compliments/compliments_only_anytime.js b/tests/configs/modules/compliments/compliments_only_anytime.js index d65bc67d..5261e58b 100644 --- a/tests/configs/modules/compliments/compliments_only_anytime.js +++ b/tests/configs/modules/compliments/compliments_only_anytime.js @@ -3,7 +3,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { timeFormat: 12, modules: [ @@ -17,7 +17,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/compliments/compliments_parts_day.js b/tests/configs/modules/compliments/compliments_parts_day.js index e490a710..08c9d94e 100644 --- a/tests/configs/modules/compliments/compliments_parts_day.js +++ b/tests/configs/modules/compliments/compliments_parts_day.js @@ -3,7 +3,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { timeFormat: 12, modules: [ @@ -19,7 +19,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/display.js b/tests/configs/modules/display.js index 070dc9e5..03aa4f19 100644 --- a/tests/configs/modules/display.js +++ b/tests/configs/modules/display.js @@ -3,7 +3,7 @@ * By Rejas * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { modules: [ { module: "helloworld", @@ -21,11 +21,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); - -config.electronOptions.fullscreen = false; -config.electronOptions.width = 800; -config.electronOptions.height = 600; +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/helloworld/helloworld.js b/tests/configs/modules/helloworld/helloworld.js index 9845e4b8..39480bc1 100644 --- a/tests/configs/modules/helloworld/helloworld.js +++ b/tests/configs/modules/helloworld/helloworld.js @@ -3,7 +3,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { modules: [ { module: "helloworld", @@ -13,7 +13,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/helloworld/helloworld_default.js b/tests/configs/modules/helloworld/helloworld_default.js index 6400c9f7..ea95ad83 100644 --- a/tests/configs/modules/helloworld/helloworld_default.js +++ b/tests/configs/modules/helloworld/helloworld_default.js @@ -3,14 +3,14 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { modules: [ { module: "helloworld", position: "bottom_bar" } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/newsfeed/default.js b/tests/configs/modules/newsfeed/default.js index 1a112566..7758da0c 100644 --- a/tests/configs/modules/newsfeed/default.js +++ b/tests/configs/modules/newsfeed/default.js @@ -3,7 +3,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { timeFormat: 12, modules: [ @@ -20,7 +20,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/newsfeed/incorrect_url.js b/tests/configs/modules/newsfeed/incorrect_url.js index ab126aa4..522fa2d1 100644 --- a/tests/configs/modules/newsfeed/incorrect_url.js +++ b/tests/configs/modules/newsfeed/incorrect_url.js @@ -2,7 +2,7 @@ * * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { timeFormat: 12, modules: [ @@ -19,7 +19,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/newsfeed/prohibited_words.js b/tests/configs/modules/newsfeed/prohibited_words.js index f4040557..68d22f54 100644 --- a/tests/configs/modules/newsfeed/prohibited_words.js +++ b/tests/configs/modules/newsfeed/prohibited_words.js @@ -2,7 +2,7 @@ * * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { timeFormat: 12, modules: [ @@ -21,7 +21,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } } ] -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/positions.js b/tests/configs/modules/positions.js index 479775c8..186c25f9 100644 --- a/tests/configs/modules/positions.js +++ b/tests/configs/modules/positions.js @@ -3,7 +3,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { modules: // Using exotic content. This is why don't accept go to JSON configuration file (function () { @@ -20,7 +20,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory( } return modules; })() -}); +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/without_modules.js b/tests/configs/without_modules.js index 02b767c0..50ff521e 100644 --- a/tests/configs/without_modules.js +++ b/tests/configs/without_modules.js @@ -3,10 +3,9 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = { ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.10.1"] -}); -delete config.modules; +}; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/e2e/env_spec.js b/tests/e2e/env_spec.js index 706274a2..b2a7238a 100644 --- a/tests/e2e/env_spec.js +++ b/tests/e2e/env_spec.js @@ -1,42 +1,13 @@ -const helpers = require("./global-setup"); const fetch = require("node-fetch"); +const helpers = require("./global-setup"); describe("Electron app environment", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/env.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/default.js"); + helpers.getDocument(done); }); - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); - }); - - it("should open a browserwindow", async function () { - await app.client.waitUntilWindowLoaded(); - app.browserWindow.focus(); - expect(await app.client.getWindowCount()).toBe(1); - expect(await app.browserWindow.isMinimized()).toBe(false); - expect(await app.browserWindow.isDevToolsOpened()).toBe(false); - expect(await app.browserWindow.isVisible()).toBe(true); - expect(await app.browserWindow.isFocused()).toBe(true); - const bounds = await app.browserWindow.getBounds(); - expect(bounds.width).toBeGreaterThan(0); - expect(bounds.height).toBeGreaterThan(0); - expect(await app.browserWindow.getTitle()).toBe("MagicMirror²"); + afterAll(function () { + helpers.stopApplication(); }); it("get request from http://localhost:8080 should return 200", function (done) { @@ -52,4 +23,10 @@ describe("Electron app environment", function () { done(); }); }); + + it("should show the title MagicMirror²", function () { + const elem = document.querySelector("title"); + expect(elem).not.toBe(null); + expect(elem.textContent).toBe("MagicMirror²"); + }); }); diff --git a/tests/e2e/fonts.js b/tests/e2e/fonts.js index b1459294..54cd2d87 100644 --- a/tests/e2e/fonts.js +++ b/tests/e2e/fonts.js @@ -1,10 +1,7 @@ -const helpers = require("./global-setup"); const fetch = require("node-fetch"); +const helpers = require("./global-setup"); describe("All font files from roboto.css should be downloadable", function () { - helpers.setupTimeout(this); - - let app; const fontFiles = []; // Statements below filters out all 'url' lines in the CSS file const fileContent = require("fs").readFileSync(__dirname + "/../../fonts/roboto.css", "utf8"); @@ -18,20 +15,10 @@ describe("All font files from roboto.css should be downloadable", function () { } beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/without_modules.js"; - - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); + helpers.startApplication("tests/configs/without_modules.js"); }); - afterAll(function () { - return helpers.stopApplication(app); + helpers.stopApplication(); }); test.each(fontFiles)("should return 200 HTTP code for file '%s'", (fontFile, done) => { diff --git a/tests/e2e/global-setup.js b/tests/e2e/global-setup.js index a1e0685b..45726493 100644 --- a/tests/e2e/global-setup.js +++ b/tests/e2e/global-setup.js @@ -1,53 +1,32 @@ -/* - * Magic Mirror Global Setup Test Suite - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ -const Application = require("spectron").Application; -const assert = require("assert"); -const path = require("path"); -const EventEmitter = require("events"); +const jsdom = require("jsdom"); -exports.getElectronPath = function () { - let electronPath = path.join(__dirname, "..", "..", "node_modules", ".bin", "electron"); - if (process.platform === "win32") { - electronPath += ".cmd"; +exports.startApplication = function (configFilename, exec) { + jest.resetModules(); + if (global.app) { + global.app.stop(); } - return electronPath; + // Set config sample for use in test + process.env.MM_CONFIG_FILE = configFilename; + if (exec) exec; + global.app = require("app.js"); + global.app.start(); }; -// Set timeout - if this is run as CI Job, increase timeout -exports.setupTimeout = function (test) { - if (process.env.CI) { - jest.setTimeout(30000); - } else { - jest.setTimeout(10000); +exports.stopApplication = function () { + if (global.app) { + global.app.stop(); } }; -exports.startApplication = function (options) { - const emitter = new EventEmitter(); - emitter.setMaxListeners(100); - - options.path = exports.getElectronPath(); - if (process.env.CI) { - options.startTimeout = 30000; - } - - const app = new Application(options); - return app.start().then(function () { - assert.strictEqual(app.isRunning(), true); - return app; - }); -}; - -exports.stopApplication = function (app) { - if (!app || !app.isRunning()) { - return; - } - - return app.stop().then(function () { - assert.strictEqual(app.isRunning(), false); +exports.getDocument = function (callback, ms) { + const url = "http://" + (config.address || "localhost") + ":" + (config.port || "8080"); + jsdom.JSDOM.fromURL(url, { resources: "usable", runScripts: "dangerously" }).then((dom) => { + dom.window.name = "jsdom"; + dom.window.onload = function () { + global.document = dom.window.document; + setTimeout(() => { + callback(); + }, ms); + }; }); }; diff --git a/tests/e2e/ipWhitelist_spec.js b/tests/e2e/ipWhitelist_spec.js index 3406e0e7..b518cfff 100644 --- a/tests/e2e/ipWhitelist_spec.js +++ b/tests/e2e/ipWhitelist_spec.js @@ -1,29 +1,13 @@ -const helpers = require("./global-setup"); const fetch = require("node-fetch"); +const helpers = require("./global-setup"); describe("ipWhitelist directive configuration", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); - }); - describe("Set ipWhitelist without access", function () { beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/noIpWhiteList.js"; + helpers.startApplication("tests/configs/noIpWhiteList.js"); + }); + afterAll(function () { + helpers.stopApplication(); }); it("should return 403", function (done) { @@ -36,8 +20,10 @@ describe("ipWhitelist directive configuration", function () { describe("Set ipWhitelist []", function () { beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/empty_ipWhiteList.js"; + helpers.startApplication("tests/configs/empty_ipWhiteList.js"); + }); + afterAll(function () { + helpers.stopApplication(); }); it("should return 200", function (done) { diff --git a/tests/e2e/mock-console.js b/tests/e2e/mock-console.js new file mode 100644 index 00000000..90b70f12 --- /dev/null +++ b/tests/e2e/mock-console.js @@ -0,0 +1,21 @@ +/** + * Suppresses errors concerning web server already shut down. + * + * @param {string} err The error message. + */ +function mockError(err) { + if (err.includes("ECONNREFUSED") || err.includes("ECONNRESET") || err.includes("socket hang up") || err.includes("exports is not defined")) { + jest.fn(); + } else { + console.dir(err); + } +} + +global.console = { + log: jest.fn(), + dir: console.dir, + error: mockError, + warn: console.warn, + info: jest.fn(), + debug: console.debug +}; diff --git a/tests/e2e/modules/alert_spec.js b/tests/e2e/modules/alert_spec.js index 12e724f0..a557acc5 100644 --- a/tests/e2e/modules/alert_spec.js +++ b/tests/e2e/modules/alert_spec.js @@ -1,32 +1,17 @@ const helpers = require("../global-setup"); describe("Alert module", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/alert/default.js"); + helpers.getDocument(done, 1000); + }); + afterAll(function () { + helpers.stopApplication(); }); - afterEach(function () { - return helpers.stopApplication(app); - }); - - describe("Default configuration", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/alert/default.js"; - }); - - it("should show the welcome message", function () { - return app.client.waitUntilTextExists(".ns-box .ns-box-inner .light.bright.small", "Welcome, start was successful!", 10000); - }); + it("should show the welcome message", function () { + const elem = document.querySelector(".ns-box .ns-box-inner .light.bright.small"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Welcome, start was successful!"); }); }); diff --git a/tests/e2e/modules/clock_es_spec.js b/tests/e2e/modules/clock_es_spec.js index 4c39a241..78818014 100644 --- a/tests/e2e/modules/clock_es_spec.js +++ b/tests/e2e/modules/clock_es_spec.js @@ -1,86 +1,71 @@ const helpers = require("../global-setup"); describe("Clock set to spanish language module", function () { - helpers.setupTimeout(this); + afterAll(function () { + helpers.stopApplication(); + }); - let app = null; - - const testMatch = async function (element, regex) { - await app.client.waitUntilWindowLoaded(); - const elem = await app.client.$(element); - const txt = await elem.getText(element); - return expect(txt).toMatch(regex); + const testMatch = function (element, regex) { + const elem = document.querySelector(element); + expect(elem).not.toBe(null); + expect(elem.textContent).toMatch(regex); }; - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); - }); - describe("with default 24hr clock config", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_24hr.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/es/clock_24hr.js"); + helpers.getDocument(done, 1000); }); - it("shows date with correct format", async function () { + it("shows date with correct format", function () { const dateRegex = /^(?:lunes|martes|miércoles|jueves|viernes|sábado|domingo), \d{1,2} de (?:enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre) de \d{4}$/; - return testMatch(".clock .date", dateRegex); + testMatch(".clock .date", dateRegex); }); - it("shows time in 24hr format", async function () { + it("shows time in 24hr format", function () { const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/; - return testMatch(".clock .time", timeRegex); + testMatch(".clock .time", timeRegex); }); }); describe("with default 12hr clock config", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_12hr.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/es/clock_12hr.js"); + helpers.getDocument(done, 1000); }); - it("shows date with correct format", async function () { + it("shows date with correct format", function () { const dateRegex = /^(?:lunes|martes|miércoles|jueves|viernes|sábado|domingo), \d{1,2} de (?:enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre) de \d{4}$/; - return testMatch(".clock .date", dateRegex); + testMatch(".clock .date", dateRegex); }); - it("shows time in 12hr format", async function () { + it("shows time in 12hr format", function () { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/; - return testMatch(".clock .time", timeRegex); + testMatch(".clock .time", timeRegex); }); }); describe("with showPeriodUpper config enabled", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_showPeriodUpper.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/es/clock_showPeriodUpper.js"); + helpers.getDocument(done, 1000); }); - it("shows 12hr time with upper case AM/PM", async function () { + it("shows 12hr time with upper case AM/PM", function () { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[AP]M$/; - return testMatch(".clock .time", timeRegex); + testMatch(".clock .time", timeRegex); }); }); describe("with showWeek config enabled", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_showWeek.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/es/clock_showWeek.js"); + helpers.getDocument(done, 1000); }); - it("shows week with correct format", async function () { + it("shows week with correct format", function () { const weekRegex = /^Semana [0-9]{1,2}$/; - return testMatch(".clock .week", weekRegex); + testMatch(".clock .week", weekRegex); }); }); }); diff --git a/tests/e2e/modules/clock_spec.js b/tests/e2e/modules/clock_spec.js index c2e03fc9..79e26f47 100644 --- a/tests/e2e/modules/clock_spec.js +++ b/tests/e2e/modules/clock_spec.js @@ -2,133 +2,115 @@ const helpers = require("../global-setup"); const moment = require("moment"); describe("Clock module", function () { - helpers.setupTimeout(this); + afterAll(function () { + helpers.stopApplication(); + }); - let app = null; - - const testMatch = async function (element, regex) { - await app.client.waitUntilWindowLoaded(); - const elem = await app.client.$(element); - const txt = await elem.getText(element); - return expect(txt).toMatch(regex); + const testMatch = function (element, regex) { + const elem = document.querySelector(element); + expect(elem).not.toBe(null); + expect(elem.textContent).toMatch(regex); }; - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); - }); - describe("with default 24hr clock config", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_24hr.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/clock_24hr.js"); + helpers.getDocument(done, 1000); }); - it("should show the date in the correct format", async function () { + it("should show the date in the correct format", function () { const dateRegex = /^(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}, \d{4}$/; - return testMatch(".clock .date", dateRegex); + testMatch(".clock .date", dateRegex); }); - it("should show the time in 24hr format", async function () { + it("should show the time in 24hr format", function () { const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/; - return testMatch(".clock .time", timeRegex); + testMatch(".clock .time", timeRegex); }); }); describe("with default 12hr clock config", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_12hr.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/clock_12hr.js"); + helpers.getDocument(done, 1000); }); - it("should show the date in the correct format", async function () { + it("should show the date in the correct format", function () { const dateRegex = /^(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}, \d{4}$/; - return testMatch(".clock .date", dateRegex); + testMatch(".clock .date", dateRegex); }); - it("should show the time in 12hr format", async function () { + it("should show the time in 12hr format", function () { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/; - return testMatch(".clock .time", timeRegex); + testMatch(".clock .time", timeRegex); }); }); describe("with showPeriodUpper config enabled", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_showPeriodUpper.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/clock_showPeriodUpper.js"); + helpers.getDocument(done, 1000); }); - it("should show 12hr time with upper case AM/PM", async function () { + it("should show 12hr time with upper case AM/PM", function () { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[AP]M$/; - return testMatch(".clock .time", timeRegex); + testMatch(".clock .time", timeRegex); }); }); describe("with displaySeconds config disabled", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_displaySeconds_false.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/clock_displaySeconds_false.js"); + helpers.getDocument(done, 1000); }); - it("should show 12hr time without seconds am/pm", async function () { + it("should show 12hr time without seconds am/pm", function () { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[ap]m$/; - return testMatch(".clock .time", timeRegex); + testMatch(".clock .time", timeRegex); }); }); describe("with showTime config disabled", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_showTime.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/clock_showTime.js"); + helpers.getDocument(done, 1000); }); - it("should show not show the time when digital clock is shown", async function () { - await app.client.waitUntilWindowLoaded(); - const time = await app.client.$$(".clock .digital .time"); - return expect(time.length).toBe(0); + it("should show not show the time when digital clock is shown", function () { + const elem = document.querySelector(".clock .digital .time"); + expect(elem).toBe(null); }); }); describe("with showWeek config enabled", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_showWeek.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/clock_showWeek.js"); + helpers.getDocument(done, 1000); }); - it("should show the week in the correct format", async function () { + it("should show the week in the correct format", function () { const weekRegex = /^Week [0-9]{1,2}$/; - return testMatch(".clock .week", weekRegex); + testMatch(".clock .week", weekRegex); }); - it("should show the week with the correct number of week of year", async function () { + it("should show the week with the correct number of week of year", function () { const currentWeekNumber = moment().week(); const weekToShow = "Week " + currentWeekNumber; - await app.client.waitUntilWindowLoaded(); - const elem = await app.client.$(".clock .week"); - const txt = await elem.getText(".clock .week"); - return expect(txt).toBe(weekToShow); + const elem = document.querySelector(".clock .week"); + expect(elem).not.toBe(null); + expect(elem.textContent).toBe(weekToShow); }); }); describe("with analog clock face enabled", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_analog.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/clock_analog.js"); + helpers.getDocument(done, 1000); }); - it("should show the analog clock face", async () => { - await app.client.waitUntilWindowLoaded(); - const clock = await app.client.$$(".clockCircle"); - return expect(clock.length).toBe(1); + it("should show the analog clock face", () => { + const elem = document.querySelector(".clockCircle"); + expect(elem).not.toBe(null); }); }); }); diff --git a/tests/e2e/modules/compliments_spec.js b/tests/e2e/modules/compliments_spec.js index 81c6e982..73f851c5 100644 --- a/tests/e2e/modules/compliments_spec.js +++ b/tests/e2e/modules/compliments_spec.js @@ -1,106 +1,87 @@ const helpers = require("../global-setup"); +/** + * move similar tests in function doTest + * + * @param {Array} complimentsArray The array of compliments. + */ +function doTest(complimentsArray) { + let elem = document.querySelector(".compliments"); + expect(elem).not.toBe(null); + elem = document.querySelector(".module-content"); + expect(elem).not.toBe(null); + expect(complimentsArray).toContain(elem.textContent); +} + describe("Compliments module", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); + afterAll(function () { + helpers.stopApplication(); }); describe("parts of days", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_parts_day.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/compliments/compliments_parts_day.js"); + helpers.getDocument(done, 1000); }); - it("if Morning compliments for that part of day", async function () { + it("if Morning compliments for that part of day", function () { const hour = new Date().getHours(); if (hour >= 3 && hour < 12) { // if morning check - const elem = await app.client.$(".compliments"); - return elem.getText(".compliments").then(function (text) { - expect(["Hi", "Good Morning", "Morning test"]).toContain(text); - }); + doTest(["Hi", "Good Morning", "Morning test"]); } }); - it("if Afternoon show Compliments for that part of day", async function () { + it("if Afternoon show Compliments for that part of day", function () { const hour = new Date().getHours(); if (hour >= 12 && hour < 17) { // if afternoon check - const elem = await app.client.$(".compliments"); - return elem.getText(".compliments").then(function (text) { - expect(["Hello", "Good Afternoon", "Afternoon test"]).toContain(text); - }); + doTest(["Hello", "Good Afternoon", "Afternoon test"]); } }); - it("if Evening show Compliments for that part of day", async function () { + it("if Evening show Compliments for that part of day", function () { const hour = new Date().getHours(); if (!(hour >= 3 && hour < 12) && !(hour >= 12 && hour < 17)) { // if evening check - const elem = await app.client.$(".compliments"); - return elem.getText(".compliments").then(function (text) { - expect(["Hello There", "Good Evening", "Evening test"]).toContain(text); - }); + doTest(["Hello There", "Good Evening", "Evening test"]); } }); }); describe("Feature anytime in compliments module", function () { describe("Set anytime and empty compliments for morning, evening and afternoon ", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_anytime.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/compliments/compliments_anytime.js"); + helpers.getDocument(done, 1000); }); - it("Show anytime because if configure empty parts of day compliments and set anytime compliments", async function () { - const elem = await app.client.$(".compliments"); - return elem.getText(".compliments").then(function (text) { - expect(["Anytime here"]).toContain(text); - }); + it("Show anytime because if configure empty parts of day compliments and set anytime compliments", function () { + doTest(["Anytime here"]); }); }); describe("Only anytime present in configuration compliments", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_only_anytime.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/compliments/compliments_only_anytime.js"); + helpers.getDocument(done, 1000); }); - it("Show anytime compliments", async function () { - const elem = await app.client.$(".compliments"); - return elem.getText(".compliments").then(function (text) { - expect(["Anytime here"]).toContain(text); - }); + it("Show anytime compliments", function () { + doTest(["Anytime here"]); }); }); }); describe("Feature date in compliments module", function () { describe("Set date and empty compliments for anytime, morning, evening and afternoon", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_date.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/compliments/compliments_date.js"); + helpers.getDocument(done, 1000); }); - it("Show happy new year compliment on new years day", async function () { - const elem = await app.client.$(".compliments"); - return elem.getText(".compliments").then(function (text) { - expect(["Happy new year!"]).toContain(text); - }); + it("Show happy new year compliment on new years day", function () { + doTest(["Happy new year!"]); }); }); }); diff --git a/tests/e2e/modules/helloworld_spec.js b/tests/e2e/modules/helloworld_spec.js index 95ee1a2d..d8f1a3c6 100644 --- a/tests/e2e/modules/helloworld_spec.js +++ b/tests/e2e/modules/helloworld_spec.js @@ -1,45 +1,33 @@ const helpers = require("../global-setup"); describe("Test helloworld module", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); + afterAll(function () { + helpers.stopApplication(); }); describe("helloworld set config text", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/helloworld/helloworld.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/helloworld/helloworld.js"); + helpers.getDocument(done, 1000); }); - it("Test message helloworld module", async function () { - const elem = await app.client.$(".helloworld"); - return expect(await elem.getText(".helloworld")).toBe("Test HelloWorld Module"); + it("Test message helloworld module", function () { + const elem = document.querySelector(".helloworld"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Test HelloWorld Module"); }); }); describe("helloworld default config text", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/helloworld/helloworld_default.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/helloworld/helloworld_default.js"); + helpers.getDocument(done, 1000); }); - it("Test message helloworld module", async function () { - const elem = await app.client.$(".helloworld"); - return expect(await elem.getText(".helloworld")).toBe("Hello World!"); + it("Test message helloworld module", function () { + const elem = document.querySelector(".helloworld"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Hello World!"); }); }); }); diff --git a/tests/e2e/modules/newsfeed_spec.js b/tests/e2e/modules/newsfeed_spec.js index fe544a0b..d7a3b9fe 100644 --- a/tests/e2e/modules/newsfeed_spec.js +++ b/tests/e2e/modules/newsfeed_spec.js @@ -1,67 +1,63 @@ const helpers = require("../global-setup"); describe("Newsfeed module", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); + afterAll(function () { + helpers.stopApplication(); }); describe("Default configuration", function () { - beforeAll(function () { - process.env.MM_CONFIG_FILE = "tests/configs/modules/newsfeed/default.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/newsfeed/default.js"); + helpers.getDocument(done, 3000); }); it("should show the newsfeed title", function () { - return app.client.waitUntilTextExists(".newsfeed .newsfeed-source", "Rodrigo Ramirez Blog", 10000); + const elem = document.querySelector(".newsfeed .newsfeed-source"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Rodrigo Ramirez Blog"); }); it("should show the newsfeed article", function () { - return app.client.waitUntilTextExists(".newsfeed .newsfeed-title", "QPanel", 10000); + const elem = document.querySelector(".newsfeed .newsfeed-title"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("QPanel"); }); - it("should NOT show the newsfeed description", async () => { - await app.client.waitUntilTextExists(".newsfeed .newsfeed-title", "QPanel", 10000); - const events = await app.client.$$(".newsfeed .newsfeed-desc"); - return expect(events.length).toBe(0); + it("should NOT show the newsfeed description", () => { + const elem = document.querySelector(".newsfeed .newsfeed-desc"); + expect(elem).toBe(null); }); }); describe("Custom configuration", function () { - beforeAll(function () { - process.env.MM_CONFIG_FILE = "tests/configs/modules/newsfeed/prohibited_words.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/newsfeed/prohibited_words.js"); + helpers.getDocument(done, 3000); }); it("should not show articles with prohibited words", function () { - return app.client.waitUntilTextExists(".newsfeed .newsfeed-title", "Problema VirtualBox", 10000); + const elem = document.querySelector(".newsfeed .newsfeed-title"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Problema VirtualBox"); }); - it("should show the newsfeed description", async () => { - await app.client.waitUntilTextExists(".newsfeed .newsfeed-title", "Problema VirtualBox", 10000); - const events = await app.client.$$(".newsfeed .newsfeed-desc"); - return expect(events.length).toBe(1); + it("should show the newsfeed description", () => { + const elem = document.querySelector(".newsfeed .newsfeed-desc"); + expect(elem).not.toBe(null); + expect(elem.textContent.length).not.toBe(0); }); }); describe("Invalid configuration", function () { - beforeAll(function () { - process.env.MM_CONFIG_FILE = "tests/configs/modules/newsfeed/incorrect_url.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/newsfeed/incorrect_url.js"); + helpers.getDocument(done, 3000); }); it("should show malformed url warning", function () { - return app.client.waitUntilTextExists(".newsfeed .small", "Error in the Newsfeed module. Malformed url.", 10000); + const elem = document.querySelector(".newsfeed .small"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Error in the Newsfeed module. Malformed url."); }); }); }); diff --git a/tests/e2e/modules_display_spec.js b/tests/e2e/modules_display_spec.js index 6132c62f..4042e810 100644 --- a/tests/e2e/modules_display_spec.js +++ b/tests/e2e/modules_display_spec.js @@ -1,38 +1,24 @@ const helpers = require("./global-setup"); describe("Display of modules", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/display.js"); + helpers.getDocument(done); + }); + afterAll(function () { + helpers.stopApplication(); }); - afterEach(function () { - return helpers.stopApplication(app); + it("should show the test header", function () { + const elem = document.querySelector("#module_0_helloworld .module-header"); + expect(elem).not.toBe(null); + // textContent gibt hier lowercase zurück, das uppercase wird durch css realisiert, was daher nicht in textContent landet + expect(elem.textContent).toBe("test_header"); }); - describe("Using helloworld", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/display.js"; - }); - - it("should show the test header", async () => { - const elem = await app.client.$("#module_0_helloworld .module-header", 10000); - return expect(await elem.getText("#module_0_helloworld .module-header")).toBe("TEST_HEADER"); - }); - - it("should show no header if no header text is specified", async () => { - const elem = await app.client.$("#module_1_helloworld .module-header", 10000); - return expect(await elem.getText("#module_1_helloworld .module-header")).toBe(""); - }); + it("should show no header if no header text is specified", function () { + const elem = document.querySelector("#module_1_helloworld .module-header"); + expect(elem).not.toBe(null); + expect(elem.textContent).toBe("undefined"); }); }); diff --git a/tests/e2e/modules_position_spec.js b/tests/e2e/modules_position_spec.js index 7ac1cadd..79b9b96f 100644 --- a/tests/e2e/modules_position_spec.js +++ b/tests/e2e/modules_position_spec.js @@ -1,38 +1,22 @@ const helpers = require("./global-setup"); describe("Position of modules", function () { - helpers.setupTimeout(this); - - let app = null; - - describe("Using helloworld", function () { - afterAll(function () { - return helpers.stopApplication(app); - }); - - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/positions.js"; - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - const positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", "bottom_bar", "fullscreen_above", "fullscreen_below"]; - - for (const position of positions) { - const className = position.replace("_", "."); - it("should show text in " + position, function () { - return app.client.$("." + className).then((result) => { - return result.getText("." + className).then((text) => { - return expect(text).toContain("Text in " + position); - }); - }); - }); - } + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/positions.js"); + helpers.getDocument(done, 1000); }); + afterAll(function () { + helpers.stopApplication(); + }); + + const positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", "bottom_bar", "fullscreen_above", "fullscreen_below"]; + + for (const position of positions) { + const className = position.replace("_", "."); + it("should show text in " + position, function () { + const elem = document.querySelector("." + className); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Text in " + position); + }); + } }); diff --git a/tests/e2e/port_config.js b/tests/e2e/port_config.js index da489414..329acab6 100644 --- a/tests/e2e/port_config.js +++ b/tests/e2e/port_config.js @@ -1,29 +1,13 @@ -const helpers = require("./global-setup"); const fetch = require("node-fetch"); +const helpers = require("./global-setup"); describe("port directive configuration", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); - }); - describe("Set port 8090", function () { beforeAll(function () { - // Set config sample for use in this test - process.env.MM_CONFIG_FILE = "tests/configs/port_8090.js"; + helpers.startApplication("tests/configs/port_8090.js"); + }); + afterAll(function () { + helpers.stopApplication(); }); it("should return 200", function (done) { @@ -36,13 +20,10 @@ describe("port directive configuration", function () { describe("Set port 8100 on environment variable MM_PORT", function () { beforeAll(function () { - process.env.MM_PORT = 8100; - // Set config sample for use in this test - process.env.MM_CONFIG_FILE = "tests/configs/port_8090.js"; + helpers.startApplication("tests/configs/port_8090.js", (process.env.MM_PORT = 8100)); }); - afterAll(function () { - delete process.env.MM_PORT; + helpers.stopApplication(); }); it("should return 200", function (done) { diff --git a/tests/e2e/vendor_spec.js b/tests/e2e/vendor_spec.js index 9fcb9aeb..f6917c0d 100644 --- a/tests/e2e/vendor_spec.js +++ b/tests/e2e/vendor_spec.js @@ -1,24 +1,12 @@ -const helpers = require("./global-setup"); const fetch = require("node-fetch"); +const helpers = require("./global-setup"); describe("Vendors", function () { - helpers.setupTimeout(this); - - let app = null; - beforeAll(function () { - process.env.MM_CONFIG_FILE = "tests/configs/env.js"; - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); + helpers.startApplication("tests/configs/default.js"); }); - afterAll(function () { - return helpers.stopApplication(app); + helpers.stopApplication(); }); describe("Get list vendors", function () { diff --git a/tests/e2e/without_modules.js b/tests/e2e/without_modules.js index 0214aed7..8aeeee28 100644 --- a/tests/e2e/without_modules.js +++ b/tests/e2e/without_modules.js @@ -1,36 +1,23 @@ const helpers = require("./global-setup"); describe("Check configuration without modules", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); + beforeAll(function (done) { + helpers.startApplication("tests/configs/without_modules.js"); + helpers.getDocument(done, 1000); + }); + afterAll(function () { + helpers.stopApplication(); }); - afterEach(function () { - return helpers.stopApplication(app); + it("Show the message MagicMirror title", function () { + const elem = document.querySelector("#module_1_helloworld .module-content"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Magic Mirror2"); }); - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/without_modules.js"; - }); - - it("Show the message MagicMirror title", async function () { - const elem = await app.client.$("#module_1_helloworld .module-content"); - return expect(await elem.getText("#module_1_helloworld .module-content")).toBe("Magic Mirror2"); - }); - - it("Show the text Michael's website", async function () { - const elem = await app.client.$("#module_5_helloworld .module-content"); - return expect(await elem.getText("#module_5_helloworld .module-content")).toBe("www.michaelteeuw.nl"); + it("Show the text Michael's website", function () { + const elem = document.querySelector("#module_5_helloworld .module-content"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("www.michaelteeuw.nl"); }); }); diff --git a/tests/e2e/dev_console.js b/tests/electron/dev_console.js similarity index 100% rename from tests/e2e/dev_console.js rename to tests/electron/dev_console.js diff --git a/tests/electron/env_spec.js b/tests/electron/env_spec.js new file mode 100644 index 00000000..46efc719 --- /dev/null +++ b/tests/electron/env_spec.js @@ -0,0 +1,40 @@ +const helpers = require("./global-setup"); + +describe("Electron app environment", function () { + helpers.setupTimeout(this); + + let app = null; + + beforeAll(function () { + // Set config sample for use in test + process.env.MM_CONFIG_FILE = "tests/configs/env.js"; + }); + + beforeEach(function () { + return helpers + .startApplication({ + args: ["js/electron.js"] + }) + .then(function (startedApp) { + app = startedApp; + }); + }); + + afterEach(function () { + return helpers.stopApplication(app); + }); + + it("should open a browserwindow", async function () { + await app.client.waitUntilWindowLoaded(); + app.browserWindow.focus(); + expect(await app.client.getWindowCount()).toBe(1); + expect(await app.browserWindow.isMinimized()).toBe(false); + expect(await app.browserWindow.isDevToolsOpened()).toBe(false); + expect(await app.browserWindow.isVisible()).toBe(true); + expect(await app.browserWindow.isFocused()).toBe(true); + const bounds = await app.browserWindow.getBounds(); + expect(bounds.width).toBeGreaterThan(0); + expect(bounds.height).toBeGreaterThan(0); + expect(await app.browserWindow.getTitle()).toBe("MagicMirror²"); + }); +}); diff --git a/tests/electron/global-setup.js b/tests/electron/global-setup.js new file mode 100644 index 00000000..a1e0685b --- /dev/null +++ b/tests/electron/global-setup.js @@ -0,0 +1,53 @@ +/* + * Magic Mirror Global Setup Test Suite + * + * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com + * MIT Licensed. + */ +const Application = require("spectron").Application; +const assert = require("assert"); +const path = require("path"); +const EventEmitter = require("events"); + +exports.getElectronPath = function () { + let electronPath = path.join(__dirname, "..", "..", "node_modules", ".bin", "electron"); + if (process.platform === "win32") { + electronPath += ".cmd"; + } + return electronPath; +}; + +// Set timeout - if this is run as CI Job, increase timeout +exports.setupTimeout = function (test) { + if (process.env.CI) { + jest.setTimeout(30000); + } else { + jest.setTimeout(10000); + } +}; + +exports.startApplication = function (options) { + const emitter = new EventEmitter(); + emitter.setMaxListeners(100); + + options.path = exports.getElectronPath(); + if (process.env.CI) { + options.startTimeout = 30000; + } + + const app = new Application(options); + return app.start().then(function () { + assert.strictEqual(app.isRunning(), true); + return app; + }); +}; + +exports.stopApplication = function (app) { + if (!app || !app.isRunning()) { + return; + } + + return app.stop().then(function () { + assert.strictEqual(app.isRunning(), false); + }); +}; diff --git a/tests/servers/basic-auth.js b/tests/electron/modules/basic-auth.js similarity index 91% rename from tests/servers/basic-auth.js rename to tests/electron/modules/basic-auth.js index a8b5b6d6..fc08ae40 100644 --- a/tests/servers/basic-auth.js +++ b/tests/electron/modules/basic-auth.js @@ -12,7 +12,7 @@ app.use(basicAuth); // Set available directories const directories = ["/tests/configs"]; -const rootPath = path.resolve(__dirname + "/../../"); +const rootPath = path.resolve(__dirname + "/../../../"); for (let directory of directories) { app.use(directory, express.static(path.resolve(rootPath + directory))); diff --git a/tests/e2e/modules/calendar_spec.js b/tests/electron/modules/calendar_spec.js similarity index 98% rename from tests/e2e/modules/calendar_spec.js rename to tests/electron/modules/calendar_spec.js index 980eca58..b6420e83 100644 --- a/tests/e2e/modules/calendar_spec.js +++ b/tests/electron/modules/calendar_spec.js @@ -1,5 +1,5 @@ const helpers = require("../global-setup"); -const serverBasicAuth = require("../../servers/basic-auth.js"); +const serverBasicAuth = require("./basic-auth.js"); describe("Calendar module", function () { helpers.setupTimeout(this); diff --git a/tests/e2e/modules/mocks/index.js b/tests/electron/modules/mocks/index.js similarity index 100% rename from tests/e2e/modules/mocks/index.js rename to tests/electron/modules/mocks/index.js diff --git a/tests/e2e/modules/mocks/weather_current.js b/tests/electron/modules/mocks/weather_current.js similarity index 100% rename from tests/e2e/modules/mocks/weather_current.js rename to tests/electron/modules/mocks/weather_current.js diff --git a/tests/e2e/modules/mocks/weather_forecast.js b/tests/electron/modules/mocks/weather_forecast.js similarity index 100% rename from tests/e2e/modules/mocks/weather_forecast.js rename to tests/electron/modules/mocks/weather_forecast.js diff --git a/tests/e2e/modules/weather_spec.js b/tests/electron/modules/weather_spec.js similarity index 100% rename from tests/e2e/modules/weather_spec.js rename to tests/electron/modules/weather_spec.js diff --git a/vendor/package-lock.json b/vendor/package-lock.json index 7aaf2391..8654c60b 100644 --- a/vendor/package-lock.json +++ b/vendor/package-lock.json @@ -1,154 +1,154 @@ { - "name": "magicmirror-vendors", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "magicmirror-vendors", - "license": "MIT", - "dependencies": { - "@fortawesome/fontawesome-free": "^5.15.4", - "moment": "^2.29.1", - "moment-timezone": "^0.5.33", - "nunjucks": "^3.2.3", - "suncalc": "^1.8.0", - "weathericons": "^2.1.0" - } - }, - "node_modules/@fortawesome/fontawesome-free": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz", - "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==", - "hasInstallScript": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/a-sync-waterfall": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", - "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, - "node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", - "engines": { - "node": "*" - } - }, - "node_modules/moment-timezone": { - "version": "0.5.33", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz", - "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==", - "dependencies": { - "moment": ">= 2.9.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/nunjucks": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz", - "integrity": "sha512-psb6xjLj47+fE76JdZwskvwG4MYsQKXUtMsPh6U0YMvmyjRtKRFcxnlXGWglNybtNTNVmGdp94K62/+NjF5FDQ==", - "dependencies": { - "a-sync-waterfall": "^1.0.0", - "asap": "^2.0.3", - "commander": "^5.1.0" - }, - "bin": { - "nunjucks-precompile": "bin/precompile" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "chokidar": "^3.3.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/suncalc": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.8.0.tgz", - "integrity": "sha1-HZiYEJVjB4dQ9JlKlZ5lTYdqy/U=" - }, - "node_modules/weathericons": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/weathericons/-/weathericons-2.1.0.tgz", - "integrity": "sha1-dFOho14gAkXjiftQd9Un7/MLc7Q=" - } - }, - "dependencies": { - "@fortawesome/fontawesome-free": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz", - "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==" - }, - "a-sync-waterfall": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", - "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, - "commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" - }, - "moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" - }, - "moment-timezone": { - "version": "0.5.33", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz", - "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==", - "requires": { - "moment": ">= 2.9.0" - } - }, - "nunjucks": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz", - "integrity": "sha512-psb6xjLj47+fE76JdZwskvwG4MYsQKXUtMsPh6U0YMvmyjRtKRFcxnlXGWglNybtNTNVmGdp94K62/+NjF5FDQ==", - "requires": { - "a-sync-waterfall": "^1.0.0", - "asap": "^2.0.3", - "commander": "^5.1.0" - } - }, - "suncalc": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.8.0.tgz", - "integrity": "sha1-HZiYEJVjB4dQ9JlKlZ5lTYdqy/U=" - }, - "weathericons": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/weathericons/-/weathericons-2.1.0.tgz", - "integrity": "sha1-dFOho14gAkXjiftQd9Un7/MLc7Q=" - } - } + "name": "magicmirror-vendors", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "magicmirror-vendors", + "license": "MIT", + "dependencies": { + "@fortawesome/fontawesome-free": "^5.15.4", + "moment": "^2.29.1", + "moment-timezone": "^0.5.33", + "nunjucks": "^3.2.3", + "suncalc": "^1.8.0", + "weathericons": "^2.1.0" + } + }, + "node_modules/@fortawesome/fontawesome-free": { + "version": "5.15.4", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz", + "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.33", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz", + "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==", + "dependencies": { + "moment": ">= 2.9.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nunjucks": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz", + "integrity": "sha512-psb6xjLj47+fE76JdZwskvwG4MYsQKXUtMsPh6U0YMvmyjRtKRFcxnlXGWglNybtNTNVmGdp94K62/+NjF5FDQ==", + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "chokidar": "^3.3.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/suncalc": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.8.0.tgz", + "integrity": "sha1-HZiYEJVjB4dQ9JlKlZ5lTYdqy/U=" + }, + "node_modules/weathericons": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/weathericons/-/weathericons-2.1.0.tgz", + "integrity": "sha1-dFOho14gAkXjiftQd9Un7/MLc7Q=" + } + }, + "dependencies": { + "@fortawesome/fontawesome-free": { + "version": "5.15.4", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz", + "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==" + }, + "a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" + }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, + "moment-timezone": { + "version": "0.5.33", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz", + "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==", + "requires": { + "moment": ">= 2.9.0" + } + }, + "nunjucks": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz", + "integrity": "sha512-psb6xjLj47+fE76JdZwskvwG4MYsQKXUtMsPh6U0YMvmyjRtKRFcxnlXGWglNybtNTNVmGdp94K62/+NjF5FDQ==", + "requires": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + } + }, + "suncalc": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.8.0.tgz", + "integrity": "sha1-HZiYEJVjB4dQ9JlKlZ5lTYdqy/U=" + }, + "weathericons": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/weathericons/-/weathericons-2.1.0.tgz", + "integrity": "sha1-dFOho14gAkXjiftQd9Un7/MLc7Q=" + } + } }