From adab421e5bc1363cda11821e0f7e6ea5f5de6dbd Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Mon, 4 Sep 2023 23:18:42 -0400 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=94=A7=20Added=20a=20list=20torrent?= =?UTF-8?q?=20endpoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 203 ++++++++++++++++++++------------ package.json | 25 ++-- services/qbittorrent.service.ts | 12 +- 3 files changed, 150 insertions(+), 90 deletions(-) diff --git a/package-lock.json b/package-lock.json index b665b57..e4db549 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "threetwo-acquisition-service", "version": "1.0.0", "dependencies": { + "@robertklep/qbittorrent": "^1.0.1", "ioredis": "^5.0.0", "moleculer": "^0.14.27", "moleculer-web": "^0.10.5" @@ -34,7 +35,7 @@ "typescript": "^4.9.3" }, "engines": { - "node": ">= 16.x.x" + "node": ">= 20.x.x" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -153,21 +154,21 @@ } }, "node_modules/@babel/core": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.11.tgz", - "integrity": "sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.15.tgz", + "integrity": "sha512-PtZqMmgRrvj8ruoEOIwVA3yoF91O+Hgw9o7DAUTNBA6Mo2jpu31clx9a7Nz/9JznqetTR6zwfC4L3LAjKQXUwA==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-compilation-targets": "^7.22.10", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.11", - "@babel/parser": "^7.22.11", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.11", - "@babel/types": "^7.22.11", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.22.15", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.22.15", + "@babel/helpers": "^7.22.15", + "@babel/parser": "^7.22.15", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.22.15", + "@babel/types": "^7.22.15", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -198,12 +199,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz", + "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.10", + "@babel/types": "^7.22.15", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -213,13 +214,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", - "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", "browserslist": "^4.21.9", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -272,28 +273,28 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", - "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.15.tgz", + "integrity": "sha512-l1UiX4UyHSFsYt17iQ3Se5pQQZZHa22zyIXURmvkmLCD4t/aU+dvNWHatKac/D9Vm9UES7nvIqHs4jZqKviUmQ==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", "@babel/helper-simple-access": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.5" + "@babel/helper-validator-identifier": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -345,32 +346,32 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", + "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.11.tgz", - "integrity": "sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.15.tgz", + "integrity": "sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==", "dev": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.11", - "@babel/types": "^7.22.11" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -462,9 +463,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.14", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.14.tgz", - "integrity": "sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.15.tgz", + "integrity": "sha512-RWmQ/sklUN9BvGGpCDgSubhHWfAx24XDTDObup4ffvxaYsptOg2P3KG0j+1eWKLxpkX0j0uHxmpq2Z1SP/VhxA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -651,9 +652,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", - "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", + "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" @@ -663,33 +664,33 @@ } }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.11.tgz", - "integrity": "sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.15.tgz", + "integrity": "sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.22.15", "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-function-name": "^7.22.5", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.11", - "@babel/types": "^7.22.11", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -707,13 +708,13 @@ } }, "node_modules/@babel/types": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", - "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", + "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.15", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1322,6 +1323,14 @@ "node": ">= 8" } }, + "node_modules/@robertklep/qbittorrent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@robertklep/qbittorrent/-/qbittorrent-1.0.1.tgz", + "integrity": "sha512-XQDKXN8sVGAIoZa+ZeGA+2p1HlQ2QPkfOtq9CL6za1qYsX2aLakkFVB7n4+ifaQoMvtV7l3RWqa/0lKwoUGR2Q==", + "dependencies": { + "needle": "^3.0.0" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -1467,9 +1476,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.17.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.12.tgz", - "integrity": "sha512-d6xjC9fJ/nSnfDeU0AMDsaJyb1iHsqCSOdi84w4u+SlN/UgQdY5tRhpMzaFYsI4mnpvgTivEaQd0yOUhAtOnEQ==", + "version": "18.17.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.14.tgz", + "integrity": "sha512-ZE/5aB73CyGqgQULkLG87N9GnyGe5TcQjv34pwS8tfBs1IkCh0ASM69mydb2znqd6v0eX+9Ytvk6oQRqu8T1Vw==", "dev": true }, "node_modules/@types/semver": { @@ -1917,15 +1926,15 @@ } }, "node_modules/array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", "is-string": "^1.0.7" }, "engines": { @@ -2854,9 +2863,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.507", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.507.tgz", - "integrity": "sha512-brvPFnO1lu3UYBpBht2qWw9qqhdG4htTjT90/9oOJmxQ77VvTxL9+ghErFqQzgj7n8268ONAmlebqjBR/S+qgA==", + "version": "1.4.508", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.508.tgz", + "integrity": "sha512-FFa8QKjQK/A5QuFr2167myhMesGrhlOBD+3cYNxO9/S4XzHEXesyTD/1/xF644gC8buFPz3ca6G1LOQD0tZrrg==", "dev": true }, "node_modules/emittery": { @@ -5691,6 +5700,41 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, + "node_modules/needle": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz", + "integrity": "sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==", + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -6571,6 +6615,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", diff --git a/package.json b/package.json index 1dcf26a..b95c72b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "threetwo-acquisition-service", "version": "1.0.0", - "description": "My Moleculer-based microservices project", + "description": "", "scripts": { "build": "tsc --project tsconfig.build.json", "dev": "ts-node ./node_modules/moleculer/bin/moleculer-runner.js --config moleculer.config.ts --hot --repl services/**/*.service.ts", @@ -19,34 +19,35 @@ "microservices", "moleculer" ], - "author": "", + "author": "Rishi Ghan", "devDependencies": { + "@jest/globals": "^29.3.1", + "@types/jest": "^29.2.3", + "@types/node": "^18.11.9", "@typescript-eslint/eslint-plugin": "^5.44.0", "@typescript-eslint/parser": "^5.44.0", + "concurrently": "^7.6.0", + "cross-env": "^7.0.3", "eslint": "^8.28.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.0.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-jest": "^27.1.6", - "prettier": "^2.8.0", - "@jest/globals": "^29.3.1", - "@types/jest": "^29.2.3", - "@types/node": "^18.11.9", - "concurrently": "^7.6.0", - "cross-env": "^7.0.3", "jest": "^29.3.1", "moleculer-repl": "^0.7.3", + "prettier": "^2.8.0", "ts-jest": "^29.0.3", "ts-node": "^10.9.1", "typescript": "^4.9.3" }, "dependencies": { - "moleculer-web": "^0.10.5", + "@robertklep/qbittorrent": "^1.0.1", "ioredis": "^5.0.0", - "moleculer": "^0.14.27" -}, + "moleculer": "^0.14.27", + "moleculer-web": "^0.10.5" + }, "engines": { - "node": ">= 16.x.x" + "node": ">= 20.x.x" } } diff --git a/services/qbittorrent.service.ts b/services/qbittorrent.service.ts index 72f7368..9e031d4 100644 --- a/services/qbittorrent.service.ts +++ b/services/qbittorrent.service.ts @@ -1,5 +1,6 @@ "use strict"; import { Context, Service, ServiceBroker, ServiceSchema, Errors } from "moleculer"; +import { qBittorrentClient} from "@robertklep/qbittorrent"; export default class QBittorrentService extends Service { // @ts-ignore @@ -16,9 +17,18 @@ export default class QBittorrentService extends Service { connect: { rest: "POST /connect", handler: async (ctx: Context<{}>) => { - return { foo: "bar" }; + const torrentClient = new qBittorrentClient("http://192.168.1.183:8089", "admin", "adminadmin"); + const info = await torrentClient.torrents.info(); + + return { foo: info }; }, }, + getList : { + rest: "GET /getList", + handler: async (ctx: Context<{}>) => { + + } + } }, methods: {}, }); From 44f612c52fd139954210c9687dd0a00d56b7f065 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Tue, 5 Sep 2023 21:53:42 -0400 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=94=A7=20Fixes=20to=20getList=20endpo?= =?UTF-8?q?int?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/api.service.ts | 273 ++++++++++++++------------------ services/qbittorrent.service.ts | 31 ++-- 2 files changed, 140 insertions(+), 164 deletions(-) diff --git a/services/api.service.ts b/services/api.service.ts index fc864ce..32768f1 100644 --- a/services/api.service.ts +++ b/services/api.service.ts @@ -1,168 +1,141 @@ -import type { Context, ServiceSchema } from "moleculer"; -import type { ApiSettingsSchema, GatewayResponse, IncomingRequest, Route } from "moleculer-web"; +import { IncomingMessage } from "http"; +import { Service, ServiceBroker, Context } from "moleculer"; import ApiGateway from "moleculer-web"; -interface Meta { - userAgent?: string | null | undefined; - user?: object | null | undefined; -} +export default class ApiService extends Service { + public constructor(broker: ServiceBroker) { + super(broker); + // @ts-ignore + this.parseServiceSchema({ + name: "api", + mixins: [ApiGateway], + // More info about settings: https://moleculer.services/docs/0.14/moleculer-web.html + settings: { + port: process.env.PORT || 3060, -const ApiService: ServiceSchema = { - name: "api", - mixins: [ApiGateway], + routes: [ + { + path: "/api", + whitelist: ["**"], + use: [], + mergeParams: true, + cors: { + origin: "*", + methods: [ + "GET", + "OPTIONS", + "POST", + "PUT", + "DELETE", + ], + allowedHeaders: ["*"], + exposedHeaders: [], + credentials: false, + maxAge: 3600, + }, - // More info about settings: https://moleculer.services/docs/0.14/moleculer-web.html - settings: { - // Exposed port - port: process.env.PORT != null ? Number(process.env.PORT) : 3060, + authentication: false, + authorization: false, + autoAliases: true, - // Exposed IP - ip: "0.0.0.0", + aliases: {}, + callingOptions: {}, - // Global Express middlewares. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Middlewares - use: [], + bodyParsers: { + json: { + strict: false, + limit: "1MB", + }, + urlencoded: { + extended: true, + limit: "1MB", + }, + }, + mappingPolicy: "all", // Available values: "all", "restrict" - routes: [ - { - path: "/api", - - whitelist: ["**"], - - // Route-level Express middlewares. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Middlewares - use: [], - - // Enable/disable parameter merging method. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Disable-merging - mergeParams: true, - - // Enable authentication. Implement the logic into `authenticate` method. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Authentication - authentication: false, - - // Enable authorization. Implement the logic into `authorize` method. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Authorization - authorization: false, - - // The auto-alias feature allows you to declare your route alias directly in your services. - // The gateway will dynamically build the full routes from service schema. - autoAliases: true, - - aliases: {}, - - /** - * Before call hook. You can check the request. - * - onBeforeCall( - ctx: Context, - route: Route, - req: IncomingRequest, - res: GatewayResponse, - ): void { - // Set request headers to context meta - ctx.meta.userAgent = req.headers["user-agent"]; - }, */ - - /** - * After call hook. You can modify the data. - * - onAfterCall( - ctx: Context, - route: Route, - req: IncomingRequest, - res: GatewayResponse, - data: unknown, - ): unknown { - // Async function which return with Promise - // return this.doSomething(ctx, res, data); - return data; - }, */ - - // Calling options. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Calling-options - // callingOptions: {}, - - bodyParsers: { - json: { - strict: false, - limit: "1MB", - }, - urlencoded: { - extended: true, - limit: "1MB", + // Enable/disable logging + logging: true, }, + ], + // Do not log client side errors (does not log an error response when the error.code is 400<=X<500) + log4XXResponses: false, + // Logging the request parameters. Set to any log level to enable it. E.g. "info" + logRequestParams: null, + logResponseData: null, + assets: { + folder: "public", + options: {}, }, - - // Mapping policy setting. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Mapping-policy - mappingPolicy: "all", // Available values: "all", "restrict" - - // Enable/disable logging - logging: true, }, - ], - // Do not log client side errors (does not log an error response when the error.code is 400<=X<500) - log4XXResponses: false, - // Logging the request parameters. Set to any log level to enable it. E.g. "info" - logRequestParams: null, - // Logging the response data. Set to any log level to enable it. E.g. "info" - logResponseData: null, + methods: { + /** + * Authenticate the request. It checks the `Authorization` token value in the request header. + * Check the token value & resolve the user by the token. + * The resolved user will be available in `ctx.meta.user` + * + * PLEASE NOTE, IT'S JUST AN EXAMPLE IMPLEMENTATION. DO NOT USE IN PRODUCTION! + * + * @param {Context} ctx + * @param {any} route + * @param {IncomingMessage} req + * @returns {Promise} - // Serve assets from "public" folder. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Serve-static-files - assets: { - folder: "public", + async authenticate (ctx: Context, route: any, req: IncomingMessage): Promise < any > => { + // Read the token from header + const auth = req.headers.authorization; - // Options to `server-static` module - options: {}, - }, - }, + if (auth && auth.startsWith("Bearer")) { + const token = auth.slice(7); - methods: { - /** - * Authenticate the request. It check the `Authorization` token value in the request header. - * Check the token value & resolve the user by the token. - * The resolved user will be available in `ctx.meta.user` - * - * PLEASE NOTE, IT'S JUST AN EXAMPLE IMPLEMENTATION. DO NOT USE IN PRODUCTION! - */ - authenticate( - ctx: Context, - route: Route, - req: IncomingRequest, - ): Record | null { - // Read the token from header - const auth = req.headers.authorization; + // Check the token. Tip: call a service which verify the token. E.g. `accounts.resolveToken` + if (token === "123456") { + // Returns the resolved user. It will be set to the `ctx.meta.user` + return { + id: 1, + name: "John Doe", + }; - if (auth && auth.startsWith("Bearer")) { - const token = auth.slice(7); + } else { + // Invalid token + throw new ApiGateway.Errors.UnAuthorizedError(ApiGateway.Errors.ERR_INVALID_TOKEN, { + error: "Invalid Token", + }); + } - // Check the token. Tip: call a service which verify the token. E.g. `accounts.resolveToken` - if (token === "123456") { - // Returns the resolved user. It will be set to the `ctx.meta.user` - return { id: 1, name: "John Doe" }; - } - // Invalid token - throw new ApiGateway.Errors.UnAuthorizedError( - ApiGateway.Errors.ERR_INVALID_TOKEN, - null, - ); - } else { - // No token. Throw an error or do nothing if anonymous access is allowed. - // throw new E.UnAuthorizedError(E.ERR_NO_TOKEN); - return null; - } - }, + } else { + // No token. Throw an error or do nothing if anonymous access is allowed. + // Throw new E.UnAuthorizedError(E.ERR_NO_TOKEN); + return null; + } + }, + */ + /** + * Authorize the request. Check that the authenticated user has right to access the resource. + * + * PLEASE NOTE, IT'S JUST AN EXAMPLE IMPLEMENTATION. DO NOT USE IN PRODUCTION! + * + * @param {Context} ctx + * @param {Object} route + * @param {IncomingMessage} req + * @returns {Promise} - /** - * Authorize the request. Check that the authenticated user has right to access the resource. - * - * PLEASE NOTE, IT'S JUST AN EXAMPLE IMPLEMENTATION. DO NOT USE IN PRODUCTION! - */ - authorize(ctx: Context, route: Route, req: IncomingRequest) { - // Get the authenticated user. - const { user } = ctx.meta; + async authorize (ctx: Context < any, { + user: string; + } > , route: Record, req: IncomingMessage): Promise < any > => { + // Get the authenticated user. + const user = ctx.meta.user; - // It check the `auth` property in action schema. - if (req.$action.auth === "required" && !user) { - throw new ApiGateway.Errors.UnAuthorizedError("NO_RIGHTS", null); - } - }, - }, -}; - -export default ApiService; + // It check the `auth` property in action schema. + // @ts-ignore + if (req.$action.auth === "required" && !user) { + throw new ApiGateway.Errors.UnAuthorizedError("NO_RIGHTS", { + error: "Unauthorized", + }); + } + }, + */ + }, + }); + } +} diff --git a/services/qbittorrent.service.ts b/services/qbittorrent.service.ts index 9e031d4..137e6fb 100644 --- a/services/qbittorrent.service.ts +++ b/services/qbittorrent.service.ts @@ -1,6 +1,7 @@ "use strict"; import { Context, Service, ServiceBroker, ServiceSchema, Errors } from "moleculer"; -import { qBittorrentClient} from "@robertklep/qbittorrent"; +import { qBittorrentClient } from "@robertklep/qbittorrent"; +const { MoleculerError } = require("moleculer").Errors; export default class QBittorrentService extends Service { // @ts-ignore @@ -14,23 +15,25 @@ export default class QBittorrentService extends Service { mixins: [], hooks: {}, actions: { - connect: { - rest: "POST /connect", - handler: async (ctx: Context<{}>) => { - const torrentClient = new qBittorrentClient("http://192.168.1.183:8089", "admin", "adminadmin"); - const info = await torrentClient.torrents.info(); - return { foo: info }; - }, - }, - getList : { - rest: "GET /getList", + getList: { + rest: "GET /getTorrents", handler: async (ctx: Context<{}>) => { - + return await this.torrentClient.torrents.info() } } - }, - methods: {}, + }, methods: {}, + async started(): Promise { + try { + this.torrentClient = new qBittorrentClient("http://192.168.1.183:8089", "admin", "adminadmin"); + + } catch (err) { + throw new MoleculerError(err, 500, "QBITTORRENT_CONNECTION_ERROR", { + data: err, + }); + } + + } }); } }