From 7fe9b64f66ad09d2076bef3c867a3d2197e51d4c Mon Sep 17 00:00:00 2001 From: iPromKnight Date: Wed, 7 Feb 2024 14:03:57 +0000 Subject: [PATCH] replace torrent-stream (high vunerabilities) with webtorrent, gives us clean package audit --- src/node/consumer/.eslintrc | 9 +- src/node/consumer/esbuild.js | 14 +- src/node/consumer/package-lock.json | 2160 ++++++++++++----- src/node/consumer/package.json | 5 +- .../consumer/src/jobs/process_torrents_job.ts | 6 +- .../src/lib/helpers/boolean_helpers.ts | 2 +- .../src/lib/helpers/promises_helpers.ts | 10 +- .../src/lib/interfaces/cinemeta_metadata.ts | 7 + .../src/lib/interfaces/kitsu_metadata.ts | 4 + .../src/lib/interfaces/logging_service.ts | 3 + .../src/lib/interfaces/metadata_query.ts | 2 +- .../src/lib/models/composition_root.ts | 1 + .../models/configuration/torrent_config.ts | 1 + .../src/lib/models/inversify_config.ts | 6 +- .../src/lib/services/cache_service.ts | 4 +- .../src/lib/services/metadata_service.ts | 1 + .../lib/services/torrent_download_service.ts | 104 +- .../lib/services/torrent_entries_service.ts | 4 +- .../src/lib/services/torrent_file_service.ts | 35 +- .../services/torrent_processing_service.ts | 5 +- .../lib/services/torrent_subtitle_service.ts | 4 +- .../src/lib/services/tracker_service.ts | 4 +- .../src/repository/database_repository.ts | 22 +- .../consumer/src/repository/models/content.ts | 18 +- .../consumer/src/repository/models/file.ts | 47 +- .../src/repository/models/ingestedPage.ts | 4 +- .../src/repository/models/ingestedTorrent.ts | 36 +- .../src/repository/models/provider.ts | 14 +- .../src/repository/models/skipTorrent.ts | 6 +- .../src/repository/models/subtitle.ts | 25 +- .../consumer/src/repository/models/torrent.ts | 32 +- src/node/consumer/tsconfig.json | 9 +- 32 files changed, 1846 insertions(+), 758 deletions(-) diff --git a/src/node/consumer/.eslintrc b/src/node/consumer/.eslintrc index 85b3aad..e0c8130 100644 --- a/src/node/consumer/.eslintrc +++ b/src/node/consumer/.eslintrc @@ -64,7 +64,12 @@ }, "overrides": [ { - "files": ["*.ts", "*.mts", "*.cts", "*.tsx"], + "files": [ + "*.ts", + "*.mts", + "*.cts", + "*.tsx" + ], "rules": { "@typescript-eslint/explicit-function-return-type": "error", "@typescript-eslint/consistent-type-assertions": [ @@ -73,7 +78,7 @@ "assertionStyle": "as", "objectLiteralTypeAssertions": "never" } - ] + ] } } ] diff --git a/src/node/consumer/esbuild.js b/src/node/consumer/esbuild.js index 938948f..17393df 100644 --- a/src/node/consumer/esbuild.js +++ b/src/node/consumer/esbuild.js @@ -1,14 +1,14 @@ -import { build } from "esbuild"; -import { readFileSync, rmSync } from "fs"; +import {build} from "esbuild"; +import {readFileSync, rmSync} from "fs"; -const { devDependencies } = JSON.parse(readFileSync("./package.json", "utf8")); +const {devDependencies} = JSON.parse(readFileSync("./package.json", "utf8")); const start = Date.now(); try { const outdir = "dist"; - rmSync(outdir, { recursive: true, force: true }); + rmSync(outdir, {recursive: true, force: true}); build({ bundle: true, @@ -27,8 +27,8 @@ try { plugins: [ { name: "populate-import-meta", - setup: ({ onLoad }) => { - onLoad({ filter: new RegExp(`${import.meta.dirname}/src/.*.(js|ts)$`) }, args => { + setup: ({onLoad}) => { + onLoad({filter: new RegExp(`${import.meta.dirname}/src/.*.(js|ts)$`)}, args => { const contents = readFileSync(args.path, "utf8"); const transformedContents = contents @@ -36,7 +36,7 @@ try { .replace(/import\.meta\.filename/g, "__filename") .replace(/import\.meta\.dirname/g, "__dirname"); - return { contents: transformedContents, loader: "default" }; + return {contents: transformedContents, loader: "default"}; }); }, } diff --git a/src/node/consumer/package-lock.json b/src/node/consumer/package-lock.json index eb2f591..88b7ff6 100644 --- a/src/node/consumer/package-lock.json +++ b/src/node/consumer/package-lock.json @@ -10,6 +10,7 @@ "license": "MIT", "dependencies": { "@tirke/node-cache-manager-mongodb": "^1.6.0", + "@types/webtorrent": "^0.109.7", "amqplib": "^0.10.3", "axios": "^1.6.1", "bottleneck": "^2.19.5", @@ -26,8 +27,8 @@ "reflect-metadata": "^0.2.1", "sequelize": "^6.36.0", "sequelize-typescript": "^2.1.6", - "torrent-stream": "^1.2.1", - "user-agents": "^1.0.1444" + "user-agents": "^1.0.1444", + "webtorrent": "^2.1.35" }, "devDependencies": { "@types/amqplib": "^0.10.4", @@ -556,6 +557,87 @@ "node": ">= 8" } }, + "node_modules/@silentbot1/nat-api": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/@silentbot1/nat-api/-/nat-api-0.4.7.tgz", + "integrity": "sha512-6aKXUf4AY6ETBdwjswQOekY6HGj3eZTAUhJx1oYicBqpMJcsphIydEQKp/Hooz6Y070MOI6tD/oT1MgS7bP3Vg==", + "dependencies": { + "chrome-dgram": "^3.0.6", + "cross-fetch-ponyfill": "^1.0.3", + "debug": "^4.3.4", + "default-gateway": "^6.0.3", + "unordered-array-remove": "^1.0.2", + "xml2js": "^0.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@thaunknown/idb-chunk-store": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@thaunknown/idb-chunk-store/-/idb-chunk-store-1.0.2.tgz", + "integrity": "sha512-UdKshbKdHDP+p0XPdv55QiU/scdB9TzvovGFSgXThf+7Yd3noLeYp6KpkYyc1jzUXvI3/8+TemPeASOimrOXvw==", + "dependencies": { + "idb": "^6.1.2", + "queue-microtask": "^1.2.3" + } + }, + "node_modules/@thaunknown/simple-peer": { + "version": "9.12.1", + "resolved": "https://registry.npmjs.org/@thaunknown/simple-peer/-/simple-peer-9.12.1.tgz", + "integrity": "sha512-IS5BXvXx7cvBAzaxqotJf4s4rJCPk5JABLK6Gbnn7oAmWVcH4hYABabBBrvvJtv/xyUqR4v/H3LalnGRJJfEog==", + "dependencies": { + "debug": "^4.3.2", + "err-code": "^3.0.1", + "get-browser-rtc": "^1.1.0", + "queue-microtask": "^1.2.3", + "streamx": "^2.13.2", + "uint8-util": "^2.1.9" + } + }, + "node_modules/@thaunknown/simple-websocket": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@thaunknown/simple-websocket/-/simple-websocket-9.1.1.tgz", + "integrity": "sha512-vzQloFWRodRZqZhpxMpBljFtISesY8TihA8T5uKwCYdj2I1ImMhE/gAeTCPsCGOtxJfGKu3hw/is6MXauWLjOg==", + "dependencies": { + "debug": "^4.3.4", + "queue-microtask": "^1.2.3", + "streamx": "^2.13.2", + "uint8-util": "^2.1.9", + "ws": "^8.12.0" + } + }, + "node_modules/@thaunknown/simple-websocket/node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@thaunknown/thirty-two": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@thaunknown/thirty-two/-/thirty-two-1.0.3.tgz", + "integrity": "sha512-bD6PvWbaf53JC04O7WnGDjqZBDgja/KT2Jd/6I2vJBIy+DLmQfQJZZ/G+16nAkVq1yGTIkO4rfc4RlH0DmEEqA==", + "dependencies": { + "uint8-util": "^2.1.9" + }, + "engines": { + "node": ">=0.2.6" + } + }, "node_modules/@tirke/node-cache-manager-mongodb": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@tirke/node-cache-manager-mongodb/-/node-cache-manager-mongodb-1.6.0.tgz", @@ -579,6 +661,14 @@ "@types/node": "*" } }, + "node_modules/@types/bittorrent-protocol": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/bittorrent-protocol/-/bittorrent-protocol-3.1.6.tgz", + "integrity": "sha512-hqiRctJX9t9kknr6nn0q7UlcWHKvw2gSnPc/4jxt7Q/T0RP9txNv27Djue9ZjCNlAJ+irqAnCxtb+TcSpMyhtA==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.12", "license": "MIT", @@ -601,7 +691,6 @@ "version": "5.1.5", "resolved": "https://registry.npmjs.org/@types/magnet-uri/-/magnet-uri-5.1.5.tgz", "integrity": "sha512-SbBjlb1KGe38VfjRR+mwqztJd/4skhdKkRbIzPDhTy7IAeEAPZWIVSEkZw00Qr4ZZOGR3/ATJ20WWPBfrKHGdA==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -622,12 +711,38 @@ "version": "5.26.5", "license": "MIT" }, + "node_modules/@types/parse-torrent": { + "version": "5.8.7", + "resolved": "https://registry.npmjs.org/@types/parse-torrent/-/parse-torrent-5.8.7.tgz", + "integrity": "sha512-vZtYe450hO+KL7B5fejM8CHWg1LPZKeVXlolphPsWf6n4H0ZUlI6ICbqHoaFmH7JQmU2yRbGgyvqqizdFuGPFQ==", + "dependencies": { + "@types/magnet-uri": "*", + "@types/node": "*", + "@types/parse-torrent-file": "*" + } + }, + "node_modules/@types/parse-torrent-file": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/parse-torrent-file/-/parse-torrent-file-4.0.6.tgz", + "integrity": "sha512-SxqVth0Iv0WuEkqWS5MaY4S4Tlyi+QHkElQREvsUPw2xHcPgKyQ2dkJRRv5vAxmLzH+tnMdOj1Nws/wsenbzUw==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/semver": { "version": "7.5.6", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", "dev": true }, + "node_modules/@types/simple-peer": { + "version": "9.11.8", + "resolved": "https://registry.npmjs.org/@types/simple-peer/-/simple-peer-9.11.8.tgz", + "integrity": "sha512-rvqefdp2rvIA6wiomMgKWd2UZNPe6LM2EV5AuY3CPQJF+8TbdrL5TjYdMf0VAjGczzlkH4l1NjDkihwbj3Xodw==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/stremio-addon-sdk": { "version": "1.6.11", "dev": true, @@ -651,6 +766,17 @@ "version": "7.0.3", "license": "MIT" }, + "node_modules/@types/webtorrent": { + "version": "0.109.7", + "resolved": "https://registry.npmjs.org/@types/webtorrent/-/webtorrent-0.109.7.tgz", + "integrity": "sha512-iDcZkXUMjWOtPpxAWXivs6rpYD++8w4vYJVqGJQKxZh1YxIXm5P3CyHGX735nJ6kFOFXLxD1O0ys/msI1nhRug==", + "dependencies": { + "@types/bittorrent-protocol": "*", + "@types/node": "*", + "@types/parse-torrent": "*", + "@types/simple-peer": "*" + } + }, "node_modules/@types/whatwg-url": { "version": "11.0.4", "license": "MIT", @@ -958,6 +1084,15 @@ "dev": true, "license": "ISC" }, + "node_modules/@webtorrent/http-node": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@webtorrent/http-node/-/http-node-1.3.0.tgz", + "integrity": "sha512-GWZQKroPES4z91Ijx6zsOsb7+USOxjy66s8AoTWg0HiBBdfnbtf9aeh3Uav0MgYn4BL8Q7tVSUpd0gGpngKGEQ==", + "dependencies": { + "freelist": "^1.0.3", + "http-parser-js": "^0.4.3" + } + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -988,10 +1123,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/addr-to-ip-port": { - "version": "1.5.4", - "license": "MIT" - }, "node_modules/ajv": { "version": "6.12.6", "dev": true, @@ -1190,10 +1321,23 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==" + }, "node_modules/balanced-match": { "version": "1.0.2", "license": "MIT" }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -1213,98 +1357,113 @@ } ] }, - "node_modules/bencode": { - "version": "0.7.0", - "license": "MIT" - }, "node_modules/bep53-range": { "version": "1.1.1", "license": "MIT" }, - "node_modules/bitfield": { - "version": "0.1.0", - "license": "-" - }, - "node_modules/bittorrent-dht": { - "version": "6.4.2", - "license": "MIT", - "dependencies": { - "bencode": "^0.7.0", - "buffer-equals": "^1.0.3", - "debug": "^2.2.0", - "inherits": "^2.0.1", - "k-bucket": "^0.6.0", - "k-rpc": "^3.6.0", - "lru": "^2.0.0" - } - }, - "node_modules/bittorrent-dht/node_modules/debug": { - "version": "2.6.9", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/bittorrent-dht/node_modules/debug/node_modules/ms": { + "node_modules/bittorrent-lsd": { "version": "2.0.0", - "license": "MIT" - }, - "node_modules/bittorrent-tracker": { - "version": "7.7.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/bittorrent-lsd/-/bittorrent-lsd-2.0.0.tgz", + "integrity": "sha512-jV+SMTGNY1iGWjf5cPA2HMeA6axuMQRWwWELtsuZ1FmQmZwC74we92nwtDTfv1WMnLx+oqEjWRri42IHjZitSQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { - "bencode": "^0.8.0", - "bn.js": "^4.4.0", - "compact2string": "^1.2.0", - "debug": "^2.0.0", - "hat": "0.0.3", - "inherits": "^2.0.1", - "ip": "^1.0.1", - "minimist": "^1.1.1", - "once": "^1.3.0", - "random-iterate": "^1.0.1", - "run-parallel": "^1.1.2", - "run-series": "^1.0.2", - "simple-get": "^2.0.0", - "simple-peer": "^6.0.0", - "simple-websocket": "^4.0.0", - "string2compact": "^1.1.1", - "uniq": "^1.0.1", - "ws": "^1.0.0", - "xtend": "^4.0.0" + "chrome-dgram": "^3.0.6", + "debug": "^4.2.0" }, - "bin": { - "bittorrent-tracker": "bin/cmd.js" + "engines": { + "node": ">=12.20.0" } }, - "node_modules/bittorrent-tracker/node_modules/bencode": { - "version": "0.8.0", - "license": "MIT" + "node_modules/bittorrent-peerid": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/bittorrent-peerid/-/bittorrent-peerid-1.3.6.tgz", + "integrity": "sha512-VyLcUjVMEOdSpHaCG/7odvCdLbAB1y3l9A2V6WIje24uV7FkJPrQrH/RrlFmKxP89pFVDEnE+YlHaFujlFIZsg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "node_modules/bittorrent-tracker/node_modules/debug": { - "version": "2.6.9", - "license": "MIT", + "node_modules/bittorrent-protocol": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/bittorrent-protocol/-/bittorrent-protocol-4.1.11.tgz", + "integrity": "sha512-8ehCNnnRpxB6wrqDzYdLY6Bx0k1ZcXwHmxfVsU9xljolgfd4jhUq9gKcbnnUj4yR8I5/qHJ5fYVoGIfrmUlAAQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { - "ms": "2.0.0" + "bencode": "^4.0.0", + "bitfield": "^4.1.0", + "debug": "^4.3.4", + "rc4": "^0.1.5", + "streamx": "^2.15.1", + "throughput": "^1.0.1", + "uint8-util": "^2.2.2", + "unordered-array-remove": "^1.0.2" + }, + "engines": { + "node": ">=12.20.0" } }, - "node_modules/bittorrent-tracker/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "license": "MIT" - }, - "node_modules/bittorrent-tracker/node_modules/once": { - "version": "1.4.0", - "license": "ISC", + "node_modules/bittorrent-protocol/node_modules/bencode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/bencode/-/bencode-4.0.0.tgz", + "integrity": "sha512-AERXw18df0pF3ziGOCyUjqKZBVNH8HV3lBxnx5w0qtgMIk4a1wb9BkcCQbkp9Zstfrn/dzRwl7MmUHHocX3sRQ==", "dependencies": { - "wrappy": "1" + "uint8-util": "^2.2.2" + }, + "engines": { + "node": ">=12.20.0" } }, - "node_modules/bn.js": { - "version": "4.12.0", - "license": "MIT" + "node_modules/bittorrent-protocol/node_modules/bitfield": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/bitfield/-/bitfield-4.2.0.tgz", + "integrity": "sha512-kUTatQb/mBd8uhvdLrUkouGDBUQiJaIOvPlptUwOWp6MFqih4d1MiVf0m3ATxfZSzu+LjW/awFeABltYa62uIA==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } }, - "node_modules/bncode": { - "version": "0.5.3" + "node_modules/block-iterator": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/block-iterator/-/block-iterator-1.1.1.tgz", + "integrity": "sha512-DrjdVWZemVO4iBf4tiOXjUrY5cNesjzy0t7sIiu2rdl8cOCHRxAgKjSJFc3vBZYYMMmshUAxajl8QQh/uxXTKQ==" }, "node_modules/boolbase": { "version": "1.0.0", @@ -1364,40 +1523,6 @@ "ieee754": "^1.2.1" } }, - "node_modules/buffer-alloc": { - "version": "1.2.0", - "license": "MIT", - "dependencies": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "node_modules/buffer-alloc-unsafe": { - "version": "1.1.0", - "license": "MIT" - }, - "node_modules/buffer-equal": { - "version": "0.0.1", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/buffer-equals": { - "version": "1.0.4", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/buffer-fill": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "license": "MIT" - }, "node_modules/buffer-more-ints": { "version": "1.0.0", "license": "MIT" @@ -1409,6 +1534,53 @@ "node": ">=4" } }, + "node_modules/bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/cache-chunk-store": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/cache-chunk-store/-/cache-chunk-store-3.2.2.tgz", + "integrity": "sha512-2lJdWbgHFFxcSth9s2wpId3CR3v1YC63KjP4T9WhpW7LWlY7Hiiei3QwwqzkWqlJTfR8lSy9F5kRQECeyj+yQA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "lru": "^3.1.0", + "queue-microtask": "^1.2.3" + } + }, + "node_modules/cache-chunk-store/node_modules/lru": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lru/-/lru-3.1.0.tgz", + "integrity": "sha512-5OUtoiVIGU4VXBOshidmtOsvBIvcQR6FD/RzWSvaeHyxCGB+PCUCu+52lqMfdc0h/2CLvHhZS4TwUmMQrrMbBQ==", + "dependencies": { + "inherits": "^2.0.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/cache-manager": { "version": "5.4.0", "license": "MIT", @@ -1538,6 +1710,22 @@ "inherits": "^2.0.1" } }, + "node_modules/chunk-store-iterator": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chunk-store-iterator/-/chunk-store-iterator-1.0.3.tgz", + "integrity": "sha512-JcSaB5h3wQstQKnaJi8sET40f0m+6Kh4mhKIr05lrWKi+EiQzn6XUoi6LipgRGMqXWNZZJaMz2tH4aeg4ptBDA==", + "dependencies": { + "block-iterator": "^1.1.1" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/color-convert": { "version": "2.0.1", "dev": true, @@ -1585,9 +1773,111 @@ "version": "1.0.3", "license": "MIT" }, + "node_modules/cpus": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cpus/-/cpus-1.0.3.tgz", + "integrity": "sha512-PXHBvGLuL69u55IkLa5e5838fLhIMHxmkV4ge42a8alGyn7BtawYgI0hQ849EedvtHIOLNNH3i6eQU1BiE9SUA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/create-torrent": { + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/create-torrent/-/create-torrent-6.0.16.tgz", + "integrity": "sha512-oO0M9KMPwEk825G7vLLUttgxBl/zwlsNdtPc9RnjFS6gQeq8sqJqlBmHcIA8sDwaYbu0mpIcARPokUgsRxjiaw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "bencode": "^4.0.0", + "block-iterator": "^1.1.1", + "fast-readable-async-iterator": "^2.0.0", + "is-file": "^1.0.0", + "join-async-iterator": "^1.1.1", + "junk": "^4.0.1", + "minimist": "^1.2.8", + "once": "^1.4.0", + "piece-length": "^2.0.1", + "queue-microtask": "^1.2.3", + "run-parallel": "^1.2.0", + "uint8-util": "^2.2.2" + }, + "bin": { + "create-torrent": "bin/cmd.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/create-torrent/node_modules/bencode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/bencode/-/bencode-4.0.0.tgz", + "integrity": "sha512-AERXw18df0pF3ziGOCyUjqKZBVNH8HV3lBxnx5w0qtgMIk4a1wb9BkcCQbkp9Zstfrn/dzRwl7MmUHHocX3sRQ==", + "dependencies": { + "uint8-util": "^2.2.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/create-torrent/node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/cross-fetch-ponyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cross-fetch-ponyfill/-/cross-fetch-ponyfill-1.0.3.tgz", + "integrity": "sha512-uOBkDhUAGAbx/FEzNKkOfx3w57H8xReBBXoZvUnOKTI0FW0Xvrj3GrYv2iZXUqlffC1LMGfQzhmBM/ke+6eTDA==", + "dependencies": { + "abort-controller": "^3.0.0", + "node-fetch": "^3.3.0" + } + }, + "node_modules/cross-fetch-ponyfill/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -1622,8 +1912,13 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/cyclist": { - "version": "0.1.1" + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "engines": { + "node": ">= 12" + } }, "node_modules/dateformat": { "version": "4.6.3", @@ -1653,16 +1948,6 @@ "version": "2.1.2", "license": "MIT" }, - "node_modules/decompress-response": { - "version": "3.3.0", - "license": "MIT", - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/deep-is": { "version": "0.1.4", "dev": true, @@ -1675,6 +1960,17 @@ "node": ">=16.0.0" } }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/define-data-property": { "version": "1.1.1", "dev": true, @@ -1789,13 +2085,6 @@ "version": "2.0.6", "license": "MIT" }, - "node_modules/end-of-stream": { - "version": "0.1.5", - "license": "MIT", - "dependencies": { - "once": "~1.3.0" - } - }, "node_modules/entities": { "version": "4.5.0", "license": "BSD-2-Clause", @@ -1806,6 +2095,11 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/err-code": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz", + "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==" + }, "node_modules/es-abstract": { "version": "1.22.3", "dev": true, @@ -1933,6 +2227,11 @@ "@esbuild/win32-x64": "0.20.0" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "dev": true, @@ -2208,6 +2507,28 @@ "node": ">=0.8.x" } }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, "node_modules/fast-copy": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.1.tgz", @@ -2219,6 +2540,11 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -2257,6 +2583,11 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-readable-async-iterator": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-readable-async-iterator/-/fast-readable-async-iterator-2.0.0.tgz", + "integrity": "sha512-8Sld+DuyWRIftl86ZguJxR2oXCBccOiJxrY/Rj9/7ZBynW8pYMWzIcqxFL1da+25jaWJZVa+HHX/8SsA21JdTA==" + }, "node_modules/fast-redact": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.3.0.tgz", @@ -2279,9 +2610,27 @@ "reusify": "^1.0.4" } }, - "node_modules/fifo": { - "version": "0.1.4", - "license": "MIT" + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } }, "node_modules/file-entry-cache": { "version": "6.0.1", @@ -2294,6 +2643,17 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/filename-reserved-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz", + "integrity": "sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -2353,12 +2713,6 @@ "dev": true, "license": "ISC" }, - "node_modules/flatten": { - "version": "0.0.1", - "engines": { - "node": "*" - } - }, "node_modules/follow-redirects": { "version": "1.15.5", "funding": [ @@ -2397,32 +2751,45 @@ "node": ">= 6" } }, - "node_modules/fs-chunk-store": { - "version": "1.7.0", - "license": "MIT", + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", "dependencies": { - "mkdirp": "^0.5.1", - "random-access-file": "^2.0.1", - "randombytes": "^2.0.3", - "rimraf": "^2.4.2", - "run-parallel": "^1.1.2", - "thunky": "^1.0.1" + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" } }, - "node_modules/fs-chunk-store/node_modules/mkdirp": { - "version": "0.5.6", - "license": "MIT", + "node_modules/freelist": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/freelist/-/freelist-1.0.3.tgz", + "integrity": "sha512-Ji7fEnMdZDGbS5oXElpRJsn9jPvBR8h/037D3bzreNmS8809cISq/2D9//JbA/TaZmkkN8cmecXwmQHmM+NHhg==" + }, + "node_modules/fs-native-extensions": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/fs-native-extensions/-/fs-native-extensions-1.2.5.tgz", + "integrity": "sha512-auDlsCu4bxLnspHJ+6bkAfCNjlVX6aIaHPI3fIexKrvLgjFedUChytCv7sxeuZfwmABdISI2A0/hDjZx7NWTKA==", + "hasInstallScript": true, + "optional": true, "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" + "napi-macros": "^2.0.0", + "node-gyp-build": "^4.2.3" } }, "node_modules/fs.realpath": { "version": "1.0.0", "license": "ISC" }, + "node_modules/fsa-chunk-store": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/fsa-chunk-store/-/fsa-chunk-store-1.1.4.tgz", + "integrity": "sha512-Z4SJTYxZIta37RXJofM6HsKrgM9W+pQxiyQuw0bpvsfn1HGXcBWyXZWhsCfi7wbNb6GIlykXZ9Jxwc95IiPMzA==", + "dependencies": { + "filename-reserved-regex": "^3.0.0" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -2488,6 +2855,28 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-stdin": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.0.0", "dev": true, @@ -2517,6 +2906,7 @@ }, "node_modules/glob": { "version": "7.2.3", + "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -2546,6 +2936,7 @@ }, "node_modules/glob/node_modules/once": { "version": "1.4.0", + "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -2704,10 +3095,6 @@ "node": ">= 0.4" } }, - "node_modules/hat": { - "version": "0.0.3", - "license": "MIT/X11" - }, "node_modules/help-me": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", @@ -2731,6 +3118,30 @@ "entities": "^4.4.0" } }, + "node_modules/http-parser-js": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.13.tgz", + "integrity": "sha512-u8u5ZaG0Tr/VvHlucK2ufMuOp4/5bvwgneXle+y228K5rMbJOlVjThONcaAw3ikAy8b2OO9RfEucdMHFz3UWMA==" + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/hybrid-chunk-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/hybrid-chunk-store/-/hybrid-chunk-store-1.2.2.tgz", + "integrity": "sha512-oZtxLfVHWKVKPS8KoYpWgVohEKbq3s90s7a1FwG7+EZFC/8bqZrdX4axlH5tO/g2PnGpZTVxS2YnftyCpydKSw==", + "dependencies": { + "@thaunknown/idb-chunk-store": "^1.0.2", + "cache-chunk-store": "^3.2.2", + "fsa-chunk-store": "^1.1.4", + "memory-chunk-store": "^1.3.5" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "license": "MIT", @@ -2741,6 +3152,11 @@ "node": ">=0.10.0" } }, + "node_modules/idb": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/idb/-/idb-6.1.5.tgz", + "integrity": "sha512-IJtugpKkiVXQn5Y+LteyBCNk1N8xpGV3wWZk9EVtZWH8DYkjBn0bX1XnGP9RkyZF0sAcywa6unHqSWKe7q4LGw==" + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -2768,10 +3184,6 @@ "node": ">= 4" } }, - "node_modules/immediate-chunk-store": { - "version": "1.0.8", - "license": "MIT" - }, "node_modules/import-fresh": { "version": "3.3.0", "dev": true, @@ -2843,13 +3255,6 @@ "version": "1.1.8", "license": "MIT" }, - "node_modules/ip-set": { - "version": "1.0.2", - "license": "MIT", - "dependencies": { - "ip": "^1.1.3" - } - }, "node_modules/ipaddr.js": { "version": "2.1.0", "license": "MIT", @@ -2942,6 +3347,11 @@ "node": ">=0.10.0" } }, + "node_modules/is-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-file/-/is-file-1.0.0.tgz", + "integrity": "sha512-ZGMuc+xA8mRnrXtmtf2l/EkIW2zaD2LSBWlaOVEF6yH4RTndHob65V4SwWWdtGKVthQfXPVKsXqw4TDUjbVxVQ==" + }, "node_modules/is-glob": { "version": "4.0.3", "dev": true, @@ -3021,6 +3431,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "dev": true, @@ -3080,9 +3501,13 @@ }, "node_modules/isexe": { "version": "2.0.0", - "dev": true, "license": "ISC" }, + "node_modules/join-async-iterator": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/join-async-iterator/-/join-async-iterator-1.1.1.tgz", + "integrity": "sha512-ATse+nuNeKZ9K1y27LKdvPe/GCe9R/u9dw9vI248e+vILeRK3IcJP4JUPAlSmKRCDK0cKhEwfmiw4Skqx7UnGQ==" + }, "node_modules/joycon": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", @@ -3129,21 +3554,15 @@ "json5": "lib/cli.js" } }, - "node_modules/k-bucket": { - "version": "0.6.0", - "license": "MIT", - "dependencies": { - "buffer-equal": "0.0.1", - "inherits": "^2.0.1" - } - }, - "node_modules/k-rpc": { - "version": "3.7.0", - "license": "MIT", - "dependencies": { - "buffer-equals": "^1.0.3", - "k-bucket": "^2.0.0", - "k-rpc-socket": "^1.5.0" + "node_modules/junk": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz", + "integrity": "sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/k-rpc-socket": { @@ -3160,14 +3579,6 @@ "version": "2.0.3", "license": "MIT" }, - "node_modules/k-rpc/node_modules/k-bucket": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "buffer-equal": "0.0.1", - "randombytes": "^2.0.3" - } - }, "node_modules/keyv": { "version": "4.5.4", "dev": true, @@ -3176,6 +3587,11 @@ "json-buffer": "3.0.1" } }, + "node_modules/last-one-wins": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/last-one-wins/-/last-one-wins-1.0.4.tgz", + "integrity": "sha512-t+KLJFkHPQk8lfN6WBOiGkiUXoub+gnb2XTYI2P3aiISL+94xgZ1vgz1SXN/N4hthuOoLXarXfBZPUruyjQtfA==" + }, "node_modules/levn": { "version": "0.4.1", "dev": true, @@ -3188,6 +3604,57 @@ "node": ">= 0.8.0" } }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, + "node_modules/load-ip-set": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/load-ip-set/-/load-ip-set-3.0.1.tgz", + "integrity": "sha512-ZFZt1g4Exq01SFtKjffqau+L4Qibt+51utymHHiWo8Iu/W7LYSqE7fiZ/iAZ6dIqbmeU6ICSIK02IizSScBkLQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "cross-fetch-ponyfill": "^1.0.1", + "ip-set": "^2.1.0", + "netmask": "^2.0.1", + "once": "^1.4.0", + "queue-microtask": "^1.2.3", + "split": "^1.0.1" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/load-ip-set/node_modules/ip-set": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-set/-/ip-set-2.1.0.tgz", + "integrity": "sha512-JdHz4tSMx1IeFj8yEcQU0i58qiSkOlmZXkZ8+HJ0ROV5KcgLRDO9F703oJ1GeZCvqggrcCbmagD/V7hghY62wA==", + "dependencies": { + "ip": "^1.1.5" + } + }, + "node_modules/load-ip-set/node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/locate-path": { "version": "6.0.0", "dev": true, @@ -3215,16 +3682,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lru": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/lru-cache": { "version": "10.2.0", "license": "ISC", @@ -3232,6 +3689,32 @@ "node": "14 || >=16.14" } }, + "node_modules/lt_donthave": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lt_donthave/-/lt_donthave-2.0.0.tgz", + "integrity": "sha512-qrNtq9faD5ycTM8Of7OUqPHPMv0H8NONf+dTAxUsAr0bAgPnD56BBhhBlskJVNL4WO+Dl/qmqWHF9eQb7+2lNA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "debug": "^4.2.0", + "unordered-array-remove": "^1.0.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/magnet-uri": { "version": "6.2.0", "funding": [ @@ -3254,10 +3737,23 @@ "thirty-two": "^1.0.2" } }, + "node_modules/memory-chunk-store": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/memory-chunk-store/-/memory-chunk-store-1.3.5.tgz", + "integrity": "sha512-E1Xc1U4ifk/FkC2ZsWhCaW1xg9HbE/OBmQTLe2Tr9c27YPSLbW7kw1cnb3kQWD1rDtErFJHa7mB9EVrs7aTx9g==", + "dependencies": { + "queue-microtask": "^1.2.3" + } + }, "node_modules/memory-pager": { "version": "1.5.0", "license": "MIT" }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -3280,6 +3776,17 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/mime-db": { "version": "1.52.0", "license": "MIT", @@ -3297,11 +3804,12 @@ "node": ">= 0.6" } }, - "node_modules/mimic-response": { - "version": "1.0.1", - "license": "MIT", + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/minimatch": { @@ -3321,14 +3829,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mkdirp": { - "version": "0.3.5", - "license": "MIT" - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "license": "MIT" - }, "node_modules/moment": { "version": "2.30.1", "license": "MIT", @@ -3440,6 +3940,12 @@ "version": "2.2.1", "license": "MIT" }, + "node_modules/napi-macros": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz", + "integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==", + "optional": true + }, "node_modules/natural-compare": { "version": "1.4.0", "dev": true, @@ -3470,6 +3976,32 @@ "version": "2.0.0", "license": "MIT" }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, "node_modules/node-fetch": { "version": "2.7.0", "license": "MIT", @@ -3504,6 +4036,28 @@ "version": "3.0.1", "license": "BSD-2-Clause" }, + "node_modules/node-gyp-build": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", + "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/nth-check": { "version": "2.1.1", "license": "BSD-2-Clause", @@ -3605,6 +4159,20 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.3", "dev": true, @@ -3621,12 +4189,6 @@ "node": ">= 0.8.0" } }, - "node_modules/options": { - "version": "0.0.6", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/p-limit": { "version": "3.1.0", "dev": true, @@ -3670,28 +4232,6 @@ "node": ">=6" } }, - "node_modules/parse-torrent": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "magnet-uri": "^4.0.0", - "parse-torrent-file": "^2.0.0" - }, - "bin": { - "parse-torrent": "bin/cmd.js" - } - }, - "node_modules/parse-torrent-file": { - "version": "2.1.4", - "license": "MIT", - "dependencies": { - "bencode": "^0.7.0", - "simple-sha1": "^2.0.0" - }, - "bin": { - "parse-torrent-file": "bin/cmd.js" - } - }, "node_modules/parse-torrent-title": { "version": "1.3.0", "resolved": "git+ssh://git@github.com/TheBeastLT/parse-torrent-title.git#022408972c2a040f846331a912a6a8487746a654", @@ -3704,21 +4244,6 @@ "node": ">=10" } }, - "node_modules/parse-torrent/node_modules/magnet-uri": { - "version": "4.2.3", - "license": "MIT", - "dependencies": { - "flatten": "0.0.1", - "thirty-two": "^0.0.2", - "xtend": "^4.0.0" - } - }, - "node_modules/parse-torrent/node_modules/magnet-uri/node_modules/thirty-two": { - "version": "0.0.2", - "engines": { - "node": ">=0.2.6" - } - }, "node_modules/parse5": { "version": "7.1.2", "license": "MIT", @@ -3757,7 +4282,6 @@ }, "node_modules/path-key": { "version": "3.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3777,38 +4301,6 @@ "node": ">=8" } }, - "node_modules/peer-wire-protocol": { - "version": "0.7.1", - "dependencies": { - "bitfield": "^0.1.0", - "bncode": "^0.2.3", - "buffer-alloc": "^1.1.0", - "buffer-from": "^1.0.0", - "readable-stream": "^1.0.2", - "speedometer": "^0.1.2" - } - }, - "node_modules/peer-wire-protocol/node_modules/bncode": { - "version": "0.2.3" - }, - "node_modules/peer-wire-swarm": { - "version": "0.12.2", - "dependencies": { - "buffer-from": "^1.0.0", - "fifo": "^0.1.4", - "once": "^1.1.1", - "peer-wire-protocol": "^0.7.0", - "speedometer": "^0.1.2", - "utp": "0.0.7" - } - }, - "node_modules/peer-wire-swarm/node_modules/once": { - "version": "1.4.0", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/pg": { "version": "8.11.3", "license": "MIT", @@ -3906,6 +4398,11 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/piece-length": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/piece-length/-/piece-length-2.0.1.tgz", + "integrity": "sha512-dBILiDmm43y0JPISWEmVGKBETQjwJe6mSU9GND+P9KW0SJGUwoU/odyH1nbalOP9i8WSYuqf1lQnaj92Bhw+Ug==" + }, "node_modules/pino": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/pino/-/pino-8.18.0.tgz", @@ -4100,10 +4597,6 @@ "node": ">= 0.6.0" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "license": "MIT" - }, "node_modules/process-warning": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", @@ -4124,7 +4617,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -4134,7 +4626,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "dependencies": { "once": "^1.4.0" } @@ -4143,7 +4634,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -4187,23 +4677,6 @@ "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" }, - "node_modules/random-access-file": { - "version": "2.2.1", - "license": "MIT", - "dependencies": { - "mkdirp-classic": "^0.5.2", - "random-access-storage": "^1.1.1" - } - }, - "node_modules/random-access-storage": { - "version": "1.4.3", - "license": "MIT", - "dependencies": { - "events": "^3.3.0", - "inherits": "^2.0.3", - "queue-tick": "^1.0.0" - } - }, "node_modules/random-iterate": { "version": "1.0.1", "license": "MIT" @@ -4233,9 +4706,21 @@ ], "license": "MIT" }, - "node_modules/re-emitter": { - "version": "1.1.4", - "license": "MIT" + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/rc4": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/rc4/-/rc4-0.1.5.tgz", + "integrity": "sha512-xdDTNV90z5x5u25Oc871Xnvu7yAr4tV7Eluh0VSvrhUkry39q1k+zkz7xroqHbRq+8PiazySHJPArqifUvz9VA==", + "engines": { + "node": ">=0.10.0" + } }, "node_modules/readable-stream": { "version": "1.1.14", @@ -4255,6 +4740,14 @@ "node": ">= 12.13.0" } }, + "node_modules/record-cache": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/record-cache/-/record-cache-1.2.0.tgz", + "integrity": "sha512-kyy3HWCez2WrotaL3O4fTn0rsIdfRKOdQQcEJ9KpvmKmbffKVvwsloX063EgRUlpJIXHiDQFhJcTbZequ2uTZw==", + "dependencies": { + "b4a": "^1.3.1" + } + }, "node_modules/reflect-metadata": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", @@ -4326,16 +4819,6 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "2.7.1", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "funding": [ @@ -4357,6 +4840,28 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/run-parallel-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", + "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/run-series": { "version": "1.1.9", "funding": [ @@ -4375,10 +4880,6 @@ ], "license": "MIT" }, - "node_modules/rusha": { - "version": "0.8.14", - "license": "MIT" - }, "node_modules/safe-array-concat": { "version": "1.1.0", "dev": true, @@ -4433,6 +4934,11 @@ "version": "2.1.2", "license": "MIT" }, + "node_modules/sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + }, "node_modules/secure-json-parse": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", @@ -4604,7 +5110,6 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -4615,7 +5120,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4634,155 +5138,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/simple-concat": { - "version": "1.0.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/simple-get": { - "version": "2.8.2", - "license": "MIT", - "dependencies": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/simple-get/node_modules/once": { - "version": "1.4.0", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/simple-peer": { - "version": "6.4.4", - "license": "MIT", - "dependencies": { - "debug": "^2.1.0", - "get-browser-rtc": "^1.0.0", - "inherits": "^2.0.1", - "randombytes": "^2.0.3", - "readable-stream": "^2.0.5" - } - }, - "node_modules/simple-peer/node_modules/debug": { - "version": "2.6.9", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/simple-peer/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "license": "MIT" - }, - "node_modules/simple-peer/node_modules/readable-stream": { - "version": "2.3.8", - "license": "MIT", - "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/simple-peer/node_modules/readable-stream/node_modules/isarray": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/simple-peer/node_modules/readable-stream/node_modules/string_decoder": { - "version": "1.1.1", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/simple-sha1": { - "version": "2.1.2", - "license": "MIT", - "dependencies": { - "rusha": "^0.8.1" - } - }, - "node_modules/simple-websocket": { - "version": "4.3.1", - "license": "MIT", - "dependencies": { - "debug": "^2.1.3", - "inherits": "^2.0.1", - "randombytes": "^2.0.3", - "readable-stream": "^2.0.5", - "ws": "^2.0.0", - "xtend": "^4.0.1" - } - }, - "node_modules/simple-websocket/node_modules/debug": { - "version": "2.6.9", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/simple-websocket/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "license": "MIT" - }, - "node_modules/simple-websocket/node_modules/readable-stream": { - "version": "2.3.8", - "license": "MIT", - "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/simple-websocket/node_modules/readable-stream/node_modules/isarray": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/simple-websocket/node_modules/readable-stream/node_modules/string_decoder": { - "version": "1.1.1", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/simple-websocket/node_modules/ws": { - "version": "2.3.1", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.0.1", - "ultron": "~1.1.0" - } - }, - "node_modules/simple-websocket/node_modules/ws/node_modules/safe-buffer": { - "version": "5.0.1", - "license": "MIT" - }, - "node_modules/simple-websocket/node_modules/ws/node_modules/ultron": { - "version": "1.1.1", - "license": "MIT" + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/slash": { "version": "3.0.0", @@ -4793,6 +5152,33 @@ "node": ">=8" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks/node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + }, "node_modules/sonic-boom": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.0.tgz", @@ -4808,8 +5194,25 @@ "memory-pager": "^1.0.2" } }, - "node_modules/speedometer": { - "version": "0.1.4" + "node_modules/speed-limiter": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/speed-limiter/-/speed-limiter-1.0.2.tgz", + "integrity": "sha512-Ax+TbUOho84bWUc3AKqWtkIvAIVws7d6QI4oJkgH4yQ5Yil+lR3vjd/7qd51dHKGzS5bFxg0++QwyNRN7s6rZA==", + "dependencies": { + "limiter": "^1.1.5", + "streamx": "^2.10.3" + } + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } }, "node_modules/split2": { "version": "4.2.0", @@ -4818,6 +5221,15 @@ "node": ">= 10.x" } }, + "node_modules/streamx": { + "version": "2.15.7", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.7.tgz", + "integrity": "sha512-NPEKS5+yjyo597eafGbKW5ujh7Sm6lDLHZQd/lRSz6S0VarpADBJItqfB4PnwpS+472oob1GX5cCY9vzfJpHUA==", + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, "node_modules/string_decoder": { "version": "0.10.31", "license": "MIT" @@ -4864,14 +5276,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/string2compact": { - "version": "1.3.2", - "license": "MIT", - "dependencies": { - "addr-to-ip-port": "^1.0.1", - "ipaddr.js": "^2.0.0" - } - }, "node_modules/strip-ansi": { "version": "6.0.1", "dev": true, @@ -4891,6 +5295,14 @@ "node": ">=4" } }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "engines": { + "node": ">=6" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "dev": true, @@ -4943,10 +5355,26 @@ "real-require": "^0.2.0" } }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/throughput": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/throughput/-/throughput-1.0.1.tgz", + "integrity": "sha512-4Mvv5P4xyVz6RM07wS3tGyZ/kPAiKtLeqznq3hK4pxDiTUSyQ5xeFlBiWxflCWexvSnxo2aAfedzKajJqihz4Q==" + }, "node_modules/thunky": { "version": "1.1.0", "license": "MIT" }, + "node_modules/timeout-refresh": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/timeout-refresh/-/timeout-refresh-1.0.3.tgz", + "integrity": "sha512-Mz0CX4vBGM5lj8ttbIFt7o4ZMxk/9rgudJRh76EvB7xXZMur7T/cjRiH2w4Fmkq0zxf2QpM8IFvOSRn8FEu3gA==", + "optional": true + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4963,53 +5391,6 @@ "version": "1.0.1", "license": "MIT" }, - "node_modules/torrent-discovery": { - "version": "5.4.0", - "license": "MIT", - "dependencies": { - "bittorrent-dht": "^6.0.0", - "bittorrent-tracker": "^7.0.0", - "debug": "^2.0.0", - "inherits": "^2.0.1", - "re-emitter": "^1.0.0", - "run-parallel": "^1.1.2", - "xtend": "^4.0.0" - } - }, - "node_modules/torrent-discovery/node_modules/debug": { - "version": "2.6.9", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/torrent-discovery/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "license": "MIT" - }, - "node_modules/torrent-piece": { - "version": "1.1.2", - "license": "MIT" - }, - "node_modules/torrent-stream": { - "version": "1.2.1", - "dependencies": { - "bitfield": "^0.1.0", - "bncode": "^0.5.2", - "buffer-from": "^1.0.0", - "end-of-stream": "^0.1.4", - "fs-chunk-store": "^1.3.0", - "hat": "0.0.3", - "immediate-chunk-store": "^1.0.5", - "ip-set": "^1.0.0", - "mkdirp": "^0.3.5", - "parse-torrent": "^4.0.0", - "peer-wire-swarm": "^0.12.0", - "rimraf": "^2.2.5", - "torrent-discovery": "^5.2.0", - "torrent-piece": "^1.0.0" - } - }, "node_modules/ts-api-utils": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.0.tgz", @@ -5558,9 +5939,13 @@ "node": ">=14.17" } }, - "node_modules/ultron": { - "version": "1.0.2", - "license": "MIT" + "node_modules/uint8-util": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/uint8-util/-/uint8-util-2.2.4.tgz", + "integrity": "sha512-uEI5lLozmKQPYEevfEhP9LY3Je5ZmrQhaWXrzTVqrLNQl36xsRh8NiAxYwB9J+2BAt99TRbmCkROQB2ZKhx4UA==", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } }, "node_modules/unbox-primitive": { "version": "1.0.2", @@ -5580,9 +5965,16 @@ "version": "1.13.6", "license": "MIT" }, - "node_modules/uniq": { - "version": "1.0.1", - "license": "MIT" + "node_modules/unordered-array-remove": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unordered-array-remove/-/unordered-array-remove-1.0.2.tgz", + "integrity": "sha512-45YsfD6svkgaCBNyvD+dFHm4qFX9g3wRSIVgWVPtm2OCnphvPxzJoe20ATsiNpNJrmzHifnxm+BN5F7gFT/4gw==" + }, + "node_modules/unordered-set": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unordered-set/-/unordered-set-2.0.1.tgz", + "integrity": "sha512-eUmNTPzdx+q/WvOHW0bgGYLWvWHNT3PTKEQLg0MAQhc0AHASHVHoP/9YytYd4RBVariqno/mEUhVZN98CmD7bg==", + "optional": true }, "node_modules/uri-js": { "version": "4.4.1", @@ -5608,14 +6000,193 @@ "lodash.clonedeep": "^4.5.0" } }, + "node_modules/ut_metadata": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/ut_metadata/-/ut_metadata-4.0.3.tgz", + "integrity": "sha512-2tovup0VDYpT8t8+EhhhKBmbgIyiYyJQZ+Hf+/61+SvjuRS2MEeA5CiSARP4q+9/83Wu09OsGrUre/Zv6OI5NA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "bencode": "^4.0.0", + "bitfield": "^4.0.0", + "debug": "^4.2.0", + "uint8-util": "^2.1.3" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/ut_metadata/node_modules/bencode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/bencode/-/bencode-4.0.0.tgz", + "integrity": "sha512-AERXw18df0pF3ziGOCyUjqKZBVNH8HV3lBxnx5w0qtgMIk4a1wb9BkcCQbkp9Zstfrn/dzRwl7MmUHHocX3sRQ==", + "dependencies": { + "uint8-util": "^2.2.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/ut_metadata/node_modules/bitfield": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/bitfield/-/bitfield-4.2.0.tgz", + "integrity": "sha512-kUTatQb/mBd8uhvdLrUkouGDBUQiJaIOvPlptUwOWp6MFqih4d1MiVf0m3ATxfZSzu+LjW/awFeABltYa62uIA==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/ut_pex": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/ut_pex/-/ut_pex-4.0.4.tgz", + "integrity": "sha512-isVTbp2TKGoMOu+4Zh/i6ijpYr0VG83xjRPgCXaUjKzgXXndjCMWg32/9kZjubD+kxEXcmXMkoS8IttS9FZE8g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "bencode": "^4.0.0", + "compact2string": "^1.4.1", + "string2compact": "^2.0.1" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/ut_pex/node_modules/addr-to-ip-port": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/addr-to-ip-port/-/addr-to-ip-port-2.0.0.tgz", + "integrity": "sha512-9bYbtjamtdLHZSqVIUXhilOryNPiL+x+Q5J/Unpg4VY3ZIkK3fT52UoErj1NdUeVm3J1t2iBEAur4Ywbl/bahw==", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/ut_pex/node_modules/bencode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/bencode/-/bencode-4.0.0.tgz", + "integrity": "sha512-AERXw18df0pF3ziGOCyUjqKZBVNH8HV3lBxnx5w0qtgMIk4a1wb9BkcCQbkp9Zstfrn/dzRwl7MmUHHocX3sRQ==", + "dependencies": { + "uint8-util": "^2.2.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/ut_pex/node_modules/string2compact": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string2compact/-/string2compact-2.0.1.tgz", + "integrity": "sha512-Bm/T8lHMTRXw+u83LE+OW7fXmC/wM+Mbccfdo533ajSBNxddDHlRrvxE49NdciGHgXkUQM5WYskJ7uTkbBUI0A==", + "dependencies": { + "addr-to-ip-port": "^2.0.0", + "ipaddr.js": "^2.0.0" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", - "license": "MIT" + "license": "MIT", + "optional": true }, - "node_modules/utp": { - "version": "0.0.7", + "node_modules/utp-native": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/utp-native/-/utp-native-2.5.3.tgz", + "integrity": "sha512-sWTrWYXPhhWJh+cS2baPzhaZc89zwlWCfwSthUjGhLkZztyPhcQllo+XVVCbNGi7dhyRlxkWxN4NKU6FbA9Y8w==", + "hasInstallScript": true, + "optional": true, "dependencies": { - "cyclist": "~0.1.0" + "napi-macros": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.0.2", + "timeout-refresh": "^1.0.0", + "unordered-set": "^2.0.1" + }, + "bin": { + "ucat": "ucat.js" + }, + "engines": { + "node": ">=8.12" + } + }, + "node_modules/utp-native/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/utp-native/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true + }, + "node_modules/utp-native/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.2.0" } }, "node_modules/uuid": { @@ -5632,9 +6203,460 @@ "node": ">= 0.10" } }, + "node_modules/web-streams-polyfill": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz", + "integrity": "sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webtorrent": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/webtorrent/-/webtorrent-2.1.35.tgz", + "integrity": "sha512-JxAdPrX75zAtBumKxOM1691phN26qTx+RgxC20UUm91l/AQ5zAeGAZp1mtoAJoLQKeZPXguMV5RA4+IToLGdLA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "@silentbot1/nat-api": "^0.4.7", + "@thaunknown/simple-peer": "^9.12.1", + "@webtorrent/http-node": "^1.3.0", + "addr-to-ip-port": "^2.0.0", + "bitfield": "^4.1.0", + "bittorrent-dht": "^11.0.5", + "bittorrent-protocol": "^4.1.11", + "cache-chunk-store": "^3.2.2", + "chunk-store-iterator": "^1.0.3", + "cpus": "^1.0.3", + "create-torrent": "^6.0.16", + "cross-fetch-ponyfill": "^1.0.3", + "debug": "^4.3.4", + "escape-html": "^1.0.3", + "fs-chunk-store": "^4.1.0", + "hybrid-chunk-store": "^1.2.2", + "immediate-chunk-store": "^2.2.0", + "join-async-iterator": "^1.1.1", + "load-ip-set": "^3.0.1", + "lt_donthave": "^2.0.0", + "memory-chunk-store": "^1.3.5", + "mime": "^3.0.0", + "once": "^1.4.0", + "parse-torrent": "^11.0.16", + "pump": "^3.0.0", + "queue-microtask": "^1.2.3", + "random-iterate": "^1.0.1", + "range-parser": "^1.2.1", + "run-parallel": "^1.2.0", + "run-parallel-limit": "^1.1.0", + "speed-limiter": "^1.0.2", + "streamx": "^2.15.7", + "throughput": "^1.0.1", + "torrent-discovery": "^11.0.1", + "torrent-piece": "^3.0.0", + "uint8-util": "^2.2.4", + "unordered-array-remove": "^1.0.2", + "ut_metadata": "^4.0.3", + "ut_pex": "^4.0.4" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "utp-native": "^2.5.3" + } + }, + "node_modules/webtorrent/node_modules/addr-to-ip-port": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/addr-to-ip-port/-/addr-to-ip-port-2.0.0.tgz", + "integrity": "sha512-9bYbtjamtdLHZSqVIUXhilOryNPiL+x+Q5J/Unpg4VY3ZIkK3fT52UoErj1NdUeVm3J1t2iBEAur4Ywbl/bahw==", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/webtorrent/node_modules/bencode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/bencode/-/bencode-4.0.0.tgz", + "integrity": "sha512-AERXw18df0pF3ziGOCyUjqKZBVNH8HV3lBxnx5w0qtgMIk4a1wb9BkcCQbkp9Zstfrn/dzRwl7MmUHHocX3sRQ==", + "dependencies": { + "uint8-util": "^2.2.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/webtorrent/node_modules/bep53-range": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bep53-range/-/bep53-range-2.0.0.tgz", + "integrity": "sha512-sMm2sV5PRs0YOVk0LTKtjuIprVzxgTQUsrGX/7Yph2Rm4FO2Fqqtq7hNjsOB5xezM4v4+5rljCgK++UeQJZguA==", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/webtorrent/node_modules/bitfield": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/bitfield/-/bitfield-4.2.0.tgz", + "integrity": "sha512-kUTatQb/mBd8uhvdLrUkouGDBUQiJaIOvPlptUwOWp6MFqih4d1MiVf0m3ATxfZSzu+LjW/awFeABltYa62uIA==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/webtorrent/node_modules/bittorrent-dht": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/bittorrent-dht/-/bittorrent-dht-11.0.5.tgz", + "integrity": "sha512-R09D6uNaziRqsc+B/j5QzkjceTak+wH9vcNLnkmt8A52EWF9lQwBP0vvCKgSA3AJOYYl+41n3osA2KYYn/z5uQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "bencode": "^4.0.0", + "debug": "^4.3.4", + "k-bucket": "^5.1.0", + "k-rpc": "^5.1.0", + "last-one-wins": "^1.0.4", + "lru": "^3.1.0", + "randombytes": "^2.1.0", + "record-cache": "^1.2.0" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/webtorrent/node_modules/bittorrent-tracker": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/bittorrent-tracker/-/bittorrent-tracker-11.0.1.tgz", + "integrity": "sha512-WDvixbEkLgnEeVk8iiF2/LwB2zsuxehir3wBFkHskB/LvYE4HQI+6RoWPHjwGqi9POPJdeOnSPFa8pZvB0Bd8A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "@thaunknown/simple-peer": "^9.12.1", + "@thaunknown/simple-websocket": "^9.1.0", + "bencode": "^4.0.0", + "bittorrent-peerid": "^1.3.3", + "chrome-dgram": "^3.0.6", + "clone": "^2.0.0", + "compact2string": "^1.4.1", + "cross-fetch-ponyfill": "^1.0.1", + "debug": "^4.1.1", + "ip": "^1.1.5", + "lru": "^3.1.0", + "minimist": "^1.2.5", + "once": "^1.4.0", + "queue-microtask": "^1.2.3", + "random-iterate": "^1.0.1", + "run-parallel": "^1.2.0", + "run-series": "^1.1.9", + "socks": "^2.0.0", + "string2compact": "^2.0.0", + "uint8-util": "^2.1.9", + "unordered-array-remove": "^1.0.2", + "ws": "^8.0.0" + }, + "bin": { + "bittorrent-tracker": "bin/cmd.js" + }, + "engines": { + "node": ">=12.20.0" + }, + "optionalDependencies": { + "bufferutil": "^4.0.3", + "utf-8-validate": "^5.0.5" + } + }, + "node_modules/webtorrent/node_modules/fs-chunk-store": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/fs-chunk-store/-/fs-chunk-store-4.1.0.tgz", + "integrity": "sha512-8apaYPaENIVUjVGqjo+Yg5/Hv7qL2fijWV+XGMCs3MR07o9DZZVMpF7dclxdjYotSjLdUGVPhqaJn+eAx6NLYQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "filename-reserved-regex": "^3.0.0", + "queue-microtask": "^1.2.2", + "random-access-file": "^4.0.0", + "randombytes": "^2.0.3", + "run-parallel": "^1.1.2", + "thunky": "^1.0.1" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/webtorrent/node_modules/immediate-chunk-store": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/immediate-chunk-store/-/immediate-chunk-store-2.2.0.tgz", + "integrity": "sha512-1bHBna0hCa6arRXicu91IiL9RvvkbNYLVq+mzWdaLGZC3hXvX4doh8e1dLhMKez5siu63CYgO5NrGJbRX5lbPA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.3" + } + }, + "node_modules/webtorrent/node_modules/k-bucket": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/k-bucket/-/k-bucket-5.1.0.tgz", + "integrity": "sha512-Fac7iINEovXIWU20GPnOMLUbjctiS+cnmyjC4zAUgvs3XPf1vo9akfCHkigftSic/jiKqKl+KA3a/vFcJbHyCg==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/webtorrent/node_modules/k-rpc": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/k-rpc/-/k-rpc-5.1.0.tgz", + "integrity": "sha512-FGc+n70Hcjoa/X2JTwP+jMIOpBz+pkRffHnSl9yrYiwUxg3FIgD50+u1ePfJUOnRCnx6pbjmVk5aAeB1wIijuQ==", + "dependencies": { + "k-bucket": "^5.0.0", + "k-rpc-socket": "^1.7.2", + "randombytes": "^2.0.5" + } + }, + "node_modules/webtorrent/node_modules/lru": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lru/-/lru-3.1.0.tgz", + "integrity": "sha512-5OUtoiVIGU4VXBOshidmtOsvBIvcQR6FD/RzWSvaeHyxCGB+PCUCu+52lqMfdc0h/2CLvHhZS4TwUmMQrrMbBQ==", + "dependencies": { + "inherits": "^2.0.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/webtorrent/node_modules/magnet-uri": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-7.0.5.tgz", + "integrity": "sha512-Ke+dDiYHK1Rq/ZyGUAgk7NIkoypivxolTj/A0qr60ypP0FjeP+NTUNEhr965HsRan0zGxKEBK73+SsjRyJWkXg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "@thaunknown/thirty-two": "^1.0.3", + "bep53-range": "^2.0.0", + "uint8-util": "^2.1.9" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/webtorrent/node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/webtorrent/node_modules/parse-torrent": { + "version": "11.0.16", + "resolved": "https://registry.npmjs.org/parse-torrent/-/parse-torrent-11.0.16.tgz", + "integrity": "sha512-5GoOdmW0HpiB78aQpBz8/5V3V1LjBRDNiL7DOs33pKeCLOzFnfMrsRD6CYmaUBT5Vi/dXE0hfePsjDGJSMF48w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "bencode": "^4.0.0", + "cross-fetch-ponyfill": "^1.0.3", + "get-stdin": "^9.0.0", + "magnet-uri": "^7.0.5", + "queue-microtask": "^1.2.3", + "uint8-util": "^2.2.4" + }, + "bin": { + "parse-torrent": "bin/cmd.js" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/webtorrent/node_modules/random-access-file": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/random-access-file/-/random-access-file-4.0.6.tgz", + "integrity": "sha512-WLk07uxKsZQZWUDjoO5ZvJHMkrBbZ5GLrCWAXYLiiBbZ4Vf4+7VlJcUJyq3fMgp0lAwTqtbFKzIn5FwqgztnUQ==", + "dependencies": { + "random-access-storage": "^3.0.0" + }, + "optionalDependencies": { + "fs-native-extensions": "^1.1.0" + } + }, + "node_modules/webtorrent/node_modules/random-access-storage": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/random-access-storage/-/random-access-storage-3.0.1.tgz", + "integrity": "sha512-raFoHJ/orMyur04GKrA+5ThOwhX9wICdqMDLqTM7bHEXPz7zi5MxLsLUaybxGu3b4mJTt8zhCpZHgjlu0x4wpg==", + "dependencies": { + "events": "^3.3.0", + "queue-tick": "^1.0.0" + } + }, + "node_modules/webtorrent/node_modules/string2compact": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string2compact/-/string2compact-2.0.1.tgz", + "integrity": "sha512-Bm/T8lHMTRXw+u83LE+OW7fXmC/wM+Mbccfdo533ajSBNxddDHlRrvxE49NdciGHgXkUQM5WYskJ7uTkbBUI0A==", + "dependencies": { + "addr-to-ip-port": "^2.0.0", + "ipaddr.js": "^2.0.0" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/webtorrent/node_modules/torrent-discovery": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/torrent-discovery/-/torrent-discovery-11.0.1.tgz", + "integrity": "sha512-+QhOUWRxhR8Y6e5z5I0qil812q11Xz9Yaj1pfYwVkereTBQT1THBCeSHxWZEHuGjKLiIBueVzPP7+wiPtedXKg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "bittorrent-dht": "^11.0.5", + "bittorrent-lsd": "^2.0.0", + "bittorrent-tracker": "^11.0.1", + "debug": "^4.3.4", + "run-parallel": "^1.2.0" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/webtorrent/node_modules/torrent-piece": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/torrent-piece/-/torrent-piece-3.0.0.tgz", + "integrity": "sha512-j0tRX7qq22nIuVFF57Tg/wAvFq79F1eM9pcMxY+b0qCCe7yXJnIrqF+Q5YEJ94tNisDnJzcqDHNrPmD9X/yAIg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "uint8-util": "^2.1.9" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/webtorrent/node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/which": { "version": "2.0.2", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -5690,12 +6712,24 @@ "version": "1.0.2", "license": "ISC" }, - "node_modules/ws": { - "version": "1.1.5", - "license": "MIT", + "node_modules/xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", "dependencies": { - "options": ">=0.0.5", - "ultron": "1.0.x" + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" } }, "node_modules/xtend": { diff --git a/src/node/consumer/package.json b/src/node/consumer/package.json index 192a1c5..3e515b1 100644 --- a/src/node/consumer/package.json +++ b/src/node/consumer/package.json @@ -27,15 +27,12 @@ "reflect-metadata": "^0.2.1", "sequelize": "^6.36.0", "sequelize-typescript": "^2.1.6", - "torrent-stream": "^1.2.1", - "user-agents": "^1.0.1444" + "webtorrent": "^2.1.35" }, "devDependencies": { "@types/amqplib": "^0.10.4", "@types/magnet-uri": "^5.1.5", "@types/node": "^20.11.16", - "@types/stremio-addon-sdk": "^1.6.10", - "@types/torrent-stream": "^0.0.9", "@types/validator": "^13.11.8", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", diff --git a/src/node/consumer/src/jobs/process_torrents_job.ts b/src/node/consumer/src/jobs/process_torrents_job.ts index 23bbfd3..4fed81f 100644 --- a/src/node/consumer/src/jobs/process_torrents_job.ts +++ b/src/node/consumer/src/jobs/process_torrents_job.ts @@ -14,9 +14,9 @@ export class ProcessTorrentsJob implements IProcessTorrentsJob { private readonly consumeQueueOptions: Options.Consume = {noAck: false}; private torrentProcessingService: ITorrentProcessingService; private logger: ILoggingService; - + constructor(@inject(IocTypes.ITorrentProcessingService) torrentProcessingService: ITorrentProcessingService, - @inject(IocTypes.ILoggingService) logger: ILoggingService){ + @inject(IocTypes.ILoggingService) logger: ILoggingService) { this.torrentProcessingService = torrentProcessingService; this.logger = logger; } @@ -55,7 +55,7 @@ export class ProcessTorrentsJob implements IProcessTorrentsJob { this.logger.error('Failed processing torrent', error); } } - + try { await channel.assertQueue(configurationService.rabbitConfig.QUEUE_NAME, this.assertQueueOptions); await channel.prefetch(configurationService.jobConfig.JOB_CONCURRENCY); diff --git a/src/node/consumer/src/lib/helpers/boolean_helpers.ts b/src/node/consumer/src/lib/helpers/boolean_helpers.ts index cd66b22..79c68a0 100644 --- a/src/node/consumer/src/lib/helpers/boolean_helpers.ts +++ b/src/node/consumer/src/lib/helpers/boolean_helpers.ts @@ -1,5 +1,5 @@ export const BooleanHelpers = { - parseBool: function(value: string | number | undefined, defaultValue: boolean): boolean { + parseBool: function (value: string | number | undefined, defaultValue: boolean): boolean { switch (typeof value) { case 'string': return parseStringToBool(value, defaultValue); diff --git a/src/node/consumer/src/lib/helpers/promises_helpers.ts b/src/node/consumer/src/lib/helpers/promises_helpers.ts index 366ec24..dacefb7 100644 --- a/src/node/consumer/src/lib/helpers/promises_helpers.ts +++ b/src/node/consumer/src/lib/helpers/promises_helpers.ts @@ -1,11 +1,11 @@ export const PromiseHelpers = { - sequence: async function(promises: (() => Promise)[]) { + sequence: async function (promises: (() => Promise)[]) { return promises.reduce((promise, func) => promise.then(result => func().then(res => result.concat(res))), Promise.resolve([])); }, - first: async function(promises) { + first: async function (promises) { return Promise.all(promises.map(p => { return p.then((val) => Promise.reject(val), (err) => Promise.resolve(err)); })).then( @@ -14,11 +14,11 @@ export const PromiseHelpers = { ); }, - delay: async function(duration: number) { + delay: async function (duration: number) { return new Promise(resolve => setTimeout(() => resolve(), duration)); }, - timeout: async function(timeoutMs: number, promise, message = 'Timed out') { + timeout: async function (timeoutMs: number, promise, message = 'Timed out') { return Promise.race([ promise, new Promise(function (resolve, reject) { @@ -29,7 +29,7 @@ export const PromiseHelpers = { ]); }, - mostCommonValue: function(array) { + mostCommonValue: function (array) { return array.sort((a, b) => array.filter(v => v === a).length - array.filter(v => v === b).length).pop(); } }; \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/cinemeta_metadata.ts b/src/node/consumer/src/lib/interfaces/cinemeta_metadata.ts index ad3fc1f..c2821f3 100644 --- a/src/node/consumer/src/lib/interfaces/cinemeta_metadata.ts +++ b/src/node/consumer/src/lib/interfaces/cinemeta_metadata.ts @@ -6,6 +6,7 @@ export interface ICinemetaJsonResponse { links?: ICinemetaLink[]; behaviorHints?: ICinemetaBehaviorHints; } + export interface ICinemetaMetaData { awards?: string; cast?: string[]; @@ -37,6 +38,7 @@ export interface ICinemetaMetaData { releaseInfo?: string; videos?: ICinemetaVideo[]; } + export interface ICinemetaPopularities { PXS_TEST?: number; PXS?: number; @@ -49,10 +51,12 @@ export interface ICinemetaPopularities { stremio?: number; stremio_lib?: number; } + export interface ICinemetaTrailer { source?: string; type?: string; } + export interface ICinemetaVideo extends ICommonVideoMetadata { name?: string; number?: number; @@ -63,15 +67,18 @@ export interface ICinemetaVideo extends ICommonVideoMetadata { thumbnail?: string; description?: string; } + export interface ICinemetaTrailerStream { title?: string; ytId?: string; } + export interface ICinemetaLink { name?: string; category?: string; url?: string; } + export interface ICinemetaBehaviorHints { defaultVideoId?: null; hasScheduledVideos?: boolean; diff --git a/src/node/consumer/src/lib/interfaces/kitsu_metadata.ts b/src/node/consumer/src/lib/interfaces/kitsu_metadata.ts index ea3f5d5..9b4f4e6 100644 --- a/src/node/consumer/src/lib/interfaces/kitsu_metadata.ts +++ b/src/node/consumer/src/lib/interfaces/kitsu_metadata.ts @@ -4,6 +4,7 @@ export interface IKitsuJsonResponse { cacheMaxAge?: number; meta?: IKitsuMeta; } + export interface IKitsuMeta { aliases?: string[]; animeType?: string; @@ -29,16 +30,19 @@ export interface IKitsuMeta { videos?: IKitsuVideo[]; year?: string; } + export interface IKitsuVideo extends ICommonVideoMetadata { imdbEpisode?: number; imdbSeason?: number; imdb_id?: string; thumbnail?: string; } + export interface IKitsuTrailer { source?: string; type?: string; } + export interface IKitsuLink { name?: string; category?: string; diff --git a/src/node/consumer/src/lib/interfaces/logging_service.ts b/src/node/consumer/src/lib/interfaces/logging_service.ts index 44e7c49..06266ed 100644 --- a/src/node/consumer/src/lib/interfaces/logging_service.ts +++ b/src/node/consumer/src/lib/interfaces/logging_service.ts @@ -1,6 +1,9 @@ export interface ILoggingService { info(message: string, ...args: any[]): void; + error(message: string, ...args: any[]): void; + debug(message: string, ...args: any[]): void; + warn(message: string, ...args: any[]): void; } \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/metadata_query.ts b/src/node/consumer/src/lib/interfaces/metadata_query.ts index 3d6932a..8acca9c 100644 --- a/src/node/consumer/src/lib/interfaces/metadata_query.ts +++ b/src/node/consumer/src/lib/interfaces/metadata_query.ts @@ -1,4 +1,4 @@ -export interface IMetaDataQuery { +export interface IMetaDataQuery { title?: string type?: string year?: number | string diff --git a/src/node/consumer/src/lib/models/composition_root.ts b/src/node/consumer/src/lib/models/composition_root.ts index a6c47cb..e52e2f0 100644 --- a/src/node/consumer/src/lib/models/composition_root.ts +++ b/src/node/consumer/src/lib/models/composition_root.ts @@ -10,6 +10,7 @@ export class CompositionalRoot implements ICompositionalRoot { private trackerService: ITrackerService; private databaseRepository: IDatabaseRepository; private processTorrentsJob: IProcessTorrentsJob; + constructor(@inject(IocTypes.ITrackerService) trackerService: ITrackerService, @inject(IocTypes.IDatabaseRepository) databaseRepository: IDatabaseRepository, @inject(IocTypes.IProcessTorrentsJob) processTorrentsJob: IProcessTorrentsJob) { diff --git a/src/node/consumer/src/lib/models/configuration/torrent_config.ts b/src/node/consumer/src/lib/models/configuration/torrent_config.ts index 33ea6c6..543f277 100644 --- a/src/node/consumer/src/lib/models/configuration/torrent_config.ts +++ b/src/node/consumer/src/lib/models/configuration/torrent_config.ts @@ -1,4 +1,5 @@ export const torrentConfig = { MAX_CONNECTIONS_PER_TORRENT: parseInt(process.env.MAX_SINGLE_TORRENT_CONNECTIONS || "20", 10), + MAX_CONNECTIONS_OVERALL: parseInt(process.env.MAX_CONNECTIONS_OVERALL || "100", 10), TIMEOUT: parseInt(process.env.TORRENT_TIMEOUT || "30000", 10) }; \ No newline at end of file diff --git a/src/node/consumer/src/lib/models/inversify_config.ts b/src/node/consumer/src/lib/models/inversify_config.ts index 6bbb2a2..17cd120 100644 --- a/src/node/consumer/src/lib/models/inversify_config.ts +++ b/src/node/consumer/src/lib/models/inversify_config.ts @@ -1,6 +1,6 @@ import "reflect-metadata"; // required import {Container} from "inversify"; -import { IocTypes } from "./ioc_types"; +import {IocTypes} from "./ioc_types"; import {ICacheService} from "../interfaces/cache_service"; import {ILoggingService} from "../interfaces/logging_service"; import {IMetadataService} from "../interfaces/metadata_service"; @@ -32,13 +32,13 @@ serviceContainer.bind(IocTypes.ICompositionalRoot).to(Compos serviceContainer.bind(IocTypes.ICacheService).to(CacheService).inSingletonScope(); serviceContainer.bind(IocTypes.ILoggingService).to(LoggingService).inSingletonScope(); serviceContainer.bind(IocTypes.ITrackerService).to(TrackerService).inSingletonScope(); +serviceContainer.bind(IocTypes.ITorrentDownloadService).to(TorrentDownloadService).inSingletonScope(); serviceContainer.bind(IocTypes.ITorrentFileService).to(TorrentFileService); serviceContainer.bind(IocTypes.ITorrentProcessingService).to(TorrentProcessingService); serviceContainer.bind(IocTypes.ITorrentSubtitleService).to(TorrentSubtitleService); serviceContainer.bind(IocTypes.ITorrentEntriesService).to(TorrentEntriesService); -serviceContainer.bind(IocTypes.ITorrentDownloadService).to(TorrentDownloadService); serviceContainer.bind(IocTypes.IMetadataService).to(MetadataService); serviceContainer.bind(IocTypes.IDatabaseRepository).to(DatabaseRepository); serviceContainer.bind(IocTypes.IProcessTorrentsJob).to(ProcessTorrentsJob); -export { serviceContainer }; +export {serviceContainer}; diff --git a/src/node/consumer/src/lib/services/cache_service.ts b/src/node/consumer/src/lib/services/cache_service.ts index dc140f9..1afae05 100644 --- a/src/node/consumer/src/lib/services/cache_service.ts +++ b/src/node/consumer/src/lib/services/cache_service.ts @@ -25,7 +25,7 @@ export class CacheService implements ICacheService { private logger: ILoggingService; private readonly memoryCache: MemoryCache; private readonly remoteCache: Cache | MemoryCache; - + constructor(@inject(IocTypes.ILoggingService) logger: ILoggingService) { this.logger = logger; if (configurationService.cacheConfig.NO_CACHE) { @@ -59,7 +59,7 @@ export class CacheService implements ICacheService { collectionName: configurationService.cacheConfig.COLLECTION_NAME, ttl: GLOBAL_TTL, url: configurationService.cacheConfig.MONGO_URI, - mongoConfig:{ + mongoConfig: { socketTimeoutMS: 120000, appName: 'knightcrawler-consumer', } diff --git a/src/node/consumer/src/lib/services/metadata_service.ts b/src/node/consumer/src/lib/services/metadata_service.ts index 7e469da..f684d8d 100644 --- a/src/node/consumer/src/lib/services/metadata_service.ts +++ b/src/node/consumer/src/lib/services/metadata_service.ts @@ -20,6 +20,7 @@ const TIMEOUT = 20000; @injectable() export class MetadataService implements IMetadataService { private cacheService: ICacheService; + constructor(@inject(IocTypes.ICacheService) cacheService: ICacheService) { this.cacheService = cacheService; } diff --git a/src/node/consumer/src/lib/services/torrent_download_service.ts b/src/node/consumer/src/lib/services/torrent_download_service.ts index 28d46a7..e265fba 100644 --- a/src/node/consumer/src/lib/services/torrent_download_service.ts +++ b/src/node/consumer/src/lib/services/torrent_download_service.ts @@ -1,5 +1,4 @@ import {encode} from 'magnet-uri'; -import torrentStream from 'torrent-stream'; import {configurationService} from './configuration_service'; import {ExtensionHelpers} from '../helpers/extension_helpers'; import {ITorrentFileCollection} from "../interfaces/torrent_file_collection"; @@ -9,7 +8,10 @@ import {ISubtitleAttributes} from "../../repository/interfaces/subtitle_attribut import {IContentAttributes} from "../../repository/interfaces/content_attributes"; import {parse} from "parse-torrent-title"; import {ITorrentDownloadService} from "../interfaces/torrent_download_service"; -import {injectable} from "inversify"; +import {inject, injectable} from "inversify"; +import {ILoggingService} from "../interfaces/logging_service"; +import {IocTypes} from "../models/ioc_types"; +import WebTorrent from "webtorrent"; interface ITorrentFile { name: string; @@ -18,15 +20,28 @@ interface ITorrentFile { fileIndex: number; } +const clientOptions = { + maxConns: configurationService.torrentConfig.MAX_CONNECTIONS_OVERALL, +} + +const torrentOptions = { + skipVerify: true, + addUID: true, + destroyStoreOnDestroy: true, + private: true, + maxWebConns: configurationService.torrentConfig.MAX_CONNECTIONS_PER_TORRENT, +} + @injectable() export class TorrentDownloadService implements ITorrentDownloadService { - private engineOptions: TorrentStream.TorrentEngineOptions = { - connections: configurationService.torrentConfig.MAX_CONNECTIONS_PER_TORRENT, - uploads: 0, - verify: false, - dht: false, - tracker: true, - }; + private torrentClient: WebTorrent.Instance; + private logger: ILoggingService; + + constructor(@inject(IocTypes.ILoggingService) logger: ILoggingService) { + this.logger = logger; + this.torrentClient = new WebTorrent(clientOptions); + this.torrentClient.on('error', errors => this.logClientErrors(errors)); + } public getTorrentFiles = async (torrent: IParsedTorrent, timeout: number = 30000): Promise => { const torrentFiles: ITorrentFile[] = await this.filesFromTorrentStream(torrent, timeout); @@ -48,29 +63,32 @@ export class TorrentDownloadService implements ITorrentDownloadService { } const magnet = encode({infoHash: torrent.infoHash, announce: torrent.trackers.split(',')}); - return new Promise((resolve, reject) => { - let engine: TorrentStream.TorrentEngine; + this.logger.debug(`Constructing torrent stream for ${torrent.title} with magnet ${magnet}`); + return new Promise((resolve, reject) => { const timeoutId = setTimeout(() => { - engine.destroy(() => { - }); + this.torrentClient.remove(magnet, {destroyStore: true}); reject(new Error('No available connections for torrent!')); }, timeout); - engine = torrentStream(magnet, this.engineOptions); + this.logger.debug(`Adding torrent with infoHash ${torrent.infoHash}`); + + this.torrentClient.add(magnet, torrentOptions, (torrent) => { - engine.on("ready", () => { - const files: ITorrentFile[] = engine.files.map((file, fileId) => ({ - ...file, + this.logger.debug(`torrent with infoHash ${torrent.infoHash} added to client.`); + + const files: ITorrentFile[] = torrent.files.map((file, fileId) => ({ fileIndex: fileId, - size: file.length, - title: file.name + length: file.length, + name: file.name, + path: file.path, })); + this.logger.debug(`Found ${files.length} files in torrent ${torrent.infoHash}`); + resolve(files); - engine.destroy(() => { - }); + this.torrentClient.remove(magnet, {destroyStore: true}); clearTimeout(timeoutId); }); }); @@ -86,12 +104,12 @@ export class TorrentDownloadService implements ITorrentDownloadService { const minAnimeExtraRatio = 5; const minRedundantRatio = videos.length <= 3 ? 30 : Number.MAX_VALUE; - const isSample = (video: ITorrentFile) => video.path?.match(/sample|bonus|promo/i) && maxSize / parseInt(video.path.toString()) > minSampleRatio; - const isRedundant = (video: ITorrentFile) => maxSize / parseInt(video.path.toString()) > minRedundantRatio; - const isExtra = (video: ITorrentFile) => video.path?.match(/extras?\//i); - const isAnimeExtra = (video: ITorrentFile) => video.path?.match(/(?:\b|_)(?:NC)?(?:ED|OP|PV)(?:v?\d\d?)?(?:\b|_)/i) + const isSample = (video: ITorrentFile) => video.path.toString()?.match(/sample|bonus|promo/i) && maxSize / video.length > minSampleRatio; + const isRedundant = (video: ITorrentFile) => maxSize / video.length > minRedundantRatio; + const isExtra = (video: ITorrentFile) => video.path.toString()?.match(/extras?\//i); + const isAnimeExtra = (video: ITorrentFile) => video.path.toString()?.match(/(?:\b|_)(?:NC)?(?:ED|OP|PV)(?:v?\d\d?)?(?:\b|_)/i) && maxSize / parseInt(video.length.toString()) > minAnimeExtraRatio; - const isWatermark = (video: ITorrentFile) => video.path?.match(/^[A-Z-]+(?:\.[A-Z]+)?\.\w{3,4}$/) + const isWatermark = (video: ITorrentFile) => video.path.toString()?.match(/^[A-Z-]+(?:\.[A-Z]+)?\.\w{3,4}$/) && maxSize / parseInt(video.length.toString()) > minAnimeExtraRatio return videos @@ -109,19 +127,23 @@ export class TorrentDownloadService implements ITorrentDownloadService { private createContent = (torrent: IParsedTorrent, torrentFiles: ITorrentFile[]): IContentAttributes[] => torrentFiles.map(file => this.mapTorrentFileToContentAttributes(torrent, file)); private mapTorrentFileToFileAttributes = (torrent: IParsedTorrent, file: ITorrentFile): IFileAttributes => { - const videoFile: IFileAttributes = { - title: file.name, - size: file.length, - fileIndex: file.fileIndex || 0, - infoHash: torrent.infoHash, - imdbId: torrent.imdbId.toString(), - imdbSeason: torrent.season || 0, - imdbEpisode: torrent.episode || 0, - kitsuId: parseInt(torrent.kitsuId.toString()) || 0, - kitsuEpisode: torrent.episode || 0 - }; - - return {...videoFile, ...parse(file.name)}; + try { + const videoFile: IFileAttributes = { + title: file.name, + size: file.length, + fileIndex: file.fileIndex || 0, + infoHash: torrent.infoHash, + imdbId: torrent.imdbId.toString(), + imdbSeason: torrent.season || 0, + imdbEpisode: torrent.episode || 0, + kitsuId: parseInt(torrent.kitsuId?.toString()) || 0, + kitsuEpisode: torrent.episode || 0 + }; + + return {...videoFile, ...parse(file.name)}; + } catch (error) { + throw new Error(`Error parsing file ${file.name} from torrent ${torrent.infoHash}: ${error}`); + } }; private mapTorrentFileToSubtitleAttributes = (torrent: IParsedTorrent, file: ITorrentFile): ISubtitleAttributes => ({ @@ -138,5 +160,9 @@ export class TorrentDownloadService implements ITorrentDownloadService { path: file.path, size: file.length, }); + + private logClientErrors(errors: Error | string) { + this.logger.error(`Error in torrent client: ${errors}`); + } } diff --git a/src/node/consumer/src/lib/services/torrent_entries_service.ts b/src/node/consumer/src/lib/services/torrent_entries_service.ts index d94f136..cc0548f 100644 --- a/src/node/consumer/src/lib/services/torrent_entries_service.ts +++ b/src/node/consumer/src/lib/services/torrent_entries_service.ts @@ -23,7 +23,7 @@ export class TorrentEntriesService implements ITorrentEntriesService { private fileService: ITorrentFileService; private subtitleService: ITorrentSubtitleService; private repository: IDatabaseRepository; - + constructor(@inject(IocTypes.IMetadataService) metadataService: IMetadataService, @inject(IocTypes.ILoggingService) logger: ILoggingService, @inject(IocTypes.ITorrentFileService) fileService: ITorrentFileService, @@ -73,7 +73,7 @@ export class TorrentEntriesService implements ITorrentEntriesService { const fileCollection: ITorrentFileCollection = await this.fileService.parseTorrentFiles(torrent) .then((torrentContents: ITorrentFileCollection) => overwrite ? this.overwriteExistingFiles(torrent, torrentContents) : torrentContents) - .then((torrentContents: ITorrentFileCollection) =>this.subtitleService.assignSubtitles(torrentContents)) + .then((torrentContents: ITorrentFileCollection) => this.subtitleService.assignSubtitles(torrentContents)) .catch(error => { this.logger.warn(`Failed getting files for ${torrent.title}`, error.message); return {}; diff --git a/src/node/consumer/src/lib/services/torrent_file_service.ts b/src/node/consumer/src/lib/services/torrent_file_service.ts index 877836f..7990cd8 100644 --- a/src/node/consumer/src/lib/services/torrent_file_service.ts +++ b/src/node/consumer/src/lib/services/torrent_file_service.ts @@ -27,7 +27,11 @@ export class TorrentFileService implements ITorrentFileService { private metadataService: IMetadataService; private torrentDownloadService: ITorrentDownloadService; private logger: ILoggingService; - + private readonly imdb_limiter: Bottleneck = new Bottleneck({ + maxConcurrent: configurationService.metadataConfig.IMDB_CONCURRENT, + minTime: configurationService.metadataConfig.IMDB_INTERVAL_MS + }); + constructor(@inject(IocTypes.IMetadataService) metadataService: IMetadataService, @inject(IocTypes.ITorrentDownloadService) torrentDownloadService: ITorrentDownloadService, @inject(IocTypes.ILoggingService) logger: ILoggingService) { @@ -35,11 +39,6 @@ export class TorrentFileService implements ITorrentFileService { this.torrentDownloadService = torrentDownloadService; this.logger = logger; } - - private readonly imdb_limiter: Bottleneck = new Bottleneck({ - maxConcurrent: configurationService.metadataConfig.IMDB_CONCURRENT, - minTime: configurationService.metadataConfig.IMDB_INTERVAL_MS - }); public parseTorrentFiles = async (torrent: IParsedTorrent): Promise => { const parsedTorrentName = parse(torrent.title); @@ -85,8 +84,8 @@ export class TorrentFileService implements ITorrentFileService { const parsedTorrentName = parse(torrent.title); const hasMovies = parsedTorrentName.complete || !!torrent.title.match(/movies?(?:\W|$)/i); const parsedVideos = videos.map(video => this.parseSeriesVideo(video)); - - return parsedVideos.map(video => ({ ...video, isMovie: this.isMovieVideo(torrent, video, parsedVideos, hasMovies) })); + + return parsedVideos.map(video => ({...video, isMovie: this.isMovieVideo(torrent, video, parsedVideos, hasMovies)})); }; private parseMovieFiles = async (torrent: IParsedTorrent, metadata: IMetadataResponse): Promise => { @@ -100,8 +99,8 @@ export class TorrentFileService implements ITorrentFileService { fileIndex: video.fileIndex, title: video.path || torrent.title, size: video.size || torrent.size, - imdbId: torrent.imdbId.toString() || metadata && metadata.imdbId.toString(), - kitsuId: parseInt(torrent.kitsuId.toString() || metadata && metadata.kitsuId.toString()) + imdbId: torrent.imdbId?.toString() || metadata && metadata.imdbId?.toString(), + kitsuId: parseInt(torrent.kitsuId?.toString() || metadata && metadata.kitsuId?.toString()) })); return {...fileCollection, videos: parsedVideos}; } @@ -140,11 +139,11 @@ export class TorrentFileService implements ITorrentFileService { .catch(error => { if (!this.isPackTorrent(torrent)) { const entries = [{name: torrent.title, path: torrent.title, size: torrent.size, fileIndex: null}]; - return { videos: entries, contents:[], subtitles: [], files: entries} + return {videos: entries, contents: [], subtitles: [], files: entries} } return Promise.reject(error); }); - + if (files.contents && files.contents.length && !files.videos.length && this.isDiskTorrent(files.contents)) { files.videos = [{name: torrent.title, path: torrent.title, size: torrent.size, fileIndex: null}]; } @@ -197,22 +196,22 @@ export class TorrentFileService implements ITorrentFileService { }; private mapSeriesMovie = async (torrent: IParsedTorrent, file: IFileAttributes): Promise => { - const kitsuId= torrent.type === TorrentType.Anime ? await this.findMovieKitsuId(file) + const kitsuId = torrent.type === TorrentType.Anime ? await this.findMovieKitsuId(file) .then(result => { if (result instanceof Error) { this.logger.warn(`Failed to retrieve kitsuId due to error: ${result.message}`); return undefined; } return result; - }): undefined; - + }) : undefined; + const imdbId = !kitsuId ? await this.findMovieImdbId(file) : undefined; const query: IMetaDataQuery = { id: kitsuId || imdbId, type: TorrentType.Movie }; - + const metadataOrError = await this.metadataService.getMetadata(query); if (metadataOrError instanceof Error) { this.logger.warn(`Failed to retrieve metadata due to error: ${metadataOrError.message}`); @@ -247,7 +246,7 @@ export class TorrentFileService implements ITorrentFileService { }]; }; - private decomposeEpisodes = async (torrent: IParsedTorrent, files: IFileAttributes[], metadata: IMetadataResponse = { episodeCount: [] }) => { + private decomposeEpisodes = async (torrent: IParsedTorrent, files: IFileAttributes[], metadata: IMetadataResponse = {episodeCount: []}) => { if (files.every(file => !file.episodes && !file.date)) { return files; } @@ -635,7 +634,7 @@ export class TorrentFileService implements ITorrentFileService { videoInfo.episode = videoInfo.episodes && videoInfo.episodes[0]; } - return { ...video, ...videoInfo }; + return {...video, ...videoInfo}; }; private isMovieVideo = (torrent: IParsedTorrent, video: IFileAttributes, otherVideos: IFileAttributes[], hasMovies: boolean): boolean => { diff --git a/src/node/consumer/src/lib/services/torrent_processing_service.ts b/src/node/consumer/src/lib/services/torrent_processing_service.ts index 516323d..c88d680 100644 --- a/src/node/consumer/src/lib/services/torrent_processing_service.ts +++ b/src/node/consumer/src/lib/services/torrent_processing_service.ts @@ -13,9 +13,10 @@ export class TorrentProcessingService implements ITorrentProcessingService { private torrentEntriesService: ITorrentEntriesService; private logger: ILoggingService; private trackerService: ITrackerService; + constructor(@inject(IocTypes.ITorrentEntriesService) torrentEntriesService: ITorrentEntriesService, @inject(IocTypes.ILoggingService) logger: ILoggingService, - @inject(IocTypes.ITrackerService) trackerService: ITrackerService){ + @inject(IocTypes.ITrackerService) trackerService: ITrackerService) { this.torrentEntriesService = torrentEntriesService; this.logger = logger; this.trackerService = trackerService; @@ -62,6 +63,6 @@ export class TorrentProcessingService implements ITorrentProcessingService { } return torrent.imdb; - }; + }; } diff --git a/src/node/consumer/src/lib/services/torrent_subtitle_service.ts b/src/node/consumer/src/lib/services/torrent_subtitle_service.ts index 83856ee..97878f8 100644 --- a/src/node/consumer/src/lib/services/torrent_subtitle_service.ts +++ b/src/node/consumer/src/lib/services/torrent_subtitle_service.ts @@ -28,7 +28,7 @@ export class TorrentSubtitleService implements ITorrentSubtitleService { return fileCollection; }; - private parseVideo = (video: IFileAttributes)=> { + private parseVideo = (video: IFileAttributes) => { const fileName = video.title.split('/').pop().replace(/\.(\w{2,4})$/, ''); const folderName = video.title.replace(/\/?[^/]+$/, ''); return { @@ -68,7 +68,7 @@ export class TorrentSubtitleService implements ITorrentSubtitleService { return undefined; } - private singleVideoFile = (videos: any[])=> { + private singleVideoFile = (videos: any[]) => { return new Set(videos.map(v => v.videoFile.fileIndex)).size === 1; } diff --git a/src/node/consumer/src/lib/services/tracker_service.ts b/src/node/consumer/src/lib/services/tracker_service.ts index b292314..5918e19 100644 --- a/src/node/consumer/src/lib/services/tracker_service.ts +++ b/src/node/consumer/src/lib/services/tracker_service.ts @@ -10,7 +10,7 @@ import {ILoggingService} from "../interfaces/logging_service"; export class TrackerService implements ITrackerService { private cacheService: ICacheService; private logger: ILoggingService; - + constructor(@inject(IocTypes.ICacheService) cacheService: ICacheService, @inject(IocTypes.ILoggingService) logger: ILoggingService) { this.cacheService = cacheService; @@ -19,7 +19,7 @@ export class TrackerService implements ITrackerService { public getTrackers = async (): Promise => this.cacheService.cacheTrackers(this.downloadTrackers); - private downloadTrackers = async(): Promise => { + private downloadTrackers = async (): Promise => { const response: AxiosResponse = await axios.get(configurationService.trackerConfig.TRACKERS_URL); const trackersListText: string = response.data; // Trackers are separated by a newline character diff --git a/src/node/consumer/src/repository/database_repository.ts b/src/node/consumer/src/repository/database_repository.ts index e5e93cd..c3ed512 100644 --- a/src/node/consumer/src/repository/database_repository.ts +++ b/src/node/consumer/src/repository/database_repository.ts @@ -21,7 +21,7 @@ import {IDatabaseRepository} from "./interfaces/database_repository"; @injectable() export class DatabaseRepository implements IDatabaseRepository { private readonly database: Sequelize; - + private models = [ Torrent, Provider, @@ -32,7 +32,7 @@ export class DatabaseRepository implements IDatabaseRepository { IngestedTorrent, IngestedPage]; private logger: ILoggingService; - + constructor(@inject(IocTypes.ILoggingService) logger: ILoggingService) { this.logger = logger; this.database = this.createDatabase(); @@ -41,7 +41,8 @@ export class DatabaseRepository implements IDatabaseRepository { public connect = async () => { try { await this.database.sync({alter: configurationService.databaseConfig.AUTO_CREATE_AND_APPLY_MIGRATIONS}); - } catch { + } catch (error) { + this.logger.debug('Failed to sync database', error); this.logger.error('Failed syncing database'); process.exit(1); } @@ -112,9 +113,14 @@ export class DatabaseRepository implements IDatabaseRepository { }); public createTorrent = async (torrent: Torrent): Promise => { - await Torrent.upsert(torrent); - await this.createContents(torrent.infoHash, torrent.contents); - await this.createSubtitles(torrent.infoHash, torrent.subtitles); + try { + await Torrent.upsert(torrent); + await this.createContents(torrent.infoHash, torrent.contents); + await this.createSubtitles(torrent.infoHash, torrent.subtitles); + } catch (error) { + this.logger.error(`Failed to create torrent: ${torrent.infoHash}`); + this.logger.debug(error); + } }; public setTorrentSeeders = async (torrent: ITorrentAttributes, seeders: number): Promise<[number]> => { @@ -211,9 +217,9 @@ export class DatabaseRepository implements IDatabaseRepository { logging: false } ); - + newDatabase.addModels(this.models); - + return newDatabase; }; } diff --git a/src/node/consumer/src/repository/models/content.ts b/src/node/consumer/src/repository/models/content.ts index c17bca1..6a697ee 100644 --- a/src/node/consumer/src/repository/models/content.ts +++ b/src/node/consumer/src/repository/models/content.ts @@ -1,22 +1,22 @@ -import {Table, Column, Model, HasMany, DataType, BelongsTo, ForeignKey} from 'sequelize-typescript'; +import {BelongsTo, Column, DataType, ForeignKey, Model, Table} from 'sequelize-typescript'; import {IContentAttributes, IContentCreationAttributes} from "../interfaces/content_attributes"; import {Torrent} from "./torrent"; @Table({modelName: 'content', timestamps: false}) export class Content extends Model { - @Column({ type: DataType.STRING(64), primaryKey: true, allowNull: false, onDelete: 'CASCADE' }) + @Column({type: DataType.STRING(64), primaryKey: true, allowNull: false, onDelete: 'CASCADE'}) @ForeignKey(() => Torrent) declare infoHash: string; - - @Column({ type: DataType.INTEGER, primaryKey: true, allowNull: false }) + + @Column({type: DataType.INTEGER, primaryKey: true, allowNull: false}) declare fileIndex: number; - - @Column({ type: DataType.STRING(512), allowNull: false }) + + @Column({type: DataType.STRING(512), allowNull: false}) declare path: string; - - @Column({ type: DataType.BIGINT }) + + @Column({type: DataType.BIGINT}) declare size: number; - @BelongsTo(() => Torrent, { constraints: false, foreignKey: 'infoHash' }) + @BelongsTo(() => Torrent, {constraints: false, foreignKey: 'infoHash'}) torrent: Torrent; } \ No newline at end of file diff --git a/src/node/consumer/src/repository/models/file.ts b/src/node/consumer/src/repository/models/file.ts index 62a4ea2..94a0b0a 100644 --- a/src/node/consumer/src/repository/models/file.ts +++ b/src/node/consumer/src/repository/models/file.ts @@ -1,8 +1,7 @@ -import {Table, Column, Model, HasMany, DataType, BelongsTo, ForeignKey} from 'sequelize-typescript'; +import {BelongsTo, Column, DataType, ForeignKey, HasMany, Model, Table} from 'sequelize-typescript'; import {IFileAttributes, IFileCreationAttributes} from "../interfaces/file_attributes"; import {Torrent} from "./torrent"; import {Subtitle} from "./subtitle"; -import {ISubtitleAttributes} from "../interfaces/subtitle_attributes"; const indexes = [ { @@ -18,43 +17,43 @@ const indexes = [ 'kitsuEpisode' ] }, - { unique: false, fields: ['imdbId', 'imdbSeason', 'imdbEpisode'] }, - { unique: false, fields: ['kitsuId', 'kitsuEpisode'] } + {unique: false, fields: ['imdbId', 'imdbSeason', 'imdbEpisode']}, + {unique: false, fields: ['kitsuId', 'kitsuEpisode']} ]; -@Table({modelName: 'file', timestamps: true, indexes: indexes }) +@Table({modelName: 'file', timestamps: true, indexes: indexes}) export class File extends Model { - @Column({ type: DataType.STRING(64), allowNull: false, onDelete: 'CASCADE' }) + @Column({type: DataType.STRING(64), allowNull: false, onDelete: 'CASCADE'}) @ForeignKey(() => Torrent) declare infoHash: string; - - @Column({ type: DataType.INTEGER}) + + @Column({type: DataType.INTEGER}) declare fileIndex: number; - - @Column({ type: DataType.STRING(512), allowNull: false }) + + @Column({type: DataType.STRING(512), allowNull: false}) declare title: string; - - @Column({ type: DataType.BIGINT }) + + @Column({type: DataType.BIGINT}) declare size: number; - - @Column({ type: DataType.STRING(32) }) + + @Column({type: DataType.STRING(32)}) declare imdbId: string; - - @Column({ type: DataType.INTEGER }) + + @Column({type: DataType.INTEGER}) declare imdbSeason: number; - - @Column({ type: DataType.INTEGER }) + + @Column({type: DataType.INTEGER}) declare imdbEpisode: number; - - @Column({ type: DataType.INTEGER }) + + @Column({type: DataType.INTEGER}) declare kitsuId: number; - - @Column({ type: DataType.INTEGER }) + + @Column({type: DataType.INTEGER}) declare kitsuEpisode: number; - @HasMany(() => Subtitle, { constraints: false, foreignKey: 'fileId'}) + @HasMany(() => Subtitle, {constraints: false, foreignKey: 'fileId'}) declare subtitles?: Subtitle[]; - @BelongsTo(() => Torrent, { constraints: false, foreignKey: 'infoHash' }) + @BelongsTo(() => Torrent, {constraints: false, foreignKey: 'infoHash'}) torrent: Torrent; } \ No newline at end of file diff --git a/src/node/consumer/src/repository/models/ingestedPage.ts b/src/node/consumer/src/repository/models/ingestedPage.ts index 2dc64a3..3c08b1b 100644 --- a/src/node/consumer/src/repository/models/ingestedPage.ts +++ b/src/node/consumer/src/repository/models/ingestedPage.ts @@ -1,4 +1,4 @@ -import { Table, Column, Model, HasMany, DataType } from 'sequelize-typescript'; +import {Column, DataType, Model, Table} from 'sequelize-typescript'; import {IIngestedPageAttributes, IIngestedPageCreationAttributes} from "../interfaces/ingested_page_attributes"; const indexes = [ @@ -11,6 +11,6 @@ const indexes = [ @Table({modelName: 'ingested_page', timestamps: true, indexes: indexes}) export class IngestedPage extends Model { - @Column({ type: DataType.STRING(512), allowNull: false }) + @Column({type: DataType.STRING(512), allowNull: false}) declare url: string; } \ No newline at end of file diff --git a/src/node/consumer/src/repository/models/ingestedTorrent.ts b/src/node/consumer/src/repository/models/ingestedTorrent.ts index a40571b..7f03914 100644 --- a/src/node/consumer/src/repository/models/ingestedTorrent.ts +++ b/src/node/consumer/src/repository/models/ingestedTorrent.ts @@ -1,4 +1,4 @@ -import { Table, Column, Model, HasMany, DataType } from 'sequelize-typescript'; +import {Column, DataType, Model, Table} from 'sequelize-typescript'; import {IIngestedTorrentAttributes, IIngestedTorrentCreationAttributes} from "../interfaces/ingested_torrent_attributes"; const indexes = [ @@ -11,30 +11,30 @@ const indexes = [ @Table({modelName: 'ingested_torrent', timestamps: true, indexes: indexes}) export class IngestedTorrent extends Model { - @Column({ type: DataType.STRING(512) }) + @Column({type: DataType.STRING(512)}) declare name: string; - - @Column({ type: DataType.STRING(512) }) + + @Column({type: DataType.STRING(512)}) declare source: string; - - @Column({ type: DataType.STRING(32) }) + + @Column({type: DataType.STRING(32)}) declare category: string; - - @Column({ type: DataType.STRING(64) }) + + @Column({type: DataType.STRING(64)}) declare info_hash: string; - - @Column({ type: DataType.STRING(32) }) + + @Column({type: DataType.STRING(32)}) declare size: string; - - @Column({ type: DataType.INTEGER }) + + @Column({type: DataType.INTEGER}) declare seeders: number; - - @Column({ type: DataType.INTEGER }) + + @Column({type: DataType.INTEGER}) declare leechers: number; - - @Column({ type: DataType.STRING(32) }) + + @Column({type: DataType.STRING(32)}) declare imdb: string; - - @Column({ type: DataType.BOOLEAN, defaultValue: false }) + + @Column({type: DataType.BOOLEAN, defaultValue: false}) declare processed: boolean; } \ No newline at end of file diff --git a/src/node/consumer/src/repository/models/provider.ts b/src/node/consumer/src/repository/models/provider.ts index 97b5036..c3506ed 100644 --- a/src/node/consumer/src/repository/models/provider.ts +++ b/src/node/consumer/src/repository/models/provider.ts @@ -1,15 +1,15 @@ -import { Table, Column, Model, HasMany, DataType } from 'sequelize-typescript'; +import {Column, DataType, Model, Table} from 'sequelize-typescript'; import {IProviderAttributes, IProviderCreationAttributes} from "../interfaces/provider_attributes"; @Table({modelName: 'provider', timestamps: false}) export class Provider extends Model { - - @Column({ type: DataType.STRING(32), primaryKey: true }) + + @Column({type: DataType.STRING(32), primaryKey: true}) declare name: string; - - @Column({ type: DataType.DATE }) + + @Column({type: DataType.DATE}) declare lastScraped: Date; - - @Column({ type: DataType.STRING(128) }) + + @Column({type: DataType.STRING(128)}) declare lastScrapedId: string; } \ No newline at end of file diff --git a/src/node/consumer/src/repository/models/skipTorrent.ts b/src/node/consumer/src/repository/models/skipTorrent.ts index 7e1eb4a..6e34c79 100644 --- a/src/node/consumer/src/repository/models/skipTorrent.ts +++ b/src/node/consumer/src/repository/models/skipTorrent.ts @@ -1,10 +1,10 @@ -import { Table, Column, Model, HasMany, DataType } from 'sequelize-typescript'; +import {Column, DataType, Model, Table} from 'sequelize-typescript'; import {ISkipTorrentAttributes, ISkipTorrentCreationAttributes} from "../interfaces/skip_torrent_attributes"; @Table({modelName: 'skip_torrent', timestamps: false}) export class SkipTorrent extends Model { - - @Column({ type: DataType.STRING(64), primaryKey: true }) + + @Column({type: DataType.STRING(64), primaryKey: true}) declare infoHash: string; } \ No newline at end of file diff --git a/src/node/consumer/src/repository/models/subtitle.ts b/src/node/consumer/src/repository/models/subtitle.ts index 7a66baf..f8ffa1e 100644 --- a/src/node/consumer/src/repository/models/subtitle.ts +++ b/src/node/consumer/src/repository/models/subtitle.ts @@ -1,7 +1,6 @@ -import {Table, Column, Model, HasMany, DataType, BelongsTo, ForeignKey} from 'sequelize-typescript'; +import {BelongsTo, Column, DataType, ForeignKey, Model, Table} from 'sequelize-typescript'; import {ISubtitleAttributes, ISubtitleCreationAttributes} from "../interfaces/subtitle_attributes"; import {File} from "./file"; -import {Torrent} from "./torrent"; const indexes = [ { @@ -13,27 +12,27 @@ const indexes = [ 'fileId' ] }, - { unique: false, fields: ['fileId'] } + {unique: false, fields: ['fileId']} ]; @Table({modelName: 'subtitle', timestamps: false, indexes: indexes}) export class Subtitle extends Model { - - @Column({ type: DataType.STRING(64), allowNull: false, onDelete: 'CASCADE' }) + + @Column({type: DataType.STRING(64), allowNull: false, onDelete: 'CASCADE'}) declare infoHash: string; - - @Column({ type: DataType.INTEGER, allowNull: false }) + + @Column({type: DataType.INTEGER, allowNull: false}) declare fileIndex: number; - - @Column({ type: DataType.BIGINT, allowNull: true, onDelete: 'SET NULL' }) + + @Column({type: DataType.BIGINT, allowNull: true, onDelete: 'SET NULL'}) @ForeignKey(() => File) declare fileId?: number | null; - - @Column({ type: DataType.STRING(512), allowNull: false }) + + @Column({type: DataType.STRING(512), allowNull: false}) declare title: string; - @BelongsTo(() => File, { constraints: false, foreignKey: 'fileId' }) + @BelongsTo(() => File, {constraints: false, foreignKey: 'fileId'}) file: File; - + path: string; } \ No newline at end of file diff --git a/src/node/consumer/src/repository/models/torrent.ts b/src/node/consumer/src/repository/models/torrent.ts index f345b55..c759d3a 100644 --- a/src/node/consumer/src/repository/models/torrent.ts +++ b/src/node/consumer/src/repository/models/torrent.ts @@ -1,4 +1,4 @@ -import { Table, Column, Model, HasMany, DataType } from 'sequelize-typescript'; +import {Column, DataType, HasMany, Model, Table} from 'sequelize-typescript'; import {ITorrentAttributes, ITorrentCreationAttributes} from "../interfaces/torrent_attributes"; import {Content} from "./content"; import {File} from "./file"; @@ -9,48 +9,48 @@ import {Subtitle} from "./subtitle"; export class Torrent extends Model { @Column({type: DataType.STRING(64), primaryKey: true}) declare infoHash: string; - + @Column({type: DataType.STRING(32), allowNull: false}) declare provider: string; - + @Column({type: DataType.STRING(512)}) declare torrentId: string; - + @Column({type: DataType.STRING(512), allowNull: false}) declare title: string; - + @Column({type: DataType.BIGINT}) declare size: number; - + @Column({type: DataType.STRING(16), allowNull: false}) declare type: string; - + @Column({type: DataType.DATE, allowNull: false}) declare uploadDate: Date; - + @Column({type: DataType.SMALLINT}) declare seeders: number; - + @Column({type: DataType.STRING(8000)}) declare trackers: string; - + @Column({type: DataType.STRING(4096)}) declare languages: string; - + @Column({type: DataType.STRING(16)}) declare resolution: string; - + @Column({type: DataType.BOOLEAN, allowNull: false, defaultValue: false}) declare reviewed: boolean; - + @Column({type: DataType.BOOLEAN, allowNull: false, defaultValue: false}) declare opened: boolean; - @HasMany(() => Content, { foreignKey: 'infoHash', constraints: false }) + @HasMany(() => Content, {foreignKey: 'infoHash', constraints: false}) contents?: Content[]; - @HasMany(() => File, { foreignKey: 'infoHash', constraints: false }) + @HasMany(() => File, {foreignKey: 'infoHash', constraints: false}) files?: File[]; - + subtitles?: Subtitle[]; } \ No newline at end of file diff --git a/src/node/consumer/tsconfig.json b/src/node/consumer/tsconfig.json index cd0f68d..435ebc2 100644 --- a/src/node/consumer/tsconfig.json +++ b/src/node/consumer/tsconfig.json @@ -8,8 +8,13 @@ "rootDir": "./src", "sourceMap": true, "target": "ES6", - "lib": ["es6"], - "types": ["node", "reflect-metadata"], + "lib": [ + "es6" + ], + "types": [ + "node", + "reflect-metadata" + ], "esModuleInterop": true, "experimentalDecorators": true, "emitDecoratorMetadata": true,