diff --git a/package-lock.json b/package-lock.json index 3fbef591d..6c43720be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,8 +12,8 @@ "@azure/arm-cosmosdb": "9.1.0", "@azure/cosmos": "4.0.1-beta.2", "@azure/cosmos-language-service": "0.0.5", - "@azure/identity": "1.2.1", - "@azure/ms-rest-nodeauth": "3.0.7", + "@azure/identity": "1.5.2", + "@azure/ms-rest-nodeauth": "3.1.1", "@azure/msal-browser": "2.14.2", "@babel/plugin-proposal-class-properties": "7.12.1", "@babel/plugin-proposal-decorators": "7.12.12", @@ -52,6 +52,7 @@ "@types/mkdirp": "1.0.1", "@types/node-fetch": "2.5.7", "@uiw/react-split": "5.9.3", + "@xmldom/xmldom": "0.7.13", "applicationinsights": "1.8.0", "bootstrap": "3.4.1", "canvas": "file:./canvas", @@ -75,12 +76,14 @@ "i18next-browser-languagedetector": "6.0.1", "i18next-http-backend": "1.0.23", "iframe-resizer-react": "1.1.0", + "immer": "9.0.6", "immutable": "4.0.0-rc.12", "is-ci": "2.0.0", "jquery": "3.7.1", "jquery-typeahead": "2.11.1", "jquery-ui-dist": "1.13.2", "knockout": "3.5.1", + "loader-utils": "2.0.3", "mkdirp": "1.0.4", "monaco-editor": "0.44.0", "ms": "2.1.3", @@ -105,10 +108,12 @@ "reflect-metadata": "0.1.13", "rx-jupyter": "5.5.12", "sanitize-html": "2.3.3", + "shell-quote": "1.7.3", "styled-components": "5.0.1", "swr": "0.4.0", "terser-webpack-plugin": "5.3.9", - "underscore": "1.9.1", + "tinykeys": "2.1.0", + "underscore": "1.12.1", "utility-types": "3.10.0", "zustand": "3.5.0" }, @@ -178,13 +183,13 @@ "less-vars-loader": "1.1.0", "mini-css-extract-plugin": "2.1.0", "monaco-editor-webpack-plugin": "7.1.0", - "node-fetch": "2.6.1", + "node-fetch": "2.6.7", "playwright": "1.13.0", "prettier": "3.0.3", "process": "0.11.10", "querystring-es3": "0.2.1", "raw-loader": "0.5.1", - "react-dev-utils": "11.0.4", + "react-dev-utils": "12.0.1", "rimraf": "3.0.0", "sinon": "3.2.1", "style-loader": "0.23.0", @@ -251,14 +256,6 @@ "tslib": "^1.10.0" } }, - "node_modules/@azure/core-asynciterator-polyfill": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.2.tgz", - "integrity": "sha512-3rkP4LnnlWawl0LZptJOdXNrT/fHp2eQMadoasa6afspXdpGrtPZuAQc2PD0cpgyuoXtUWyC3tv7xfntjGS5Dw==", - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@azure/core-auth": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.5.0.tgz", @@ -277,66 +274,35 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, - "node_modules/@azure/core-http": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-1.2.6.tgz", - "integrity": "sha512-odtH7UMKtekc5YQ86xg9GlVHNXR6pq2JgJ5FBo7/jbOjNGdBqcrIVrZx2bevXVJz/uUTSx6vUf62gzTXTfqYSQ==", + "node_modules/@azure/core-client": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.9.2.tgz", + "integrity": "sha512-kRdry/rav3fUKHl/aDLd/pDLcB+4pOFwPPTVEExuMyaI5r+JBbMWqRbCY1pn5BniDaU3lRxO9eaQ1AmSMehl/w==", "dependencies": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-asynciterator-polyfill": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-tracing": "1.0.0-preview.11", + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-rest-pipeline": "^1.9.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.6.1", "@azure/logger": "^1.0.0", - "@types/node-fetch": "^2.5.0", - "@types/tunnel": "^0.0.1", - "form-data": "^3.0.0", - "node-fetch": "^2.6.0", - "process": "^0.11.10", - "tough-cookie": "^4.0.0", - "tslib": "^2.2.0", - "tunnel": "^0.0.6", - "uuid": "^8.3.0", - "xml2js": "^0.4.19" + "tslib": "^2.6.2" }, "engines": { - "node": ">=8.0.0" + "node": ">=18.0.0" } }, - "node_modules/@azure/core-http/node_modules/@azure/core-tracing": { - "version": "1.0.0-preview.11", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.11.tgz", - "integrity": "sha512-frF0pJc9HTmKncVokhBxCqipjbql02DThQ1ZJ9wLi7SDMLdPAFyDI5xZNzX5guLz+/DtPkY+SGK2li9FIXqshQ==", + "node_modules/@azure/core-client/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", "dependencies": { - "@opencensus/web-types": "0.0.7", - "@opentelemetry/api": "1.0.0-rc.0", - "tslib": "^2.0.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=8.0.0" + "node": ">=18.0.0" } }, - "node_modules/@azure/core-http/node_modules/@opentelemetry/api": { - "version": "1.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.0-rc.0.tgz", - "integrity": "sha512-iXKByCMfrlO5S6Oh97BuM56tM2cIBB0XsL/vWF/AtJrJEKx4MC/Xdu0xDsGXMGcNWpqF7ujMsjjnp0+UHBwnDQ==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@azure/core-http/node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@azure/core-http/node_modules/tslib": { + "node_modules/@azure/core-client/node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" @@ -457,42 +423,44 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/@azure/identity": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-1.2.1.tgz", - "integrity": "sha512-vCzV4Xg5hWJ2e4Et0waOmIEgYHsqtGF06kklnqblZg0hKDLKxTAX5FzKYuDMk1CctY2UdEmWFcA2li2uOXOLXQ==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-1.5.2.tgz", + "integrity": "sha512-vqyeRbd2i0h9F4mqW5JbkP1xfabqKQ21l/81osKhpOQ2LtwaJW6nw4+0PsVYnxcbPHFCIZt6EWAk74a3OGYZJA==", "dependencies": { - "@azure/core-http": "^1.2.0", - "@azure/core-tracing": "1.0.0-preview.9", + "@azure/core-auth": "^1.3.0", + "@azure/core-client": "^1.0.0", + "@azure/core-rest-pipeline": "^1.1.0", + "@azure/core-tracing": "1.0.0-preview.12", "@azure/logger": "^1.0.0", - "@azure/msal-node": "1.0.0-beta.1", - "@opentelemetry/api": "^0.10.2", + "@azure/msal-node": "1.0.0-beta.6", + "@types/stoppable": "^1.1.0", "axios": "^0.21.1", "events": "^3.0.0", "jws": "^4.0.0", "msal": "^1.0.2", "open": "^7.0.0", "qs": "^6.7.0", + "stoppable": "^1.1.0", "tslib": "^2.0.0", "uuid": "^8.3.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=12.0.0" }, "optionalDependencies": { - "keytar": "^5.4.0" + "keytar": "^7.3.0" } }, "node_modules/@azure/identity/node_modules/@azure/core-tracing": { - "version": "1.0.0-preview.9", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.9.tgz", - "integrity": "sha512-zczolCLJ5QG42AEPQ+Qg9SRYNUyB+yZ5dzof4YEc+dyWczO9G2sBqbAjLB7IqrsdHN2apkiB2oXeDKCsq48jug==", + "version": "1.0.0-preview.12", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.12.tgz", + "integrity": "sha512-nvo2Wc4EKZGN6eFu9n3U7OXmASmL8VxoPIH7xaD6OlQqi44bouF0YIi9ID5rEsKLiAU59IYx6M297nqWVMWPDg==", "dependencies": { - "@opencensus/web-types": "0.0.7", - "@opentelemetry/api": "^0.10.2", - "tslib": "^2.0.0" + "@opentelemetry/api": "^1.0.0", + "tslib": "^2.2.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=12.0.0" } }, "node_modules/@azure/identity/node_modules/tslib": { @@ -599,13 +567,13 @@ } }, "node_modules/@azure/ms-rest-nodeauth": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@azure/ms-rest-nodeauth/-/ms-rest-nodeauth-3.0.7.tgz", - "integrity": "sha512-7Q1MyMB+eqUQy8JO+virSIzAjqR2UbKXE/YQZe+53gC8yakm8WOQ5OzGfPP+eyHqeRs6bQESyw2IC5feLWlT2A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@azure/ms-rest-nodeauth/-/ms-rest-nodeauth-3.1.1.tgz", + "integrity": "sha512-UA/8dgLy3+ZiwJjAZHxL4MUB14fFQPkaAOZ94jsTW/Z6WmoOeny2+cLk0+dyIX/iH6qSrEWKwbStEeB970B9pA==", "dependencies": { "@azure/ms-rest-azure-env": "^2.0.0", "@azure/ms-rest-js": "^2.0.4", - "adal-node": "^0.1.28" + "adal-node": "^0.2.2" } }, "node_modules/@azure/msal-browser": { @@ -632,61 +600,17 @@ } }, "node_modules/@azure/msal-node": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.0.0-beta.1.tgz", - "integrity": "sha512-dO/bgVScpl5loZfsfhHXmFLTNoDxGvUiZIsJCe1+HpHyFWXwGsBZ71P5ixbxRhhf/bPpZS3X+/rm1Fq2uUucJw==", + "version": "1.0.0-beta.6", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.0.0-beta.6.tgz", + "integrity": "sha512-ZQI11Uz1j0HJohb9JZLRD8z0moVcPks1AFW4Q/Gcl67+QvH4aKEJti7fjCcipEEZYb/qzLSO8U6IZgPYytsiJQ==", "deprecated": "A newer major version of this library is available. Please upgrade to the latest available version.", "dependencies": { - "@azure/msal-common": "^1.7.2", - "axios": "^0.19.2", + "@azure/msal-common": "^4.0.0", + "axios": "^0.21.1", "jsonwebtoken": "^8.5.1", "uuid": "^8.3.0" } }, - "node_modules/@azure/msal-node/node_modules/@azure/msal-common": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-1.7.2.tgz", - "integrity": "sha512-3/voCdFKONENX+5tMrNOBSrVJb6NbE7YB8vc4FZ/4ZbjpK7GVtq9Bu1MW+HZhrmsUzSF/joHx0ZIJDYIequ/jg==", - "dependencies": { - "debug": "^4.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@azure/msal-node/node_modules/axios": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", - "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", - "deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410", - "dependencies": { - "follow-redirects": "1.5.10" - } - }, - "node_modules/@azure/msal-node/node_modules/follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "dependencies": { - "debug": "=3.1.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@azure/msal-node/node_modules/follow-redirects/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/@azure/msal-node/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, "node_modules/@babel/code-frame": { "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", @@ -7069,17 +6993,6 @@ "node": ">=10" } }, - "node_modules/@mapbox/node-pre-gyp/node_modules/detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@mapbox/node-pre-gyp/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -10182,29 +10095,10 @@ "@octokit/openapi-types": "^19.0.2" } }, - "node_modules/@opencensus/web-types": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@opencensus/web-types/-/web-types-0.0.7.tgz", - "integrity": "sha512-xB+w7ZDAu3YBzqH44rCmG9/RlrOmFuDPt/bpf17eJr8eZSrLt7nc7LnWdxM9Mmoj/YKMHpxRg28txu3TcpiL+g==", - "engines": { - "node": ">=6.0" - } - }, "node_modules/@opentelemetry/api": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-0.10.2.tgz", - "integrity": "sha512-GtpMGd6vkzDMYcpu2t9LlhEgMy/SzBwRnz48EejlRArYqZzqSzAsKmegUK7zHgl+EOIaK9mKHhnRaQu3qw20cA==", - "dependencies": { - "@opentelemetry/context-base": "^0.10.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@opentelemetry/context-base": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/context-base/-/context-base-0.10.2.tgz", - "integrity": "sha512-hZNKjKOYsckoOEgBziGMnBcX0M7EtstnCmwz5jZUOUYwlZ+/xxX6z3jPu1XVO2Jivk0eLfuP9GP+vFD49CMetw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", "engines": { "node": ">=8.0.0" } @@ -12837,6 +12731,12 @@ "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "devOptional": true }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true + }, "node_modules/@types/post-robot": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/@types/post-robot/-/post-robot-10.0.1.tgz", @@ -13625,6 +13525,14 @@ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "devOptional": true }, + "node_modules/@types/stoppable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/stoppable/-/stoppable-1.1.3.tgz", + "integrity": "sha512-7wGKIBJGE4ZxFjk9NkjAxZMLlIXroETqP1FJCdoSvKmEznwmBxQFmTB1dsCkAvVcNemuSZM5qkkd9HE/NL2JTw==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/styled-components": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.1.tgz", @@ -13651,14 +13559,6 @@ "@types/jest": "*" } }, - "node_modules/@types/tunnel": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.1.tgz", - "integrity": "sha512-AOqu6bQu5MSWwYvehMXLukFHnupHrpZ8nvgae5Ggie9UwzDR1CCwoXgSSWNZJuyOlCdfdsWMA5F2LlmvyoTv8A==", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/underscore": { "version": "1.7.36", "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.7.36.tgz", @@ -14207,6 +14107,14 @@ } } }, + "node_modules/@xmldom/xmldom": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz", + "integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -14324,29 +14232,39 @@ } }, "node_modules/adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha512-98nQ5MQSyJR0ZY/R0Mue/cv4OkebRyKz4hS40GdkZU42Bq49ldHeup7UeAo/0vROMB57CX2et6IF0U/Pe1rY3A==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.2.4.tgz", + "integrity": "sha512-zIcvbwQFKMUtKxxj8YMHeTT1o/TPXfVNsTXVgXD8sxwV6h4AFQgK77dRciGhuEF9/Sdm3UQPJVPc/6XxrccSeA==", "deprecated": "This package is no longer supported. Please migrate to @azure/msal-node.", "dependencies": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", + "@xmldom/xmldom": "^0.8.3", + "async": "^2.6.3", + "axios": "^0.21.1", "date-utils": "*", "jws": "3.x.x", - "request": ">= 2.52.0", "underscore": ">= 1.3.1", "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", "xpath.js": "~1.1.0" }, "engines": { "node": ">= 0.6.15" } }, - "node_modules/adal-node/node_modules/@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" + "node_modules/adal-node/node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/adal-node/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dependencies": { + "lodash": "^4.17.14" + } }, "node_modules/adal-node/node_modules/jwa": { "version": "1.4.1", @@ -14662,7 +14580,9 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "optional": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/archy": { "version": "1.0.0", @@ -14670,16 +14590,6 @@ "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", "dev": true }, - "node_modules/are-we-there-yet": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", - "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", - "optional": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -14963,7 +14873,9 @@ "node_modules/async": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "dev": true, + "peer": true }, "node_modules/async-hook-jl": { "version": "1.7.6", @@ -15107,6 +15019,32 @@ "webpack": ">=2" } }, + "node_modules/babel-loader/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/babel-loader/node_modules/loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/babel-loader/node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -16442,7 +16380,9 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "dev": true, "optional": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -16719,7 +16659,9 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "optional": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/content-disposition": { "version": "0.5.4", @@ -16993,7 +16935,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "devOptional": true + "dev": true }, "node_modules/cosmiconfig": { "version": "5.2.1", @@ -17834,7 +17776,9 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dev": true, "optional": true, + "peer": true, "dependencies": { "mimic-response": "^2.0.0" }, @@ -18123,7 +18067,9 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "optional": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/denodeify": { "version": "1.2.1", @@ -18177,15 +18123,12 @@ } }, "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", "optional": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, "engines": { - "node": ">=0.10" + "node": ">=8" } }, "node_modules/detect-newline": { @@ -20298,9 +20241,9 @@ "optional": true }, "node_modules/filesize": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz", - "integrity": "sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg==", + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", "dev": true, "engines": { "node": ">= 0.4.0" @@ -20698,22 +20641,200 @@ } }, "node_modules/fork-ts-checker-webpack-plugin": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz", - "integrity": "sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.5.5", - "chalk": "^2.4.1", - "micromatch": "^3.1.10", + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", "minimatch": "^3.0.4", - "semver": "^5.6.0", - "tapable": "^1.0.0", - "worker-rpc": "^0.1.0" + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" }, "engines": { - "node": ">=6.11.5", + "node": ">=10", "yarn": ">=1.0.0" + }, + "peerDependencies": { + "eslint": ">= 6", + "typescript": ">= 2.7", + "vue-template-compiler": "*", + "webpack": ">= 4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { @@ -20725,6 +20846,30 @@ "node": ">=6" } }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -20960,43 +21105,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", - "optional": true, - "dependencies": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "node_modules/gauge/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "optional": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -21348,16 +21456,18 @@ "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" }, "node_modules/gzip-size": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", - "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", "dev": true, "dependencies": { - "duplexer": "^0.1.1", - "pify": "^4.0.1" + "duplexer": "^0.1.2" }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/handle-thing": { @@ -21493,7 +21603,9 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "optional": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/has-value": { "version": "1.0.0", @@ -21782,6 +21894,32 @@ "html-loader": "^0.5.1" } }, + "node_modules/html-loader/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/html-loader/node_modules/loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/html-minifier": { "version": "3.5.21", "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", @@ -22261,6 +22399,14 @@ "node-fetch": "2.6.1" } }, + "node_modules/i18next-http-backend/node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "engines": { + "node": "4.x || >=6.0.0" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -22356,10 +22502,9 @@ } }, "node_modules/immer": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz", - "integrity": "sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA==", - "dev": true, + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.6.tgz", + "integrity": "sha512-G95ivKpy+EvVAnAab4fVa4YGYn24J1SpEktnJX7JJ45Bd7xqME/SCplFzYFmTbrkwZbQ4xJK1xMTUYBkN6pWsQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/immer" @@ -22811,7 +22956,9 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, "optional": true, + "peer": true, "dependencies": { "number-is-nan": "^1.0.0" }, @@ -28943,22 +29090,16 @@ "integrity": "sha512-yQa1dz+FilQ+w3JM6GH2V/wnFeQhfbkK9stvs3UiraW3GOEO7zrOBBh0ZuHsrzeN1xx6v7P5EpA2JtOUUnfN/w==" }, "node_modules/keytar": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/keytar/-/keytar-5.6.0.tgz", - "integrity": "sha512-ueulhshHSGoryfRXaIvTj0BV1yB0KddBGhGoqCxSN9LR1Ks1GKuuCdVhF+2/YOs5fMl6MlTI9On1a4DHDXoTow==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", + "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", "hasInstallScript": true, "optional": true, "dependencies": { - "nan": "2.14.1", - "prebuild-install": "5.3.3" + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1" } }, - "node_modules/keytar/node_modules/nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "optional": true - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -29232,29 +29373,16 @@ } }, "node_modules/loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", - "dev": true, + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.3.tgz", + "integrity": "sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", - "json5": "^1.0.1" + "json5": "^2.1.2" }, "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/loader-utils/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" + "node": ">=8.9.0" } }, "node_modules/locate-path": { @@ -31350,12 +31478,6 @@ "node": ">=12" } }, - "node_modules/microevent.ts": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz", - "integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==", - "dev": true - }, "node_modules/micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -31431,7 +31553,9 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "dev": true, "optional": true, + "peer": true, "engines": { "node": ">=8" }, @@ -31846,19 +31970,61 @@ } }, "node_modules/node-abi": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", - "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", + "version": "3.60.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.60.0.tgz", + "integrity": "sha512-zcGgwoXbzw9NczqbGzAWL/ToDYAxv1V8gL1D67ClbdkIfeeDBbY0GelZtC25ayLvVjr2q2cloHeQV1R0QAWqRQ==", "optional": true, "dependencies": { - "semver": "^5.4.1" + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" } }, + "node_modules/node-abi/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "optional": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + }, "node_modules/node-abort-controller": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" }, + "node_modules/node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", + "optional": true + }, "node_modules/node-dir": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", @@ -31873,11 +32039,22 @@ } }, "node_modules/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, "engines": { "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } } }, "node_modules/node-forge": { @@ -31976,12 +32153,6 @@ "url": "https://github.com/sponsors/antelle" } }, - "node_modules/noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha512-6kM8CLXvuW5crTxsAtva2YLrRrDaiTIkIePWs9moLHqbFWT94WpNFjwS/5dfLfECg5i/lkmw3aoqVidxt23TEQ==", - "optional": true - }, "node_modules/nopt": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", @@ -32035,18 +32206,6 @@ "node": ">=8" } }, - "node_modules/npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "optional": true, - "dependencies": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -32069,7 +32228,9 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "dev": true, "optional": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -33543,44 +33704,81 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/prebuild-install": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.3.tgz", - "integrity": "sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", "optional": true, "dependencies": { - "detect-libc": "^1.0.3", + "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", - "node-abi": "^2.7.0", - "noop-logger": "^0.1.1", - "npmlog": "^4.0.1", + "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", - "simple-get": "^3.0.3", + "simple-get": "^4.0.0", "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0", - "which-pm-runs": "^1.0.0" + "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/prebuild-install/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "node_modules/prebuild-install/node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "optional": true, "dependencies": { - "minimist": "^1.2.6" + "mimic-response": "^3.1.0" }, - "bin": { - "mkdirp": "bin/cmd.js" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prebuild-install/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prebuild-install/node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true, + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" } }, "node_modules/prelude-ls": { @@ -33764,7 +33962,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "devOptional": true + "dev": true }, "node_modules/process-on-spawn": { "version": "1.0.0", @@ -34171,106 +34369,110 @@ } }, "node_modules/react-dev-utils": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz", - "integrity": "sha512-dx0LvIGHcOPtKbeiSUM4jqpBl3TcY7CDjZdfOIcKeznE7BWr9dg0iPG90G5yfVQ+p/rGNMXdbfStvzQZEVEi4A==", + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", "dev": true, "dependencies": { - "@babel/code-frame": "7.10.4", - "address": "1.1.2", - "browserslist": "4.14.2", - "chalk": "2.4.2", - "cross-spawn": "7.0.3", - "detect-port-alt": "1.1.6", - "escape-string-regexp": "2.0.0", - "filesize": "6.1.0", - "find-up": "4.1.0", - "fork-ts-checker-webpack-plugin": "4.1.6", - "global-modules": "2.0.0", - "globby": "11.0.1", - "gzip-size": "5.1.1", - "immer": "8.0.1", - "is-root": "2.1.0", - "loader-utils": "2.0.0", - "open": "^7.0.2", - "pkg-up": "3.1.0", - "prompts": "2.4.0", - "react-error-overlay": "^6.0.9", - "recursive-readdir": "2.2.2", - "shell-quote": "1.7.2", - "strip-ansi": "6.0.0", - "text-table": "0.2.0" + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-dev-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/react-dev-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { "node": ">=10" - } - }, - "node_modules/react-dev-utils/node_modules/@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/react-dev-utils/node_modules/browserslist": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.2.tgz", - "integrity": "sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw==", - "dev": true, - "dependencies": { - "caniuse-lite": "^1.0.30001125", - "electron-to-chromium": "^1.3.564", - "escalade": "^3.0.2", - "node-releases": "^1.1.61" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" }, "funding": { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/react-dev-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/react-dev-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/react-dev-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/react-dev-utils/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", + "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dev-utils/node_modules/globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, "engines": { "node": ">=10" }, @@ -34278,48 +34480,94 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "node_modules/react-dev-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, "engines": { - "node": ">=8.9.0" + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/react-dev-utils/node_modules/loader-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "dev": true, + "engines": { + "node": ">= 12.13.0" } }, "node_modules/react-dev-utils/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { - "p-locate": "^4.1.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/react-dev-utils/node_modules/node-releases": { - "version": "1.1.77", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.77.tgz", - "integrity": "sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==", - "dev": true - }, - "node_modules/react-dev-utils/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/react-dev-utils/node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, "dependencies": { - "p-limit": "^2.2.0" + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/react-dev-utils/node_modules/path-exists": { @@ -34331,35 +34579,13 @@ "node": ">=8" } }, - "node_modules/react-dev-utils/node_modules/prompts": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", - "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", + "node_modules/react-dev-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/react-dev-utils/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dev-utils/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" + "has-flag": "^4.0.0" }, "engines": { "node": ">=8" @@ -34917,7 +35143,7 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "devOptional": true, + "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -34932,7 +35158,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "devOptional": true + "dev": true }, "node_modules/readdirp": { "version": "3.6.0", @@ -36449,10 +36675,9 @@ } }, "node_modules/shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", + "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==" }, "node_modules/shellwords": { "version": "0.1.1", @@ -36522,7 +36747,9 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "dev": true, "optional": true, + "peer": true, "dependencies": { "decompress-response": "^4.2.0", "once": "^1.3.1", @@ -37091,6 +37318,15 @@ "node": ">=0.10.0" } }, + "node_modules/stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "engines": { + "node": ">=4", + "npm": ">=6" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -37123,7 +37359,9 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, "optional": true, + "peer": true, "dependencies": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -37137,7 +37375,9 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, "optional": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -37146,7 +37386,9 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, "optional": true, + "peer": true, "dependencies": { "ansi-regex": "^2.0.0" }, @@ -37294,6 +37536,32 @@ "node": ">= 0.12.0" } }, + "node_modules/style-loader/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/style-loader/node_modules/loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/style-loader/node_modules/schema-utils": { "version": "0.4.7", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", @@ -37826,6 +38094,11 @@ "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" }, + "node_modules/tinykeys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tinykeys/-/tinykeys-2.1.0.tgz", + "integrity": "sha512-/MESnqBD1xItZJn5oGQ4OsNORQgJfPP96XSGoyu4eLpwpL0ifO0SYR5OD76u0YMhMXsqkb0UqvI9+yXTh4xv8Q==" + }, "node_modules/tinyqueue": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-1.2.3.tgz", @@ -37925,6 +38198,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "devOptional": true, "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -37939,6 +38213,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "devOptional": true, "engines": { "node": ">= 4.0.0" } @@ -38477,9 +38752,9 @@ } }, "node_modules/underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" }, "node_modules/unherit": { "version": "1.1.3", @@ -39304,21 +39579,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/webpack-bundle-analyzer/node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "dev": true, - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/webpack-cli": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", @@ -39824,15 +40084,6 @@ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" }, - "node_modules/which-pm-runs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", - "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", - "optional": true, - "engines": { - "node": ">=4" - } - }, "node_modules/which-typed-array": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", @@ -39855,7 +40106,9 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, "optional": true, + "peer": true, "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } @@ -39994,15 +40247,6 @@ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "dev": true }, - "node_modules/worker-rpc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/worker-rpc/-/worker-rpc-0.1.1.tgz", - "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==", - "dev": true, - "dependencies": { - "microevent.ts": "~0.1.1" - } - }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -40148,26 +40392,6 @@ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" }, - "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xml2js/node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } - }, "node_modules/xmlbuilder": { "version": "8.2.2", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz", @@ -40183,14 +40407,6 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "devOptional": true }, - "node_modules/xmldom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz", - "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==", - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/xpath.js": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", @@ -40425,4 +40641,4 @@ } } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index e2ae50acd..3e8c12964 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "@azure/arm-cosmosdb": "9.1.0", "@azure/cosmos": "4.0.1-beta.2", "@azure/cosmos-language-service": "0.0.5", - "@azure/identity": "1.2.1", - "@azure/ms-rest-nodeauth": "3.0.7", + "@azure/identity": "1.5.2", + "@azure/ms-rest-nodeauth": "3.1.1", "@azure/msal-browser": "2.14.2", "@babel/plugin-proposal-class-properties": "7.12.1", "@babel/plugin-proposal-decorators": "7.12.12", @@ -47,6 +47,7 @@ "@types/mkdirp": "1.0.1", "@types/node-fetch": "2.5.7", "@uiw/react-split": "5.9.3", + "@xmldom/xmldom": "0.7.13", "applicationinsights": "1.8.0", "bootstrap": "3.4.1", "canvas": "file:./canvas", @@ -70,12 +71,14 @@ "i18next-browser-languagedetector": "6.0.1", "i18next-http-backend": "1.0.23", "iframe-resizer-react": "1.1.0", + "immer": "9.0.6", "immutable": "4.0.0-rc.12", "is-ci": "2.0.0", "jquery": "3.7.1", "jquery-typeahead": "2.11.1", "jquery-ui-dist": "1.13.2", "knockout": "3.5.1", + "loader-utils": "2.0.3", "mkdirp": "1.0.4", "monaco-editor": "0.44.0", "ms": "2.1.3", @@ -100,10 +103,12 @@ "reflect-metadata": "0.1.13", "rx-jupyter": "5.5.12", "sanitize-html": "2.3.3", + "shell-quote": "1.7.3", "styled-components": "5.0.1", "swr": "0.4.0", "terser-webpack-plugin": "5.3.9", - "underscore": "1.9.1", + "tinykeys": "2.1.0", + "underscore": "1.12.1", "utility-types": "3.10.0", "zustand": "3.5.0" }, @@ -173,13 +178,13 @@ "less-vars-loader": "1.1.0", "mini-css-extract-plugin": "2.1.0", "monaco-editor-webpack-plugin": "7.1.0", - "node-fetch": "2.6.1", + "node-fetch": "2.6.7", "playwright": "1.13.0", "prettier": "3.0.3", "process": "0.11.10", "querystring-es3": "0.2.1", "raw-loader": "0.5.1", - "react-dev-utils": "11.0.4", + "react-dev-utils": "12.0.1", "rimraf": "3.0.0", "sinon": "3.2.1", "style-loader": "0.23.0", @@ -241,4 +246,4 @@ "printWidth": 120, "endOfLine": "auto" } -} +} \ No newline at end of file diff --git a/src/Common/Constants.ts b/src/Common/Constants.ts index 1eed03a4f..69bd5ed49 100644 --- a/src/Common/Constants.ts +++ b/src/Common/Constants.ts @@ -138,7 +138,7 @@ export class PortalBackendEndpoints { } export class MongoProxyEndpoints { - public static readonly Development: string = "https://localhost:7238"; + public static readonly Local: string = "https://localhost:7238"; public static readonly Mpac: string = "https://cdb-ms-mpac-mp.cosmos.azure.com"; public static readonly Prod: string = "https://cdb-ms-prod-mp.cosmos.azure.com"; public static readonly Fairfax: string = "https://cdb-ff-prod-mp.cosmos.azure.us"; diff --git a/src/Common/MongoProxyClient.ts b/src/Common/MongoProxyClient.ts index 44400d874..907b0305e 100644 --- a/src/Common/MongoProxyClient.ts +++ b/src/Common/MongoProxyClient.ts @@ -672,6 +672,27 @@ export function getEndpoint(endpoint: string): string { return url; } +export function useMongoProxyEndpoint(api: string): boolean { + const activeMongoProxyEndpoints: string[] = [ + MongoProxyEndpoints.Local, + MongoProxyEndpoints.Mpac, + MongoProxyEndpoints.Prod, + ]; + let canAccessMongoProxy: boolean = userContext.databaseAccount.properties.publicNetworkAccess === "Enabled"; + if ( + configContext.MONGO_PROXY_ENDPOINT !== MongoProxyEndpoints.Local && + userContext.databaseAccount.properties.ipRules?.length > 0 + ) { + canAccessMongoProxy = canAccessMongoProxy && configContext.MONGO_PROXY_OUTBOUND_IPS_ALLOWLISTED; + } + + return ( + canAccessMongoProxy && + configContext.NEW_MONGO_APIS?.includes(api) && + activeMongoProxyEndpoints.includes(configContext.MONGO_PROXY_ENDPOINT) + ); +} + // TODO: This function throws most of the time except on Forbidden which is a bit strange // It causes problems for TypeScript understanding the types async function errorHandling(response: Response, action: string, params: unknown): Promise { @@ -688,24 +709,3 @@ async function errorHandling(response: Response, action: string, params: unknown export function getARMCreateCollectionEndpoint(params: DataModels.MongoParameters): string { return `subscriptions/${params.sid}/resourceGroups/${params.rg}/providers/Microsoft.DocumentDB/databaseAccounts/${userContext.databaseAccount.name}/mongodbDatabases/${params.db}/collections/${params.coll}`; } - -function useMongoProxyEndpoint(api: string): boolean { - const activeMongoProxyEndpoints: string[] = [ - MongoProxyEndpoints.Development, - MongoProxyEndpoints.Mpac, - MongoProxyEndpoints.Prod, - ]; - let canAccessMongoProxy: boolean = userContext.databaseAccount.properties.publicNetworkAccess === "Enabled"; - if ( - configContext.MONGO_PROXY_ENDPOINT !== MongoProxyEndpoints.Development && - userContext.databaseAccount.properties.ipRules?.length > 0 - ) { - canAccessMongoProxy = canAccessMongoProxy && configContext.MONGO_PROXY_OUTBOUND_IPS_ALLOWLISTED; - } - - return ( - canAccessMongoProxy && - configContext.NEW_MONGO_APIS?.includes(api) && - activeMongoProxyEndpoints.includes(configContext.MONGO_PROXY_ENDPOINT) - ); -} diff --git a/src/ConfigContext.ts b/src/ConfigContext.ts index 435166b90..061f25286 100644 --- a/src/ConfigContext.ts +++ b/src/ConfigContext.ts @@ -83,6 +83,7 @@ let configContext: Readonly = { `^https:\\/\\/.*\\.analysis-df\\.net$`, `^https:\\/\\/.*\\.analysis-df\\.windows\\.net$`, `^https:\\/\\/.*\\.azure-test\\.net$`, + `^https:\\/\\/cosmos-explorer-preview\\.azurewebsites\\.net`, ], // Webpack injects this at build time gitSha: process.env.GIT_SHA, hostedExplorerURL: "https://cosmos.azure.com/", @@ -108,6 +109,7 @@ let configContext: Readonly = { "updateDocument", "deleteDocument", "createCollectionWithProxy", + "legacyMongoShell", ], MONGO_PROXY_OUTBOUND_IPS_ALLOWLISTED: false, CASSANDRA_PROXY_ENDPOINT: CassandraProxyEndpoints.Prod, diff --git a/src/Explorer/Controls/CommandButton/CommandButtonComponent.tsx b/src/Explorer/Controls/CommandButton/CommandButtonComponent.tsx index 1e5cfc171..6337f947e 100644 --- a/src/Explorer/Controls/CommandButton/CommandButtonComponent.tsx +++ b/src/Explorer/Controls/CommandButton/CommandButtonComponent.tsx @@ -1,6 +1,7 @@ /** * React component for Command button component. */ +import { KeyboardAction } from "KeyboardShortcuts"; import * as React from "react"; import CollapseChevronDownIcon from "../../../../images/QueryBuilder/CollapseChevronDown_16x.png"; import { KeyCodes } from "../../../Common/Constants"; @@ -30,7 +31,7 @@ export interface CommandButtonComponentProps { /** * Click handler for command button click */ - onCommandClick: (e: React.SyntheticEvent) => void; + onCommandClick: (e: React.SyntheticEvent | KeyboardEvent) => void; /** * Label for the button @@ -107,10 +108,17 @@ export interface CommandButtonComponentProps { * Vertical bar to divide buttons */ isDivider?: boolean; + /** * Aria-label for the button */ ariaLabel: string; + + /** + * If specified, a keyboard action that should trigger this button's onCommandClick handler when activated. + * If not specified, the button will not be triggerable by keyboard shortcuts. + */ + keyboardAction?: KeyboardAction; } export class CommandButtonComponent extends React.Component { diff --git a/src/Explorer/Menus/CommandBar/CommandBarComponentAdapter.tsx b/src/Explorer/Menus/CommandBar/CommandBarComponentAdapter.tsx index 141bda577..9a5f222a3 100644 --- a/src/Explorer/Menus/CommandBar/CommandBarComponentAdapter.tsx +++ b/src/Explorer/Menus/CommandBar/CommandBarComponentAdapter.tsx @@ -5,6 +5,7 @@ */ import { CommandBar as FluentCommandBar, ICommandBarItemProps } from "@fluentui/react"; import { useNotebook } from "Explorer/Notebook/useNotebook"; +import { KeyboardActionGroup, useKeyboardActionGroup } from "KeyboardShortcuts"; import { userContext } from "UserContext"; import * as React from "react"; import create, { UseStore } from "zustand"; @@ -40,6 +41,7 @@ export const CommandBar: React.FC = ({ container }: Props) => { const buttons = useCommandBar((state) => state.contextButtons); const isHidden = useCommandBar((state) => state.isHidden); const backgroundColor = StyleConstants.BaseLight; + const setKeyboardHandlers = useKeyboardActionGroup(KeyboardActionGroup.COMMAND_BAR); if (userContext.apiType === "Postgres" || userContext.apiType === "VCoreMongo") { const buttons = @@ -105,6 +107,10 @@ export const CommandBar: React.FC = ({ container }: Props) => { }, }; + const allButtons = staticButtons.concat(contextButtons).concat(controlButtons); + const keyboardHandlers = CommandBarUtil.createKeyboardHandlers(allButtons); + setKeyboardHandlers(keyboardHandlers); + return (
{ const selectedCollection: ViewModels.Collection = selectedNodeState.findSelectedCollection(); selectedCollection && selectedCollection.onNewStoredProcedureClick(selectedCollection); @@ -277,6 +280,7 @@ function createNewDatabase(container: Explorer): CommandButtonComponentProps { return { iconSrc: AddDatabaseIcon, iconAlt: label, + keyboardAction: KeyboardAction.NEW_DATABASE, onCommandClick: async () => { const throughputCap = userContext.databaseAccount?.properties.capacity?.totalThroughputLimit; if (throughputCap && throughputCap !== -1) { @@ -297,6 +301,7 @@ function createNewSQLQueryButton(selectedNodeState: SelectedNodeState): CommandB id: "newQueryBtn", iconSrc: AddSqlQueryIcon, iconAlt: label, + keyboardAction: KeyboardAction.NEW_QUERY, onCommandClick: () => { const selectedCollection: ViewModels.Collection = selectedNodeState.findSelectedCollection(); selectedCollection && selectedCollection.onNewQueryClick(selectedCollection); @@ -312,6 +317,7 @@ function createNewSQLQueryButton(selectedNodeState: SelectedNodeState): CommandB id: "newQueryBtn", iconSrc: AddSqlQueryIcon, iconAlt: label, + keyboardAction: KeyboardAction.NEW_QUERY, onCommandClick: () => { const selectedCollection: ViewModels.Collection = selectedNodeState.findSelectedCollection(); selectedCollection && selectedCollection.onNewMongoQueryClick(selectedCollection); @@ -337,6 +343,7 @@ export function createScriptCommandButtons(selectedNodeState: SelectedNodeState) const newStoredProcedureBtn: CommandButtonComponentProps = { iconSrc: AddStoredProcedureIcon, iconAlt: label, + keyboardAction: KeyboardAction.NEW_SPROC, onCommandClick: () => { const selectedCollection: ViewModels.Collection = selectedNodeState.findSelectedCollection(); selectedCollection && selectedCollection.onNewStoredProcedureClick(selectedCollection); @@ -356,6 +363,7 @@ export function createScriptCommandButtons(selectedNodeState: SelectedNodeState) const newUserDefinedFunctionBtn: CommandButtonComponentProps = { iconSrc: AddUdfIcon, iconAlt: label, + keyboardAction: KeyboardAction.NEW_UDF, onCommandClick: () => { const selectedCollection: ViewModels.Collection = selectedNodeState.findSelectedCollection(); selectedCollection && selectedCollection.onNewUserDefinedFunctionClick(selectedCollection); @@ -375,6 +383,7 @@ export function createScriptCommandButtons(selectedNodeState: SelectedNodeState) const newTriggerBtn: CommandButtonComponentProps = { iconSrc: AddTriggerIcon, iconAlt: label, + keyboardAction: KeyboardAction.NEW_TRIGGER, onCommandClick: () => { const selectedCollection: ViewModels.Collection = selectedNodeState.findSelectedCollection(); selectedCollection && selectedCollection.onNewTriggerClick(selectedCollection); @@ -397,6 +406,7 @@ function createOpenQueryButton(container: Explorer): CommandButtonComponentProps return { iconSrc: BrowseQueriesIcon, iconAlt: label, + keyboardAction: KeyboardAction.OPEN_QUERY, onCommandClick: () => useSidePanel.getState().openSidePanel("Open Saved Queries", ), commandButtonLabel: label, @@ -411,6 +421,7 @@ function createOpenQueryFromDiskButton(): CommandButtonComponentProps { return { iconSrc: OpenQueryFromDiskIcon, iconAlt: label, + keyboardAction: KeyboardAction.OPEN_QUERY_FROM_DISK, onCommandClick: () => useSidePanel.getState().openSidePanel("Load Query", ), commandButtonLabel: label, ariaLabel: label, diff --git a/src/Explorer/Menus/CommandBar/CommandBarUtil.tsx b/src/Explorer/Menus/CommandBar/CommandBarUtil.tsx index 384bd06cd..fc67ad894 100644 --- a/src/Explorer/Menus/CommandBar/CommandBarUtil.tsx +++ b/src/Explorer/Menus/CommandBar/CommandBarUtil.tsx @@ -7,6 +7,7 @@ import { IDropdownStyles, } from "@fluentui/react"; import { useQueryCopilot } from "hooks/useQueryCopilot"; +import { KeyboardHandlerMap } from "KeyboardShortcuts"; import * as React from "react"; import _ from "underscore"; import ChevronDownIcon from "../../../../images/Chevron_down.svg"; @@ -233,3 +234,28 @@ export const createConnectionStatus = (container: Explorer, poolId: PoolIdType, onRender: () => , }; }; + +export function createKeyboardHandlers(allButtons: CommandButtonComponentProps[]): KeyboardHandlerMap { + const handlers: KeyboardHandlerMap = {}; + + function createHandlers(buttons: CommandButtonComponentProps[]) { + buttons.forEach((button) => { + if (!button.disabled && button.keyboardAction) { + handlers[button.keyboardAction] = (e) => { + button.onCommandClick(e); + + // If the handler is bound, it means the button is visible and enabled, so we should prevent the default action + return true; + }; + } + + if (button.children && button.children.length > 0) { + createHandlers(button.children); + } + }); + } + + createHandlers(allButtons); + + return handlers; +} diff --git a/src/Explorer/Panes/CassandraAddCollectionPane/CassandraAddCollectionPane.tsx b/src/Explorer/Panes/CassandraAddCollectionPane/CassandraAddCollectionPane.tsx index dbef20b12..cd91a6628 100644 --- a/src/Explorer/Panes/CassandraAddCollectionPane/CassandraAddCollectionPane.tsx +++ b/src/Explorer/Panes/CassandraAddCollectionPane/CassandraAddCollectionPane.tsx @@ -202,8 +202,8 @@ export const CassandraAddCollectionPane: FunctionComponent = setIsExecuting(true); const entity: Entities.ITableEntity = entityFromAttributes(entities); - const newEntity: Entities.ITableEntity = await tableDataClient.createDocument(queryTablesTab.collection, entity); try { + const newEntity: Entities.ITableEntity = await tableDataClient.createDocument(queryTablesTab.collection, entity); await tableEntityListViewModel.addEntityToCache(newEntity); if (!tryInsertNewHeaders(tableEntityListViewModel, newEntity)) { tableEntityListViewModel.redrawTableThrottled(); diff --git a/src/Explorer/Tables/TableDataClient.ts b/src/Explorer/Tables/TableDataClient.ts index c6882bc33..a9d7c96a6 100644 --- a/src/Explorer/Tables/TableDataClient.ts +++ b/src/Explorer/Tables/TableDataClient.ts @@ -172,8 +172,9 @@ export class CassandraAPIDataClient extends TableDataClient { deferred.resolve(entity); }, (error) => { - handleError(error, "AddRowCassandra", `Error while adding new row to table ${collection.id()}`); - deferred.reject(error); + const errorText = error.responseJSON?.message ?? JSON.stringify(error); + handleError(errorText, "AddRowCassandra", `Error while adding new row to table ${collection.id()}`); + deferred.reject(errorText); }, ) .finally(clearInProgressMessage); @@ -406,12 +407,13 @@ export class CassandraAPIDataClient extends TableDataClient { deferred.resolve(); }, (error) => { + const errorText = error.responseJSON?.message ?? JSON.stringify(error); handleError( - error, + errorText, "CreateKeyspaceCassandra", `Error while creating a keyspace with query ${createKeyspaceQuery}`, ); - deferred.reject(error); + deferred.reject(errorText); }, ) .finally(clearInProgressMessage); @@ -444,8 +446,13 @@ export class CassandraAPIDataClient extends TableDataClient { deferred.resolve(); }, (error) => { - handleError(error, "CreateTableCassandra", `Error while creating a table with query ${createTableQuery}`); - deferred.reject(error); + const errorText = error.responseJSON?.message ?? JSON.stringify(error); + handleError( + errorText, + "CreateTableCassandra", + `Error while creating a table with query ${createTableQuery}`, + ); + deferred.reject(errorText); }, ) .finally(clearInProgressMessage); @@ -493,8 +500,9 @@ export class CassandraAPIDataClient extends TableDataClient { deferred.resolve(data); }, (error: any) => { - handleError(error, "FetchKeysCassandra", `Error fetching keys for table ${collection.id()}`); - deferred.reject(error); + const errorText = error.responseJSON?.message ?? JSON.stringify(error); + handleError(errorText, "FetchKeysCassandra", `Error fetching keys for table ${collection.id()}`); + deferred.reject(errorText); }, ) .done(clearInProgressMessage); @@ -533,8 +541,9 @@ export class CassandraAPIDataClient extends TableDataClient { deferred.resolve(data); }, (error: any) => { - handleError(error, "FetchKeysCassandra", `Error fetching keys for table ${collection.id()}`); - deferred.reject(error); + const errorText = error.responseJSON?.message ?? JSON.stringify(error); + handleError(errorText, "FetchKeysCassandra", `Error fetching keys for table ${collection.id()}`); + deferred.reject(errorText); }, ) .done(clearInProgressMessage); @@ -578,8 +587,9 @@ export class CassandraAPIDataClient extends TableDataClient { deferred.resolve(data.columns); }, (error: any) => { - handleError(error, "FetchSchemaCassandra", `Error fetching schema for table ${collection.id()}`); - deferred.reject(error); + const errorText = error.responseJSON?.message ?? JSON.stringify(error); + handleError(errorText, "FetchSchemaCassandra", `Error fetching schema for table ${collection.id()}`); + deferred.reject(errorText); }, ) .done(clearInProgressMessage); @@ -618,8 +628,9 @@ export class CassandraAPIDataClient extends TableDataClient { deferred.resolve(data.columns); }, (error: any) => { - handleError(error, "FetchSchemaCassandra", `Error fetching schema for table ${collection.id()}`); - deferred.reject(error); + const errorText = error.responseJSON?.message ?? JSON.stringify(error); + handleError(errorText, "FetchSchemaCassandra", `Error fetching schema for table ${collection.id()}`); + deferred.reject(errorText); }, ) .done(clearInProgressMessage); diff --git a/src/Explorer/Tabs/DocumentsTab.ts b/src/Explorer/Tabs/DocumentsTab.ts index 3591378da..1d13237d0 100644 --- a/src/Explorer/Tabs/DocumentsTab.ts +++ b/src/Explorer/Tabs/DocumentsTab.ts @@ -1,6 +1,7 @@ import { ItemDefinition, PartitionKey, PartitionKeyDefinition, QueryIterator, Resource } from "@azure/cosmos"; import { Platform, configContext } from "ConfigContext"; import { querySampleDocuments, readSampleDocument } from "Explorer/QueryCopilot/QueryCopilotUtilities"; +import { KeyboardAction } from "KeyboardShortcuts"; import { QueryConstants } from "Shared/Constants"; import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility"; import * as ko from "knockout"; @@ -893,6 +894,7 @@ export default class DocumentsTab extends TabsBase { buttons.push({ iconSrc: NewDocumentIcon, iconAlt: label, + keyboardAction: KeyboardAction.NEW_ITEM, onCommandClick: this.onNewDocumentClick, commandButtonLabel: label, ariaLabel: label, @@ -907,6 +909,7 @@ export default class DocumentsTab extends TabsBase { buttons.push({ iconSrc: SaveIcon, iconAlt: label, + keyboardAction: KeyboardAction.SAVE_ITEM, onCommandClick: this.onSaveNewDocumentClick, commandButtonLabel: label, ariaLabel: label, @@ -921,6 +924,7 @@ export default class DocumentsTab extends TabsBase { buttons.push({ iconSrc: DiscardIcon, iconAlt: label, + keyboardAction: KeyboardAction.CANCEL_OR_DISCARD, onCommandClick: this.onRevertNewDocumentClick, commandButtonLabel: label, ariaLabel: label, @@ -936,6 +940,7 @@ export default class DocumentsTab extends TabsBase { buttons.push({ iconSrc: SaveIcon, iconAlt: label, + keyboardAction: KeyboardAction.SAVE_ITEM, onCommandClick: this.onSaveExistingDocumentClick, commandButtonLabel: label, ariaLabel: label, @@ -950,6 +955,7 @@ export default class DocumentsTab extends TabsBase { buttons.push({ iconSrc: DiscardIcon, iconAlt: label, + keyboardAction: KeyboardAction.CANCEL_OR_DISCARD, onCommandClick: this.onRevertExisitingDocumentClick, commandButtonLabel: label, ariaLabel: label, @@ -965,6 +971,7 @@ export default class DocumentsTab extends TabsBase { buttons.push({ iconSrc: DeleteDocumentIcon, iconAlt: label, + keyboardAction: KeyboardAction.DELETE_ITEM, onCommandClick: this.onDeleteExisitingDocumentClick, commandButtonLabel: label, ariaLabel: label, diff --git a/src/Explorer/Tabs/MongoShellTab/MongoShellTabComponent.tsx b/src/Explorer/Tabs/MongoShellTab/MongoShellTabComponent.tsx index cb47a070d..a89ca5fc7 100644 --- a/src/Explorer/Tabs/MongoShellTab/MongoShellTabComponent.tsx +++ b/src/Explorer/Tabs/MongoShellTab/MongoShellTabComponent.tsx @@ -9,7 +9,6 @@ import { isInvalidParentFrameOrigin, isReadyMessage } from "../../../Utils/Messa import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../../Utils/NotificationConsoleUtils"; import Explorer from "../../Explorer"; import TabsBase from "../TabsBase"; -import { getMongoShellOrigin } from "./getMongoShellOrigin"; import { getMongoShellUrl } from "./getMongoShellUrl"; //eslint-disable-next-line @@ -35,7 +34,7 @@ export interface IMongoShellTabAccessor { } export interface IMongoShellTabComponentStates { - url: string; + url: URL; } export interface IMongoShellTabComponentProps { @@ -50,13 +49,16 @@ export default class MongoShellTabComponent extends Component< IMongoShellTabComponentStates > { private _logTraces: Map; + private _useMongoProxyEndpoint: boolean; constructor(props: IMongoShellTabComponentProps) { super(props); this._logTraces = new Map(); + this._useMongoProxyEndpoint = userContext.features.enableLegacyMongoShell; + // this._useMongoProxyEndpoint = useMongoProxyEndpoint("legacyMongoShell"); this.state = { - url: getMongoShellUrl(), + url: getMongoShellUrl(this._useMongoProxyEndpoint), }; props.onMongoShellTabAccessor({ @@ -119,9 +121,10 @@ export default class MongoShellTabComponent extends Component< ) + Constants.MongoDBAccounts.defaultPort.toString(); const databaseId = this.props.collection.databaseId; const collectionId = this.props.collection.id(); - const apiEndpoint = configContext.BACKEND_ENDPOINT; + const apiEndpoint = this._useMongoProxyEndpoint + ? configContext.MONGO_PROXY_ENDPOINT + : configContext.BACKEND_ENDPOINT; const encryptedAuthToken: string = userContext.accessToken; - const targetOrigin = getMongoShellOrigin(); shellIframe.contentWindow.postMessage( { @@ -137,7 +140,7 @@ export default class MongoShellTabComponent extends Component< apiEndpoint: apiEndpoint, }, }, - targetOrigin, + window.origin, ); } @@ -218,7 +221,7 @@ export default class MongoShellTabComponent extends Component< name="explorer" className="iframe" style={{ width: "100%", height: "100%", border: 0, padding: 0, margin: 0, overflow: "hidden" }} - src={this.state.url} + src={this.state.url.toString()} id={this.props.tabsBaseInstance.tabId} onLoad={(event) => this.setContentFocus(event)} title="Mongo Shell" diff --git a/src/Explorer/Tabs/MongoShellTab/getMongoShellOrigin.test.ts b/src/Explorer/Tabs/MongoShellTab/getMongoShellOrigin.test.ts deleted file mode 100644 index 8f62b2a0c..000000000 --- a/src/Explorer/Tabs/MongoShellTab/getMongoShellOrigin.test.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { extractFeatures } from "Platform/Hosted/extractFeatures"; -import { configContext } from "../../../ConfigContext"; -import { updateUserContext } from "../../../UserContext"; -import { getMongoShellOrigin } from "./getMongoShellOrigin"; - -describe("getMongoShellOrigin", () => { - (window as { origin: string }).origin = "window_origin"; - - beforeEach(() => { - updateUserContext({ - features: extractFeatures( - new URLSearchParams({ - "feature.enableLegacyMongoShellV1": "false", - "feature.enableLegacyMongoShellV2": "false", - "feature.enableLegacyMongoShellV1Debug": "false", - "feature.enableLegacyMongoShellV2Debug": "false", - "feature.loadLegacyMongoShellFromBE": "false", - }), - ), - }); - }); - - it("should return by default", () => { - expect(getMongoShellOrigin()).toBe(window.origin); - }); - - it("should return window.origin when enableLegacyMongoShellV1", () => { - updateUserContext({ - features: extractFeatures( - new URLSearchParams({ - "feature.enableLegacyMongoShellV1": "true", - }), - ), - }); - - expect(getMongoShellOrigin()).toBe(window.origin); - }); - - it("should return window.origin when enableLegacyMongoShellV2===true", () => { - updateUserContext({ - features: extractFeatures( - new URLSearchParams({ - "feature.enableLegacyMongoShellV2": "true", - }), - ), - }); - - expect(getMongoShellOrigin()).toBe(window.origin); - }); - - it("should return window.origin when enableLegacyMongoShellV1Debug===true", () => { - updateUserContext({ - features: extractFeatures( - new URLSearchParams({ - "feature.enableLegacyMongoShellV1Debug": "true", - }), - ), - }); - - expect(getMongoShellOrigin()).toBe(window.origin); - }); - - it("should return window.origin when enableLegacyMongoShellV2Debug===true", () => { - updateUserContext({ - features: extractFeatures( - new URLSearchParams({ - "feature.enableLegacyMongoShellV2Debug": "true", - }), - ), - }); - - expect(getMongoShellOrigin()).toBe(window.origin); - }); - - it("should return BACKEND_ENDPOINT when loadLegacyMongoShellFromBE===true", () => { - updateUserContext({ - features: extractFeatures( - new URLSearchParams({ - "feature.loadLegacyMongoShellFromBE": "true", - }), - ), - }); - - expect(getMongoShellOrigin()).toBe(configContext.BACKEND_ENDPOINT); - }); -}); diff --git a/src/Explorer/Tabs/MongoShellTab/getMongoShellOrigin.ts b/src/Explorer/Tabs/MongoShellTab/getMongoShellOrigin.ts deleted file mode 100644 index 774a4443c..000000000 --- a/src/Explorer/Tabs/MongoShellTab/getMongoShellOrigin.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { configContext } from "../../../ConfigContext"; -import { userContext } from "../../../UserContext"; - -export function getMongoShellOrigin(): string { - if (userContext.features.loadLegacyMongoShellFromBE === true) { - return configContext.BACKEND_ENDPOINT; - } - - return window.origin; -} diff --git a/src/Explorer/Tabs/MongoShellTab/getMongoShellUrl.test.ts b/src/Explorer/Tabs/MongoShellTab/getMongoShellUrl.test.ts index 1d75f682d..0c138ff61 100644 --- a/src/Explorer/Tabs/MongoShellTab/getMongoShellUrl.test.ts +++ b/src/Explorer/Tabs/MongoShellTab/getMongoShellUrl.test.ts @@ -1,9 +1,9 @@ -import { extractFeatures } from "Platform/Hosted/extractFeatures"; -import { Platform, configContext, resetConfigContext, updateConfigContext } from "../../../ConfigContext"; +import { Platform, resetConfigContext, updateConfigContext } from "../../../ConfigContext"; import { updateUserContext, userContext } from "../../../UserContext"; -import { getExtensionEndpoint, getMongoShellUrl } from "./getMongoShellUrl"; +import { getMongoShellUrl } from "./getMongoShellUrl"; const mongoBackendEndpoint = "https://localhost:1234"; +const hostedExplorerURL = "https://cosmos.azure.com/"; describe("getMongoShellUrl", () => { let queryString = ""; @@ -13,6 +13,7 @@ describe("getMongoShellUrl", () => { updateConfigContext({ BACKEND_ENDPOINT: mongoBackendEndpoint, + hostedExplorerURL: hostedExplorerURL, platform: Platform.Hosted, }); @@ -32,175 +33,18 @@ describe("getMongoShellUrl", () => { cassandraEndpoint: "fakeCassandraEndpoint", }, }, - features: extractFeatures( - new URLSearchParams({ - "feature.enableLegacyMongoShellV1": "false", - "feature.enableLegacyMongoShellV2": "false", - "feature.enableLegacyMongoShellV1Debug": "false", - "feature.enableLegacyMongoShellV2Debug": "false", - "feature.loadLegacyMongoShellFromBE": "false", - }), - ), portalEnv: "prod", }); queryString = `resourceId=${userContext.databaseAccount.id}&accountName=${userContext.databaseAccount.name}&mongoEndpoint=${userContext.databaseAccount.properties.documentEndpoint}`; }); - it("should return /mongoshell/indexv2.html by default", () => { - expect(getMongoShellUrl()).toBe(`/mongoshell/indexv2.html?${queryString}`); + it("should return /indexv2.html by default", () => { + expect(getMongoShellUrl().toString()).toContain(`/indexv2.html?${queryString}`); }); - it("should return /mongoshell/indexv2.html when portalEnv==localhost", () => { - updateUserContext({ - portalEnv: "localhost", - }); - - expect(getMongoShellUrl()).toBe(`/mongoshell/indexv2.html?${queryString}`); - }); - - it("should return /mongoshell/index.html when enableLegacyMongoShellV1===true", () => { - updateUserContext({ - features: extractFeatures( - new URLSearchParams({ - "feature.enableLegacyMongoShellV1": "true", - }), - ), - }); - - expect(getMongoShellUrl()).toBe(`/mongoshell/index.html?${queryString}`); - }); - - it("should return /mongoshell/index.html when enableLegacyMongoShellV2===true", () => { - updateUserContext({ - features: extractFeatures( - new URLSearchParams({ - "feature.enableLegacyMongoShellV2": "true", - }), - ), - }); - - expect(getMongoShellUrl()).toBe(`/mongoshell/indexv2.html?${queryString}`); - }); - - it("should return /mongoshell/index.html when enableLegacyMongoShellV1Debug===true", () => { - updateUserContext({ - features: extractFeatures( - new URLSearchParams({ - "feature.enableLegacyMongoShellV1Debug": "true", - }), - ), - }); - - expect(getMongoShellUrl()).toBe(`/mongoshell/debug/index.html?${queryString}`); - }); - - it("should return /mongoshell/index.html when enableLegacyMongoShellV2Debug===true", () => { - updateUserContext({ - features: extractFeatures( - new URLSearchParams({ - "feature.enableLegacyMongoShellV2Debug": "true", - }), - ), - }); - - expect(getMongoShellUrl()).toBe(`/mongoshell/debug/indexv2.html?${queryString}`); - }); - - describe("loadLegacyMongoShellFromBE===true", () => { - beforeEach(() => { - resetConfigContext(); - updateConfigContext({ - BACKEND_ENDPOINT: mongoBackendEndpoint, - platform: Platform.Hosted, - }); - - updateUserContext({ - features: extractFeatures( - new URLSearchParams({ - "feature.loadLegacyMongoShellFromBE": "true", - }), - ), - }); - }); - - it("should return /mongoshell/index.html", () => { - const endpoint = getExtensionEndpoint(configContext.platform, configContext.BACKEND_ENDPOINT); - expect(getMongoShellUrl()).toBe(`${endpoint}/content/mongoshell/debug/index.html?${queryString}`); - }); - - it("configContext.platform !== Platform.Hosted, should return /mongoshell/indexv2.html", () => { - updateConfigContext({ - platform: Platform.Portal, - }); - - const endpoint = getExtensionEndpoint(configContext.platform, configContext.BACKEND_ENDPOINT); - expect(getMongoShellUrl()).toBe(`${endpoint}/content/mongoshell/debug/index.html?${queryString}`); - }); - - it("configContext.BACKEND_ENDPOINT !== '' and configContext.platform !== Platform.Hosted, should return /mongoshell/indexv2.html", () => { - resetConfigContext(); - updateConfigContext({ - platform: Platform.Portal, - BACKEND_ENDPOINT: mongoBackendEndpoint, - }); - - const endpoint = getExtensionEndpoint(configContext.platform, configContext.BACKEND_ENDPOINT); - expect(getMongoShellUrl()).toBe(`${endpoint}/content/mongoshell/debug/index.html?${queryString}`); - }); - - it("configContext.BACKEND_ENDPOINT === '' and configContext.platform === Platform.Hosted, should return /mongoshell/indexv2.html", () => { - resetConfigContext(); - updateConfigContext({ - platform: Platform.Hosted, - }); - - const endpoint = getExtensionEndpoint(configContext.platform, configContext.BACKEND_ENDPOINT); - expect(getMongoShellUrl()).toBe(`${endpoint}/content/mongoshell/debug/index.html?${queryString}`); - }); - - it("configContext.BACKEND_ENDPOINT === '' and configContext.platform !== Platform.Hosted, should return /mongoshell/indexv2.html", () => { - resetConfigContext(); - updateConfigContext({ - platform: Platform.Portal, - }); - - const endpoint = getExtensionEndpoint(configContext.platform, configContext.BACKEND_ENDPOINT); - expect(getMongoShellUrl()).toBe(`${endpoint}/content/mongoshell/debug/index.html?${queryString}`); - }); - }); -}); - -describe("getExtensionEndpoint", () => { - it("when platform === Platform.Hosted, backendEndpoint is undefined", () => { - expect(getExtensionEndpoint(Platform.Hosted, undefined)).toBe(""); - }); - - it("when platform === Platform.Hosted, backendEndpoint === ''", () => { - expect(getExtensionEndpoint(Platform.Hosted, "")).toBe(""); - }); - - it("when platform === Platform.Hosted, backendEndpoint === null", () => { - expect(getExtensionEndpoint(Platform.Hosted, null)).toBe(""); - }); - - it("when platform === Platform.Hosted, backendEndpoint != ''", () => { - expect(getExtensionEndpoint(Platform.Hosted, "foo")).toBe("foo"); - }); - - it("when platform === Platform.Portal, backendEndpoint is udefined", () => { - expect(getExtensionEndpoint(Platform.Portal, undefined)).toBe(""); - }); - - it("when platform === Platform.Portal, backendEndpoint === ''", () => { - expect(getExtensionEndpoint(Platform.Portal, "")).toBe(""); - }); - - it("when platform === Platform.Portal, backendEndpoint === null", () => { - expect(getExtensionEndpoint(Platform.Portal, null)).toBe(""); - }); - - it("when platform !== Platform.Portal, backendEndpoint != ''", () => { - expect(getExtensionEndpoint(Platform.Portal, "foo")).toBe("foo"); + it("should return /index.html when useMongoProxyEndpoint is true", () => { + const useMongoProxyEndpoint: boolean = true; + expect(getMongoShellUrl(useMongoProxyEndpoint).toString()).toContain(`/index.html?${queryString}`); }); }); diff --git a/src/Explorer/Tabs/MongoShellTab/getMongoShellUrl.ts b/src/Explorer/Tabs/MongoShellTab/getMongoShellUrl.ts index a029fe440..0ecbcb83e 100644 --- a/src/Explorer/Tabs/MongoShellTab/getMongoShellUrl.ts +++ b/src/Explorer/Tabs/MongoShellTab/getMongoShellUrl.ts @@ -1,45 +1,15 @@ -import { configContext, Platform } from "../../../ConfigContext"; +import { configContext } from "ConfigContext"; import { userContext } from "../../../UserContext"; -export function getMongoShellUrl(): string { +export function getMongoShellUrl(useMongoProxyEndpoint?: boolean): URL { const { databaseAccount: account } = userContext; const resourceId = account?.id; const accountName = account?.name; const mongoEndpoint = account?.properties?.mongoEndpoint || account?.properties?.documentEndpoint; const queryString = `resourceId=${resourceId}&accountName=${accountName}&mongoEndpoint=${mongoEndpoint}`; + const path: string = useMongoProxyEndpoint + ? `/mongoshell/index.html?${queryString}` + : `/mongoshell/indexv2.html?${queryString}`; - if (userContext.features.enableLegacyMongoShellV1 === true) { - return `/mongoshell/index.html?${queryString}`; - } - - if (userContext.features.enableLegacyMongoShellV1Debug === true) { - return `/mongoshell/debug/index.html?${queryString}`; - } - - if (userContext.features.enableLegacyMongoShellV2 === true) { - return `/mongoshell/indexv2.html?${queryString}`; - } - - if (userContext.features.enableLegacyMongoShellV2Debug === true) { - return `/mongoshell/debug/indexv2.html?${queryString}`; - } - - if (userContext.portalEnv === "localhost") { - return `/mongoshell/indexv2.html?${queryString}`; - } - - if (userContext.features.loadLegacyMongoShellFromBE === true) { - const extensionEndpoint: string = getExtensionEndpoint(configContext.platform, configContext.BACKEND_ENDPOINT); - return `${extensionEndpoint}/content/mongoshell/debug/index.html?${queryString}`; - } - - return `/mongoshell/indexv2.html?${queryString}`; -} - -export function getExtensionEndpoint(platform: string, backendEndpoint: string): string { - const runtimeEndpoint = platform === Platform.Hosted ? backendEndpoint : ""; - - const extensionEndpoint: string = backendEndpoint || runtimeEndpoint || ""; - - return extensionEndpoint; + return new URL(path, configContext.hostedExplorerURL); } diff --git a/src/Explorer/Tabs/QueryTab/QueryTabComponent.tsx b/src/Explorer/Tabs/QueryTab/QueryTabComponent.tsx index fa849c212..07f0a9eba 100644 --- a/src/Explorer/Tabs/QueryTab/QueryTabComponent.tsx +++ b/src/Explorer/Tabs/QueryTab/QueryTabComponent.tsx @@ -10,6 +10,7 @@ import { OnExecuteQueryClick, QueryDocumentsPerPage } from "Explorer/QueryCopilo import { QueryCopilotSidebar } from "Explorer/QueryCopilot/V2/Sidebar/QueryCopilotSidebar"; import { QueryResultSection } from "Explorer/Tabs/QueryTab/QueryResultSection"; import { useSelectedNode } from "Explorer/useSelectedNode"; +import { KeyboardAction } from "KeyboardShortcuts"; import { QueryConstants } from "Shared/Constants"; import { LocalStorageUtility, StorageKey, getRUThreshold, ruThresholdEnabled } from "Shared/StorageUtility"; import { Action } from "Shared/Telemetry/TelemetryConstants"; @@ -393,6 +394,7 @@ export default class QueryTabComponent extends React.Component OnExecuteQueryClick(this.props.copilotStore) : this.onExecuteQueryClick, @@ -408,6 +410,7 @@ export default class QueryTabComponent extends React.Component { this._toggleCopilot(!this.state.copilotActive); }, @@ -468,6 +472,7 @@ export default class QueryTabComponent extends React.Component this.queryAbortController.abort(), commandButtonLabel: label, ariaLabel: label, diff --git a/src/Explorer/Tabs/StoredProcedureTab/StoredProcedureTabComponent.tsx b/src/Explorer/Tabs/StoredProcedureTab/StoredProcedureTabComponent.tsx index 98e398e1b..ce8c6ac45 100644 --- a/src/Explorer/Tabs/StoredProcedureTab/StoredProcedureTabComponent.tsx +++ b/src/Explorer/Tabs/StoredProcedureTab/StoredProcedureTabComponent.tsx @@ -1,5 +1,6 @@ import { Resource, StoredProcedureDefinition } from "@azure/cosmos"; import { Pivot, PivotItem } from "@fluentui/react"; +import { KeyboardAction } from "KeyboardShortcuts"; import React from "react"; import ExecuteQueryIcon from "../../../../images/ExecuteQuery.svg"; import DiscardIcon from "../../../../images/discard.svg"; @@ -321,6 +322,7 @@ export default class StoredProcedureTabComponent extends React.Component< buttons.push({ iconSrc: SaveIcon, iconAlt: label, + keyboardAction: KeyboardAction.SAVE_ITEM, onCommandClick: this.onSaveClick, commandButtonLabel: label, ariaLabel: label, @@ -334,6 +336,7 @@ export default class StoredProcedureTabComponent extends React.Component< buttons.push({ iconSrc: SaveIcon, iconAlt: label, + keyboardAction: KeyboardAction.SAVE_ITEM, onCommandClick: this.onUpdateClick, commandButtonLabel: label, ariaLabel: label, @@ -347,6 +350,7 @@ export default class StoredProcedureTabComponent extends React.Component< buttons.push({ iconSrc: DiscardIcon, iconAlt: label, + keyboardAction: KeyboardAction.CANCEL_OR_DISCARD, onCommandClick: this.onDiscard, commandButtonLabel: label, ariaLabel: label, @@ -360,6 +364,7 @@ export default class StoredProcedureTabComponent extends React.Component< buttons.push({ iconSrc: ExecuteQueryIcon, iconAlt: label, + keyboardAction: KeyboardAction.EXECUTE_ITEM, onCommandClick: () => { this.collection.container.openExecuteSprocParamsPanel(this.node); }, diff --git a/src/Explorer/Tabs/Tabs.tsx b/src/Explorer/Tabs/Tabs.tsx index 53678ed5a..b33f3d4af 100644 --- a/src/Explorer/Tabs/Tabs.tsx +++ b/src/Explorer/Tabs/Tabs.tsx @@ -6,6 +6,7 @@ import { IpRule } from "Contracts/DataModels"; import { MessageTypes } from "Contracts/ExplorerContracts"; import { CollectionTabKind } from "Contracts/ViewModels"; import Explorer from "Explorer/Explorer"; +import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter"; import { QueryCopilotTab } from "Explorer/QueryCopilot/QueryCopilotTab"; import { SplashScreen } from "Explorer/SplashScreen/SplashScreen"; import { ConnectTab } from "Explorer/Tabs/ConnectTab"; @@ -13,6 +14,7 @@ import { PostgresConnectTab } from "Explorer/Tabs/PostgresConnectTab"; import { QuickstartTab } from "Explorer/Tabs/QuickstartTab"; import { VcoreMongoConnectTab } from "Explorer/Tabs/VCoreMongoConnectTab"; import { VcoreMongoQuickstartTab } from "Explorer/Tabs/VCoreMongoQuickstartTab"; +import { KeyboardAction, KeyboardActionGroup, useKeyboardActionGroup } from "KeyboardShortcuts"; import { hasRUThresholdBeenConfigured } from "Shared/StorageUtility"; import { userContext } from "UserContext"; import { CassandraProxyOutboundIPs, MongoProxyOutboundIPs, PortalBackendIPs } from "Utils/EndpointUtils"; @@ -41,6 +43,16 @@ export const Tabs = ({ explorer }: TabsProps): JSX.Element => { showMongoAndCassandraProxiesNetworkSettingsWarningState, setShowMongoAndCassandraProxiesNetworkSettingsWarningState, ] = useState(showMongoAndCassandraProxiesNetworkSettingsWarning()); + + const setKeyboardHandlers = useKeyboardActionGroup(KeyboardActionGroup.TABS); + useEffect(() => { + setKeyboardHandlers({ + [KeyboardAction.SELECT_LEFT_TAB]: () => useTabs.getState().selectLeftTab(), + [KeyboardAction.SELECT_RIGHT_TAB]: () => useTabs.getState().selectRightTab(), + [KeyboardAction.CLOSE_TAB]: () => useTabs.getState().closeActiveTab(), + }); + }, [setKeyboardHandlers]); + return (
{networkSettingsWarning && ( @@ -297,6 +309,9 @@ const isQueryErrorThrown = (tab?: Tab, tabKind?: ReactTabKind): boolean => { }; const getReactTabContent = (activeReactTab: ReactTabKind, explorer: Explorer): JSX.Element => { + // React tabs have no context buttons. + useCommandBar.getState().setContextButtons([]); + // eslint-disable-next-line no-console switch (activeReactTab) { case ReactTabKind.Connect: @@ -325,7 +340,7 @@ const getReactTabContent = (activeReactTab: ReactTabKind, explorer: Explorer): J const showMongoAndCassandraProxiesNetworkSettingsWarning = (): boolean => { const ipRules: IpRule[] = userContext.databaseAccount?.properties?.ipRules; if ( - ((userContext.apiType === "Mongo" && configContext.MONGO_PROXY_ENDPOINT !== MongoProxyEndpoints.Development) || + ((userContext.apiType === "Mongo" && configContext.MONGO_PROXY_ENDPOINT !== MongoProxyEndpoints.Local) || (userContext.apiType === "Cassandra" && configContext.CASSANDRA_PROXY_ENDPOINT !== CassandraProxyEndpoints.Development)) && ipRules?.length diff --git a/src/Explorer/Tabs/TriggerTabContent.tsx b/src/Explorer/Tabs/TriggerTabContent.tsx index bf756598e..5fd28502a 100644 --- a/src/Explorer/Tabs/TriggerTabContent.tsx +++ b/src/Explorer/Tabs/TriggerTabContent.tsx @@ -1,5 +1,6 @@ import { TriggerDefinition } from "@azure/cosmos"; import { Dropdown, IDropdownOption, Label, TextField } from "@fluentui/react"; +import { KeyboardAction } from "KeyboardShortcuts"; import React, { Component } from "react"; import DiscardIcon from "../../../images/discard.svg"; import SaveIcon from "../../../images/save-cosmos.svg"; @@ -218,6 +219,18 @@ export class TriggerTabContent extends Component diff --git a/src/Explorer/Tabs/UserDefinedFunctionTabContent.tsx b/src/Explorer/Tabs/UserDefinedFunctionTabContent.tsx index c0d78ff9a..98b90c045 100644 --- a/src/Explorer/Tabs/UserDefinedFunctionTabContent.tsx +++ b/src/Explorer/Tabs/UserDefinedFunctionTabContent.tsx @@ -1,12 +1,13 @@ import { UserDefinedFunctionDefinition } from "@azure/cosmos"; import { Label, TextField } from "@fluentui/react"; +import { KeyboardAction } from "KeyboardShortcuts"; import React, { Component } from "react"; import DiscardIcon from "../../../images/discard.svg"; import SaveIcon from "../../../images/save-cosmos.svg"; import * as Constants from "../../Common/Constants"; +import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils"; import { createUserDefinedFunction } from "../../Common/dataAccess/createUserDefinedFunction"; import { updateUserDefinedFunction } from "../../Common/dataAccess/updateUserDefinedFunction"; -import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils"; import * as ViewModels from "../../Contracts/ViewModels"; import { Action } from "../../Shared/Telemetry/TelemetryConstants"; import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; @@ -80,6 +81,7 @@ export default class UserDefinedFunctionTabContent extends Component< setState: this.setState, iconSrc: SaveIcon, iconAlt: label, + keyboardAction: KeyboardAction.SAVE_ITEM, onCommandClick: this.onSaveClick, commandButtonLabel: label, ariaLabel: label, @@ -94,6 +96,7 @@ export default class UserDefinedFunctionTabContent extends Component< ...this, iconSrc: SaveIcon, iconAlt: label, + keyboardAction: KeyboardAction.SAVE_ITEM, onCommandClick: this.onUpdateClick, commandButtonLabel: label, ariaLabel: label, @@ -109,6 +112,7 @@ export default class UserDefinedFunctionTabContent extends Component< ...this, iconSrc: DiscardIcon, iconAlt: label, + keyboardAction: KeyboardAction.CANCEL_OR_DISCARD, onCommandClick: this.onDiscard, commandButtonLabel: label, ariaLabel: label, diff --git a/src/KeyboardShortcuts.tsx b/src/KeyboardShortcuts.tsx new file mode 100644 index 000000000..66efd68b4 --- /dev/null +++ b/src/KeyboardShortcuts.tsx @@ -0,0 +1,157 @@ +import * as React from "react"; +import { PropsWithChildren, useEffect } from "react"; +import { KeyBindingMap, tinykeys } from "tinykeys"; +import create, { UseStore } from "zustand"; + +/** + * Represents a keyboard shortcut handler. + * Return `true` to prevent the default action of the keyboard shortcut. + * Any other return value will allow the default action to proceed. + */ +export type KeyboardActionHandler = (e: KeyboardEvent) => boolean | void; + +export type KeyboardHandlerMap = Partial>; + +/** + * The groups of keyboard actions that can be managed by the application. + * Each group can be updated separately, but, when updated, must be completely replaced. + */ +export enum KeyboardActionGroup { + TABS = "TABS", + COMMAND_BAR = "COMMAND_BAR", +} + +/** + * The possible actions that can be triggered by keyboard shortcuts. + */ +export enum KeyboardAction { + NEW_QUERY = "NEW_QUERY", + EXECUTE_ITEM = "EXECUTE_ITEM", + CANCEL_OR_DISCARD = "CANCEL_OR_DISCARD", + SAVE_ITEM = "SAVE_ITEM", + OPEN_QUERY = "OPEN_QUERY", + OPEN_QUERY_FROM_DISK = "OPEN_QUERY_FROM_DISK", + NEW_SPROC = "NEW_SPROC", + NEW_UDF = "NEW_UDF", + NEW_TRIGGER = "NEW_TRIGGER", + NEW_DATABASE = "NEW_DATABASE", + NEW_COLLECTION = "NEW_CONTAINER", + NEW_ITEM = "NEW_ITEM", + DELETE_ITEM = "DELETE_ITEM", + TOGGLE_COPILOT = "TOGGLE_COPILOT", + SELECT_LEFT_TAB = "SELECT_LEFT_TAB", + SELECT_RIGHT_TAB = "SELECT_RIGHT_TAB", + CLOSE_TAB = "CLOSE_TAB", +} + +/** + * The keyboard shortcuts for the application. + * This record maps each action to the keyboard shortcuts that trigger the action. + * Even if an action is specified here, it will not be triggered unless a handler is set for it. + */ +const bindings: Record = { + // NOTE: The "$mod" special value is used to represent the "Control" key on Windows/Linux and the "Command" key on macOS. + // See https://www.npmjs.com/package/tinykeys#commonly-used-keys-and-codes for more information on the expected values for keyboard shortcuts. + + [KeyboardAction.NEW_QUERY]: ["$mod+J", "Alt+N Q"], + [KeyboardAction.EXECUTE_ITEM]: ["Shift+Enter"], + [KeyboardAction.CANCEL_OR_DISCARD]: ["Escape"], + [KeyboardAction.SAVE_ITEM]: ["$mod+S"], + [KeyboardAction.OPEN_QUERY]: ["$mod+O"], + [KeyboardAction.OPEN_QUERY_FROM_DISK]: ["$mod+Shift+O"], + [KeyboardAction.NEW_SPROC]: ["Alt+N P"], + [KeyboardAction.NEW_UDF]: ["Alt+N F"], + [KeyboardAction.NEW_TRIGGER]: ["Alt+N T"], + [KeyboardAction.NEW_DATABASE]: ["Alt+N D"], + [KeyboardAction.NEW_COLLECTION]: ["Alt+N C"], + [KeyboardAction.NEW_ITEM]: ["Alt+N I"], + [KeyboardAction.DELETE_ITEM]: ["Alt+D"], + [KeyboardAction.TOGGLE_COPILOT]: ["$mod+P"], + [KeyboardAction.SELECT_LEFT_TAB]: ["$mod+Alt+["], + [KeyboardAction.SELECT_RIGHT_TAB]: ["$mod+Alt+]"], + [KeyboardAction.CLOSE_TAB]: ["$mod+Alt+W"], +}; + +interface KeyboardShortcutState { + /** + * A set of all the keyboard shortcuts handlers. + */ + allHandlers: KeyboardHandlerMap; + + /** + * A set of all the groups of keyboard shortcuts handlers. + */ + groups: Partial>; + + /** + * Sets the keyboard shortcut handlers for the given group. + */ + setHandlers: (group: KeyboardActionGroup, handlers: KeyboardHandlerMap) => void; +} + +/** + * Defines the calling component as the manager of the keyboard actions for the given group. + * @param group The group of keyboard actions to manage. + * @returns A function that can be used to set the keyboard action handlers for the given group. + */ +export const useKeyboardActionGroup = (group: KeyboardActionGroup) => (handlers: KeyboardHandlerMap) => + useKeyboardActionHandlers.getState().setHandlers(group, handlers); + +const useKeyboardActionHandlers: UseStore = create((set, get) => ({ + allHandlers: {}, + groups: {}, + setHandlers: (group: KeyboardActionGroup, handlers: KeyboardHandlerMap) => { + const state = get(); + const groups = { ...state.groups, [group]: handlers }; + + // Combine all the handlers from all the groups in the correct order. + const allHandlers: KeyboardHandlerMap = {}; + eachKey(groups).forEach((group) => { + const groupHandlers = groups[group]; + if (groupHandlers) { + eachKey(groupHandlers).forEach((action) => { + // Check for duplicate handlers in development mode. + // We don't want to raise an error here in production, but having duplicate handlers is a mistake. + if (process.env.NODE_ENV === "development" && allHandlers[action]) { + throw new Error(`Duplicate handler for Keyboard Action "${action}".`); + } + allHandlers[action] = groupHandlers[action]; + }); + } + }); + set({ groups, allHandlers }); + }, +})); + +function createHandler(action: KeyboardAction): KeyboardActionHandler { + return (e) => { + const state = useKeyboardActionHandlers.getState(); + const handler = state.allHandlers[action]; + if (handler && handler(e)) { + e.preventDefault(); + e.stopPropagation(); + } + }; +} + +const allHandlers: KeyBindingMap = {}; +eachKey(bindings).forEach((action) => { + const shortcuts = bindings[action]; + shortcuts.forEach((shortcut) => { + allHandlers[shortcut] = createHandler(action); + }); +}); + +export function KeyboardShortcutRoot({ children }: PropsWithChildren) { + useEffect(() => { + // We bind to the body because Fluent UI components sometimes shift focus to the body, which is above the root React component. + tinykeys(document.body, allHandlers); + }, []); + + return <>{children}; +} + +/** A _typed_ version of `Object.keys` that preserves the original key type */ +function eachKey(record: Partial>): K[] { + return Object.keys(record) as K[]; +} diff --git a/src/Main.tsx b/src/Main.tsx index c6b79b139..f79ee29f1 100644 --- a/src/Main.tsx +++ b/src/Main.tsx @@ -21,6 +21,7 @@ import "../externals/jquery.typeahead.min.js"; // Image Dependencies import { Platform } from "ConfigContext"; import { QueryCopilotCarousel } from "Explorer/QueryCopilot/CopilotCarousel"; +import { KeyboardShortcutRoot } from "KeyboardShortcuts"; import "../images/CosmosDB_rgb_ui_lighttheme.ico"; import hdeConnectImage from "../images/HdeConnectCosmosDB.svg"; import "../images/favicon.ico"; @@ -91,52 +92,54 @@ const App: React.FunctionComponent = () => { } return ( -
-
-
- {/* Main Command Bar - Start */} - - {/* Collections Tree and Tabs - Begin */} -
- {/* Collections Tree - Start */} - {userContext.apiType !== "Postgres" && userContext.apiType !== "VCoreMongo" && ( -
-
- {/* Collections Tree Expanded - Start */} - - {/* Collections Tree Expanded - End */} - {/* Collections Tree Collapsed - Start */} - - {/* Collections Tree Collapsed - End */} + +
+
+
+ {/* Main Command Bar - Start */} + + {/* Collections Tree and Tabs - Begin */} +
+ {/* Collections Tree - Start */} + {userContext.apiType !== "Postgres" && userContext.apiType !== "VCoreMongo" && ( +
+
+ {/* Collections Tree Expanded - Start */} + + {/* Collections Tree Expanded - End */} + {/* Collections Tree Collapsed - Start */} + + {/* Collections Tree Collapsed - End */} +
-
- )} - -
- {/* Collections Tree and Tabs - End */} - + {/* Collections Tree and Tabs - End */} +
+ + + {} + {} + {} + {}
- - - {} - {} - {} - {} -
+ ); }; diff --git a/src/Platform/Hosted/extractFeatures.ts b/src/Platform/Hosted/extractFeatures.ts index 7bf3c8a3f..626b855bb 100644 --- a/src/Platform/Hosted/extractFeatures.ts +++ b/src/Platform/Hosted/extractFeatures.ts @@ -31,11 +31,6 @@ export type Features = { readonly mongoProxyAPIs?: string; readonly enableThroughputCap: boolean; readonly enableHierarchicalKeys: boolean; - readonly enableLegacyMongoShellV1: boolean; - readonly enableLegacyMongoShellV1Debug: boolean; - readonly enableLegacyMongoShellV2: boolean; - readonly enableLegacyMongoShellV2Debug: boolean; - readonly loadLegacyMongoShellFromBE: boolean; readonly enableCopilot: boolean; readonly copilotVersion?: string; readonly disableCopilotPhoenixGateaway: boolean; @@ -43,6 +38,7 @@ export type Features = { readonly copilotChatFixedMonacoEditorHeight: boolean; readonly enablePriorityBasedExecution: boolean; readonly disableConnectionStringLogin: boolean; + readonly enableLegacyMongoShell: boolean; // can be set via both flight and feature flag autoscaleDefault: boolean; @@ -106,11 +102,6 @@ export function extractFeatures(given = new URLSearchParams(window.location.sear notebooksDownBanner: "true" === get("notebooksDownBanner"), enableThroughputCap: "true" === get("enablethroughputcap"), enableHierarchicalKeys: "true" === get("enablehierarchicalkeys"), - enableLegacyMongoShellV1: "true" === get("enablelegacymongoshellv1"), - enableLegacyMongoShellV1Debug: "true" === get("enablelegacymongoshellv1debug"), - enableLegacyMongoShellV2: "true" === get("enablelegacymongoshellv2"), - enableLegacyMongoShellV2Debug: "true" === get("enablelegacymongoshellv2debug"), - loadLegacyMongoShellFromBE: "true" === get("loadlegacymongoshellfrombe"), enableCopilot: "true" === get("enablecopilot", "true"), copilotVersion: get("copilotversion") ?? "v2.0", disableCopilotPhoenixGateaway: "true" === get("disablecopilotphoenixgateaway"), @@ -118,6 +109,7 @@ export function extractFeatures(given = new URLSearchParams(window.location.sear copilotChatFixedMonacoEditorHeight: "true" === get("copilotchatfixedmonacoeditorheight"), enablePriorityBasedExecution: "true" === get("enableprioritybasedexecution"), disableConnectionStringLogin: "true" === get("disableconnectionstringlogin"), + enableLegacyMongoShell: "true" === get("enablelegacymongoshell"), }; } diff --git a/src/Utils/EndpointUtils.ts b/src/Utils/EndpointUtils.ts index c59db4205..f8398568c 100644 --- a/src/Utils/EndpointUtils.ts +++ b/src/Utils/EndpointUtils.ts @@ -82,7 +82,7 @@ export const MongoProxyOutboundIPs: { [key: string]: string[] } = { }; export const allowedMongoProxyEndpoints: ReadonlyArray = [ - MongoProxyEndpoints.Development, + MongoProxyEndpoints.Local, MongoProxyEndpoints.Mpac, MongoProxyEndpoints.Prod, MongoProxyEndpoints.Fairfax, diff --git a/src/hooks/useTabs.ts b/src/hooks/useTabs.ts index 10bc3b144..982768afa 100644 --- a/src/hooks/useTabs.ts +++ b/src/hooks/useTabs.ts @@ -1,3 +1,4 @@ +import { clamp } from "@fluentui/react"; import create, { UseStore } from "zustand"; import * as ViewModels from "../Contracts/ViewModels"; import { CollectionTabKind } from "../Contracts/ViewModels"; @@ -29,6 +30,11 @@ export interface TabsState { setQueryCopilotTabInitialInput: (input: string) => void; setIsTabExecuting: (state: boolean) => void; setIsQueryErrorThrown: (state: boolean) => void; + getCurrentTabIndex: () => number; + selectTabByIndex: (index: number) => void; + selectLeftTab: () => void; + selectRightTab: () => void; + closeActiveTab: () => void; } export enum ReactTabKind { @@ -175,4 +181,44 @@ export const useTabs: UseStore = create((set, get) => ({ setIsQueryErrorThrown: (state: boolean) => { set({ isQueryErrorThrown: state }); }, + getCurrentTabIndex: () => { + const state = get(); + if (state.activeReactTab !== undefined) { + return state.openedReactTabs.indexOf(state.activeReactTab); + } else if (state.activeTab !== undefined) { + const nonReactTabIndex = state.openedTabs.indexOf(state.activeTab); + if (nonReactTabIndex !== -1) { + return state.openedReactTabs.length + nonReactTabIndex; + } + } + + return -1; + }, + selectTabByIndex: (index: number) => { + const state = get(); + const totalTabCount = state.openedReactTabs.length + state.openedTabs.length; + const clampedIndex = clamp(index, totalTabCount - 1, 0); + + if (clampedIndex < state.openedReactTabs.length) { + set({ activeTab: undefined, activeReactTab: state.openedReactTabs[clampedIndex] }); + } else { + set({ activeTab: state.openedTabs[clampedIndex - state.openedReactTabs.length], activeReactTab: undefined }); + } + }, + selectLeftTab: () => { + const state = get(); + state.selectTabByIndex(state.getCurrentTabIndex() - 1); + }, + selectRightTab: () => { + const state = get(); + state.selectTabByIndex(state.getCurrentTabIndex() + 1); + }, + closeActiveTab: () => { + const state = get(); + if (state.activeReactTab !== undefined) { + state.closeReactTab(state.activeReactTab); + } else if (state.activeTab !== undefined) { + state.closeTab(state.activeTab); + } + }, })); diff --git a/web.config b/web.config index 9d9ff2619..4a967e52a 100644 --- a/web.config +++ b/web.config @@ -30,7 +30,7 @@ - +