diff --git a/package-lock.json b/package-lock.json index 4900698..6ca2791 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@automapper/classes": "^8.7.7", "@automapper/core": "^8.7.7", "@automapper/nestjs": "^8.7.7", + "@golevelup/nestjs-rabbitmq": "^3.4.0", "@grpc/grpc-js": "^1.8.5", "@grpc/proto-loader": "^0.7.4", "@nestjs/common": "^9.0.0", @@ -898,6 +899,46 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "node_modules/@golevelup/nestjs-common": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-common/-/nestjs-common-1.4.4.tgz", + "integrity": "sha512-NTjtOhHTMuGwiR3lmBQKKaRr++mHQEsh8AxtaH+/EWOYKMK2Cv/8duaH9MQ0hI3TwnouyaA5IRxYR1ZCUyNXOQ==", + "dependencies": { + "nanoid": "^3.2.0" + } + }, + "node_modules/@golevelup/nestjs-discovery": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-discovery/-/nestjs-discovery-3.0.0.tgz", + "integrity": "sha512-ZvkXtobTKxXB1LJanP/l6Z/Fing88IMBr3uabQpU2IWjfsstjh02qYDSU2cfD6CSmNldX5ewW5Pd+SdK2lU8Sw==", + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/@golevelup/nestjs-modules": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-modules/-/nestjs-modules-0.6.1.tgz", + "integrity": "sha512-E0STg8In8fhIivnGDJAA70+XLPHzK5bMTkCnif9FbZ8waTYDQ3T/QQL0h73k+CUFeznn1hmuEW14sNaE+8cd7w==", + "dependencies": { + "lodash": "^4.17.21" + }, + "peerDependencies": { + "@nestjs/common": "^9.x", + "rxjs": "^7.x" + } + }, + "node_modules/@golevelup/nestjs-rabbitmq": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-rabbitmq/-/nestjs-rabbitmq-3.4.0.tgz", + "integrity": "sha512-Ca6JtboZL11qTWl8mFYT3phs+JAhZDhct6/gKbcNEhaaEd3IU6+hEBnjs7LDbYSAIdlpZNODy/rRGSPCFmUYsQ==", + "dependencies": { + "@golevelup/nestjs-common": "^1.4.4", + "@golevelup/nestjs-discovery": "^3.0.0", + "@golevelup/nestjs-modules": "^0.6.1", + "amqp-connection-manager": "^3.0.0", + "amqplib": "^0.8.0" + } + }, "node_modules/@grpc/grpc-js": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.5.tgz", @@ -2769,6 +2810,58 @@ } } }, + "node_modules/amqp-connection-manager": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/amqp-connection-manager/-/amqp-connection-manager-3.9.0.tgz", + "integrity": "sha512-ZKw9ckJKz40Lc2pC7DY0NVocpzPalMaCgv0sBn+N4er2QFAJul9pIiMOm/FsPHeCzB+FulV7PckOpmZvWvewGQ==", + "dependencies": { + "promise-breaker": "^5.0.0" + }, + "engines": { + "node": ">=10.0.0", + "npm": ">5.0.0" + }, + "peerDependencies": { + "amqplib": "*" + } + }, + "node_modules/amqplib": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.8.0.tgz", + "integrity": "sha512-icU+a4kkq4Y1PS4NNi+YPDMwdlbFcZ1EZTQT2nigW3fvOb6AOgUQ9+Mk4ue0Zu5cBg/XpDzB40oH10ysrk2dmA==", + "dependencies": { + "bitsyntax": "~0.1.0", + "bluebird": "^3.7.2", + "buffer-more-ints": "~1.0.0", + "readable-stream": "1.x >=1.1.9", + "safe-buffer": "~5.2.1", + "url-parse": "~1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/amqplib/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/amqplib/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/amqplib/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -3024,6 +3117,37 @@ "node": ">=8" } }, + "node_modules/bitsyntax": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.1.0.tgz", + "integrity": "sha512-ikAdCnrloKmFOugAfxWws89/fPc+nw0OOG1IzIE72uSOg/A3cYptKCjSUhDTuj7fhsJtzkzlv7l3b8PzRHLN0Q==", + "dependencies": { + "buffer-more-ints": "~1.0.0", + "debug": "~2.6.9", + "safe-buffer": "~5.1.2" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/bitsyntax/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/bitsyntax/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/bitsyntax/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -3049,6 +3173,11 @@ "node": ">= 6" } }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -3184,6 +3313,11 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "node_modules/buffer-more-ints": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -6467,6 +6601,17 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -7007,6 +7152,11 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "node_modules/promise-breaker": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/promise-breaker/-/promise-breaker-5.0.0.tgz", + "integrity": "sha512-mgsWQuG4kJ1dtO6e/QlNDLFtMkMzzecsC69aI5hlLEjGHFNpHrvGhFi4LiK5jg2SMQj74/diH+wZliL9LpGsyA==" + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -7093,6 +7243,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -7227,6 +7382,11 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -8370,6 +8530,15 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -9379,6 +9548,42 @@ } } }, + "@golevelup/nestjs-common": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-common/-/nestjs-common-1.4.4.tgz", + "integrity": "sha512-NTjtOhHTMuGwiR3lmBQKKaRr++mHQEsh8AxtaH+/EWOYKMK2Cv/8duaH9MQ0hI3TwnouyaA5IRxYR1ZCUyNXOQ==", + "requires": { + "nanoid": "^3.2.0" + } + }, + "@golevelup/nestjs-discovery": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-discovery/-/nestjs-discovery-3.0.0.tgz", + "integrity": "sha512-ZvkXtobTKxXB1LJanP/l6Z/Fing88IMBr3uabQpU2IWjfsstjh02qYDSU2cfD6CSmNldX5ewW5Pd+SdK2lU8Sw==", + "requires": { + "lodash": "^4.17.15" + } + }, + "@golevelup/nestjs-modules": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-modules/-/nestjs-modules-0.6.1.tgz", + "integrity": "sha512-E0STg8In8fhIivnGDJAA70+XLPHzK5bMTkCnif9FbZ8waTYDQ3T/QQL0h73k+CUFeznn1hmuEW14sNaE+8cd7w==", + "requires": { + "lodash": "^4.17.21" + } + }, + "@golevelup/nestjs-rabbitmq": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-rabbitmq/-/nestjs-rabbitmq-3.4.0.tgz", + "integrity": "sha512-Ca6JtboZL11qTWl8mFYT3phs+JAhZDhct6/gKbcNEhaaEd3IU6+hEBnjs7LDbYSAIdlpZNODy/rRGSPCFmUYsQ==", + "requires": { + "@golevelup/nestjs-common": "^1.4.4", + "@golevelup/nestjs-discovery": "^3.0.0", + "@golevelup/nestjs-modules": "^0.6.1", + "amqp-connection-manager": "^3.0.0", + "amqplib": "^0.8.0" + } + }, "@grpc/grpc-js": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.5.tgz", @@ -10803,6 +11008,50 @@ "ajv": "^8.0.0" } }, + "amqp-connection-manager": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/amqp-connection-manager/-/amqp-connection-manager-3.9.0.tgz", + "integrity": "sha512-ZKw9ckJKz40Lc2pC7DY0NVocpzPalMaCgv0sBn+N4er2QFAJul9pIiMOm/FsPHeCzB+FulV7PckOpmZvWvewGQ==", + "requires": { + "promise-breaker": "^5.0.0" + } + }, + "amqplib": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.8.0.tgz", + "integrity": "sha512-icU+a4kkq4Y1PS4NNi+YPDMwdlbFcZ1EZTQT2nigW3fvOb6AOgUQ9+Mk4ue0Zu5cBg/XpDzB40oH10ysrk2dmA==", + "requires": { + "bitsyntax": "~0.1.0", + "bluebird": "^3.7.2", + "buffer-more-ints": "~1.0.0", + "readable-stream": "1.x >=1.1.9", + "safe-buffer": "~5.2.1", + "url-parse": "~1.5.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + } + } + }, "ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -10988,6 +11237,36 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "bitsyntax": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.1.0.tgz", + "integrity": "sha512-ikAdCnrloKmFOugAfxWws89/fPc+nw0OOG1IzIE72uSOg/A3cYptKCjSUhDTuj7fhsJtzkzlv7l3b8PzRHLN0Q==", + "requires": { + "buffer-more-ints": "~1.0.0", + "debug": "~2.6.9", + "safe-buffer": "~5.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -11012,6 +11291,11 @@ } } }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, "body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -11109,6 +11393,11 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "buffer-more-ints": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" + }, "busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -13568,6 +13857,11 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -13951,6 +14245,11 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "promise-breaker": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/promise-breaker/-/promise-breaker-5.0.0.tgz", + "integrity": "sha512-mgsWQuG4kJ1dtO6e/QlNDLFtMkMzzecsC69aI5hlLEjGHFNpHrvGhFi4LiK5jg2SMQj74/diH+wZliL9LpGsyA==" + }, "prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -14020,6 +14319,11 @@ "side-channel": "^1.0.4" } }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -14118,6 +14422,11 @@ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -14926,6 +15235,15 @@ "punycode": "^2.1.0" } }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index 53702f6..ec675ef 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@automapper/classes": "^8.7.7", "@automapper/core": "^8.7.7", "@automapper/nestjs": "^8.7.7", + "@golevelup/nestjs-rabbitmq": "^3.4.0", "@grpc/grpc-js": "^1.8.5", "@grpc/proto-loader": "^0.7.4", "@nestjs/common": "^9.0.0", diff --git a/src/modules/configuration/adapters/secondaries/configuration.messager.ts b/src/modules/configuration/adapters/secondaries/configuration.messager.ts new file mode 100644 index 0000000..cd3e4bb --- /dev/null +++ b/src/modules/configuration/adapters/secondaries/configuration.messager.ts @@ -0,0 +1,14 @@ +import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; +import { Injectable } from '@nestjs/common'; +import { IMessageBroker } from '../../domain/interfaces/message-broker'; + +@Injectable() +export class ConfigurationMessager extends IMessageBroker { + constructor(private readonly _amqpConnection: AmqpConnection) { + super('configuration'); + } + + publish(routingKey: string, message: string): void { + this._amqpConnection.publish(this.exchange, routingKey, message); + } +} diff --git a/src/modules/configuration/adapters/secondaries/logging.messager.ts b/src/modules/configuration/adapters/secondaries/logging.messager.ts new file mode 100644 index 0000000..00988ec --- /dev/null +++ b/src/modules/configuration/adapters/secondaries/logging.messager.ts @@ -0,0 +1,14 @@ +import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; +import { Injectable } from '@nestjs/common'; +import { IMessageBroker } from '../../domain/interfaces/message-broker'; + +@Injectable() +export class LoggingMessager extends IMessageBroker { + constructor(private readonly _amqpConnection: AmqpConnection) { + super('logging'); + } + + publish(routingKey: string, message: string): void { + this._amqpConnection.publish(this.exchange, routingKey, message); + } +} diff --git a/src/modules/configuration/configuration.module.ts b/src/modules/configuration/configuration.module.ts index 67755e2..e66f072 100644 --- a/src/modules/configuration/configuration.module.ts +++ b/src/modules/configuration/configuration.module.ts @@ -1,8 +1,12 @@ +import { RabbitMQModule } from '@golevelup/nestjs-rabbitmq'; import { Module } from '@nestjs/common'; +import { ConfigModule, ConfigService } from '@nestjs/config'; import { CqrsModule } from '@nestjs/cqrs'; import { DatabaseModule } from '../database/database.module'; import { ConfigurationController } from './adapters/primaries/configuration.controller'; +import { ConfigurationMessager } from './adapters/secondaries/configuration.messager'; import { ConfigurationRepository } from './adapters/secondaries/configuration.repository'; +import { LoggingMessager } from './adapters/secondaries/logging.messager'; import { CreateConfigurationUseCase } from './domain/usecases/create-configuration.usecase'; import { DeleteConfigurationUseCase } from './domain/usecases/delete-configuration.usecase'; import { FindAllConfigurationsUseCase } from './domain/usecases/find-all-configurations.usecase'; @@ -11,12 +15,35 @@ import { UpdateConfigurationUseCase } from './domain/usecases/update-configurati import { ConfigurationProfile } from './mappers/configuration.profile'; @Module({ - imports: [DatabaseModule, CqrsModule], + imports: [ + DatabaseModule, + CqrsModule, + RabbitMQModule.forRootAsync(RabbitMQModule, { + imports: [ConfigModule], + useFactory: async (configService: ConfigService) => ({ + exchanges: [ + { + name: 'configuration', + type: 'topic', + }, + { + name: 'logging', + type: 'topic', + }, + ], + uri: configService.get('RMQ_URI'), + connectionInitOptions: { wait: false }, + }), + inject: [ConfigService], + }), + ], exports: [], controllers: [ConfigurationController], providers: [ ConfigurationProfile, ConfigurationRepository, + ConfigurationMessager, + LoggingMessager, FindAllConfigurationsUseCase, FindConfigurationByUuidUseCase, CreateConfigurationUseCase, diff --git a/src/modules/configuration/domain/interfaces/message-broker.ts b/src/modules/configuration/domain/interfaces/message-broker.ts new file mode 100644 index 0000000..594aa43 --- /dev/null +++ b/src/modules/configuration/domain/interfaces/message-broker.ts @@ -0,0 +1,12 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export abstract class IMessageBroker { + exchange: string; + + constructor(exchange: string) { + this.exchange = exchange; + } + + abstract publish(routingKey: string, message: string): void; +} diff --git a/src/modules/configuration/domain/usecases/create-configuration.usecase.ts b/src/modules/configuration/domain/usecases/create-configuration.usecase.ts index 0ff0ffb..000a463 100644 --- a/src/modules/configuration/domain/usecases/create-configuration.usecase.ts +++ b/src/modules/configuration/domain/usecases/create-configuration.usecase.ts @@ -1,7 +1,9 @@ import { Mapper } from '@automapper/core'; import { InjectMapper } from '@automapper/nestjs'; import { CommandHandler } from '@nestjs/cqrs'; +import { ConfigurationMessager } from '../../adapters/secondaries/configuration.messager'; import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository'; +import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; import { CreateConfigurationCommand } from '../../commands/create-configuration.command'; import { CreateConfigurationRequest } from '../dtos/create-configuration.request'; import { Configuration } from '../entities/configuration'; @@ -10,6 +12,8 @@ import { Configuration } from '../entities/configuration'; export class CreateConfigurationUseCase { constructor( private readonly _repository: ConfigurationRepository, + private readonly _configurationMessager: ConfigurationMessager, + private readonly _loggingMessager: LoggingMessager, @InjectMapper() private readonly _mapper: Mapper, ) {} @@ -22,8 +26,27 @@ export class CreateConfigurationUseCase { try { const configuration = await this._repository.create(entity); + this._configurationMessager.publish( + 'create', + JSON.stringify(configuration), + ); + this._loggingMessager.publish( + 'configuration.create.info', + JSON.stringify(configuration), + ); return configuration; } catch (error) { + let key = 'configuration.create.crit'; + if (error.message.includes('Already exists')) { + key = 'configuration.create.warning'; + } + this._loggingMessager.publish( + key, + JSON.stringify({ + command, + error, + }), + ); throw error; } } diff --git a/src/modules/configuration/domain/usecases/delete-configuration.usecase.ts b/src/modules/configuration/domain/usecases/delete-configuration.usecase.ts index 89472aa..b239dce 100644 --- a/src/modules/configuration/domain/usecases/delete-configuration.usecase.ts +++ b/src/modules/configuration/domain/usecases/delete-configuration.usecase.ts @@ -1,17 +1,38 @@ import { CommandHandler } from '@nestjs/cqrs'; +import { ConfigurationMessager } from '../../adapters/secondaries/configuration.messager'; import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository'; +import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; import { DeleteConfigurationCommand } from '../../commands/delete-configuration.command'; import { Configuration } from '../entities/configuration'; @CommandHandler(DeleteConfigurationCommand) export class DeleteConfigurationUseCase { - constructor(private readonly _repository: ConfigurationRepository) {} + constructor( + private readonly _repository: ConfigurationRepository, + private readonly _configurationMessager: ConfigurationMessager, + private readonly _loggingMessager: LoggingMessager, + ) {} async execute(command: DeleteConfigurationCommand): Promise { try { const configuration = await this._repository.delete(command.uuid); + this._configurationMessager.publish( + 'delete', + JSON.stringify({ uuid: configuration.uuid }), + ); + this._loggingMessager.publish( + 'configuration.delete.info', + JSON.stringify({ uuid: configuration.uuid }), + ); return configuration; } catch (error) { + this._loggingMessager.publish( + 'configuration.delete.crit', + JSON.stringify({ + command, + error, + }), + ); throw error; } } diff --git a/src/modules/configuration/domain/usecases/find-configuration-by-uuid.usecase.ts b/src/modules/configuration/domain/usecases/find-configuration-by-uuid.usecase.ts index c81dde0..15a9756 100644 --- a/src/modules/configuration/domain/usecases/find-configuration-by-uuid.usecase.ts +++ b/src/modules/configuration/domain/usecases/find-configuration-by-uuid.usecase.ts @@ -1,12 +1,16 @@ import { NotFoundException } from '@nestjs/common'; import { QueryHandler } from '@nestjs/cqrs'; import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository'; +import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; import { FindConfigurationByUuidQuery } from '../../queries/find-configuration-by-uuid.query'; import { Configuration } from '../entities/configuration'; @QueryHandler(FindConfigurationByUuidQuery) export class FindConfigurationByUuidUseCase { - constructor(private readonly _repository: ConfigurationRepository) {} + constructor( + private readonly _repository: ConfigurationRepository, + private readonly _loggingMessager: LoggingMessager, + ) {} async execute( findConfigurationByUuid: FindConfigurationByUuidQuery, @@ -18,6 +22,13 @@ export class FindConfigurationByUuidUseCase { if (!configuration) throw new NotFoundException(); return configuration; } catch (error) { + this._loggingMessager.publish( + 'configuration.read.warning', + JSON.stringify({ + query: findConfigurationByUuid, + error, + }), + ); throw error; } } diff --git a/src/modules/configuration/domain/usecases/update-configuration.usecase.ts b/src/modules/configuration/domain/usecases/update-configuration.usecase.ts index 7103c0b..34a8d83 100644 --- a/src/modules/configuration/domain/usecases/update-configuration.usecase.ts +++ b/src/modules/configuration/domain/usecases/update-configuration.usecase.ts @@ -1,7 +1,9 @@ import { Mapper } from '@automapper/core'; import { InjectMapper } from '@automapper/nestjs'; import { CommandHandler } from '@nestjs/cqrs'; +import { ConfigurationMessager } from '../../adapters/secondaries/configuration.messager'; import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository'; +import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; import { UpdateConfigurationCommand } from '../../commands/update-configuration.command'; import { UpdateConfigurationRequest } from '../dtos/update-configuration.request'; import { Configuration } from '../entities/configuration'; @@ -10,6 +12,8 @@ import { Configuration } from '../entities/configuration'; export class UpdateConfigurationUseCase { constructor( private readonly _repository: ConfigurationRepository, + private readonly _configurationMessager: ConfigurationMessager, + private readonly _loggingMessager: LoggingMessager, @InjectMapper() private readonly _mapper: Mapper, ) {} @@ -25,8 +29,23 @@ export class UpdateConfigurationUseCase { command.updateConfigurationRequest.uuid, entity, ); + this._configurationMessager.publish( + 'update', + JSON.stringify(command.updateConfigurationRequest), + ); + this._loggingMessager.publish( + 'configuration.update.info', + JSON.stringify(command.updateConfigurationRequest), + ); return configuration; } catch (error) { + this._loggingMessager.publish( + 'configuration.update.crit', + JSON.stringify({ + command, + error, + }), + ); throw error; } } diff --git a/src/modules/configuration/tests/unit/create-configuration.usecase.spec.ts b/src/modules/configuration/tests/unit/create-configuration.usecase.spec.ts index 107ab34..a59e85b 100644 --- a/src/modules/configuration/tests/unit/create-configuration.usecase.spec.ts +++ b/src/modules/configuration/tests/unit/create-configuration.usecase.spec.ts @@ -1,7 +1,9 @@ import { classes } from '@automapper/classes'; import { AutomapperModule } from '@automapper/nestjs'; import { Test, TestingModule } from '@nestjs/testing'; +import { ConfigurationMessager } from '../../adapters/secondaries/configuration.messager'; import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository'; +import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; import { CreateConfigurationCommand } from '../../commands/create-configuration.command'; import { CreateConfigurationRequest } from '../../domain/dtos/create-configuration.request'; import { Domain } from '../../domain/dtos/domain.enum'; @@ -31,6 +33,10 @@ const mockConfigurationRepository = { }), }; +const mockMessager = { + publish: jest.fn().mockImplementation(), +}; + describe('CreateConfigurationUseCase', () => { let createConfigurationUseCase: CreateConfigurationUseCase; @@ -44,6 +50,14 @@ describe('CreateConfigurationUseCase', () => { }, CreateConfigurationUseCase, ConfigurationProfile, + { + provide: ConfigurationMessager, + useValue: mockMessager, + }, + { + provide: LoggingMessager, + useValue: mockMessager, + }, ], }).compile(); diff --git a/src/modules/configuration/tests/unit/delete-configuration.usecase.spec.ts b/src/modules/configuration/tests/unit/delete-configuration.usecase.spec.ts index eda9c97..35503c5 100644 --- a/src/modules/configuration/tests/unit/delete-configuration.usecase.spec.ts +++ b/src/modules/configuration/tests/unit/delete-configuration.usecase.spec.ts @@ -1,5 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; +import { ConfigurationMessager } from '../../adapters/secondaries/configuration.messager'; import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository'; +import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; import { DeleteConfigurationCommand } from '../../commands/delete-configuration.command'; import { Domain } from '../../domain/dtos/domain.enum'; import { DeleteConfigurationUseCase } from '../../domain/usecases/delete-configuration.usecase'; @@ -43,6 +45,10 @@ const mockConfigurationRepository = { }), }; +const mockMessager = { + publish: jest.fn().mockImplementation(), +}; + describe('DeleteConfigurationUseCase', () => { let deleteConfigurationUseCase: DeleteConfigurationUseCase; @@ -54,6 +60,14 @@ describe('DeleteConfigurationUseCase', () => { useValue: mockConfigurationRepository, }, DeleteConfigurationUseCase, + { + provide: ConfigurationMessager, + useValue: mockMessager, + }, + { + provide: LoggingMessager, + useValue: mockMessager, + }, ], }).compile(); diff --git a/src/modules/configuration/tests/unit/find-configuration-by-uuid.usecase.spec.ts b/src/modules/configuration/tests/unit/find-configuration-by-uuid.usecase.spec.ts index 9d60bae..69f691e 100644 --- a/src/modules/configuration/tests/unit/find-configuration-by-uuid.usecase.spec.ts +++ b/src/modules/configuration/tests/unit/find-configuration-by-uuid.usecase.spec.ts @@ -1,6 +1,8 @@ import { NotFoundException } from '@nestjs/common'; import { Test, TestingModule } from '@nestjs/testing'; +import { ConfigurationMessager } from '../../adapters/secondaries/configuration.messager'; import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository'; +import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; import { Domain } from '../../domain/dtos/domain.enum'; import { FindConfigurationByUuidRequest } from '../../domain/dtos/find-configuration-by-uuid.request'; import { FindConfigurationByUuidUseCase } from '../../domain/usecases/find-configuration-by-uuid.usecase'; @@ -25,6 +27,10 @@ const mockConfigurationRepository = { }), }; +const mockMessager = { + publish: jest.fn().mockImplementation(), +}; + describe('FindConfigurationByUuidUseCase', () => { let findConfigurationByUuidUseCase: FindConfigurationByUuidUseCase; @@ -37,6 +43,14 @@ describe('FindConfigurationByUuidUseCase', () => { useValue: mockConfigurationRepository, }, FindConfigurationByUuidUseCase, + { + provide: ConfigurationMessager, + useValue: mockMessager, + }, + { + provide: LoggingMessager, + useValue: mockMessager, + }, ], }).compile(); diff --git a/src/modules/configuration/tests/unit/update-configuration.usecase.spec.ts b/src/modules/configuration/tests/unit/update-configuration.usecase.spec.ts index fcfb8ad..2609a3f 100644 --- a/src/modules/configuration/tests/unit/update-configuration.usecase.spec.ts +++ b/src/modules/configuration/tests/unit/update-configuration.usecase.spec.ts @@ -1,7 +1,9 @@ import { classes } from '@automapper/classes'; import { AutomapperModule } from '@automapper/nestjs'; import { Test, TestingModule } from '@nestjs/testing'; +import { ConfigurationMessager } from '../../adapters/secondaries/configuration.messager'; import { ConfigurationRepository } from '../../adapters/secondaries/configuration.repository'; +import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; import { UpdateConfigurationCommand } from '../../commands/update-configuration.command'; import { UpdateConfigurationRequest } from '../../domain/dtos/update-configuration.request'; import { Configuration } from '../../domain/entities/configuration'; @@ -33,6 +35,10 @@ const mockConfigurationRepository = { }), }; +const mockMessager = { + publish: jest.fn().mockImplementation(), +}; + describe('UpdateConfigurationUseCase', () => { let updateConfigurationUseCase: UpdateConfigurationUseCase; @@ -47,6 +53,14 @@ describe('UpdateConfigurationUseCase', () => { }, UpdateConfigurationUseCase, ConfigurationProfile, + { + provide: ConfigurationMessager, + useValue: mockMessager, + }, + { + provide: LoggingMessager, + useValue: mockMessager, + }, ], }).compile();