From b81d742c6c70d4cf1cab365b0e3efc087441db00 Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Thu, 16 Jun 2022 00:56:51 +0500 Subject: [PATCH 1/3] feat(api): deployment through zipped/compressed file --- api/package-lock.json | 349 +++++++++++++++++++++++++++++++++++ api/package.json | 2 + api/public/swagger.yaml | 3 +- api/src/controllers/drive.ts | 7 +- api/src/routes/api/drive.ts | 24 ++- api/src/utils/extractName.ts | 6 + api/src/utils/file.ts | 4 + api/src/utils/index.ts | 2 + api/src/utils/zipped.ts | 39 ++++ 9 files changed, 432 insertions(+), 4 deletions(-) create mode 100644 api/src/utils/extractName.ts create mode 100644 api/src/utils/zipped.ts diff --git a/api/package-lock.json b/api/package-lock.json index 9da3f1d..5c9ba17 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -25,6 +25,7 @@ "morgan": "^1.10.0", "multer": "^1.4.3", "swagger-ui-express": "4.3.0", + "unzipper": "^0.10.11", "url": "^0.10.3" }, "bin": { @@ -45,6 +46,7 @@ "@types/node": "^15.12.2", "@types/supertest": "^2.0.11", "@types/swagger-ui-express": "^4.1.3", + "@types/unzipper": "^0.10.5", "dotenv": "^10.0.0", "http-headers-validation": "^0.0.1", "jest": "^27.0.6", @@ -2176,6 +2178,15 @@ "integrity": "sha512-MhSa0yylXtVMsyT8qFpHA1DLHj4DvQGH5ntxrhHSh8PxUVNi35Wk+P5hVgqbO2qZqOotqr9jaoPRL+iRjWYm/A==", "dev": true }, + "node_modules/@types/unzipper": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@types/unzipper/-/unzipper-0.10.5.tgz", + "integrity": "sha512-NrLJb29AdnBARpg9S/4ktfPEisbJ0AvaaAr3j7Q1tg8AgcEUsq2HqbNzvgLRoWyRtjzeLEv7vuL39u1mrNIyNA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/webidl-conversions": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz", @@ -2684,6 +2695,26 @@ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" }, + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -2710,6 +2741,11 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==" + }, "node_modules/bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", @@ -2881,6 +2917,22 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", + "engines": { + "node": ">=0.2.0" + } + }, "node_modules/busboy": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", @@ -3011,6 +3063,17 @@ } ] }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" + } + }, "node_modules/chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", @@ -3780,6 +3843,36 @@ "node": ">=10" } }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -4450,6 +4543,42 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/fstream/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==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/fstream/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -7064,6 +7193,11 @@ "node": ">= 0.8.0" } }, + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==" + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -8910,6 +9044,11 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, "node_modules/setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", @@ -9648,6 +9787,14 @@ "node": ">=8" } }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", + "engines": { + "node": "*" + } + }, "node_modules/traverse-chain": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/traverse-chain/-/traverse-chain-0.1.0.tgz", @@ -9926,6 +10073,45 @@ "node": ">= 0.8" } }, + "node_modules/unzipper": { + "version": "0.10.11", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", + "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + } + }, + "node_modules/unzipper/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/unzipper/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/update-notifier": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", @@ -12097,6 +12283,15 @@ "integrity": "sha512-MhSa0yylXtVMsyT8qFpHA1DLHj4DvQGH5ntxrhHSh8PxUVNi35Wk+P5hVgqbO2qZqOotqr9jaoPRL+iRjWYm/A==", "dev": true }, + "@types/unzipper": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@types/unzipper/-/unzipper-0.10.5.tgz", + "integrity": "sha512-NrLJb29AdnBARpg9S/4ktfPEisbJ0AvaaAr3j7Q1tg8AgcEUsq2HqbNzvgLRoWyRtjzeLEv7vuL39u1mrNIyNA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/webidl-conversions": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz", @@ -12500,6 +12695,20 @@ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" }, + "big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==" + }, + "binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", + "requires": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + } + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -12525,6 +12734,11 @@ } } }, + "bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==" + }, "bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", @@ -12651,6 +12865,16 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, + "buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==" + }, + "buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==" + }, "busboy": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", @@ -12748,6 +12972,14 @@ "integrity": "sha512-jUNz+a9blQTQVu4uFcn17uAD8IDizPzQkIKh3LCJfg9BkyIqExYYdyc/ZSlWUSKb8iYiXxKsxbv4zYSvkqjrxw==", "dev": true }, + "chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", + "requires": { + "traverse": ">=0.3.0 <0.4" + } + }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", @@ -13374,6 +13606,38 @@ "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", "dev": true }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "requires": { + "readable-stream": "^2.0.2" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -13896,6 +14160,35 @@ "dev": true, "optional": true }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "requires": { + "minimist": "^1.2.6" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -15839,6 +16132,11 @@ "type-check": "~0.3.2" } }, + "listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==" + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -17219,6 +17517,11 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, "setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", @@ -17785,6 +18088,11 @@ "punycode": "^2.1.1" } }, + "traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==" + }, "traverse-chain": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/traverse-chain/-/traverse-chain-0.1.0.tgz", @@ -17972,6 +18280,47 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, + "unzipper": { + "version": "0.10.11", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", + "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", + "requires": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "update-notifier": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", diff --git a/api/package.json b/api/package.json index c3a0292..b2b0d12 100644 --- a/api/package.json +++ b/api/package.json @@ -64,6 +64,7 @@ "morgan": "^1.10.0", "multer": "^1.4.3", "swagger-ui-express": "4.3.0", + "unzipper": "^0.10.11", "url": "^0.10.3" }, "devDependencies": { @@ -81,6 +82,7 @@ "@types/node": "^15.12.2", "@types/supertest": "^2.0.11", "@types/swagger-ui-express": "^4.1.3", + "@types/unzipper": "^0.10.5", "dotenv": "^10.0.0", "http-headers-validation": "^0.0.1", "jest": "^27.0.6", diff --git a/api/public/swagger.yaml b/api/public/swagger.yaml index dd34dd8..2cd3eb3 100644 --- a/api/public/swagger.yaml +++ b/api/public/swagger.yaml @@ -727,7 +727,8 @@ paths: examples: 'Example 1': value: {status: failure, message: 'Deployment failed!'} - summary: 'Creates/updates files within SASjs Drive using uploaded JSON file.' + description: "Accepts JSON file and zipped compressed JSON file as well.\nCompressed file should only contain one JSON file and should have same name\nas of compressed file e.g. deploy.JSON should be compressed to deploy.JSON.zip\nAny other file or JSON file in zipped will be ignored!" + summary: 'Creates/updates files within SASjs Drive using uploaded JSON/compressed JSON file.' tags: - Drive security: diff --git a/api/src/controllers/drive.ts b/api/src/controllers/drive.ts index d4eee88..3562311 100644 --- a/api/src/controllers/drive.ts +++ b/api/src/controllers/drive.ts @@ -96,7 +96,12 @@ export class DriveController { } /** - * @summary Creates/updates files within SASjs Drive using uploaded JSON file. + * Accepts JSON file and zipped compressed JSON file as well. + * Compressed file should only contain one JSON file and should have same name + * as of compressed file e.g. deploy.JSON should be compressed to deploy.JSON.zip + * Any other file or JSON file in zipped will be ignored! + * + * @summary Creates/updates files within SASjs Drive using uploaded JSON/compressed JSON file. * */ @Example(successDeployResponse) diff --git a/api/src/routes/api/drive.ts b/api/src/routes/api/drive.ts index 71ffa4a..6126946 100644 --- a/api/src/routes/api/drive.ts +++ b/api/src/routes/api/drive.ts @@ -7,9 +7,12 @@ import { multerSingle } from '../../middlewares/multer' import { DriveController } from '../../controllers/' import { deployValidation, + extractJSONFromZip, + extractName, fileBodyValidation, fileParamValidation, - folderParamValidation + folderParamValidation, + isZipFile } from '../../utils' const controller = new DriveController() @@ -49,7 +52,24 @@ driveRouter.post( async (req, res) => { if (!req.file) return res.status(400).send('"file" is not present.') - const fileContent = await readFile(req.file.path) + let fileContent: string = '' + + const { value: zipFile } = isZipFile(req.file) + if (zipFile) { + fileContent = await extractJSONFromZip(zipFile) + const fileInZip = extractName(zipFile.originalname) + + if (!fileContent) { + deleteFile(req.file.path) + return res + .status(400) + .send( + `No content present in ${fileInZip} of compressed file ${zipFile.originalname}` + ) + } + } else { + fileContent = await readFile(req.file.path) + } let jsonContent try { diff --git a/api/src/utils/extractName.ts b/api/src/utils/extractName.ts new file mode 100644 index 0000000..181ed4a --- /dev/null +++ b/api/src/utils/extractName.ts @@ -0,0 +1,6 @@ +import path from 'path' + +export const extractName = (filePath: string) => { + const extension = path.extname(filePath) + return path.basename(filePath, extension) +} diff --git a/api/src/utils/file.ts b/api/src/utils/file.ts index 7df3d9d..f109e0d 100644 --- a/api/src/utils/file.ts +++ b/api/src/utils/file.ts @@ -1,5 +1,6 @@ import path from 'path' import { homedir } from 'os' +import fs from 'fs-extra' export const apiRoot = path.join(__dirname, '..', '..') export const codebaseRoot = path.join(apiRoot, '..') @@ -47,3 +48,6 @@ export const generateUniqueFileName = (fileName: string, extension = '') => new Date().getTime(), extension ].join('') + +export const createReadStream = async (filePath: string) => + fs.createReadStream(filePath) diff --git a/api/src/utils/index.ts b/api/src/utils/index.ts index 09254ba..4fc0f8e 100644 --- a/api/src/utils/index.ts +++ b/api/src/utils/index.ts @@ -3,6 +3,7 @@ export * from './connectDB' export * from './copySASjsCore' export * from './desktopAutoExec' export * from './extractHeaders' +export * from './extractName' export * from './file' export * from './generateAccessToken' export * from './generateAuthCode' @@ -13,6 +14,7 @@ export * from './getPreProgramVariables' export * from './getServerUrl' export * from './instantiateLogger' export * from './isDebugOn' +export * from './zipped' export * from './parseLogToArray' export * from './removeTokensInDB' export * from './saveTokensInDB' diff --git a/api/src/utils/zipped.ts b/api/src/utils/zipped.ts new file mode 100644 index 0000000..925d1b6 --- /dev/null +++ b/api/src/utils/zipped.ts @@ -0,0 +1,39 @@ +import path from 'path' +import unZipper from 'unzipper' +import { extractName } from './extractName' +import { createReadStream } from './file' + +export const isZipFile = ( + file: Express.Multer.File +): { error?: string; value?: Express.Multer.File } => { + const fileExtension = path.extname(file.originalname) + if (fileExtension.toUpperCase() !== '.ZIP') + return { error: `"file" has invalid extension ${fileExtension}` } + + const allowedMimetypes = ['application/zip', 'application/x-zip-compressed'] + + if (!allowedMimetypes.includes(file.mimetype)) + return { error: `"file" has invalid type ${file.mimetype}` } + + return { value: file } +} + +export const extractJSONFromZip = async (zipFile: Express.Multer.File) => { + let fileContent: string = '' + + const fileInZip = extractName(zipFile.originalname) + const zip = (await createReadStream(zipFile.path)).pipe( + unZipper.Parse({ forceStream: true }) + ) + + for await (const entry of zip) { + const fileName = entry.path as string + if (fileName.toUpperCase().endsWith('.JSON') && fileName === fileInZip) { + fileContent = await entry.buffer() + } else { + entry.autodrain() + } + } + + return fileContent +} From 4e7579dc107a7fc39b59debd8403cd0fc54db9d6 Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Thu, 16 Jun 2022 17:58:56 +0500 Subject: [PATCH 2/3] chore(specs): specs added for deploy upload file and zipped file --- api/package-lock.json | 35 ++++ api/package.json | 2 + api/src/routes/api/spec/drive.spec.ts | 286 +++++++++++++++++++++++++- api/src/utils/zipped.ts | 1 + 4 files changed, 319 insertions(+), 5 deletions(-) diff --git a/api/package-lock.json b/api/package-lock.json index 5c9ba17..6be30ee 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -32,6 +32,7 @@ "api": "build/src/server.js" }, "devDependencies": { + "@types/adm-zip": "^0.5.0", "@types/bcryptjs": "^2.4.2", "@types/cookie-parser": "^1.4.2", "@types/cors": "^2.8.12", @@ -47,6 +48,7 @@ "@types/supertest": "^2.0.11", "@types/swagger-ui-express": "^4.1.3", "@types/unzipper": "^0.10.5", + "adm-zip": "^0.5.9", "dotenv": "^10.0.0", "http-headers-validation": "^0.0.1", "jest": "^27.0.6", @@ -1755,6 +1757,15 @@ "yarn": ">=1.9.4" } }, + "node_modules/@types/adm-zip": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.5.0.tgz", + "integrity": "sha512-FCJBJq9ODsQZUNURo5ILAQueuA8WJhRvuihS3ke2iI25mJlfV2LK8jG2Qj2z2AWg8U0FtWWqBHVRetceLskSaw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/babel__core": { "version": "7.1.15", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz", @@ -2283,6 +2294,15 @@ "node": ">=0.4.0" } }, + "node_modules/adm-zip": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz", + "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -11886,6 +11906,15 @@ "validator": "^13.6.0" } }, + "@types/adm-zip": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.5.0.tgz", + "integrity": "sha512-FCJBJq9ODsQZUNURo5ILAQueuA8WJhRvuihS3ke2iI25mJlfV2LK8jG2Qj2z2AWg8U0FtWWqBHVRetceLskSaw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/babel__core": { "version": "7.1.15", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz", @@ -12372,6 +12401,12 @@ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true }, + "adm-zip": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz", + "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==", + "dev": true + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", diff --git a/api/package.json b/api/package.json index b2b0d12..bbd4bbb 100644 --- a/api/package.json +++ b/api/package.json @@ -68,6 +68,7 @@ "url": "^0.10.3" }, "devDependencies": { + "@types/adm-zip": "^0.5.0", "@types/bcryptjs": "^2.4.2", "@types/cookie-parser": "^1.4.2", "@types/cors": "^2.8.12", @@ -83,6 +84,7 @@ "@types/supertest": "^2.0.11", "@types/swagger-ui-express": "^4.1.3", "@types/unzipper": "^0.10.5", + "adm-zip": "^0.5.9", "dotenv": "^10.0.0", "http-headers-validation": "^0.0.1", "jest": "^27.0.6", diff --git a/api/src/routes/api/spec/drive.spec.ts b/api/src/routes/api/spec/drive.spec.ts index 341bd02..e9e6e8a 100644 --- a/api/src/routes/api/spec/drive.spec.ts +++ b/api/src/routes/api/spec/drive.spec.ts @@ -3,6 +3,7 @@ import { Express } from 'express' import mongoose, { Mongoose } from 'mongoose' import { MongoMemoryServer } from 'mongodb-memory-server' import request from 'supertest' +import AdmZip from 'adm-zip' import { folderExists, @@ -72,11 +73,52 @@ describe('drive', () => { }) describe('deploy', () => { - const shouldFailAssertion = async (payload: any) => { - const res = await request(app) - .post('/SASjsApi/drive/deploy') - .auth(accessToken, { type: 'bearer' }) - .send({ appLoc: '/Public', fileTree: payload }) + const makeRequest = async (payload: any, type: string = 'payload') => { + const requestUrl = + type === 'payload' + ? '/SASjsApi/drive/deploy' + : '/SASjsApi/drive/deploy/upload' + + if (type === 'payload') { + return await request(app) + .post(requestUrl) + .auth(accessToken, { type: 'bearer' }) + .send({ appLoc: '/Public', fileTree: payload }) + } + if (type === 'file') { + const deployContents = JSON.stringify({ + appLoc: '/Public', + fileTree: payload + }) + return await request(app) + .post(requestUrl) + .auth(accessToken, { type: 'bearer' }) + .attach('file', Buffer.from(deployContents), 'deploy.json') + } else { + const deployContents = JSON.stringify({ + appLoc: '/Public', + fileTree: payload + }) + const zip = new AdmZip() + // add file directly + zip.addFile( + 'deploy.json', + Buffer.from(deployContents, 'utf8'), + 'entry comment goes here' + ) + + return await request(app) + .post(requestUrl) + .auth(accessToken, { type: 'bearer' }) + .attach('file', zip.toBuffer(), 'deploy.json.zip') + } + } + + const shouldFailAssertion = async ( + payload: any, + type: string = 'payload' + ) => { + const res = await makeRequest(payload, type) expect(res.statusCode).toEqual(400) @@ -176,6 +218,240 @@ describe('drive', () => { await deleteFolder(path.join(getFilesFolder(), 'public')) }) + + describe('upload', () => { + it('should respond with payload example if valid JSON file was not provided', async () => { + await shouldFailAssertion(null, 'file') + await shouldFailAssertion(undefined, 'file') + await shouldFailAssertion('data', 'file') + await shouldFailAssertion({}, 'file') + await shouldFailAssertion( + { + userId: 1, + title: 'test is cool' + }, + 'file' + ) + await shouldFailAssertion( + { + membersWRONG: [] + }, + 'file' + ) + await shouldFailAssertion( + { + members: {} + }, + 'file' + ) + await shouldFailAssertion( + { + members: [ + { + nameWRONG: 'jobs', + type: 'folder', + members: [] + } + ] + }, + 'file' + ) + await shouldFailAssertion( + { + members: [ + { + name: 'jobs', + type: 'WRONG', + members: [] + } + ] + }, + 'file' + ) + await shouldFailAssertion( + { + members: [ + { + name: 'jobs', + type: 'folder', + members: [ + { + name: 'extract', + type: 'folder', + members: [ + { + name: 'makedata1', + type: 'service', + codeWRONG: '%put Hello World!;' + } + ] + } + ] + } + ] + }, + 'file' + ) + }) + + it('should successfully deploy if valid JSON file was provided', async () => { + const deployContents = JSON.stringify({ + appLoc: '/public', + fileTree: getTreeExample() + }) + const res = await request(app) + .post('/SASjsApi/drive/deploy/upload') + .auth(accessToken, { type: 'bearer' }) + .attach('file', Buffer.from(deployContents), 'deploy.json') + + expect(res.statusCode).toEqual(200) + expect(res.text).toEqual( + '{"status":"success","message":"Files deployed successfully to @sasjs/server."}' + ) + await expect(folderExists(getFilesFolder())).resolves.toEqual(true) + + const testJobFolder = path.join( + getFilesFolder(), + 'public', + 'jobs', + 'extract' + ) + await expect(folderExists(testJobFolder)).resolves.toEqual(true) + + const exampleService = getExampleService() + const testJobFile = + path.join(testJobFolder, exampleService.name) + '.sas' + + await expect(fileExists(testJobFile)).resolves.toEqual(true) + + await expect(readFile(testJobFile)).resolves.toEqual( + exampleService.code + ) + + await deleteFolder(path.join(getFilesFolder(), 'public')) + }) + }) + + describe('upload - zipped', () => { + it('should respond with payload example if valid Zipped file was not provided', async () => { + await shouldFailAssertion(null, 'zip') + await shouldFailAssertion(undefined, 'zip') + await shouldFailAssertion('data', 'zip') + await shouldFailAssertion({}, 'zip') + await shouldFailAssertion( + { + userId: 1, + title: 'test is cool' + }, + 'zip' + ) + await shouldFailAssertion( + { + membersWRONG: [] + }, + 'zip' + ) + await shouldFailAssertion( + { + members: {} + }, + 'zip' + ) + await shouldFailAssertion( + { + members: [ + { + nameWRONG: 'jobs', + type: 'folder', + members: [] + } + ] + }, + 'zip' + ) + await shouldFailAssertion( + { + members: [ + { + name: 'jobs', + type: 'WRONG', + members: [] + } + ] + }, + 'zip' + ) + await shouldFailAssertion( + { + members: [ + { + name: 'jobs', + type: 'folder', + members: [ + { + name: 'extract', + type: 'folder', + members: [ + { + name: 'makedata1', + type: 'service', + codeWRONG: '%put Hello World!;' + } + ] + } + ] + } + ] + }, + 'zip' + ) + }) + + it('should successfully deploy if valid Zipped file was provided', async () => { + const deployContents = JSON.stringify({ + appLoc: '/public', + fileTree: getTreeExample() + }) + + const zip = new AdmZip() + // add file directly + zip.addFile( + 'deploy.json', + Buffer.from(deployContents, 'utf8'), + 'entry comment goes here' + ) + const res = await request(app) + .post('/SASjsApi/drive/deploy/upload') + .auth(accessToken, { type: 'bearer' }) + .attach('file', zip.toBuffer(), 'deploy.json.zip') + + expect(res.statusCode).toEqual(200) + expect(res.text).toEqual( + '{"status":"success","message":"Files deployed successfully to @sasjs/server."}' + ) + await expect(folderExists(getFilesFolder())).resolves.toEqual(true) + + const testJobFolder = path.join( + getFilesFolder(), + 'public', + 'jobs', + 'extract' + ) + await expect(folderExists(testJobFolder)).resolves.toEqual(true) + + const exampleService = getExampleService() + const testJobFile = + path.join(testJobFolder, exampleService.name) + '.sas' + + await expect(fileExists(testJobFile)).resolves.toEqual(true) + + await expect(readFile(testJobFile)).resolves.toEqual( + exampleService.code + ) + + await deleteFolder(path.join(getFilesFolder(), 'public')) + }) + }) }) describe('folder', () => { diff --git a/api/src/utils/zipped.ts b/api/src/utils/zipped.ts index 925d1b6..f90f79a 100644 --- a/api/src/utils/zipped.ts +++ b/api/src/utils/zipped.ts @@ -30,6 +30,7 @@ export const extractJSONFromZip = async (zipFile: Express.Multer.File) => { const fileName = entry.path as string if (fileName.toUpperCase().endsWith('.JSON') && fileName === fileInZip) { fileContent = await entry.buffer() + break } else { entry.autodrain() } From 28a6a36bb708b93fb5c2b74d587e9b2e055582be Mon Sep 17 00:00:00 2001 From: Allan Bowe Date: Thu, 16 Jun 2022 13:07:59 +0000 Subject: [PATCH 3/3] fix: npm audit fix to avoid warnings on npm i --- package-lock.json | 122 +++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 62 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1611d8c..5245807 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2770,9 +2770,9 @@ } }, "node_modules/npm": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/npm/-/npm-8.10.0.tgz", - "integrity": "sha512-6oo65q9Quv9mRPGZJufmSH+C/UFdgelwzRXiglT/2mDB50zdy/lZK5dFY0TJ9fJ/8gHqnxcX1NM206KLjTBMlQ==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/npm/-/npm-8.12.2.tgz", + "integrity": "sha512-TArexqro9wpl/6wz6t6YdYhOoiy/UArqiSsSsqI7fieEhQEswDQSJcgt/LuCDjl6mfCDi0So7S2UZ979qLYRPg==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -2858,7 +2858,7 @@ "@npmcli/run-script": "^3.0.1", "abbrev": "~1.1.1", "archy": "~1.0.0", - "cacache": "^16.0.7", + "cacache": "^16.1.1", "chalk": "^4.1.2", "chownr": "^2.0.0", "cli-columns": "^4.0.0", @@ -2883,7 +2883,7 @@ "libnpmsearch": "^5.0.2", "libnpmteam": "^4.0.2", "libnpmversion": "^3.0.1", - "make-fetch-happen": "^10.1.3", + "make-fetch-happen": "^10.1.7", "minipass": "^3.1.6", "minipass-pipeline": "^1.2.4", "mkdirp": "^1.0.4", @@ -2900,7 +2900,7 @@ "npm-user-validate": "^1.0.1", "npmlog": "^6.0.2", "opener": "^1.5.2", - "pacote": "^13.3.0", + "pacote": "^13.6.0", "parse-conflict-json": "^2.0.2", "proc-log": "^2.0.1", "qrcode-terminal": "^0.12.0", @@ -2910,7 +2910,7 @@ "readdir-scoped-modules": "^1.1.0", "rimraf": "^3.0.2", "semver": "^7.3.7", - "ssri": "^9.0.0", + "ssri": "^9.0.1", "tar": "^6.1.11", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", @@ -2965,7 +2965,7 @@ "peer": true }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "5.2.0", + "version": "5.2.1", "dev": true, "inBundle": true, "license": "ISC", @@ -3389,7 +3389,7 @@ } }, "node_modules/npm/node_modules/cacache": { - "version": "16.0.7", + "version": "16.1.1", "dev": true, "inBundle": true, "license": "ISC", @@ -3759,7 +3759,7 @@ } }, "node_modules/npm/node_modules/glob": { - "version": "8.0.1", + "version": "8.0.3", "dev": true, "inBundle": true, "license": "ISC", @@ -3769,8 +3769,7 @@ "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "once": "^1.3.0" }, "engines": { "node": ">=12" @@ -4121,7 +4120,7 @@ } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "4.0.5", + "version": "4.0.6", "dev": true, "inBundle": true, "license": "ISC", @@ -4186,7 +4185,7 @@ } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "4.0.3", + "version": "4.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -4194,7 +4193,7 @@ "dependencies": { "@npmcli/run-script": "^3.0.0", "npm-package-arg": "^9.0.1", - "pacote": "^13.0.5" + "pacote": "^13.5.0" }, "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" @@ -4272,14 +4271,14 @@ } }, "node_modules/npm/node_modules/make-fetch-happen": { - "version": "10.1.3", + "version": "10.1.7", "dev": true, "inBundle": true, "license": "ISC", "peer": true, "dependencies": { "agentkeepalive": "^4.2.1", - "cacache": "^16.0.2", + "cacache": "^16.1.0", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", @@ -4292,7 +4291,7 @@ "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.3", "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.1.1", + "socks-proxy-agent": "^7.0.0", "ssri": "^9.0.0" }, "engines": { @@ -4300,7 +4299,7 @@ } }, "node_modules/npm/node_modules/minimatch": { - "version": "5.0.1", + "version": "5.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -4509,7 +4508,7 @@ } }, "node_modules/npm/node_modules/node-gyp/node_modules/glob": { - "version": "7.2.0", + "version": "7.2.3", "dev": true, "inBundle": true, "license": "ISC", @@ -4518,7 +4517,7 @@ "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -4633,7 +4632,7 @@ } }, "node_modules/npm/node_modules/npm-packlist": { - "version": "5.0.3", + "version": "5.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -4760,7 +4759,7 @@ } }, "node_modules/npm/node_modules/pacote": { - "version": "13.3.0", + "version": "13.6.0", "dev": true, "inBundle": true, "license": "ISC", @@ -4777,7 +4776,7 @@ "minipass": "^3.1.6", "mkdirp": "^1.0.4", "npm-package-arg": "^9.0.0", - "npm-packlist": "^5.0.0", + "npm-packlist": "^5.1.0", "npm-pick-manifest": "^7.0.0", "npm-registry-fetch": "^13.0.1", "proc-log": "^2.0.0", @@ -5009,7 +5008,7 @@ } }, "node_modules/npm/node_modules/rimraf/node_modules/glob": { - "version": "7.2.0", + "version": "7.2.3", "dev": true, "inBundle": true, "license": "ISC", @@ -5018,7 +5017,7 @@ "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -5141,7 +5140,7 @@ } }, "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "6.2.0", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "MIT", @@ -5192,7 +5191,7 @@ "peer": true }, "node_modules/npm/node_modules/ssri": { - "version": "9.0.0", + "version": "9.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -5911,9 +5910,9 @@ "peer": true }, "node_modules/semantic-release": { - "version": "19.0.2", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-19.0.2.tgz", - "integrity": "sha512-7tPonjZxukKECmClhsfyMKDt0GR38feIC2HxgyYaBi+9tDySBLjK/zYDLhh+m6yjnHIJa9eBTKYE7k63ZQcYbw==", + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-19.0.3.tgz", + "integrity": "sha512-HaFbydST1cDKZHuFZxB8DTrBLJVK/AnDExpK0s3EqLIAAUAHUgnd+VSJCUtTYQKkAkauL8G9CucODrVCc7BuAA==", "dev": true, "peer": true, "dependencies": { @@ -9019,9 +9018,9 @@ "peer": true }, "npm": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/npm/-/npm-8.10.0.tgz", - "integrity": "sha512-6oo65q9Quv9mRPGZJufmSH+C/UFdgelwzRXiglT/2mDB50zdy/lZK5dFY0TJ9fJ/8gHqnxcX1NM206KLjTBMlQ==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/npm/-/npm-8.12.2.tgz", + "integrity": "sha512-TArexqro9wpl/6wz6t6YdYhOoiy/UArqiSsSsqI7fieEhQEswDQSJcgt/LuCDjl6mfCDi0So7S2UZ979qLYRPg==", "dev": true, "peer": true, "requires": { @@ -9035,7 +9034,7 @@ "@npmcli/run-script": "^3.0.1", "abbrev": "~1.1.1", "archy": "~1.0.0", - "cacache": "^16.0.7", + "cacache": "^16.1.1", "chalk": "^4.1.2", "chownr": "^2.0.0", "cli-columns": "^4.0.0", @@ -9060,7 +9059,7 @@ "libnpmsearch": "^5.0.2", "libnpmteam": "^4.0.2", "libnpmversion": "^3.0.1", - "make-fetch-happen": "^10.1.3", + "make-fetch-happen": "^10.1.7", "minipass": "^3.1.6", "minipass-pipeline": "^1.2.4", "mkdirp": "^1.0.4", @@ -9077,7 +9076,7 @@ "npm-user-validate": "^1.0.1", "npmlog": "^6.0.2", "opener": "^1.5.2", - "pacote": "^13.3.0", + "pacote": "^13.6.0", "parse-conflict-json": "^2.0.2", "proc-log": "^2.0.1", "qrcode-terminal": "^0.12.0", @@ -9087,7 +9086,7 @@ "readdir-scoped-modules": "^1.1.0", "rimraf": "^3.0.2", "semver": "^7.3.7", - "ssri": "^9.0.0", + "ssri": "^9.0.1", "tar": "^6.1.11", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", @@ -9117,7 +9116,7 @@ "peer": true }, "@npmcli/arborist": { - "version": "5.2.0", + "version": "5.2.1", "bundled": true, "dev": true, "peer": true, @@ -9432,7 +9431,7 @@ } }, "cacache": { - "version": "16.0.7", + "version": "16.1.1", "bundled": true, "dev": true, "peer": true, @@ -9704,7 +9703,7 @@ } }, "glob": { - "version": "8.0.1", + "version": "8.0.3", "bundled": true, "dev": true, "peer": true, @@ -9713,8 +9712,7 @@ "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "once": "^1.3.0" } }, "graceful-fs": { @@ -9970,7 +9968,7 @@ } }, "libnpmexec": { - "version": "4.0.5", + "version": "4.0.6", "bundled": true, "dev": true, "peer": true, @@ -10019,14 +10017,14 @@ } }, "libnpmpack": { - "version": "4.0.3", + "version": "4.1.0", "bundled": true, "dev": true, "peer": true, "requires": { "@npmcli/run-script": "^3.0.0", "npm-package-arg": "^9.0.1", - "pacote": "^13.0.5" + "pacote": "^13.5.0" } }, "libnpmpublish": { @@ -10081,13 +10079,13 @@ "peer": true }, "make-fetch-happen": { - "version": "10.1.3", + "version": "10.1.7", "bundled": true, "dev": true, "peer": true, "requires": { "agentkeepalive": "^4.2.1", - "cacache": "^16.0.2", + "cacache": "^16.1.0", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", @@ -10100,12 +10098,12 @@ "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.3", "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.1.1", + "socks-proxy-agent": "^7.0.0", "ssri": "^9.0.0" } }, "minimatch": { - "version": "5.0.1", + "version": "5.1.0", "bundled": true, "dev": true, "peer": true, @@ -10254,7 +10252,7 @@ } }, "glob": { - "version": "7.2.0", + "version": "7.2.3", "bundled": true, "dev": true, "peer": true, @@ -10262,7 +10260,7 @@ "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -10344,7 +10342,7 @@ } }, "npm-packlist": { - "version": "5.0.3", + "version": "5.1.0", "bundled": true, "dev": true, "peer": true, @@ -10435,7 +10433,7 @@ } }, "pacote": { - "version": "13.3.0", + "version": "13.6.0", "bundled": true, "dev": true, "peer": true, @@ -10451,7 +10449,7 @@ "minipass": "^3.1.6", "mkdirp": "^1.0.4", "npm-package-arg": "^9.0.0", - "npm-packlist": "^5.0.0", + "npm-packlist": "^5.1.0", "npm-pick-manifest": "^7.0.0", "npm-registry-fetch": "^13.0.1", "proc-log": "^2.0.0", @@ -10615,7 +10613,7 @@ } }, "glob": { - "version": "7.2.0", + "version": "7.2.3", "bundled": true, "dev": true, "peer": true, @@ -10623,7 +10621,7 @@ "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -10701,7 +10699,7 @@ } }, "socks-proxy-agent": { - "version": "6.2.0", + "version": "7.0.0", "bundled": true, "dev": true, "peer": true, @@ -10744,7 +10742,7 @@ "peer": true }, "ssri": { - "version": "9.0.0", + "version": "9.0.1", "bundled": true, "dev": true, "peer": true, @@ -11270,9 +11268,9 @@ "peer": true }, "semantic-release": { - "version": "19.0.2", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-19.0.2.tgz", - "integrity": "sha512-7tPonjZxukKECmClhsfyMKDt0GR38feIC2HxgyYaBi+9tDySBLjK/zYDLhh+m6yjnHIJa9eBTKYE7k63ZQcYbw==", + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-19.0.3.tgz", + "integrity": "sha512-HaFbydST1cDKZHuFZxB8DTrBLJVK/AnDExpK0s3EqLIAAUAHUgnd+VSJCUtTYQKkAkauL8G9CucODrVCc7BuAA==", "dev": true, "peer": true, "requires": {