diff --git a/package-lock.json b/package-lock.json index a7847f3cd..865cd8b0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,25 +65,25 @@ "dev": true }, "@babel/core": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.8.tgz", - "integrity": "sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.9.tgz", + "integrity": "sha512-5ug+SfZCpDAkVp9SFIZAzlW18rlzsOcJGaetCjkySnrXXDUw9AR8cDUm1iByTmdWM6yxX6/zycaV76w3YTF2gw==", "dev": true, "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.7", + "@babel/generator": "^7.17.9", "@babel/helper-compilation-targets": "^7.17.7", "@babel/helper-module-transforms": "^7.17.7", - "@babel/helpers": "^7.17.8", - "@babel/parser": "^7.17.8", + "@babel/helpers": "^7.17.9", + "@babel/parser": "^7.17.9", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", + "@babel/traverse": "^7.17.9", "@babel/types": "^7.17.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", + "json5": "^2.2.1", "semver": "^6.3.0" }, "dependencies": { @@ -117,9 +117,9 @@ } }, "@babel/generator": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz", - "integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.9.tgz", + "integrity": "sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ==", "dev": true, "requires": { "@babel/types": "^7.17.0", @@ -165,23 +165,13 @@ } }, "@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", + "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.16.7", "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.17.0" } }, "@babel/helper-hoist-variables": { @@ -255,20 +245,20 @@ "dev": true }, "@babel/helpers": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.8.tgz", - "integrity": "sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.9.tgz", + "integrity": "sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q==", "dev": true, "requires": { "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", + "@babel/traverse": "^7.17.9", "@babel/types": "^7.17.0" } }, "@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.9.tgz", + "integrity": "sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.16.7", @@ -335,9 +325,9 @@ } }, "@babel/parser": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz", - "integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.9.tgz", + "integrity": "sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -449,9 +439,9 @@ } }, "@babel/runtime-corejs3": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.8.tgz", - "integrity": "sha512-ZbYSUvoSF6dXZmMl/CYTMOvzIFnbGfv4W3SEHYgMvNsFTeLaF2gkGAF4K2ddmtSK4Emej+0aYcnSC6N5dPCXUQ==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.9.tgz", + "integrity": "sha512-WxYHHUWF2uZ7Hp1K+D1xQgbgkGUfA+5UPOegEXGt2Y5SMog/rYCVaifLZDbw8UkNXozEqqrZTy6bglL7xTaCOw==", "requires": { "core-js-pure": "^3.20.2", "regenerator-runtime": "^0.13.4" @@ -476,18 +466,18 @@ } }, "@babel/traverse": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", - "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.9.tgz", + "integrity": "sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw==", "dev": true, "requires": { "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", + "@babel/generator": "^7.17.9", "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", + "@babel/helper-function-name": "^7.17.9", "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.3", + "@babel/parser": "^7.17.9", "@babel/types": "^7.17.0", "debug": "^4.1.0", "globals": "^11.1.0" @@ -1240,9 +1230,9 @@ } }, "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, @@ -1319,9 +1309,9 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, @@ -1435,9 +1425,9 @@ } }, "@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.0.tgz", + "integrity": "sha512-r8aveDbd+rzGP+ykSdF3oPuTVRWRfbBiHl0rVDM2yNEmSMXfkObQLV46b4RnCv3Lra51OlfnZhkkFaDl2MIRaA==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -1453,9 +1443,9 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, @@ -1471,9 +1461,9 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, @@ -1491,9 +1481,9 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, @@ -1511,9 +1501,9 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, @@ -1549,9 +1539,9 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, @@ -1633,9 +1623,9 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, @@ -1653,9 +1643,9 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, @@ -1676,16 +1666,16 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, "@types/node": { - "version": "16.11.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.26.tgz", - "integrity": "sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ==", + "version": "16.11.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.27.tgz", + "integrity": "sha512-C1pD3kgLoZ56Uuy5lhfOxie4aZlA3UMGLX9rXteq4WitEZH6Rl80mwactt9QG0w0gLFlN/kLBTFnGXtDVWvWQw==", "dev": true }, "@types/normalize-package-data": { @@ -1705,16 +1695,16 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, "@types/prettier": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.4.tgz", - "integrity": "sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.0.tgz", + "integrity": "sha512-G/AdOadiZhnJp0jXCaBQU449W2h716OW/EoXeYkCytxKL06X1WCXB4DZpp8TpZ8eyIJVS1cw4lrlkkSYU21cDw==", "dev": true }, "@types/qs": { @@ -1739,9 +1729,9 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, @@ -1754,9 +1744,9 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, @@ -1770,9 +1760,9 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, @@ -1791,9 +1781,9 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, @@ -1807,16 +1797,16 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, "@types/tough-cookie": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.1.tgz", - "integrity": "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", + "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==" }, "@types/underscore": { "version": "1.11.4", @@ -1832,9 +1822,9 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" } } }, @@ -2113,14 +2103,15 @@ "optional": true }, "array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" } }, "array.prototype.map": { @@ -2205,11 +2196,6 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", @@ -2221,9 +2207,9 @@ "integrity": "sha1-0WkB0QzOxZUWwZe5zNiTBom4E7Q=" }, "aws-sdk": { - "version": "2.1107.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1107.0.tgz", - "integrity": "sha512-gZaCm+zSSwjUYSa/cVg63uXhq5w9coT9yA8aTDOYzFkyl19b9H2CCixPeyf7KHtZdGwe3QAG2Oe6Rw0xtoCs+Q==", + "version": "2.1114.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1114.0.tgz", + "integrity": "sha512-LB3q0aHK37GccvNZ4HKtA+0YF94GWYDbJMz3XYoNSEVFOFnLj2DfpkoWlBSnBEJlG9m8GRNssDWs65gQ3MVzDQ==", "requires": { "buffer": "4.9.2", "events": "1.1.1", @@ -3246,9 +3232,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001325", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001325.tgz", - "integrity": "sha512-sB1bZHjseSjDtijV1Hb7PB2Zd58Kyx+n/9EotvZ4Qcz2K3d0lWB8dB4nb8wN/TsOGFq3UuAm0zQZNQ4SoR7TrQ==", + "version": "1.0.30001332", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001332.tgz", + "integrity": "sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw==", "dev": true }, "capture-exit": { @@ -4308,9 +4294,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.4.103", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.103.tgz", - "integrity": "sha512-c/uKWR1Z/W30Wy/sx3dkZoj4BijbXX85QKWu9jJfjho3LBAXNEGAEW3oWiGb+dotA6C6BzCTxL2/aLes7jlUeg==", + "version": "1.4.107", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.107.tgz", + "integrity": "sha512-Huen6taaVrUrSy8o7mGStByba8PfOWWluHNxSHGBrCgEdFVLtvdQDBr9LBCF9Uci8SYxh28QNNMO0oC17wbGAg==", "dev": true }, "elliptic": { @@ -4461,9 +4447,9 @@ } }, "es-abstract": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.2.tgz", - "integrity": "sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w==", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.5.tgz", + "integrity": "sha512-Aa2G2+Rd3b6kxEUKTF4TaW67czBLyAv3z7VOhYRU50YBx+bbsYZ9xQP4lMNazePuFlybXI0V4MruPos7qUo5fA==", "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", @@ -4476,7 +4462,7 @@ "is-callable": "^1.2.4", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", + "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", "is-weakref": "^1.0.2", "object-inspect": "^1.12.0", @@ -4527,6 +4513,15 @@ } } }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -4538,9 +4533,9 @@ } }, "es5-ext": { - "version": "0.10.59", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.59.tgz", - "integrity": "sha512-cOgyhW0tIJyQY1Kfw6Kr0viu9ZlUctVchRMZ7R0HiH3dxTSp5zJDLecwxUqPUrGKMsgBI1wd1FL+d9Jxfi4cLw==", + "version": "0.10.60", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.60.tgz", + "integrity": "sha512-jpKNXIt60htYG59/9FGf2PYT3pwMpnEbNKysU+k/4FGwyGtMotOvcZOuW+EmXXYASRqYSXQfGL5cVIthOTgbkg==", "dev": true, "requires": { "es6-iterator": "^2.0.3", @@ -4900,9 +4895,9 @@ } }, "eslint-plugin-import": { - "version": "2.25.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", - "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", "dev": true, "requires": { "array-includes": "^3.1.4", @@ -4910,14 +4905,14 @@ "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.2", + "eslint-module-utils": "^2.7.3", "has": "^1.0.3", - "is-core-module": "^2.8.0", + "is-core-module": "^2.8.1", "is-glob": "^4.0.3", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.12.0" + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" }, "dependencies": { "doctrine": { @@ -5731,11 +5726,10 @@ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "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==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", + "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", "requires": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" @@ -8095,9 +8089,9 @@ } }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -8471,17 +8465,17 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "json-merger": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/json-merger/-/json-merger-1.1.7.tgz", - "integrity": "sha512-B0k+roIIiZ/vkKkhQQlDf986fFJN5nYn+G6o+zAy7NtRtkFud2GlqsTHl88RA7v4eGKgVQ2sjowSCKbKlCWEKA==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/json-merger/-/json-merger-1.1.9.tgz", + "integrity": "sha512-kbt/SUtX3sMm11PjBG4CjgjIEaYKqWP7xYk8lwIlXUs1EXCZaIHKv9uqSxAs6EPdisQhsa2k64C3I/RVn+562w==", "requires": { - "commander": "^7.2.0", - "fs-extra": "^9.1.0", + "commander": "^9.1.0", + "fs-extra": "^10.0.1", "js-yaml": "^4.1.0", - "json-ptr": "^3.0.0", + "json-ptr": "^3.1.0", "jsonpath": "^1.1.1", "lodash.range": "^3.2.0", - "vm2": "^3.9.5" + "vm2": "^3.9.9" }, "dependencies": { "argparse": { @@ -8490,9 +8484,9 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.1.0.tgz", + "integrity": "sha512-i0/MaqBtdbnJ4XQs4Pmyb+oFQl+q0lsAmokVUH92SlSw4fkeAcG3bVon+Qt7hmtF+u3Het6o4VgrcY3qAoEB6w==" }, "js-yaml": { "version": "4.1.0", @@ -8656,9 +8650,9 @@ } }, "keyv": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.2.1.tgz", - "integrity": "sha512-cAJq5cTfxQdq1DHZEVNpnk4mEvhP+8UP8UQftLtTtJ98beKkRHf+62M0mIDM2u/IWXyP8bmGB375/6uGdSX2MA==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.2.2.tgz", + "integrity": "sha512-uYS0vKTlBIjNCAUqrjlxmruxOEiZxZIHXyp32sdcGmP+ukFrmWUnE//RcPXJH3Vxrni1H2gsQbjHE0bH7MtMQQ==", "requires": { "compress-brotli": "^1.3.6", "json-buffer": "3.0.1" @@ -8679,9 +8673,9 @@ "dev": true }, "knex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/knex/-/knex-1.0.5.tgz", - "integrity": "sha512-EPEQNA0Yn5H5yoqKuCpdGn1EmispA/wS7OMaCAmirHlvHpiZUqcTerD9OU71t3nVLSnuXa0nYcnkUtRSPchsnA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/knex/-/knex-1.0.7.tgz", + "integrity": "sha512-89jxuRATt4qJMb9ZyyaKBy0pQ4d5h7eOFRqiNFnUvsgU+9WZ2eIaZKrAPG1+F3mgu5UloPUnkVE5Yo2sKZUs6Q==", "requires": { "colorette": "2.0.16", "commander": "^9.1.0", @@ -9297,9 +9291,9 @@ } }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "optional": true, "requires": { @@ -9319,9 +9313,9 @@ } }, "node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.3.tgz", + "integrity": "sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw==", "dev": true }, "nodemon": { @@ -10430,14 +10424,14 @@ "dev": true }, "promise.any": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/promise.any/-/promise.any-2.0.3.tgz", - "integrity": "sha512-BTzZue0G5jWLe5YRxn5yEPm8WI+wI/Kp387Y0P70m4S3VPYRBFuQiQ5GEHgFbpWs0RsTk4pGhQKRaFqVoJfsDw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/promise.any/-/promise.any-2.0.4.tgz", + "integrity": "sha512-Yyl7jstFInFv/eIjm8Sj+pyyzHKZJPMr6yOdxxls1xdVatc3kVyVOvMPmqDaKC5kzxjwuMCkn41isweIUf8DPw==", "requires": { "array.prototype.map": "^1.0.4", "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", + "es-abstract": "^1.19.2", "es-aggregate-error": "^1.0.7", "get-intrinsic": "^1.1.1", "iterate-value": "^1.0.2" @@ -11966,9 +11960,9 @@ }, "dependencies": { "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" }, "debug": { "version": "4.3.4", @@ -13139,9 +13133,9 @@ } }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "requires": { "lru-cache": "^6.0.0" diff --git a/src/api.v2/controllers/experimentController.js b/src/api.v2/controllers/experimentController.js index df68fb284..01d0e4b0f 100644 --- a/src/api.v2/controllers/experimentController.js +++ b/src/api.v2/controllers/experimentController.js @@ -53,13 +53,13 @@ const createExperiment = async (req, res) => { const patchExperiment = async (req, res) => { const { params: { experimentId }, body } = req; - logger.log(`Updating experiment ${experimentId}`); + logger.log(`Patching experiment ${experimentId}`); const snakeCasedKeysToPatch = _.mapKeys(body, (_value, key) => _.snakeCase(key)); await new Experiment().updateById(experimentId, snakeCasedKeysToPatch); - logger.log(`Finished updating experiment ${experimentId}`); + logger.log(`Finished patching experiment ${experimentId}`); res.json(OK()); }; @@ -86,6 +86,22 @@ const updateSamplePosition = async (req, res) => { res.json(OK()); }; +const getProcessingConfig = async (req, res) => { + const { params: { experimentId } } = req; + logger.log('Getting processing config for experiment ', experimentId); + + const result = await new Experiment().getProcessingConfig(experimentId); + res.json(result); +}; + +const updateProcessingConfig = async (req, res) => { + const { params: { experimentId }, body } = req; + logger.log('Updating processing config for experiment ', experimentId); + + await new Experiment().updateProcessingConfig(experimentId, body); + res.json(OK()); +}; + const getBackendStatus = async (req, res) => { const { experimentId } = req.params; @@ -114,7 +130,9 @@ module.exports = { getAllExperiments, getExperiment, createExperiment, + updateProcessingConfig, patchExperiment, updateSamplePosition, + getProcessingConfig, getBackendStatus, }; diff --git a/src/api.v2/controllers/sampleController.js b/src/api.v2/controllers/sampleController.js index 03521f2be..e2898a612 100644 --- a/src/api.v2/controllers/sampleController.js +++ b/src/api.v2/controllers/sampleController.js @@ -1,3 +1,5 @@ +const _ = require('lodash'); + const Sample = require('../model/Sample'); const Experiment = require('../model/Experiment'); const MetadataTrack = require('../model/MetadataTrack'); @@ -36,9 +38,25 @@ const createSample = async (req, res) => { res.json(OK()); }; +const patchSample = async (req, res) => { + const { params: { experimentId, sampleId }, body } = req; + + logger.log(`Patching sample ${sampleId} in experiment ${experimentId}`); + + const snakeCasedKeysToPatch = _.mapKeys(body, (_value, key) => _.snakeCase(key)); + + await new Sample().updateById(sampleId, snakeCasedKeysToPatch); + + logger.log(`Finished patching sample ${sampleId} in experiment ${experimentId}`); + + res.json(OK()); +}; + const deleteSample = async (req, res) => { const { params: { experimentId, sampleId } } = req; + logger.log(`Deleting sample ${sampleId} from experiment ${experimentId}`); + await sqlClient.get().transaction(async (trx) => { await new Sample(trx).destroy(sampleId); await new Experiment(trx).deleteSample(experimentId, sampleId); @@ -51,5 +69,6 @@ const deleteSample = async (req, res) => { module.exports = { createSample, + patchSample, deleteSample, }; diff --git a/src/api.v2/model/Experiment.js b/src/api.v2/model/Experiment.js index 667e77f1c..5bff9470e 100644 --- a/src/api.v2/model/Experiment.js +++ b/src/api.v2/model/Experiment.js @@ -143,6 +143,25 @@ class Experiment extends BasicModel { } } + async getProcessingConfig(experimentId) { + const result = await this.findOne({ id: experimentId }); + if (_.isEmpty(result)) { + throw new NotFoundError('Experiment not found'); + } + + return result.processingConfig; + } + + async updateProcessingConfig(experimentId, body) { + const { name: stepName, body: change } = body[0]; + const updateString = JSON.stringify({ [stepName]: change }); + + await this.sql(tableNames.EXPERIMENT) + .update({ + processing_config: this.sql.raw(`processing_config || '${updateString}'::jsonb`), + }).where('id', experimentId); + } + async addSample(experimentId, sampleId) { await this.sql(tableNames.EXPERIMENT) .update({ diff --git a/src/api.v2/model/__mocks__/Experiment.js b/src/api.v2/model/__mocks__/Experiment.js index cfc4dd365..351c445db 100644 --- a/src/api.v2/model/__mocks__/Experiment.js +++ b/src/api.v2/model/__mocks__/Experiment.js @@ -4,6 +4,8 @@ const stub = { getAllExperiments: jest.fn(), getExperimentData: jest.fn(), updateSamplePosition: jest.fn(), + updateProcessingConfig: jest.fn(), + getProcessingConfig: jest.fn(), addSample: jest.fn(), deleteSample: jest.fn(), ...BasicModel, diff --git a/src/api.v2/routes/experiment.js b/src/api.v2/routes/experiment.js index 982a39b53..56bff2043 100644 --- a/src/api.v2/routes/experiment.js +++ b/src/api.v2/routes/experiment.js @@ -1,6 +1,6 @@ const { - createExperiment, getExperiment, patchExperiment, getAllExperiments, - updateSamplePosition, getBackendStatus, + createExperiment, getExperiment, patchExperiment, updateSamplePosition, + getAllExperiments, getProcessingConfig, updateProcessingConfig, getBackendStatus, } = require('../controllers/experimentController'); const { expressAuthenticationOnlyMiddleware, expressAuthorizationMiddleware } = require('../middlewares/authMiddlewares'); @@ -26,6 +26,14 @@ module.exports = { expressAuthorizationMiddleware, (req, res, next) => updateSamplePosition(req, res).catch(next), ], + 'experiment#getProcessingConfig': [ + expressAuthorizationMiddleware, + (req, res, next) => getProcessingConfig(req, res).catch(next), + ], + 'experiment#updateProcessingConfig': [ + expressAuthorizationMiddleware, + (req, res, next) => updateProcessingConfig(req, res).catch(next), + ], 'experiment#getBackendStatus': [ expressAuthorizationMiddleware, (req, res, next) => getBackendStatus(req, res).catch(next), diff --git a/src/api.v2/routes/sample.js b/src/api.v2/routes/sample.js index 9f09cba17..872b8bf6e 100644 --- a/src/api.v2/routes/sample.js +++ b/src/api.v2/routes/sample.js @@ -1,5 +1,6 @@ const { createSample, + patchSample, deleteSample, } = require('../controllers/sampleController'); @@ -10,6 +11,10 @@ module.exports = { expressAuthorizationMiddleware, (req, res, next) => createSample(req, res).catch(next), ], + 'sample#patchSample': [ + expressAuthorizationMiddleware, + (req, res, next) => patchSample(req, res).catch(next), + ], 'sample#deleteSample': [ expressAuthorizationMiddleware, (req, res, next) => deleteSample(req, res).catch(next), diff --git a/src/specs/api.v2.yaml b/src/specs/api.v2.yaml index 39f2ba18f..3205aed86 100644 --- a/src/specs/api.v2.yaml +++ b/src/specs/api.v2.yaml @@ -58,6 +58,71 @@ paths: - env - clusterEnv description: Returns a status on the health of the API. + '/experiments/{experimentId}/processingConfig': + get: + summary: Get processing configuration for an experiment + description: Get processing configuration for an experiment + operationId: getProcessingConfig + x-eov-operation-id: experiment#getProcessingConfig + x-eov-operation-handler: routes/experiment + responses: + '200': + description: get processing configuration for an experiment + content: + application/json: + schema: + $ref: '#/components/schemas/ProcessingConfig' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '401': + description: The request lacks authentication credentials. + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '404': + description: Not found error. + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + + put: + summary: Update processing configuration for an experiment + description: Update processing configuration for an experiment + operationId: updateProcessingConfig + x-eov-operation-id: experiment#updateProcessingConfig + x-eov-operation-handler: routes/experiment + responses: + '200': + description: Processing configuration for an experiment + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPSuccess' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '401': + description: The request lacks authentication credentials. + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '404': + description: Not found error. + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '/experiments': get: summary: Get all experiments @@ -168,7 +233,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ExperimentPatch' + $ref: '#/components/schemas/PatchExperiment' responses: '200': description: Create experiment @@ -283,6 +348,52 @@ paths: application/json: schema: $ref: '#/components/schemas/HTTPError' + patch: + summary: Patch sample + operationId: patchSample + x-eov-operation-id: sample#patchSample + x-eov-operation-handler: routes/sample + requestBody: + content: + application/json: + schema: + type: object + properties: + name: + type: string + additionalProperties: false + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPSuccess' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '401': + description: The request lacks authentication credentials. + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '403': + description: Forbidden request for this user. + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '404': + description: Not found error. + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + delete: summary: Delete sample operationId: deleteSample @@ -371,14 +482,17 @@ paths: application/json: schema: $ref: '#/components/schemas/HTTPError' + components: schemas: CreateExperiment: $ref: './models/experiment-bodies/CreateExperiment.v2.yaml' ExperimentInfo: $ref: './models/experiment-bodies/ExperimentInfo.v2.yaml' - ExperimentPatch: - $ref: './models/experiment-bodies/ExperimentPatch.v2.yaml' + PatchExperiment: + $ref: './models/experiment-bodies/PatchExperiment.v2.yaml' + ProcessingConfig: + $ref: './models/experiment-bodies/ProcessingConfig.v2.yaml' GetAllExperiments: $ref: './models/experiment-bodies/GetAllExperiments.v2.yaml' CreateSample: diff --git a/src/specs/models/experiment-bodies/ExperimentPatch.v2.yaml b/src/specs/models/experiment-bodies/PatchExperiment.v2.yaml similarity index 89% rename from src/specs/models/experiment-bodies/ExperimentPatch.v2.yaml rename to src/specs/models/experiment-bodies/PatchExperiment.v2.yaml index 7ebbd8520..a99124eb1 100644 --- a/src/specs/models/experiment-bodies/ExperimentPatch.v2.yaml +++ b/src/specs/models/experiment-bodies/PatchExperiment.v2.yaml @@ -1,4 +1,4 @@ -title: Experiment Patch +title: Patch Experiment description: The properties of an experiment that can be patched type: object properties: diff --git a/src/specs/models/experiment-bodies/ProcessingConfig.v2.yaml b/src/specs/models/experiment-bodies/ProcessingConfig.v2.yaml index 42288d940..f0c61678d 100644 --- a/src/specs/models/experiment-bodies/ProcessingConfig.v2.yaml +++ b/src/specs/models/experiment-bodies/ProcessingConfig.v2.yaml @@ -25,4 +25,4 @@ required: - numGenesVsNumUmis - doubletScores - dataIntegration - - configureEmbedding \ No newline at end of file + - configureEmbedding diff --git a/tests/api.v2/controllers/experimentController.test.js b/tests/api.v2/controllers/experimentController.test.js index 7a4b796a1..bc689c6ba 100644 --- a/tests/api.v2/controllers/experimentController.test.js +++ b/tests/api.v2/controllers/experimentController.test.js @@ -177,6 +177,38 @@ describe('experimentController', () => { expect(experimentInstance.updateSamplePosition).not.toHaveBeenCalled(); }); + it('getProcessingConfig works', async () => { + const mockReq = { + params: { + experimentId: mockExperiment.id, + }, + }; + experimentInstance.getProcessingConfig.mockImplementationOnce(() => Promise.resolve()); + + await experimentController.getProcessingConfig(mockReq, mockRes); + expect(experimentInstance.getProcessingConfig).toHaveBeenCalledWith(mockExperiment.id); + }); + + it('updateProcessingConfig works', async () => { + const mockReq = { + params: { + experimentId: mockExperiment.id, + }, + body: [{ + name: 'classifier', + body: { + someChangedField: 'a value', + }, + }], + }; + experimentInstance.updateProcessingConfig.mockImplementationOnce(() => Promise.resolve()); + + await experimentController.updateProcessingConfig(mockReq, mockRes); + expect(experimentInstance.updateProcessingConfig).toHaveBeenCalledWith( + mockExperiment.id, mockReq.body, + ); + }); + it('getBackendStatus works correctly', async () => { getPipelineStatus .mockImplementationOnce(() => Promise.resolve('gem2sStatus')) diff --git a/tests/api.v2/controllers/sampleController.test.js b/tests/api.v2/controllers/sampleController.test.js index d8b9db81f..76782ff86 100644 --- a/tests/api.v2/controllers/sampleController.test.js +++ b/tests/api.v2/controllers/sampleController.test.js @@ -123,4 +123,22 @@ describe('sampleController', () => { expect(mockRes.json).not.toHaveBeenCalled(); }); + + it('patchSample works correctly', async () => { + const mockSampleNewName = 'theNewName'; + const mockReq = { + params: { experimentId: mockExperimentId, sampleId: mockSampleId }, + body: { name: mockSampleNewName }, + }; + + sampleInstance.updateById.mockImplementationOnce(() => Promise.resolve()); + + await sampleController.patchSample(mockReq, mockRes); + + expect(sampleInstance.updateById).toHaveBeenCalledWith( + mockSampleId, { name: mockSampleNewName }, + ); + + expect(mockRes.json).toHaveBeenCalledWith(OK()); + }); }); diff --git a/tests/api.v2/mocks/data/getProcessingConfigResponse.json b/tests/api.v2/mocks/data/getProcessingConfigResponse.json new file mode 100644 index 000000000..92714b559 --- /dev/null +++ b/tests/api.v2/mocks/data/getProcessingConfigResponse.json @@ -0,0 +1,342 @@ +[{ + "processingConfig":{ + "classifier": { + "brandNewTries": "changing lmaolxdd" + }, + "doubletScores": { + "auto": true, + "enabled": true, + "filterSettings": { + "binStep": 0.05, + "probabilityThreshold": 0.5 + }, + "330390E9Cdc94C7FB68A0C51Fd059Dda": { + "auto": true, + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + + "enabled": true, + "filterSettings": { + "binStep": 0.05, + "probabilityThreshold": 0.3784758 + }, + "defaultFilterSettings": { + "binStep": 0.05, + "probabilityThreshold": 0.3784758 + } + }, + "46E6484545Dc4Aeb932DE1B43178Fe09": { + "auto": true, + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + + "enabled": true, + "filterSettings": { + "binStep": 0.05, + "probabilityThreshold": 0.4101394 + }, + "defaultFilterSettings": { + "binStep": 0.05, + "probabilityThreshold": 0.4101394 + } + }, + "7Ff6388CCa204325A30C0C29135E1D05": { + "auto": true, + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + + "enabled": true, + "filterSettings": { + "binStep": 0.05, + "probabilityThreshold": 0.7622447 + }, + "defaultFilterSettings": { + "binStep": 0.05, + "probabilityThreshold": 0.7622447 + } + } + }, + "dataIntegration": { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + + "dataIntegration": { + "method": "harmony", + "methodSettings": { + "fastmnn": { + "numGenes": 2000, + "normalisation": "logNormalize" + }, + "harmony": { + "numGenes": 2000, + "normalisation": "logNormalize" + }, + "seuratv4": { + "numGenes": 2000, + "normalisation": "logNormalize" + }, + "unisample": { + "numGenes": 2000, + "normalisation": "logNormalize" + } + } + }, + "dimensionalityReduction": { + "method": "rpca", + "numPCs": 30, + "excludeGeneCategories": [] + } + }, + "numGenesVsNumUmis": { + "enabled": true, + "filterSettings": { + "regressionType": "gam", + "regressionTypeSettings": { + "gam": { + "pLevel": 0.001 + } + } + }, + "330390E9Cdc94C7FB68A0C51Fd059Dda": { + "auto": true, + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + + "enabled": true, + "filterSettings": { + "regressionType": "linear", + "regressionTypeSettings": { + "linear": { + "pLevel": 0.00009066183 + }, + "spline": { + "pLevel": 0.00009066183 + } + } + }, + "defaultFilterSettings": { + "regressionType": "linear", + "regressionTypeSettings": { + "linear": { + "pLevel": 0.00009066183 + }, + "spline": { + "pLevel": 0.00009066183 + } + } + } + }, + "46E6484545Dc4Aeb932DE1B43178Fe09": { + "auto": true, + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + + "enabled": true, + "filterSettings": { + "regressionType": "linear", + "regressionTypeSettings": { + "linear": { + "pLevel": 0.00009075234 + }, + "spline": { + "pLevel": 0.00009075234 + } + } + }, + "defaultFilterSettings": { + "regressionType": "linear", + "regressionTypeSettings": { + "linear": { + "pLevel": 0.00009075234 + }, + "spline": { + "pLevel": 0.00009075234 + } + } + } + }, + "7Ff6388CCa204325A30C0C29135E1D05": { + "auto": true, + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + + "enabled": true, + "filterSettings": { + "regressionType": "linear", + "regressionTypeSettings": { + "linear": { + "pLevel": 0.00009180207 + }, + "spline": { + "pLevel": 0.00009180207 + } + } + }, + "defaultFilterSettings": { + "regressionType": "linear", + "regressionTypeSettings": { + "linear": { + "pLevel": 0.00009180207 + }, + "spline": { + "pLevel": 0.00009180207 + } + } + } + } + }, + "configureEmbedding": { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + + "embeddingSettings": { + "method": "umap", + "methodSettings": { + "tsne": { + "perplexity": 30, + "learningRate": 938.9167 + }, + "umap": { + "distanceMetric": "cosine", + "minimumDistance": 0.3 + } + } + }, + "clusteringSettings": { + "method": "louvain", + "methodSettings": { + "louvain": { + "resolution": 0.8 + } + } + } + }, + "cellSizeDistribution": { + "auto": true, + "enabled": false, + "filterSettings": { + "binStep": 200, + "minCellSize": 1080 + }, + "330390E9Cdc94C7FB68A0C51Fd059Dda": { + "auto": true, + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + + "enabled": false, + "filterSettings": { + "binStep": 200, + "minCellSize": 907 + }, + "defaultFilterSettings": { + "binStep": 200, + "minCellSize": 907 + } + }, + "46E6484545Dc4Aeb932DE1B43178Fe09": { + "auto": true, + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + + "enabled": false, + "filterSettings": { + "binStep": 200, + "minCellSize": 623 + }, + "defaultFilterSettings": { + "binStep": 200, + "minCellSize": 623 + } + }, + "7Ff6388CCa204325A30C0C29135E1D05": { + "auto": true, + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + + "enabled": false, + "filterSettings": { + "binStep": 200, + "minCellSize": 516 + }, + "defaultFilterSettings": { + "binStep": 200, + "minCellSize": 516 + } + } + }, + "mitochondrialContent": { + "auto": true, + "enabled": true, + "filterSettings": { + "method": "absolute_threshold", + "methodSettings": { + "absoluteThreshold": { + "binStep": 0.05, + "maxFraction": 0.1 + } + } + }, + "330390E9Cdc94C7FB68A0C51Fd059Dda": { + "auto": true, + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + + "enabled": true, + "filterSettings": { + "method": "absolute_threshold", + "methodSettings": { + "absoluteThreshold": { + "binStep": 0.05, + "maxFraction": 0.1 + } + } + }, + "defaultFilterSettings": { + "method": "absolute_threshold", + "methodSettings": { + "absoluteThreshold": { + "binStep": 0.05, + "maxFraction": 0.1 + } + } + } + }, + "46E6484545Dc4Aeb932DE1B43178Fe09": { + "auto": true, + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + + "enabled": true, + "filterSettings": { + "method": "absolute_threshold", + "methodSettings": { + "absoluteThreshold": { + "binStep": 0.05, + "maxFraction": 0.1 + } + } + }, + "defaultFilterSettings": { + "method": "absolute_threshold", + "methodSettings": { + "absoluteThreshold": { + "binStep": 0.05, + "maxFraction": 0.1 + } + } + } + }, + "7Ff6388CCa204325A30C0C29135E1D05": { + "auto": true, + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + + "enabled": true, + "filterSettings": { + "method": "absolute_threshold", + "methodSettings": { + "absoluteThreshold": { + "binStep": 0.05, + "maxFraction": 0.1 + } + } + }, + "defaultFilterSettings": { + "method": "absolute_threshold", + "methodSettings": { + "absoluteThreshold": { + "binStep": 0.05, + "maxFraction": 0.1 + } + } + } + } + } + } +}] \ No newline at end of file diff --git a/tests/api.v2/model/Experiment.test.js b/tests/api.v2/model/Experiment.test.js index e3b13d6e4..70a763223 100644 --- a/tests/api.v2/model/Experiment.test.js +++ b/tests/api.v2/model/Experiment.test.js @@ -4,8 +4,9 @@ const sqlClient = require('../../../src/sql/sqlClient'); const helpers = require('../../../src/sql/helpers'); const validSamplesOrderResult = ['sampleId1', 'sampleId2', 'sampleId3', 'sampleId4']; - +const getProcessingConfigResponse = require('../mocks/data/getProcessingConfigResponse'); const { mockSqlClient, mockTrx } = require('../mocks/getMockSqlClient')(); +const BasicModel = require('../../../src/api.v2/model/BasicModel'); jest.mock('../../../src/sql/sqlClient', () => ({ get: jest.fn(() => mockSqlClient), @@ -184,4 +185,26 @@ describe('model/Experiment', () => { expect(mockSqlClient.raw).toHaveBeenCalledWith('samples_order - \'mockSampleId\''); expect(mockSqlClient.where).toHaveBeenCalledWith('id', 'mockExperimentId'); }); + + it('getProcessingConfig works', async () => { + const mockFind = jest.spyOn(BasicModel.prototype, 'find') + .mockImplementationOnce(() => Promise.resolve(getProcessingConfigResponse)); + + const result = await new Experiment().getProcessingConfig(mockExperimentId); + expect(mockFind).toHaveBeenCalledWith({ id: mockExperimentId }); + expect(result).toMatchSnapshot(); + }); + + it('updateProcessingConfig works', async () => { + const mockBody = [{ + name: 'classifier', + body: { + changedField: 'IamChanging so much', + }, + }]; + + mockSqlClient.where.mockImplementationOnce(() => { Promise.resolve(); }); + await new Experiment().updateProcessingConfig(mockExperimentId, mockBody); + expect(mockSqlClient.where).toHaveBeenCalledWith('id', mockExperimentId); + }); }); diff --git a/tests/api.v2/model/__snapshots__/Experiment.test.js.snap b/tests/api.v2/model/__snapshots__/Experiment.test.js.snap index e8fcfd911..27bb6818a 100644 --- a/tests/api.v2/model/__snapshots__/Experiment.test.js.snap +++ b/tests/api.v2/model/__snapshots__/Experiment.test.js.snap @@ -12,6 +12,335 @@ Array [ ] `; +exports[`model/Experiment getProcessingConfig works 1`] = ` +Object { + "cellSizeDistribution": Object { + "330390E9Cdc94C7FB68A0C51Fd059Dda": Object { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + "auto": true, + "defaultFilterSettings": Object { + "binStep": 200, + "minCellSize": 907, + }, + "enabled": false, + "filterSettings": Object { + "binStep": 200, + "minCellSize": 907, + }, + }, + "46E6484545Dc4Aeb932DE1B43178Fe09": Object { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + "auto": true, + "defaultFilterSettings": Object { + "binStep": 200, + "minCellSize": 623, + }, + "enabled": false, + "filterSettings": Object { + "binStep": 200, + "minCellSize": 623, + }, + }, + "7Ff6388CCa204325A30C0C29135E1D05": Object { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + "auto": true, + "defaultFilterSettings": Object { + "binStep": 200, + "minCellSize": 516, + }, + "enabled": false, + "filterSettings": Object { + "binStep": 200, + "minCellSize": 516, + }, + }, + "auto": true, + "enabled": false, + "filterSettings": Object { + "binStep": 200, + "minCellSize": 1080, + }, + }, + "classifier": Object { + "brandNewTries": "changing lmaolxdd", + }, + "configureEmbedding": Object { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + "clusteringSettings": Object { + "method": "louvain", + "methodSettings": Object { + "louvain": Object { + "resolution": 0.8, + }, + }, + }, + "embeddingSettings": Object { + "method": "umap", + "methodSettings": Object { + "tsne": Object { + "learningRate": 938.9167, + "perplexity": 30, + }, + "umap": Object { + "distanceMetric": "cosine", + "minimumDistance": 0.3, + }, + }, + }, + }, + "dataIntegration": Object { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + "dataIntegration": Object { + "method": "harmony", + "methodSettings": Object { + "fastmnn": Object { + "normalisation": "logNormalize", + "numGenes": 2000, + }, + "harmony": Object { + "normalisation": "logNormalize", + "numGenes": 2000, + }, + "seuratv4": Object { + "normalisation": "logNormalize", + "numGenes": 2000, + }, + "unisample": Object { + "normalisation": "logNormalize", + "numGenes": 2000, + }, + }, + }, + "dimensionalityReduction": Object { + "excludeGeneCategories": Array [], + "method": "rpca", + "numPCs": 30, + }, + }, + "doubletScores": Object { + "330390E9Cdc94C7FB68A0C51Fd059Dda": Object { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + "auto": true, + "defaultFilterSettings": Object { + "binStep": 0.05, + "probabilityThreshold": 0.3784758, + }, + "enabled": true, + "filterSettings": Object { + "binStep": 0.05, + "probabilityThreshold": 0.3784758, + }, + }, + "46E6484545Dc4Aeb932DE1B43178Fe09": Object { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + "auto": true, + "defaultFilterSettings": Object { + "binStep": 0.05, + "probabilityThreshold": 0.4101394, + }, + "enabled": true, + "filterSettings": Object { + "binStep": 0.05, + "probabilityThreshold": 0.4101394, + }, + }, + "7Ff6388CCa204325A30C0C29135E1D05": Object { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + "auto": true, + "defaultFilterSettings": Object { + "binStep": 0.05, + "probabilityThreshold": 0.7622447, + }, + "enabled": true, + "filterSettings": Object { + "binStep": 0.05, + "probabilityThreshold": 0.7622447, + }, + }, + "auto": true, + "enabled": true, + "filterSettings": Object { + "binStep": 0.05, + "probabilityThreshold": 0.5, + }, + }, + "mitochondrialContent": Object { + "330390E9Cdc94C7FB68A0C51Fd059Dda": Object { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + "auto": true, + "defaultFilterSettings": Object { + "method": "absolute_threshold", + "methodSettings": Object { + "absoluteThreshold": Object { + "binStep": 0.05, + "maxFraction": 0.1, + }, + }, + }, + "enabled": true, + "filterSettings": Object { + "method": "absolute_threshold", + "methodSettings": Object { + "absoluteThreshold": Object { + "binStep": 0.05, + "maxFraction": 0.1, + }, + }, + }, + }, + "46E6484545Dc4Aeb932DE1B43178Fe09": Object { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + "auto": true, + "defaultFilterSettings": Object { + "method": "absolute_threshold", + "methodSettings": Object { + "absoluteThreshold": Object { + "binStep": 0.05, + "maxFraction": 0.1, + }, + }, + }, + "enabled": true, + "filterSettings": Object { + "method": "absolute_threshold", + "methodSettings": Object { + "absoluteThreshold": Object { + "binStep": 0.05, + "maxFraction": 0.1, + }, + }, + }, + }, + "7Ff6388CCa204325A30C0C29135E1D05": Object { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + "auto": true, + "defaultFilterSettings": Object { + "method": "absolute_threshold", + "methodSettings": Object { + "absoluteThreshold": Object { + "binStep": 0.05, + "maxFraction": 0.1, + }, + }, + }, + "enabled": true, + "filterSettings": Object { + "method": "absolute_threshold", + "methodSettings": Object { + "absoluteThreshold": Object { + "binStep": 0.05, + "maxFraction": 0.1, + }, + }, + }, + }, + "auto": true, + "enabled": true, + "filterSettings": Object { + "method": "absolute_threshold", + "methodSettings": Object { + "absoluteThreshold": Object { + "binStep": 0.05, + "maxFraction": 0.1, + }, + }, + }, + }, + "numGenesVsNumUmis": Object { + "330390E9Cdc94C7FB68A0C51Fd059Dda": Object { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + "auto": true, + "defaultFilterSettings": Object { + "regressionType": "linear", + "regressionTypeSettings": Object { + "linear": Object { + "pLevel": 0.00009066183, + }, + "spline": Object { + "pLevel": 0.00009066183, + }, + }, + }, + "enabled": true, + "filterSettings": Object { + "regressionType": "linear", + "regressionTypeSettings": Object { + "linear": Object { + "pLevel": 0.00009066183, + }, + "spline": Object { + "pLevel": 0.00009066183, + }, + }, + }, + }, + "46E6484545Dc4Aeb932DE1B43178Fe09": Object { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + "auto": true, + "defaultFilterSettings": Object { + "regressionType": "linear", + "regressionTypeSettings": Object { + "linear": Object { + "pLevel": 0.00009075234, + }, + "spline": Object { + "pLevel": 0.00009075234, + }, + }, + }, + "enabled": true, + "filterSettings": Object { + "regressionType": "linear", + "regressionTypeSettings": Object { + "linear": Object { + "pLevel": 0.00009075234, + }, + "spline": Object { + "pLevel": 0.00009075234, + }, + }, + }, + }, + "7Ff6388CCa204325A30C0C29135E1D05": Object { + "apiUrl": "http://api.api-default.svc.cluster.local:3000", + "auto": true, + "defaultFilterSettings": Object { + "regressionType": "linear", + "regressionTypeSettings": Object { + "linear": Object { + "pLevel": 0.00009180207, + }, + "spline": Object { + "pLevel": 0.00009180207, + }, + }, + }, + "enabled": true, + "filterSettings": Object { + "regressionType": "linear", + "regressionTypeSettings": Object { + "linear": Object { + "pLevel": 0.00009180207, + }, + "spline": Object { + "pLevel": 0.00009180207, + }, + }, + }, + }, + "enabled": true, + "filterSettings": Object { + "regressionType": "gam", + "regressionTypeSettings": Object { + "gam": Object { + "pLevel": 0.001, + }, + }, + }, + }, +} +`; + exports[`model/Experiment updateSamplePosition rolls back if the parameters are invalid 1`] = ` Array [ "( diff --git a/tests/api.v2/routes/experiment.test.js b/tests/api.v2/routes/experiment.test.js index 4f2387409..ab9b06462 100644 --- a/tests/api.v2/routes/experiment.test.js +++ b/tests/api.v2/routes/experiment.test.js @@ -9,6 +9,7 @@ const experimentController = require('../../../src/api.v2/controllers/experiment const getExperimentResponse = require('../mocks/data/getExperimentResponse.json'); const getAllExperimentsResponse = require('../mocks/data/getAllExperimentsResponse.json'); +const getProcessingConfigResponse = require('../mocks/data/getProcessingConfigResponse.json'); jest.mock('../../../src/api.v2/controllers/experimentController', () => ({ getAllExperiments: jest.fn(), @@ -16,6 +17,8 @@ jest.mock('../../../src/api.v2/controllers/experimentController', () => ({ createExperiment: jest.fn(), patchExperiment: jest.fn(), updateSamplePosition: jest.fn(), + getProcessingConfig: jest.fn(), + updateProcessingConfig: jest.fn(), })); jest.mock('../../../src/api.v2/middlewares/authMiddlewares'); @@ -234,4 +237,39 @@ describe('tests for experiment route', () => { return done(); }); }); + + it('getProcessingConfig works', async (done) => { + const experimentId = 'experiment-id'; + experimentController.getProcessingConfig.mockImplementationOnce((req, res) => { + res.json(getProcessingConfigResponse); + return Promise.resolve(); + }); + request(app) + .get(`/v2/experiments/${experimentId}/processingConfig`) + .expect(200) + .end((err) => { + if (err) { + return done(err); + } + return done(); + }); + }); + + it('updateProcessingConfig works', async (done) => { + const experimentId = 'experiment-id'; + + experimentController.updateProcessingConfig.mockImplementationOnce((req, res) => { + res.json(OK()); + return Promise.resolve(); + }); + request(app) + .put(`/v2/experiments/${experimentId}/processingConfig`) + .expect(200) + .end((err) => { + if (err) { + return done(err); + } + return done(); + }); + }); }); diff --git a/tests/api.v2/routes/sample.test.js b/tests/api.v2/routes/sample.test.js index 11c118f0a..46fc32691 100644 --- a/tests/api.v2/routes/sample.test.js +++ b/tests/api.v2/routes/sample.test.js @@ -10,6 +10,7 @@ const sampleController = require('../../../src/api.v2/controllers/sampleControll jest.mock('../../../src/api.v2/controllers/sampleController', () => ({ createSample: jest.fn(), deleteSample: jest.fn(), + patchSample: jest.fn(), })); jest.mock('../../../src/api.v2/middlewares/authMiddlewares'); @@ -89,13 +90,8 @@ describe('tests for experiment route', () => { return Promise.resolve(); }); - const invalidExperimentData = { - description: 'experimentDescription', - }; - request(app) .delete(`/v2/experiments/${experimentId}/samples/${sampleId}`) - .send(invalidExperimentData) .expect(200) .end((err) => { if (err) { @@ -106,4 +102,44 @@ describe('tests for experiment route', () => { return done(); }); }); + + it('Patching a sample works', async (done) => { + sampleController.patchSample.mockImplementationOnce((req, res) => { + res.json(OK()); + return Promise.resolve(); + }); + + request(app) + .patch(`/v2/experiments/${experimentId}/samples/${sampleId}`) + .send({ name: 'newSampleName' }) + .expect(200) + .end((err) => { + if (err) { + return done(err); + } + // there is no point testing for the values of the response body + // - if something is wrong, the schema validator will catch it + return done(); + }); + }); + + it('Patching a sample fails if requestBody is invalid', async (done) => { + sampleController.patchSample.mockImplementationOnce((req, res) => { + res.json(OK()); + return Promise.resolve(); + }); + + request(app) + .patch(`/v2/experiments/${experimentId}/samples/${sampleId}`) + .send({ aName: 'newSampleName' }) + .expect(400) + .end((err) => { + if (err) { + return done(err); + } + // there is no point testing for the values of the response body + // - if something is wrong, the schema validator will catch it + return done(); + }); + }); }); diff --git a/tests/api/event-services/work-request.test.js b/tests/api/event-services/work-request.test.js index f1f3089ae..665592953 100644 --- a/tests/api/event-services/work-request.test.js +++ b/tests/api/event-services/work-request.test.js @@ -74,7 +74,7 @@ describe('handleWorkRequest', () => { await handleWorkRequest(workRequest); } catch (e) { expect(e.message).toMatch( - /^Error: distanceMetric must be one of the following/, + /^Error: distanceMetric must be one of the following:/, ); } });